;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ;<>******************************************************<> ;<>* *<> ;<>* D D D *<> ;<>* *<> ;<>* Dysan Corporation *<> ;<>* C.E. Division *<> ;<>* 1244 Reamwood Avenue *<> ;<>* Sunnyvale, Cal. 94086 *<> ;<>* 408-734-1624 *<> ;<>* *<> ;<>* VERSION [ 1.0 ] *<> ;<>* *<> ;<>******************************************************<> ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><> title 'Drive Diagnostic Program for CP/M 80 1/15/83' page 75 ; File ddd.asm ; ; Digital Research's MAC macro assembler has ; been used to compile this program. ; ; Digitial Research ; P.O. Box 579 ; 801 Lighthouse Avenue ; Pacific Grove, Ca 93950 ; (408) 649-3896 ; ; This example skeleton program may be used to read ; the Digital Diagnostic Diskette. Many features can ; be added to make a more substantial program. The ; read routines are directed at the 8 inch "DDD",but ; can be altered for 5 1/4 inch "DDD" ; ; The Western Digital 1793 floppy controller has been ; chosen because of it's wide use in micro computers. ; This program dosn't depend upon this controller, but ; the controller used must be able to read FM or MFM ; formats. ; ; Western Digital Corp ; P.O. Box 2180 ; 3128 Redhill Avenue ; Newport Beach, Cal 92663 ; (714) 557-3550 ; ; N O T I C E ; This document contains information developed by ; Dysan Corporation (Dysan) and is furnished for ; information only. ; Dysan makes no warranty or representation (expressed ; or implied) with respect to the accuracy,completeness ; or usefulness of the information contained herein. ; Further Dysan assumes no responsibility for liability ; or damage of any kind which may result from the use ; of of the information contained herein. page ; ; The following features of { DDD } are utilized: ; ; Radial alignment check ; Azimuth alignment check ; Centering ; Stepper Hysteresis ; Index Timing ; ; The RPM check is not a function of the { DDD }. *********************** *** "CONFIGURATION" *** *********************** ; A. Hazeltine 1500 Terminal ; B. 8080 Assembly language ; C. Timing based on 4mhz Z80 processor ; D. Direct Console I/O to CP/M 80 ; E. Disk operations written for Dysan's ; Single Card Computer. ; F. Diagnostic Disk (808-100) ******************************** *** "MACRO CALL BDOS DIRECT" *** ******************************** ; ; This macro is presently used to Link console I/O ; only, the disk i/o routines also may be linked ; to CP/M 2.2 with this macro. ; ; e.g. gobios 24 ; select drive ; ; ; Function: ; Loads Warm boot address to bdos ; and computes offset to routine. wboot equ 0 ; warm boot address gobios macro @func lhld wboot+1 ; Warm boot address lxi d,@func ; Offset dad d ; Add offset pchl ; Go to bdos routine endm page *************************** *** "CONSOLE FUNCTIONS" *** *************************** ; The following are direct console commands ; which can be altered for most consoles. ; note: ; The text print routine must be altered ; if "Row" is send before "Column" or ; bias is needed. lead$in equ 126 ; console lead-in add$cur equ 17 ; address cursor command clr$co equ 28 ; clear to foreground spaces end$ln equ 15 ; clear to end of line **************************************** *** "FLOPPY CONTROLLER PORT EQUATES" *** **************************************** ; Change the following Port assignments for ; Your system. ; ; "FDC" Acronym Floppy Disk Controller ; ; FDC port assignments: ; fdc equ 0f8h ; Base port address FDC ; cmd equ fdc ; command reg. stat equ fdc ; status reg. trk equ fdc+1 ; track reg. sec equ fdc+2 ; sector reg. data equ fdc+3 ; data reg. dma equ fdc+4 ; Dma controller ; dsel equ fdc+5 ; drive select ************************************ *** "FLOPPY CONTROLLER COMMANDS" *** ************************************ clear equ 0d0h ; clear FDC sdma equ 87h ; Start Dma Transfer rsec equ 80h ; read sector raddr equ 0c0h ; read address seek equ 18h ; seek track restore equ 8 ; home Head(s) sdelay equ 4 ; seek delay flag ************************************* *** "FLOPPY CONTROLLER VARIABLES" *** ************************************* rate equ 1 ; step rate retry equ 1 ; read retries fdelay equ 11 ; FDC delay lneg equ 28 ; last neg. sector +2 lpos equ 27 ; last pos. sector +2 tsec equ (26/2)-1 ; centering test ref equ 798 ; reference time (single Den) page ****************************** *** "MISCELLANOUS EQUATES" *** ****************************** ttrk equ 76 ; total number of tracks cr equ 0dh ; carriage return lf equ 0ah ; line feed esc equ 1bh ; escape bs equ 8 ; back space bell equ 7 ; audio alert *************************** *** "MAIN PROGRAM LOOP" *** *************************** org 100h ; ==== ==== lxi sp,stack ; init stack call select ; select drive ; main: lxi sp,stack ; reset stack call cls ; clear display lxi h,me1 ; display Menu.. call text call ci ; selection? cpi 'R' ; "Radial" jz radial cpi 'A' ; "Azimuth" jz azimuth cpi 'C' ; "Centering" jz center cpi 'H' ; "Hysteresis" jz hyster cpi 'S' ; "RPM" jz rpm cpi 'I' ; "Index" jz index cpi 'E' ; "Exit to DOS" jz exit mvi a,bell ; Not valid call co jmp main ; try again... page ********************** *** " EXIT TO DOS" *** ********************** exit: call cls ; clear display jmp wboot ************************* *** "CONSOLE STATUS" *** ************************* ; returns with zero status flag set. cstat: push h ; save all registers push d push b call cstat1 ; Data ready? pop b pop d pop h ora a ret cstat1: gobios 3 ; macro *********************** *** "CONSOLE INPUT" *** *********************** ; ; Returns character in "A" reg. ci: push h ; Save all registers push d push b call ci1 ; take character pop b pop d pop h cpi esc ; Exit? jz main ; YES! cpi 'a' ; convert to upper case rc ; only... cpi '{' rnc ani '^'+1 ret ci1: gobios 6 ; macro page ************************ *** "CONSOLE OUTPUT" *** ************************ ; ; Enter with character in "A" reg. co: push h ; save all registers push d push b mov c,a ; Pass char in "C" reg call co1 pop b pop d pop h ret co1: gobios 9 ******************** *** "LINE INPUT" *** ******************** ; used to input data greater then one ; character and is terminated by "CR". getln: lxi d,buffer ; input buffer ; gl1: call ci ; Wait for Input cpi lf ; Line feeds Not allowed jz gl1 cpi '_' ; treat as back space jz back cpi bs ; check for back space jz back cpi 7fh ; Delete char? jz back cpi cr jz gl2 cpi ' ' jc gl1 ; control Characters Not allowed ; gl2: stax d ; store char inx d ; next address call co ; echo char cpi cr ; end of Line? rz ; Yes! lxi h,buffer+4 ; end of Buffer call dehl ; check jnz gl1 ; No! page ; back: lxi h,buffer ; can backup ? call dehl jz gl1 ; NO! dcx d ; Backup text pointer mvi a,bs ; backup cursor call co mvi a,' ' ; store Space call co mvi a,bs ; adjust cursor call co jmp gl1 ; New char ********************************** *** "BIAS FROM SELECTED TRACK" *** ********************************** ; ; Sets the required offset for Hysteresis ; test. offset: call cls ; clear display lxi h,me6 ; OFFSET? call text call getln ; Input offset call getnum ; convert to hex cpi cr ; at end of line? jnz offset1 ; error... mov a,h ; check Limits ora a jnz offset1 mov a,l cpi ttrk+1 ; Greater then last track? jnc offset1 sta bais ; save offset ret ; offset1: mvi a,bell ; alert operator call co jmp offset page ******************************* *** "INPUT TRACK LOCATIONS" *** ******************************* ; Input track locations for Radial ; Hysteresis,Centering and Index tests. ; "B" contents Upper Limit upon entry. inp$trk: call cls ; clear display... call text ; inp$trk1: call ci ; waiting... cmp b ; within limits? jnc inp$trk2 ; no... sui 'A' jc inp$trk2 ; try again lhld temp ; table pointer mvi d,0 mov e,a dad d ; add offset mov a,m ; load track jmp track ; seek to track ; inp$trk2: mvi a,bell ; alert call co jmp inp$trk1 ; try again... *********************************************** *** "RADIAL AND HYSTERESIS TRACK LOCATIONS" *** *********************************************** rh$tbl db 0 db 3 db 38 db 41 db 70 db 73 *************************** *** "INDEX TRACK TABLE" *** *************************** ix$tbl: db 0 db 76 ************************* ** "CENTERING TRACKS" *** ************************* cen$tbl: db 35 db 44 db 47 page ******************************* *** "PRINT DECIMAL NUMBERS" *** ******************************* ; ; Enter with number to be printed in ; 'DE' reg. pnum: push h ; Setup Stack lxi h,10 ; Terminator... push h push h ; pn1: call div16 ; Divide Number By (10) mov a,d ; Check result ora e ; = 0 jz pn2 xthl dcr l push h lxi h,10 jmp pn1 ; Divide Again ; pn2: pop d ; Display Values mov e,l ; pn3: mov a,e ; Check for Terminator (10) cpi 10 pop d ; Next digit rz adi '0' ; Add ascii Bias call co jmp pn3 **************************** *** "16 BIT SUBTRACTION" *** **************************** ; ; Subtract "DE" from "HL" subde: mov a,l sub e mov l,a mov a,h sbb d mov h,a ret page ************************************************ *** "CONVERT ASCII DECIMAL NUMBER TO BINARY" *** ************************************************ ; ; Returns 16 bit hex value in "HL" regs. get$num: call sksp ; Skip Spaces and Return Char lxi h,0 ; Clear counter mov b,h ; Clear "B" ; get$num1: cpi cr ; end of line? cpi '0' ; less than rc ; yes Error! cpi ':' ; Upper Limit rnc ; Returns "CR" mvi a,0f0h ; mask Upper Nibble ana h rnz inr b ; +1 push b ; Save count.. mov b,h mov c,l ; Swap "HL" with "BC" dad h dad h dad b dad h ldax d ; Load Same Char.. inx d ; next Char ani 0fh ; Mask Lower Nibble add l mov l,a ; save result mvi a,0 ; Clear "A" adc h ; Add carry mov h,a pop b ; restore counter.. ldax d ; Load next Char.. jmp getnum1 ***************************************** *** "SKIP OVER SPACES IN TEXT BUFFER" *** ***************************************** sksp: lxi d,buffer ; point to text buffer ; sksp1: ldax d ; check for Space cpi ' ' ; First Non Space return rnz inx d jmp sksp1 ***************************** *** "COMPARE "DE" TO "HL" *** ***************************** dehl: mov a,l ; compare "E" to "L" cmp e ; If not zero return rnz mov a,h cmp d ret page ********************************** *** "16/24 BIT DIVIDE ROUTINE" *** ********************************** ; Divide "HL" by "DE" ; div16: xra a ; optional 16 bit divide ; div24: sta msb ; Normal 24 bit divide shld msb1 lxi h,msb2 mvi m,24+1 lxi b,0 push b div25: mov a,e ral mov e,a mov a,d ral mov d,a lda msb ral sta msb dcr m pop h rz mvi a,0 aci 0 dad h mov b,h add l lhld msb1 sub l mov c,a mov a,b sbb h mov b,a push b jnc div26 dad b xthl ; div26: lxi h,msb2 cmc jmp div25 page ****************************** *** "CLEAR CONSOLE DISLAY" *** ****************************** ; Clear console to foreground spaces. cls: mvi a,lead$in ; lead in call co mvi a,clr$co ; clear to foreground spaces jmp co **************************** *** "CLEAR DISPLAY LINE" *** **************************** cline: mvi a,0 ; starting column sta column lxi h,set$cur ; set cursor call text mvi a,lead$in ; lead in byte call co mvi a,end$ln ; clear to end of line call co ret ************************* *** "FATAL ERROR MSG" *** ************************* fatal: call cline ; clear line mvi a,30 ; column position sta column lxi h,set$cur call text lxi h,me2 ; Fatal error msg call text ret page ****************************** *** "PRINT STRING OF TEXT" *** ****************************** ; Enter with "HL" pointing to text string, ; terminate string with Null. ; ; Direction cursor position is used for displays. ; The value (-1) at the start of string indicates ; that column and row position will follow. ; e.g. ; db -1,50,10,'NOW IS THE TIME' ; ^ ^ ^ ; | | |_Row position (add bias if needed) ; | |_Column position (add bias if needed) ; |_Flag (send console lead-in sequence. text: mov a,m ; load char. ora a ; end of string? rz ; yes cpi -1 ; position cursor? jz text1 ; yes inx h ; next char. call co ; output jmp text ; text1: inx h ; move passed command mvi a,lead$in ; leading for console call co ; issue. mvi a,add$cur ; address cursor call co mov a,m ; column position... inx h call co mov a,m ; row position call co inx h jmp text page ************************* *** "CENTERING CHECK" *** ************************* ; ; Centering test requires the FDC to read ; all the sectors before diskette centering ; is consider OK. center: lxi h,cen$tbl ; track table shld temp lxi h,me9 ; tracks with mvi b,'D' ; limit call inp$trk ; seek track call cls ; clear display lxi h,me10 ; centering msg. call text lxi h,me15 ; frame call text lxi h,me11 ; New track msg call text ; center1: mvi a,10 ; set row position sta row call rd$trk ; read centering track jc center3 ; fatal error.. call cline ; clear line mvi a,30 ; set cursor... sta column ; column position lxi h,set$cur call text lda diff ; must = 0 ora a lxi h,me3 ; "RE-CLAMP DISKETTE" jnz center2 mov a,c cpi tsec ; all sec read? jnz center2 lxi h,me4 ; "CENTERING OK" ; center2: call text call cstat ; abort? jz center1 call ci cpi ' ' ; new track? jnz center1 ; no... jmp center ; yes.. ; center3: call fatal ; fatal error jmp center2 page ********************************* *** "AZIMUTH ALIGNMENT CHECK" *** ********************************* azimuth: call cls ; clear display... mvi a,76 ; seek to azimuth track call track ; move... lxi h,me12 ; type of test msg call text lxi h,me15 ; frame call text mvi a,10 ; set display row sta row ; azimuth1: lxi h,azi$tab ; set translation table shld xpoint ; pointers shld ypoint call rd$trk ; read azimuth track jc azimuth3 ; fatal error... call cline ; clear line mvi a,20 ; Display negative angle sta column lxi h,set$cur ; set cursor call text mvi a,'-' ; direction of angle call co ; output... mvi a,' ' ; space call co lhld ypoint ; translation mov e,m ; data negative... mvi d,0 call pnum ; display lxi h,me5 ; print minutes call text mvi a,45 ; Display Positive angle sta column lxi h,set$cur call text mvi a,'+' ; direction of angle call co ; output... mvi a,' ' ; space call co lhld xpoint ; translation mov e,m ; data positive.. mvi d,0 call pnum ; display lxi h,me5 ; print minutes call text ; azimuth2: call cstat ; abort? jz azimuth1 call ci ; test... jmp azimuth1 ; no.. ; ; Fatal error Has occurred ; azimuth3: call fatal ; fatal read error jmp azimuth2 page ******************************** *** "RADIAL ALIGNMENT CHECK" *** ******************************** radial: lxi h,rh$tbl ; table pointer shld temp lxi h,me7 ; track display.. mvi b,'G' ; limit call inp$trk ; select track and seek call cls lxi h,me8 ; print scale... call text lxi h,me11 ; Space bar msg call text ; radial1: mvi a,11 ; set row position sta row ; lxi h,rad$pos ; radial positive shld xpoint ; cursor table ; lxi h,rad$neg ; radial negative shld ypoint ; cursor table ; call rd$trk ; read radial track jc radial4 ; Fatal error has occurred call cline ; clear line (1) lda row push psw inr a ; clear line (2) sta row call cline pop psw ; reset line position sta row lhld ypoint ; negative mov a,m sta column ; position cursor mov b,a lxi h,set$cur call text mvi a,'^' ; set pointer call co lhld xpoint mov a,m ; positive position sta column mov c,a ; save cursor position lxi h,set$cur ; set cursor call text mvi a,'^' call co mov a,b sta column ; reset column position lda row ; down one line inr a sta row page ************************************ *** "SET POINTERS AND DRAW LINE" *** ************************************ ; used to draw the graphic display of the ; radial error. lxi h,set$cur ; position cursor call text mov a,c sub b ; line length dcr a ; less (1) mov b,a mvi a,'|' ; pointer... call co ; radial2: mvi a,'_' ; jointing line call co dcr b ; line length -1 jnz radial2 mvi a,'|' call co ; radial3: call cstat ; check for abort jz radial1 ; read again call ci ; new track? cpi ' ' jnz radial1 ; no... jmp radial ; new track... **************************** *** "FATAL RADIAL ERROR" *** **************************** radial4: call cline ; clear display lda row ; next line inr a sta row call cline call fatal ; fatal read error jmp radial3 ; abort? page ********************************** *** "STEPPER HYSTERESIS CHECK" *** ********************************** ; ; This routine uses one of the progressive offset ; tracks to determine the stepper motor hysteresis. hyster: lxi h,rh$tbl ; table pointer shld temp lxi h,me7 ; track msg mvi b,'G' ; limit call inp$trk ; seek track mvi a,10 ; set row sta row call offset ; offset from call cls ; selected track. lxi h,me14 ; display test call text lxi h,me15 ; frame call text lxi h,me11 ; new track Msg. call text ; hyster1: lda bais ; offset from track mov b,a lda ctrk ; save current track sta savtrk add b ; add bais to current track cpi ttrk ; within limits? jc hyster2 ; OK! mvi a,ttrk ; set last track ; ; Move to (ID) inside diameter hyster2: call track ; seek to track lda savtrk ; back to test track call track ; seek... call rd$trk ; read track... jc hyster8 ; fatal error!!! lda diff ; difference sta hyerr ; save the difference ; Move to (OD) outside Diameter lda bais ; tracks to move mov b,a lda ctrk ; current track sub b jnc hyster4 ; Ok to move xra a ; set to track (0) page ; hyster4: call track ; seek to track lda savtrk ; back to test track call track call rd$trk ; read track jc hyster8 ; fatal Error!! lda hyerr ; load error First mov c,a ; read operation lda diff ; last reading sub c jp hyster6 cma inr a ; hyster6: call hyster9 ; hyster7: call cstat ; abort? jz hyster1 ; re-test call ci cpi ' ' ; new parameters jz hyster jmp hyster1 ; new track and offset ; hyster8: call fatal ; fatal read error call home ; recal.drive jmp hyster7 page ********************************** *** "DISPLAY HYSTERESIS ERROR" *** ********************************** ; ; Presently setup for 48 tpi drives ; with increments in .5 millinches. hyster9: push psw ; save error call cline ; clear display mvi a,25 ; set column sta column lxi h,set$cur call text lxi h,me16 ; Hysteresis error msg call text pop psw ora a jz hyster11 mov c,a ; count mvi b,5 ; increments xra a ; clear acc. ; hyster10: add b daa ; decimal adjust dcr c jnz hyster10 ; hyster11: push psw ani 0f0h ; mask upper nibble rar!rar!rar!rar adi '0' ; add ascii bais call co mvi a,'.' ; decimal point call co pop psw ani 0fh adi '0' call co ret page ********************** *** "INDEX TIMING" *** ********************** ; ; This function computes the time from leading ; edge of index to first sector ID mark ; and displays it in 10.0 Us. increments ; note: ; (Dysan AAD disk) is used for reference. index: mvi a,10 ; set row sta row lxi h,ix$tbl ; track table shld temp lxi h,me13 ; track locations mvi b,'C' call inp$trk ; move to Index track call cls ; clear display.. lxi h,me17 ; display scale call text lxi h,me15 call text lxi h,me11 call text ; index1: lxi h,0 ; clear counter shld temp mvi c,5 ; average (5) readings ; index2: call clpend ; clear FDC call prg$dma ; program controller lxi d,0 ; clear counter ; index3: in stat ; wait for next Index ani 2 jnz index3 ; Compute time from index to ID index4: in stat ; loop until next ani 2 ; index... jz index4 ; ; Read address.. ; nop ; 1.00 mvi a,raddr ; 1.75 out cmd ; 2.75 call delay ; [ 50 usec ] mvi a,sdma ; 1.75 out dma ; 2.75 page ; ; 10 Usec Test cnt. loop index5: inx d ; 1.50 [ counter ] inx h ; 1.50 in stat ; 2.75 ani 1 ; 1.75 jnz index5 ; 2.50 ; index6: lxi h,6 ; adj. over head dad d ; error (60usec) xchg lhld temp dad d ; add cnt shld temp dcr c ; next reading jnz index2 xchg lxi h,5 ; divide by 5 call div16 dad d ; add remainder xchg lxi h,0 ; counter... lda secbuf+2 ; must contain sec (1) ID cpi 1 jnz index9 ; out of range mvi a,10 ; loop time * cnt index7: dad d dcr a jnz index7 lxi d,ref ; Timing ref call subde ; to id mark xchg ; (200 usec) AAD jnc index8 mov a,e cma mov e,a mov a,d ; negate "DE" cma mov d,a inx d lxi h,200 ; 200 - error call subde jnc index9 lxi h,0 ; out of range jmp index9 ; index8: lxi h,200 ; 200 + error dad d ; index9: xchg push d call cline ; clear line mvi a,25 sta column lxi h,set$cur ; position cursor call text lxi h,me18 ; time in MS. call text pop d call pnum ; display time... call cstat ; abort? jz index1 ; re-test call ci ; esc? cpi ' ' ; new track? jz index ; yes.. jmp index1 ; new track... page ***************************** *** "CHECK SPINDLE SPEED" *** ***************************** ; ; All timing is based on 4mhz Z80 Cpu ; rpm: call cls ; clear display lxi h,me19 ; test preformed call text lxi h,me15 ; frame... call text mvi a,10 ; set row sta row ; rpm1: call rpm2 ; compute time in 100us increments shld temp ; store count call cline ; clear line mvi a,19 ; set cursor sta column lxi h,set$cur call text lhld temp xchg ; convert to milliseconds lxi h,10 call div16 push h ; Save remainder call pnum mvi a,'.' ; decimal point call co pop h xchg call pnum ; fraction lxi h,me20 ; milliseconds msg call text mvi a,50 sta column lxi h,set$cur call text lhld temp ; convert to RPM mvi a,9 ; divide By 600,000 lxi d,27c0h call div24 push h ; remainder call pnum mvi a,'.' ; fraction call co pop h xchg call pnum lxi h,me21 ; rpm msg call text call cstat ; abort? jz rpm1 ; No.. call ci ; Esc key? jmp rpm1 ; No.. page ******************************* *** "INDEX TO INDEX TIMING" *** ******************************* ; ; returns time in 100 Us increments to caller ; in "HL" regs. rpm2: call clpend ; Clear pending commands lxi h,0 ; Clear Counter rpm3: in stat ; Loop Until Index ani 2 ; Mask All But Index Bit jnz rpm3 ; No Index rpm4: in stat ; if Index... ani 2 ; Wait for No Index jz rpm4 ; In Index Hole ; Add index hole to count rpm5: call rpm7 ; 4.25 in stat ; 2.75 ani 2 ; 1.75 jnz rpm5 ; 2.50 ; Total = 11.25 ; Count until next Index rpm6: call rpm7 ; 4.25 in stat ; 2.75 ani 2 ; 1.75 jz rpm6 ; 2.50 ret ; total = 11.25 ************************* *** "RPM TIMING LOOP" *** ************************* ; ; The loop time must be adjusted for 100us ; increments. ; ; note: "RPM5 and RPM6" loop time must be counted. ; rpm7: inx h ; 1.50 mvi a,22 ; 1.75 ; rpm8: dcr a ; 1.00 (22 * 1.00) = 22 Usec jnz rpm8 ; 2.50 (22 * 2.50) = 55 Usec inx d ; 1.50 inx d ; 1.50 inx d ; 1.50 inx d ; 1.50 ret ; 2.50 ; total = 88.75 page ************************ *** "READ DDD TRACK" *** ************************ ; ; Att: Main read routine for program. ; ============================== ; ; Reads the Positive and Negative offset ; sectors and returns pointers to the ; translation tables set by caller. ; rd$trk: mvi c,lpos ; last sector mvi a,1 ; beginning sector positive call rd$sec ; read positive offsets cpi 1 ; unable to read jz rd$trk2 ; first sec? sta diff ; store last sector tested mvi c,lneg mvi a,2 ; beginning sector negative call rd$sec ; read negative offsets cpi 2 ; fatal error? jz rd$trk2 ; set error flag ; ; Positive sector Translation ; lda diff inr a ; adj. sector Num. sui 4 rar ; divide by two lhld xpoint ; translate Table pointer mvi d,0 ; setup for Offset mov e,a dad d ; add offset shld xpoint ; set pointer ; ; Negative Sector Translation in sec ; last sector sui 4 rar ; divide by two mov c,a sub e ; diff. for Hysteresis sta diff mov e,c ; offset lhld ypoint ; translation table pointer dad d ; offset in table shld ypoint ; set pointer ora a ; clear carry ret ; Set fatal error Flag, caller processes ; the error. rd$trk2: stc ; carry = Fatal error ret page ******************************************* *** "READ SECTORS BY INCREMENTS OF TWO" *** ******************************************* ; ; Enter with first sector to be read in 'A' reg. ; Returns to caller on Error or Last sector. ; note: ; Z flag set if good read else Nz rd$sec: call read ; read sector in sec ; current sector rnz adi 2 out sec cmp c ; last sec? rz ; yes... jmp rd$sec ******************************************************** *** "THE FOLLOWING ARE HARDWARD DEPENDENT ROUTINES" *** ******************************************************** ; ********************** *** "DRIVE SELECT" *** ********************** ; ; The drive select routine must be expanded ; for selected systems. select: mvi a,21h ; select bits out dsel ; select drive... jmp home ; home drive ******************************* *** "SEEK HEAD(S) TO TRACK" *** ******************************* ; ; Enter with new track location in ; 'A' register. track: out data ; new track call clpend ; clear FDC mvi a,seek+rate ; seek command + step rate ; track1: out cmd ; issue... call delay ; delay for FDC ; track2: in stat ; busy ? rrc ; test jc track2 ; still busy... mvi a,sdelay ; set seek delay bit sta dflag in trk ; set current track sta ctrk ret page *************************************** *** "RESTORE HEAD(S) TO TRACK ZERO" *** *************************************** home: call clpend ; clear FDC mvi a,restore+rate ; restore command + step rate jmp track1 ; issue command... ***************************** *** "READ SECTOR ROUTINE" *** ***************************** ; Enter this routine with the sector to ; be read in the 'A' register. ; ; This routine will keep trying to read ; the sector until retry count equals zero. ; ; The 1793 controller has a built-in automatic ; four retries to read ID, so the value set in ; the equate (RETRY) is equal to [ 4 * retry + 1]. read: out sec ; set sector mvi e,retry ; to read ; read1: call clpend ; clear FDC call prg$dma ; program "DMA" controller lda dflag ; seek delay flag ori rsec ; read sector command out cmd ; issue.. mvi a,sdma ; start transfer out dma call comp ; transfer completed? ; read2: xra a ; clear seek delay sta dflag in stat ; good read? ora a rz ; yes... dcr e ; count off retries jnz read1 ; try again in stat ; return status ora a ret page ************************************** *** "WAIT FOR END OF DMA TRANSFER" *** ************************************** comp: call delay ; before each check in stat ; Completed Transfer? rrc rnc ; YES! jmp comp ******************************** *** "PROGRAM DMA CONTROLLER" *** ******************************** prg$dma: mvi b,15 ; Bytes Count lxi h,cmd$tbl ; Command Table ; prg$dma1: mov a,m ; load out dma ; write to controller inx h dcr b ; -1 jnz prg$dma1 ret ************************************** *** "COMMAND TABLE DMA CONTROLLER" *** ************************************** ; This data is used to program Zilog's ; z80 DMA controller. cmd$tbl: db 0c3h ; Re-Set DMA Controller db 8bh ; Clear Block Counter db 79h ; Recieve Block dw secbuf ; Address To Store Block dw 256 ; Block Size db 14h ; Define Port (B) Address db 28h ; Define Port (A) Address db 85h db data ; Data Reg FDC db 8ah ; Set DMA Controller Active HIGH db 0cfh db 3 ; Data ----> Memory db 0cfh page ************************************ *** "CLEAR PENDING COMMANDS FDC" *** ************************************ ; ; Clears the floppy controller of any ; pending commands. clpend: mvi a,clear ; clear FDC command out cmd ; issue... *************************************** *** "FDC DELAY TO PROCESS COMMANDS" *** *************************************** ; ; This delay must be adjusted for different ; clock speeds. 50 usec delay loop. ; ; Note: ; If altered, Ajust Index Timining Routine. delay: ; 4.25 mvi a,fdelay ; 1.75 delay1: dcr a ; 11.00 jnz delay1 ; 27.50 nop ; 1.00 nop ; 1.00 nop ; 1.00 ret ; 2.50 page ******************************** *** "RADIAL TRANSLATE TABLE" *** ******************************** ; Cursor Positioning table for radial ; alignment test. rad$neg: db 38 ; 1 millinch db 36 ; 2 " " db 34 ; 3 " " db 32 ; 4 " " db 30 ; 5 " " db 28 ; 6 " " db 26 ; 7 " " db 24 ; 8 " " db 22 ; 9 " " db 20 ; 10 " " db 17 ; 11 " " db 14 ; 12 " " db 11 ; 13 " " rad$pos: db 40 ; 1 millinch db 42 ; 2 " " db 44 ; 3 " " db 46 ; 4 " " db 48 ; 5 " " db 50 ; 6 " " db 52 ; 7 " " db 54 ; 8 " " db 56 ; 9 " " db 58 ; 10 " " db 61 ; 11 " " db 64 ; 12 " " db 67 ; 13 " " ********************************* *** "AZIMUTH TRANSLATE TABLE" *** ********************************* azi$tab: db 18 ; head azmuith angle db 20 ; +/- minutes db 22 db 24 db 26 db 28 db 30 db 32 db 34 db 36 db 38 db 40 db 42 page ************************** *** "PROGRAM MESSAGES" *** ************************** me1: db -1,27,1,'Drive Diagnostic Program' db -1,31,2,'CP/M 80 Ver 1.0' db -1,23,4,'( Dysan Corp. Santa Clara, Ca. )' db -1,18,5,'<*>======================================<*>' db -1,18,6,'<*> DIAGNOSTIC COMMAND MENU <*>' db -1,18,7,'<*>======================================<*>' db -1,18,8,'<*> <*>' db -1,18,9,'<*> R = Radial H = Hysteresis <*>' db -1,18,10,'<*> <*>' db -1,18,11,'<*> A = Azimuth I = Index Timing <*>' db -1,18,12,'<*> <*>' db -1,18,13,'<*> C = Centering S = Spindle Speed <*>' db -1,18,14,'<*> <*>' db -1,18,15,'<*> E = Exit Program <*>' db -1,18,16,'<*> <*>' db -1,18,17,'<*><*><*<*><*><*><*><*><*><*><*><*><*><*><*>' db -1,18,19,'SELECTION? ....',bs,0 me2: db 'FATAL READ ERROR',0 me3: db 'RE-CLAMP DISKETTE ....',bs,0 me4: db 'CENTERING OK ....',bs,0 me5: db ' Minutes',0 me6: db -1,25,2,'<>==========================<>' db -1,25,3,'<> TRACK OFFSET <>' db -1,25,4,'<>==========================<>' db -1,25,5,'<> <>' db -1,25,6,'<> 0 ---> 76 <>' db -1,25,7,'<> <>' db -1,25,8,'<>==========================<>' db -1,25,9,'<> Cancels Test <>' db -1,25,10,'<>==========================<>' db -1,25,12,'OFFSET? ...',bs,0 me7: db -1,25,2,'<>==========================<>' db -1,25,3,'<> TRACK SELECTION <>' db -1,25,4,'<>==========================<>' db -1,25,5,'<> <>' db -1,25,6,'<> A = (0) D = (41) <>' db -1,25,7,'<> <>' db -1,25, 8,'<> B = (3) E = (70) <>' db -1,25, 9,'<> <>' db -1,25,10,'<> C = (38) F = (73) <>' db -1,25,11,'<> <>' db -1,25,12,'<>==========================<>' db -1,25,13,'<> Cancels Test <>' db -1,25,14,'<>==========================<>' db -1,25,16,'TRACK? ...',bs,0 me8: db -1,24,5,'--- RADIAL ALIGNMENT CHECK ---' db -1,10,9,'Away',-1,36,9,'Spindle',-1,63,9,'Toward' db -1,10,10,'13 12 11 10 9 8 7 6 5 4 3 2 1' db '-1 2 3 4 5 6 7 8 9 10 11 12 13',0 page me9: db -1,25,2,'<>==========================<>' db -1,25,3,'<> TRACK SELECTION <>' db -1,25,4,'<>==========================<>' db -1,25,5,'<> <>' db -1,25,6,'<> A = (35) B = (44) <>' db -1,25,7,'<> <>' db -1,25,8,'<> C = (47) <>' db -1,25,9,'<> <>' db -1,25,10,'<>==========================<>' db -1,25,11,'<> Cancels Test <>' db -1,25,12,'<>==========================<>' db -1,25,14,'TRACK? ...',bs,0 me10: db -1,23,5,'--- DISKETTE CENTERING CHECK ---',0 me11: db -1,23,14,'Press For New Track',0 me12: db -1,24,5,'--- AZIMUTH ALIGNMENT CHECK ---' db -1,25,14,' Will Cancel AZIMUTH Check',0 me13: db -1,25,2,'<>==========================<>' db -1,25,3,'<> TRACK SELECTION <>' db -1,25,4,'<>==========================<>' db -1,25,5,'<> <>' db -1,25,6,'<> A = (0) B = (76) <>' db -1,25,7,'<> <>' db -1,25,8,'<>==========================<>' db -1,25,9,'<> Cancels Test <>' db -1,25,10,'<>==========================<>' db -1,25,12,'TRACK? ...',bs,0 me14: db -1,28,5,'--- HYSTERESIS CHECK ---',0 me15: db -1,15,8,'##################################################' db -1,15,12,'##################################################',0 me16: db 'Positioner Hysteresis = ',0 me17: db -1,25,5,'--- INDEX TO DATA TIME ---',0 me18: db 'Index To ID In Usecs = ',0 me19: db -1,27,5,'--- SPINDLE SPEED CHECK ---' db -1,25,14,' Will Cancel RPM Check',0 me20: db ' Milliseconds',0 me21: db ' RPM',0 page ************************* *** "POSITION CURSOR" *** ************************* set$cur db 0ffh column ds 1 ; set column row ds 1 ; set row db 0 ; terminator *********************************** *** "PROGRAM VARIABLE STOREAGE" *** *********************************** temp ds 2 ; temp storage diff ds 1 ; 1st - 2nd read ctrk ds 1 ; current track savtrk ds 1 ; temp storage Hysteresis test dflag ds 1 ; seek delay flag point ds 2 ; table pointer xpoint ds 2 ; table pointer positive ypoint ds 2 ; table pointer negative xoff ds 1 ; positive offset yoff ds 1 ; negative offset bais ds 1 ; bais from test track (Hysteresis) hyerr ds 1 ; hysteresis error on first reading ; ; Storage area for 16/24 bit divide routine ; msb ds 1 msb1 ds 2 msb2 ds 2 buffer ds 4 ; console input buffer secbuf ds 256 ; sector buffer ds 100 ; stack space stack equ $ ; top down... page