title floppy drive test 3/15/82 channl equ 50h ;Start channel address vector equ channl+1 ;branch address start equ 0efh ;port address to start the controller setma equ 23h ;Command to set DMA address rdsec equ 20h ;Command to read a sector wrsec equ 21h ;Command to write a sector snsta equ 22h ;Command to sense drive status strtry equ 28h ;Command to set error retry count stlgcl equ 2eh ;Command to set logical drive sttime equ 2fh ;Command to set head unload/ ; drive deselect timeout rdtrk equ 29h ;Command to read a track wrtrk equ 2ah ;Command to write a track conhlt equ 25h ;Command to halt controller branch equ 26h ;Command to branch in channel setchn equ 27h ;Command to set channel address sttksz equ 2dh ;Command to set track size good equ 40h ;normal command completion fiver equ 4h ;five inch drive flag wrprot equ 40h ;write protect flag dblsid equ 4 ;double sided drive & media flag index equ 10h ;Delta index status bit wproct equ 40h ;Write protected status bit dready equ 80h ;Drive ready status bit home equ 0a0h ;Internal home-disk routine address seek equ 0a3h ; seek-track sdrive equ 0a6h ; set-drive hsync equ 0a9h ; header-sync diskd equ 4001h ;Disk data port status equ 4003h ;Status port contrl equ 4007h ;Control port conin equ 1 crlfs equ 0d0ah ;Carraige return / line feed sequence acr equ 0dh ;A carraige return character alf equ 0ah ;A line feed character aesc equ 1bh ;An escape character adel equ 7fh ;A delete character retries equ 3 ;Disk retries before verify error wboot equ 0 ;warm boot address bdos equ 5 ;Bdos entry address wrstrn equ 9h ;bdos write string wcon equ 2 ;Write console function direct equ 6 ;Direct console I/O org 100h lxi sp,stack mvi a,branch ;branch command sta channl ;controller starts here sub a ;zero A sta vector+2 ;extended address byte call drvcks ;look for drives rst 7 lda drvson ;drvson indicates active drives cpi 0 jz none ;no drives active call drvrpt ;report status to terminal call input ;proceed or restart call seeks ;do seek tests call wrtrds ;do writes & reads tests call finals ;report final results jmp wboot ;end drvcks mvi c,8 ;maximum number of drives drvlp lxi h,snstat ;get address of sense command shld vector ;store it in vector lxi h,0 ;timer count lxi d,0 ;auxilliary counter mvi a,8 ;# of possible drives sub c ;to find current drive sta snsdrv ;tell sense command sub a ;zero A mov b,a ;zero B sta snsrlt ;clear result byte of sense command out start ;start controller timelp dcx h ;count down mov a,h ;ck count ora l jnz cksns ;skip 2 dcr b ;decrement auxilliary counter jz panic1 ;controller not responding cksns lda snsrlt ;sense command result status cpi 0 ;zero means command not finished jz timelp ;wait for controller push b ;save count call login ;record results in table pop b ;recover count dcr c ;drive count-down jnz drvlp ;next drive ret ;else return login ani good ;non-zero means active drive jnz trks ;to find out about it lhld logpnt ;get pointer sub a ;zero A mov m,a ;indicates inactive drive inx h ;update pointer mov m,a inx h ;for next drive shld logpnt ;store pointer ret trks lxi h,rdsect ;load add of rd sect command shld vector ;store it for controller mvi a,40 ;to check # of trks sta rdsctk ;tells it to read track 40 mvi a,8 ;maximum number of drives sub c ;drive counter sta rdscdr ;tells controller which drive sub a ;zero A sta rdscrs ;clears result byte out start ;start controller rswait lda rdscrs ;look for result ora a ;still zero? jz rswait ;wait for results ani good ;if ok, its 77 or 80 trks jz fivnch ;else log a 5 inch 40 trk lda dstat1 ;to find whether 5 or 8 inch ani 4h ;on means 5 inch jz eighin ;if 8 inch mvi a,79 ;# of trks if 5 inch lhld logpnt ;get log pointer mov m,a ;number of last track inx h ;to next entry (sngl or dble sided) inx h ;to next drive shld logpnt ;store the updated pointer ret eighin lhld logpnt ;load log pointer mvi a,76 ;last trk number mov m,a ;log it inx h ;next log entry lda dstat2 ;3 bit tells # of sides ani 4h ;on means dbl sided jz sngl ;single sided mvi a,80h ;dble sided bit sngl mov m,a ;record it inx h ;increment pointer for next drive shld logpnt ;save it ret fivnch lhld logpnt ;load pointer mvi a,39 ;highest track number mov m,a ;log it inx h ;increment pointer inx h ;twice for next drive shld logpnt ;save it lda rdscrs ;read sector result cpi 83h ;illegal track value rz ;everything ok call hexout ;sends error code to terminal panic3 lxi d,pan3ms ;unexpected error code call wrterm ret mvi a,6 ;offset to next drive results add e jnc nocary inr d nocary mov e,a dcr c ;possible drives count rz ;all done mov b,c sub c cpi 0 mvi a,1 jz logit shift ral dcr b jnz shift logit mov b,a lda drvson ora b ret drvrpt lda drvson ani 1 jz two call phsout call report two lda drvson ani 2 jz three mvi a,1 call phsout call report three lda drvson ani 4 jz four call phsout call report four lda drvson ani 8 jz five mvi3 call phsout call report five lda drvson ani 10h jz six mvi4 call phsout call report six lda drvson ani 20h jz seven mvi5 call phsout call report seven lda drvson ani 40h jz eight mvi6 call phsout call report eight lda drvson ani 80h rz mvi a,7 call phsout jmp report report push d ldax d ani fiver jz eignch lxi d,fivems call wrterm pop d inx d inx d ldax d ani wrprot rz protcd lxi d,wrprms jmp wrterm eignch pop d inx d inx d ldax d ani wrprot jnz protcd ani dblsid rz lxi d,dblmsg jmp wrterm ret input lxi d,rspnms call wrterm call inrspn cpi 'y' rz jmp 100 inrspn mvi c,conin jmp bdos seeks mvi a,0ffh sta nowdrv nxdrv call curdrv cpi 0ffh ;flag means no more drives rz ;finished seeks - do writes sta nowdrv ;update nowdrv jmp nxdrv curdrv lda nowdrv ;current drive, initialized to 0ffh inr a ;see if active mov b,a ;save incremented value jnz ongo ;advance if it is active lda drvson ;otherwise load available drives rrc ;see if physical one is active rc ;if so, b has correct value (drv 0) find1 inr b ;otherwise increment b jz panic ;guard against endless loop rrc ;while rotating a jnc find1 ;until the first active drive appears ret ;should do it ongo mov c,b ;if active, save in c lda drvson rrc ;for incrementing a ongone dcr c ;and rotate past all rrc ;previous drives jnz ongone rc ;b should be right at this point ongo2 inr b ;else increase it rrc ;keep looking rc ;next active drive push psw ;save a mvi a,7 ;maximum drive number cmp b ;see if done jz nomore ;no more drives pop psw ;recover a jmp ongo2 nomore mvi b,0ffh ;flag in b pop psw ret wrtrds rst 7 finals rst 7 phsout push psw lxi d,drvmsg call wrterm pop psw jmp hexout wrterm mvi c,wrstrn jmp bdos none lxi d,nodrvs mvi c,wrstrn call bdos jmp wboot hexout mov l,a mvi h,0 ***************************************************************** * * * Putdc prints the ascii decimal equivalent of the number in HL * * * ***************************************************************** putdc lxi b,-10 phl push d mov d,b mov e,b phllp dad b inx d jc phllp xthl xchg movh ora l cnz phl pop h mvi a,'0' add l sub c pchar push h push b push d push psw mov e,a mvi c,2 call bdos pop psw pop d pop b pop h ret panic lxi d,panmsg call wrterm jmp wboot panic1 lxi d,pan1ms call wrterm jmp wboot snstat db snsta ;sense status command snsdrv db 0 ;physical drive number dstat1 db 0 ;dstat 1 dstat2 db 0 ;dstat 2 dstat3 db 0 ;dstat 3 snsrlt db 0 ;command result db conhlt ;controller halt db 0 ;halt result status setdma db setma ;set dma for seeks dw dskbuf ;all purpose buffer (8k-8192 bytes) db 0 ;extended address byte db conhlt ;controller halt db 0 ;halt result status rdsect db rdsec ;command to read a sector rdsctk db 40 ;default to ck size of 5" drives sidsec db 1 ;side 0 sector 1 rdscdr db 0 ;physical drive number rdscrs db 0 ;result status db conhlt ;controller halt command db 0 ;halt result status trktbl ds 15 ;table used by write track command wrtrak db wrtrk ;write track command wrtktk db 0 ; wrtksd db 0 ; wrtkdr db 0 ; wrtabl dw trktbl ; db 0 wtrslt db 0 db conhlt db 0 rdtrak db rdtrk ;read track command rdtktk db 0 ; rdtksd db 0 ; rdtkdr db 0 ; rdsctb dw trktbl ; db 0 rtrslt db 0 db conhlt db 0 drvson db 0 ;drives being tested (one bit each) nowdrv db 0 ;current drive logpnt dw drvlog ;pointer to drvlog drvlog ds 16 ;drive log (trks & sides) panmsg dw crlfs db 'endless loop in program$' pan1ms db ' controller not responding$' pan3ms db ' unexpected error code $' drvmsg dw crlfs db 'physical $' fivems db ' is a 5 inch $' eighms db ' is an 8 inch $' wrprms db ' write protected$' dblmsg db ' double-sided drive$' nodrvs dw crlfs db 'no drives are ready$' rspnms dw crlfs db 'OK? (respond Y or fix & respond N):$' ds 30 stack equ $ dskbuf ds 8192 ;8K disk buffer