;***************************************************************************** ;* * ;* PROGRAM TO CONTROL THE TRACK POSITION, ETC. OF 5 1/4 INCH * ;* FLOPPY DRIVES TO MAKE HEAD ALIGNMENT POSSIBLE. * ;* BY RONALD E. JACOBS * ;* NOVEMBER 1, 1983 * ;* * ;* 05/22/86 added microdecision drive control capabilities * ;***************************************************************************** .Z80 ;written in Z80 assembly language ORG 0 ;for use with M80/L80 ;************************************************************************ ;* * ;* the following is a user setable equate * ;* * ;************************************************************************ diradfg equ 1 ;0 for freedom; 1 for adm 31 cursor addressing CR EQU 0Dh ;CARRIAGE RETURN LF EQU 0Ah ;LINE FEED BDOS EQU 5 LD SP,STACK ;STARTING ADDR OF STACK CALL RDTAIL ;SEE IF FOR 8" OR 5" DRIVES AND PATCH IF NEEDED CALL DISPLA ;WRITE THE CRT SCREEN DISPLAY COMAND: LD B,44 ;COLUMN ADDRESS (NO OFFSET) LD C,19 ;ROW ADDRESS (NO OFFSET) CALL CURADD ;MOVE CURSOR TO 'Command:' CALL GETCHR ;**************************************************************** ;* * ;* SEE IF CHARACTER JUST RECEIVED FROM CONSOLE WAS * ;* A DIGIT (0-3). IF SO, CHECK FOR A SECOND DIGIT. * ;* IF NOT CHECK TO SEE IF CHARACTER IS A VALID LETTER. * ;* * ;**************************************************************** LD B,4 ;COUNT TRHCNT EQU $-1 ;TRACK HIGH DIGIT COUNT LD C,'3' ;3 FOR 5" OR 7 FOR 8" DRIVES TRHDIG EQU $-1 ;HIGHEST TRACK DIGIT DIGIT: CP C JP Z,TRACK ;IF A DIGIT, GET 2nd DIGIT DEC C ;NEXT LOWER ASCII DIGIT DJNZ DIGIT ;ALL 4 DIGITS TRIED YET ? JR ALPHA ;NOT A DIGIT, GO SEE IF ALPHA COMMAND ;***************************************************************** ;* * ;* DETERMINE IF A VALID LETTER COMMAND WAS TYPED * ;* AND TAKE APPROPRIATE ACTION * ;* * ;***************************************************************** ALPHA: CP 'C' JP Z,CURREV CP 'c' JP Z,CURREV CP 'I' JP Z,STEPI CP 'i' JP Z,STEPI CP 'O' JP Z,STEPO CP 'o' JP Z,STEPO CP 'R' JP Z,RECAL CP 'r' JP Z,RECAL CP 'S' JP Z,SIDSEL CP 's' JP Z,SIDSEL MOTCHR: CP 'M' JP Z,MOTOR CP 'm' JP Z,MOTOR CP 'L' JP Z,SELDRV CP 'l' JP Z,SELDRV CP 03h ;03h= ^C JP Z,EXIT ;WARM BOOT JP COMAND ;CHAR TYPED WASN'T VALID COMMAND ;**************************************************************** ;* * ;* CURREV ROUTINE * ;* * ;* TOGGLES A FLAG (RCXCHG) WHICH THE CURSOR ADDRESSING * ;* ROUTINE USES TO REVERSE OR NOT REVERSE THE ORDER * ;* OF TRANSMISSION OF ROW AND COLUMN TO THE TERMINAL. * ;* * ;**************************************************************** CURREV: LD A,(RCXCHG) OR A JP Z,REV LD A,0 LD (RCXCHG),A JP COMAND REV: LD A,1 LD (RCXCHG),A JP COMAND ;**************************************************************** ;* * ;* EXIT ROUTINE * ;* * ;* 1. RESTORE ORIGINAL DEFAULT DRIVE * ;* 2. RESTORE ORIGINAL 8",5-1/4" DRIVE ORDER * ;* 3. MOVE CURSOR TO SCREEN BOTTOM LEFT * ;* 4. WARM BOOT * ;* * ;**************************************************************** EXIT: ld a,(mdflag) ;0=djdma, 1=microdecision or a ;test if djdma or microdecision jp nz,wboot ;skip decision 1 housekeeping LD C,0Eh ;BDOS SELECT DISC LD A,(ORGDSK) ;RESTORE ORIGINAL DEFAULT DRIVE LD E,A CALL BDOS LD A,(PHYDRV) ;WAS ORIGINAL DRIVE 0 8 OR 5 INCH AND 00000100b ;IN BIT 2=0 THEN ORIGINALLY 8" LD (ORDR58),A ;PATCH INTO SUBROUTINE MFFRST CALL MFFRST ;RESTORE ORIGINAL 8, 5" DRIVE ORDER LD A,16d ;RESTORE DJDMA DRIVE DESELECT TIME LD (DESTIM),A ;STORE BYTE IN DJDMA COMMAND STRING CALL DESEL LD A,10d ;RESTORE DJDMA ERROR RETRYS COUNT LD (RETNUM),A ;STORE BYTE IN DJDMA COMMAND STRING CALL RETRYS wboot: LD B,0 ;COLUMN ADDRESS (NO OFFSET) LD C,23 ;ROW ADDRESS (NO OFFSET) CALL CURADD ;POSITION THE CURSOR FOR EXIT JP 0 ;WARM BOOT ;**************************************************************** ;* * ;* MOTOR ROUTINE * ;* * ;**************************************************************** MOTOR: LD B,2Ah ;COLUMN ADDR (NO OFFSET) LD C,13 ;ROW ADDR (NO OFFSET) CALL CURADD ;CURSOR ADDR SUBROUTINE LD A,(MOTOGL) ;MOTOR TOGGLE FLAG CP 0 JP Z,MOTRON LD C,09h ;BDOS PRINT STRING FUNCTION LD DE,OFFMSG ;START OF OFF MESSAGE STRING CALL BDOS XOR A LD (MOTOGL),A JP COMAND ;RETURN FOR NEXT COMMAND MOTRON: LD C,09h ;BDOS PRINT STRING FUNCTION LD DE,ONMSG ;START OF ON MESSAGE STRING CALL BDOS LD A,1 LD (MOTOGL),A JP COMAND ;RETURN FOR NEXT COMMAND MOTOGL: DB 0 ;MOTOR TOGGLE FLAG OFFMSG: DB 'OFF $' ;EXTRA WHITE SPACE FOR PATCH USE ONMSG: DB 'ON $' ; WITH 8"DRIVES ;**************************************************************** ;* * ;* RECAL ROUTINE * ;* * ;* 1. WRITES CONTROLLER COMMANDS TO 50h * ;* 2. CAUSES CONTROLER TO EXECUTE THESE COMMANDS * ;* 3. CONTROLLER COPIES BYTES FROM MAIN MEMORY TO * ;* CONTROLLER MEMORY (1030h). * ;* 4. CONTROLLER BEGINS EXECUTING INSTRUCTIONS AT 1030h * ;* 5. THE INSTRUCTIONS AT 1030h CALL THE CONTROLLERS * ;* HOME HEAD ROUTINE * ;* 6. AT COMPLETION OF THIS CONTROLLER EXECUTES THE HALT * ;* COMMAND. DURING THE ABOVE STEPS THE MAIN CPU IS * ;* WAITING FOR THE HALT COMMAND (25h) STATUS BYTE TO * ;* CHANGE FROM 00 TO INDICATE THE DJDMA IS FINISHED * ;* * ;**************************************************************** ;* THESE BYTES WILL BE LOADED INTO CONTROLLERS MEMORY AT 1030h * HOMEHD: DB 0CDh ;CALL INSTRUCTION DW 00A0h ;ADDRESS ON DJDMA OF JUMP VECTOR TO HOME ROUTINE HOMEND: DB 0C9h ;RETURN INSTRUCTION ;* THESE BYTES WILL BE LOADED INTO MAIN MEMORY AT 0050h * WRTCOM: DB 0A1h ;DJDMA WRITE CONTROLLER MEMORY COMMAND DW HOMEHD ;STARTING ADDRESS OF STRING TO TRANSFER DB 00 ;EXTENDED ADDRESS OF STRING TO TRANSFER DW HOMEND-HOMEHD+1 ;NUMBER OF BYTES IN STRING BEING TRANSFERED DW 1030h ;TRANSFER STRING TO 1030h IN CONTROLLER MEMORY DB 0A2h ;DJDMA EXECUTE CONTROLLER ROUTINE COMMAND DW 1030h ;ADDRESS IN CONTROLLER TO BEGIN EXECUTING AT DB 25h ;DJDMA CONTROLLER HALT COMMAND WRTHLT: DB 00 ;HALT COMMAND STATUS BYTE RECAL: LD HL,WRTCOM ;ADDRESS TO BEGIN TRANSFERRING BYTES FROM LD BC,WRTHLT-WRTCOM+1 ;NUMBER OF BYTES TO TRANSFER LD DE,0050h ;ADDRESS TO BEGIN TRANSFERRING BYTES TO LDIR ;DOES THE TRANSFER OUT (0EFh),A ;START THE DJDMA WRTDON: LD A,(WRTHLT-WRTCOM+50h) ;ACTUAL HALT STATUS BYTE ADDRESS OR A ;HAS HALT COMMAND COMPLETED ? JP Z,WRTDON CALL RUNONE ;RUN READ SECTOR ONCE JP COMAND ;RETURN FOR NEXT COMMAND ;**************************************************************** ;* * ;* SELDRV ROUTINE * ;* * ;**************************************************************** SELDRV: LD B,2Ah ;COLUMN ADDRESS (NO OFFSET) LD C,15 ;ROW ADDRESS (NO OFFSET) CALL CURADD ;MOVE CURSOR TO DRIVE LETTER POSITION DRVCHR: CALL GETCHR ;GET ACTUAL DRIVE NUMBER FROM TERMINAL CP '0' ;VALID CHARACTER IS 0-3 JP Z,SELPNT CP '1' JP Z,SELPNT CP '2' JP Z,SELPNT CP '3' JP Z,SELPNT JP DRVCHR ;CHARACTER WASN'T VALID; TRY AGAIN SELPNT: LD C,6 ;BDOS DIRECT CONSOLE I/0 LD E,A ;PRINT SELECTED DRIVE ON CRT AND 00001111b ;CONVERT ASCII DIGIT TO BINARY LD (MOTDRV),A ;STORE DRIVE NUMBER CALL BDOS JP COMAND ;RETURN FOR NEXT COMMAND ;**************************************************************** ;* * ;* SIDSEL ROUTINE * ;* * ;* TOGGLE THE CHOSEN SIDE, DISPLAY CHOICE ON CRT, * ;* STORE CHOICE FOR USE BY MOTRUN SUBROUTINE * ;* * ;**************************************************************** SIDSEL: LD B,29h ;COLUMN ADDRESS (NO OFFSET) LD C,11 ;ROW ADDRESS (NO OFFSET) CALL CURADD ;CURSOR ADDRESS SUBROUTINE LD A,(MOTSS) ;MOTOR SIDE/SECTOR BYTE BIT 7,A ;BIT 7 SELECTS SIDE JP Z,SIDE1 RES 7,A ;SELECT SIDE 0 LD (MOTSS),A ;STORE BYTE IN DJDMA COMMAND STRING LD C,06h ;BDOS DIRECT CONSOLE I/O LD E,'0' ;PRINT SIDE ON CRT CALL BDOS ld a,0 ;bit 2 selects microdecision head ld (mdside),a ;store byte in microdecision seek command JP COMAND SIDE1: SET 7,A ;SELECT SIDE 1 LD (MOTSS),A ;STORE BYTE IN DJDMA COMMAND STRING LD C,06h ;BDOS DIRECT CONSOLE I/O LD E,'1' ;PRINT SIDE ON CRT CALL BDOS ld a,00000100b ;bit 2 selects microdecision head ld (mdside),a ;store byte in microdecision seek command JP COMAND ;**************************************************************** ;* * ;* STEPI ROUTINE * ;* * ;* INCREMENT THE ASCII REPRESNTATION OF THE CURRENT TRACK * ;* NUMBER BY ONE (IF NOT ALREADY HIGHEST TRACK). PRINT IT * ;* ON THE CRT AND INSERT IT IN THE DJDMA READ SECTOR * ;* COMMAND STRING. * ;* * ;**************************************************************** STEPI: LD A,(MOTTRK) ;CURRENT TRACK IN HEX HITRAK: CP 39d ;HIGHEST ALLOWED TRACK NUMBER JP Z,COMAND ;DON'T STEP IN IF ALREADY AT 39 LD A,(DIGIT2) ;ASCII ONES DIGIT OF CURRENT TRACK CP '9' ;IS IT AN ASCII 9 ? JP NZ,TRKINC ;IF LESS THEN 9 INCREMENT IT 1 ;*IF ONES DIGIT IS A 9:* LD A,30h ;ASCII 0 LD (DIGIT2),A ;STORE A 0 IN ONES DIGIT OF TRACK LD A,(DIGIT1) ;OLD ASCII TENS DIGIT OF TRACK # INC A ;INCREMENT TENS BY 1 LD (DIGIT1),A ;STORE IT CALL TRKCRT ;PRINT THE NEW TRACK NUMBER ON CRT CALL TRKHEX ;CONVERT TO HEX TRACK #, PUT IN COMMAND JP COMAND ;GO GET NEXT COMMAND FROM TERMINAL ;*IF ONES DIGIT IS 0 TO 8 :* TRKINC: INC A ;INCREMENT ONES DIGIT BY ONE LD (DIGIT2),A ;STORE IT CALL TRKCRT ;PRINT THE NEW TRACK # ON CRT CALL TRKHEX ;CONVERT TO HEX TRACK #, PUT IN COMMAND JP COMAND ;GO GET NEXT COMMAND FROM TERMINAL ;**************************************************************** ;* * ;* STEPO ROUTINE * ;* * ;* DECREMENT THE ASCII REPRESNTATION OF THE CURRENT TRACK * ;* NUMBER BY ONE (IF NOT ALREADY LOWEST TRACK). PRINT IT * ;* ON THE CRT AND INSERT IT IN THE DJDMA READ SECTOR * ;* COMMAND STRING. * ;* * ;**************************************************************** STEPO: LD A,(MOTTRK) ;CURRENT TRACK IN HEX CP 00d ;LOWEST ALLOWED TRACK NUMBER JP Z,COMAND ;DON'T STEP OUT IF ALREADY AT 00 LD A,(DIGIT2) ;ASCII ONES DIGIT OF CURRENT TRACK CP 30h ;IS IT AN ASCII 0 ? JP NZ,TRKDEC ;IF GREATER THEN 0 DECREMENT IT 1 ;*IF ONES DIGIT IS A 0:* LD A,39h ;ASCII 9 LD (DIGIT2),A ;STORE A 9 IN ONES DIGIT OF TRACK LD A,(DIGIT1) ;OLD ASCII TENS DIGIT OF TRACK # DEC A ;DECREMENT TENS BY 1 LD (DIGIT1),A ;STORE IT CALL TRKCRT ;PRINT THE NEW TRACK NUMBER ON CRT CALL TRKHEX ;CONVERT TO HEX TRACK #, PUT IN COMMAND JP COMAND ;GO GET NEXT COMMAND FROM TERMINAL ;*IF ONES DIGIT IS 1 TO 9:* TRKDEC: DEC A ;DECREMENT ONES DIGIT BY ONE LD (DIGIT2),A ;STORE IT CALL TRKCRT ;PRINT THE NEW TRACK NUMBER ON CRT CALL TRKHEX ;CONVERT TO HEX TRACK #, PUT IN COMMAND JP COMAND ;GO GET NEXT COMMAND FROM TERMINAL ;**************************************************************** ;* * ;* TRACK ROUTINE * ;* * ;* TAKE THE ASCII TRACK NUMBER FROM THE * ;* DE REGISTER PAIR AND SEND THE HEAD TO THAT TRACK * ;* AND DISPLAY IT ON THE SCREEN. * ;* * ;**************************************************************** TRACK: LD (DIGIT1),A ;SAVE THE FIRST DIGIT LD B,2Ah ;COLUMN ADDRESS (NO OFFSET) LD C,09d ;ROW ADDRESS (NO OFFSET) CALL CURADD ;MOVE CURSOR TO TRACK NUMBER POSITION LD C,6 ;BDOS DIRECT CONSOLE I/O LD A,(DIGIT1) LD E,A ;PRINT THE FIRST DIGIT CALL BDOS GET2ND: CALL GETCHR ;GET THE 2nd DIGIT OF TRACK NUMBER LD (DIGIT2),A ;SAVE THE SECOND CHARACTER ;*identify what digit the second character is, if any:* LD B,0Ah ;COUNT LD C,39h ;ASCII 9 LOOP: CP C JP Z,LMIT76 ;IF DIGIT IDENTIFIED DEC C ;TRY NEXT LOWER DIGIT DJNZ LOOP ;ALL 10 DIGITS TRIED YET ? JP GET2ND ;ERROR: CHARACTER NOT 0-9 ;*don't allow tracks higher than 76 * LMIT76: LD A,(DIGIT1) ;TENS DIGIT OF TRACK NUMBER CP '7' JP NZ,TRKPNT ;OK IF TENS DIGIT LESS THAN 7 LD A,(DIGIT2) ;TENS MUST=7 SO CHECK 2nd DIGIT CP '7' JP NC,GET2ND ;BAD IF ONES GREATER THAN 6 TRKPNT: LD C,6 ;BDOS DIRECT CONSOLE I/O LD A,(DIGIT2) ;PRINT THE SECOND DIGIT LD E,A CALL BDOS CALL TRKHEX ;CONVERT ASCII TRACK TO HEX,LOAD IN JP COMAND ;GO GET NEXT COMMAND FROM CONSOLE DIGIT1: DB 31h ;ASCII 1 \ MAKES ASCII TRACK DIGIT2: DB 36h ;ASCII 6 / NUMBER 16 ;**************************************************************** ;* * ;* CURADD SUBROUTINE * ;* * ;* DIRECT CURSOR ADDRESSING SUBROUTINE: upon entry * ;* to CURADD reg. B should contain COLUMN addr without * ;* offset. Reg. C should contain ROW address without * ;* offset. * ;* * ;**************************************************************** CURADD: LD A,20h ;COLUMN OFFSET ADD A,B LD (COL),A ;STORE COLUMN (ADDR+OFFSET) LD A,20h ;ROW OFFSET ADD A,C LD (ROW),A ;STORE ROW (ADDRESS+OFFSET) LD C,6 ;BDOS DIRECT CONSOLE I/O LD E,1Bh ;esc character-TERMINAL DEPENDENT CALL BDOS LD C,6 ;BDOS DIRECT CONSOLE I/O LD E,'=' ;= character-TERMINAL DEPENDENT CALL BDOS ;OUTPUT CHARACTER LD A,(RCXCHG) ;IS ORDER OF TRANSMISSION OF OR A ;ROW AND COLUMN TO BE REVERSED ? JP NZ,COLOUT ROWOUT: LD C,6 ;BDOS DIRECT CONSOLE I/O LD A,(COL) ;OUTPUT COLUMN ADDRESS LD E,A CALL BDOS LD A,(RCXCHG) ;IS COLUMN NEXT OR ARE WE DONE ? OR A JP NZ,CURRET COLOUT: LD C,6 ;BDOS DIRECT CONSOLE I/O LD A,(ROW) ;OUTPUT ROW ADDRESS LD E,A CALL BDOS LD A,(RCXCHG) ;ARE WE DONE OR IS ROW NEXT ? OR A JP NZ,ROWOUT CURRET: RET ROW: DS 1 COL: DS 1 RCXCHG: DB diradfg ;use 0 for freedom, use 1 for adm 31 ;**************************************************************** ;* * ;* DESEL SUBROUTINE * ;* * ;* SETS THE NUMBER OF REVOLUTIONS BEFORE THE DJDMA * ;* IS DESELECTED AFTER DISC ACTIVITY. * ;* * ;**************************************************************** DESCOM: DB 2Fh ;HEAD UNLOAD DRIVE DESELECT TIMEOUT COMMAND DESTIM: DB 03h ;NUMBER OF REVOLUTIONS BEFORE TIMEOUT DB 25h ;DJDMA HALT COMMAND DESHLT: DB 00h ;STATUS BYTE DESEL: LD HL,DESCOM ;ADDRESS TO BEGIN TRANSFERING BYTES FROM LD DE,0050h ;ADDRESS TO BEGIN TRANSFERING BYTES TO LD BC,04 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER OUT (0EFh),A ;START THE DJDMA DESDON: LD A,(DESHLT-DESCOM+50h);ACTUAL HALT STATUS BYTE ADDRESS OR A ;HAS HALT COMMAND COMPLETED ? JP Z,DESDON RET ;**************************************************************** ;* * ;* DISPLA SUBROUTINE * ;* * ;* SUBROUTINE: SCROLLS WHATEVER IS ON THE SCREEN OFF * ;* AND DISPLAYS THE MFSTEP COMMANDS AND OTHER INFORMATION * ;* ON THE SCREEN. * ;* * ;**************************************************************** DISPLA: LD C,09h ;BDOS PRINT STRING FUNCTION LD DE,SCREEN ;START ADDR OF STRING CALL BDOS ;BDOS ENTRY POINT RET SCREEN: DB LF,LF,LF,LF,LF,LF,LF,LF DB LF,LF,LF,LF,LF,LF,LF,LF,LF,LF DB LF,LF,LF,LF,LF,LF DRVSIZ: DB 'DJDMA 5 1/4" FLOPPY DRIVE ALIGNMENT TOOL ' DB CR,LF DB 'REVISION 2.0 MAY 22, 1986 Jacobs Computer Services' DB LF,LF,LF,LF,LF,CR DB 'step (I)n 1 track ' DB CR,LF,LF DB 'step (O)ut 1 track ' DB CR,LF DB ' TRACK 16' DB CR,LF,'seek to track (NN) ' DB CR,LF DB ' SIDE 0' DB CR,LF,'(R)ecalibrate ' DB CR,LF MOT5: DB ' MOTOR OFF ' DB CR,LF,'(M)otor on/off ' DB CR,LF DB ' DRIVE 0' DB CR,LF DB '(S)ide 0-1' DB CR,LF,LF DB 'drive se(L)ect (0-3)' DB CR,LF DB ' Command:' DB CR,LF DB '^C = EXIT' DB CR,LF,LF DB '(C)ursor addressing' DB LF,'$' DS 100h ;STACK SPACE STACK EQU $ ;**************************************************************** ;* * ;* SUBROUTINE DRVORD * ;* * ;* SAVE THE ORIGINAL DEFAULT DISC * ;* * ;**************************************************************** DRVORD: LD C,19h ;BDOS RETURN CURRENT DISC CALL BDOS LD (ORGDSK),A ;SAVE CURRENT DEFAULT DISC RET ORGDSK: DS 1 ;**************************************************************** ;* * ;* GETCHR SUBROUTINE * ;* * ;* FETCHES A CHARACTER FROM THE CONSOLE. * ;* RETURNS IT IN REGISTER A. AND SINCE THIS ROUTINE IS * ;* NEARLY ALWAYS RUNNING, IT KEEPS THE MOTOR RUNNING BY * ;* CALLING MOTRUN. * ;* * ;**************************************************************** GETCHR: LD C,06 ;BDOS DIRECT CONSOLE I/O LD E,0FFh ;FOR CONSOLE INPUT CALL BDOS PUSH AF CALL MOTRUN POP AF CP 0 ;IF 0 THEN NO CHARACTER WAS READY JR Z,GETCHR ;TRY AGAIN TO GET A CHARACTER RET ;******************************************************** ;* * ;* SUBROUTINE MFFRST * ;* * ;* 1. SETS 5-1/4" DRIVES TO 0-3 (OR 4-8 IF ORDR58 * ;* =0) AND 8" TO 4-8 (OR 0-4 IF ORDR58=0) * ;* 2. SAVE THE ORIGINAL DRIVE ORDER * ;* * ;******************************************************** SETDRV: DB 2Eh ;DJDMA SET LOGICAL DRIVE COMMAND ORDR58: DB 4 ;SET ORDER OF 8" AND 5-1/4" DRVS PHYDRV: DB 0 ;STATUS BYTE DB 25H ;DJDMA HALT CONTROLLER COMMAND PHYHLT: DB 00 ;STATUS BYTE MFFRST: LD HL,SETDRV ;START ADDR OF BLOCK TO TRANSFER BYTES FROM LD DE,0050h ;START ADDRESS OF BLOCK TO TRANSFER BYTES TO LD BC,5 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER OUT (0EFh),A ;KICK DJDMA PHYDON: LD A,(PHYHLT-SETDRV+50h) ;HAS DJDMA HALT INSTRUCTION COMPLETED ? OR A JP Z,PHYDON ;TRY AGAIN IF NOT RET ;**************************************************************** ;* * ;* SUBROUTINE MOTRUN * ;* * ;* KEEP MOTOR RUNNING IF MOTOR ON (MOTOGL=1) SELECTED * ;* DO THIS BY GIVING THE READ SECTOR COMMAND * ;* * ;**************************************************************** MOTRUN: LD A,(MOTOGL) ;0=MOTOR OFF 1=ON CP 0 RET Z ;RETURN IF DESIRED OFF CALL RUNONE ;GIVE A READ SECTOR COMMAND (MAKES MOTOR RUN) RET ;**************************************************************** ;* * ;* SUBROUTINE RDTAIL * ;* * ;* READS THE COMMAND TAIL (e.g. A> FSTEP 8 ), DETERMINES * ;* IF FOR 5 1/4 OR FOR 8" DRIVES. IF FOR 8" PATCHES * ;* THE PROGRAM ACCORDINGLY. IF FOR 5" DOES NOT PATCH AS * ;* PROGRAM IS ALREADY SET UP FOR 5 1/4" DRIVES. * ;* * ;* IF FOR MICRODECION, PATCHES THE PROGRAM ACCORDINGLY * ;* * ;**************************************************************** RDTAIL: LD A,(80h) ;FIND NUMBER OF BYTES IN COMMAND TAIL CP 2 ;OK IF 2 BYTES (A SPACE AND HOPEFULLY A DIGIT) JP NZ,ERRMSG ;NOT OK IF NOT 2 BYTES, GIVE ERROR MESSAGE LD A,(82h) ;LOAD THE ASCII CHARACTER FROM THE TAIL cp 'm' ;see if tail character is an 'm' jp z,mdpatch ;patch to work with microdecision drives cp 'M' ;see if tail character is an 'M' jp z,mdpatch ;patch to work with microdecision drives CP '5' ;SEE IF TAIL CHARACTER IS A '5' JP Z,D1INIT ;DON'T PATCH SCREEN, DO DECISION 1 INITIALIZE;RET Z ;NO PATCHING NEEDED, BEGIN PROGRAM CP '8' ;WASN'T A '5', IS IT AN '8'? JP NZ,ERRMSG ;NOT A '5' OR '8' SO GIVE ERROR MESSAGE ;* PATCH FSTEP TO WORK WITH 8" INSTEAD OF 5" DRIVES * patch8: LD A,0 LD (ORDR58),A ;SET ORDER TO 8" FOLLOWED BY 5" DRIVES LD DE,MOT5 ;START ADDRESS TO TRANSFER BLOCK TO LD HL,MOT8 ;START ADDRESS TO TRANSFER BLOCK FROM LD BC,MOT8ND-MOT8 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER LD DE,DRVSIZ ;START ADDRESS TO TRANSFER BLOCK TO LD HL,SIGNON ;START ADDRESS TO TRANSFER BLOCK FROM LD BC,SIGNND-SIGNON ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER LD DE,OFFMSG ;START ADDRESS TO TRANSFER BLOCK TO LD HL,OFFMS8 ;START ADDRESS TO TRANSFER BLOCK FROM LD BC,OFFND8-OFFMS8 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER LD DE,ONMSG ;START ADDRESS TO TRANSFER BLOCK TO LD HL,ONMS8 ;START ADDRESS TO TRANSFER BLOCK FROM LD BC,ONND8-ONMS8 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER LD A,8 ;FOR CHANGE TO 8 POSSIBLE DIGITS LD (TRHCNT),A ;NUMBER OF POSSIBLE TENS DIGITS IN TRACK NUMBER LD A,'7' ;FOR CHANGE TO MAX 77 TRACKS LD (TRHDIG),A ;HIGHEST POSSIBLE ASCII TENS DIGIT IN TRACK LD A,41d ;FOR CHANGE TO HEAD LOAD/UNLOAD LD (MOTOR+1),A ;MOTOR ON-OFF COLUMN ADDRESS LD A,'H' ;PATCH MOTOR ON/OFF CHARACTER FOR LD (MOTCHR+1),A ;HEAD LOAD/UNLOAD LD A,'h' LD (MOTCHR+6),A LD A,76d ;FOR CHANGE TO 76 TRACKS LD (HITRAK+1),A ;HIGHEST TRACK NUMBER D1INIT: CALL DESEL ;SET DJDMA TO FASTEST DRIVE DESELECT TIME CALL RETRYS ;SET DJDMA TO LOWEST NUMBER OF RETRYS CALL MFFRST ;ORDER 5 1/4" BEFORE 8" DRIVES CALL DRVORD ;SAVE THE ORIGINAL DEFAULT DISC RET ;PATCHING COMPLETED ERRMSG: LD C,9 ;BDOS PRINT STRING FUNCTION LD DE,USEAGE ;STRING TO PRINT CALL BDOS JP 0 ;WARM BOOT USEAGE: DB CR,LF DB 'usage:' DB CR,LF,LF DB 'FSTEP 5 for 5 1/4" drives controlled by DJDMA' DB CR,LF DB 'FSTEP 8 for 8" drives controlled by DJDMA' db cr,lf db 'FSTEP M for 5 1/4" drives controlled by MicroDecision' DB CR,LF,'$' SIGNON: DB 'DJDMA 8" FLOPPY DRIVE ALIGNMENT TOOL ' SIGNND EQU $ OFFMS8: DB 'UNLOADED$' OFFND8 EQU $ ONMS8: DB 'LOADED $' ONND8 EQU $ MOT8: DB ' HEAD UNLOADED' DB CR,LF,'(H)ead loaded/unloaded' MOT8ND EQU $ ;************************************************************************* ;* * ;* PATCH THE SCREEN DISPLAY FOR USE WITH MICRODECISION CONTROLLED * ;* DRIVES * ;* * ;************************************************************************* mdpatch:ld a,1 ;1=microdecision controlled drive ld (mdflag),a ;store flag indicating microdec. for later use LD DE,DRVSIZ ;START ADDRESS TO TRANSFER BLOCK TO LD HL,mdSIGN ;START ADDRESS TO TRANSFER BLOCK FROM LD BC,mdSIGND-mdSIGN ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER RET ;PATCHING COMPLETED mdflag: db 0 ;0=djdma; 1=microdecision controlled drive mdSIGN: DB 'MICRODECISION FLOPPY DRIVE ALIGNMENT TOOL' mdSIGND EQU $ ;**************************************************************** ;* * ;* SUBROUTINE RETRYS * ;* * ;* SETS THE NUMBER OF RETRYS THE DJDMA MAKES WHEN A CRC * ;* ERROR OCCURS IN THE DATA FIELD. * ;* * ;**************************************************************** RETCOM: DB 28h ;SET ERROR RETRY COUNT COMMAND RETNUM: DB 01 ;INITIALIZE TO LOWEST NUMBER DB 25h ;DJDMA HALT CONTROLLER COMMAND RETHLT: DB 00 ;STATUS BYTE RETRYS: LD HL,RETCOM ;START ADDRESS OF BLOCK TO TRANSFER FROM LD DE,0050h ;START ADDR OF BLOCK TO TRANSFER TO LD BC,04 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER OUT (0EFh),A ;START THE DJDMA RETDON: LD A,(RETHLT-RETCOM+50h);ACTUAL HALT STATUS BYTE ADDRESS OR A ;HAS HALT COMMAND COMPLETED ? JP Z,RETDON RET ;**************************************************************** ;* * ;* SUBROUTINE RUNONE * ;* * ;* GIVE ONE READ SECTOR COMMAND. THIS MAKES THE MOTOR * ;* RUN FOR 5 1/4" DRIVES (OR THE HEAD LOAD FOR 8" * ;* DRIVES) * ;* * ;**************************************************************** MOTCMD: DB 20h ;DJDMA READ SECTOR COMMAND MOTTRK: DB 16 ;TRACK #(FILLED BY ROUTINE TRACK) MOTSS: DB 00000011b ;BIT 7=SIDE, LOW NIBBLE=SECTOR MOTDRV: DB 0 ;DRIVE #(FILLED BY ROUTINE SELDRV) DB 00 ;STATUS BYTE DB 25h ;DJDMA HALT CONTROLLER COMMAND MOTHLT: DB 00 ;STATUS BYTE RUNONE: ld a,(mdflag) ;0=djdma, 1=microdecision or a jp nz,mddrv ;run the djdma controlled motor LD HL,MOTCMD ;START ADDRESS OF BLOCK TRANSFER FROM LD DE,0050h ;START ADDR OF BLOCK TO TRANSFER TO LD BC,07 ;NUMBER OF BYTES TO TRANSFER LDIR ;DOES THE TRANSFER OUT (0EFh),A ;START THE DJDMA DONYET: LD A,(MOTHLT-MOTCMD+50h);DOES HALT INSTRUCTION STATUS BYTE OR A ;INDICATE INSTRUCTION COMPLETED ? JP Z,DONYET RET ;run the microdecision controlled motor mddrv: ld a,(motdrv) ;get the drive number (0-3) ld b,00010000b ;upper four bits will drive drive select lines mddrv1: or a ;see if correct drive has been reached jp z,mdmotr ;correct bit is now set for the selected drive dec a ;try the next drive rlc b ;select next drive higher drive bit jp mddrv1 ;loop mdmotr: ld a,(motdrv) ;get the drive number (0-3) or a ;see if drive 0 ld a,1 ;we're prepared if it is drive 0 jp z,drivon ;go turn on drive 0 motor (bits 0,1 select mtr) inc a ;must be drive 1, 2,or 3 (md wants only 1 or 2) drivon: or b ;add in the drive select line to motor line out (0F7h),a ;turn on selected microdecision drive ret ;**************************************************************** ;* * ;* SUBROUTINE TRKCRT * ;* * ;* 1. MOVE CURSOR TO TRACK NUMBER DISPLAY ON CRT * ;* 2. PRINT THE TWO ASCII TRACK DIGITS ON CRT * ;* * ;**************************************************************** TRKCRT: LD B,2Ah ;COLUMN ADDRESS (NO OFFSET) LD C,09d ;ROW ADDRESS (NO OFFSET) CALL CURADD ;MOVE CURSOR TO TRACK NUMBER POSITION LD C,6 ;BDOS DIRECT CONSOLE I/O LD A,(DIGIT1) LD E,A ;PRINT THE FIRST DIGIT CALL BDOS LD C,6 ;BDOS DIRECT CONSOLE I/O LD A,(DIGIT2) ;PRINT THE SECOND DIGIT LD E,A CALL BDOS RET ;************************************************************************ ;* * ;* SUBROUTINE TRKHEX * ;* * ;* CONVERT THE TWO ASCII TRACK DIGITS TO A HEX BYTE AND LOAD IT * ;* INTO THE DJDMA READ SECTOR COMMAND * ;* * ;************************************************************************ TRKHEX: XOR A LD (MOTTRK),A ;INITIALIZE AT LOWEST TRACK (0) LD A,(DIGIT1) ;ASCII TENS TRACK DIGIT SUB 30h ;NOW HEX TENS TRACK DIGIT CP 0 JP Z,ONES ;THERE ARE NO TENS LD B,A LD A,(MOTTRK) ;INITIALIZED AT LOWEST TRACK (0) ADDTEN: ADD A,10d DJNZ ADDTEN LD (MOTTRK),A ;TEMPORARY STORAGE ONES: LD A,(DIGIT2) ;ASCII ONES TRACK DIGIT SUB 30h ;NOW HEX ONES TRACK DIGIT CP 0 RET Z ;THERE ARE NO ONES TO ADD LD B,A LD A,(MOTTRK) ADDONE: ADD A,1 DJNZ ADDONE LD (MOTTRK),A ;INSERT HEX TRACK NUMBER IN STRING LD (MDTRAK),A ;INSERT HEX TRACK NUMBER IN MICRODEC STRING ld a,(mdflag) ;0=djdma, 1=microdecision or a jp nz,mdseek ;if a microdecision, go do the seek RET ;************************************************************************ ;* * ;* SUBROUTINE MDSEEK * ;* * ;* STEPS THE MICRODECISION CONTROLLED DRIVE HEAD TO THE TRACK * ;* SPECIFIED IN BYTE MDTRK. THE SEEK COMMAND IS A THREE BYTE * ;* COMMAND. * ;* * ;************************************************************************ MDSEEK: CALL MDSTAT ;GET THE STATUS OF THE 765 CONTROLLER CHIP CALL MDDLY ;DELAY 12.5 uS LD A,0Fh ;NEC 765 SEEK COMMAND CODE OUT (0FBh),A ;SEND SEEK COMMAND TO NEC 765 DATA PORT CALL MDDLY ;DELAY 12.5 uS LD A,0 ;BIT 2 SELECTS THE DRIVE HEAD MDSIDE EQU $-1 ;FOR CONVENIENT PATCHING BY SUBROUTINE SIDSEL OUT (0FBh),A ;BYTE 2 OF SEEK COMMAND CALL MDDLY ;DELAY 12.5 uS LD A,16 ;BYTE 3 SELECTS THE CYLINDER NUMBER (0-39) MDTRAK EQU $-1 ;FOR PATCHING BY SUBROUTINE TRKHEX OUT (0FBh),A ;*THE FOLLOWING COMMAND TERMINATES SEEK AND RECALIBRATE COMMANDS* CALL MDDLY ;DELAY 12.5 uS LD A,08 ;SENSE INTERRUPT STATUS COMMAND(CLEARS FDD0-3) OUT (0FBh),A ;ISSUE THE COMMAND IN A,(0FBh) ;READ STATUS 0 IN A,(OFBh) ;READ PRESENT CYLINDER NUMBER RET ;************************************************************************ ;* * ;* SUBROUTINE MDSTAT * ;* * ;* READS MICRODECISION PORT 0FAh TO GET THE STATUS OF THE NEC 765 * ;* CONTROLLER CHIP. * ;* * ;************************************************************************ MDSTAT: CALL MDDLY ;DELAY 12.5 uS IN A,(0FAh) ;READ NEC 765 STATUS PORT AND 0Fh ;keep lower 4 bits (fdd0-fdd3 busy) OR A RET ;************************************************************************ ;* * ;* SUBROUTINE MDDLY * ;* * ;* DELAYS 12 uS. 12uS IS THE MINIMUM TIME REQUIRED BETWEEN BYTES * ;* BEING OUTPUT TO THE NEC 765. * ;* 12.5uS = (50 CYCLES)/(4 MHZ) * ;* * ;************************************************************************ MDDLY: EX (SP),IX ;23 CLOCK CYCLES TO EXECUTE THIS INSTRUCTION EX (SP),IX ;23 MORE CLOCK CYCLES RET ; 1 CLOCK CYCLE FOR RET (3 CYCLES FOR CALL) END