0A>type b:FDC85.MAC PAGE 65 TITLE FDC8/5 VERSION 2.2 (29.11.82) .Z80 .PHASE 100H ; ORG 100H ; ; TEST PROGRAMS FOR THE H.K.M-FLOPPY- ; DISC CONTOLLER FDC 8/5 REV.1 ; COPYRIGHT 1981 H.K.M ; ; DISK TIMING ; LONGEST TIMING FOR TEST ; REPLACE WITH VALUES OF YOUR DISK ; DEFINE HEADLOAD, STEPRATE AND HEADUNLOADTIME ; HLT EQU 240 ; HEADLOADTIME IN MS (8 MHZ CLOCK) SRT EQU 14 ; STEPRATETIME IN MS (8 MHZ CLOCK) HUT EQU 240 ; HEADUNLOADTIME IN MS (8 MHZ CLOCK) ; HLTS EQU ((HLT-1)/2)*2 HUTS EQU (HUT+15)/16 SRTS EQU 16-SRT ; ; DISK LAYOUT FOR MINIDISKS (200 or 400 KBYTE) ; ; DOUBLE DENSITY ; 40 TRACKS / DISK or SIDE ; 10 SECTORS / TRACK ; 512 BYTE / SECTOR ; MAXSEC EQU 10 ; 10 SECTORS FMTGAP EQU 1EH ; END GAP LENGTH ; ; RETRY COUNTER (NORM. 10 TIMES) ; RETRY EQU 10 ; ; DISK LAYOUT FOR 8" DISKS (577,5 or 1145 KBYTE) ; ; DOUBLE DENSITY ; 77 TRACKS / DISK or SIDE ; 15 SECTORS / TRACK ; 512 BYTE / SECTOR ; ;MAXSEC EQU 15 ; 15 SECTORS ;FMTGAP EQU 1BH ; END GAP LENGTH ; ; I/O PORTS ; FDC EQU 0 ; STATUS PORT FDD EQU FDC+1 ; DATA PORT FTC EQU FDD+1 ; SECTOR TERMINATION DMA EQU FTC+1 ; DMA I/O ADDRESS ; VECTOR: DEFW TERMI ; INTERRUPT VECTOR ; CMDTAB: DEFB 0 ; COMMAND BYTE UNIT: DEFB 0 ; UNIT (0...3) TRACK: DEFB 0 ; TRACK (0...39/77) DEFB 0 ; HEAD (0 for SIDE 0, 1 for SIDE 1) ; single sided is SIDE 0 only! SECTOR: DEFB 0 ; SECTOR (1...10/15) DEFB 2 ; N = 512 Bytes/Sector DEFB MAXSEC ; MAX SECTORS DEFB 10H ; READ/WRITE-GAP LENGTH DEFB 2 ; DATA-LENGTH (128 BYTE SECTORS only!) ; ; RESULT-TABLE ; FOR READ, WRITE, FORMAT AND READ ID ; REST: DEFB 0 ; STATUS 0 ; D7 & D6 = 00 normal Termination ; = 01 started, not succesful ; = 10 Invalid command, not started ; = 11 Floppy-Ready-Line Changes ; D5 = 1 Seek completed ; D4 = 1 Fault from Floppy or ; not Track 0 after 77 steps ; D3 = 1 Floppy not ready ; D2 = Head Address at Interrupt ; D1 & D0 = Unit-Number at Interrupt DEFB 0 ; STATUS 1 ; D7 = 1 End of Cylinder ; D6 = 0 not used ; D5 = 1 CRC-Error ; D4 = 1 Overrun, uPD765 not serviced ; during READ, WRITE or FORMAT ; D3 = 0 not used ; D2 = 1 ID not found ; D1 = 1 not writable (write protected) ; D0 = 1 Missing Address Mark DEFB 0 ; STATUS 2 ; D7 = 0 not used ; D6 = 1 deleted Address-Mark ; D5 = 1 CRC-Error in Data-Field ; D4 = 1 Wrong Cylinder ; D3 = 1 Scan equal hit ; D2 = 1 Scan not satisfied ; D1 = 1 Bad cylinder ; D0 = 1 Missing Address-Mark in Data DEFB 0 ; TRACK DEFB 0 ; HEAD DEFB 0 ; SECTOR DEFB 0 ; N (SECTOR-LENGTH) ; ; SET INTERRUPT MODE 2 ; used for DMA and IM2 Mode (first to call) ;****** INIDMA: ; NO PARAMETERS ;****** DI ; DISABLE LD A,HIGH(VECTOR) ; LOAD INTERRUPT VECTOR LD I,A IM 2 ; VECTOR INTERRUPT EI INID: RET ; ; INITIALIZE UPD 765 C ; ( SOFT RESET ) ; for both modes, DMA and NON-DMA (first access to uPD765) ;****** INIFDC: ; NO PARAMETERS ;****** LD B,0 ; SOFT RESET LOOP: DJNZ LOOP IN A,(FDC) CP 80H ; REQUEST FOR MASTER JR Z,INI1 ; OK IN A,(FDD) ; ELSE FETCH DATA JR INIFDC INI1: RET ; DONE ; ; SPECIFY DISK PARAMETERS DMA-MODE !! ; DMA-Mode only!, specify drive-parameters ; head-load-time, step-rate-time and head-unload-time ;***** SPECD: ; NO PARAMETERS ;***** LD HL,(UNIT) PUSH HL LD HL,HLTS*256+SRTS*16+HUTS ; TIMING FOR DISK LD BC,0303H ; 3 BYTES FOR SPECIFY LD (UNIT),HL CALL CMFD ; TRANSMIT COMMAND POP HL LD (UNIT),HL SPE1: RET ; ; SPECIFY DISC PARAMETERS NON-DMA-MODE !! ; NON-DMA-Mode only!, specify drive-parameters ; head-load-time, step-rate-time and head-unload-time ;**** SPEC: ; NO PARAMETERS ;**** LD HL,(UNIT) PUSH HL LD HL,HLTS*256+256+SRTS*16+HUTS LD BC,0303H LD (UNIT),HL CALL CMFD POP HL LD (UNIT),HL SPE2: RET ; ; MOVE HEAD TO HOME POSITION ; to move head to track 0, in uPD765's Track-Register is 0 after RESET ; neccessary one time for each Unit after RESET ;***** RECAL: ; PARAMETERS: UNIT ;***** LD BC,0207H ; RECALIBRATE CALL MOTO ; WAIT FOR DISK CALL SENS ; RECAL. FINISHED ? REC1: RET ; ; SEEK TRACK ; used to move the Head to a specified Track ;**** SEEK: ; PARAMETERS: UNIT, TRACK ;**** LD BC,030FH ; SEEK TRACK CALL MOTO ; SEEK FINISHED ? SENS: LD BC,0108H ; SENSE DRIVE CALL CMFD CALL NEXT ; FETCH RESULT PUSH AF ; SAVE RESULT CP 80H ; INVALID COMMAND ? CALL NZ,NEXT ; NO => NEXT RESULT POP AF ; FIRST RESULT BIT 5,A ; SEEK FINISHED ? JR Z,SENS ; NO => WAIT SK1: RET ; YES => ALL DONE ; ; READ ID-FIELD ; to find the actual Track, read double density ;***** RDIDF: ; PARAMETERS: UNIT ;***** LD BC,024AH ; READ ID CALL MOTO CALL RESULT ; FETCH RESULTS RDID1: RET ; ; SENSE DRIVE STATUS ; ;**** SDRS: ; PARAMETERS: UNIT ;**** LD BC,0204H ; SENSE DRIVE CALL CMFD CALL NEXT ; A=STATUS 3 SD1: RET ; D7 = Fault ; D6 = Write Protected ; D5 = Ready ; D4 = Track 0 ; D3 = two sided ; D2 = Head-Address ; D1,D0 = Unit ; ; WRITE 512-SECTOR TO DISK IN DMA-MODE ; only possible in DMA-Mode ;****** WR512D: ; PARAMETERS: UNIT, TRACK, SECTOR ;****** LD B,RETRY ; RETRY COUNTER WR0: PUSH BC ; SAVE COUNTER LD BC,0945H ; WRITE CALL MOTO LD BC,CWLEN*256+DMA ; MEM TO DISK LD HL,CWRT ; SETUP DMA OTIR ; AND START DMA CALL RESULT ; TERMINATE AND ; FETCH RESULTS POP BC ; UNSAVE COUNTER JR Z,WR1 ; NO ERROR DJNZ WR0 ; ERROR => TRY AGAIN ; FATAL ERROR ; RETURNS WITH A = 0 IF NO ERROR ; AND WITH A .NE. 0 IF ERRORS OCCURED WR1: RET ; ; WRITE 512 SECTOR TO DISK NON DMA MODE !! ; NON-DMA-Mode only ! ;***** WR512: ; PARAMETERS: UNIT, TRACK, SECTOR ;***** LD B,RETRY ; RETRY COUNTER WR5: PUSH BC ; SAVE COUNTER LD BC,0945H ; WRITE CALL MOTO LD HL,DBUF ; .BUFFER LD BC,FDD ; 256 BYTES, DATA PORT LD DE,WR99 ; EXEC-END-ADDRESS PUSH DE ; ON STACK LD E,0A0H ; RQM AND ECEX-END MASK WR6: IN A,(FDC) ; REQUEST FOR MASTER ? AND E ; EXEC PHASE ABORTED? JP P,WR6 ; NOT REQUEST FOR MASTER RET PO ; EXEC-PHASE ENDED OUTI ; YES: TRANSFER BYTE JP NZ,WR6 ; 256 DONE ? WR7: IN A,(FDC) ; NEXT 256 BYTES ****************** AND E ; EXEC. PHASE ABORTED? JP P,WR7 RET PO OUTI ; SEND BYTE TO FDC JP NZ,WR7 ; DONE ? RET ; JP WR99 WR99: OUT (FTC),A ; TERMINATE CALL RESULT ; FETCH RESULTS POP BC ; UNSAVE COUNTER JR Z,WR8 ; NO ERRORS DJNZ WR5 ; ERROR: TRY AGAIN ; FATAL ERROR ; RETURNS WITH A = 0 IF NO ERROR ; AND WITH A .NE. 0 IF ERRORS OCCURED WR8: RET ; ; READ 512-SECTOR FROM DISK IN DMA MODE ; DMA-Mode only! ;****** RD512D: ; PARAMETERS: UNIT, TRACK, SECTOR ;****** LD B,RETRY ; COMPARE WR512D RD0: PUSH BC LD BC,0946H ; READ CALL MOTO LD BC,CRLEN*256+DMA ; DISK TO MEM LD HL,CRDT OTIR CALL RESULT POP BC JR Z,RD1 DJNZ RD0 ; RETURNS WITH A = 0 IF NO ERROR ; AND WITH A .NE. 0 IF ERRORS OCCURED RD1: RET ; ; READ 512 SECTOR NON DMA MODE ! ; NON-DMA-Mode only ;***** RD512: ; PARAMETERS: UNIT, TRACK, SECTOR ;***** LD B,RETRY ; COMPARE WR512 RD4: PUSH BC LD BC,0946H ; READ CALL MOTO LD HL,DBUF LD BC,FDD RD5: IN A,(FDC) RLCA JR NC,RD5 INI JR NZ,RD5 RD6: IN A,(FDC) RLCA JR NC,RD6 INI JR NZ,RD6 OUT (FTC),A ;TERMINATE CALL RESULT POP BC JR Z,RD7 DJNZ RD4 ; RETURNS WITH A = 0 IF NO ERROR ; AND WITH A .NE. 0 IF ERRORS OCCURED RD7: RET ; RESULT: ; FETCH RESULTS OF READ/WRITE OPERATION, store in REST ; AND CHECK THEM FOR R/W-ERRORS ; DESTROYES: AF,BC,HL ; RETURNS WITH: Z & A=0, IF NO ERRORS ; AND WITH: NZ & A=? IF ANY ERROR ; LD B,6 ; 7 RESULTS CALL NEXT LD HL,REST ; RESULT-TABLE LD (HL),A ; STORE RESULT AND 0C0H ; ERROR ? LD C,A ; SAVE RESLOP: CALL NEXT INC HL LD (HL),A ; STORE RESULT DJNZ RESLOP LD A,C OR A RET ; MOTO: ; WAITS UNTIL DISK READY AND THEN ; TRANSMITS COMMAND TO FD-CONTROLLER ; DESTROYES: AF,BC,HL ; PUSH BC ; SAVE COMMAND ; WAIT UNTIL DISK READY LD BC,0204H ; SENSE DRIVE CALL CMFD CALL NEXT ; FETCH RESULT BIT 5,A ; DISK READY ? JR Z,MOTO+1 ; NO => WAIT POP BC ; YES => FETCH COMMAND ; CMFD: ; TRANSMITS COMMAND TO FD-CONTROLLER ; DESTROYES: AF,BC,HL ; LD HL,CMDTAB ; POINT TO COMMANDTABLE CMFD1: IN A,(FDC) ; REQUEST FOR MASTER ? AND 0C0H CP 80H JR NZ,CMFD1 ; NO => WAIT LD A,C ; YES => OUT (FDD),A ; SEND COMMAND INC HL ; POINT TO NEXT BYTE LD C,(HL) DJNZ CMFD1 ; SEND NEXT BYTE RET ; ALL BYTES TRANSFERRED ; NEXT: ; READ NEXT RESULT-BYTE FROM FD-CONTROLLER ; DESTROYES: AF ; IN A,(FDC) ; REQUEST FOR MASTER & AND 0C0H ; TRANSFER TO MASTER ? CP 0C0H JR NZ,NEXT ; NO => WAIT IN A,(FDD) ; YES => FETCH RESULT RET ; ; FORMAT A TRACK IN NON-DMA-MODE ; NON-DMA-Mode only !! (IBM-Format, Filler = 0E5H) ;***** FORMT: ;***** LD BC,(TRACK) PUSH BC LD DE,(SECTOR) LD (FTAB),BC LD A,1 LD (FTAB+2),A PUSH DE LD HL,MAXSEC*256+2 LD (TRACK),HL LD HL,0E500H+FMTGAP LD (SECTOR),HL LD BC,064DH CALL MOTO LD HL,FTAB-1 LD BC,0400H+FDD LD D,MAXSEC INC HL F00: PUSH HL LD B,4 F01: IN A,(FDC) RLCA JR NC,F01 OUTI JR NZ,F01 DEC D JR Z,F02 DEC HL DEC HL INC (HL) POP HL JR F00 F02: POP HL CALL RESULT POP HL LD (SECTOR),HL POP HL LD (TRACK),HL F03: RET FTAB: DEFB 0 ; TRACK DEFB 0 ; HEAD DEFB 1 ; SECTOR DEFB 2 ; 512 BYTES ; ; FORMAT A TRACK IN DMA MODE ; DMA-Mode only (IBM-DD-Format, Filler: 0E5H) ;****** FORMTD: ; PARAMETERS: UNIT, TRACK, SECTOR ;****** ; ; SET UP BUFFER ; LD BC,(TRACK) ; B = HEAD, C = TRACK PUSH BC LD DE,(SECTOR) ; D = N, E = SECTOR PUSH DE LD HL,DBUF LD A,1 ; A = SECTOR COUNTER FLP01: LD (HL),C INC HL LD (HL),B INC HL LD (HL),A INC HL LD (HL),D INC HL INC A ; DONE ? CP MAXSEC+1 JR NZ,FLP01 ; LD HL,MAXSEC*256+2 ; 512 BYTES, 10 SECTORS LD (TRACK),HL LD HL,0E500H+FMTGAP ; FILLER AND GAPLENGTH LD (SECTOR),HL LD BC,064DH ; 6 BYTE COMMAND FORMAT CALL MOTO ; COMMAND OUT LD BC,CFLEN*256+DMA LD HL,CFT OTIR CALL RESULT POP HL LD (SECTOR),HL POP HL LD (TRACK),HL FMT9: RET ; ; SECTOR BUFFER ; DBUF: DEFS 200H ; SECTOR BUFFER ; ; COMMAND TABLES FOR DMA CONTROLLER ; CWRT: ; DMA WRITE TO DISK DEFB 83H ; DISABLE DMA DEFB 0C3H ; RESET DMA DEFB 79H ; WR0: TRANSFER B TO A DEFW DBUF ; A-ADDRESS FOLLOWES DEFW 512-1 ; BLOCKLENGTH FOLLOWS DEFB 14H ; WR1: A-ADDRESS INC, A = MEMORY DEFB 0C7H ; RESET PORT A TIMING DEFB 28H ; WR2: B-ADRESS FIXED, B = I/O-PORT DEFB 0CBH ; RESET PORT B TIMING DEFB 95H ; WR4: BYTE-MODE DEFB FDD ; B-LOW-ADDRES FOLLOWS DEFB 12H ; INT.CNTL.BYTE FOLLOWS , INT AT END OF BLOCK DEFB LOW(VECTOR) ; INT.-VECTOR-FOLLOWS DEFB 8AH ; WR5: STOP AT END OF BLOCK, READY LOW DEFB 0CFH ; LOAD DEFB 5 ; WR0: TRANSFER A TO B !!! DEFB 0CFH ; LOAD DEFB 0ABH ; ENABLE INTERRUPT DEFB 87H ; ENABLE DMA CWRE: CWLEN EQU CWRE-CWRT ; CFT: ; DMA WRITE TO DISK FOR FORMAT DEFB 83H ; DISABLE DMA DEFB 0C3H ; RESET DMA DEFB 79H ; WR0: TRANSFER B TO A DEFW MAXSEC*4-1 ; A-ADDRESS FOLLOWES DEFW 512-1 ; BLOCKLENGTH FOLLOWS DEFB 14H ; WR1: A-ADDRESS INC, A = MEMORY DEFB 0C7H ; RESET PORT A TIMING DEFB 28H ; WR2: B-ADRESS FIXED, B = I/O-PORT DEFB 0CBH ; RESET PORT B TIMING DEFB 95H ; WR4: BYTE-MODE DEFB FDD ; B-LOW-ADDRES FOLLOWS DEFB 12H ; INT.CNTL.BYTE FOLLOWS , INT AT END OF BLOCK DEFB LOW(VECTOR) ; INT.-VECTOR-FOLLOWS DEFB 8AH ; WR5: STOP AT END OF BLOCK, READY LOW DEFB 0CFH ; LOAD DEFB 5 ; WR0: TRANSFER A TO B !!! DEFB 0CFH ; LOAD DEFB 0ABH ; ENABLE INTERRUPT DEFB 87H ; ENABLE DMA CFTE: CFLEN EQU CFTE-CFT ; CRDT: ; DMA READ FROM DISK DEFB 83H ; DISABLE DMA DEFB 79H ; WR0: TRANSFER B TO A DEFW DBUF ; A-ADDRESS FOLLOWES DEFW 512-1 ; BLOCKLENGTH FOLLOWS DEFB 14H ; WR1: A-ADDRESS INC, A = MEMORY DEFB 0C7H ; RESET PORT A TIMING DEFB 28H ; WR2: B-ADRESS FIXED, B = I/O-PORT DEFB 0CBH ; RESET PORT B TIMING DEFB 95H ; WR4: BYTE-MODE DEFB FDD ; B-LOW-ADDRES FOLLOWS DEFB 12H ; INT.CNTL.BYTE FOLLOWS , INT AT END OF BLOCK DEFB LOW(VECTOR) ; INT.-VECTOR-FOLLOWS DEFB 8AH ; WR5: STOP AT END OF BLOCK, READY LOW DEFB 0CFH ; LOAD DEFB 0ABH ; ENABLE INTERRUPT DEFB 87H ; ENABLE DMA CRDE: CRLEN EQU CRDE-CRDT ; ; INTERRUPT SERVICE ROUTINE ; TERMI: OUT (FTC),A ; TERMINATE PUSH AF ; SAVE LD A,0C3H ; RESET DMA LOGIC OUT (DMA),A POP AF ; UNSAVE EI RETI ; PAGE ; ; ADDRESSES OF ROUTINES ; ; INIDMA SET INTERRUPT MODE 2 START DEFL INIDMA STOP DEFL INID ; INIFDC RESET UPD 765 START DEFL INIFDC STOP DEFL INI1 ; SPECD SPECIFY DMA-MODE START DEFL SPECD STOP DEFL SPE1 ; SPEC SPECIFY NON-DMA-MODE START DEFL SPEC STOP DEFL SPE2 ; RECAL,U MOVE HEAD TO HOME POSITION START DEFL RECAL STOP DEFL REC1 ; SEEK,U,T SEEK TRACK START DEFL SEEK STOP DEFL SK1 ; RDIDF,U READ ID FIELD START DEFL RDIDF STOP DEFL RDID1 ; SDRS,U SENSE DRIVE STATUS START DEFL SDRS STOP DEFL SD1 ; WR512D,U,T,S WRITE SECTOR (512 BYTE) DMA MODE START DEFL WR512D STOP DEFL WR1 ; WR512,U,T,S WRITE SECTOR (512 BYTE) NON DMA MODE START DEFL WR512 STOP DEFL WR8 ; RD512D,U,T,S READ SECTOR (512 BYTE) DMA-MODE START DEFL RD512D STOP DEFL RD1 ; RD512,U,T,S READ SECTOR (512 BYTE) NON DMA-MODE START DEFL RD512 STOP DEFL RD7 ; FORMT,U,T FORMAT A TRACK NON-DMA-MODE START DEFL FORMT STOP DEFL F03 ; FORMTD,U,T FORMAT TRACK DMA-MODE START DEFL FORMTD STOP DEFL FMT9 ; ; DBUF 512 BYTE BUFFER FOR DISK OPERATONS BEGIN DEFL DBUF LAST DEFL DBUF+1FFH ; CMDTAB COMMAND TABLE FOR UPD 765 BEGIN DEFL CMDTAB LAST DEFL CMDTAB+8 ; REST RESULT TABLE (READ,WRITE,FORMAT,READ ID) BEGIN DEFL REST LAST DEFL REST+6 ; .DEPHASE ; END