; HDC/DMA head park program ; Initial coding - 8/1/83 - BJG org 100h .z80 bdos equ 05 rstchan equ 50h drive0 equ 0 drive1 equ 1 drive2 equ 2 drive3 equ 3 head0 equ 01CH ;0001 1100 head1 equ 018H ;0001 1000 head2 equ 014H ;0001 0100 head3 equ 010H ;0001 0000 head4 equ 0CH ;0000 1100 head5 equ 08H ;0000 1000 head6 equ 4 ;0000 0100 head7 equ 0 ;0000 0000 sel equ 0 ;drive byte for seek command select equ 3 ;drive/head select byte stepl equ 1 steph equ 2 cmnd equ 0bh status equ 0ch stepin equ 0fh ;constant to go to maxtrac stepout equ 10h ;constant to go to track 0 step equ 06h sense equ 05h attn equ 55h maxtrac equ 306 ;number of tracks for m10/m16 cpm equ 0 ;warm boot channel equ cmdchan stepdeì eqõ  01Eè ;steð delaù foò  ST-506 settle equ 0 ;head settle for ST-506 secsiz equ 7 ;1024 byte sectors reset equ 54H arg0 equ 07 ;command arguments arg1 equ 08 ;command arguments arg2 equ 09 ;command arguments arg3 equ 0ah ;command arguments cnsts equ 04h ;load constants cmd ready equ 04h mesage: ld sp,01000h ld c,25 clear: push bc call crlf ;clear the screen pop bc dec c jp nz,clear Š ; print a signon message ld de,signon ;print signon message call pmsg ld de,sign1 call pmsg call crlf ; set up the DMA channel and reset the controller init: ld b,0 ld c,10H ld hl,channel ld (rstchan),hl ld (channel + 0dh),hl ;link field init xor a ld (rstchan + 2),a ;channel address @ 80h ld (channel + 0fh),a ;link field init out (reset),a loop1: dec c ;wait for controller to reset jr nz,loop1 ; perform a LOAD CONSTANTS command init1: ld ix,channel ld (ix + sel),a ;zero select byte ld (ix + stepl),a ;zero steps ld (ix + steph),a ;zero steps ld (ix + arg0),a ;zero cyl argument ld (ix + arg2),a ;zero head settle ld a,01ah ;drive 0 head 0 ld (ix + select),a ;turn off step ld a,stepdel ;3 ms steps ld (ix + arg1),a ld a,secsiz ld (ix + arg3),a ;1024 sectors ld a, cnsts ;load constants cmd ld (ix + cmnd),a call loop ; check for drive presence - all four drives ld iy,drv0 ;drive pointer ld a,sense ld (ix + cmnd),a ;sense status command check: ld a,0 ld (ix + status),a ;null the status ld a,(iy) ld (ix + select),a push af ;save current drive call loop ;kick controller bit 2,a Š jp nz,next ;check for drive ready pop af ;get back current drive ld (iy),a ;save it check1: inc iy inc a ;increment drive cp 04 jp nz,check ;loop for 3 drives jp start ; go here if no drive present next: ld a,0ffh ld (iy),a ;flag drive as non-existant pop af jp check1 ; step all the valid drives to track 0 start: ld b,0 ;counter ld iy,drv0 ;drive table pointer ld a,step ld (ix + cmnd),a ;step command start1: ld a,0 ld (ix + status),a ;null the status ld a,0ffh ld (ix + stepl),a ld (ix + steph),a ld a,(iy) cp 0ffh ;check for non existant drive jp z,newone or stepout ld (ix + sel),a ;send it home constant ld (ix + select),a call loop ; step all the valid drives to maxtrack goout: xor a ld (ix + status),a ;null the status ld a,(ix+sel) and stepin ;for each drive ld (ix + sel),a ;constant to seek in ld hl,maxtrac ;306d for cmi ld (channel + stepl),hl call loop newone: inc iy inc b bit 2,b jp z,start1 ;once for each drive jp leave ;warm boot Š; Routine kicks controller and waits for status to change ; from a 0 to some other value... 'A' register contains status ; value on return. (H & L, C, A registers not preserved) loop: out (attn),a ;kick controller ld hl,0 ld c,10h ;1 minute to respond loop0: ld a,(ix + status) cp 00h ret nz dec hl ld a,h or l jp nz,loop0 dec c jp nz,loop0 jp error ; print string pointed to by D & E pmsg: ld c,09 ;bdos print line call call bdos ; print CRLF crlf: ld e,0ah ;CR call cout ld e,0dh ;LF ; print character in the E register cout: ld c,02 ;bdos print character call call bdos ret ; print a space space: ld e,20h call cout ret ; Controller timeout error error: ld de,errmsg call pmsg call crlf jp cpm ; successful down exit... print logoff and select drive 4 leave: ld bc,00h ld iy,drv0 leav1: ld a,(iy) cp 0ffh ;was it active Š jp nz,incb ;take jump if not incc: inc c bit 2,c jp nz,lmesag inc iy jp leav1 incb: inc b jp incc lmesag: push bc call space ;print a space pop bc ld a,030h ;force ascii "1" add a,b ;get number drives tested push bc ld e,a call cout pop bc ld a,b cp 1 ;special message for 1 drive jp nz,many ld de,lvmsg1 jp cont many: ld de,lvmsg cont: call pmsg ld de,signof call pmsg call crlf call crlf ld de,advise call pmsg call crlf call crlf ; select drive 4 for power down ld hl,0 ld (channel + 1),hl ;null the steps ld a,drive3 ld (ix + sel),a ld (ix + select),a ;select last drive out (attn),a ;kick controller stop: jp stop ;loop forever ; display messages signon: db ' Decision 1 Shutdown Program $' sign1º  dâ  § No÷ parkinç winchesteò headó iî safå landinç zones... $' signof: db ' Your system is now ready to be turned off. $' errmsg: db ' HDC/DMA controller not responding! $' lvmsg: db ' drives are now ready to be turned off. $' lvmsg1: db ' drive is now ready to be turned off. $' advise: db ' Remember to backup on floppy and run CHECK.COM periodically!! $' ; local variables Š drv0: db 0 drv1: db 1 drv2: db 2 drv3: db 3 ; DMA command channel on reset cmdchan equ $ end