ignatz@ihuxx.UUCP (Dave Ihnat, Chicago, IL) (12/30/83)
As usual, delete all lines up to and including the line of dashes, and execute the remainder as a shellscript. Good luck! Dave Ihnat ihuxx!ignatz ------------------------------------------------------------ echo x - dddread.me cat >dddread.me <<'!E!O!F!' ******************************************************************************* ******************************************************************************* DDD Version 1.1 With this program and Dysan Corporation's "Digital Diagnostic Diskette"tm ($30 for SS and $40 for DS as of 1983...) You can comprehensively test, verify, and align the heads of your flexible diskette drive, under your own oper- ating conditions, without need for expensive oscilloscopes and drive exercisers, to practically the same precision achievable by the usual analog methods. Any time you suspect a bug in one of your drives, you can determine which drive is at fault and what the problem is. No more expensive shot-in-the-dark trips to the service center; no more intermittent bugs which won't appear for the serviceman. Takes the mystery out of flexible diskette systems!! ******************************************************************************* ******************************************************************************* System Requirements: The DDDtm is available for all flexible diskette formats, and works independently of any operating system. This program is built around CP/M and the 1793 floppy disk controller chip, and can be easily configured and assembled (with ASM - no macros... ) for most CP/M systems. The screen displays require an addressable cursor and clear screen facility from your terminal, but you could display the test results without the trick graphics if you don't have these capabilities. Operator Requirements: You will have to know how to edit and assemble 8080 assembly language. Step-by-step instructions for customizing the program will be published in Dr. Dobb's Journal, probably in November 1983. The code is well-commented and could probably be customized without the magazine if you must. You will, however, need to know some hardware-specific information about your terminal and disk controller; count on needing the manufacturers' manuals and/or cribbing the information from your BIOS source. (The disk reads must bypass CP/M function calls entirely - you have to send raw commands to the controller, and retrieve the data byte-by-byte.) Tests Performed: Radial Alignment - on six different tracks, to within 1/2 milliinch Positioner Hysteresis - " , using any offset up to full width Head Azimuth - from -42 to +42 minutes Index Timing - inner and outer tracks Diskette Centering - three levels of difficulty (tests bearings, clamping) Spindle Speed - (not a function of the DDD... ) (Many other problems, such as dirty heads, will show themselves during these tests... You will want to get familiar with the results of the different tests while your drives are working, so that you can recognize the changes caused by new bugs.) Verification: DDD11.ASM is a 47K file CRC (Version 5.0 and previous...) 6E 94 CRC (Version 5.1 and derivatives...) 7B79 (Comment by Dave Ihnat: UNIX sum: 49686 <x>, where <x> is 45 on a 1K System V filesystem, and (I suspect) 91 on a 512-byte filesystem. Note that the CRC sums most likely *won't* come out correctly. - DMI) Author: LOREN AMELANG CIS Email [70110,551] (I access Snail Mail more often than Email... but if you want to send machine code...) Box 24, Philo, CA 95466 0024 (Best way to contact me...) ******************************************************************************* Take the mystery out of YOUR flexible disk system !!! ******************************************************************************* !E!O!F! echo x - ddd11.asm cat >ddd11.asm <<'!E!O!F!' ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ;<>******************************************************<> ;<>* *<> ;<>* D D D *<> ;<>* *<> ;<>* Dysan Corporation *<> ;<>* Customer Engineering Division *<> ;<>* 1244 Reamwood Avenue *<> ;<>* Sunnyvale, Cal. 94086 *<> ;<>* *<> ;<>******************************************************<> ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ; 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 the information contained herein. ; THIS PROGRAM IS IN THE PUBLIC DOMAIN, AND MAY BE ; FREELY COPIED AND DISTRIBUTED ; ; ; **************************************************************** ; ; USAGE: ; ; To use this program, a digital alignment disk is required. ; You may purchase the required "Digital Diagnostic Diskette" (tm) ; directly from Dysan Corporation. Available DDD(tm) models are: ; ; SIDES:............SINGLE SIDED.............DOUBLE SIDED ; DENSITY:......SINGLE(FM) DOUBLE(MFM)...SINGLE(FM) DOUBLE(MFM) ; SIZE & TPI: ; 8" 48 TPI 808-100 808-200 808-300 808-400 ; 5.25" 48 TPI 508-100 508-200 508-300 508-400 ; 5.25" 96 TPI 506-100 506-200 506-300 506-400 ; 5.25" 100 TPI CALL FOR AVAILABILITY CALL FOR AVAILABILITY ; ; ; PRICES: Single Sided - $30.00 Double Sided - $40.00 ; Plus appropriate sales taxes and shipping costs ; Prices and models subject to change without notice ; ; ; ORDERING: Contact your local Dysan sales Rep. or call ; Inside Northern California: (408) 988-3472 ; Outside Northern California: (800) 551-9000 ; ; ; TECHNICAL INFORMATION: For information regarding DDD(tm) ; applications contact Dysan's ; CE Division TECH-LINE: (408)734-1624 ; ; ; **************************************************************** ; ; HISTORY: ; ; VERSION 1.0: Developed by Dysan for their Single Card Computer ; and Hazeltine 1500 terminal ; ; VERSION 1.1: Modified by Loren Amelang, Box 24, Philo, Ca. ; 95466 0024 ; Added drive selection; commented out code which required ; a macro assembler (you can now use ASM); substituted ; CP/M BDOS calls for version 1.0 BIOS calls; modified cline ; & its usage for terminals without clear-to-end-of-line; ; added display of last sectors read; modified disc ; read routines for CCS 2422 controller and ; programmed I/O transfer; ; ; ; **************************************************************** ; ; ENVIRONMENT: ; ; 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 its 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 ; ; 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 }. ; ; Original configuration (Version 1.0): ; ; 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) ; ; ; **************************************************************** ; ; PROGRAM SOURCE CODE: ; ; title 'Drive Diagnostic Program for CP/M 80 1/15/83' ; ; File ddd.asm ; wboot equ 0 ; warm boot address bdos equ 5 ; jump address for bdos calls ********************** *** "CONDITIONALS" *** ********************** ; ; Choose the appropriate assemble time options for your system, ; or use this space to add new system options. ; true equ 0ffffh false equ not true ; Dysan equ false ;set this true for Dysan controller CCS equ true ;set this true for CCS 2422 controller ; programmed i/o transfer, etc. lineclr equ false ;set this true if your console has ; a clear-to-end-of-line command Hazel equ false ;set this true for Hazeltine 1500 terminal ; (requiring "lead-in" to commands) Loren equ true ;set this true for Loren's homebrew terminal... ; ;ADD CONDITIONAL OPTIONS FOR YOUR ENVIRONMENT HERE... ; ; ******************************** *** "MACRO CALL BIOS DIRECT" *** ******************************** ; ; This macro was used in version 1.0 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 bios ; and computes offset to routine. ; ; ;gobios macro @func ; lhld wboot+1 ; Warm boot address ; lxi d,@func ; Offset ; dad d ; Add offset ; pchl ; Go to bios routine ; endm *************************** *** "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 sent before "Column" or ; bias is needed. if Hazel ;version 1.0 add$cur equ 17 ; address cursor command clr$co equ 28 ; clear to foreground spaces lead$in equ 126 ; console lead-in end$ln equ 15 ; clear to end of line endif if Loren ;version 1.1 add$cur equ 01 ; address cursor command clr$co equ 05 ; clear to foreground spaces endif cr equ 0dh ; carriage return lf equ 0ah ; line feed esc equ 1Bh ; escape bs equ 8 ; back space bell equ 7 ; audio alert **************************************** *** "FLOPPY CONTROLLER PORT EQUATES" *** **************************************** ; Change the following Port assignments for ; Your system. ; ; "FDC" Acronym Floppy Disk Controller ; ; FDC port assignments: ; if Dysan ;version 1.0 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 endif if CCS ;version 1.1 fdc equ 30H ; 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 004CH ;memory address of pointer to ; sector buffer dsel equ fdc+4 ; drive select port: ;output BX for single density ; FX for double density ; where X = 1 for drive A ; 2 for drive B ; 4 for drive C ; 8 for drive D endif ************************************ *** "FLOPPY CONTROLLER COMMANDS" *** ************************************ ; These are common to most systems using the 1793. ; sdma is a Dysan controller command, ignored in V. 1.1. 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 ; see "delay" routine - this value is for ; 4 Mhz. Z-80; adjust here or in "delay" ; to suit your clock and processor... indxbyt equ 2 ; byte in status reg. when index hole ; is passing sensor busybyt equ 1 ; byte in status reg. when controller ; is busy drqbyt equ 2 ; byte in status reg. when data is ; waiting to be read by the computer ****************************** *** "DDD DISKETTE EQUATES" *** ****************************** ; Adjust to match your diskette size and format. ttrk equ 76 ; total number of tracks sectors equ 26 ; sectors per track ; 26 for 8" DDD, 16 for 5.25" DDD lneg equ sectors+2 ; last neg. sector +2 lpos equ sectors+1 ; last pos. sector +2 tsec equ (sectors/2)-1 ; centering test if Dysan ref equ 798 ; reference time (single Den) ; (used in "index 7") endif if CCS ref equ 24eh ; experimentally determined... endif *************************** *** "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 'D' ;"Drive Select" jnz ex call select jmp main ;new drive selected - get option ex: 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 ; call cstat1 ; Data ready? mvi c,11 ; BDOS console status call bdos ; function call added for V1.1 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 mvi c,1 ; BDOS console input call bdos ; function call added for V1.1 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 ************************ *** "CONSOLE OUTPUT" *** ************************ ; ; Enter with character in "A" reg. co: push psw push h ; save all registers push d push b ; mov c,a ; Pass char in "C" reg mov e,a ; Pass char in "E" reg for V1.1 mvi c,6 ; BDOS direct console i/o call bdos ; function call added for V1.1 ; call co1 pop b pop d pop h pop psw ret ;co1: ; gobios 9 ; macro ******************** *** "LINE INPUT" *** ******************** ; used to input data greater then one ; character which is terminated by "CR". ; (used only by "offset:" directly below here...) getln: ; lxi d,buffer ; input buffer ; Following code added to V1.1 to use standard BDOS call for Line Input: lxi d,inbuf ; input buffer in BDOS 10 format mvi c,0Ah ; Console Input Line function call bdos ; added for V 1.1 lhld incnt ; get # of characterrs read mvi h,0 ; incnt is only one byte... xchg ; move to de reg lxi h,buffer ; get text buffer address dad d ; increment buffer pointer by # chars mvi m,0dh ; place "cr" after valid chars ; as V1.0 expects... ret ; ;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! ; jnz gl1 ; No! ; 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: 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 ; Note: some Dysan spec sheets list track 5 rather ; than 3 as an index track - my Revision A DDD definitely ; uses track 3... LA. 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: if Hazel mvi a,lead$in ; lead in call co endif mvi a,clr$co ; clear to foreground spaces jmp co **************************** *** "CLEAR DISPLAY LINE" *** **************************** cline: if lineclr mvi a,0 ; starting column sta column lxi h,set$cur ; set cursor call text endif if Hazel AND lineclr mvi a,lead$in ; lead in byte call co endif if lineclr mvi a,end$ln ; clear to end of line call co endif if NOT lineclr mvi a,11 ; starting column sta column lxi h,set$cur ; set cursor call text lxi h,blanks ;address of a string of 56 blanks... call text endif ret ************************* *** "FATAL ERROR MSG" *** ************************* fatal: if lineclr call cline ; clear line endif 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 (-1) at the start of string indicates ; to this routine ; that column and row position will follow. ; This format does not necessarily go out to ; your terminal. If your terminal needs row sent before column, ; or a constant bias added (0,0 is not the upper left ; corner of the screen), you'll have to invent code ; within this routine to accomplish that. ; ; This is the internal representation format: ; 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) AND 0FFH ; position cursor? ; "and offh" added for ASM compatibility jz text1 ; yes inx h ; next char. call co ; output jmp text ; text1: inx h ; move passed command if Hazel mvi a,lead$in ; leading for console call co ; issue. endif 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 ************************* *** "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: call rd$trk ; read centering track mvi a,10 ; set row position sta row jc center3 ; fatal error.. if lineclr call cline ; clear line endif 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 ; azimuth1: lxi h,azi$tab ; set translation table shld xpoint ; pointers shld ypoint call rd$trk ; read azimuth track mvi a,10 ; set row position sta row jc azimuth3 ; fatal error... if lineclr call cline ; clear line endif 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 lxi h,me11 ; Space bar msg call text ; radial1: ; 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 mvi a,11 ; set row position sta row 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 ************************************ *** "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: if lineclr call cline ; clear display lda row ; next line inr a sta row call cline endif 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 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... mvi a,10 ; set row sta row 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 mvi a,10 ; set row sta row 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 if lineclr call cline ; clear display endif 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. 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 indxbyt jnz index3 ; Compute time from index to ID index4: in stat ; loop until next ani indxbyt ; index... jz index4 ; ; Read address.. ; nop ; 1.00 mvi a,raddr ; 1.75 out cmd ; 2.75 call delay ; [ 50 usec ] if Dysan mvi a,sdma ; 1.75 out dma ; 2.75 endif if CCS ; ; 10 Usec Test cnt. loop index5: inx d ; 1.50 [ counter ] inx h ; 1.50 in stat ; 2.75 ani drqbyt ; 1.75 - loop until drq set... jz index5 ; 2.50 LHLD DMA IN DATA MOV M,A INX H IN DATA MOV M,A INX H IN DATA MOV M,A INX H IN DATA MOV M,A INX H IN DATA MOV M,A INX H IN DATA MOV M,A endif if Dysan ; ; 10 Usec Test cnt. loop index5: inx d ; 1.50 [ counter ] inx h ; 1.50 in stat ; 2.75 ani busybyt ; 1.75 - loop until not busy jnz index5 ; 2.50 endif ; 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 ; Value of ref is in DDD variable ;equates... it is subtracted from ;the measured # of microsec. here ;to adjust timing to a standard ;Analog Alignment Diskette... ; If you have a 4 Mhz. Z-80 and single density DDD ; and are using the Dysan environment, 798 is the ; magic number. Otherwise you'll have to "cut and try" ; and without the AAD you'll have to guess... ; (A relative measure is better than no measure...) call subde xchg 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 if lineclr call cline ; clear line endif 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 performed 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 if lineclr call cline ; clear line endif 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" *** ******************************* ; ; With 4 Mhz. Z-80, ; 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 at your clock speed with your processor. ; ; note: "RPM5 or 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 A,7 ;Upper case code adds a simple display of ; last sector read (+ & -), giving ; ? and @ if first sectors fail ; and A thru Z representing the 26 ; possible sectors on an 8" disk ; or A thru P for a 5.25" disk STA ROW MVI A,39 STA COLUMN LXI H,SET$CUR CALL TEXT mvi c,lpos ; last sector mvi a,1 ; beginning sector positive call rd$sec ; read positive offsets ADI 3eH ; translate sector # to alpha code */ CALL CO ; display on console */ SUI 3eH ; return to sector # */ 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 ADI 3eH CALL CO SUI 3eH 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 HARDWARE DEPENDENT ROUTINES" *** ******************************************************** ; ; ********************** *** "DRIVE SELECT" *** ********************** ; ; The drive select routine must be expanded ; for selected systems. select: if Dysan mvi a,21h ; select bits out dsel ; select drive... endif if CCS ;The upper case code performs drive ; selection on the CCS 2422 controller ; for single side double density... CALL CLS ; clear console */ LXI H,SELMSG CALL TEXT ; print drive selection request */ CALL CI ; get response */ CPI 'A' ; accept A,B,C,D, as responses */ JZ SELECT1 JC SELECT CPI 'B' JZ SELECT1 CPI 'C' JZ SELECT3 CPI 'D' JZ SELECT4 JMP SELECT ; repeat if invalid choice */ SELECT4:ADI 3 ; make low nybble an 8 */ SELECT3:INR A ; make a 4 */ SELECT1:SUI '@' ; make B into 2 or A into 1 */ ORI 0F0H ; add high nybble: */ ; F for double density, B for single STA SELPT ; store select bits for future use... */ OUT DSEL MVI A,40H ; select side 0... 00 selects side 1... */ OUT 04 ; secondary control port */ endif 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... if Dysan call delay ; delay for FDC endif if CCS ;This controller seems to need more ; delay - I can't explain why... LA. call delayB ; delay for FDC endif ; 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 if CCS DELAYB: PUSH B ; extra delay for CCS controller... */ LXI B,2000H DELAYC: DCX B MOV A,C ORA B JNZ DELAYC POP B RET endif *************************************** *** "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 if CCS LHLD DMA ; get pointer to memory buffer */ MVI B,40H ; initialize loop counter for I/O */ ;transfers: 40 for 8" DD, 20 for 8" SD endif lda dflag ; seek delay flag ori rsec ; read sector command out cmd ; issue.. if Dysan mvi a,sdma ; start transfer out dma endif if CCS BREAD: IN DATA ; code to perform I/O transfer of */ MOV M,A ; data to memory */ INX H IN DATA MOV M,A INX H IN DATA MOV M,A INX H IN DATA MOV M,A INX H DCR B ; decrement loop counter... */ JNZ BREAD endif 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 ************************************** *** "WAIT FOR END OF DMA TRANSFER" *** ************************************** comp: call delay ; before each check in stat ; Completed Transfer? rrc rnc ; YES! jmp comp ******************************** *** "PROGRAM DISK CONTROLLER" *** ******************************** prg$dma: if Dysan 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 endif if CCS LXI H,SECBUF ; store address of memory buffer */ SHLD DMA ; in pointer for disk controller */ LDA SELPT ; get drive select bits */ OUT DSEL ; sets autowait for 2422 controller... */ ; to ensure synchronization of I/O transfer endif ret ************************************** *** "COMMAND TABLE DMA CONTROLLER" *** ************************************** ; This data is used to program Zilog's ; z80 DMA controller. cmd$tbl: if Dysan 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 endif ************************************ *** "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 Timing 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: if Dysan db (-1) AND 0FFH,27,1,'Drive Diagnostic Program' db (-1) AND 0FFH,31,2,'CP/M 80 Ver 1.0' db (-1) AND 0FFH,23,4,'( Dysan Corp. Santa Clara, Ca. )' endif db (-1) AND 0FFH,18,5,'<*>======================================<*>' db (-1) AND 0FFH,18,6,'<*> DIAGNOSTIC COMMAND MENU <*>' db (-1) AND 0FFH,18,7,'<*>======================================<*>' db (-1) AND 0FFH,18,8,'<*> <*>' db (-1) AND 0FFH,18,9,'<*> R = Radial H = Hysteresis <*>' db (-1) AND 0FFH,18,10,'<*> <*>' db (-1) AND 0FFH,18,11,'<*> A = Azimuth I = Index Timing <*>' db (-1) AND 0FFH,18,12,'<*> <*>' db (-1) AND 0FFH,18,13,'<*> C = Centering S = Spindle Speed <*>' db (-1) AND 0FFH,18,14,'<*> <*>' db (-1) AND 0FFH,18,15,'<*> D = Drive Sel E = Exit Program <*>' db (-1) AND 0FFH,18,16,'<*> <*>' db (-1) AND 0FFH,18,17,'<*><*><*<*><*><*><*><*><*><*><*><*><*><*><*>' db (-1) AND 0FFH,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) AND 0FFH,25,2,'<>==========================<>' db (-1) AND 0FFH,25,3,'<> TRACK OFFSET <>' db (-1) AND 0FFH,25,4,'<>==========================<>' db (-1) AND 0FFH,25,5,'<> <>' db (-1) AND 0FFH,25,6,'<> 0 ---> 76 <>' db (-1) AND 0FFH,25,7,'<> <>' db (-1) AND 0FFH,25,8,'<>==========================<>' db (-1) AND 0FFH,25,9,'<> <ESC> Cancels Test <>' db (-1) AND 0FFH,25,10,'<>==========================<>' db (-1) AND 0FFH,25,12,'OFFSET? ...',bs,0 me7: db (-1) AND 0FFH,25,2,'<>==========================<>' db (-1) AND 0FFH,25,3,'<> TRACK SELECTION <>' db (-1) AND 0FFH,25,4,'<>==========================<>' db (-1) AND 0FFH,25,5,'<> <>' db (-1) AND 0FFH,25,6,'<> A = (0) D = (41) <>' db (-1) AND 0FFH,25,7,'<> <>' db (-1) AND 0FFH,25, 8,'<> B = (3) E = (70) <>' db (-1) AND 0FFH,25, 9,'<> <>' db (-1) AND 0FFH,25,10,'<> C = (38) F = (73) <>' db (-1) AND 0FFH,25,11,'<> <>' db (-1) AND 0FFH,25,12,'<>==========================<>' db (-1) AND 0FFH,25,13,'<> <ESC> Cancels Test <>' db (-1) AND 0FFH,25,14,'<>==========================<>' db (-1) AND 0FFH,25,16,'TRACK? ...',bs,0 me8: db (-1) AND 0FFH,24,5,'--- RADIAL ALIGNMENT CHECK ---' db (-1) AND 0FFH,10,9,'Away',(-1) AND 0FFH,36,9,'Spindle',(-1) AND 0FFH,63,9,'Toward' db (-1) AND 0FFH,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 (-1) AND 0FFH,25,2,'<>==========================<>' db (-1) AND 0FFH,25,3,'<> TRACK SELECTION <>' db (-1) AND 0FFH,25,4,'<>==========================<>' db (-1) AND 0FFH,25,5,'<> <>' db (-1) AND 0FFH,25,6,'<> A = (35) B = (44) <>' db (-1) AND 0FFH,25,7,'<> <>' db (-1) AND 0FFH,25,8,'<> C = (47) <>' db (-1) AND 0FFH,25,9,'<> <>' db (-1) AND 0FFH,25,10,'<>==========================<>' db (-1) AND 0FFH,25,11,'<> <ESC> Cancels Test <>' db (-1) AND 0FFH,25,12,'<>==========================<>' db (-1) AND 0FFH,25,14,'TRACK? ...',bs,0 me10: db (-1) AND 0FFH,23,5,'--- DISKETTE CENTERING CHECK ---',0 me11: db (-1) AND 0FFH,23,14,'Press <SPACE BAR> For New Track',0 me12: db (-1) AND 0FFH,24,5,'--- AZIMUTH ALIGNMENT CHECK ---' db (-1) AND 0FFH,25,14,'<ESC> Will Cancel AZIMUTH Check',0 me13: db (-1) AND 0FFH,25,2,'<>==========================<>' db (-1) AND 0FFH,25,3,'<> TRACK SELECTION <>' db (-1) AND 0FFH,25,4,'<>==========================<>' db (-1) AND 0FFH,25,5,'<> <>' db (-1) AND 0FFH,25,6,'<> A = (0) B = (76) <>' db (-1) AND 0FFH,25,7,'<> <>' db (-1) AND 0FFH,25,8,'<>==========================<>' db (-1) AND 0FFH,25,9,'<> <ESC> Cancels Test <>' db (-1) AND 0FFH,25,10,'<>==========================<>' db (-1) AND 0FFH,25,12,'TRACK? ...',bs,0 me14: db (-1) AND 0FFH,28,5,'--- HYSTERESIS CHECK ---',0 me15: db (-1) AND 0FFH,15,8,'##################################################' db (-1) AND 0FFH,15,12,'##################################################',0 me16: db 'Positioner Hysteresis = ',0 me17: db (-1) AND 0FFH,25,5,'--- INDEX TO DATA TIME ---',0 me18: db 'Index To ID In Usecs = ',0 me19: db (-1) AND 0FFH,27,5,'--- SPINDLE SPEED CHECK ---' db (-1) AND 0FFH,25,14,'<ESC> Will Cancel RPM Check',0 me20: db ' Milliseconds',0 me21: db ' RPM',0 BLANKS: DB ' ' DB ' ',0 SELMSG: DB (-1) AND 0FFH,15,12,'WHICH DRIVE HAS THE DDD - A,B,C,D ?' DB (-1) AND 0FFH,25,14,'SELECTION ? ....',0 ************************* *** "POSITION CURSOR" *** ************************* set$cur db 0ffh column ds 1 ; set column row ds 1 ; set row db 0 ; terminator *********************************** *** "PROGRAM VARIABLE STORAGE" *** *********************************** 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 SELPT DS 1 ;STORES BYTE FOR DISC CONTROL PORT ; ; Storage area for 16/24 bit divide routine ; msb ds 1 msb1 ds 2 msb2 ds 2 inbuf: db 3 ;"max" byte for BDOS 10 incnt ds 1 ;"cnt" buffer for BDOS 10 buffer ds 4 ; console input buffer secbuf ds 256 ; sector buffer ds 100 ; stack space stack equ $ ; top down... !E!O!F!