; ;<>******************************************************<> ;<>* *<> ;<>* D D D *<> ;<>* *<> ;<>* Dysan Corporation *<> ;<>* C.E. Division *<> ;<>* 1244 Reamwood Avenue *<> ;<>* Sunnyvale, Cal. 94086 *<> ;<>* 408-734-1624 *<> ;<>* *<> ;<>* VERSION [ 2.0 ] *<> ;<>* *<> ;<>******************************************************<> ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ; File ddd.asm ;===================================== ; SEE Also DDD.DOC ; for credits ;===================================== ; 01/05/84 ; This file is a modification of the original ; DDD1.ASM which has been modified to run using ; a Tarbell double-denisty (with DMA) controller ; and a Soroc IQ-120 terminal (at 19.2k baud) ; It can be assembled with Digital Research's ; ASM.COM ; Much thanks is given to R.Kely of Dysan for ; his efforts and assistance. ; If any modifications are made or errors found ; it would be much appreciated if the information ; was passed on to R.Beach c/o ; N.O.C.C.C. RCPM ; Orange, Calif. ; 24hrs (300 buad) ; (714) 633-5240 ;======================================================= ; 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. ; ; 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 }. ; wboot equ 0 ; warm boot address bdos equ 5 *************************** *** "CONSOLE FUNCTIONS" *** *************************** ; for Soroc 120 at 19.2k baud lead$in equ 1bh ; console lead-in add$cur equ 3dh ; address cursor command clr$co equ 2ah ; clear to foreground spaces end$ln equ 54h ; clear to end of line flg equ 0ffh ; cursor flag **************************************** *** "FLOPPY CONTROLLER PORT EQUATES" *** **************************************** ; tarbell double-density (with DMA) 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. dsel equ fdc+4 ; drive select intrq equ fdc+5 ; adr0 equ 0e0h ; dma base port wct0 equ adr0+1 ; dma word count port dmacmd equ adr0+8 ; dma command port ************************************ *** "FLOPPY CONTROLLER COMMANDS" *** ************************************ clear equ 0d0h ; clear FDC sdma equ 41h ; Start Dma Transfer rcmd equ 80h ; read sector raddr equ 0c0h ; read address seek equ 1ch ; seek track with verify restore equ 1 ; home Head(s) sdelay equ 4 ; seek delay flag ************************************* *** "FLOPPY CONTROLLER VARIABLES" *** ************************************* rate equ 1 ; 0=3ms, 1=6ms, 2=15ms 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 608 ; reference time (single Den) ****************************** *** "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 org 100h *************************** *** "MAIN PROGRAM LOOP" *** *************************** lxi sp,stack call select ; make drive select first 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 'D' ; "Drive select" jz select cpi 'E' ; "Exit to DOS" jz exit mvi a,bell ; Not valid call co jmp main ; try again... ********************** *** " 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 mvi c,11 call bdos pop b pop d pop h ora a ret *********************** *** "CONSOLE INPUT" *** *********************** ; ; Returns character in "A" reg. ci: push h ; Save all registers push d push b mvi c,1 call bdos 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 ************************ *** "CONSOLE OUTPUT" *** ************************ ; ; Enter with character in "A" reg. co: push h ; save all registers push d push b mov e,a mvi c,6 call bdos pop b pop d pop h ret ******************** *** "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 cpi cr ; end of Line? rz ; Yes! lxi h,buffer+4 ; end of Buffer call dehl ; check jnz gl1 ; No! ; 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 ******************************* *** "INPUT TRACK LOCATIONS" *** ******************************* ; Input track locations for Radial ; Hysteresis,Centering and Index tests. ; "B" contents Upper Limit upon entry. inp$trk: push b ; save upper limit call cls ; clear display... call text ; inp$trk1: call ci ; waiting... pop b ; get upper limit back 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 ******************************* *** "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 ************************************************ *** "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 ********************************** *** "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 ****************************** *** "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 call co ;routine added to give terminal time to respond push h lxi h,stall call text pop h ret **************************** *** "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 ****************************** *** "PRINT STRING OF TEXT" *** ****************************** ; Enter with "HL" pointing to text string, ; terminate string with Null. ; ; Direction cursor position is used for displays. ; The value (flg) at the start of string indicates ; that row and column position will follow. ; e.g. ; db flg,10,50,'NOW IS THE TIME' ; ^ ^ ^ ; | | |_Column position ; | |_Row position ; |_Flag (send console lead-in sequence.) text: mov a,m ; load char. ora a ; end of string? rz ; yes cpi flg ; position cursor? jz text1 ; yes inx h ; next char. call co ; output jmp text ; ;soroc needs an offset of 32 ; 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... adi 32 ; add offset inx h call co mov a,m ; row position adi 32 ; add offset call co inx h jmp text ************************* *** "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 ********************************* *** "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 ******************************** *** "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 ; at row #5 lxi h,me11 ; Space bar msg call text ; at row #14 ; 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 ; row = 11 push psw ; save on stack inr a ; clear line (2) sta row ; row = 12 call cline ; clear line pop psw ; reset line position sta row ; row 11 again lhld ypoint ; negative mov a,m sta column ; position cursor mov b,a ; b = left mark lxi h,set$cur call text mvi a,'^' ; set pointer call co lhld xpoint mov a,m ; positive position sta column mov c,a ; c = right mark lxi h,set$cur ; set cursor call text mvi a,'^' call co mov a,b ; get left mark back sta column ; reset column position lda row ; down one line inr a sta row ************************************ *** "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 ; right mark sub b ; line length = c - b 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? ********************************** *** "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) ; 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 ********************************** *** "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 ********************** *** "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. ; note-note: Tarbell has a hardware head-delay ; so sector two was used a the read sector. ; ; NOTE: Tarbell controller has a "hardwired" head ; delay, so it is necessary to "look" at ; sector #2 instead of #1. End results are ; the same if the added time is taken into ; consideration. (rdb) ; 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 mvi a,sdma ; 1.75 out dmacmd ; 2.75 ; 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,10 ; divide by 10 call div16 dad d ; add remainder xchg lxi h,0 ; counter... lda secbuf+2 ; must contain sec (2) ID cpi 2 jnz index9 ; out of range mvi a,2 ; 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,0 ; was 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... ***************************** *** "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.. ******************************* *** "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 ************************ *** "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 ******************************************* *** "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" *** ********************** select: call cls ; clear screen lxi h,me22 ; print message call text call ci cpi 'A' ; less than a jc serr cpi 'E' ; greater that d jnc serr select1: sui 'A' add a add a add a add a ani 1011$1000b ; side 0 only ori 8 ; set density out dsel ; select drive... jmp home ; home drive serr: mvi a,bell call co jmp select ******************************* *** "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 *************************************** *** "RESTORE HEAD(S) TO TRACK ZERO" *** *************************************** home: call clpend ; clear FDC mvi a,restore+rate ; restore command + step rate out cmd ; issue it jmp main ; show main menu ***************************** *** "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: sta sect mvi e,retry ; to read ; read1: call clpend ; clear FDC call prg$dma ; program "DMA" controller lda sect ; get sector to read out sec ; send it mvi a,sdma ; issue dma cmd out dmacmd ; send to dma mvi b,rcmd ; get read command call hdld ; load the head ora b ; or in the read cmd out cmd ; send to FDC call dmalop ; 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 hdld: in cmd ani 20h mvi a,0 rz mvi a,4 ret ************************************** *** "WAIT FOR END OF DMA TRANSFER" *** ************************************** dmalop: in intrq ; check intrq port rlc ; bit 7 jc dmalop ; loop if busy xra a ; clear dma chip out dmacmd ret ******************************** *** "PROGRAM DMA CONTROLLER" *** ******************************** ; ; setup 8257 dma controller prg$dma: xra a ; clear dma chip out dmacmd ; output it mvi a,0d0h ; force intrp. cmnd out cmd lhld dmared ; read cmd + read length mov a,l ; get read length (count) out wct0 mov a,h ; get read command out wct0 lxi h,secbuf ; pointer to buffer mov a,l ; low addr. byte out adr0 mov a,h ; hi addr. byte out adr0 lda sect ; sector # to read out sec ret ************************************ *** "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 ******************************** *** "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 ; ************************** *** "PROGRAM MESSAGES" *** ************************** ME1: DB FLG,2,27,'DRIVE DIAGNOSTIC PROGRAM' DB FLG,3,31,'CP/M 2.2 VER 2.0' DB FLG,5,16,'<*>======================================<*>' DB FLG,6,16,'<*> DIAGNOSTIC COMMAND MENU <*>' DB FLG,7,16,'<*>======================================<*>' DB FLG,8,16,'<*> <*>' DB FLG,9,16,'<*> R = RADIAL H = HYSTERESIS <*>' DB FLG,10,16,'<*> <*>' DB FLG,11,16,'<*> A = AZIMUTH I = INDEX TIMING <*>' DB FLG,12,16,'<*> <*>' DB FLG,13,16,'<*> C = CENTERING S = SPINDLE SPEED <*>' DB FLG,14,16,'<*> <*>' DB FLG,15,16,'<*> D = DRIVE SEL E = EXIT PROGRAM <*>' DB FLG,16,16,'<*> <*>' DB FLG,17,16,'<*><*><*<*><*><*><*><*><*><*><*><*><*><*><*>' DB FLG,19,16,'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 FLG,2,18,'<>==========================<>' DB FLG,3,18,'<> TRACK OFFSET <>' DB FLG,4,18,'<>==========================<>' DB FLG,5,18,'<> <>' DB FLG,6,18,'<> 0 ---> 76 <>' DB FLG,7,18,'<> <>' DB FLG,8,18,'<>==========================<>' DB FLG,9,18,'<> CANCELS TEST <>' DB FLG,10,18,'<>==========================<>' DB FLG,12,18,'OFFSET? ...',BS,0 ME7: DB FLG,2,18,'<>==========================<>' DB FLG,3,18,'<> TRACK SELECTION <>' DB FLG,4,18,'<>==========================<>' DB FLG,5,18,'<> <>' DB FLG,6,18,'<> A = (0) D = (41) <>' DB FLG,7,18,'<> <>' DB FLG,8,18,'<> B = (3) E = (70) <>' DB FLG,9,18,'<> <>' DB FLG,10,18,'<> C = (38) F = (73) <>' DB FLG,11,18,'<> <>' DB FLG,12,18,'<>==========================<>' DB FLG,13,18,'<> CANCELS TEST <>' DB FLG,14,18,'<>==========================<>' DB FLG,16,18,'TRACK? ...',BS,0 ME8: DB FLG,5,24,'--- RADIAL ALIGNMENT CHECK ---' DB FLG,9,10,'AWAY',FLG,9,36,'SPINDLE',FLG,9,63,'TOWARD' DB FLG,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 ME9: DB FLG,2,18,'<>==========================<>' DB FLG,3,18,'<> TRACK SELECTION <>' DB FLG,4,18,'<>==========================<>' DB FLG,5,18,'<> <>' DB FLG,6,18,'<> A = (35) B = (44) <>' DB FLG,7,18,'<> <>' DB FLG,8,18,'<> C = (47) <>' DB FLG,9,18,'<> <>' DB FLG,10,18,'<>==========================<>' DB FLG,11,18,'<> CANCELS TEST <>' DB FLG,12,18,'<>==========================<>' DB FLG,14,18,'TRACK? ...',BS,0 ME10: DB FLG,5,23,'--- DISKETTE CENTERING CHECK ---',0 ME11: DB FLG,14,23,'PRESS FOR NEW TRACK',0 ME12: DB FLG,5,24,'--- AZIMUTH ALIGNMENT CHECK ---' DB FLG,14,25,' WILL CANCEL AZIMUTH CHECK',0 ME13: DB FLG,2,18,'<>==========================<>' DB FLG,3,18,'<> TRACK SELECTION <>' DB FLG,4,18,'<>==========================<>' DB FLG,5,18,'<> <>' DB FLG,6,18,'<> A = (0) B = (76) <>' DB FLG,7,18,'<> <>' DB FLG,8,18,'<>==========================<>' DB FLG,9,18,'<> CANCELS TEST <>' DB FLG,10,18,'<>==========================<>' DB FLG,12,18,'TRACK? ...',BS,0 ME14: DB FLG,5,28,'--- HYSTERESIS CHECK ---',0 ME15: DB FLG,8,15,'##################################################' DB FLG,12,15,'##################################################',0 ME16: DB 'POSITIONER HYSTERESIS = ',0 ME17: DB FLG,5,25,'--- INDEX TO DATA TIME ---',0 ME18: DB 'INDEX TO ID IN USECS = ',0 ME19: DB FLG,5,27,'--- SPINDLE SPEED CHECK ---' DB FLG,14,25,' WILL CANCEL RPM CHECK',0 ME20: DB ' MILLISECONDS',0 ME21: DB ' RPM',0 ME22: DB FLG,2,25,'<>=============================<>' DB FLG,3,25,'<> DRIVE SELECTION <>' DB FLG,4,25,'<>=============================<>' DB FLG,5,25,'<> <>' DB FLG,6,25,'<> A - B - C - D <>' DB FLG,7,25,'<> <>' DB FLG,8,25,'<>=============================<>' DB FLG,9,25,'<> Cancels Test <>' DB FLG,10,25,'<>=============================<>' DB FLG,12,25,'SELECT? ',0 STALL: DB 1,1,1,1,1,1,0 ;just to kill some time ************************* *** "POSITION CURSOR" *** ************************* set$cur db 0FFH row ds 1 ; set row column ds 1 ; set column db 0 ; terminator *********************************** *** "PROGRAM VARIABLE STOREAGE" *** *********************************** temp ds 2 ; temp storage diff ds 1 ; 1st - 2nd read ctrk ds 1 ; currnet 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 dmared dw 040FFh ; dma read default sect ds 1 ; sector to be read cur1 ds 1 ; temp cursor storage ; ; 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... END