; Tarbell Duplex 816 BOOT Module for CP/M-86 and MP/M-86. ; Copyright (c) 1984, Tarbell Electronics ; Last changed 7-29-84 by Don Tarbell ; ; logical equates false equ 0 true equ not false dubsid equ false ; this disk double sided? mini equ false ; true for 5-inch floppy disks. ; memory addresses. load equ 4000h ; load address. bootad equ 200h ; address of this module. nxtseg equ 400h ; next module segment. ; sector and byte counts. if not mini ; if 8-inch floppy. t0spt equ 26 ; track 0 sectors per track. t1spt equ 16 ; track 1 sectors per track. fsize equ 0ch ; bits 2 & 3 high for 8-inch. endif if mini ; if 5-inch floppy. t0spt equ 18 ; track 0 sectors per track. t1spt equ 10 ; track 1 sectors per track. fsize equ 00h ; bits 2 & 3 low for latch. endif t0bps equ 128 ; track 0 bytes per sector. t1bps equ 512 ; track 1 bytes per sector. t0bpt equ t0spt * t0bps ; track 0 bytes per track. t1bpt equ t1spt * t1bps ; track 1 bytes per track. nbytes equ t0bpt + t1bpt ; total bytes on system tracks. ; 2793 floppy interface port addresses. pcsbas equ 0f000h ; peripheral register base adr. fbase equ pcsbas + 80h ; 2793 floppy ic base address. fdisk equ fbase ; command/status port. fsect equ fbase + 4 ; sector port. fcont equ pcsbas + 100h ; control port. ; 80186 dma port addresses. conbas equ 0ff00h ; control block base after reset. dmacon0 equ conbas+0cah ; control word. dmatc0 equ conbas+0c8h ; transfer count. dmadpu0 equ conbas+0c6h ; destination pointer upper. dmadpl0 equ conbas+0c4h ; destination pointer lower. dmaspu0 equ conbas+0c2h ; source pointer upper. dmaspl0 equ conbas+0c0h ; source pointer lower. fdmard equ 0a266h ; dma floppy to memory code. cseg org bootad xor ax,ax ; clear segment registers. mov ds,ax mov es,ax mov ss,ax mov sp,bootad+100h ; put stack above this module. ; set up the 80186 dma controller. mov dx,dmaspu0 ; source upper port. out dx,ax ; source upper port=0. mov dx,dmadpu0 ; destination upper. out dx,ax ; upper 4 bits of abs adr. mov ax,load ; get load address. mov dx,dmadpl0 ; destination lower. out dx,ax ; lower 16 bits of abs adr. mov ax,nbytes-t0bps ; get number of bytes to move. mov dx,dmatc0 ; transfer count. out dx,ax mov ax,fdmard ; dma command. mov dx,dmacon0 ; dma control port. out dx,ax ; arm the dma. ; set up 2793 floppy controller. mov dx,fcont ; get control register port. mov al,10h+fsize ; get single density code for latch. out dx,al ; do it. mov bh,2 ; init track count = 2. mov bl,t0spt+1 ; track 0 last sector + 1. mov al,2 ; set starting sector = 2. rdtrk: mov dx,fsect ; get sector port. out dx,al ; write al to sector port. mov al,94h ; read multiple sectors. mov dx,fdisk ; get command port number. out dx,al ; commence multi-sector read. call delay ; fool around a little. ; wait for track completion. sectlp: mov dx,fsect ; get sector port address. in al,dx ; read sector number. cmp al,bl ; is it past last one yet? jnz sectlp ; keep checking if not. ; terminate multi-sector read operation. mov al,0d0h ; code to force interrupt. mov dx,fdisk ; command port address. out dx,al ; force interrupt. call delay ; wait for good status. ; see if it's all done reading the system. dec bh ; decrement track counter. jnz keepon ; do next track if not zero. jmpf entry ; hop if finished. keepon: if not dubsid ; if not double sided. mov al,fsize ; double-density latch code. mov dx,fcont ; get control reg adr. out dx,al ; set to double density. mov al,59h ; get step in code. mov dx,fdisk ; command port address. out dx,al ; step in. call delay ; settle time. steplp: in al,dx ; read 2793 status. and al,80h ; is it still busy stepping? jnz steplp ; loop back if so. endif if dubsid ; if double-sided disk. mov al,40h+fsize ; get side-one latch code. mov dx,fcont ; get control reg port adr. out dx,al ; flip to other side. endif ; prepare to read next track. mov bl,t1spt+1 ; get last sector + 1. mov al,1 ; get first sector number. jmps rdtrk ; loop back and read track. ; Provide some delay for status valid, etc. delay: mov cx,1000h ; initialize counter. delayl: loop delayl ; decrement until zero. ret ; Define the density selection byte. org bootad+7dh if not dubsid ; if not double-sided. db not(0deh), 0deh endif if dubsid ; if double-sided. db not(0dch), 0dch endif ; Define entry point of secondary loader. cseg nxtseg org 0 entry: end