;***************************************************************************** ;* * ;* 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 * ;* latest work done 05/29/86 * ;***************************************************************************** .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 report equ 0 ;set non-zero for microdecision troubleshooting 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 ld a,(mdflag) ;0=djdma, 1=microdecision or a jp z,comand ;if a djdma, don't do the following code call mdrcal ;recalibrate drive 0 1X only-also prints to CRT 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 * ;* * ;* DETERMINE IF A DJDMA OR A MICRODECISION IS INVOLVED * ;* AND CALL THE APPROPRIATE SUBROUTINE. * ;* * ;**************************************************************** RECAL: ld a,(mdflag) ;0=djdma, 1=microdecision or a PUSH PSW CALL Z,DJRCAL ;recalibrate the DJDMA controlled drive POP PSW CALL NZ,MDRCAL ;RECALIBRATE THE MICRODECISION CONTROLLED DRIVE JP COMAND ;**************************************************************** ;* * ;* DJRCAL SUBROUTINE * ;* * ;* 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 DJRCAL: 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 RET ;**************************************************************** ;* * ;* MDRCAL ROUTINE * ;* * ;* RECALIBRATE THE MICRODECISION CONTROLLED DRIVE BY: * ;* 1. GIVING THE NEC 765 RECALIBRATE COMMAND (WHICH * ;* STEPS OUT A MAXIMUM OF 77 TRACKS UNTIL THE * ;* TRACK 0 LINE GOES TRUE. * ;* 2. TERMINATE THE COMMAND BY GIVING THE NEC 765 * ;* SENSE INTERRUPT STATUS COMMAND. * ;* * ;**************************************************************** mdrcal: CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A COMMAND BYTE LD A,07h ;NEC 765 RECALIBRATE COMMAND CODE OUT (0FBh),A ;SEND RECALIBRATE COMMAND TO NEC 765 DATA PORT CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A COMMAND BYTE LD A,(MOTDRV) ;BITS 0 (=US0) AND 1 (=US1) SELECT THE DRIVE OUT (0FBh),A ;SEND SECOND COMMAND BYTE TO NEC 765 DATA PORT CALL RESULT ;PERFORM NEC 765 SENSE INTERRUPT STATUS COMMAND call mdpcn ;get pointer to present drive's PCN in hl LD A,(hl) ;present drive's present track number call mkasci ;convert the hex track number to ascii chars call trkcrt ;print the new track number on crt RET ;**************************************************************** ;* * ;* 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 FOR USE BY DJDMA CALL BDOS ld a,(mdflag) ;0=djdma, 1=microdecision or a jp z,comand ;if a djdma, don't do the following code ;*TEST FOR MICRODECISION DRIVES WHICH HAVE NEVER BEEN CALIBRATED BY FSTEP call mddrv ;so hardware selects the new drive call mdpcn ;get pointer to present drive's PCN in hl LD A,(hl) ;present drive's present track number cp 0FFh ;will be 0ffh if fstep has never moved drive hd jp nz,caldon ;if drive has already been calibrated call mdrcal ;recalibrate the new drive(also prints to CRT) jp comand ;return for next command caldon: call mkasci ;convert the hex track number to ascii chars call trkcrt ;print the new drive's track number on the CRT 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,(mdflag) ;0=djdma, 1=microdecision or a jp nz,mdstpi ;if a microdecision, do the md step in routine ;*DECISION 1 STEP IN ROUTINE 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 1F 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 ;*microdecision step in routine mdstpi: call mdpcn ;get pointer to present drive's PCN in hl LD A,(hl) ;present drive's present track number CP 39d ;HIGHEST ALLOWED TRACK NUMBER JP Z,COMAND ;DON'T STEP IN IF ALREADY AT 39 inc a ;INCREMENT TRACK NUMBER BY 1 ld (mdtrak),a ;insert the track number into microd seek cmd call mkasci ;convert the hex track number to ascii chars call trkcrt ;print the new track number on crt call mdseek ;go do the seek 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,(mdflag) ;0=djdma, 1=microdecision or a jp nz,mdstpo ;if a microdecision, do the md step out routine 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 ;*microdecision step out routine mdstpo: call mdpcn ;get pointer to present drive's PCN in hl LD A,(hl) ;present drive's present track number CP 0 ;LOWEST ALLOWED TRACK NUMBER JP Z,COMAND ;DON'T STEP OUT IF ALREADY AT TRACK 0 dec a ;DECREMENT TRACK NUMBER BY 1 ld (mdtrak),a ;insert the track number into microd seek cmd call mkasci ;convert track number to ascii characters call trkcrt ;print the new track number on crt call mdseek ;go do the seek jp comand ;go get next command from terminal ;**************************************************************** ;* * ;* SUBROUTINE MKASCI * ;* * ;* 1. ON ENTRY, A CONTAINS THE HEX TRACK NUMBER THAT WAS * ;* STORED BY NEC 765 RESULT COMMAND. * ;* 2. CONVERT IT TO TWO ASCII DIGITS AND STORE THEM FOR * ;* USE BY THE TRKCRT ROUTINE (WHICH PRINTS THEM TO THE * ;* CRT. * ;* * ;**************************************************************** mkasci: ld b,'0' ;initialize ascii tens digit of track number tens: push psw ;save the hex track number ld a,b ld (digit1),a ;store the ascii tens digit of track number pop psw ;retrieve the hex track number sub 10 ;find number of tens in the hex track number jp c,lodigt ;if less then 10 remained in reg A inc b jp tens lodigt: add a,10 ;add the 10 that was subtracted to mk neg # ld b,'0' ;initialize ascii tens digit of track number oneslp: push psw ;save the hex track number ld a,b ld (digit2),a ;store the ascii tens digit of track number pop psw ;retrieve the hex track number sub 1 ;find number of tens in the hex track number ret c ;*return* if less then 10 remained in reg A inc b jp oneslp ;**************************************************************** ;* * ;* 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. * ;* * ;**************************************************************** ;*use microdecision sense drive status command to get status byte 3 (st3) and ;*to select the side GETCHR: ld a,(mdflag) ;0=djdma, 1=microdecision or a jp z,CHARIN ;if a microdecision is not being run CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A NEW COMMAND? LD A,04 ;SENSE DRIVE STATUS COMMAND OUT (0FBh),A ;ISSUE THE COMMAND CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A COMMAND BYTE LD a,(mdside) ;BIT 2 SELECTS THE HEAD ld b,a LD A,(MOTDRV) ;BIT 0=US0, BIT 1=US1 FOR DRIVE SELECTION OR B ;MERGE HEAD SELECT BITS WITH DRIVE SELECT BITS OUT (0FBh),A ;BYTE 2 OF DRIVE STATUS COMMAND ;*NOTE: reading the result is delayed until later in the getchr routin in order ;*to keep side one selected (if it is) as long as possible charin: CALL MOTRUN LD C,06 ;BDOS DIRECT CONSOLE I/O LD E,0FFh ;FOR CONSOLE INPUT CALL BDOS CP 0 ;IF 0 THEN NO CHARACTER WAS READY JR Z,charin ;TRY AGAIN TO GET A CHARACTER PUSH AF ;preserve the character and the flag ld a,(mdflag) ;0=djdma, 1=microdecision or a jp z,CHRINA ;if a microdecision is not being run CALL RDRDY ;IS DATA PORT READY TO SEND A RESULT BYTE? IN A,(0FBh) ;READ STATUS 3 chrina: POP AF ;retrieve the character and the flag 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,(mdflag) ;0=djdma, 1=microdecision ld b,a LD A,(MOTOGL) ;0=MOTOR OFF 1=ON or b ;test if djdma or microdecision CP 0 call nz,RUNONE ;not called only if is djdma and motor is off 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,(MOTOGL) ;SEE IF MOTOR HAS BEEN SELECTED TO BE ON OR A ; 0=OFF 1=ON JP Z,DRIVON ;IF MOTOR IS NOT SUPPOSED TO BE ON 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 * ;* used only by the Decision 1 * ;* 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 (mdtrak),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 ld (mdtrak),a ;store the tens count in the microdecsn string ONES: LD A,(DIGIT2) ;ASCII ONES TRACK DIGIT SUB 30h ;NOW HEX ONES TRACK DIGIT CP 0 jp z,hexend;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 hexend: 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 CMDRDY ;IS DATA PORT READY TO RECEIVE A COMMAND BYTE LD A,0Fh ;NEC 765 SEEK COMMAND CODE OUT (0FBh),A ;SEND SEEK COMMAND TO NEC 765 DATA PORT CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A COMMAND BYTE LD B,0 ;BIT 2 SELECTS THE HEAD (PATCHED BY SIDSEL) MDSIDE EQU $-1 ;FOR CONVENIENT PATCHING BY SUBROUTINE SIDSEL LD A,(MOTDRV) ;BIT 0=US0, BIT 1=US1 FOR DRIVE SELECTION OR B ;MERGE HEAD SELECT BITS WITH DRIVE SELECT BITS OUT (0FBh),A ;BYTE 2 OF SEEK COMMAND CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A COMMAND BYTE LD A,16 ;BYTE 3 SELECTS THE CYLINDER NUMBER (0-39) MDTRAK EQU $-1 ;FOR PATCHING BY SUBROUTINE TRKHEX OUT (0FBh),A CALL RESULT ;SENSE INTERRUPT STATUS (TO TERMINATE COMMAND) RET ;************************************************************************ ;* * ;* SUBROUTINE RESULT * ;* THIS ROUTINE PERFORMS THE SENSE INTERRUPT STATUS COMMAND OF * ;* THE NEC 765 DISK CONTROLLER. IT IS NECESSARY TO PERFORM THIS * ;* COMMAND FOLLOWING SEEK AND RECALIBRATE COMMANDS IN ORDER TO * ;* PROPERLY TERMINATE THEM. * ;* * ;************************************************************************ PCNTBL: ;0FFh = FSTEP HAS NEVER ACCESSED THIS DRIVE MDPCN0: DB 0FFh ;MICRODECISION DRIVE 0 PRESENT CYLINDER NUMBER MDPCN1: DB 0FFh ;MICRODECISION DRIVE 1 PRESENT CYLINDER NUMBER MDPCN2: DB 0FFh ;MICRODECISION DRIVE 2 PRESENT CYLINDER NUMBER MDPCN3: DB 0FFh ;MICRODECISION DRIVE 3 PRESENT CYLINDER NUMBER result: CALL CMDRDY ;IS DATA PORT READY TO RECEIVE A NEW COMMAND? LD A,08 ;SENSE INTERRUPT STATUS COMMAND(CLEARS FDD0-3) OUT (0FBh),A ;ISSUE THE COMMAND CALL RDRDY ;IS DATA PORT READY TO SEND A RESULT BYTE? IN A,(0FBh) ;READ STATUS 0 IF REPORT NE 0 ;USED FOR TROUBLESHOOTING push psw call tblpnt ;~tblpnt temporary for trouble reporting ld c,6 ;~bdos direct console i/o ld e,'r' ;~character to output call bdos ;~^^^^^^^for troubleshooting^^^^^^^^^^^ pop psw ENDIF and 11000000b ;save the interrupt code cp 10000000b ;bit 7=1, 6=0 --> invalid command-never started jp z,result ;if invalid command, start command over CALL RDRDY ;IS DATA PORT READY TO SEND A RESULT BYTE? CALL MDPCN ;RETURNS POINTER IN HL TO PRESENT DRIVES PCN IN A,(0FBh) ;READ PRESENT CYLINDER NUMBER LD (HL),A ;STORE PCN IN APPROPRIATE BYTE FOR PRESENT DRIV IF REPORT NE 0 ;USED FOR TROUBLESHOOTING call tblpnt ;~ ld c,6 ;~bdos direct console i/o ld e,'c' ;~character to output call bdos ;~^^^^^^^for troubleshooting^^^^^^^^^^^ ENDIF RET ;************************************************************************ ;* * ;* SUBROUTINE MDPCN * ;* * ;* FOR THE MICRODECISION, RETURNS A POINTER IN HL TO THE PRESENT * ;* DRIVES PRESENT CYLINDER NUMBER. THE TABLE IS FILLED BY STORING * ;* THE RESULTS OF THE NEC 765 SENSE INTERRUPT STATUS COMMAND * ;* (RESULT SUBROUTINE). * ;* * ;************************************************************************ MDPCN: LD HL,PCNTBL-1 ;TABLE OF EACH OF 4 DRIVES PRESENT CYLINDER #s LD A,(MOTDRV) ;PRESENT DRIVES NUMBER INC A NEXTDR: INC HL ;DEVELOP A POINTER (IN HL) TO BYTE FOR PRESENT DEC A ; CYLINDER NUMBER FOR PRESENT DRIVE JP NZ,NEXTDR RET ;************************************************************************ ;* * ;* SUBROUTINE CMDRDY * ;* * ;* READS MICRODECISION PORT 0FAh TO GET THE STATUS OF THE NEC 765 * ;* CONTROLLER CHIP. THIS IS A CHECK TO SEE IF THE CHIP IS READY * ;* FOR THE NEXT BYTE OF THE COMMAND. * ;* * ;************************************************************************ CMDRDY: CALL MDDLY ;DELAY 12.5 uS IN A,(0FAh) ;READ NEC 765 STATUS PORT AND 11000000b ;MASK OUT SOME BITS CP 10000000b ;IS DATA PORT READY TO RECEIVE DATA? JP NZ,CMDRDY ;LOOP UNTIL READY RET ;************************************************************************ ;* * ;* SUBROUTINE RDRDY * ;* * ;* READS MICRODECISION PORT 0FAh TO GET THE STATUS OF THE NEC 765 * ;* CONTROLLER CHIP. THIS IS A CHECK TO SEE IF THE CHIP IS READY * ;* FOR THE NEXT BYTE OF THE RESULT. * ;* * ;************************************************************************ RDRDY: CALL MDDLY ;DELAY 12.5 uS IN A,(0FAh) ;READ NEC 765 STATUS PORT anä 11000000b ;savå DATÁ INPUT/OUTPUT,REQUESÔ FOÒ MASTEÒ BITS CP 11000000b ;IS DATA PORT READY TO SEND DATA? JP NZ,RDRDY ;LOOP UNTIL READY IF REPORT NE 0 ;USED FOR TROUBLESHOOTING call tblpnt ;~ push psw ;~ ld e,'s' ;~ ld c,6 ;~ call bdos ;~ pop psw ;~ ENDIF 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) ;************************************************************************ ; temproarilyr for trouble reporting ; saves the a register ;************************************************************************ IF REPORT NE 0 ;USED FOR TROUBLESHOOTING tblpnt: ld h,a ;~save for reuse ld a,' ' ;prepare to print a space call is09 ld a,h rlc a ;~get upper nybble rlc a ;~ rlc a ;~ rlc a ;~ call tblout ;~ ;~ ld a,h ;~ call tblout ;~ ld a,h ;~ ret ;~ tblout: and 0fh ;~mask upper four bits or 30h ;~make ascii digit cp 3Ah ;~is it a 0-9 or A-F? jp c,is09 ;~it is a digit 0-9 add a,7 ;~make it A-F is09: ld e,a ;~ready to be printed ld c,6 ;~bdos direct console i/o push hl ;~ call bdos ;~^^^^^^^^for troubleshooting^^^^^^^^^^^ pop hl ;~ ret ;~ ENDIF END