|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 31232 (0x7a00) Types: TextFile Names: »FLOPPY.MAC«
└─⟦72577d508⟧ Bits:30003297 Diverse BIOS typer til RC703 └─ ⟦this⟧ »FLOPPY.MAC«
SUBTTL FLOPPY DISK DRIVER ;======================================================== ;= FLOPPY DISK DRIVER = ;======================================================== WRALL EQU 0 ; WRITE TO ALLOCATED SECTOR. WRDIR EQU 1 ; WRITE TO DIRECTORY SECTOR. WRUAL EQU 2 ; WRITE TO UNALLOCATED SECTOR (FIRST SECTOR OF A ; NEW DATA BLOCK). PAGE ;================================================ ;= PROCEDURE SECTION = ;================================================ ;SELECT DISK DRIVE ;ENTRY: C=DRIVE NUMBER ;EXIT : HL=DISK PARAMETER HEADER SELD: LD HL,0 ; PROCEDURE SELECT_DISK; ADD HL,SP ; LD SP,STACK ; SP := LOCAL_STACK; PUSH HL ; LD HL,0 ; ERROR CODE LD A,(DRNO) ; DRIVE OK? CP C ; CY IF SO JP C,RSELD ; RET IF ERROR LD A,C ; LD (SEKDSK),A ; INIT. SEEK DISK WITH NEW DRIVE NO. LD BC,10H ; INIT. DPH LENGTH LD DE,FD0 ; GET FD0 ADDRESS LD HL,00H ; INIT. DPH OFFSET SELD10: OR A ; JP Z,SELD20 ; INC DE ; DE:=DE+DRIVE_NO ADD HL,BC ; HL:=HL+(DRIVE_NO.*DPH_LENGTH) DEC A ; JP SELD10 ; SELD20: LD C,L ; LD B,H ; EX DE,HL ; LD A,(HL) ; LD HL,CFORM ; CP (HL) ; JP Z,SELN ; PUSH AF ; IF: NEW_FORMAT # CURRENT_FORMAT THEN PUSH BC ; IF: HOST_WRITE # 0 THEN LD A,(HSTWRT) ; WRITE BUFFER TO DISK OR A ; ELSE: CALL NZ,WRTHST ; ELSE: XOR A ; LD (HSTWRT),A ; POP BC ; POP AF ; LD (CFORM),A ; TFj VÆLG FLOPPY- CP 16 ; TFj CLOCKFREKVENS JP Z,MINIFL ; TFj LD A,2 ; TFj MINIFL: INC A ; TFj OUT (SW1),A ; TFj LD A,(CFORM) ; TFj SELN: LD (CFORM),A ; CURRENT_FORMAT := FORMAT(DRIVE_NO); CALL GFPA ; GET NEW FLOPPY_DISK_PARMS ADDRESS LD (FORM),HL ; INC HL ; INC HL ; INC HL ; INC HL ; LD A,(HL) ; INIT. NUMBER OF TRACKS ON ONE DISK PAGE LD (EOTV),A ; PUSH BC ; LD A,(CFORM) ; AND 11111000B ; REMOVE POSITION BITS OR A ; RLA ; LD E,A ; LD D,0 ; LD HL,FSPA00 ; ADD HL,DE ; INIT. ACTUAL DISK_PARMS_BLOCK LD DE,DPBLCK ; LD BC,10H ; LDIR ; LD HL,(DPBLCK) ; GET ADDRESS OF DPBXX (XX=0,08,16,,56,64) LD BC,13 ; REL. TO START ADD HL,BC ; ADDRESS OF OFFSET WORD EX DE,HL ; LD HL,TRKOFF ; TRACK OFFSET TABLE LD B,0 ; LD A,(SEKDSK) ; BC= SEEK DISK NO. LD C,A ; ADD HL,BC ; ADD HL,BC ; HL= ADDRESS OF OFFSET VALUE IN OFFSET TBL LD BC,2 ; NO OF BYTES TO MOVE LDIR ; POP BC ; LD HL,DPBASE ; ADD HL,BC ; GET ADR. OF ACTUAL DISK_PARMS_HEADER EX DE,HL ; LD HL,10 ; ADD HL,DE ; EX DE,HL ; LD A,(DPBLCK) ; INIT. DISK_PARMS_HEADER WITH LD (DE),A ; ACTUAL DISK_PARMS_BLOCK INC DE ; LD A,(DPBLCK+1) ; LD (DE),A ; RSELD: EX DE,HL ; HL:=DPH(DISK) POP HL ; LD SP,HL ; EX DE,HL ; RET ; PAGE GFPA: LD HL,FDF1 ; LD A,(CFORM) ; AND 11111000B ; REMOVE POSITION BITS LD E,A ; LD D,0 ; ADD HL,DE ; RET ; ;SETTRACK ;ENTRY: BC=TRACK NUMBER SETT: LD H,B ; LD L,C ; LD (SEKTRK),HL ; RET ; ;SETSECTOR ;ENTRY: BC=SECTOR NUMBER SETS: LD L,C ; LD H,B ; LD (SEKSEC),HL ; RET ; ;SET DMA ADDRESS ;ENTRY: BC=DMA ADDRESS SETD: LD H,B ; LD L,C ; LD (DMAADR),HL ; RET ; ;TRANSLATE SECTOR NUMBER ;ENTRY: BC=SECTOR NUMBER SECTRA: LD H,B ; LD L,C ; RET ; PAGE ;READ THE SELECTED CP/M SECTOR ;ENTRY: ;EXIT : A=RESULT (0 OK,1 HARD ERROR) XREAD: XOR A ;PATCHES FROM DIGITAL LD (UNACNT),A ; LD A,1 ; LD (READOP),A ; READ OPERATION LD (RSFLAG),A ; MUST READ DATA LD A,WRUAL ; LD (WRTYPE),A ; TREAT AS UNALLOCATED JP RWOPER ; TO PERFORM THE READ ;WRITE THE SELECTED CP/M SECTOR ;ENTRY: ;EXIT : C=WRITETYPE A=RESULT XWRITE: XOR A ; LD (READOP),A ; NOT A READ OPERATION LD A,C ; WRITE TYPE IN C LD (WRTYPE),A ; CP WRUAL ; WRITE UNALLOCATED? JP NZ,CHKUNA ; CHECK FOR UNALLOCATED ;WRITE TO UNALLOCATED, SET PARAMETERS LD A,(CPMRBP) ; UNACNT := BLKSIZE/128; LD (UNACNT),A ; LD A,(SEKDSK) ; UNADSK := SEKDSK; LD (UNADSK),A ; LD HL,(SEKTRK) ; UNATRK := SEKTRK; LD (UNATRK),HL ; LD HL,(SEKSEC) ; UNASEC := SEKSEC; LD (UNASEC),HL ; ;CHECK FOR WRITE TO UNALLOCATED SECTOR CHKUNA: LD A,(UNACNT) ; ANY UNALLOCATED REMAIN? OR A ; JP Z,ALLOC ; SKIP IF NOT PAGE ;MORE UNALLOCATED RECORDS REMAIN DEC A ; UNACNT := UNACNT -1; LD (UNACNT),A ; LD A,(SEKDSK) ; SAME DISK? LD HL,UNADSK ; CP (HL) ; SEKDSK=UNADSK? JP NZ,ALLOC ; SKIP IF NOT ;DISKS ARE THE SAME LD HL,UNATRK ; SAME TRACK? CALL TRKCMP ; SEKTRK=UNATRK? JP NZ,ALLOC ; SKIP IF NOT ;TRACKS ARE THE SAME LD A,(SEKSEC) ; SAME SECTOR? LD HL,UNASEC ; CP (HL) ; SEKSEC=UNASEC? JP NZ,ALLOC ; SKIP IF NOT LD A,(SEKSEC+1) ; INC HL ; CP (HL) ; COMPARE MSB JP NZ,ALLOC ; ;MATCH, MOVE TO NEXT SECTOR FOR FUTURE REFERENCE LD HL,(UNASEC) ; INC HL ; LD (UNASEC),HL ; UNASEC:=UNASEC+1 EX DE,HL ; LD HL,CPMSPT ; GET SECTORS PER TRACK PUSH BC ; LD C,(HL) ; INC HL ; LD B,(HL) ; EX DE,HL ; AND A ; RESET CARRY SBC HL,BC ; END OF TRACK POP BC ; JP C,NOOVF ; SKIP IF NO OVERFLOW PAGE ;OVERFLOW TO NEXT TRACK LD HL,00 ; UNASEC:=0 LD (UNASEC),HL ; LD HL,(UNATRK) ; INC HL ; LD (UNATRK),HL ; UNATRK:=UNATRK+1 ;MATCH FOUND, MARK AS UNNECESSARY READ NOOVF: XOR A ; LD (RSFLAG),A ; RSFLAG:=0 LD A,(SEKSEC) ; LD HL,SECMSK ; AND (HL) ; CP (HL) ; LD A,0 ; JP NZ,SETMSK ; INC A ; SETMSK: LD (UNAMSK),A ; JP RWOPER ; TO PERFORM THE WRITE ;NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ ALLOC: XOR A ; LD (UNACNT),A ; UNACNT:=0 LD A,(SECMSK) ; LD (RSFLAG),A ; RSFLAG:=1 PAGE ; COMMON CODE FOR READ AND WRITE FOLLOWS RWOPER: LD HL,0 ; ADD HL,SP ; LD SP,STACK ; ESTABLISH LOCAL STACK PUSH HL ; SAVE OLD SP LD A,(SECSHF) ; COMPUTE HOST SECTOR LD B,A ; LD HL,(SEKSEC) ; RSECS: DEC B ; JP Z,SETSH ; SRL H ; HOST_SECTOR := SEEK_SECTOR DIVIDED RR L ; WITH SECTOR SHIFT CONSTANT JP RSECS ; SETSH: LD (SEKHST),HL ; HOST SECTOR TO SEEK ;ACTIVE HOST SECTOR? LD HL,HSTACT ; HOST ACTIVE FLAG LD A,(HL) ; LD (HL),1 ; ALWAYS BECOMES 1 OR A ; WAS IT ALREADY? JP Z,FILHST ; FILL HOST IF NOT ;HOST BUFFER ACTIVE, SAME AS SEEK BUFFER? LD A,(SEKDSK) ; LD HL,HSTDSK ; SAME DISK? CP (HL) ; SEKDSK=HSTDSK? JP NZ,NOMATC ; ;SAME DISK, SAME TRACK? LD HL,HSTTRK ; CALL TRKCMP ; SEKTRK=HSTTRK JP NZ,NOMATC ; PAGE ;SAME DISK, SAME TRACK, SAME SECTOR? LD A,(SEKHST) ; LD HL,HSTSEC ; SEKHST=HSTSEC? CP (HL) ; JP NZ,NOMATC ; LSB COMPARE LD A,(SEKHST+1) ; INC HL ; CP (HL) ; MSB COMPARE JP Z,MATCH ; SKIP IF MATCH ;PROPER DISK, BUT NOT CORRECT SECTOR NOMATC: LD A,(HSTWRT) ; HOST WRITTEN? OR A ; CALL NZ,WRTHST ; WRITE HOST BUFFER TO DISK ;MAY HAVE TO FILL THE HOST BUFFER FILHST: LD A,(SEKDSK) ; LD (HSTDSK),A ; LD HL,(SEKTRK) ; LD (HSTTRK),HL ; LD HL,(SEKHST) ; LD (HSTSEC),HL ; LD A,(RSFLAG) ; NEAD TO READ? OR A ; CALL NZ,RDHST ; YES, IF 1 XOR A ; LD (HSTWRT),A ; NO PENDING WRITE PAGE ;COPY DATA TO OR FROM BUFFER MATCH: LD A,(SEKSEC) ; MASK BUFFER NUMBER LD HL,SECMSK ; LEAST SIGNIF BITS AND (HL) ; TO POINT OUT POSISTION IN HOST BUFFER LD L,A ; READY TO SHIFT LD H,00H ; ADD HL,HL ; SHIFT LEFT 7 ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; BUFF_OFFSET:=128*(SEEKSEC AND SECMASK); ;HL HAS RELATIVE HOST BUFFER ADDRESS LD DE,HSTBUF ; ADD HL,DE ; HL:=HOST BUFFER ADDRESS EX DE,HL ; NOW IN DE LD HL,(DMAADR) ; GET/PUT CP/M DATA LD BC,128 ; LENGTH OF MOVE EX DE,HL ; LD A,(READOP) ; WHICH WAY? OR A ; JP NZ,RWMOVE ; SKIP IF READ ;WRITE OPERATION, MARK AND SWITCH DIRECTION LD A,1 ; HOSTWRT:=1; LD (HSTWRT),A ; EX DE,HL ; SOURCE/DEST SWAP PAGE ;BC INITIALLY 128, HL IS SOURCE, DE IS DEST RWMOVE: LDIR ; ;DATA HAS BEEN MOVED TO/FROM HOST BUFFER LD A,(WRTYPE) ; WRITE TYPE CP WRDIR ; TO DIRECTORY? LD HL,ERFLAG ; IN CASE OF ERRORS LD A,(HL) ; PUSH AF ; OR A ; JP Z,RRWOPX ; XOR A ; LD (HSTACT),A ; DO: SET HOST_ACTIVE:=FALSE RRWOPX: POP AF ; LD (HL),0 ; JP NZ,RRWOP ; NO FURTHER PROCESSING ;CLEAR HOST BUFFER FOR DIRECTORY WRITE OR A ; ERRORS? JP NZ,RRWOP ; SKIP IF NOT SO XOR A ; LD (HSTWRT),A ; BUFFER WRITTEN CALL WRTHST ; LD HL,ERFLAG ; LD A,(HL) ; LD (HL),0 ; RRWOP: POP HL ; RETURN: LD SP,HL ; SP:=GLOBAL_SP; RET ; PAGE ;UTILITY SUBROUTINE FOR 16-BIT COMPARE ;HL=UNATRK OR HSTTRK, COMPARE WITH SEKTRK TRKCMP: EX DE,HL ; LD HL,SEKTRK ; LD A,(DE) ; LOW BYTE COMPARE CP (HL) ; SAME? RET NZ ; RETURN IF NOT ;LOW BYTES EQUAL, TEST HIGH LS INC DE ; INC HL ; LD A,(DE) ; CP (HL) ; SETS FLAGS RET ; PAGE ;========================================================== ;= WRITEHOST performs the physical write to the host disk.= ;========================================================== WRTHST: LD A,(DSKTYP) ; IF: DISK TYPE := HARD OR A ; THEN: GOTO HARD WRITE HOST JP NZ,HWRHST ; ELSE: CALL CHKTRK ; JP SECWR ; ;========================================================== ;= READHOST performs the physical read from the host disk = ;========================================================== RDHST: LD A,(UNAMSK) ; OR A ; JP NZ,RCHECK ; IF UNAMSK THEN FORCE PRE_READ; LD (UNACNT),A ; RCHECK: LD A,(DSKTYP) ; IF: DISK TYPE := HARD OR A ; THEN: GOTO HARD READ HOST JP NZ,HRDHST ; ELSE: CALL CHKTRK ; JP SECRD ; PAGE ;============================================================================== ;= CHECK HOST DISK AND TRACK EQUAL TO LAST HOST AND DISK = ;= = ;= S U P P O R T S O N L Y 2 5 6 S E C T O R S A N D T R A C K S = ;============================================================================== CHKTRK: LD A,(HSTSEC) ; LD C,A ; SECTOR:=HSTSEC; LD A,(EOTV) ; HEADNO:=0; LD B,A ; DEC A ; CP C ; LD A,(HSTDSK) ; JP NC,SET1 ; IF HSTSEC>EOTV-1 THEN END; OR 4 ; BEGIN LD (DSKNO),A ; HEADNO:=1; LD A,C ; SECTOR:=SECTOR-EOTV; SUB B ; END; LD C,A ; JP SET2 ; SET1: LD (DSKNO),A ; SET2: LD B,0 ; LD HL,(TRANTB) ; TRANSLATE SECTOR ADD HL,BC ; LD A,(HL) ; LD (ACSEC),A ; ACTUAL_SECTOR := TRANSLATED_SECTOR LD A,(HSTTRK) ; LD (ACTRA),A ; ACTUAL_TRACK := HOST_TRACK LD HL,HSTBUF ; LD (DSKAD),HL ; LD A,(HSTDSK) ; IF: HOST_DISK := LAST_DISK THEN LD HL,LSTDSK ; CP (HL) ; IF: HOST_TRACK := LAST_TRACK THEN JP NZ,SEEKT ; LD A,(HSTTRK) ; END LD HL,LSTTRK ; CP (HL) ; ELSE: JP NZ,SEEKT ; LD A,(HSTTRK+1) ; ELSE: INC HL ; CP (HL) ; COMPARE MSB RET Z ; PAGE SEEKT: LD A,(HSTDSK) ; LAST_DISK := HOST_DISK LD (LSTDSK),A ; LD HL,(HSTTRK) ; LAST_TRACK := HOST_TRACK LD (LSTTRK),HL ; CALL CLFIT ; CLEAR FLOPPY INTERRUPT FLAG CALL FL07 ; SEEK DRIVE_NO, HEAD AND SECTOR CALL WFITR ; AWAIT FLOPPY INTERRUPT LD A,(DSKNO) ; AND 3 ; ADD A,32 ; REG. BC := COMPLETION CODE CP B ; IF STATUS=SEEK_END THEN RET Z ; RETURN; RECA: CALL CLFIT ; CALL FL04 ; RECALIBRATE; PUSH BC ; CALL WFITR ; CALL FL07 ; SEEK(ACTRA); CALL WFITR ; POP BC ; RET ; RETURN; PAGE SECRD: LD A,10 ; LD (REPET),A ; RPSC: CALL FDSTART ; CALL CLFIT ; LD HL,(FORM) ; LD C,(HL) ; INC HL ; LD B,(HL) ; INC HL ; CALL FLPW ; CALL RFDAT ; CALL WATIR ; LD C,0 ; SECCH: LD HL,RSTAB ; LD A,(HL) ; AND 0F8H ; RET Z ; SCRP: AND 8 ; JP NZ,SCR1 ; LD A,(REPET) ; DEC A ; LD (REPET),A ; JP Z,SCR1 ; CP 5 ; CALL Z,RECA ; XOR A ; CP C ; JP Z,RPSC ; JP RPSW ; SCR1: LD A,C ; LD (HSTACT),A ; LD A,1 ; LD (ERFLAG),A ; RET ; PAGE SECWR: LD A,10 ; LD (REPET),A ; RPSW: CALL FDSTART ; CALL CLFIT ; LD HL,(FORM) ; LD C,(HL) ; INC HL ; LD B,(HL) ; INC HL ; CALL FLPR ; CALL WFDAT ; CALL WATIR ; LD C,1 ; JP SECCH ; RFDAT: LD A,6 ; JP GNCOM ; WFDAT: LD A,5 ; JP GNCOM ; PAGE FDSTAR: IN A,(SW1) ; PROCEDURE START_FLOPPY_MOTOR; AND 80H ; BEGIN ; TFj RET Z ; IF MINI_DRIVE THEN BEGIN DI ; BEGIN LD HL,(EXCNT1) ; STOPPED:=STOP_TIMER=0; LD A,L ; STOP_TIMER:=FD_TIME_OUT; OR H ; IF STOPPED THEN LD HL,(FDTIMO) ; BEGIN LD (EXCNT1),HL ; START_MOTOR; EI ; WAITD(50); (* WAIT 1 SEC *) RET NZ ; END; ; TFj LD A,1 ; END; IN A,(SW1) ; TFj jeg bruger motorswitchen på SET 0,A ; TFj drive C og D også OUT (SW1),A ; END; ; TFj LD HL,50 ; LD HL,15 ; TFj virker vist godtnok alligevel CALL WAITD ; RET ; FDSTOP: IN A,(SW1) ; PROCEDURE STOP_FLOPPY_MOTOR; AND 80H ; BEGIN (* CALLED WHEN STOP_TIMER REACH 0 *) ; TFj RET Z ; IF MINI_DRIVE THEN ; TFj LD A,0 ; STOP_MOTOR; IN A,(SW1) ; TFj RES 0,A ; OUT (SW1),A ; END; RET ; WAITD: LD (DELCNT),HL ; PROCEDURE WAITD; WAIT10: LD HL,(DELCNT) ; LD A,L ; OR H ; JP NZ,WAIT10 ; RET ; PAGE XHOME: LD A,(HSTWRT) ;PATCH FROM DIG. CHECK FOR PENDING WRITE OR A ; JR NZ,XHOM01 ; LD (HSTACT),A ;CLEAR HOST ACTIVE FLAG ;END PATCH FROM DIGITAL. XHOM01: LD A,(DSKTYP) ; IF: DISK TYPE := HARD AND A ; THEN: JP Z,XHOM20 ; LD A,(SEKDSK) ; LD (LSTDSK),A ; LAST_DISK:=SEEK_DISK LD HL,(DPBLCK) ; LD DE,13 ; GET TRACK OFFSET IN DISK PARMS. BLOCK ADD HL,DE ; LD E,(HL) ; INC HL ; LD D,(HL) ; LD (LSTTRK),DE ; LAST_TRACK:=TRACK_OFFSET CALL STSKFL ; SET UP TASK FILE TO WD1000 CALL HDSEEK ; POSITION HEADS RET NC ; IF: NO COMMAND ISSUED CALL WAITHD ; THEN: END XHOM10: IN A,(HDSTRG) ; ELSE: AND 10H ; AWAIT HARD DISK INTERRUPT JP Z,XHOM10 ; AWAIT SEEK COMPLETE RET ; END. XHOM20: CALL FDSTAR ; ELSE: LD A,(SEKDSK) ; LD (DSKNO),A ; LD (LSTDSK),A ; XOR A ; LD (LSTTRK),A ; LASTTRACK:=0 LD (LSTTRK+1),A ; CALL CLFIT ; CLEAR FLOPPY INTERRUPT CALL FL04 ; RECALIBRATE FLOPPY CALL WFITR ; AWAIT FLOPPY INTERRUPT RET ; PAGE ; PROCEDURE WAIT_READY_WRITE; FL02: IN A,(FDC) ; AND 0C0H ; CP 080H ; JP NZ,FL02 ; RET ; ; PROCEDURE WAIT_READY_READ; FL03: IN A,(FDC) ; AND 0C0H ; CP 0C0H ; JP NZ,FL03 ; RET ; ; PROCEDURE RECALIBRATE; FL04: CALL FL041 ; RECALIBRATE CALL WATIR ; WAIT FINISHED LD A,(RSTAB) ; BIT 4,A ; RET Z ; IF EQUIPTMENT CHECK THEN FL041: CALL CLFIT ; CALL FL02 ; WAIT_READY_WRITE; LD A,7 ; OUT (FDD),A ; RECALIBRATE; CALL FL02 ; WAIT_READY_WRITE; LD A,(DSKNO) ; AND 3 ; OUT (FDD),A ; SELECT_DRIVE; RET ; ; PROCEDURE SENSE_DRIVE_STATUS; FL05: CALL FL02 ; WAIT_READY_WRITE; LD A,4 ; OUT (FDD),A ; CALL FL02 ; WAIT_READY_WRITE; LD A,(DSKNO) ; AND 3 ; OUT (FDD),A ; SELECT_DRIVE; CALL FL03 ; WAIT_READY_READ; IN A,(FDD) ; LD (RSTAB),A ; RSTAB:=INTERRUPT_REGISTER; RET ; PAGE ; PROCEDURE SENSE_INTERRUPT_STATUS; FL06: CALL FL02 ; WAIT_READY_WRITE; LD A,8 ; OUT (FDD),A ; SENSE_INT; CALL FL03 ; WAIT_READY_READ; IN A,(FDD) ; LD (RSTAB),A ; RSTAB:=STATUS_REGISTER_0; AND 0C0H ; CP 080H ; RET Z ; CALL FL03 ; WAIT_READY_READ; IN A,(FDD) ; LD (RSTAB+1),A ; RSTAB1:=STATUS_REGISTER_1; RET ; ; PROCEDURE SEEK; FL07: CALL FL02 ; WAIT_READY_WRITE; LD A,15 ; OUT (FDD),A ; SEEK; CALL FL02 ; WAIT_READY_WRITE; LD A,(DSKNO) ; SELECT_DRIVE_AND_HEAD; AND 3 ; OUT (FDD),A ; CALL FL02 ; WAIT_READY_WRITE; LD A,(ACTRA) ; OUT (FDD),A ; SELECT_CYLINDER; RET ; PAGE ; PROCEDURE READ_RESULT; RSULT: LD HL,RSTAB ; FOR D:=7 DOWNTO 0 DO LD D,7 ; BEGIN RSL1: CALL FL03 ; WAIT_READY_READ; IN A,(FDD) ; RESULT_TABLE(D):=READCHAR(FDD); LD (HL),A ; INC HL ; LD A,4 ; RSL2: DEC A ; DELAY; JP NZ,RSL2 ; IN A,(FDC) ; AND 10H ; RET Z ; DEC D ; JP NZ,RSL1 ; RET ; END; CLFIT: DI ; PROCEDURE CLEAR_FLOPPY_INTERRUPT; XOR A ; LD (FL_FLG),A ; EI ; RET ; WFITR: CALL WATIR ; PROCEDURE WAIT_CLEAR_FD_INTERRUPT; LD A,(RSTAB) ; LD B,A ; LD A,(RSTAB+1) ; LD C,A ; CALL CLFIT ; RET ; PAGE WATIR: LD A,(FL_FLG) ; PROCEDURE WAIT_FD_INTERRUPT; OR A ; JP Z,WATIR ; RET ; FLPR: LD A,5 ; PROCEDURE START_DMA_READ; DI ; OUT (DMAMAS),A ; SET_CH1_MASK; LD A,49H ; MODE:=READ; FLFW: OUT (DMAMOD),A ; SELECT_MODE; OUT (DMACBC),A ; CLEAR_BYTECOUNTER; LD A,(DSKAD+0) ; OUT (DMAAD1),A ; SET_LOW_ADDRESS; LD A,(DSKAD+1) ; OUT (DMAAD1),A ; SET_HIGH_ADDRESS; LD A,C ; OUT (DMACN1),A ; SET_LOW_COUNT; LD A,B ; OUT (DMACN1),A ; SET_HIGH_COUNT; LD A,1 ; OUT (DMAMAS),A ; CLEAR_CH1_MASK; EI ; RET ; FLPW: LD A,5 ; PROCEDURE START_DMA_WRITE; DI ; OUT (DMAMAS),A ; SET_CH1_MASK; LD A,45H ; MODE:=WRITE; JP FLFW ; GOTO START_DMA_COMMON; PAGE GNCOM: PUSH AF ; PROCEDURE GENERAL_COMMAND; DI ; CALL FL02 ; WAIT_READY_WRITE; POP AF ; LD B,(HL) ; INC HL ; ADD A,B ; ADD MF/FMF TO COMMAND; OUT (FDD),A ; CALL FL02 ; WAIT_READY_WRITE; LD A,(DSKNO) ; OUT (FDD),A ; SELECT_HEAD_AND_DRIVE; CALL FL02 ; WAIT_READY_WRITE; LD A,(ACTRA) ; OUT (FDD),A ; SELECT_CYLINDER; CALL FL02 ; WAIT_READY_WRITE; LD A,(DSKNO) ; RRA ; RRA ; AND 3 ; OUT (FDD),A ; SELECT_HEAD; CALL FL02 ; WAIT_READY_WRITE; LD A,(ACSEC) ; OUT (FDD),A ; SELECT_SECTOR; CALL FL02 ; WAIT_READY_WRITE; LD A,(HL) ; INC HL ; OUT (FDD),A ; SELECT_NUMBER_TYPE; CALL FL02 ; WAIT_READY_WRITE; LD A,(HL) ; INC HL ; OUT (FDD),A ; SELECT_FINAL_SECTOR; CALL FL02 ; LD A,(HL) ; OUT (FDD),A ; SELECT_GAP_LENGTH; CALL FL02 ; LD A,(DTLV) ; OUT (FDD),A ; SELECT_DATA_LENGTH; EI ; RET ; PAGE ;======================================================== ;= UP765 FLOPPY DISK CONTROLLER INTERRUPT ROUTINE = ;======================================================== FLITR: LD (SP_SAV),SP ; SAVE ACCUMULATOR AND FLAGS LD SP,ISTACK ; SAVE REGISTERS PUSH AF ; PUSH BC ; PUSH DE ; ESTABLISH LOCAL STACK PUSH HL ; SAVE GLOBAL STACK POINTER LD A,0FFH ; LD (FL_FLG),A ; FLOPPY_BUSY:=FALSE; LD A,5 ; FITX: DEC A ; JP NZ,FITX ; IN A,(FDC) ; AND 16 ; JP NZ,FIT1 ; CALL FL06 ; SENSE_INTERRUPT_STATUS; JP FIT2 ; FIT1: CALL RSULT ; READ_RESULT; FIT2: POP HL ; POP DE ; RESTORE GLOBAL STACKPOINTER POP BC ; RESTORE REGISTERS POP AF ; RESTORE ACCUMULATOR AND FLAGS LD SP,(SP_SAV) ; EI ; RETI ; PAGE «eof»