; ;================================================================================================== ; RAM FLOPPY DISK DRIVER ;================================================================================================== ; ; ; RF_U0IO .EQU $A0 RF_U1IO .EQU $A4 ; ; IO PORT OFFSETS ; RF_DAT .EQU 0 RF_AL .EQU 1 RF_AH .EQU 2 RF_ST .EQU 3 ; ; ; RF_INIT: CALL NEWLINE ; FORMATTING PRTS("RF: UNITS=$") LD A,RFCNT CALL PRTDECB ; ; SETUP THE DISPATCH TABLE ENTRIES ; ; ; SETUP THE DISPATCH TABLE ENTRIES ; LD B,RFCNT ; LOOP CONTROL LD C,0 ; PHYSICAL UNIT INDEX RF_INIT0: PUSH BC ; SAVE LOOP CONTROL LD B,C ; PHYSICAL UNIT LD C,DIODEV_RF ; DEVICE TYPE LD DE,0 ; UNIT DATA BLOB ADDRESS CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED POP BC ; RESTORE LOOP CONTROL INC C ; NEXT PHYSICAL UNIT DJNZ RF_INIT0 ; LOOP UNTIL DONE ; XOR A ; INIT SUCCEEDED RET ; RETURN ; ; ; RF_DISPATCH: ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER LD A,C ; DEVICE/UNIT FROM C AND $0F ; ISOLATE UNIT NUM CP 2 ; CHECK FOR MAX UNIT EXCEEDED LD (RF_UNIT),A ; SAVE IT CALL NC,PANIC ; PANIC IF TOO HIGH ; ; DISPATCH ACCORDING TO DISK SUB-FUNCTION LD A,B ; GET REQUESTED FUNCTION AND $0F ; ISOLATE SUB-FUNCTION JP Z,RF_STATUS ; SUB-FUNC 0: STATUS DEC A JP Z,RF_RESET ; SUB-FUNC 1: RESET DEC A JP Z,RF_SEEK ; SUB-FUNC 2: SEEK DEC A JP Z,RF_READ ; SUB-FUNC 3: READ SECTORS DEC A JP Z,RF_WRITE ; SUB-FUNC 4: WRITE SECTORS DEC A JP Z,RF_VERIFY ; SUB-FUNC 5: VERIFY SECTORS DEC A JP Z,RF_FORMAT ; SUB-FUNC 6: FORMAT TRACK DEC A JP Z,RF_DEVICE ; SUB-FUNC 7: DEVICE REPORT DEC A JP Z,RF_MEDIA ; SUB-FUNC 8: MEDIA REPORT DEC A JP Z,RF_DEFMED ; SUB-FUNC 9: DEFINE MEDIA DEC A JP Z,RF_CAP ; SUB-FUNC 10: REPORT CAPACITY DEC A JP Z,RF_GEOM ; SUB-FUNC 11: REPORT GEOMETRY ; RF_VERIFY: RF_FORMAT: RF_DEFMED: CALL PANIC ; INVALID SUB-FUNCTION ; ; ; RF_STATUS: XOR A ; STATUS ALWAYS OK RET ; ; ; RF_RESET: XOR A ; ALWAYS OK RET ; ; ; RF_CAP: LD A,C ; DEVICE/UNIT IS IN C AND $0F ; ISOLATE UNIT NUM CP RFCNT ; CHECK FOR MAX UNIT EXCEEDED CALL NC,PANIC ; PANIC IF TOO HIGH ; LD DE,0 LD HL,$2000 ; 8192 BLOCKS OF 512 BYTES XOR A RET ; ; ; RF_GEOM: ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE CALL RF_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC LD L,H ; DIVIDE BY 256 FOR # TRACKS LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT LD E,16 ; SECTORS / TRACK = 16 RET ; DONE, A STILL HAS RF_CAP STATUS ; ; ; RF_DEVICE: LD D,DIODEV_RF ; D := DEVICE TYPE LD E,C ; E := PHYSICAL UNIT LD C,%00110000 ; C := ATTRIBUTES, NON-REMOVALBE RAM FLOPPY XOR A ; SIGNAL SUCCESS RET ; ; ; RF_MEDIA: LD E,MID_RF ; RAM FLOPPY MEDIA LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE XOR A ; SIGNAL SUCCESS RET ; ; ; RF_SEEK: BIT 7,D ; CHECK FOR LBA FLAG CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) LD BC,HSTLBA ; POINT TO LBA STORAGE CALL ST32 ; SAVE LBA ADDRESS XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ; ; RF_READ: LD (RF_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS CALL RF_SETIO CALL RF_SETADR LD HL,(RF_DSKBUF) LD B,0 LD A,(RF_IO) OR RF_DAT LD C,A INIR INIR XOR A RET ; ; ; RF_WRITE: LD (RF_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS CALL RF_SETIO LD A,(RF_IO) OR RF_ST LD C,A IN A,(C) BIT 0,A ; CHECK WRITE PROTECT LD A,1 ; PREPARE TO RETURN FALSE (ERROR) RET NZ ; WRITE PROTECTED! CALL RF_SETADR LD HL,(RF_DSKBUF) LD B,0 LD A,(RF_IO) OR RF_DAT LD C,A OTIR OTIR XOR A RET ; ; ; RF_SETIO: LD A,(RF_UNIT) ; GET DEVICE/UNIT AND $0F ; ISOLATE UNIT NUM JR NZ,RF_SETIO1 LD A,RF_U0IO JR RF_SETIO3 RF_SETIO1: DEC A JR NZ,RF_SETIO2 LD A,RF_U1IO JR RF_SETIO3 RF_SETIO2: CALL PANIC ; INVALID UNIT RF_SETIO3: LD (RF_IO),A RET ; ; ; RF_SETADR: LD A,(RF_IO) OR RF_AL LD C,A LD A,(HSTLBALO) OUT (C),A LD A,(HSTLBALO+1) INC C OUT (C),A RET ; ; ; RF_IO .DB 0 ; RF_UNIT .DB 0 RF_DSKBUF .DW 0