diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index 1bcae37e..48bdf63f 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -1,3 +1,9 @@ +Version 2.8.7 +------------- +- WBW: Implemented multi-sector I/O in all disk drivers +- WBW: Added support for RC2014 SMB Floppy controller modules (SMC and WDC) +- WBW: New function dispatching for disk drivers + Version 2.8.6 ------------- - WBW: Added support for RC2014 (SIO and ACIA drivers primarily) @@ -6,6 +12,7 @@ Version 2.8.6 - WBW: Added console support to XModem (for RC2014 primarily) - E?B: Fixed IDE/PPIDE when used with non-CF drives - WBW: Patched SUBMIT.COM so that it always puts temp file on A: for immediate execution +- WBW: Accommodate spin up time for true IDE hard disks (IDE or PPIDE) Version 2.8.5 ------------- diff --git a/Source/HBIOS/fd.asm b/Source/HBIOS/fd.asm index 4ff21d9c..17b63582 100644 --- a/Source/HBIOS/fd.asm +++ b/Source/HBIOS/fd.asm @@ -9,76 +9,118 @@ ; PORTS ; #IF ((FDMODE == FDMODE_DIO) | (FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3) | (FDMODE == FDMODE_SMBSMC)) -FDC_MSR .EQU $36 ; 8272 MAIN STATUS REGISTER -FDC_DATA .EQU $37 ; 8272 DATA PORT -FDC_DIR .EQU $38 ; DATA INPUT REGISTER -FDC_DOR .EQU $3A ; DIGITAL OUTPUT REGISTER (LATCH) -FDC_DMA .EQU $3C ; PSEUDO DMA DATA PORT -#ENDIF -#IF (FDMODE = FDMODE_ZETA2) -FDC_MSR .EQU $30 ; 8272 MAIN STATUS REGISTER -FDC_DATA .EQU $31 ; 8272 DATA PORT -FDC_DOR .EQU $38 ; DIGITAL OUTPUT REGISTER -FDC_DCR .EQU $28 ; CONFIGURATION CONTROL REGISTER -FDC_TC .EQU $38 ; TERMINAL COUNT (W/ DACK) -#ENDIF -#IF (FDMODE == FDMODE_DIDE) -FDC_BID .EQU $20 ; IO RANGE 20H-3FH -FDC_MSR .EQU $2A ; 8272 MAIN STATUS REGISTER -FDC_DATA .EQU $2B ; 8272 DATA PORT -FDC_DOR .EQU $2C ; DOR -FDC_DCR .EQU $2D ; DCR -FDC_DACK .EQU $3C ; DACK -FDC_TC .EQU $3D ; TERMINAL COUNT (W/ DACK) -FDC_DMA .EQU $3C ; NOT USED BY DIDE +FDC_MSR .EQU $36 ; 8272 MAIN STATUS REGISTER +FDC_DATA .EQU $37 ; 8272 DATA PORT +FDC_DIR .EQU $38 ; DATA INPUT REGISTER +FDC_DOR .EQU $3A ; DIGITAL OUTPUT REGISTER (LATCH) +FDC_DMA .EQU $3C ; PSEUDO DMA DATA PORT +#ENDIF +#IF (FDMODE = FDMODE_ZETA2) +FDC_MSR .EQU $30 ; 8272 MAIN STATUS REGISTER +FDC_DATA .EQU $31 ; 8272 DATA PORT +FDC_DOR .EQU $38 ; DIGITAL OUTPUT REGISTER +FDC_DCR .EQU $28 ; CONFIGURATION CONTROL REGISTER +FDC_TC .EQU $38 ; TERMINAL COUNT (W/ DACK) +#ENDIF +#IF (FDMODE == FDMODE_DIDE) +FDC_BID .EQU $20 ; IO RANGE 20H-3FH +FDC_MSR .EQU $2A ; 8272 MAIN STATUS REGISTER +FDC_DATA .EQU $2B ; 8272 DATA PORT +FDC_DOR .EQU $2C ; DOR +FDC_DCR .EQU $2D ; DCR +FDC_DACK .EQU $3C ; DACK +FDC_TC .EQU $3D ; TERMINAL COUNT (W/ DACK) +FDC_DMA .EQU $3C ; NOT USED BY DIDE #ENDIF #IF (FDMODE == FDMODE_N8) -FDC_MSR .EQU $8C ; 8272 MAIN STATUS REGISTER -FDC_DATA .EQU $8D ; 8272 DATA PORT -FDC_DOR .EQU $92 ; DOR -FDC_DCR .EQU $91 ; DCR -FDC_DACK .EQU $90 ; DACK -FDC_TC .EQU $93 ; TERMINAL COUNT (W/ DACK) -FDC_DMA .EQU $3C ; NOT USED BY N8 +FDC_MSR .EQU $8C ; 8272 MAIN STATUS REGISTER +FDC_DATA .EQU $8D ; 8272 DATA PORT +FDC_DOR .EQU $92 ; DOR +FDC_DCR .EQU $91 ; DCR +FDC_DACK .EQU $90 ; DACK +FDC_TC .EQU $93 ; TERMINAL COUNT (W/ DACK) +FDC_DMA .EQU $3C ; NOT USED BY N8 #ENDIF #IF (FDMODE = FDMODE_SMBWDC) -FDC_MSR .EQU $50 ; 8272 MAIN STATUS REGISTER -FDC_DATA .EQU $51 ; 8272 DATA PORT -FDC_DOR .EQU $58 ; DIGITAL OUTPUT REGISTER -FDC_DCR .EQU $48 ; CONFIGURATION CONTROL REGISTER -FDC_TC .EQU $58 ; TERMINAL COUNT (W/ DACK) +FDC_MSR .EQU $50 ; 8272 MAIN STATUS REGISTER +FDC_DATA .EQU $51 ; 8272 DATA PORT +FDC_DOR .EQU $58 ; DIGITAL OUTPUT REGISTER +FDC_DCR .EQU $48 ; CONFIGURATION CONTROL REGISTER +FDC_TC .EQU $58 ; TERMINAL COUNT (W/ DACK) #ENDIF ; ; DISK OPERATIONS ; -DOP_READ .EQU 0 ; READ OPERATION -DOP_WRITE .EQU 1 ; WRITE OPERATION -DOP_FORMAT .EQU 2 ; FORMAT OPERATION -DOP_READID .EQU 3 ; READ ID OPERATION +DOP_READ .EQU 0 ; READ OPERATION +DOP_WRITE .EQU 1 ; WRITE OPERATION +DOP_FORMAT .EQU 2 ; FORMAT OPERATION +DOP_READID .EQU 3 ; READ ID OPERATION ; ; FDC RESULT CODES ; -FRC_OK .EQU 0 ; 00 -FRC_NOTIMPL .EQU -01H ; FF -FRC_CMDERR .EQU -02H ; FE -FRC_ERROR .EQU -03H ; FD -FRC_ABORT .EQU -04H ; FC -FRC_BUFMAX .EQU -05H ; FB -FRC_ABTERM .EQU -08H ; F8 -FRC_INVCMD .EQU -09H ; F7 -FRC_DSKCHG .EQU -0AH ; F6 -FRC_ENDCYL .EQU -0BH ; F5 -FRC_DATAERR .EQU -0CH ; F4 -FRC_OVERRUN .EQU -0DH ; F3 -FRC_NODATA .EQU -0EH ; F2 -FRC_NOTWRIT .EQU -0FH ; F1 -FRC_MISADR .EQU -10H ; F0 -FRC_TOFDCRDY .EQU -11H ; EF -FRC_TOSNDCMD .EQU -12H ; EE -FRC_TOGETRES .EQU -13H ; ED -FRC_TOEXEC .EQU -14H ; EC -FRC_TOSEEKWT .EQU -15H ; EB +FRC_OK .EQU 0 ; 00 +FRC_NOTIMPL .EQU -01H ; FF +FRC_CMDERR .EQU -02H ; FE +FRC_ERROR .EQU -03H ; FD +FRC_ABORT .EQU -04H ; FC +FRC_BUFMAX .EQU -05H ; FB +FRC_ABTERM .EQU -08H ; F8 +FRC_INVCMD .EQU -09H ; F7 +FRC_DSKCHG .EQU -0AH ; F6 +FRC_ENDCYL .EQU -0BH ; F5 +FRC_DATAERR .EQU -0CH ; F4 +FRC_OVERRUN .EQU -0DH ; F3 +FRC_NODATA .EQU -0EH ; F2 +FRC_NOTWRIT .EQU -0FH ; F1 +FRC_MISADR .EQU -10H ; F0 +FRC_TOFDCRDY .EQU -11H ; EF +FRC_TOSNDCMD .EQU -12H ; EE +FRC_TOGETRES .EQU -13H ; ED +FRC_TOEXEC .EQU -14H ; EC +FRC_TOSEEKWT .EQU -15H ; EB +; +; FD DEVICE CONFIGURATION +; +FD_DEVCNT .EQU 2 ; 2 DEVICES SUPPORTED +FD_CFGSIZ .EQU 8 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS +; ; OFFSET OF... +FD_DEV .EQU 0 ; DEVICE NUMBER (BYTE) +FD_STAT .EQU 1 ; LAST STATUS (BYTE) +FD_MEDTYP .EQU 2 ; MEDIA TYPE FDM... (BYTE) +FD_CURTRK .EQU 3 ; CURRENT TRACK (BYTE) +FD_HST .EQU 4 ; HOSTS SEEK POSITION +FD_HSTTRK .EQU FD_HST + 0 ; HOST TRACK (WORD) +FD_HSTSEC .EQU FD_HST + 2 ; HOST SECTOR (BYTE) +FD_HSTHD .EQU FD_HST + 3 ; HOST HEAD (BYTE) +; +FD_CFGTBL: + ; DEVICE 0, PRIMARY MASTER + .DB 0 ; DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB FDMEDIA ; MEDIA TYPE + .DB $FF ; CURRENT TRACK + .DB 0 ; HOST TRACK + .DB 0 ; HOST SECTOR + .DW 0 ; HOST HEAD +#IF (FD_DEVCNT >= 2) + ; DEVICE 1, PRIMARY SLAVE + .DB 1 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB FDMEDIA ; MEDIA TYPE + .DB $FF ; CURRENT TRACK + .DB 0 ; HOST TRACK + .DB 0 ; HOST SECTOR + .DW 0 ; HOST HEAD +#ENDIF +; +#IF ($ - FD_CFGTBL) != (FD_DEVCNT * FD_CFGSIZ) + .ECHO "*** INVALID FD CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER ; #IF (FDTRACE > 0) ; @@ -107,9 +149,9 @@ FSS_TOSEEKWT .TEXT "SEEK WAIT TIMEOUT$" ; ; FDC STATUS STRING TABLE ; -FSST: .DB FRC_OK \ .DW FSS_OK +FSST: .DB FRC_OK \ .DW FSS_OK FSST_ENTSIZ .EQU $ - FSST - .DB FRC_NOTIMPL \ .DW FSS_NOTIMPL + .DB FRC_NOTIMPL \ .DW FSS_NOTIMPL .DB FRC_CMDERR \ .DW FSS_CMDERR .DB FRC_ERROR \ .DW FSS_ERROR .DB FRC_ABORT \ .DW FSS_ABORT @@ -153,31 +195,31 @@ CFD_VERSION .EQU 00010000B ; CMD --> ST0 ; ; Specify Command: ; +-----+-----+-----+-----+-----+-----+-----+-----+-----+ -; |Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +; |Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +-----+-----+-----+-----+-----+-----+-----+-----+-----+ -; | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | -; | 1 | ----- STEP RATE ----- | -- HEAD UNLOAD TIME - | -; | 2 | ------------ HEAD LOAD TIME ----------- | NDM | +; | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | +; | 1 | ----- STEP RATE ----- | -- HEAD UNLOAD TIME - | +; | 2 | ------------ HEAD LOAD TIME ----------- | NDM | ; +-----+-----+-----+-----+-----+-----+-----+-----+-----+ ; ; -; Step Rate (milliseconds): Head Unload Time (milliseconds): Head Load Time (milliseconds): -; +------+------+------+------+------+ +------+------+------+------+------+ +------+------+------+------+------+ -; | | BITRATE | | | BITRATE | | | BITRATE | -; | VAL | 1.0M | 500K | 300K | 250K | | VAL | 1.0M | 500K | 300K | 250K | | VAL | 1.0M | 500K | 300K | 250K | -; +------+------+------+------+------+ +------+------+------+------+------+ +------+------+------+------+------+ -; | 0 | 8.0 | 16.0 | 26.7 | 32.0 | | 0 | 128 | 256 | 426 | 512 | | 0 | 128 | 256 | 426 | 512 | -; | 1 | 7.5 | 15.0 | 25.0 | 30.0 | | 1 | 8 | 16 | 26.7 | 32 | | 1 | 1 | 2 | 3.3 | 4 | -; | 2 | 7.0 | 14.0 | 23.3 | 28.0 | | 2 | 16 | 32 | 53.3 | 64 | | 2 | 2 | 4 | 6.7 | 8 | -; | ... | ... | ... | ... | ... | | ... | ... | ... | ... | ... | | ... | ... | ... | ... | ... | -; | 14 | 1.0 | 2.0 | 3.3 | 4.0 | | 14 | 112 | 224 | 373 | 448 | | 126 | 126 | 252 | 420 | 504 | -; | 15 | 0.5 | 1.0 | 1.7 | 2.0 | | 15 | 120 | 240 | 400 | 480 | | 127 | 127 | 254 | 423 | 508 | -; +------+------+------+------+------+ +------+------+------+------+------+ +------+------+------+------+------+ +; Step Rate (milliseconds): Head Unload Time (milliseconds): Head Load Time (milliseconds): +; +------+------+------+------+------+ +------+------+------+------+------+ +------+------+------+------+------+ +; | | BITRATE | | | BITRATE | | | BITRATE | +; | VAL | 1.0M | 500K | 300K | 250K | | VAL | 1.0M | 500K | 300K | 250K | | VAL | 1.0M | 500K | 300K | 250K | +; +------+------+------+------+------+ +------+------+------+------+------+ +------+------+------+------+------+ +; | 0 | 8.0 | 16.0 | 26.7 | 32.0 | | 0 | 128 | 256 | 426 | 512 | | 0 | 128 | 256 | 426 | 512 | +; | 1 | 7.5 | 15.0 | 25.0 | 30.0 | | 1 | 8 | 16 | 26.7 | 32 | | 1 | 1 | 2 | 3.3 | 4 | +; | 2 | 7.0 | 14.0 | 23.3 | 28.0 | | 2 | 16 | 32 | 53.3 | 64 | | 2 | 2 | 4 | 6.7 | 8 | +; | ... | ... | ... | ... | ... | | ... | ... | ... | ... | ... | | ... | ... | ... | ... | ... | +; | 14 | 1.0 | 2.0 | 3.3 | 4.0 | | 14 | 112 | 224 | 373 | 448 | | 126 | 126 | 252 | 420 | 504 | +; | 15 | 0.5 | 1.0 | 1.7 | 2.0 | | 15 | 120 | 240 | 400 | 480 | | 127 | 127 | 254 | 423 | 508 | +; +------+------+------+------+------+ +------+------+------+------+------+ +------+------+------+------+------+ ; ; IBM PS/2 CALLS FOR: ; STEP RATE: 3ms (6ms FOR ALL 41mm OR 720K DRIVES) ; HEAD LOAD TIME: 15ms -; +; ; STATIC CONFIGURATION, NEVER CHANGES (PRIVATE) ; FCD_MT .EQU 000H ; MULTI-TRACK, WE DON'T USE, SET TO 0 @@ -277,7 +319,7 @@ FCD_TBL: LD HL,FCD_PC120 \ RET ; FDM120 = 3 LD HL,FCD_PC111 \ RET ; FDM111 = 4 ; -; DOR BITS (3AH) +; DOR BITS (3AH) ; ; DISKIO 250KBPS 500KBPS ; ------- ------- ------- @@ -363,85 +405,71 @@ FCS_VERSION .DB "VER$" ; ; FDC COMMAND TABLE ; -FCT .DB CFD_READ \ .DW FCS_READ +FCT .DB CFD_READ \ .DW FCS_READ FCT_ENTSIZ .EQU $ - FCT - .DB CFD_READDEL \ .DW FCS_READDEL - .DB CFD_WRITE \ .DW FCS_WRITE - .DB CFD_WRITEDEL \ .DW FCS_WRITEDEL - .DB CFD_READTRK \ .DW FCS_READTRK - .DB CFD_READID \ .DW FCS_READID - .DB CFD_FMTTRK \ .DW FCS_FMTTRK - .DB CFD_SCANEQ \ .DW FCS_SCANEQ - .DB CFD_SCANLOEQ \ .DW FCS_SCANLOEQ - .DB CFD_SCANHIEQ \ .DW FCS_SCANHIEQ - .DB CFD_RECAL \ .DW FCS_RECAL - .DB CFD_SENSEINT \ .DW FCS_SENSEINT - .DB CFD_SPECIFY \ .DW FCS_SPECIFY - .DB CFD_DRVSTAT \ .DW FCS_DRVSTAT - .DB CFD_SEEK \ .DW FCS_SEEK - .DB CFD_VERSION \ .DW FCS_VERSION + .DB CFD_READDEL \ .DW FCS_READDEL + .DB CFD_WRITE \ .DW FCS_WRITE + .DB CFD_WRITEDEL \ .DW FCS_WRITEDEL + .DB CFD_READTRK \ .DW FCS_READTRK + .DB CFD_READID \ .DW FCS_READID + .DB CFD_FMTTRK \ .DW FCS_FMTTRK + .DB CFD_SCANEQ \ .DW FCS_SCANEQ + .DB CFD_SCANLOEQ \ .DW FCS_SCANLOEQ + .DB CFD_SCANHIEQ \ .DW FCS_SCANHIEQ + .DB CFD_RECAL \ .DW FCS_RECAL + .DB CFD_SENSEINT \ .DW FCS_SENSEINT + .DB CFD_SPECIFY \ .DW FCS_SPECIFY + .DB CFD_DRVSTAT \ .DW FCS_DRVSTAT + .DB CFD_SEEK \ .DW FCS_SEEK + .DB CFD_VERSION \ .DW FCS_VERSION FCT_COUNT .EQU (($ - FCT) / FCT_ENTSIZ) ; # ENTRIES IN TABLE #ENDIF ; -; -; -FD_DISPATCH: - CALL FD_SELECTUNIT - RET NZ -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,FD_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,FD_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,FD_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,FD_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,FD_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,FD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,FD_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,FD_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,FD_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,FD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,FD_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,FD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +; DRIVER FUNCTION TABLE +; +FD_FNTBL: + .DW FD_STATUS + .DW FD_RESET + .DW FD_SEEK + .DW FD_READ + .DW FD_WRITE + .DW FD_VERIFY + .DW FD_FORMAT + .DW FD_DEVICE + .DW FD_MEDIA + .DW FD_DEFMED + .DW FD_CAP + .DW FD_GEOM +#IF (($ - FD_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID FD FUNCTION TABLE ***\n" +#ENDIF ; FD_VERIFY: FD_FORMAT: FD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; INVALID SUB-FUNCTION ; ; ; FD_DEVICE: - LD D,DIODEV_FD ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT + LD D,DIODEV_FD ; D := DEVICE TYPE + LD E,(IY+FD_DEV) ; E := PHYSICAL DEVICE NUMBER #IF (FDMEDIA == FDM720) - LD C,%11010100 ; 3.5" DS/DD -#ENDIF + LD C,%11010100 ; 3.5" DS/DD +#ENDIF #IF (FDMEDIA == FDM144) - LD C,%11011000 ; 3.5" DS/HD -#ENDIF + LD C,%11011000 ; 3.5" DS/HD +#ENDIF #IF (FDMEDIA == FDM360) - LD C,%10110100 ; 5.25" DS/DD -#ENDIF + LD C,%10110100 ; 5.25" DS/DD +#ENDIF #IF (FDMEDIA == FDM120) - LD C,%10111000 ; 5.25" DS/HD -#ENDIF + LD C,%10111000 ; 5.25" DS/HD +#ENDIF #IF (FDMEDIA == FDM111) - LD C,%10010100 ; 8" DS/DD -#ENDIF - XOR A ; SIGNAL SUCCESS + LD C,%10010100 ; 8" DS/DD +#ENDIF + XOR A ; SIGNAL SUCCESS RET ; ; FD_MEDIA @@ -453,8 +481,9 @@ FD_MEDIA: #IF (FDMAUTO) ; SETUP TO READ TRK 0, HD 0, SEC 0 - LD A,C ; C STILL HAS REQUESTED DRIVE - AND 0FH + ;LD A,C ; C STILL HAS REQUESTED DRIVE + LD A,(IY+FD_DEV) ; GET DRIVE UNIT + ;AND 0FH LD (FCD_DS),A LD A,0 LD (FCD_C),A @@ -476,30 +505,32 @@ FD_MEDIARETRY: ; TRY PRIMARY MEDIA CHOICE FIRST LD A,FDMEDIA CALL FD_TESTMEDIA - JR Z,FD_MEDIA3 ; IF SUCCESS, WE ARE DONE - + JR Z,FD_MEDIA3 ; IF SUCCESS, WE ARE DONE + ; TRY ALTERNATE MEDIA CHOICE LD A,FDMEDIAALT CALL FD_TESTMEDIA - JR Z,FD_MEDIA3 ; IF SUCCESS, WE ARE DONE - + JR Z,FD_MEDIA3 ; IF SUCCESS, WE ARE DONE + DJNZ FD_MEDIARETRY - + ; NO JOY, RETURN WITH E=0 (NO MEDIA) - LD HL,(FDDS_MEDIAADR) - LD (HL),0 ; SET TO NO MEDIA + ;LD HL,(FDDS_MEDIAADR) + ;LD (HL),0 ; SET TO NO MEDIA + LD (IY+FD_MEDTYP),0 ; SET DRIVE = NO MEDIA LD E,0 - OR $FF ; SIGNAL ERROR + OR $FF ; SIGNAL ERROR RET FD_TESTMEDIA: - LD HL,(FDDS_MEDIAADR) - LD (HL),A + ;LD HL,(FDDS_MEDIAADR) + ;LD (HL),A + LD (IY+FD_MEDTYP),A PUSH BC CALL FD_START POP BC RET - + FD_MEDIA3: #IF (FDTRACE < 3) @@ -514,13 +545,14 @@ FD_MEDIA4: #IF (FDTRACE >= 3) LD DE,FDSTR_SELECT CALL WRITESTR - LD BC,(FDDS_MEDIAADR) - CALL PRTHEXWORD + ;LD BC,(FDDS_MEDIAADR) + ;CALL PRTHEXWORD #ENDIF ; LOAD THE MEDIA BYTE - LD HL,(FDDS_MEDIAADR) - LD A,(HL) + ;LD HL,(FDDS_MEDIAADR) + ;LD A,(HL) + LD A,(IY+FD_MEDTYP) ; GET CURRENT MEDIA TYPE ADD A,MID_FD720 ; ASSUMES MID_ VALUES ARE IN SAME ORDER AS FDM VALUES #IF (FDTRACE >= 3) @@ -536,52 +568,39 @@ FD_MEDIA4: FD_CAP: CALL FD_GEOM ; GET GEOMETRY ; HL=TRACKS, D=HEADS, E=SECTORS - PUSH HL ; SAVE TRACK COUNT - LD H,D ; HEADS COUNT TO H - RES 7,H ; MAKE SURE LBA CAPABILITY BIT IS CLEARED - CALL MULT8 ; HL := H * E FOR SECTORS / CYL - POP DE ; RECOVER TRACKS, E == TRACK COUNT - LD H,L ; MOVE WORKING COUNT L --> H - CALL MULT8 ; HL := H * E FOR TOTAL SECTORS - LD DE,0 ; HI WORD ALWAYS ZERO - XOR A ; SIGNAL SUCCESS - RET ; DONE + PUSH HL ; SAVE TRACK COUNT + LD H,D ; HEADS COUNT TO H + RES 7,H ; MAKE SURE LBA CAPABILITY BIT IS CLEARED + CALL MULT8 ; HL := H * E FOR SECTORS / CYL + POP DE ; RECOVER TRACKS, E == TRACK COUNT + LD H,L ; MOVE WORKING COUNT L --> H + CALL MULT8 ; HL := H * E FOR TOTAL SECTORS + LD DE,0 ; HI WORD ALWAYS ZERO + XOR A ; SIGNAL SUCCESS + RET ; DONE ; ; ; FD_GEOM: - ;LD A,C ; GET DEVICE/UNIT - ;OR $0F ; ISOLATE UNIT - LD A,(FD_UNIT) ; GET DEVICE/UNIT - OR A ; SET FLAGS - JR Z,FD_GEOM0 ; UNIT 0 - DEC A ; NOPE, TRY UNIT 1 - JR Z,FD_GEOM1 ; UNIT 1 - CALL PANIC ; INVALID UNIT -FD_GEOM0: - LD A,(FCD_U0MEDIA) - JR FD_GEOM2 -FD_GEOM1: - LD A,(FCD_U1MEDIA) -FD_GEOM2: - RLCA ; TABLE IS 4 BYTE ENTRIES - RLCA ; A = A * 4 - LD HL,FCD_TBL ; HL = START OF TABLE - LD D,0 ; SET DE TO TABLE OFFSET + LD A,(IY+FD_MEDTYP) ; GET CURRENT MEDIA TYPE + RLCA ; TABLE IS 4 BYTE ENTRIES + RLCA ; A = A * 4 + LD HL,FCD_TBL ; HL = START OF TABLE + LD D,0 ; SET DE TO TABLE OFFSET LD E,A - ADD HL,DE ; OFFSET BASED ON DESIRED MEDIA - CALL JPHL ; CALL THE TABLE ENTRY (SEE FCD_TBL) + ADD HL,DE ; OFFSET BASED ON DESIRED MEDIA + CALL JPHL ; CALL THE TABLE ENTRY (SEE FCD_TBL) ; HL NOW POINTS TO START OF DESIRED MEDIA INFO - LD A,(HL) ; GET TRACKS - INC HL ; POINT TO HEADS - LD D,(HL) ; GET HEADS - ;SET 7,D ; SET LBA CAPABILITY BIT (FUTURE) - INC HL ; POINT TO SECTORS - LD E,(HL) ; GET SECTORS - LD L,A ; L := TRACKS - LD H,0 ; HI WORD OF TRACKS IS ALWAYS ZERO - XOR A ; SIGNAL SUCCESS - RET ; DONE + LD A,(HL) ; GET TRACKS + INC HL ; POINT TO HEADS + LD D,(HL) ; GET HEADS + ;SET 7,D ; SET LBA CAPABILITY BIT (FUTURE) + INC HL ; POINT TO SECTORS + LD E,(HL) ; GET SECTORS + LD L,A ; L := TRACKS + LD H,0 ; HI WORD OF TRACKS IS ALWAYS ZERO + XOR A ; SIGNAL SUCCESS + RET ; DONE ; ; FD_INIT ; @@ -594,40 +613,43 @@ FD_INIT: ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,2 ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX + LD B,FD_DEVCNT ; LOOP CONTROL + LD IY,FD_CFGTBL ; START OF CFG TABLE FD_INIT0: - PUSH BC ; SAVE LOOP CONTROL - LD B,C ; PHYSICAL UNIT - LD C,DIODEV_FD ; 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 FD_INIT0 ; LOOP UNTIL DONE + PUSH BC ; SAVE LOOP CONTROL + LD BC,FD_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + CALL FD_INITUNIT ; DO UNIT INITIALIZATION + LD BC,FD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ FD_INIT0 ; LOOP AS NEEDED ; - LD A,FDMEDIA - LD (FCD_U0MEDIA),A - LD (FCD_U1MEDIA),A - LD A,0FEH - LD (FCD_U0TRK),A - LD (FCD_U1TRK),A - LD A,FDTRACE LD (FCD_TRACE),A - +; LD BC,0 LD (FCD_IDLECNT),BC - +; LD A,DOR_INIT LD (FST_DOR),A - +; CALL FC_RESETFDC CALL FD_CLRDSKCHG - +; LD A,TRUE LD (FCD_FDCRDY),A - +; + RET +; +; UNIT INITIALIZATION +; +FD_INITUNIT: + LD (IY+FD_STAT),0 ; CLEAR STATUS + LD (IY+FD_MEDTYP),FDMEDIA ; SET DEFAULT MEDIA TYPE + LD (IY+FD_CURTRK),$FE ; SPECIAL VALUE FOR CURTRK RET ; ; FD_IDLE QUIESCES THE FLOPPY SUBSYSTEM (MOTOR OFF) @@ -639,7 +661,7 @@ FD_IDLE: LD A,B OR C RET Z ; COUNTER ALREADY FIRED - + DEC BC ; DECREMENT COUNTER LD (FCD_IDLECNT),BC ; SAVE IT LD A,B @@ -652,13 +674,11 @@ FD_IDLE: ; FD_STATUS ; FD_STATUS: - ;CALL FD_SELECTUNIT - LD HL,(FDDS_TRKADR) - LD A,(HL) ; A = CURRENT TRACK - + LD A,(IY+FD_CURTRK) ; A = CURRENT TRACK + CP 0FFH ; IS CURRENT TRACK = $FF? JR Z,FD_STATUS1 ; IF SO, NOT READY - + XOR A ; A = 0 = OK RET ; RETURN @@ -669,7 +689,7 @@ FD_STATUS1: ; ; FD_RESET: - XOR A ; ALWAYS OK + XOR A ; ALWAYS OK RET ; ; FD_CLRDSKCHG @@ -687,7 +707,7 @@ FD_CLRDSKCHG1: DJNZ FD_CLRDSKCHG1 ; ; FD_WTSEEK -; +; ; WAIT FOR PENDING SEEK OPERATION TO COMPLETE BY POLLING SENSEINT ; AND WAITING FOR ABTERM OR OK. ; @@ -698,55 +718,60 @@ FD_WTSEEKLOOP: PUSH BC CALL FC_SENSEINT POP BC - + LD A,(FST_RC) ; CHECK RC CP FRC_ABTERM ; ABTERM = DONE/FAILED JR Z,FD_RETRC CP FRC_OK ; OK = DONE/SUCCESS JR Z,FD_RETRC - + DEC BC ; CHECK LOOP COUNTER IN BC LD A,B ; " OR C ; " JR NZ,FD_WTSEEKLOOP ; LOOP UNTIL COUNTER EXHAUSTED - + FD_RETRC: LD A,(FST_RC) OR A RET ; TIMEOUT/FAILED -; +; ; FD_FDCRESET ; FD_FDCRESET: CALL FC_RESETFDC CALL FD_CLRDSKCHG - + LD A,TRUE LD (FCD_FDCRDY),A ; MARK ALL DRIVES AS NEEDING RECALIBRATION - ; NOTE THAT IF THE VALUE IS CURRENT $FF, + ; NOTE THAT IF THE VALUE IS CURRENT $FF, ; WE NEED TO LEAVE IT ALONE, SO WE 'OR' IN THE ; $FE TO AVOID THIS SCENARIO. - LD A,(FCD_U0TRK) - OR 0FEH - LD (FCD_U0TRK),A - - LD A,(FCD_U1TRK) - OR 0FEH - LD (FCD_U1TRK),A + + PUSH IY ; SAVE CURRENT IY + LD B,FD_DEVCNT ; LOOP CONTROL + LD DE,FD_CFGSIZ ; SIZE OF CFG ENTRY + LD IY,FD_CFGTBL ; START OF CFG TABLE +FD_FDCRESET1: + LD A,(IY+FD_CURTRK) ; GET CURRENT TRACK + OR $FE ; APPLY NEW VALUE + LD (IY+FD_CURTRK),A ; UPDATE TRACK + ADD IY,DE ; BUMP IY TO NEXT ENTRY + DJNZ FD_FDCRESET1 ; LOOP AS NEEDED + POP IY ; RESTORE IY RET ; ; FD_DRIVERESET -; +; ; ATTEMPT TO FULLY RESET FLOPPY DRIVE, PRIMARILY RECALIBRATE ; FD_DRIVERESET: CALL FC_SPECIFY RET NZ ; ERROR, BAIL OUT - + CALL FC_RECAL RET NZ ; ERROR, BAIL OUT @@ -764,45 +789,16 @@ FD_DRIVERESET: ; ; ; -FD_SELECTUNIT: - PUSH HL - PUSH DE - - LD A,C - AND 0FH ; ISOLATE THE UNIT NIBBLE - LD (FD_UNIT),A ; SAVE IT - - ; GOOD PLACE FOR AN INTEGRITY CHECK - CP 2 - CALL NC,PANIC - - LD HL,FCD_UNITS - LD D,0 - AND 0FH - RLCA - LD E,A - ADD HL,DE - - LD (FDDS_TRKADR),HL ; LOAD TRKADR - INC HL ; SKIP TRK - LD (FDDS_MEDIAADR),HL ; LOAD MEDIAADR - - POP DE - POP HL - - XOR A - RET -; -; -; FD_SEEK: - LD (HSTSEC),DE ; RECORD HEAD/SECTOR - LD (HSTTRK),HL ; RECORD TRACK + PUSH HL ; SAVE INCOMING HL TO (SP) + LD A,FD_HST ; A := HST OFFSET IN CFG ENTRY + CALL LDHLIYA ; HL := HST VALUE ADR + EX (SP),HL ; RESTORE INCOMING HL, HST ADR TO (SP) + POP BC ; HST ADR TO BC + CALL ST32 ; SAVE HST IN CFG ENTRY XOR A ; SIGNAL SUCCESS RET ; -; -; FD_READ: LD (FD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS LD A,DOP_READ @@ -820,39 +816,41 @@ FD_RW: RET Z ; ZERO SECTOR I/O, RETURN W/ E=0 & A=0 LD B,A ; INIT SECTOR DOWNCOUNTER LD C,0 ; INIT SECTOR READ/WRITE COUNT - + PUSH BC ; SAVE COUNTERS CALL FD_GEOM ; E := SPT, D := HDS POP BC ; RESTORE COUNTERS JR NZ,FD_RW4 ; BAIL OUT ON ERROR RES 7,D ; MAKE SURE LBA BIT IS CLEARED LD (FD_CURGEOM),DE ; SAVE AS FD_CURSPT & FD_CURHDS - + FD_RW1: PUSH BC ; SAVE COUNTERS CALL FD_RUN ; PERFORM SECTOR READ/WRITE JR NZ,FD_RW3 ; IF ERROR, SKIP INCREMENT - + ; INCREMENT SECTOR AND CHECK FOR TRACK OVERFLOW - LD HL,HSTSEC ; POINT TO CURRENT SECTOR + LD A,FD_HSTSEC ; HST SECTOR OFFSET IN CFG + CALL LDHLIYA ; HL := ADR OF HST SECTOR INC (HL) ; INCREMENT SECTOR LD A,(FD_CURSPT) ; A := SECTORS PER TRACK CP (HL) ; COMPARE SPT TO CURRENT SECTOR JR NZ,FD_RW2 ; IF NO OVERFLOW, DONE - + ; RESET SECTOR, INCREMENT HEAD, AND CHECK FOR CYLINDER OVERFLOW LD (HL),0 ; RESET SECTOR TO ZERO - LD HL,HSTHEAD ; POINT TO CURRENT HEAD + INC HL ; POINT TO HST HEAD INC (HL) ; INCREMENT HEAD LD A,(FD_CURHDS) ; A : = HEADS - CP (HL) ; COMPARE HEADS TO CUR HEAD + CP (HL) ; COMPARE HEADS TO HST HEAD JR NZ,FD_RW2 ; IF NO OVERFLOW, DONE - + ; RESET HEAD AND INCREMENT TRACK LD (HL),0 ; RESET HEAD TO ZERO - LD HL,(HSTTRK) ; GET CURRENT TRACK - INC HL ; INCREMENT - LD (HSTTRK),HL ; AND SAVE IT + DEC HL ; POINT TO HST TRACK + DEC HL ; ... + DEC HL ; ... + INC (HL) ; INCREMENT HST TRACK LSB FD_RW2: LD HL,FD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR @@ -869,29 +867,24 @@ FD_RW4: LD HL,(FD_DSKBUF) ; CURRENT DMA TO HL OR A ; SET FLAGS BASED ON RETURN CODE RET ; AND RETURN, A HAS RETURN CODE - + ; FD_RUN: ; UPDATE DRIVE SELECTION - ;LD A,(HSTDSK) ; GET THE NEW DRIVE SELECTION - ;AND 0FH - LD A,(FD_UNIT) ; GET UNIT + LD A,(IY+FD_DEV) ; GET UNIT LD (FCD_DS),A ; UPDATE FCD_DS TO NEW VALUE - ;LD C,A - ;CALL FD_SELECTUNIT - + ; MAP HSTTRK TO FCD_H, FCD_C - LD A,(HSTTRK) ; GET TRACK VALUE (CYLINDER IS MORE ACCURATE) + LD A,(IY+FD_HSTTRK) ; GET TRACK VALUE (CYLINDER IS MORE ACCURATE) LD (FCD_C),A ; ... AND MOVE IT TO CYL PARM - LD A,(HSTHEAD) ; GET HEAD VALUE + LD A,(IY+FD_HSTHD) ; GET HEAD VALUE LD (FCD_H),A ; ... AND MOVE IT TO HEAD PARM ; MAP HSTSEC TO FCD_R - LD BC,(HSTSEC) - LD A,C + LD A,(IY+FD_HSTSEC) INC A ; SWITCH FROM ZERO BASED TO ONE BASED LD (FCD_R),A - + ; SET RETRY COUNTER LD B,5 FD_RETRY: @@ -902,7 +895,7 @@ FD_RETRY: LD A,(FST_RC) ; CHECK RESULT OR A RET Z ; SUCCESS - + DJNZ FD_RETRY ; RETRY TILL COUNTER EXHAUSTED #IF (FDTRACE == 1) @@ -923,60 +916,51 @@ FD_START: ; COPY MEDIA CONFIG INTO FCD ; THIS IS HERE TO ACCOMMODATE DIFFERENT MEDIA ; IN DIFFERENT FLOPPY UNITS. - LD HL,(FDDS_MEDIAADR) - LD A,(HL) ; A = MEDIA BYTE - RLCA ; TABLE IS 4 BYTE ENTRIES - RLCA ; A = A * 4 - LD HL,FCD_TBL ; HL = START OF TABLE - LD D,0 ; SET DE TO TABLE OFFSET + LD A,(IY+FD_MEDTYP) ; A = MEDIA BYTE + RLCA ; TABLE IS 4 BYTE ENTRIES + RLCA ; A = A * 4 + LD HL,FCD_TBL ; HL = START OF TABLE + LD D,0 ; SET DE TO TABLE OFFSET LD E,A - ADD HL,DE ; OFFSET BASED ON DESIRED MEDIA - CALL JPHL ; CALL THE TABLE ENTRY (SEE FCD_TBL) - LD DE,FCD ; DE = DESTINATION - LD BC,FCD_LEN ; BC = BYTES TO COPY - LDIR ; BYTES COPY FROM MDB TO FCD + ADD HL,DE ; OFFSET BASED ON DESIRED MEDIA + CALL JPHL ; CALL THE TABLE ENTRY (SEE FCD_TBL) + LD DE,FCD ; DE = DESTINATION + LD BC,FCD_LEN ; BC = BYTES TO COPY + LDIR ; BYTES COPY FROM MDB TO FCD - CALL FC_MOTORON ; INCLUDES LATCH SETUP + CALL FC_MOTORON ; INCLUDES LATCH SETUP - LD HL,(FDDS_TRKADR) - LD A,(HL) - CP 0FEH ; FF = DRIVE NEEDS TO BE RESET - JR C,FD_RUN0 ; NO RESET NEEDED, BYPASS + LD A,(IY+FD_CURTRK) + CP 0FEH ; FF = DRIVE NEEDS TO BE RESET + JR C,FD_RUN0 ; NO RESET NEEDED, BYPASS CALL FD_DRIVERESET JR NZ,FD_RUNERR - - ; RECORD CURRENT TRACK POSITION - LD A,0 - LD HL,(FDDS_TRKADR) - LD (HL),A + + LD (IY+FD_CURTRK),0 ; ZERO CUR TRACK POS FD_RUN0: ; COMPARE CURRENT TRACK WITH REQUESTED TRACK TO SEE IF SEEK NEEDED - LD HL,(FDDS_TRKADR) - LD A,(HL) - LD B,A LD A,(FCD_C) - CP B - JR Z,FD_RUN1 ; FDDS_TRKADR == FCD_C, SKIP SEEK - + CP (IY+FD_CURTRK) + JR Z,FD_RUN1 ; FDDS_TRKADR == FCD_C, SKIP SEEK + ; INITIATE SEEK TO NEW TRACK CALL FC_SEEK JR NZ,FD_RUNERR - + ; WAIT FOR SEEK TO COMPLETE CALL FD_WTSEEK JR NZ,FD_RUNERR - + ; RECORD NEW CURRENT TRACK LD A,(FCD_C) - LD HL,(FDDS_TRKADR) - LD (HL),A - + LD (IY+FD_CURTRK),A + FD_RUN1: ; GET THE REQUESTED OPERATION LD A,(FCD_DOP) - + ; SETUP RETURN ADDRESS LD HL,FD_RUNCHK PUSH HL @@ -1006,9 +990,7 @@ FD_RUNERR: LD (FCD_FDCRDY),A ; FLAG DRIVE IN ERROR STATUS BY SETTING TRKADR == FF - LD A,0FFH - LD HL,(FDDS_TRKADR) - LD (HL),A + LD (IY+FD_CURTRK),$FF JP FD_RETRC @@ -1050,7 +1032,7 @@ FC_READID: LD A,CFD_READID | 01000000B CALL FC_SETUPCMD JP FOP - + FC_RECAL: LD A,CFD_RECAL | 00000000B CALL FC_SETUPCMD @@ -1092,17 +1074,17 @@ FC_SETUPCMD: LD (FCP_CMD),A ; SAVE IT FOR LATER INC DE - LD A,(FCD_H) ; START WITH HDS + LD A,(FCD_H) ; START WITH HDS AND 01H ; MASK TO REMOVE IRRELEVANT BITS FOR SAFETY RLCA ; MAKE ROOM FOR DS BITS - RLCA ; + RLCA ; LD B,A ; SAVE WHAT WE HAVE SO FAR IN B LD A,(FCD_DS) ; GET DS VALUE AND 03H ; MASK TO REMOVE IRRELEVANT BITS FOR SAFETY OR B ; COMBINE WITH SAVED LD (DE),A ; SAVE THE BYTE INC DE - + LD A,2 ; LENGTH IS 2 BYTES AT THIS POINT LD (FCP_LEN),A @@ -1114,43 +1096,43 @@ FC_SETUPIO: LD A,(FCD_C) LD (DE),A INC DE - + LD A,(FCD_H) LD (DE),A INC DE - + LD A,(FCD_R) LD (DE),A INC DE - + LD A,FCD_N LD (DE),A INC DE - + LD A,(FCD_EOT) LD (DE),A INC DE - + LD A,(FCD_GPL) LD (DE),A INC DE - + LD A,FCD_DTL LD (DE),A INC DE - + LD A,9 LD (FCP_LEN),A RET - + FC_SETUPSEEK: - CALL FC_SETUPCMD ; START WITH GENERIC IO CMD - + CALL FC_SETUPCMD ; START WITH GENERIC IO CMD + LD A,(FCD_C) LD (DE),A INC DE - + LD A,3 LD (FCP_LEN),A @@ -1159,15 +1141,15 @@ FC_SETUPSEEK: FC_SETUPSPECIFY: CALL FC_SETUPCMD DEC DE ; BACKUP 1 BYTE, WE ONLY WANT FIRST BYTE - + LD A,(FCD_SRTHUT) LD (DE),A ; SAVE THE BYTE INC DE - + LD A,(FCD_HLTND) LD (DE),A ; SAVE THE BYTE INC DE - + LD A,3 LD (FCP_LEN),A @@ -1256,8 +1238,8 @@ FC_MOTORON: LD BC,300H ; LD BC,10H LD (FCD_IDLECNT),BC - -#IF (FDTRACE >= 3) + +#IF (FDTRACE >= 3) LD DE,FDSTR_MOTON CALL WRITESTR #ENDIF @@ -1265,50 +1247,50 @@ FC_MOTORON: LD A,(FST_DOR) PUSH AF - LD A,(FCD_DOR) ; GET NEW LATCH VALUE (W/ MOTOR ON) - CALL FC_SETDOR ; AND IMPLEMENT IT + LD A,(FCD_DOR) ; GET NEW LATCH VALUE (W/ MOTOR ON) + CALL FC_SETDOR ; AND IMPLEMENT IT POP AF #IF ((FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3) | (FDMODE == FDMODE_SMBSMC)) - XOR 00000010B ; MOTOR BIT INVERTED ON ZETA + XOR 00000010B ; MOTOR BIT INVERTED ON ZETA #ENDIF - BIT 1,A ; SET FLAGS SET BASED ON CURRENT MOTOR BIT - RET Z ; MOTOR WAS PREVIOUSLY ON, WE ARE DONE + BIT 1,A ; SET FLAGS SET BASED ON CURRENT MOTOR BIT + RET Z ; MOTOR WAS PREVIOUSLY ON, WE ARE DONE #ENDIF #IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8) | (FDMODE == FDMODE_ZETA2) | (FDMODE == FDMODE_SMBWDC)) ; SETUP DCR FOR DIDE HARDWARE - LD A,(FCD_DCR) ; GET NEW DCR VALUE - CALL FC_SETDCR ; AND IMPLEMENT IT + LD A,(FCD_DCR) ; GET NEW DCR VALUE + CALL FC_SETDCR ; AND IMPLEMENT IT - LD HL,FST_DOR ; POINT TO FDC_DOR - LD A,(HL) ; START WITH CURRENT DOR + LD HL,FST_DOR ; POINT TO FDC_DOR + LD A,(HL) ; START WITH CURRENT DOR PUSH AF - AND 11111100B ; GET RID OF ANY ACTIVE DS BITS - LD C,A ; SAVE IT FOR NOW - LD A,(FCD_DS) ; NOW GET CURRENT DS - LD B,A ; PUT IN B FOR LATER - OR C ; COMBINE WITH SAVED DOR - LD C,A ; RE-SAVE IT - INC B ; SET UP B AS LOOP COUNTER (DS + 1) - LD A,00001000B ; STARTING BIT PATTERN FOR MOTOR + AND 11111100B ; GET RID OF ANY ACTIVE DS BITS + LD C,A ; SAVE IT FOR NOW + LD A,(FCD_DS) ; NOW GET CURRENT DS + LD B,A ; PUT IN B FOR LATER + OR C ; COMBINE WITH SAVED DOR + LD C,A ; RE-SAVE IT + INC B ; SET UP B AS LOOP COUNTER (DS + 1) + LD A,00001000B ; STARTING BIT PATTERN FOR MOTOR FC_MOTORON1: - RLA ; SHIFT LEFT - DJNZ FC_MOTORON1 ; DS TIMES - OR C ; COMBINE WITH SAVED - LD (HL),A ; COMMIT THE NEW VALUE TO FST_DOR - CALL FC_SETDOR ; OUTPUT TO CONTROLLER + RLA ; SHIFT LEFT + DJNZ FC_MOTORON1 ; DS TIMES + OR C ; COMBINE WITH SAVED + LD (HL),A ; COMMIT THE NEW VALUE TO FST_DOR + CALL FC_SETDOR ; OUTPUT TO CONTROLLER LD C,A POP AF CP C - RET Z ; MOTOR WAS PREVIOUSLY ON + RET Z ; MOTOR WAS PREVIOUSLY ON #ENDIF #IF (FDTRACE >= 3) LD DE,FDSTR_MOTDELAY CALL WRITESTR #ENDIF - CALL LDELAY ; DELAY FOR MOTOR SPINUP IF NOT PREVIOUSLY ON + CALL LDELAY ; DELAY FOR MOTOR SPINUP IF NOT PREVIOUSLY ON RET ; ; SET FST_DOR FOR MOTOR CONTROL OFF @@ -1317,11 +1299,11 @@ FC_MOTOROFF: LD A,(FCD_FDCRDY) CP TRUE CALL NZ,FD_FDCRESET - + LD A,DOR_INIT - CALL FC_SETDOR ; OUTPUT TO CONTROLLER - -#IF (FDTRACE >= 3) + CALL FC_SETDOR ; OUTPUT TO CONTROLLER + +#IF (FDTRACE >= 3) LD DE,FDSTR_MOTOFF CALL WRITESTR #ENDIF @@ -1343,53 +1325,53 @@ FOP: ; ; CLEAR FDC, DISCARD ANY PENDING BYTES (GARBAGE?) ; - LD B,0 ; B IS LOOP COUNTER + LD B,0 ; B IS LOOP COUNTER FOP_CLR1: - CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR - IN A,(FDC_MSR) ; GET STATUS - AND 0C0H ; ISOLATE HIGH NIBBLE, RQM/DIO/NDM/CB - CP 0C0H ; LOOKING FOR RQM=1, DIO=1, BYTES PENDING - JR NZ,FOP_CMD1 ; NO BYTES PENDING, GO TO NEXT PHASE - IN A,(FDC_DATA) ; GET THE PENDING BYTE AND DISCARD + CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR + IN A,(FDC_MSR) ; GET STATUS + AND 0C0H ; ISOLATE HIGH NIBBLE, RQM/DIO/NDM/CB + CP 0C0H ; LOOKING FOR RQM=1, DIO=1, BYTES PENDING + JR NZ,FOP_CMD1 ; NO BYTES PENDING, GO TO NEXT PHASE + IN A,(FDC_DATA) ; GET THE PENDING BYTE AND DISCARD DJNZ FOP_CLR1 - JP FOP_TOFDCRDY ; OTHERWISE, TIMEOUT + JP FOP_TOFDCRDY ; OTHERWISE, TIMEOUT ; ; SEND COMMAND ; FOP_CMD1: LD HL,FCP_BUF LD A,(FCP_LEN) - LD D,A ; D = CMD BYTES TO SEND + LD D,A ; D = CMD BYTES TO SEND FOP_CMD2: ; START OF LOOP TO SEND NEXT BYTE - LD B,0 ; B IS LOOP COUNTER - -FOP_CMD4: ; START OF STATUS LOOP, WAIT FOR FDC TO BE READY FOR BYTE - CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR - IN A,(FDC_MSR) ; READ MAIN STATUS REGISTER - AND 0C0H ; ISOLATE RQM/DIO - CP 080H ; LOOKING FOR RQM=1, DIO=0 (FDC READY FOR A BYTE) - JR Z,FOP_CMD6 ; GOOD, GO TO SEND BYTE - CP 0C0H ; HMMMM... RQM=1 & DIO=1, FDC WANTS TO SEND US DATA, UNEXPECTED - JR Z,FOP_RES ; GO IMMEDIATELY TO RESULTS??? - DJNZ FOP_CMD4 ; LOOP TILL COUNTER EXHAUSTED - JP FOP_TOSNDCMD ; COUNTER EXHAUSTED, TIMEOUT / EXIT + LD B,0 ; B IS LOOP COUNTER + +FOP_CMD4: ; START OF STATUS LOOP, WAIT FOR FDC TO BE READY FOR BYTE + CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR + IN A,(FDC_MSR) ; READ MAIN STATUS REGISTER + AND 0C0H ; ISOLATE RQM/DIO + CP 080H ; LOOKING FOR RQM=1, DIO=0 (FDC READY FOR A BYTE) + JR Z,FOP_CMD6 ; GOOD, GO TO SEND BYTE + CP 0C0H ; HMMMM... RQM=1 & DIO=1, FDC WANTS TO SEND US DATA, UNEXPECTED + JR Z,FOP_RES ; GO IMMEDIATELY TO RESULTS??? + DJNZ FOP_CMD4 ; LOOP TILL COUNTER EXHAUSTED + JP FOP_TOSNDCMD ; COUNTER EXHAUSTED, TIMEOUT / EXIT FOP_CMD6: ; SEND NEXT BYTE - LD A,(HL) ; POINT TO NEXT BYTE TO SEND - OUT (FDC_DATA),A ; PUSH IT TO FDC - INC HL ; INCREMENT POINTER FOR NEXT TIME - DEC D ; DECREMENT NUM BYTES LEFT TO SEND - JR NZ,FOP_CMD2 ; DO NEXT BYTE + LD A,(HL) ; POINT TO NEXT BYTE TO SEND + OUT (FDC_DATA),A ; PUSH IT TO FDC + INC HL ; INCREMENT POINTER FOR NEXT TIME + DEC D ; DECREMENT NUM BYTES LEFT TO SEND + JR NZ,FOP_CMD2 ; DO NEXT BYTE ; ; EXECUTION PHASE ; FOP_X1: LD A,(FCP_CMD) - + LD HL,FOP_RES PUSH HL - + CP CFD_READ JP Z,FXR_READ CP CFD_WRITE @@ -1475,7 +1457,7 @@ FOP_TOEXEC: FOP_ERR: LD (FST_RC),A - + FOP_EVAL: LD A,(FCP_CMD) ; DRVSTAT IS WEIRD, HAS ONLY ST3, NOTHING TO EVAL @@ -1485,18 +1467,18 @@ FOP_EVAL: LD A,(FRB_LEN) CP 1 JP M,FOP_EXIT - + FOP_EVALST0: LD A,(FRB_ST0) AND 11000000B - CP 01000000B ; ABTERM + CP 01000000B ; ABTERM JR Z,FOP_ABTERM - CP 10000000B ; INVCMD + CP 10000000B ; INVCMD JR Z,FOP_INVCMD - CP 11000000B ; DSKCHG + CP 11000000B ; DSKCHG JR Z,FOP_DSKCHG JR FOP_EXIT - + FOP_ABTERM: ; SENSEINT DOES NOT USE ST1 LD A,(FCP_CMD) @@ -1511,14 +1493,14 @@ FOP_ABTERM1: ; NO FURTHER DATA, SET FST TO ABTERM LD C,FRC_ABTERM JR FOP_SETFST -FOP_INVCMD: +FOP_INVCMD: LD C,FRC_INVCMD JR FOP_SETFST FOP_DSKCHG: LD C,FRC_DSKCHG JR FOP_SETFST - + FOP_EVALST1: LD A,(FRB_ST1) @@ -1566,7 +1548,7 @@ FXR_NOP: ; NULL EXECUTION, NO DATA TO READ/WRITE (USED BY READID) ; ; DO NOTHING, BUT WAIT FOR FDC READY. LOOP NEEDS TO ALLOW FOR -; 2 FULL ROTATIONS OF THE DISK WHICH IS 400ms AT 300RPM +; 2 FULL ROTATIONS OF THE DISK WHICH IS 400ms AT 300RPM ; FXR_NULL: LD BC,$4000 ; LOOP COUNTER, $4000 * 25us = 410ms @@ -1584,7 +1566,7 @@ FXR_NULL1: RET ; ; READ DATA -; +; FXR_READ: HB_DI ; TIME CRITICAL , INTERRUPTS WILL CAUSE I/O ERRS LD HL,(FD_DSKBUF) ; POINT TO SECTOR BUFFER START @@ -1609,8 +1591,8 @@ FXRR4: IN A,(FDC_DATA) ; GET PENDING BYTE LD (HL),A ; STORE IT IN BUFFER INC HL ; INCREMENT THE BUFFER POINTER DEC DE ; DECREMENT BYTE COUNT - LD A,D - OR E + LD A,D + OR E JR NZ,FXRR2 ; IF NOT ZERO, REPEAT LOOP JR FXR_END ; CLEAN EXIT @@ -1650,8 +1632,8 @@ FXRW4: LD A,(HL) ; GET NEXT BYTE TO WRITE OUT (FDC_DATA),A ; WRITE IT INC HL ; INCREMENT THE BUFFER POINTER DEC DE ; DECREMENT LOOP COUNTER - LD A,D - OR E + LD A,D + OR E JR NZ,FXRW2 ; IF NOT ZERO, REPEAT LOOP JR FXR_END ; CLEAN EXIT FXRW5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED @@ -1707,7 +1689,7 @@ FC_PRTFST0: ; START OF LOOP LD C,(HL) CP C JR Z,FC_PRTFST1 ; FOUND CODE - + ADD HL,DE ; POINT TO NEXT ENTRY DJNZ FC_PRTFST0 ; CHECK NEXT ENTRY TILL COUNT IS ZERO @@ -1717,7 +1699,7 @@ FC_PRTFST0: ; START OF LOOP CALL PRTHEXBYTE CALL PC_RBKT JR FC_PRTFSTX - + FC_PRTFST1: ; ENTRY FOUND, PRINT IT CALL PC_SPACE INC HL @@ -1752,7 +1734,7 @@ FCPC_LOOP: ; START OF LOOP LD C,(HL) CP C JR Z,FCPC_MATCH ; FOUND CODE - + ADD HL,DE ; POINT TO NEXT ENTRY DJNZ FCPC_LOOP ; CHECK NEXT ENTRY TILL COUNT IS ZERO @@ -1762,7 +1744,7 @@ FCPC_LOOP: ; START OF LOOP CALL PRTHEXBYTE CALL PC_RBKT JR FCPC_EXIT - + FCPC_MATCH: ; ENTRY FOUND, PRINT IT INC HL LD E,(HL) @@ -1783,21 +1765,21 @@ FC_PRTRESULTS: ; IF TRACE IS SET, FORCE PRINT RESULTS LD A,(FCD_TRACE) OR A - RET Z ; IF TRACE = 0, BE SILENT! - - CP 3 ; IS TRACE >= 3 ? - JR NC,FCPR2 ; YES, SO FORCE PRINT EVERYTHING! - + RET Z ; IF TRACE = 0, BE SILENT! + + CP 3 ; IS TRACE >= 3 ? + JR NC,FCPR2 ; YES, SO FORCE PRINT EVERYTHING! + ; IF RC=OK, GET OUT, NOTHING TO PRINT LD A,(FST_RC) CP FRC_OK RET Z - + ; SPECIAL CASE, DON'T PRINT IF SENSEINT & INVCMD/DSK CHG/ABTERM LD A,(FCP_CMD) CP CFD_SENSEINT JR NZ,FCPR2 - + LD A,(FST_RC) CP FRC_INVCMD JR Z,FCPR_EXIT @@ -1806,10 +1788,10 @@ FC_PRTRESULTS: CP FRC_ABTERM JR Z,FCPR_EXIT JR FCPR_EXIT - + FCPR2: CALL NEWLINE - + LD DE,FDSTR_FD CALL WRITESTR CALL PC_COLON @@ -1922,24 +1904,8 @@ FCD_TRACE .DB 0 ; TRACE LEVEL FCD_TO .DB 0 ; TIMEOUT COUNTDOWN TIMER FCD_FDCRDY .DB 0 ; FALSE MEANS FDC RESET NEEDED ; -; FLOPPY UNIT DATA -; -FCD_UNITS: -FCD_U0TRK .DB 0FFH ; CURRENT TRACK -FCD_U0MEDIA .DB FDMEDIA ; MEDIA BYTE -; .DW FDDPH0 ; ADDRESS OF DPH -; -FCD_U1TRK .DB 0FFH ; CURRENT TRACK -FCD_U1MEDIA .DB FDMEDIA ; MEDIA BYTE -; -; WORKING STORAGE (DERIVED FROM ABOVE FOR ACTIVE DRIVE UNIT) -; -FDDS_TRKADR .DW 0 ; POINTER TO FDCUXTRK ABOVE -FDDS_MEDIAADR .DW 0 ; POINTER TO FDCUXMEDIA ABOVE -; ; GENERAL WORKING STORAGE ; -FD_UNIT .DB 0 FD_DSKBUF .DW 0 FD_CURGEOM .EQU $ ; TWO BYTES BELOW FD_CURSPT .DB 0 ; CURRENT SECTORS PER TRACK diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 13a3c165..825f1fa8 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -5,7 +5,7 @@ ; ; THIS FILE CONTAINS THE HBIOS IMAGE THAT IS INTENDED TO RUN IN A DEDICATED RAM BANK. THE CODE IS ; CONSTRUCTED SUCH THAT IT CAN BE LAUNCHED IN A VARIETY OF MODES AND INSTALL ITSELF. A SMALL 512 -; BYTE PROXY IS PLACED AT THE TOP OF CPU MEMORY (FE00H-FFFFH). THIS PROXY CODE ALLOWS CODE +; BYTE PROXY IS PLACED AT THE TOP OF CPU MEMORY (FE00H-FFFFH). THIS PROXY CODE ALLOWS CODE ; RUNNING FROM ANY BANK TO INVOKE HBIOS FUNCTIONS. NORMALLY, ANY BANK THAT RUNS CODE WOULD SETUP ; THE RST 8 VECTOR TO POINT TO THE PROXY INVOKE ENTRY POINT AT FFF0H. CALLS VIA THE PROXY INVOKE ; ENTRY POINT TRANSPARENTLY SWAP IN THE HBIOS BANK, PERFORM THE REQUESTED FUNCTION, AND RETURN @@ -174,8 +174,8 @@ CB_BIDROMDN .DB BID_ROMDN ; ; THE FOLLOWING CODE IS RELOCATED TO THE TOP OF MEMORY TO HANDLE INVOCATION DISPATCHING ; - .FILL (HBX_IMG - $) ; FILL TO START OF PROXY IMAGE START - .ORG HBX_LOC ; ADJUST FOR RELOCATION + .FILL (HBX_IMG - $) ; FILL TO START OF PROXY IMAGE START + .ORG HBX_LOC ; ADJUST FOR RELOCATION ; ; MEMORY LAYOUT: ; @@ -187,40 +187,40 @@ CB_BIDROMDN .DB BID_ROMDN ; ; DEFINITIONS ; -HBX_BUFSIZ .EQU $40 ; INTERBANK COPY BUFFER SIZE +HBX_BUFSIZ .EQU $40 ; INTERBANK COPY BUFFER SIZE ; ; HBIOS IDENTIFICATION DATA BLOCK ; HBX_IDENT: - .DB 'W',~'W' ; MARKER - .DB RMJ << 4 | RMN ; FIRST BYTE OF VERSION INFO - .DB RUP << 4 | RTP ; SECOND BYTE OF VERSION INFO + .DB 'W',~'W' ; MARKER + .DB RMJ << 4 | RMN ; FIRST BYTE OF VERSION INFO + .DB RUP << 4 | RTP ; SECOND BYTE OF VERSION INFO ; ;================================================================================================== ; HBIOS ENTRY FOR RST 08 PROCESSING ;================================================================================================== ; HBX_INVOKE: - LD (HBX_INVSP),SP ; SAVE ORIGINAL STACK FRAME - LD A,(HB_CURBNK) ; GET CURRENT BANK - LD (HB_INVBNK),A ; SAVE INVOCATION BANK + LD (HBX_INVSP),SP ; SAVE ORIGINAL STACK FRAME + LD A,(HB_CURBNK) ; GET CURRENT BANK + LD (HB_INVBNK),A ; SAVE INVOCATION BANK - LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH - LD A,BID_BIOS ; HBIOS BANK - CALL HBX_BNKSEL ; SELECT IT - LD SP,HB_STACK ; NOW USE FULL HBIOS STACK IN HBIOS BANK + LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH + LD A,BID_BIOS ; HBIOS BANK + CALL HBX_BNKSEL ; SELECT IT + LD SP,HB_STACK ; NOW USE FULL HBIOS STACK IN HBIOS BANK - CALL HB_DISPATCH ; CALL HBIOS FUNCTION DISPATCHER + CALL HB_DISPATCH ; CALL HBIOS FUNCTION DISPATCHER - LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH - PUSH AF ; SAVE AF (FUNCTION RETURN) - LD A,(HB_INVBNK) ; LOAD ORIGINAL BANK - CALL HBX_BNKSEL ; SELECT IT - POP AF ; RESTORE AF - LD SP,0 ; RESTORE ORIGINAL STACK FRAME + LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH + PUSH AF ; SAVE AF (FUNCTION RETURN) + LD A,(HB_INVBNK) ; LOAD ORIGINAL BANK + CALL HBX_BNKSEL ; SELECT IT + POP AF ; RESTORE AF + LD SP,0 ; RESTORE ORIGINAL STACK FRAME HBX_INVSP .EQU $ - 2 - RET ; RETURN TO CALLER + RET ; RETURN TO CALLER ; ;;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ;; BNKSEL - Switch Memory Bank to Bank in A. @@ -246,9 +246,9 @@ HBX_BNKSEL_INT: BIT 7,A ; BIT 7 SET REQUESTS RAM PAGE JR Z,HBX_ROM ; NOT SET, SELECT ROM PAGE RES 7,A ; RAM PAGE REQUESTED: CLEAR ROM BIT - ADD A,16 ; ADD 16 x 32K - RAM STARTS FROM 512K -; -HBX_ROM: + ADD A,16 ; ADD 16 x 32K - RAM STARTS FROM 512K +; +HBX_ROM: RLCA ; TIMES 2 - GET 16K PAGE INSTEAD OF 32K OUT (MPGSEL_0),A ; BANK_0: 0K - 16K INC A ; @@ -258,8 +258,8 @@ HBX_ROM: #IF (PLATFORM == PLT_N8) BIT 7,A ; TEST BIT 7 FOR RAM VS. ROM JR Z,HBX_ROM ; IF NOT SET, SELECT ROM PAGE -; -HBX_RAM: +; +HBX_RAM: RES 7,A ; CLEAR BIT 7 FROM ABOVE RLCA ; SCALE SELECTOR TO RLCA ; ... GO FROM Z180 4K PAGE SIZE @@ -268,8 +268,8 @@ HBX_RAM: LD A,N8_DEFACR | 80H ; SELECT RAM BY SETTING BIT 7 OUT0 (N8_ACR),A ; ... IN N8 ACR REGISTER RET ; DONE -; -HBX_ROM: +; +HBX_ROM: OUT0 (N8_RMAP),A ; BANK INDEX TO N8 RMAP REGISTER XOR A ; ZERO ACCUM OUT0 (Z180_BBR),A ; ZERO BANK BASE @@ -282,7 +282,7 @@ HBX_ROM: RLCA ; RAM FLAG TO CARRY FLAG AND BIT 0 JR NC,HBX_BNKSEL1 ; IF NC, WANT ROM PAGE, SKIP AHEAD XOR %00100001 ; SET BIT FOR HI 512K, CLR BIT 0 -HBX_BNKSEL1: +HBX_BNKSEL1: RLCA ; CONTINUE SHIFTING TO SCALE SELECTOR RLCA ; FOR Z180 4K PAGE -> DESIRED 32K PAGE OUT0 (Z180_BBR),A ; WRITE TO BANK BASE @@ -308,35 +308,35 @@ HBX_BNKCPY: HB_DI #ENDIF - LD (HBX_BC_SP),SP ; PUT STACK - LD SP,HBX_TMPSTK ; ... IN HI MEM + LD (HBX_BC_SP),SP ; PUT STACK + LD SP,HBX_TMPSTK ; ... IN HI MEM - LD A,(HB_CURBNK) ; GET CURRENT BANK - PUSH AF ; AND SAVE TO RESTORE LATER - PUSH BC ; CUR LEN -> (SP) + LD A,(HB_CURBNK) ; GET CURRENT BANK + PUSH AF ; AND SAVE TO RESTORE LATER + PUSH BC ; CUR LEN -> (SP) ; HBX_BC_LOOP: - EX (SP),HL ; HL := CUR LEN, (SP) := CUR SRC - LD BC,HBX_BUFSIZ ; SET BC TO BOUNCE BUFFER SIZE - OR A ; CLEAR CARRY FLAG - SBC HL,BC ; CUR LEN := CUR LEN - BBUF SIZE - JR C,HBX_BC_LAST ; END GAME, LESS THAN BBUF BYTES LEFT - EX (SP),HL ; HL := CUR SRC, (SP) := REM LEN - CALL HBX_BC_ITER ; DO A FULL BBUF SIZE CHUNK - JR HBX_BC_LOOP ; AND REPEAT TILL DONE + EX (SP),HL ; HL := CUR LEN, (SP) := CUR SRC + LD BC,HBX_BUFSIZ ; SET BC TO BOUNCE BUFFER SIZE + OR A ; CLEAR CARRY FLAG + SBC HL,BC ; CUR LEN := CUR LEN - BBUF SIZE + JR C,HBX_BC_LAST ; END GAME, LESS THAN BBUF BYTES LEFT + EX (SP),HL ; HL := CUR SRC, (SP) := REM LEN + CALL HBX_BC_ITER ; DO A FULL BBUF SIZE CHUNK + JR HBX_BC_LOOP ; AND REPEAT TILL DONE ; HBX_BC_LAST: ; HL IS BETWEEN -(BBUF SIZE) AND -1, BC = BBUF SIZE - OR A ; CLEAR CARRY - ADC HL,BC ; HL := REM LEN (0 - 127) - EX (SP),HL ; HL := CUR SRC, (SP) := REM LEN - POP BC ; BC := REM LEN - CALL NZ,HBX_BC_ITER ; DO FINAL CHUNK, IFF > 0 BYTES - POP AF ; RECOVER ORIGINAL BANK - CALL HBX_BNKSEL ; SWITCH + OR A ; CLEAR CARRY + ADC HL,BC ; HL := REM LEN (0 - 127) + EX (SP),HL ; HL := CUR SRC, (SP) := REM LEN + POP BC ; BC := REM LEN + CALL NZ,HBX_BC_ITER ; DO FINAL CHUNK, IFF > 0 BYTES + POP AF ; RECOVER ORIGINAL BANK + CALL HBX_BNKSEL ; SWITCH - LD SP,$FFFF ; RESTORE STACK -HBX_BC_SP .EQU $ - 2 ; ... TO ORIGINAL VALUE + LD SP,$FFFF ; RESTORE STACK +HBX_BC_SP .EQU $ - 2 ; ... TO ORIGINAL VALUE #IF (INTTYPE == IT_SIMH) HB_EI @@ -345,20 +345,20 @@ HBX_BC_SP .EQU $ - 2 ; ... TO ORIGINAL VALUE ; HBX_BC_ITER: ; HL = SRC ADR, DE = DEST ADR, BC = LEN - PUSH BC ; SAVE COPY LEN - PUSH DE ; FINAL DEST ON STACK - LD DE,HBX_BUF ; SET DEST TO BUF - LD A,(HB_SRCBNK) ; GET SOURCE BANK - CALL HBX_BNKSEL ; SWITCH TO SOURCE BANK - LDIR ; HL -> BUF (DE), BC BYTES, HL UPDATED SRC ADR - POP DE ; DE := FINAL DEST - POP BC ; GET LEN BACK IN BC - PUSH HL ; SAVE UPDATED SRC ADR - LD HL,HBX_BUF ; SET SRC ADR TO BUF - LD A,(HB_DSTBNK) ; GET DEST BANK - CALL HBX_BNKSEL ; SWITCH TO DEST BANK - LDIR ; BUF (HL) -> DE, BC BYTES, DE UPDATED DEST ADR - POP HL ; RECOVER UPDATED SRC ADR + PUSH BC ; SAVE COPY LEN + PUSH DE ; FINAL DEST ON STACK + LD DE,HBX_BUF ; SET DEST TO BUF + LD A,(HB_SRCBNK) ; GET SOURCE BANK + CALL HBX_BNKSEL ; SWITCH TO SOURCE BANK + LDIR ; HL -> BUF (DE), BC BYTES, HL UPDATED SRC ADR + POP DE ; DE := FINAL DEST + POP BC ; GET LEN BACK IN BC + PUSH HL ; SAVE UPDATED SRC ADR + LD HL,HBX_BUF ; SET SRC ADR TO BUF + LD A,(HB_DSTBNK) ; GET DEST BANK + CALL HBX_BNKSEL ; SWITCH TO DEST BANK + LDIR ; BUF (HL) -> DE, BC BYTES, DE UPDATED DEST ADR + POP HL ; RECOVER UPDATED SRC ADR ; HL = UPD SRC, DE = UPD DEST, BC = 0 RET ; @@ -367,23 +367,23 @@ HBX_BC_ITER: ; ON INPUT A=TARGET BANK, HL=TARGET ADDRESS ; HBX_BNKCALL: - LD (HBX_TGTBNK),A ; STUFF TARGET BANK TO CALL INTO CODE BELOW - LD (HBX_TGTADR),HL ; STUFF ADDRESS TO CALL INTO CODE BELOW - LD A,(HB_CURBNK) ; GET CURRENT BANK - PUSH AF ; SAVE FOR RETURN + LD (HBX_TGTBNK),A ; STUFF TARGET BANK TO CALL INTO CODE BELOW + LD (HBX_TGTADR),HL ; STUFF ADDRESS TO CALL INTO CODE BELOW + LD A,(HB_CURBNK) ; GET CURRENT BANK + PUSH AF ; SAVE FOR RETURN HBX_TGTBNK .EQU $ + 1 - LD A,$FF ; LOAD BANK TO CALL ($FF OVERLAID AT ENTRY) - CALL HBX_BNKSEL ; ACTIVATE THE NEW BANK + LD A,$FF ; LOAD BANK TO CALL ($FF OVERLAID AT ENTRY) + CALL HBX_BNKSEL ; ACTIVATE THE NEW BANK HBX_TGTADR .EQU $ + 1 - CALL $FFFF ; CALL ROUTINE ($FFFF IS OVERLAID ABOVE) + CALL $FFFF ; CALL ROUTINE ($FFFF IS OVERLAID ABOVE) - EX (SP),HL ; SAVE HL AND GET BANK TO RESTORE IN HL - PUSH AF ; SAVE AF - LD A,H ; BANK TO RESTORE TO A - CALL HBX_BNKSEL ; RESTORE IT - POP AF ; RECOVER AF - POP HL ; RECOVER HL + EX (SP),HL ; SAVE HL AND GET BANK TO RESTORE IN HL + PUSH AF ; SAVE AF + LD A,H ; BANK TO RESTORE TO A + CALL HBX_BNKSEL ; RESTORE IT + POP AF ; RECOVER AF + POP HL ; RECOVER HL RET ; ; PEEK & POKE ROUTINES @@ -393,11 +393,11 @@ HBX_PEEK: #IF (INTTYPE == IT_SIMH) HB_DI #ENDIF - LD (HBX_PPSP),SP ; SAVE ORIGINAL STACK FRAME - LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM + LD (HBX_PPSP),SP ; SAVE ORIGINAL STACK FRAME + LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM LD A,(HB_CURBNK) PUSH AF - LD A,D + LD A,D CALL HBX_BNKSEL LD E,(HL) JR HBX_PPRET @@ -406,18 +406,18 @@ HBX_POKE: #IF (INTTYPE == IT_SIMH) HB_DI #ENDIF - LD (HBX_PPSP),SP ; SAVE ORIGINAL STACK FRAME - LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM + LD (HBX_PPSP),SP ; SAVE ORIGINAL STACK FRAME + LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM LD A,(HB_CURBNK) PUSH AF - LD A,D + LD A,D CALL HBX_BNKSEL LD (HL),E ; HBX_PPRET: POP AF CALL HBX_BNKSEL - LD SP,0 ; RESTORE ORIGINAL STACK FRAME + LD SP,0 ; RESTORE ORIGINAL STACK FRAME HBX_PPSP .EQU $ - 2 #IF (INTTYPE == IT_SIMH) HB_EI @@ -451,13 +451,13 @@ HBX_IVT: .DW INT_BAD ; IVT_CSIO .DW INT_BAD ; IVT_SER0 .DW INT_BAD ; IVT_SER1 - .DW INT_BAD ; - .DW INT_BAD ; - .DW INT_BAD ; - .DW INT_BAD ; - .DW INT_BAD ; - .DW INT_BAD ; - .DW INT_BAD ; + .DW INT_BAD ; + .DW INT_BAD ; + .DW INT_BAD ; + .DW INT_BAD ; + .DW INT_BAD ; + .DW INT_BAD ; + .DW INT_BAD ; ; ; INTERRUPT HANDLER STUBS ; @@ -467,30 +467,30 @@ HBX_IVT: ; ; INT_IM1: - PUSH HL ; SAVE HL - LD HL,HB_IM1INT ; HL := IM1 INT HANDLER IN BIOS BANK - JR HBX_INT ; TO TO ROUTING CODE + PUSH HL ; SAVE HL + LD HL,HB_IM1INT ; HL := IM1 INT HANDLER IN BIOS BANK + JR HBX_INT ; TO TO ROUTING CODE ; INT_TIMER: ; TIMER INTERRUPT HANDLER - PUSH HL ; SAVE HL - LD HL,HB_TIMINT ; HL := INT ADR IN BIOS - JR HBX_INT ; GO TO ROUTING CODE + PUSH HL ; SAVE HL + LD HL,HB_TIMINT ; HL := INT ADR IN BIOS + JR HBX_INT ; GO TO ROUTING CODE ; INT_BAD: ; BAD INTERRUPT HANDLER - PUSH HL ; SAVE HL - LD HL,HB_BADINT ; HL := INT HANDLER IN BIOS BANK - JR HBX_INT ; TO TO ROUTING CODE + PUSH HL ; SAVE HL + LD HL,HB_BADINT ; HL := INT HANDLER IN BIOS BANK + JR HBX_INT ; TO TO ROUTING CODE ; #IF (SIOENABLE) INT_SIO: ; SIO INTERRUPT HANDLER - PUSH HL ; SAVE HL - LD HL,SIO_INT ; HL := SIO INT HANDLER IN BIOS BANK - JR HBX_INT ; TO TO ROUTING CODE + PUSH HL ; SAVE HL + LD HL,SIO_INT ; HL := SIO INT HANDLER IN BIOS BANK + JR HBX_INT ; TO TO ROUTING CODE #ENDIF ; ; COMMON INTERRUPT DISPATCHING CODE ; SETUP AND CALL HANDLER IN BIOS BANK -; +; HBX_INT: ; COMMON INTERRUPT ROUTING CODE ; LD (HBX_INT_SP),SP ; SAVE ORIGINAL STACK FRAME @@ -537,23 +537,23 @@ HBX_BUF .FILL HBX_BUFSIZ,0 ; HBIOS PROXY MGMT BLOCK (TOP 32 BYTES) ; #IFDEF ROMBOOT - .DB BID_BOOT ; CURRENTLY ACTIVE LOW MEMORY BANK ID + .DB BID_BOOT ; CURRENTLY ACTIVE LOW MEMORY BANK ID #ELSE - .DB BID_USR ; CURRENTLY ACTIVE LOW MEMORY BANK ID -#ENDIF - .DB 0 ; BANK ACTIVE AT TIME OF HBIOS CALL INVOCATION - .DW 0 ; BNKCPY SOURCE ADDRESS - .DB BID_USR ; BNKCPY SOURCE BANK ID - .DW 0 ; BNKCPY DESTINATION ADDRESS - .DB BID_USR ; BNKCPY DESTINATION BANK ID - .DW 0 ; BNKCPY LENGTH - .FILL 6,0 ; FILLER, RESERVED FOR FUTURE HBIOS USE - JP HBX_INVOKE ; FIXED ADR ENTRY FOR HBX_INVOKE (ALT FOR RST 08) - JP HBX_BNKSEL ; FIXED ADR ENTRY FOR HBX_BNKSEL - JP HBX_BNKCPY ; FIXED ADR ENTRY FOR HBX_BNKCPY - JP HBX_BNKCALL ; FIXED ADR ENTRY FOR HBX_BNKCALL - .DW HBX_IDENT ; ADDRESS OF HBIOS PROXY START (DEPRECATED) - .DW HBX_IDENT ; ADDRESS OF HBIOS IDENT INFO DATA BLOCK + .DB BID_USR ; CURRENTLY ACTIVE LOW MEMORY BANK ID +#ENDIF + .DB 0 ; BANK ACTIVE AT TIME OF HBIOS CALL INVOCATION + .DW 0 ; BNKCPY SOURCE ADDRESS + .DB BID_USR ; BNKCPY SOURCE BANK ID + .DW 0 ; BNKCPY DESTINATION ADDRESS + .DB BID_USR ; BNKCPY DESTINATION BANK ID + .DW 0 ; BNKCPY LENGTH + .FILL 6,0 ; FILLER, RESERVED FOR FUTURE HBIOS USE + JP HBX_INVOKE ; FIXED ADR ENTRY FOR HBX_INVOKE (ALT FOR RST 08) + JP HBX_BNKSEL ; FIXED ADR ENTRY FOR HBX_BNKSEL + JP HBX_BNKCPY ; FIXED ADR ENTRY FOR HBX_BNKCPY + JP HBX_BNKCALL ; FIXED ADR ENTRY FOR HBX_BNKCALL + .DW HBX_IDENT ; ADDRESS OF HBIOS PROXY START (DEPRECATED) + .DW HBX_IDENT ; ADDRESS OF HBIOS IDENT INFO DATA BLOCK ; .FILL $MEMTOP - $ ; FILL TO END OF MEMORY (AS NEEDED) .ORG HBX_IMG + HBX_SIZ ; RESET ORG @@ -582,9 +582,9 @@ HB_STACK .EQU $ ; TOP OF HBIOS STACK ;================================================================================================== ; HB_START: - DI ; NO INTERRUPTS - IM 1 ; INTERRUPT MODE 1 - LD SP,HBX_LOC ; SETUP INITIAL STACK JUST BELOW HBIOS PROXY + DI ; NO INTERRUPTS + IM 1 ; INTERRUPT MODE 1 + LD SP,HBX_LOC ; SETUP INITIAL STACK JUST BELOW HBIOS PROXY ; #IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) ; SET BASE FOR CPU IO REGISTERS @@ -610,15 +610,15 @@ HB_START: OUT0 (Z180_DCNTL),A CALL DLY8 ; SETTLE - ; MMU SETUP - LD A,$80 - OUT0 (Z180_CBAR),A ; SETUP FOR 32K/32K BANK CONFIG -;#IFDEF ROMBOOT -; XOR A -; OUT0 (Z180_BBR),A ; BANK BASE = 0 -;#ENDIF - LD A,(RAMSIZE + RAMBIAS - 64) >> 2 - OUT0 (Z180_CBR),A ; COMMON BASE = LAST (TOP) BANK + ; MMU SETUP + LD A,$80 + OUT0 (Z180_CBAR),A ; SETUP FOR 32K/32K BANK CONFIG +;#IFDEF ROMBOOT +; XOR A +; OUT0 (Z180_BBR),A ; BANK BASE = 0 +;#ENDIF + LD A,(RAMSIZE + RAMBIAS - 64) >> 2 + OUT0 (Z180_CBR),A ; COMMON BASE = LAST (TOP) BANK #IF (Z180_CLKDIV >= 1) ; SET CLOCK DIVIDE TO 1 RESULTING IN FULL XTAL SPEED @@ -660,7 +660,7 @@ HB_START: ;X2 .EQU X1 + 2 ;X3 .EQU X2 + 2 ;X4 .EQU X3 + 2 - + ; LD HL,(HBX_IMG) ; LD (X1),HL @@ -697,27 +697,27 @@ HB_START: CALL HBX_BNKCPY ; ; INTERRUPTS ARE ENABLED BY BNKCPY!!! - DI ; RE-DISABLE INTERRUPTS + DI ; RE-DISABLE INTERRUPTS ; ; TRANSITION TO HBIOS IN RAM BANK ; - LD A,BID_BIOS ; BIOS BANK ID - LD HL,HB_START1 ; EXECUTION RESUMES HERE - CALL HBX_BNKCALL ; CONTINUE IN RAM BANK, DO NOT RETURN - HALT ; WE SHOULD NOT COME BACK HERE! + LD A,BID_BIOS ; BIOS BANK ID + LD HL,HB_START1 ; EXECUTION RESUMES HERE + CALL HBX_BNKCALL ; CONTINUE IN RAM BANK, DO NOT RETURN + HALT ; WE SHOULD NOT COME BACK HERE! ; -HB_RAMFLAG .DB FALSE ; ASSUME FALSE, SET TO TRUE BELOW AFTER RAM TRANSITION +HB_RAMFLAG .DB FALSE ; ASSUME FALSE, SET TO TRUE BELOW AFTER RAM TRANSITION ; ; EXECUTION RESUMES HERE AFTER SWITCH TO RAM BANK ; -HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK +HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK ; ; INTERRUPTS ARE ENABLED BY BNKCALL!!! - DI ; RE-DISABLE INTERRUTPS + DI ; RE-DISABLE INTERRUTPS ; - LD SP,HBX_LOC ; RESET STACK SINCE WE DO NOT RETURN - LD A,TRUE ; ACCUM := TRUE - LD (HB_RAMFLAG),A ; SET RAMFLAG + LD SP,HBX_LOC ; RESET STACK SINCE WE DO NOT RETURN + LD A,TRUE ; ACCUM := TRUE + LD (HB_RAMFLAG),A ; SET RAMFLAG ; ; PERFORM DYNAMIC CPU SPEED DERIVATION ; @@ -773,7 +773,7 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK ; IO PORT SCAN ; #IF 0 -PSCN: +PSCN: LD C,0 ; IO PORT NUMBER LD B,0 ; LOOP COUNTER CALL NEWLINE @@ -812,7 +812,7 @@ PSCNX .EQU $ + 1 LD HL,INT_TIMER ; ADDRESS OF TIMER INT HANDLER ;LD ($39),HL ; ... IS TARGET OF JP LD ($31),HL ; ... IS TARGET OF JP - + LD HL,INT_TIMER LD (HBX_IVT),HL ; @@ -837,7 +837,7 @@ PSCNX .EQU $ + 1 LD (HBX_IVT + IVT_TIM0),HL ; SETUP PERIODIC TIMER INTERRUPT ON TIMER 0 - LD HL,(CB_CPUKHZ) ; 50HZ = 18432000 / 20 / 50 / X, SO X = CPU KHZ + LD HL,(CB_CPUKHZ) ; 50HZ = 18432000 / 20 / 50 / X, SO X = CPU KHZ LD B,0 LD C,Z180_RLDR0L ; INITIALIZE TIMER 0 RELOAD REGISTER OUT (C),L @@ -849,7 +849,7 @@ PSCNX .EQU $ + 1 OUT (C),H LD A,%00010001 ; ENABLE TIMER0 INT AND DOWN COUNTING OUT0 (Z180_TCR),A -; +; #ENDIF ; #IF (INTTYPE == IT_RC) @@ -958,18 +958,18 @@ INITSYS1: ; ; BIOS IS CONFIGURED TO AUTO ACTIVATE CRT DEVICE. FIRST, ; CHECK TO SEE IF WE HAVE A VALID CRT DEVICE TO USE. -; - LD A,(CB_CRTDEV) ; GET THE CRT DEVICE - INC A ; INCREMENT TO TEST FOR $FF - JR Z,INITSYS3 ; IF NO CRT DEVICE, BYPASS CONSOLE SWITCH +; + LD A,(CB_CRTDEV) ; GET THE CRT DEVICE + INC A ; INCREMENT TO TEST FOR $FF + JR Z,INITSYS3 ; IF NO CRT DEVICE, BYPASS CONSOLE SWITCH ; ; IF PLATFORM HAS A CONFIG JUMPER, CHECK TO SEE IF IT IS JUMPERED. ; IF SO, BYPASS SWITCH TO CRT CONSOLE (FAILSAFE MODE) ; #IF ((PLATFORM != PLT_N8) & (PLATFORM != PLT_MK4)) - IN A,(RTC) ; RTC PORT, BIT 6 HAS STATE OF CONFIG JUMPER - BIT 6,A ; BIT 6 HAS CONFIG JUMPER STATE - JR Z,INITSYS3 ; Z=SHORTED, BYPASS CONSOLE SWITCH + IN A,(RTC) ; RTC PORT, BIT 6 HAS STATE OF CONFIG JUMPER + BIT 6,A ; BIT 6 HAS CONFIG JUMPER STATE + JR Z,INITSYS3 ; Z=SHORTED, BYPASS CONSOLE SWITCH #ENDIF ; ; NOTIFY USER OF CONSOLE SWITCH ON BOOT CONSOLE @@ -993,10 +993,10 @@ INITSYS3: ; #IFDEF ROMBOOT ; PERFORM BANK CALL TO OS IMAGES BANK - LD A,BID_OSIMG ; CHAIN TO OS IMAGES BANK - LD HL,0 ; ENTER AT ADDRESS 0 - CALL HBX_BNKCALL ; GO THERE - HALT ; WE SHOULD NEVER COME BACK! + LD A,BID_OSIMG ; CHAIN TO OS IMAGES BANK + LD HL,0 ; ENTER AT ADDRESS 0 + CALL HBX_BNKCALL ; GO THERE + HALT ; WE SHOULD NEVER COME BACK! #ELSE ; COPY OS IMAGE: BID_USR: --> BID_USR:0 LD A,BID_USR @@ -1008,10 +1008,10 @@ INITSYS3: CALL HBX_BNKCPY ; ; PERFORM BANK CALL TO OS IMAGES BANK - LD A,BID_USR ; CHAIN TO OS IMAGES BANK - LD HL,0 ; ENTER AT ADDRESS 0 - CALL HBX_BNKCALL ; GO THERE - HALT ; WE SHOULD NEVER COME BACK! + LD A,BID_USR ; CHAIN TO OS IMAGES BANK + LD HL,0 ; ENTER AT ADDRESS 0 + CALL HBX_BNKCALL ; GO THERE + HALT ; WE SHOULD NEVER COME BACK! ; #ENDIF ; @@ -1135,22 +1135,22 @@ HB_DISPCALL: ; #ENDIF ; *DEBUG* END ; - LD A,B ; REQUESTED FUNCTION IS IN B - CP BF_CIO + $10 ; $00-$0F: CHARACTER I/O + LD A,B ; REQUESTED FUNCTION IS IN B + CP BF_CIO + $10 ; $00-$0F: CHARACTER I/O JP C,CIO_DISPATCH - CP BF_DIO + $10 ; $10-$1F: DISK I/O + CP BF_DIO + $10 ; $10-$1F: DISK I/O JP C,DIO_DISPATCH - CP BF_RTC + $10 ; $20-$2F: REAL TIME CLOCK (RTC) + CP BF_RTC + $10 ; $20-$2F: REAL TIME CLOCK (RTC) JP C,RTC_DISPATCH - CP BF_EMU + $10 ; $30-$3F: EMULATION - CALL C,PANIC ; OBSOLETE! - CP BF_VDA + $10 ; $40-$4F: VIDEO DISPLAY ADAPTER + CP BF_EMU + $10 ; $30-$3F: EMULATION + CALL C,PANIC ; OBSOLETE! + CP BF_VDA + $10 ; $40-$4F: VIDEO DISPLAY ADAPTER JP C,VDA_DISPATCH - - CP BF_SYS ; SKIP TO BF_SYS VALUE AT $F0 - CALL C,PANIC ; PANIC IF LESS THAN BF_SYS - JP SYS_DISPATCH ; OTHERWISE SYS CALL - CALL PANIC ; THIS SHOULD NEVER BE REACHED + + CP BF_SYS ; SKIP TO BF_SYS VALUE AT $F0 + CALL C,PANIC ; PANIC IF LESS THAN BF_SYS + JP SYS_DISPATCH ; OTHERWISE SYS CALL + CALL PANIC ; THIS SHOULD NEVER BE REACHED ; ;================================================================================================== ; CHARACTER I/O DEVICE DISPATCHER @@ -1175,7 +1175,7 @@ CIO_DISPATCH: JR C,CIO_DISPATCH1 ; UNIT OK, PROCEED CP CIODEV_CONSOLE ; CHECK FOR SPECIAL VALUE - CONSOLE OUTPUT JR Z,CIO_DISPATCH_CON ; DO IT -; +; ; NOT GOOD, INCOMING UNIT IS OUT OF RANGE POP HL ; RESTORE HL/STACK CALL PANIC ; PANIC @@ -1195,25 +1195,22 @@ CIO_DISPATCH1: CALL ADDHLA ; HL := ADDRESS OF ENTRY IN TABLE ; ; GET FIRST WORD OF TABLE ENTRY AND SAVE FOR DRIVER CALL - LD A,(HL) ; DEREFERENCE - INC HL ; ... - PUSH HL ; SAVE IT FOR BELOW - LD H,(HL) ; ... - LD L,A ; ... SO HL HAS ADDRESS OF DRIVER DISPATCH - LD (CIO_TGTADR),HL ; SAVE THE TARGET ADDRESS TO CALL LATER + LD A,(HL) + LD (CIO_TGTADR+0),A + INC HL + LD A,(HL) + LD (CIO_TGTADR+1),A + INC HL ; ; GET SECOND WORD OF TABLE ENTRY AND PUT IN IY FOR DRIVER CALL - POP HL ; GET TABLE ENTRY ADDRESS BACK - INC HL ; INCREMENT TO DATA WORD LD A,(HL) ; GET DATA WORD INC HL ; ... LD H,(HL) ; ... LD L,A ; ... INTO HL - PUSH HL ; AND COPY IT - POP IY ; ... TO IY -; + EX (SP),HL ; RESTORE HL & MOVE BLOB ADR TO (SP) + POP IY ; BLOB ADR TO IY + ; CALL DRIVER (ADDRESS BYTES OF CALL INSTRUCTION UPDATED ABOVE) - POP HL ; GET ORIGINAL HL BACK (10) CALL PANIC ; CALL DRIVER DISPATCH ENTRY CIO_TGTADR .EQU $ - 2 ; REFERENCE TO ADDRESS OF CALL INSTRUCTION POP IY ; RESTORE ORIGINAL IY @@ -1227,7 +1224,7 @@ CIO_TGTADR .EQU $ - 2 ; REFERENCE TO ADDRESS OF CALL INSTRUCTION ; EACH ENTRY IS DEFINED AS: ; ; WORD DRIVER DISPATCH ENTRY ADDRESS -; WORD UNIT SPECIFIC DATA (MAY BE AN ADDRESS) +; WORD UNIT SPECIFIC DATA (TYPICALLY A DEVICE INSTANCE DATA ADDRESS) ; CIO_MAX .EQU 16 ; UP TO 16 UNITS CIO_SIZ .EQU CIO_MAX * 4 ; EACH ENTRY IS 4 BYTES @@ -1250,38 +1247,6 @@ CIO_ADDENT: ; B: FUNCTION ; C: UNIT NUMBER ; - -;NDIO_NEWDISP: -; ; START OF THE ACTUAL DRIVER DISPATCHING LOGIC -; PUSH IY ; SAVE ORIGINAL IY -; PUSH HL ; SAVE HL -; LD HL,NDIO_RET ; GET RETURN VECTOR -; EX (SP),HL ; RECOVER HL & PUT RETURN VECTOR ON TOS -; PUSH HL ; SAVE HL -; LD HL,DIO_TBL ; POINT TO DISPATCH TABLE -; LD A,C ; GET REQUESTED UNIT FROM C -; RLCA ; MULTIPLY UNIT BY 4 -; RLCA ; ... TO GET BYTE OFFSET OF ENTRY -; CALL ADDHLA ; HL -> ENTRY ADDRESS -; LD A,(HL) ; DRIVER ID TO A -; PUSH AF ; SAVE IT FOR NOW -; INC HL ; POINT TO UNIT -; LD C,(HL) ; PUT IT IN C FOR DRIVER -; INC HL ; POINT TO LSB OF UNIT DATA ADDRESS -; LD A,(HL) ; HL := UNIT DATA ADDRESS -; INC HL ; ... -; LD H,(HL) ; ... -; LD L,A ; ... -; POP AF ; RECOVER DRIVER ID -; EX (SP),HL ; RECOVER ORIG HL & PUT UNIT DATA ADDRESS TO TOS -; POP IY ; IY := UNIT DATA ADDRESS -; JP NDIO_DISPATCH2 ; USE LEGACY DISPATCHER -;; -;NDIO_RET: -; POP IY ; RECOVER IY -; OR A ; MAKE SURE FLAGS ARE SET -; RET ; AND RETURN - DIO_DISPATCH: ; #IF 0 ; *DEBUG* START @@ -1289,7 +1254,7 @@ DIO_DISPATCH: ; DUMP INCOMING CALL CALL NEWLINE PRTS("DIO>$") - CALL REGDMP ; DUMP REGS, NONE DESTROYED + CALL REGDMP ; DUMP REGS, NONE DESTROYED ; ; DO THE ACTUAL DISPATCH PROCESSING CALL DIO_DISPCALL @@ -1297,94 +1262,96 @@ DIO_DISPATCH: ; DUMP CALL RESULTS AND RETURN CALL NEWLINE PRTS("DIO<$") - CALL REGDMP ; DUMP REGS, NONE DESTROYED + CALL REGDMP ; DUMP REGS, NONE DESTROYED RET ; #ENDIF ; *DEBUG* END ; ; ON ENTRY C IS HBIOS UNIT # (INDEX INTO DIO_TBL OF DISK DEVICES) -; USE UNIT # IN C TO LOOKUP DIO_TBL ENTRY, THEN -; CONVERT C TO THE DEVICE/DRIVER SPECIFIC UNIT ID -; AND GET THE DEVICE TYPE TO A FOR DRIVER DISPATCHING -; SETUP IY WITH DEVICE SPECIFIC DATA POINTER +; USE UNIT # IN C TO LOOKUP DIO_TBL ENTRY. THE DIO_TBL +; ENTRY CONTAINS THE START OF THE DRIVER FUNCTION TABLE AND +; THE DEVICE SPECIFIC INSTANCE DATA (BLOB). SET IY TO BLOB ADDRESS +; AND CALL THE SPECIFIC FUNCTION REQUESTED IN THE DRIVER. ; DIO_DISPCALL: PUSH IY ; SAVE INCOMING IY - + + ; SETUP TO RESTORE IY AT EXIT LD IY,DIO_DISPEXIT ; PRIME STACK WITH PUSH IY ; ... RETURN VECTOR - + + ; START WITH IY POINTING TO START OF DIO_TBL LD IY,DIO_TBL ; POINT IY TO START OF DIO TABLE + + ; CHECK INCOMING UNIT INDEX IN C FOR VAILIDITY LD A,C ; A := INCOMING DISK UNIT INDEX CP (IY-1) ; COMPARE TO COUNT JR NC,DIO_DISPERR ; HANDLE INVALID UNIT INDEX - PUSH DE ; SAVE DE - RLCA ; MULTIPLY UNIT INDEX - RLCA ; ... BY 4 (SIZE OF TABLE ENTRY) - LD D,0 ; SET DE TO - LD E,A ; ... TABLE ENTRY OFFSET - ADD IY,DE ; APPLY OFFSET SO IY HAS ENTRY ADR - EX DE,HL ; SAVE HL IN DE - LD A,(IY+0) ; A := DEVICE TYPE - LD C,(IY+1) ; C := DEVICE NUMBER + ; CHECK FUNCTION INDEX FOR VALIDITY + LD A,B ; A := INCOMING FUNCTION NUMBER + AND $0F ; LOW NIBBLE ONLY FOR FUNC INDEX + CP DIO_FNCNT ; COMPARE TO DIO FUNCTION COUNT IN A + JR NC,DIO_DISPERR ; HANDLED INVALID FUNCTION NUMBER + + ; BUMP IY TO ACTUAL DIO_TBL ENTRY FOR INCOMING UNIT INDEX + LD B,0 ; MSB IS ALWAYS ZERO + RLC C ; MULTIPLY UNIT INDEX + RLC C ; ... BY 4 FOR TABLE ENTRY OFFSET + ADD IY,BC ; SET IY TO ENTRY ADDRESS + + ; DERIVE DRIVER FUNC ADR TO CALL + PUSH HL ; SAVE INCOMING HL + LD L,(IY+0) ; COPY DRIVER FUNC TABLE + LD H,(IY+1) ; ... START TO HL + RLCA ; CONV UNIT (STILL IN A) TO FN ADR OFFSET + CALL ADDHLA ; HL NOW HAS DRIVER FUNC TBL START ADR + LD A,(HL) ; DEREFERENCE HL + INC HL ; ... TO GET + LD H,(HL) ; ... ACTUAL + LD L,A ; ... TARGET FUNCTION ADDRESS + EX (SP),HL ; RESTORE HL, FUNC ADR ON STACK + + ; GET UNIT INSTANCE DATA BLOB ADDRESS TO IY + PUSH HL ; SAVE INCOMING HL LD L,(IY+2) ; HL := DATA BLOB ADDRESS LD H,(IY+3) ; ... - EX (SP),HL ; RESTORE DE INTO HL, BLOB ADR TO TOS - EX DE,HL ; ORIGINAL DE & HL RESTORED - POP IY ; BLOB ADR TO IY - -#IF (MDENABLE) - CP DIODEV_MD - JP Z,MD_DISPATCH -#ENDIF -#IF (FDENABLE) - CP DIODEV_FD - JP Z,FD_DISPATCH -#ENDIF -#IF (RFENABLE) - CP DIODEV_RF - JP Z,RF_DISPATCH -#ENDIF -#IF (IDEENABLE) - CP DIODEV_IDE - JP Z,IDE_DISPATCH -#ENDIF -#IF (PPIDEENABLE) - CP DIODEV_PPIDE - JP Z,PPIDE_DISPATCH -#ENDIF -#IF (SDENABLE) - CP DIODEV_SD - JP Z,SD_DISPATCH -#ENDIF -#IF (PRPENABLE) - #IF (PRPSDENABLE) - CP DIODEV_PRPSD - JP Z,PRPSD_DISPATCH - #ENDIF -#ENDIF -#IF (PPPENABLE) - #IF (PPPSDENABLE) - CP DIODEV_PPPSD - JP Z,PPPSD_DISPATCH - #ENDIF -#ENDIF -#IF (HDSKENABLE) - CP DIODEV_HDSK - JP Z,HDSK_DISPATCH -#ENDIF - CALL PANIC - RET + EX (SP),HL ; RESTORE HL, BLOB ADR ON TOS + POP IY ; IY := BLOB ADR + + RET ; JUMP TO DRIVER FUNC ADR ON TOS ; -DIO_DISPEXIT: +DIO_DISPEXIT: POP IY ; RECOVER ORIGINAL INCOMING IY RET ; AND RETURN TO CALLER ; DIO_DISPERR: CALL PANIC ; PANIC OR $FF ; SIGNAL ERROR - RET ; AND RETURN + RET ; AND RETURN VIA DISPEXIT +; +; HBIOS DISK DEVICE UNIT TABLE +; +; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION. +; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT +; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES. +; EACH ENTRY IS DEFINED AS: +; +; WORD DRIVER DISPATCH ENTRY ADDRESS +; WORD UNIT SPECIFIC DATA (TYPICALLY A DEVICE INSTANCE DATA ADDRESS) +; +DIO_MAX .EQU 16 ; UP TO 16 UNITS +DIO_SIZ .EQU DIO_MAX * 4 ; EACH ENTRY IS 4 BYTES +; + .DB DIO_MAX ; MAX ENTRY COUNT TABLE PREFIX +DIO_CNT .DB 0 ; ENTRY COUNT PREFIX +DIO_TBL .FILL DIO_SIZ,0 ; SPACE FOR ENTRIES +; +; ADD AN ENTRY TO THE DIO UNIT TABLE +; +DIO_ADDENT: + LD HL,DIO_TBL ; POINT TO DIO TABLE + JP HB_ADDENT ; ... AND GO TO COMMON CODE ; ; CONVERT AN HBIOS STANDARD HARD DISK CHS ADDRESS TO ; AN LBA ADDRESS. A STANDARD HBIOS HARD DISK IS ASSUMED @@ -1395,28 +1362,6 @@ DIO_DISPERR: ; HB_CHS2LBA: ; - ;; DEBUG: DUMP INCOMING TRACK:HEAD/SEC - ;CALL NEWLINE - ;PUSH BC - ;PUSH HL - ;POP BC - ;CALL PRTHEXWORD - ;CALL PC_COLON - ;PUSH DE - ;POP BC - ;CALL PRTHEXWORD - ;POP BC -; - ; WE HAVE INCOMING HARDDISK CHS, CONVERT TO LBA - ; HL=TRACK (0..N), D=HEAD (0..15), E=SECTOR (0..15) - ; XLAT HL:DE (TT:HS) --> 32 BIT LBA (LBAHI:LBALO) - ; - ; D/E -> A (COMBINE HEAD/SEC AND SAVE IN A) - ; 0 -> D - ; H -> E - ; L -> H - ; A -> L - ; LD A,D ; HEAD TO A RLCA ; LEFT SHIFT TO HIGH NIBBLE RLCA ; ... DEPENDS ON HIGH @@ -1427,45 +1372,9 @@ HB_CHS2LBA: LD E,H LD H,L LD L,A -; - ;; DEBUG: DUMP RESULTING LBA (32 BIT) - ;PRTS("-->$") - ;PUSH BC - ;PUSH DE - ;POP BC - ;CALL PRTHEXWORD - ;PUSH HL - ;POP BC - ;CALL PRTHEXWORD - ;POP BC -; XOR A RET ; -; HBIOS DISK DEVICE UNIT TABLE -; -; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION. -; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT -; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES. -; EACH ENTRY IS DEFINED AS: -; -; BYTE DEVICE TYPE ID -; BYTE DEVICE/DRIVER UNIT NUMBER -; WORD UNIT DATA ADDRESS -; -DIO_MAX .EQU 16 ; UP TO 16 UNITS -DIO_SIZ .EQU DIO_MAX * 4 ; EACH ENTRY IS 4 BYTES -; - .DB DIO_MAX ; MAX ENTRY COUNT TABLE PREFIX -DIO_CNT .DB 0 ; ENTRY COUNT PREFIX -DIO_TBL .FILL DIO_SIZ,0 ; SPACE FOR ENTRIES -; -; ADD AN ENTRY TO THE DIO UNIT TABLE -; -DIO_ADDENT: - LD HL,DIO_TBL ; POINT TO DIO TABLE - JP HB_ADDENT ; ... AND GO TO COMMON CODE -; ;================================================================================================== ; REAL TIME CLOCK DEVICE DISPATCHER ;================================================================================================== @@ -1491,9 +1400,6 @@ RTC_DISPATCH: ; C: UNIT NUMBER ; VDA_DISPATCH: -; LD A,C ; REQUESTED DEVICE/UNIT IS IN C -; AND $F0 ; ISOLATE THE DEVICE PORTION - ; ; ON ENTRY C IS HBIOS UNIT # (INDEX INTO VDA_TBL OF VIDEO DEVICES) ; USE UNIT # IN C TO LOOKUP VDA_TBL ENTRY, THEN @@ -1506,7 +1412,7 @@ VDA_DISPATCH: LD HL,VDA_CNT ; HL := ADDRESS OF TABLE ENTRY COUNT CP (HL) ; COMPARE TO INCOMING ENTRY INDEX JR C,VDA_DISPATCH1 ; UNIT OK, PROCEED -; +; ; NOT GOOD, INCOMING UNIT IS OUT OF RANGE POP HL ; RESTORE HL/STACK CALL PANIC ; PANIC @@ -1576,32 +1482,32 @@ VDA_ADDENT: ; B: FUNCTION ; SYS_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,SYS_RESET ; $F0 + LD A,B ; GET REQUESTED FUNCTION + AND $0F ; ISOLATE SUB-FUNCTION + JP Z,SYS_RESET ; $F0 DEC A - JP Z,SYS_VER ; $F1 + JP Z,SYS_VER ; $F1 DEC A - JP Z,SYS_SETBNK ; $F2 + JP Z,SYS_SETBNK ; $F2 DEC A - JP Z,SYS_GETBNK ; $F3 + JP Z,SYS_GETBNK ; $F3 DEC A - JP Z,SYS_SETCPY ; $F4 + JP Z,SYS_SETCPY ; $F4 DEC A - JP Z,SYS_BNKCPY ; $F5 + JP Z,SYS_BNKCPY ; $F5 DEC A - JP Z,SYS_ALLOC ; $F6 + JP Z,SYS_ALLOC ; $F6 DEC A - JP Z,SYS_FREE ; $F7 + JP Z,SYS_FREE ; $F7 DEC A - JP Z,SYS_GET ; $F8 + JP Z,SYS_GET ; $F8 DEC A - JP Z,SYS_SET ; $F9 + JP Z,SYS_SET ; $F9 DEC A - JP Z,SYS_PEEK ; $FA + JP Z,SYS_PEEK ; $FA DEC A - JP Z,SYS_POKE ; $FB - CALL PANIC ; INVALID + JP Z,SYS_POKE ; $FB + CALL PANIC ; INVALID ; ; SET ACTIVE MEMORY BANK AND RETURN PREVIOUSLY ACTIVE MEMORY BANK ; NOTE THAT IT GOES INTO EFFECT AS HBIOS FUNCTION IS EXITED @@ -1609,84 +1515,47 @@ SYS_DISPATCH: ; CALLER MUST EXTABLISH UPPER MEMORY STACK BEFORE INVOKING THIS FUNCTION! ; SYS_SETBNK: - PUSH HL ; SAVE INCOMING HL - LD HL,HB_INVBNK ; POINT TO HBIOS INVOKE BANK ID ADDRESS - LD A,(HL) ; GET EXISTING BANK ID TO A - LD (HL),C ; UPDATE INVOKE BANK TO NEW BANK ID - LD C,A ; PUT PREVIOUS BANK ID IN C FOR RETURN - POP HL ; RESTORE ORIGINAL HL - XOR A ; SIGNAL SUCCESS - RET ; DONE + PUSH HL ; SAVE INCOMING HL + LD HL,HB_INVBNK ; POINT TO HBIOS INVOKE BANK ID ADDRESS + LD A,(HL) ; GET EXISTING BANK ID TO A + LD (HL),C ; UPDATE INVOKE BANK TO NEW BANK ID + LD C,A ; PUT PREVIOUS BANK ID IN C FOR RETURN + POP HL ; RESTORE ORIGINAL HL + XOR A ; SIGNAL SUCCESS + RET ; DONE ; ; GET ACTIVE MEMORY BANK ; SYS_GETBNK: - LD A,(HB_INVBNK) ; GET THE ACTIVE MEMORY BANK - LD C,A ; MOVE TO C - XOR A ; SIGNAL SUCCESS + LD A,(HB_INVBNK) ; GET THE ACTIVE MEMORY BANK + LD C,A ; MOVE TO C + XOR A ; SIGNAL SUCCESS RET ; ; SET BANKS AND LENGTH FOR INTERBANK MEMORY COPY (BNKCPY) ; ENTRY: E=SOURCE BANK ID -; D=DEST BANK ID -; HL=COPY LENGTH (IN BYTES) +; D=DEST BANK ID +; HL=COPY LENGTH (IN BYTES) ; SYS_SETCPY: LD A,E - LD (HB_SRCBNK),A ; RECORD THE SOURCE BANK + LD (HB_SRCBNK),A ; RECORD THE SOURCE BANK LD A,D - LD (HB_DSTBNK),A ; RECORD THE DESTINATION BANK - LD (HB_CPYLEN),HL ; RECORD THE COPY LENGTH + LD (HB_DSTBNK),A ; RECORD THE DESTINATION BANK + LD (HB_CPYLEN),HL ; RECORD THE COPY LENGTH XOR A RET ; ; PERFORM MEMORY COPY POTENTIALLY ACROSS BANKS ; ENTRY: HL=SOURCE ADDRESS -; DE=DESTINATION ADDRESS +; DE=DESTINATION ADDRESS ; NOTE: SRC/DEST BANK & COPY LENGTH MUST BE SET VIA SETCPY ; SYS_BNKCPY: - PUSH HL ; SAVE INCOMING HL - LD HL,(HB_CPYLEN) ; HL := COPY LEN (SAVED IN SETCPY) - EX (SP),HL ; RESTORE HL & SET (SP) TO COPY LEN - POP BC ; BC := COPY LEN - - ;; *DEBUG* START - ;PUSH AF - ;PUSH BC - ;PUSH DE - ;PUSH HL - ; - ;CALL NEWLINE - ; - ;LD A,(HB_SRCBNK) - ;CALL PRTHEXBYTE - ;CALL PC_COLON - ;PUSH BC - ;PUSH HL - ;POP BC - ;CALL PRTHEXWORD - ;POP BC - ;CALL PC_SPACE - - ;LD A,(HB_DSTBNK) - ;CALL PRTHEXBYTE - ;CALL PC_COLON - ;PUSH BC - ;PUSH DE - ;POP BC - ;CALL PRTHEXWORD - ;POP BC - ;CALL PC_SPACE - - ;CALL PRTHEXWORD - - ;POP HL - ;POP DE - ;POP BC - ;POP AF - ; *DEBUG* END - + PUSH HL ; SAVE INCOMING HL + LD HL,(HB_CPYLEN) ; HL := COPY LEN (SAVED IN SETCPY) + EX (SP),HL ; RESTORE HL & SET (SP) TO COPY LEN + POP BC ; BC := COPY LEN CALL HB_BNKCPY XOR A RET @@ -1707,7 +1576,7 @@ SYS_ALLOC: ; ALL OTHER REGISTERS PRESERVED ; SYS_FREE: - CALL PANIC ; NOT YET IMPLEMENTED + CALL PANIC ; NOT YET IMPLEMENTED OR $FF RET ; @@ -1728,7 +1597,7 @@ SYS_VER: ; ITEM TO RETURN INDICATED IN C ; SYS_GET: - LD A,C ; GET REQUESTED SUB-FUNCTION + LD A,C ; GET REQUESTED SUB-FUNCTION CP BF_SYSGET_CIOCNT JR Z,SYS_GETCIOCNT CP BF_SYSGET_DIOCNT @@ -1743,7 +1612,7 @@ SYS_GET: JR Z,SYS_GETMEMINFO CP BF_SYSGET_BNKINFO JR Z,SYS_GETBNKINFO - OR $FF ; SIGNAL ERROR + OR $FF ; SIGNAL ERROR RET ; ; GET BOOT INFORMATION @@ -1765,7 +1634,7 @@ SYS_GETBOOTINFO: ; DE: CPU SPEED IN KHZ ; SYS_GETCPUINFO: - LD H,0 ; NOT YET DEFINED + LD H,0 ; NOT YET DEFINED LD A,(CB_CPUMHZ) LD L,A LD DE,(CB_CPUKHZ) @@ -1799,35 +1668,35 @@ SYS_GETBNKINFO: ; GET SERIAL UNIT COUNT ; SYS_GETCIOCNT: - LD A,(CIO_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) - LD E,A ; PUT IT IN E - XOR A ; SIGNALS SUCCESS + LD A,(CIO_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) + LD E,A ; PUT IT IN E + XOR A ; SIGNALS SUCCESS RET ; ; GET DISK UNIT COUNT ; SYS_GETDIOCNT: - LD A,(DIO_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) - LD E,A ; PUT IT IN E - XOR A ; SIGNALS SUCCESS + LD A,(DIO_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) + LD E,A ; PUT IT IN E + XOR A ; SIGNALS SUCCESS RET ; ; GET VIDEO UNIT COUNT ; SYS_GETVDACNT: - LD A,(VDA_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) - LD E,A ; PUT IT IN E - XOR A ; SIGNALS SUCCESS + LD A,(VDA_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST) + LD E,A ; PUT IT IN E + XOR A ; SIGNALS SUCCESS RET ; ; SET SYSTEM PARAMETERS ; PARAMETER(S) TO SET INDICATED IN C ; SYS_SET: - LD A,C ; GET REQUESTED SUB-FUNCTION + LD A,C ; GET REQUESTED SUB-FUNCTION CP BF_SYSSET_BOOTINFO JR Z,SYS_SETBOOTINFO - OR $FF ; SIGNAL ERROR + OR $FF ; SIGNAL ERROR RET ; ; SET BOOT INFORMATION @@ -1847,7 +1716,7 @@ SYS_SETBOOTINFO: ; RETURN: E=BYTE VALUE ; SYS_PEEK: - CALL HBX_PEEK ; IMPLEMENTED IN PROXY + CALL HBX_PEEK ; IMPLEMENTED IN PROXY XOR A RET ; @@ -1855,7 +1724,7 @@ SYS_PEEK: ; ENTRY: D=BANK ID, HL=ADDRESS IN HBIOS BANK, E=BYTE VALUE ; SYS_POKE: - CALL HBX_POKE ; IMPLEMENTED IN PROXY + CALL HBX_POKE ; IMPLEMENTED IN PROXY XOR A RET ; @@ -1866,53 +1735,6 @@ SYS_RESET: LD (CB_HEAPTOP),HL ; RESTORE HEAP TOP XOR A RET -;; -;; GET HCB VALUE BYTE -;; C: HCB INDEX (OFFSET INTO HCB) -;; RETURN BYTE VALUE IN E -;; -;SYS_HCBGETB: -; CALL SYS_HCBPTR ; LOAD HL WITH PTR -; LD E,(HL) ; GET BYTE VALUE -; RET ; DONE -;; -;; PUT HCB VALUE BYTE -;; C: HCB INDEX (OFFSET INTO HCB) -;; E: VALUE TO WRITE -;; -;SYS_HCBPUTB: -; CALL SYS_HCBPTR ; LOAD HL WITH PTR -; LD (HL),E ; PUT BYTE VALUE -; RET -;; -;; GET HCB VALUE WORD -;; C: HCB INDEX (OFFSET INTO HCB) -;; RETURN WORD VALUE IN DE -;; -;SYS_HCBGETW: -; CALL SYS_HCBPTR ; LOAD HL WITH PTR -; LD E,(HL) ; GET BYTE VALUE -; INC HL -; LD D,(HL) ; GET BYTE VALUE -; RET ; DONE -;; -;; PUT HCB VALUE WORD -;; C: HCB INDEX (OFFSET INTO HCB) -;; DE: VALUE TO WRITE -;; -;SYS_HCBPUTW: -; CALL SYS_HCBPTR ; LOAD HL WITH PTR -; LD (HL),E ; PUT BYTE VALUE -; INC HL -; LD (HL),D ; PUT BYTE VALUE -; RET -; -;; CALCULATE REAL ADDRESS OF HCB VALUE FROM HCB OFFSET -;; -;SYS_HCBPTR: -; LD A,C ; LOAD INDEX (HCB OFFSET) -; LD HL,HCB ; GET HCB ADDRESS -; JP ADDHLA ; CALC REAL ADDRESS AND RET ; ;================================================================================================== ; GLOBAL HBIOS FUNCTIONS @@ -1936,7 +1758,7 @@ CIO_IDLE: ; EACH ENTRY WILL LOOK LIKE: ; CALL XXXX ; CALL INT HANDLER ; RET NZ ; RETURN IF HANDLED -; +; HB_IM1INT: ; IM1 DEVICE INTERRUPT HANDLER RET ; START WITH NO ENTRIES .FILL 4 * 8,$C9 ; ROOM FOR 8 ENTRIES @@ -1985,7 +1807,7 @@ HB_TIMINT1: DEC (HL) JR NZ,HB_TIMINT2 LD (HL),250 -; +; LD A,'*' CALL COUT JR HB_TIMINT2 @@ -2001,7 +1823,7 @@ HB_TIMINT2: IN0 A,(Z180_TCR) IN0 A,(Z180_TMDR0L) #ENDIF -; +; RET ; ; BAD INTERRUPT HANDLER @@ -2061,7 +1883,7 @@ HB_ALLOC: ; USE EX (SP),HL INSTEAD???? PUSH HL ; PUT IT BACK ON STACK LD HL,(HB_TMPSZ) ; RECOVER INCOMING MEM SIZE PARM -; +; ; CALC NEW HEAP TOP AND HANDLE OUT-OF-SPACE ERROR PUSH DE ; SAVE INCOMING DE LD DE,4 ; SIZE OF HEADER @@ -2365,10 +2187,10 @@ HB_CPUSPD1: ; LD B,8 ;HB_CPUSPDX: ; PUSH BC - + ; WAIT FOR AN INITIAL TICK TO ALIGN, THEN WAIT ; FOR SECOND TICK AND TO GET A FULL ONE SECOND LOOP COUNT - + CALL HB_RDSEC ; GET SECONDS LD (HB_CURSEC),A ; AND INIT CURSEC CALL HB_WAITSEC ; WAIT FOR SECONDS TICK @@ -2379,14 +2201,14 @@ HB_CPUSPD1: ; POP BC ; CALL NEWLINE ; CALL PRTHEXWORD - + ; POP BC ; DJNZ HB_CPUSPDX ; LD A,H OR L RET Z ; FAILURE, USE DEFAULT CPU SPEED - + ; ; MOVE LOOP COUNT TO HL PUSH DE @@ -2402,7 +2224,7 @@ HB_CPUSPD1: RL H SLA L RL H -; +; LD (CB_CPUKHZ),HL LD DE,1000 CALL DIV16 @@ -2410,7 +2232,7 @@ HB_CPUSPD1: LD (CB_CPUMHZ),A ; RET -; +; HB_WAITSEC: ; WAIT FOR SECONDS TICK ; RETURN SECS VALUE IN A, LOOP COUNT IN DE @@ -2450,11 +2272,11 @@ HB_WAITSEC1: ;NOP ; 6 TSTATES ;NOP ; 6 TSTATES ;NOP ; 6 TSTATES -#ENDIF -; - PUSH DE +#ENDIF +; + PUSH DE CALL HB_RDSEC ; GET SECONDS - POP DE + POP DE INC DE ; BUMP COUNTER LD HL,HB_CURSEC ; POINT TO COMP VALUE CP (HL) ; TEST FOR CHANGE @@ -2586,7 +2408,7 @@ PS_DISK: PRTS("Disk $") LD A,C ; MOVE UNIT NUM TO A CALL PRTDECB ; PRINT IT, ASSUME SINGLE DIGIT - PRTS(" $") ; PAD TO NEXT COLUMN + PRTS(" $") ; PAD TO NEXT COLUMN ; ; DEVICE COLUMN LD B,BF_DIODEVICE ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C @@ -2632,7 +2454,7 @@ PS_PRTDT1: ; ; PRINT DISK CAPACITY (UNIT IN C, ATTRIBUTE IN E) ; -PS_PRTDC: +PS_PRTDC: ; LD A,E ; ATTRIBUTE TO ACCUM BIT 7,A ; TEST FOR FLOPPY @@ -2734,7 +2556,7 @@ PS_SERIAL: PRTS("Serial $") LD A,C ; MOVE UNIT NUM TO A CALL PRTDECB ; PRINT IT, ASSUME SINGLE DIGIT - PRTS(" $") ; PAD TO NEXT COLUMN + PRTS(" $") ; PAD TO NEXT COLUMN ; ; DEVICE COLUMN LD B,BF_CIODEVICE ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C @@ -2840,10 +2662,10 @@ PS_PRTSC1: CALL PC_COMMA #IF (VDAEMU == EMUTYP_TTY) PRTS("TTY$") -#ENDIF +#ENDIF #IF (VDAEMU == EMUTYP_ANSI) PRTS("ANSI$") -#ENDIF +#ENDIF RET ; PS_PRTSC2: @@ -2861,7 +2683,7 @@ PS_VIDEO: PRTS("Video $") LD A,C ; MOVE UNIT NUM TO A CALL PRTDECB ; PRINT IT, ASSUME SINGLE DIGIT - PRTS(" $") ; PAD TO NEXT COLUMN + PRTS(" $") ; PAD TO NEXT COLUMN ; ; DEVICE COLUMN LD B,BF_VDADEV ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C @@ -2922,7 +2744,7 @@ PS_PRTDEV: LD A,E ; NUM CALL PRTDECB ; PRINT NUM, ASSUME 1 CHAR CALL PC_COLON ; PRINT COLON - LD A,12 - 2 ; 12 CHAR FIELD - 1 POS FOR UNIT NUM AND 1 POS FOR COLON + LD A,12 - 2 ; 12 CHAR FIELD - 1 POS FOR UNIT NUM AND 1 POS FOR COLON SUB C CALL PS_PAD ; PAD N SPACES (SPECIFIED IN A) RET @@ -3016,13 +2838,13 @@ PS_SDSTRREF: .DW PS_SDUART, PS_SDASCI, PS_SDTERM, .DW PS_SDPRPCON, PS_SDPPPCON, PS_SDSIO, PS_SDACIA ; -PS_SDUART .TEXT "UART$" -PS_SDASCI .TEXT "ASCI$" -PS_SDTERM .TEXT "TERM$" -PS_SDPRPCON .TEXT "PRPCON$" -PS_SDPPPCON .TEXT "PPPCON$" -PS_SDSIO .TEXT "SIO$" -PS_SDACIA .TEXT "ACIA$" +PS_SDUART .TEXT "UART$" +PS_SDASCI .TEXT "ASCI$" +PS_SDTERM .TEXT "TERM$" +PS_SDPRPCON .TEXT "PRPCON$" +PS_SDPPPCON .TEXT "PPPCON$" +PS_SDSIO .TEXT "SIO$" +PS_SDACIA .TEXT "ACIA$" ; ; SERIAL TYPE STRINGS ; @@ -3040,24 +2862,24 @@ PS_STPARMAP .DB "NONENMNS" PS_VDSTRREF: .DW PS_VDVDU, PS_VDCVDU, PS_VDNEC, PS_VDTMS, PS_VDVGA ; -PS_VDVDU .TEXT "VDU$" -PS_VDCVDU .TEXT "CVDU$" -PS_VDNEC .TEXT "NEC$" -PS_VDTMS .TEXT "TMS$" -PS_VDVGA .TEXT "VGA$" +PS_VDVDU .TEXT "VDU$" +PS_VDCVDU .TEXT "CVDU$" +PS_VDNEC .TEXT "NEC$" +PS_VDTMS .TEXT "TMS$" +PS_VDVGA .TEXT "VGA$" ; ; VIDEO TYPE STRINGS ; -PS_VTCRT .TEXT "CRT$" +PS_VTCRT .TEXT "CRT$" ; ; VIDEO CONFIG STRINGS ; ; ; -; 0 1 2 3 4 5 6 7 -; 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -PS_STRHDR .TEXT "Unit Device Type Capacity/Mode\r\n" - .TEXT "---------- ---------- ---------------- --------------------\r\n$" +; 0 1 2 3 4 5 6 7 +; 01234567890123456789012345678901234567890123456789012345678901234567890123456789 +PS_STRHDR .TEXT "Unit Device Type Capacity/Mode\r\n" + .TEXT "---------- ---------- ---------------- --------------------\r\n$" ; ;================================================================================================== ; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED) @@ -3158,33 +2980,27 @@ CST2: RET ; ;================================================================================================== +; MISCELLANEOUS UTILITY FUNCTIONS +;================================================================================================== +; +; SET HL TO IY+A, A IS TRASHED +; +LDHLIYA: + PUSH IY ; COPY INSTANCE DATA PTR + POP HL ; ... TO HL + ;JP ADDHLA ; APPLY OFFSET TO HL AND RETURN + ADD A,L ; ADD OFFSET TO LSB + LD L,A ; ... PUT BACK IN L + RET NC ; DONE IF CF NOT SET + INC H ; IF CF SET, BUMP MSB + RET ; ... AND RETURN +; +;================================================================================================== ; HBIOS GLOBAL DATA ;================================================================================================== ; IDLECOUNT .DB 0 ; -; THE HOST (HST) VALUES BELOW INDICATE THE DISK AND BLOCK CURRENTLY -; ADDRESSED FOR READ/WRITE OPERATIONS. -; THE 32-BIT BLOCK ADDRESS CAN BE TREADED AS EITHER CHS OR LBA, HIGH ORDER BIT ON SIGNIFIES LBA -; CHS: -; .DW 0 ; TRACK (0-65535) -; .DB 0 ; SECTOR (0-255) -; .DB 0 ; HEAD (0-127) -; -; LBA: -; .DW 0 ; LBA LOW WORD -; .DW 0 ; LBA HIGH WORD -; -; FULL 32 BIT LBA -HSTLBA .EQU $ ; REFERS TO START OF 32-BIT LBA -; LBA LOW WORD -OR- TRACK -HSTLBALO .EQU $ ; BLOCK ADDRESS LBA LOW WORD -HSTTRK .DW 0 ; CYLINDER (0-65535) -; LBA HIGH WORD -OR- HEAD/SECTOR -HSTLBAHI .EQU $ ; BLOCK ADDRESS LBA HIGH WORD -HSTSEC .DB 0 ; SECTOR (0-255) -HSTHEAD .DB 0 ; HEAD (0-255) -; HEAPCURB .DW 0 ; MARK HEAP ADDRESS AFTER INITIALIZATION ; HB_TICKS .FILL 4,0 ; 32 BIT TICK COUNTER @@ -3193,9 +3009,9 @@ STR_BANNER .DB "RetroBrew HBIOS v", BIOSVER, ", ", TIMESTAMP, "$" STR_PLATFORM .DB PLATFORM_NAME, "$" STR_SWITCH .DB "*** Activating CRT Console ***$" ; -HB_CURSEC .DB 0 +HB_CURSEC .DB 0 ; CURRENT SECOND (TEMP) ; -HB_BCDTMP .FILL 5,0 ; TEMPORARY BCD NUMBER STORAGE +HB_BCDTMP .FILL 5,0 ; BCD NUMBER STORAGE (TEMP) ; HB_WRKBUF .FILL 512,0 ; INTERNAL DISK BUFFER ; diff --git a/Source/HBIOS/hdsk.asm b/Source/HBIOS/hdsk.asm index 7d1311aa..e9da24f8 100644 --- a/Source/HBIOS/hdsk.asm +++ b/Source/HBIOS/hdsk.asm @@ -24,7 +24,7 @@ HDSK_LBA .EQU 2 ; OFFSET OF LBA (DWORD) ; HDSK_CFGTBL: ; DEVICE 0 - .DB 0 ; DEVICE NUMBER + .DB 0 ; DRIVER DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA ; DEVICE 1 @@ -55,15 +55,12 @@ HDSK_INIT: ; SETUP THE DISPATCH TABLE ENTRIES ; XOR A ; ZERO ACCUM - LD (HDSK_CURDEV),A ; SET CURRENT DEVICE NUM TO ZERO + LD (HDSK_CURDEV),A ; INIT CURRENT DEVICE NUM LD IY,HDSK_CFGTBL ; START OF DEV CFG TABLE HDSK_INIT0: CALL HDSK_PROBE ; HARDWARE PROBE JR NZ,HDSK_INIT1 ; SKIP DEVICE IF NOT PRESENT - LD A,(HDSK_CURDEV) ; GET CURRENT DEVICE - LD (IY+HDSK_DEV),A ; POPULATE DEVICE FIELD OF CFG ENTRY - LD B,A ; PUT IN B - LD C,DIODEV_HDSK ; DEVICE TYPE TO C + LD BC,HDSK_FNTBL ; BC := DRIVER FUNC TABLE ADDRESS PUSH IY ; CFG ENTRY POINTER POP DE ; ... TO DE CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK TABLE @@ -74,7 +71,7 @@ HDSK_INIT1: LD HL,HDSK_CURDEV ; POINT TO CURRENT DEVICE INC (HL) ; AND INCREMENT IT LD A,(IY) ; GET FIRST BYTE OF ENTRY - INC A ; TEST FOR $FF + INC A ; TEST FOR END OF TABLE ($FF) JR NZ,HDSK_INIT0 ; IF NOT, LOOP ; XOR A ; INIT SUCCEEDED @@ -98,35 +95,26 @@ HDSK_INITDEV: XOR A ; SIGNAL SUCCESS (REDUNDANT) RET ; AND DONE ; +; DRIVER FUNCTION TABLE +; +HDSK_FNTBL: + .DW HDSK_STATUS + .DW HDSK_RESET + .DW HDSK_SEEK + .DW HDSK_READ + .DW HDSK_WRITE + .DW HDSK_VERIFY + .DW HDSK_FORMAT + .DW HDSK_DEVICE + .DW HDSK_MEDIA + .DW HDSK_DEFMED + .DW HDSK_CAP + .DW HDSK_GEOM +#IF (($ - HDSK_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID HDSK FUNCTION TABLE ***\n" +#ENDIF ; ; -HDSK_DISPATCH: - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,HDSK_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,HDSK_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,HDSK_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,HDSK_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,HDSK_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,HDSK_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,HDSK_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,HDSK_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,HDSK_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,HDSK_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,HDSK_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,HDSK_GEOM ; SUB-FUNC 11: REPORT GEOMETRY ; HDSK_VERIFY: HDSK_FORMAT: @@ -276,10 +264,8 @@ HDSK_RW0: JR NZ,HDSK_RW5 ; BAIL OUT ON ERROR ; INCREMENT LBA - LD A,HDSK_LBA ; OFFSET OF LBA IN DEV CFG - PUSH IY ; COPY IT - POP HL ; ... TO HL - CALL ADDHLA ; SET HL := LBA ADDRESS + LD A,HDSK_LBA ; LBA OFFSET IN CFG ENTRY + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL INC32HL ; INCREMENT THE VALUE ; INCREMENT DMA @@ -290,7 +276,6 @@ HDSK_RW0: XOR A ; A := 0 SIGNALS SUCCESS HDSK_RW5: - POP BC ; RECOVER COUNTERS JR NZ,HDSK_RW6 ; IF ERROR, GET OUT diff --git a/Source/HBIOS/ide.asm b/Source/HBIOS/ide.asm index 1284d36f..30c8e408 100644 --- a/Source/HBIOS/ide.asm +++ b/Source/HBIOS/ide.asm @@ -11,7 +11,7 @@ ; +-----------------------------------------------------------------------+ ; | CONTROL BLOCK REGISTERS | ; +-----------------------+-------+-------+-------------------------------+ -; | REGISTER | PORT | DIR | DESCRIPTION | +; | REGISTER | PORT | DIR | DESCRIPTION | ; +-----------------------+-------+-------+-------------------------------+ ; | IDE_IO_ALTSTAT | 0x0E | R | ALTERNATE STATUS REGISTER | ; | IDE_IO_CTRL | 0x0E | W | DEVICE CONTROL REGISTER | @@ -21,7 +21,7 @@ ; +-----------------------+-------+-------+-------------------------------+ ; | COMMAND BLOCK REGISTERS | ; +-----------------------+-------+-------+-------------------------------+ -; | REGISTER | PORT | DIR | DESCRIPTION | +; | REGISTER | PORT | DIR | DESCRIPTION | ; +-----------------------+-------+-------+-------------------------------+ ; | IDE_IO_DATA | 0x00 | R/W | DATA INPUT/OUTPUT | ; | IDE_IO_ERR | 0x01 | R | ERROR REGISTER | @@ -31,7 +31,7 @@ ; | IDE_IO_CYLLO | 0x04 | R/W | CYLINDER NUM REGISTER (LSB) | ; | IDE_IO_CYLHI | 0x05 | R/W | CYLINDER NUM REGISTER (MSB) | ; | IDE_IO_DRVHD | 0x06 | R/W | DRIVE/HEAD REGISTER | -; | IDE_IO_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) | +; | IDE_IO_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) | ; | IDE_IO_LBA1* | 0x04 | R/W | LBA BYTE 1 (BITS 8-15) | ; | IDE_IO_LBA2* | 0x05 | R/W | LBA BYTE 2 (BITS 16-23) | ; | IDE_IO_LBA3* | 0x06 | R/W | LBA BYTE 3 (BITS 24-27) | @@ -42,9 +42,9 @@ ; ; === STATUS REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR | +; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; BSY: BUSY @@ -58,9 +58,9 @@ ; ; === ERROR REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF | +; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; (VALID WHEN ERR BIT IS SET IN STATUS REGISTER) ; @@ -75,9 +75,9 @@ ; ; === DRIVE/HEAD / LBA3 REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 | +; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; L: 0 = CHS ADDRESSING, 1 = LBA ADDRESSING @@ -86,9 +86,9 @@ ; ; === DEVICE CONTROL REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | X | X | X | X | 1 | SRST | ~IEN | 0 | +; | X | X | X | X | 1 | SRST | ~IEN | 0 | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; SRST: SOFTWARE RESET @@ -106,8 +106,8 @@ ; IDE2: SECONDARY MASTER ; IDE3: SECONDARY SLAVE ; -IDE_UNITCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE -IDE_IO_BASE .EQU $20 ; DEFAULT IO BASE (NOTE OVERRIDES BELOW) +IDE_DEVCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE +IDE_IO_BASE .EQU $20 ; DEFAULT IO BASE (NOTE OVERRIDES BELOW) ; #IF (IDEMODE == IDEMODE_MK4) IDE_IO_BASE .SET MK4_IDE @@ -123,46 +123,46 @@ IDE_IO_BASE .SET $E0 #IF ((IDEMODE == IDEMODE_DIO) | (IDEMODE == IDEMODE_MK4)) #IF (IDE8BIT) -IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W) +IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W) #ELSE -IDE_IO_DATALO .EQU $IDE_IO_BASE + $00 ; DATA PORT (16 BIT PIO LO BYTE) (R/W) -IDE_IO_DATAHI .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO HI BYTE) (R/W) +IDE_IO_DATALO .EQU $IDE_IO_BASE + $00 ; DATA PORT (16 BIT PIO LO BYTE) (R/W) +IDE_IO_DATAHI .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO HI BYTE) (R/W) IDE_IO_DATA .EQU IDE_IO_DATALO #ENDIF #ENDIF ; #IF (IDEMODE == IDEMODE_DIDE) -IDE_UNITCNT .SET 4 ; DIDE HAS PRIMARY AND SECONDARY INTERACES +IDE_DEVCNT .SET 4 ; DIDE HAS PRIMARY AND SECONDARY INTERACES #IF (IDE8BIT) -IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W) +IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W) #ELSE -IDE_IO_DATA .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO LO/HI BYTES) (R/W) -IDE_IO_DMA .EQU $IDE_IO_BASE + $09 ; DATA PORT (16 BIT DMA LO/HI BYTES) (R/W) +IDE_IO_DATA .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO LO/HI BYTES) (R/W) +IDE_IO_DMA .EQU $IDE_IO_BASE + $09 ; DATA PORT (16 BIT DMA LO/HI BYTES) (R/W) #ENDIF #ENDIF ; #IF ((IDEMODE == IDEMODE_RC) | (IDEMODE == IDEMODE_SMB)) -IDE_UNITCNT .SET 1 ; RC2014 COMPACT FLASH SUPPORTS ONLY 1 DEVICE +IDE_DEVCNT .SET 1 ; RC2014 COMPACT FLASH SUPPORTS ONLY 1 DEVICE IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT) (R/W) #ENDIF ; ;IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA INPUT/OUTPUT (R/W) -IDE_IO_ERR .EQU $IDE_IO_BASE + $01 ; ERROR REGISTER (R) -IDE_IO_FEAT .EQU $IDE_IO_BASE + $01 ; FEATURES REGISTER (W) -IDE_IO_COUNT .EQU $IDE_IO_BASE + $02 ; SECTOR COUNT REGISTER (R/W) -IDE_IO_SECT .EQU $IDE_IO_BASE + $03 ; SECTOR NUMBER REGISTER (R/W) -IDE_IO_CYLLO .EQU $IDE_IO_BASE + $04 ; CYLINDER NUM REGISTER (LSB) (R/W) -IDE_IO_CYLHI .EQU $IDE_IO_BASE + $05 ; CYLINDER NUM REGISTER (MSB) (R/W) -IDE_IO_DRVHD .EQU $IDE_IO_BASE + $06 ; DRIVE/HEAD REGISTER (R/W) +IDE_IO_ERR .EQU $IDE_IO_BASE + $01 ; ERROR REGISTER (R) +IDE_IO_FEAT .EQU $IDE_IO_BASE + $01 ; FEATURES REGISTER (W) +IDE_IO_COUNT .EQU $IDE_IO_BASE + $02 ; SECTOR COUNT REGISTER (R/W) +IDE_IO_SECT .EQU $IDE_IO_BASE + $03 ; SECTOR NUMBER REGISTER (R/W) +IDE_IO_CYLLO .EQU $IDE_IO_BASE + $04 ; CYLINDER NUM REGISTER (LSB) (R/W) +IDE_IO_CYLHI .EQU $IDE_IO_BASE + $05 ; CYLINDER NUM REGISTER (MSB) (R/W) +IDE_IO_DRVHD .EQU $IDE_IO_BASE + $06 ; DRIVE/HEAD REGISTER (R/W) IDE_IO_LBA0 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 0 (BITS 0-7) (R/W) IDE_IO_LBA1 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 1 (BITS 8-15) (R/W) IDE_IO_LBA2 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 2 (BITS 16-23) (R/W) IDE_IO_LBA3 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 3 (BITS 24-27) (R/W) -IDE_IO_STAT .EQU $IDE_IO_BASE + $07 ; STATUS REGISTER (R) -IDE_IO_CMD .EQU $IDE_IO_BASE + $07 ; COMMAND REGISTER (EXECUTE) (W) -IDE_IO_ALTSTAT .EQU $IDE_IO_BASE + $0E ; ALTERNATE STATUS REGISTER (R) -IDE_IO_CTRL .EQU $IDE_IO_BASE + $0E ; DEVICE CONTROL REGISTER (W) -IDE_IO_DRVADR .EQU $IDE_IO_BASE + $0F ; DRIVE ADDRESS REGISTER (R) +IDE_IO_STAT .EQU $IDE_IO_BASE + $07 ; STATUS REGISTER (R) +IDE_IO_CMD .EQU $IDE_IO_BASE + $07 ; COMMAND REGISTER (EXECUTE) (W) +IDE_IO_ALTSTAT .EQU $IDE_IO_BASE + $0E ; ALTERNATE STATUS REGISTER (R) +IDE_IO_CTRL .EQU $IDE_IO_BASE + $0E ; DEVICE CONTROL REGISTER (W) +IDE_IO_DRVADR .EQU $IDE_IO_BASE + $0F ; DRIVE ADDRESS REGISTER (R) ; ; COMMAND BYTES ; @@ -200,30 +200,73 @@ IDE_DRVSEL: IDE_DRVMASTER .DB %11100000 ; LBA, MASTER DEVICE IDE_DRVSLAVE .DB %11110000 ; LBA, SLAVE DEVICE ; -; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN IDE_UNITDATA) -; SEE IDE_UNITDATA IN DATA STORAGE BELOW +; IDE DEVICE CONFIGURATION +; +IDE_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS +; +IDE_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +IDE_STAT .EQU 1 ; LAST STATUS (BYTE) +IDE_TYPE .EQU 2 ; DEVICE TYPE (BYTE) +IDE_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE) +IDE_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +IDE_LBA .EQU 8 ; OFFSET OF LBA (DWORD) +; +IDE_CFGTBL: + ; DEVICE 0, PRIMARY MASTER + .DB 0 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#IF (IDE_DEVCNT >= 2) + ; DEVICE 1, PRIMARY SLAVE + .DB 1 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#ENDIF +#IF (IDE_DEVCNT >= 3) + ; DEVICE 2, SECONDARY MASTER + .DB 2 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#ENDIF +#IF (IDE_DEVCNT >= 4) + ; DEVICE 2, SECONDARY SLAVE + .DB 3 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#ENDIF ; -IDE_STAT .EQU 0 ; LAST STATUS (1 BYTE) -IDE_TYPE .EQU 1 ; DEVICE TYPE (1 BYTE) -IDE_CAPACITY .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES) -IDE_CFFLAG .EQU 6 ; CF FLAG (1 BYTE), NON-ZERO=CF +#IF ($ - IDE_CFGTBL) != (IDE_DEVCNT * IDE_CFGSIZ) + .ECHO "*** INVALID IDE CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER ; ; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL ; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING ; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES -; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED. +; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED. ; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY ; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO -; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255. +; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255. ; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS. ; IDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS IDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS ; -; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA -; -#DEFINE IDE_DPTR(FIELD) CALL IDE_DPTRIMP \ .DB FIELD -; ;============================================================================= ; INITIALIZATION ENTRY POINT ;============================================================================= @@ -254,10 +297,6 @@ IDE_INIT: LD A,IDE_IO_DATA ; GET IO ADDRESS CALL PRTHEXBYTE ; PRINT IT ; - ; PRINT UNIT COUNT - PRTS(" UNITS=$") ; PRINT LABEL FOR UNIT COUNT - LD A,IDE_UNITCNT ; GET UNIT COUNT - CALL PRTDECB ; PRINT IT IN DECIMAL ; CALL IDE_DETECT ; CHECK FOR HARDWARE JR Z,IDE_INIT00 ; CONTINUE IF PRESENT @@ -268,45 +307,47 @@ IDE_INIT: RET ; IDE_INIT00: + ; PRINT UNIT COUNT + PRTS(" DEVICES=$") ; PRINT LABEL FOR DEVICE COUNT + LD A,IDE_DEVCNT ; GET UNIT COUNT + CALL PRTDECB ; PRINT IT IN DECIMAL ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,IDE_UNITCNT ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX + LD B,IDE_DEVCNT ; LOOP CONTROL + LD IY,IDE_CFGTBL ; START OF CFG TABLE IDE_INIT0: - PUSH BC ; SAVE LOOP CONTROL - LD B,C ; PHYSICAL UNIT - LD C,DIODEV_IDE ; 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 IDE_INIT0 ; LOOP UNTIL DONE + PUSH BC ; SAVE LOOP CONTROL + LD BC,IDE_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD BC,IDE_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ IDE_INIT0 ; LOOP AS NEEDED ; ; INITIALIZE THE IDE INTERFACE NOW CALL IDE_RESET ; DO HARDWARE SETUP/INIT RET NZ ; ABORT IF RESET FAILS ; ; DEVICE DISPLAY LOOP - LD B,IDE_UNITCNT ; LOOP ONCE PER UNIT - LD C,0 ; C IS UNIT INDEX + LD B,IDE_DEVCNT ; LOOP ONCE PER DEVICE + LD IY,IDE_CFGTBL ; START OF CFG TABLE IDE_INIT1: - LD A,C ; UNIT NUM TO ACCUM PUSH BC ; SAVE LOOP CONTROL CALL IDE_INIT2 ; DISPLAY UNIT INFO + LD BC,IDE_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY POP BC ; RESTORE LOOP CONTROL - INC C ; INCREMENT UNIT INDEX DJNZ IDE_INIT1 ; LOOP UNTIL DONE RET ; DONE ; IDE_INIT2: - LD (IDE_UNIT),A ; SET CURRENT UNIT -; ; CHECK FOR BAD STATUS - IDE_DPTR(IDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED - LD A,(HL) - OR A - JP NZ,IDE_PRTSTAT + LD A,(IY+IDE_STAT) ; GET STATUS + OR A ; SET FLAGS + JP NZ,IDE_PRTSTAT ; EXIT VIA PRINT STATUS ; CALL IDE_PRTPREFIX ; PRINT DEVICE PREFIX ; @@ -316,18 +357,15 @@ IDE_INIT2: ; ; PRINT LBA/NOLBA CALL PC_SPACE ; FORMATTING - LD HL,HB_WRKBUF ; POINT TO BUFFER START - LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG - ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS - LD A,(HL) ; GET THE BYTE - BIT 1,A ; CHECK THE LBA BIT + BIT 1,(IY+IDE_FLAGS) ; TEST LBA FLAG LD DE,IDE_STR_NO ; POINT TO "NO" STRING CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED PRTS("LBA$") ; PRINT "LBA" REGARDLESS ; ; PRINT STORAGE CAPACITY (BLOCK COUNT) PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - IDE_DPTR(IDE_CAPACITY) ; SET HL TO ADR OF DEVICE CAPACITY + LD A,IDE_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 ; GET THE CAPACITY VALUE CALL PRTHEX32 ; PRINT HEX VALUE ; @@ -356,48 +394,30 @@ IDE_DETECT: RET ; AND RETURN ; ;============================================================================= -; FUNCTION DISPATCH ENTRY POINT +; DRIVER FUNCTION TABLE ;============================================================================= ; -IDE_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP IDE_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (IDE_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,IDE_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,IDE_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,IDE_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,IDE_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,IDE_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,IDE_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,IDE_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,IDE_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,IDE_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,IDE_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,IDE_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,IDE_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +IDE_FNTBL: + .DW IDE_STATUS + .DW IDE_RESET + .DW IDE_SEEK + .DW IDE_READ + .DW IDE_WRITE + .DW IDE_VERIFY + .DW IDE_FORMAT + .DW IDE_DEVICE + .DW IDE_MEDIA + .DW IDE_DEFMED + .DW IDE_CAP + .DW IDE_GEOM +#IF (($ - IDE_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID IDE FUNCTION TABLE ***\n" +#ENDIF ; IDE_VERIFY: IDE_FORMAT: IDE_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; NOT IMPLEMENTED ; ; ; @@ -436,12 +456,11 @@ IDE_IO1: LD HL,(IDE_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS CALL JPHL ; ... AND CALL IT JR NZ,IDE_IO2 ; IF ERROR, SKIP INCREMENT - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,IDE_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,IDE_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -461,8 +480,7 @@ IDE_IO3: ; IDE_STATUS: ; RETURN UNIT STATUS - IDE_DPTR(IDE_STAT) ; HL := ADR OF STATUS, AF TRASHED - LD A,(HL) ; GET STATUS OF SELECTED UNIT + LD A,(IY+IDE_STAT) ; GET STATUS OF SELECTED DEVICE OR A ; SET FLAGS RET ; AND RETURN ; @@ -470,14 +488,12 @@ IDE_STATUS: ; IDE_DEVICE: LD D,DIODEV_IDE ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - IDE_DPTR(IDE_CFFLAG) ; POINT TO CF FLAG - LD A,(HL) ; GET FLAG - OR A ; SET ACCUM FLAGS + LD E,(IY+IDE_DEV) ; E := PHYSICAL DEVICE NUMBER + BIT 0,(IY+IDE_FLAGS) ; TEST CF BIT IN FLAGS LD C,%00000000 ; ASSUME NON-REMOVABLE HARD DISK JR Z,IDE_DEVICE1 ; IF Z, WE ARE DONE LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH -IDE_DEVICE1: +IDE_DEVICE1: XOR A ; SIGNAL SUCCESS RET ; @@ -489,8 +505,7 @@ IDE_MEDIA: JR Z,IDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA ; ; GET CURRENT STATUS - IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+IDE_STAT) ; GET STATUS OR A ; SET FLAGS JR NZ,IDE_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET ; @@ -507,8 +522,7 @@ IDE_MEDIA1: CALL IDE_RESET ; RESET IDE INTERFACE ; IDE_MEDIA2: - IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+IDE_STAT) ; GET STATUS OR A ; SET FLAGS LD D,0 ; NO MEDIA CHANGE DETECTED LD E,MID_HD ; ASSUME WE ARE OK @@ -522,19 +536,21 @@ IDE_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 + LD (IY+IDE_LBA+0),L ; SAVE NEW LBA + LD (IY+IDE_LBA+1),H ; ... + LD (IY+IDE_LBA+2),E ; ... + LD (IY+IDE_LBA+3),D ; ... XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ; ; IDE_CAP: - IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+IDE_STAT) ; GET STATUS PUSH AF ; SAVE IT - IDE_DPTR(IDE_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT - CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL + LD A,IDE_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL LD BC,512 ; 512 BYTES PER BLOCK POP AF ; RECOVER STATUS OR A ; SET FLAGS @@ -639,7 +655,8 @@ IDE_SETADDR: ; IDE_IO_LBA3 HAS ALREADY BEEN SET ; HSTLBA2-0 --> IDE_IO_LBA2-0 LD C,IDE_IO_LBA0 + 3 ; STARTING IO PORT (NOT PRE-DEC BELOW) - LD HL,HSTLBA + 2 ; STARTING LBA BYTE ADR + LD A,IDE_LBA + 2 ; OFFSET OF 3RD BYTE OF LBA IN CFG + CALL LDHLIYA ; HL := IY + A, REG A TRASHED LD B,3 ; SEND 3 BYTES IDE_SETADDR1: ; @@ -704,7 +721,6 @@ IDE_GETBUF: CALL IDE_WAITDRQ ; WAIT FOR BUFFER READY RET NZ ; BAIL OUT IF TIMEOUT - ;LD HL,(IDE_DSKBUF) LD B,0 #IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE)) @@ -835,28 +851,28 @@ IDE_RESET: LD DE,150000/16 ; ~???MS CALL VDELAY ; - ; CLEAR OUT ALL DATA (FOR ALL UNITS) - LD HL,IDE_UDATA - LD BC,IDE_UDLEN - XOR A - CALL FILL + ;; CLEAR OUT ALL DATA (FOR ALL UNITS) + ;LD HL,IDE_UDATA + ;LD BC,IDE_UDLEN + ;XOR A + ;CALL FILL ; - LD A,(IDE_UNIT) ; GET THE CURRENT UNIT SELECTION - PUSH AF ; AND SAVE IT + ;LD A,(IDE_UNIT) ; GET THE CURRENT UNIT SELECTION + ;PUSH AF ; AND SAVE IT + PUSH IY ; SAVE CURRENT DEVICE CFG PTR ; PROBE / INITIALIZE ALL UNITS - LD B,IDE_UNITCNT ; NUMBER OF UNITS TO TRY - LD C,0 ; UNIT INDEX FOR LOOP + LD B,IDE_DEVCNT ; NUMBER OF UNITS TO TRY + LD IY,IDE_CFGTBL ; START OF CFG TABLE IDE_RESET1: - LD A,C ; UNIT NUMBER TO A - PUSH BC + PUSH BC ; SAVE LOOP CONTROL CALL IDE_INITUNIT ; PROBE/INIT UNIT - POP BC - INC C ; NEXT UNIT + LD BC,IDE_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC DJNZ IDE_RESET1 ; LOOP AS NEEDED ; - POP AF ; RECOVER ORIGINAL UNIT NUMBER - LD (IDE_UNIT),A ; AND SAVE IT + POP IY ; RECOVER DEVICE CFG PTR ; XOR A ; SIGNAL SUCCESS RET ; AND DONE @@ -864,8 +880,6 @@ IDE_RESET1: ; ; IDE_INITUNIT: - LD (IDE_UNIT),A ; SET ACTIVE UNIT - CALL IDE_SELUNIT ; SELECT UNIT RET NZ ; ABORT IF ERROR @@ -888,17 +902,18 @@ IDE_INITUNIT: ; REGISTER A IS DESTROYED ; IDE_SELUNIT: - LD A,(IDE_UNIT) ; GET UNIT - CP IDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) - JP NC,IDE_INVUNIT ; HANDLE INVALID UNIT +#IF (IDETRACE >= 3) + CALL IDE_PRTPREFIX + PRTS(" SELUNIT$") +#ENDIF ; #IF (IDEMODE == IDEMODE_DIDE) ; SELECT PRIMARY/SECONDARY INTERFACE FOR DIDE HARDWARE #ENDIF -; - ; DETERMINE AND SAVE DRIVE/HEAD VALUE FOR SELECTED UNIT - PUSH HL ; SAVE HL - LD A,(IDE_UNIT) ; GET CURRENT UNIT + PUSH HL ; SAVE HL, IT IS DESTROYED BELOW + PUSH IY + POP BC + LD A,(IY+IDE_DEV) ; GET DEVICE AND $01 ; LS BIT DETERMINES MASTER/SLAVE LD HL,IDE_DRVSEL CALL ADDHLA @@ -921,7 +936,7 @@ IDE_PROBE: OUT (IDE_IO_DRVHD),A DCALL PC_SPACE DCALL PRTHEXBYTE - + CALL DELAY ; DELAY ~16US ; LD C,IDE_IO_STAT @@ -974,8 +989,8 @@ IDE_PROBE0: ; IDE_PROBE1: ; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS - IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD (HL),IDE_TYPEATA ; SET THE DEVICE TYPE + LD A,IDE_TYPEATA ; TYPE = ATA + LD (IY+IDE_TYPE),A ; SET IT IN INSTANCE DATA XOR A ; SIGNAL SUCCESS RET ; DONE, NOTE THAT A=0 AND Z IS SET ; @@ -983,23 +998,22 @@ IDE_PROBE1: ; IDE_INITDEV: ; - IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD A,(HL) ; GET THE DEVICE TYPE + LD A,(IY+IDE_TYPE) ; GET THE DEVICE TYPE OR A ; SET FLAGS JP Z,IDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS ; ; CLEAR OUT UNIT SPECIFIC DATA, BUT PRESERVE THE EXISTING ; VALUE OF THE UNIT TYPE WHICH WAS ESTABLISHED BY THE DEVICE ; PROBES WHEN THE IDE BUS WAS RESET - PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE - PUSH HL ; SAVE UNIT TYPE FIELD POINTER - IDE_DPTR(0) ; SET HL TO START OF UNIT DATA - LD BC,IDE_UDLEN - XOR A - CALL FILL - POP HL ; RECOVER UNIT TYPE FIELD POINTER - POP AF ; RECOVER UNIT TYPE VALUE - LD (HL),A ; AND PUT IT BACK + ;PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE + ;PUSH HL ; SAVE UNIT TYPE FIELD POINTER + ;IDE_DPTR(0) ; SET HL TO START OF UNIT DATA + ;LD BC,IDE_UDLEN + ;XOR A + ;CALL FILL + ;POP HL ; RECOVER UNIT TYPE FIELD POINTER + ;POP AF ; RECOVER UNIT TYPE VALUE + ;LD (HL),A ; AND PUT IT BACK ; #IF (IDE8BIT) LD A,IDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO @@ -1022,6 +1036,9 @@ IDE_INITDEV: LD DE,HB_WRKBUF ; POINT TO BUFFER DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING ; + XOR A + LD (IY+IDE_FLAGS),0 ; CLEAR FLAGS + ; DETERMINE IF CF DEVICE LD HL,HB_WRKBUF ; FIRST WORD OF IDENTIFY DATA HAS CF FLAG LD A,$8A ; FIRST BYTE OF MARKER IS $8A @@ -1031,13 +1048,19 @@ IDE_INITDEV: LD A,$84 ; SECOND BYTE OF MARKER IS $84 CP (HL) ; COMPARE JR NZ,IDE_INITDEV1 ; IF NOT MATCH, NOT CF - IDE_DPTR(IDE_CFFLAG) ; POINT HL TO CF FLAG FIELD - LD A,$FF ; SET FLAG VALUE TO NON-ZERO (TRUE) - LD (HL),A ; SAVE IT + SET 0,(IY+IDE_FLAGS) ; SET FLAGS BIT FOR CF MEDIA ; IDE_INITDEV1: + ; DETERMINE IF LBA CAPABLE + LD A,(HB_WRKBUF+98+1) ; GET BYTE WITH LBA BIT FROM BUFFER + BIT 1,A ; CHECK THE LBA BIT + JR Z,IDE_INITDEV2 ; NOT SET, BYPASS + SET 1,(IY+IDE_FLAGS) ; SET FLAGS BIT FOR LBA +; +IDE_INITDEV2: ; GET DEVICE CAPACITY AND SAVE IT - IDE_DPTR(IDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD + LD A,IDE_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED PUSH HL ; SAVE POINTER LD HL,HB_WRKBUF ; POINT TO BUFFER START LD A,120 ; OFFSET OF SECTOR COUNT @@ -1047,18 +1070,16 @@ IDE_INITDEV1: CALL ST32 ; SAVE CAPACITY ; ; RESET CARD STATUS TO 0 (OK) - IDE_DPTR(IDE_STAT) ; HL := ADR OF STATUS, AF TRASHED XOR A ; A := 0 (STATUS = OK) - LD (HL),A ; SAVE IT + LD (IY+IDE_STAT),A ; SAVE IT ; RET ; RETURN, A=0, Z SET ; ; ; IDE_CHKDEVICE: - IDE_DPTR(IDE_STAT) - LD A,(HL) - OR A + LD A,(IY+IDE_STAT) ; GET STATUS + OR A ; SET FLAGS RET Z ; RETURN IF ALL IS WELL ; ; ATTEMPT TO REINITIALIZE HERE??? @@ -1098,7 +1119,7 @@ IDE_WAITDRQ2: AND %10001000 ; TO FILL (OR READY TO FILL) XOR %00001000 RET Z - DEC DE + DEC DE LD A,D OR E JR NZ,IDE_WAITDRQ2 @@ -1159,12 +1180,8 @@ IDE_BSYTO: JR IDE_ERR ; IDE_ERR: - PUSH HL ; IS THIS NEEDED? - PUSH AF ; SAVE INCOMING STATUS - IDE_DPTR(IDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED - POP AF ; RESTORE INCOMING STATUS - LD (HL),A ; UPDATE STATUS - POP HL ; IS THIS NEEDED? + LD (IY+IDE_STAT),A ; SAVE NEW STATUS +; IDE_ERR2: #IF (IDETRACE >= 2) CALL IDE_PRTSTAT @@ -1252,7 +1269,7 @@ IDE_PRTPREFIX: PUSH AF CALL NEWLINE PRTS("IDE$") - LD A,(IDE_UNIT) + LD A,(IY+IDE_DEV) ; GET CURRENT DEVICE NUM ADD A,'0' CALL COUT CALL PC_COLON @@ -1268,14 +1285,14 @@ IDE_DSKY: LD (HL),A ; SAVE IN BUFFER INC HL ; INCREMENT BUFFER POINTER IN A,(IDE_IO_CYLHI) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER IN A,(IDE_IO_CYLLO) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER IN A,(IDE_IO_SECT) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - CALL DSKY_HEXOUT ; SEND IT TO DSKY + LD (HL),A ; SAVE IN BUFFER + CALL DSKY_HEXOUT ; SEND IT TO DSKY RET #ENDIF ; @@ -1299,40 +1316,11 @@ IDE_STR_NO .TEXT "NO$" ; DATA STORAGE ;============================================================================= ; -IDE_TIMEOUT .DB IDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC -IDE_TOSCALER .DW CPUMHZ * 961 ; WAIT FUNCS SCALER FOR CPU SPEED +IDE_TIMEOUT .DB IDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC +IDE_TOSCALER .DW CPUMHZ * 961 ; WAIT FUNCS SCALER FOR CPU SPEED ; -IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS -IDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS -IDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK -; -IDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO -IDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER -; -; UNIT SPECIFIC DATA STORAGE -; -IDE_UDATA .FILL IDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES -IDE_DLEN .EQU $ - IDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS -IDE_UDLEN .EQU IDE_DLEN / IDE_UNITCNT ; LENGTH OF PER UNIT DATA -; -;============================================================================= -; HELPER ROUTINES -;============================================================================= +IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS +IDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS +IDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK ; -; IMPLEMENTATION FOR MACRO IDE_DPTR -; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA -; HL := ADR OF IDE_UNITDATA[(IDE_UNIT)][(SP)] -; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET -; AF IS TRASHED -; -IDE_DPTRIMP: - LD HL,IDE_UDATA ; POINT TO START OF UNIT DATA ARRAY - LD A,(IDE_UNIT) ; GET CURRENT UNIT NUM - RLCA ; MULTIPLY BY - RLCA ; ... SIZE OF PER UNIT DATA - RLCA ; ... (8 BYTES) - EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS - ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM - INC HL ; BUMP HL TO NEXT REAL INSTRUCTION - EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA - JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN +IDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER diff --git a/Source/HBIOS/ide.asm.new b/Source/HBIOS/ide.asm.new deleted file mode 100644 index 8d6b443a..00000000 --- a/Source/HBIOS/ide.asm.new +++ /dev/null @@ -1,1269 +0,0 @@ -; -;============================================================================= -; IDE DISK DRIVER -;============================================================================= -; -; TODO: -; - IMPLEMENT IDE_INITDEVICE -; - HANDLE SECONDARY INTERFACE ON DIDE -; - IMPLEMENT INTELLIGENT RESET, CHECK IF DEVICE IS ACTUALLY BROKEN BEFORE RESET -; -; +-----------------------------------------------------------------------+ -; | CONTROL BLOCK REGISTERS | -; +-----------------------+-------+-------+-------------------------------+ -; | REGISTER | PORT | DIR | DESCRIPTION | -; +-----------------------+-------+-------+-------------------------------+ -; | IDE_IO_ALTSTAT | 0x0E | R | ALTERNATE STATUS REGISTER | -; | IDE_IO_CTRL | 0x0E | W | DEVICE CONTROL REGISTER | -; | IDE_IO_DRVADR | 0x0F | R | DRIVE ADDRESS REGISTER | -; +-----------------------+-------+-------+-------------------------------+ -; -; +-----------------------+-------+-------+-------------------------------+ -; | COMMAND BLOCK REGISTERS | -; +-----------------------+-------+-------+-------------------------------+ -; | REGISTER | PORT | DIR | DESCRIPTION | -; +-----------------------+-------+-------+-------------------------------+ -; | IDE_IO_DATA | 0x00 | R/W | DATA INPUT/OUTPUT | -; | IDE_IO_ERR | 0x01 | R | ERROR REGISTER | -; | IDE_IO_FEAT | 0x01 | W | FEATURES REGISTER | -; | IDE_IO_COUNT | 0x02 | R/W | SECTOR COUNT REGISTER | -; | IDE_IO_SECT | 0x03 | R/W | SECTOR NUMBER REGISTER | -; | IDE_IO_CYLLO | 0x04 | R/W | CYLINDER NUM REGISTER (LSB) | -; | IDE_IO_CYLHI | 0x05 | R/W | CYLINDER NUM REGISTER (MSB) | -; | IDE_IO_DRVHD | 0x06 | R/W | DRIVE/HEAD REGISTER | -; | IDE_IO_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) | -; | IDE_IO_LBA1* | 0x04 | R/W | LBA BYTE 1 (BITS 8-15) | -; | IDE_IO_LBA2* | 0x05 | R/W | LBA BYTE 2 (BITS 16-23) | -; | IDE_IO_LBA3* | 0x06 | R/W | LBA BYTE 3 (BITS 24-27) | -; | IDE_IO_STAT | 0x07 | R | STATUS REGISTER | -; | IDE_IO_CMD | 0x07 | W | COMMAND REGISTER (EXECUTE) | -; +-----------------------+-------+-------+-------------------------------+ -; * LBA0-4 ARE ALTERNATE DEFINITIONS OF SECT, CYL, AND DRVHD PORTS -; -; === STATUS REGISTER === -; -; 7 6 5 4 3 2 1 0 -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR | -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; -; BSY: BUSY -; DRDY: DRIVE READY -; DWF: DRIVE WRITE FAULT -; DSC: DRIVE SEEK COMPLETE -; DRQ: DATA REQUEST -; CORR: CORRECTED DATA -; IDX: INDEX -; ERR: ERROR -; -; === ERROR REGISTER === -; -; 7 6 5 4 3 2 1 0 -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF | -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; (VALID WHEN ERR BIT IS SET IN STATUS REGISTER) -; -; BBK: BAD BLOCK DETECTED -; UNC: UNCORRECTABLE DATA ERROR -; MC: MEDIA CHANGED -; IDNF: ID NOT FOUND -; MCR: MEDIA CHANGE REQUESTED -; ABRT: ABORTED COMMAND -; TK0NF: TRACK 0 NOT FOUND -; AMNF: ADDRESS MARK NOT FOUND -; -; === DRIVE/HEAD / LBA3 REGISTER === -; -; 7 6 5 4 3 2 1 0 -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 | -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; -; L: 0 = CHS ADDRESSING, 1 = LBA ADDRESSING -; DRV: 0 = DRIVE 0 (PRIMARY) SELECTED, 1 = DRIVE 1 (SLAVE) SELECTED -; HS: CHS = HEAD ADDRESS (0-15), LBA = BITS 24-27 OF LBA -; -; === DEVICE CONTROL REGISTER === -; -; 7 6 5 4 3 2 1 0 -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | X | X | X | X | 1 | SRST | ~IEN | 0 | -; +-------+-------+-------+-------+-------+-------+-------+-------+ -; -; SRST: SOFTWARE RESET -; ~IEN: INTERRUPT ENABLE -; -#IF (IDETRACE >= 3) -#DEFINE DCALL CALL -#ELSE -#DEFINE DCALL \; -#ENDIF -; -; UNIT MAPPING IS AS FOLLOWS: -; IDE0: PRIMARY MASTER -; IDE1: PRIMARY SLAVE -; IDE2: SECONDARY MASTER -; IDE3: SECONDARY SLAVE -; -IDE_UNITCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE -; -#IF (IDEMODE == IDEMODE_MK4) -IDE_IO_BASE .EQU MK4_IDE -#ELSE -IDE_IO_BASE .EQU $20 -#ENDIF - -#IF ((IDEMODE == IDEMODE_DIO) | (IDEMODE == IDEMODE_MK4)) -#IF (IDE8BIT) -IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W) -#ELSE -IDE_IO_DATALO .EQU $IDE_IO_BASE + $00 ; DATA PORT (16 BIT PIO LO BYTE) (R/W) -IDE_IO_DATAHI .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO HI BYTE) (R/W) -IDE_IO_DATA .EQU IDE_IO_DATALO -#ENDIF -#ENDIF -; -#IF (IDEMODE == IDEMODE_DIDE) -IDE_UNITCNT .SET 4 ; DIDE HAS PRIMARY AND SECONDARY INTERACES -#IF (IDE8BIT) -IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W) -#ELSE -IDE_IO_DATA .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO LO/HI BYTES) (R/W) -IDE_IO_DMA .EQU $IDE_IO_BASE + $09 ; DATA PORT (16 BIT DMA LO/HI BYTES) (R/W) -#ENDIF -#ENDIF -; -;IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA INPUT/OUTPUT (R/W) -IDE_IO_ERR .EQU $IDE_IO_BASE + $01 ; ERROR REGISTER (R) -IDE_IO_FEAT .EQU $IDE_IO_BASE + $01 ; FEATURES REGISTER (W) -IDE_IO_COUNT .EQU $IDE_IO_BASE + $02 ; SECTOR COUNT REGISTER (R/W) -IDE_IO_SECT .EQU $IDE_IO_BASE + $03 ; SECTOR NUMBER REGISTER (R/W) -IDE_IO_CYLLO .EQU $IDE_IO_BASE + $04 ; CYLINDER NUM REGISTER (LSB) (R/W) -IDE_IO_CYLHI .EQU $IDE_IO_BASE + $05 ; CYLINDER NUM REGISTER (MSB) (R/W) -IDE_IO_DRVHD .EQU $IDE_IO_BASE + $06 ; DRIVE/HEAD REGISTER (R/W) -IDE_IO_LBA0 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 0 (BITS 0-7) (R/W) -IDE_IO_LBA1 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 1 (BITS 8-15) (R/W) -IDE_IO_LBA2 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 2 (BITS 16-23) (R/W) -IDE_IO_LBA3 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 3 (BITS 24-27) (R/W) -IDE_IO_STAT .EQU $IDE_IO_BASE + $07 ; STATUS REGISTER (R) -IDE_IO_CMD .EQU $IDE_IO_BASE + $07 ; COMMAND REGISTER (EXECUTE) (W) -IDE_IO_ALTSTAT .EQU $IDE_IO_BASE + $0E ; ALTERNATE STATUS REGISTER (R) -IDE_IO_CTRL .EQU $IDE_IO_BASE + $0E ; DEVICE CONTROL REGISTER (W) -IDE_IO_DRVADR .EQU $IDE_IO_BASE + $0F ; DRIVE ADDRESS REGISTER (R) -; -; COMMAND BYTES -; -IDE_CIDE_RECAL .EQU $10 -IDE_CIDE_READ .EQU $20 -IDE_CIDE_WRITE .EQU $30 -IDE_CIDE_IDDEV .EQU $EC -IDE_CIDE_SETFEAT .EQU $EF -; -; FEATURE BYTES -; -IDE_FEAT_ENABLE8BIT .EQU $01 -IDE_FEAT_DISABLE8BIT .EQU $81 -; -; IDE DEVICE TYPES -; -IDE_TYPEUNK .EQU 0 -IDE_TYPEATA .EQU 1 -IDE_TYPEATAPI .EQU 2 -; -; IDE DEVICE STATUS -; -IDE_STOK .EQU 0 -IDE_STINVUNIT .EQU -1 -IDE_STNOMEDIA .EQU -2 -IDE_STCMDERR .EQU -3 -IDE_STIOERR .EQU -4 -IDE_STRDYTO .EQU -5 -IDE_STDRQTO .EQU -6 -IDE_STBSYTO .EQU -7 -; -; DRIVE SELECTION BYTES (FOR USE IN DRIVE/HEAD REGISTER) -; -IDE_DRVSEL: -IDE_DRVMASTER .DB %11100000 ; LBA, MASTER DEVICE -IDE_DRVSLAVE .DB %11110000 ; LBA, SLAVE DEVICE -;; -;; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN IDE_UNITDATA) -;; SEE IDE_UNITDATA IN DATA STORAGE BELOW -;; -;IDE_STAT .EQU 0 ; LAST STATUS (1 BYTE) -;IDE_TYPE .EQU 1 ; DEVICE TYPE (1 BYTE) -; - .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES) -;IDE_CFFLAG .EQU 6 ; CF FLAG (1 BYTE), NON-ZERO=CF -; -; PER UNIT INSTANCE DATA OFFSETS -; -IDE_IDDEV .EQU 0 ; DEVICE UNIT NUMBER -IDE_IDBASE .EQU 1 ; I/O BASE -IDE_IDMODE .EQU 2 ; MODE FLAGS - ; BIT 0: 8BIT DATA I/O -XXXXXXXXXX -IDE_IDSTAT .EQU 0 ; LAST STATUS (1 BYTE) -IDE_IDTYPE .EQU 1 ; DEVICE TYPE (1 BYTE), ATA OR ATAPI -IDE_IDCAP .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES) -IDE_IDCF .EQU 6 ; COMPACT FLASH FLAG (1 BYTE), NON-ZERO=CF -; -; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL -; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING -; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES -; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED. -; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY -; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO -; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255. -; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS. -; -IDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS -IDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS -; -; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA -; -#DEFINE IDE_DPTR(FIELD) CALL IDE_DPTRIMP \ .DB FIELD -; -;============================================================================= -; INITIALIZATION ENTRY POINT -;============================================================================= -; -IDE_INIT: - CALL NEWLINE ; FORMATTING - PRTS("IDE:$") - CALL IDE_DETECT ; CHECK FOR HARDWARE - JR Z,IDE_INIT00 ; CONTINUE IF PRESENT -; - ; HARDWARE NOT PRESENT - PRTS(" NOT PRESENT$") - OR $FF ; SIGNAL FAILURE - RET -; -IDE_INIT00: -; -; SETUP THE DISPATCH TABLE ENTRIES -; - LD B,IDE_UNITCNT ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX -IDE_INIT0: - PUSH BC ; SAVE LOOP CONTROL - LD B,C ; PHYSICAL UNIT - LD C,DIODEV_IDE ; 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 IDE_INIT0 ; LOOP UNTIL DONE -; - ; COMPUTE CPU SPEED COMPENSATED TIMEOUT SCALER - ; AT 1MHZ, THE SCALER IS 961 (50000US / 52TS = 961) - ; SCALER IS THEREFORE 961 * CPU SPEED IN MHZ - LD DE,961 ; LOAD SCALER FOR 1MHZ - LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ - CALL MULT8X16 ; HL := DE * A - LD (IDE_TOSCALER),HL ; SAVE IT -; -#IF (IDEMODE == IDEMODE_DIO) - PRTS(" MODE=DIO$") -#ENDIF -#IF (IDEMODE == IDEMODE_DIDE) - PRTS(" MODE=DIDE$") -#ENDIF -#IF (IDEMODE == IDEMODE_MK4) - PRTS(" MODE=MK4$") -#ENDIF - ; PRINT IDE INTERFACE PORT ADDRESS - PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS - LD A,IDE_IO_DATA ; GET IO ADDRESS - CALL PRTHEXBYTE ; PRINT IT -; - ; PRINT UNIT COUNT - PRTS(" UNITS=$") ; PRINT LABEL FOR UNIT COUNT - LD A,IDE_UNITCNT ; GET UNIT COUNT - CALL PRTDECB ; PRINT IT IN DECIMAL -; - ; INITIALIZE THE IDE INTERFACE NOW - CALL IDE_RESET ; DO HARDWARE SETUP/INIT - RET NZ ; ABORT IF RESET FAILS -; - ; DEVICE DISPLAY LOOP - LD B,IDE_UNITCNT ; LOOP ONCE PER UNIT - LD C,0 ; C IS UNIT INDEX -IDE_INIT1: - LD A,C ; UNIT NUM TO ACCUM - PUSH BC ; SAVE LOOP CONTROL - CALL IDE_INIT2 ; DISPLAY UNIT INFO - POP BC ; RESTORE LOOP CONTROL - INC C ; INCREMENT UNIT INDEX - DJNZ IDE_INIT1 ; LOOP UNTIL DONE - RET ; DONE -; -IDE_INIT2: - LD (IDE_UNIT),A ; SET CURRENT UNIT -; - ; CHECK FOR BAD STATUS - IDE_DPTR(IDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED - LD A,(HL) - OR A - JP NZ,IDE_PRTSTAT -; - CALL IDE_PRTPREFIX ; PRINT DEVICE PREFIX -; -#IF (IDE8BIT) - PRTS(" 8BIT$") -#ENDIF -; - ; PRINT LBA/NOLBA - CALL PC_SPACE ; FORMATTING - LD HL,HB_WRKBUF ; POINT TO BUFFER START - LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG - ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS - LD A,(HL) ; GET THE BYTE - BIT 1,A ; CHECK THE LBA BIT - LD DE,IDE_STR_NO ; POINT TO "NO" STRING - CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED - PRTS("LBA$") ; PRINT "LBA" REGARDLESS -; - ; PRINT STORAGE CAPACITY (BLOCK COUNT) - PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - IDE_DPTR(IDE_CAPACITY) ; SET HL TO ADR OF DEVICE CAPACITY - CALL LD32 ; GET THE CAPACITY VALUE - CALL PRTHEX32 ; PRINT HEX VALUE -; - ; PRINT STORAGE SIZE IN MB - PRTS(" SIZE=$") ; PRINT FIELD LABEL - LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB - CALL SRL32 ; RIGHT SHIFT - CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED) - PRTS("MB$") ; PRINT SUFFIX -; - XOR A ; SIGNAL SUCCESS - RET ; RETURN WITH A=0, AND Z SET -; -;---------------------------------------------------------------------- -; PROBE FOR IDE HARDWARE -;---------------------------------------------------------------------- -; -; ON RETURN, ZF SET INDICATES HARDWARE FOUND -; -IDE_DETECT: -; -#IF (IDEMODE == IDEMODE_DIDE) -#ENDIF -; - XOR A ; SIGNAL SUCCESS - RET ; AND RETURN -; -;============================================================================= -; FUNCTION DISPATCH ENTRY POINT -;============================================================================= -; -IDE_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP IDE_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (IDE_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,IDE_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,IDE_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,IDE_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,IDE_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,IDE_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,IDE_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,IDE_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,IDE_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,IDE_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,IDE_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,IDE_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,IDE_GEOM ; SUB-FUNC 11: REPORT GEOMETRY -; -IDE_VERIFY: -IDE_FORMAT: -IDE_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION -; -; -; -IDE_READ: - LD (IDE_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS -#IF (IDETRACE == 1) - LD HL,IDE_PRTERR ; SET UP IDE_PRTERR - PUSH HL ; ... TO FILTER ALL EXITS -#ENDIF - CALL IDE_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT - JP IDE_RDSEC -; -; -; -IDE_WRITE: - LD (IDE_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS -#IF (IDETRACE == 1) - LD HL,IDE_PRTERR ; SET UP IDE_PRTERR - PUSH HL ; ... TO FILTER ALL EXITS -#ENDIF - CALL IDE_SELUNIT ; HARDWARE SELECTION OF TARGET UNIT - JP IDE_WRSEC -; -; -; -IDE_STATUS: - ; RETURN UNIT STATUS - IDE_DPTR(IDE_STAT) ; HL := ADR OF STATUS, AF TRASHED - LD A,(HL) ; GET STATUS OF SELECTED UNIT - OR A ; SET FLAGS - RET ; AND RETURN -; -; -; -IDE_DEVICE: - LD D,DIODEV_IDE ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - IDE_DPTR(IDE_CFFLAG) ; POINT TO CF FLAG - LD A,(HL) ; GET FLAG - OR A ; SET ACCUM FLAGS - LD C,%00000000 ; ASSUME NON-REMOVABLE HARD DISK - JR Z,IDE_DEVICE1 ; IF Z, WE ARE DONE - LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH -IDE_DEVICE1: - XOR A ; SIGNAL SUCCESS - RET -; -; IDE_GETMED -; -IDE_MEDIA: - LD A,E ; GET FLAGS - OR A ; SET FLAGS - JR Z,IDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA -; - ; GET CURRENT STATUS - IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS - OR A ; SET FLAGS - JR NZ,IDE_MEDIA1 ; ERROR ACTIVE, TO RIGHT TO RESET -; - ; USE IDENTIFY COMMAND TO CHECK DEVICE - LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT - LD (HL),IDE_TOFAST ; USE FAST TIMEOUT DURING IDENTIFY COMMAND - CALL IDE_IDENTIFY ; EXECUTE IDENTIFY COMMAND - LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT - LD (HL),IDE_TONORM ; BACK TO NORMAL TIMEOUT - JR Z,IDE_MEDIA2 ; IF SUCCESS, BYPASS RESET -; -IDE_MEDIA1: - CALL IDE_RESET ; RESET IDE INTERFACE -; -IDE_MEDIA2: - IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS - OR A ; SET FLAGS - LD D,0 ; NO MEDIA CHANGE DETECTED - LD E,MID_HD ; ASSUME WE ARE OK - RET Z ; RETURN IF GOOD INIT - LD E,MID_NONE ; SIGNAL NO MEDIA - RET ; AND RETURN -; -; -; -IDE_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 -; -; -; -IDE_CAP: - IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS - PUSH AF ; SAVE IT - IDE_DPTR(IDE_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT - CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL - LD BC,512 ; 512 BYTES PER BLOCK - POP AF ; RECOVER STATUS - OR A ; SET FLAGS - RET -; -; -; -IDE_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 IDE_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 IDE_CAP STATUS -; -;============================================================================= -; FUNCTION SUPPORT ROUTINES -;============================================================================= -; -IDE_SETFEAT: - PUSH AF -#IF (IDETRACE >= 3) - CALL IDE_PRTPREFIX - PRTS(" SETFEAT$") -#ENDIF - LD A,(IDE_DRVHD) - OUT (IDE_IO_DRVHD),A - DCALL PC_SPACE - DCALL PRTHEXBYTE - POP AF - OUT (IDE_IO_FEAT),A ; SET THE FEATURE VALUE - DCALL PC_SPACE - DCALL PRTHEXBYTE - LD A,IDE_CIDE_SETFEAT ; CMD = SETFEAT - LD (IDE_CMD),A ; SAVE IT - JP IDE_RUNCMD ; RUN COMMAND AND EXIT -; -; -; -IDE_IDENTIFY: -#IF (IDETRACE >= 3) - CALL IDE_PRTPREFIX - PRTS(" IDDEV$") -#ENDIF - LD A,(IDE_DRVHD) - OUT (IDE_IO_DRVHD),A - DCALL PC_SPACE - DCALL PRTHEXBYTE - LD A,IDE_CIDE_IDDEV - LD (IDE_CMD),A - CALL IDE_RUNCMD - RET NZ - LD HL,HB_WRKBUF - JP IDE_GETBUF ; EXIT THRU BUFRD -; -; -; -IDE_RDSEC: - CALL IDE_CHKDEVICE - RET NZ -; -#IF (IDETRACE >= 3) - CALL IDE_PRTPREFIX - PRTS(" READ$") -#ENDIF - LD A,(IDE_DRVHD) - OUT (IDE_IO_DRVHD),A - DCALL PC_SPACE - DCALL PRTHEXBYTE - CALL IDE_SETADDR ; SETUP CYL, TRK, HEAD - LD A,IDE_CIDE_READ - LD (IDE_CMD),A - CALL IDE_RUNCMD - RET NZ - LD HL,(IDE_DSKBUF) - JP IDE_GETBUF -; -; -; -IDE_WRSEC: - CALL IDE_CHKDEVICE - RET NZ -; -#IF (IDETRACE >= 3) - CALL IDE_PRTPREFIX - PRTS(" WRITE$") -#ENDIF - LD A,(IDE_DRVHD) - OUT (IDE_IO_DRVHD),A - DCALL PC_SPACE - DCALL PRTHEXBYTE - CALL IDE_SETADDR ; SETUP CYL, TRK, HEAD - LD A,IDE_CIDE_WRITE - LD (IDE_CMD),A - CALL IDE_RUNCMD - RET NZ - LD HL,(IDE_DSKBUF) - JP IDE_PUTBUF -; -; -; -IDE_SETADDR: - ; SEND 3 LOWEST BYTES OF LBA IN REVERSE ORDER - ; IDE_IO_LBA3 HAS ALREADY BEEN SET - ; HSTLBA2-0 --> IDE_IO_LBA2-0 - LD C,IDE_IO_LBA0 + 3 ; STARTING IO PORT (NOT PRE-DEC BELOW) - LD HL,HSTLBA + 2 ; STARTING LBA BYTE ADR - LD B,3 ; SEND 3 BYTES -IDE_SETADDR1: -; -#IF (IDETRACE >= 3) - LD A,(HL) - CALL PC_SPACE - CALL PRTHEXBYTE -#ENDIF -; - DEC C ; NEXT PORT - OUTD ; SEND NEXT BYTE - JR NZ,IDE_SETADDR1 ; LOOP TILL DONE -; - ; SEND COUNT OF BLOCKS TO TRANSFER - ; 1 --> IDE_IO_COUNT - LD A,1 ; COUNT VALUE IS 1 BLOCK -; -#IF (IDETRACE >= 3) - DCALL PC_SPACE - DCALL PRTHEXBYTE -#ENDIF -; - DEC C ; PORT := IDE_IO_COUNT - OUT (C),A ; SEND IT -; -#IF (DSKYENABLE) - CALL IDE_DSKY -#ENDIF -; - RET -; -;============================================================================= -; COMMAND PROCESSING -;============================================================================= -; -IDE_RUNCMD: - CALL IDE_WAITRDY ; WAIT FOR DRIVE READY - RET NZ ; BAIL OUT ON TIMEOUT -; - LD A,(IDE_CMD) ; GET THE COMMAND - DCALL PC_SPACE - DCALL PRTHEXBYTE - OUT (IDE_IO_CMD),A ; SEND IT (STARTS EXECUTION) -#IF (IDETRACE >= 3) - PRTS(" -->$") -#ENDIF -; - CALL IDE_WAITBSY ; WAIT FOR DRIVE READY (COMMAND DONE) - RET NZ ; BAIL OUT ON TIMEOUT -; - CALL IDE_GETRES - JP NZ,IDE_CMDERR - RET -; -; -; -IDE_GETBUF: -#IF (IDETRACE >= 3) - PRTS(" GETBUF$") -#ENDIF - - CALL IDE_WAITDRQ ; WAIT FOR BUFFER READY - RET NZ ; BAIL OUT IF TIMEOUT - - ;LD HL,(IDE_DSKBUF) - LD B,0 - -#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE)) - LD C,IDE_IO_DATA - INIR - INIR -;X1: -; NOP -; INI -; JR NZ,X1 -;X2: -; NOP -; INI -; JR NZ,X2 -#ELSE - LD C,IDE_IO_DATAHI -IDE_GETBUF1: - IN A,(IDE_IO_DATALO) ; READ THE LO BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; INC BUFFER POINTER - INI ; READ AND SAVE HI BYTE, INC HL, DEC B - JP NZ,IDE_GETBUF1 ; LOOP AS NEEDED -#ENDIF - CALL IDE_WAITRDY ; PROBLEMS IF THIS IS REMOVED! - CALL IDE_GETRES - JP NZ,IDE_IOERR - RET -; -; -; -IDE_PUTBUF: -#IF (IDETRACE >= 3) - PRTS(" GETBUF$") -#ENDIF - - CALL IDE_WAITDRQ ; WAIT FOR BUFFER READY - RET NZ ; BAIL OUT IF TIMEOUT -; - ;LD HL,(IDE_DSKBUF) - LD B,0 - -#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE)) - LD C,IDE_IO_DATA - OTIR - OTIR -#ELSE - LD C,IDE_IO_DATAHI -IDE_PUTBUF1: - LD A,(HL) ; GET THE LO BYTE AND KEEP IT IN A FOR LATER - INC HL ; BUMP TO NEXT BYTE IN BUFFER - OUTI ; WRITE HI BYTE, INC HL, DEC B - OUT (IDE_IO_DATALO),A ; NOW WRITE THE SAVED LO BYTE TO LO BYTE - JP NZ,IDE_PUTBUF1 ; LOOP AS NEEDED -#ENDIF - CALL IDE_WAITRDY ; PROBLEMS IF THIS IS REMOVED! - CALL IDE_GETRES - JP NZ,IDE_IOERR - RET -; -; -; -IDE_GETRES: - IN A,(IDE_IO_STAT) ; GET STATUS - DCALL PC_SPACE - DCALL PRTHEXBYTE - AND %00000001 ; ERROR BIT SET? - RET Z ; NOPE, RETURN WITH ZF -; - IN A,(IDE_IO_ERR) ; READ ERROR REGISTER - DCALL PC_SPACE - DCALL PRTHEXBYTE - OR $FF ; FORCE NZ TO SIGNAL ERROR - RET ; RETURN -; -;============================================================================= -; HARDWARE INTERFACE ROUTINES -;============================================================================= -; -; RESET ALL DEVICES ON BUS -; -IDE_RESET: -; -#IF (PLATFORM == PLT_MK4) - ; USE HARDWARE RESET LINE - LD A,$80 ; HIGH BIT OF XAR IS IDE RESET - OUT (MK4_XAR),A - LD DE,2 ; DELAY 32US (SPEC IS >= 25US) - CALL VDELAY - XOR A ; CLEAR RESET BIT - OUT (MK4_XAR),A -#ELSE - ; INITIATE SOFT RESET - LD A,%00001110 ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES - OUT (IDE_IO_CTRL),A -#ENDIF -; - LD DE,2 ; DELAY 32US (SPEC IS >= 25US) - CALL VDELAY -; - ; CONFIGURE OPERATION AND END SOFT RESET - LD A,%00001010 ; NO INTERRUPTS, DEASSERT RESET - OUT (IDE_IO_CTRL),A ; PUSH TO REGISTER -; -; SPEC ALLOWS UP TO 450MS FOR DEVICES TO ASSERT THEIR PRESENCE -; VIA -DASP. I ENCOUNTER PROBLEMS LATER ON IF I DON'T WAIT HERE -; FOR THAT TO OCCUR. THUS FAR, IT APPEARS THAT 150MS IS SUFFICIENT -; FOR ANY DEVICE ENCOUNTERED. MAY NEED TO EXTEND BACK TO 500MS -; IF A SLOWER DEVICE IS ENCOUNTERED. -; - ;LD DE,500000/16 ; ~500MS - LD DE,150000/16 ; ~???MS - CALL VDELAY -; - ; CLEAR OUT ALL DATA (FOR ALL UNITS) - LD HL,IDE_UDATA - LD BC,IDE_UDLEN - XOR A - CALL FILL -; - LD A,(IDE_UNIT) ; GET THE CURRENT UNIT SELECTION - PUSH AF ; AND SAVE IT - - ; PROBE / INITIALIZE ALL UNITS - LD B,IDE_UNITCNT ; NUMBER OF UNITS TO TRY - LD C,0 ; UNIT INDEX FOR LOOP -IDE_RESET1: - LD A,C ; UNIT NUMBER TO A - PUSH BC - CALL IDE_INITUNIT ; PROBE/INIT UNIT - POP BC - INC C ; NEXT UNIT - DJNZ IDE_RESET1 ; LOOP AS NEEDED -; - POP AF ; RECOVER ORIGINAL UNIT NUMBER - LD (IDE_UNIT),A ; AND SAVE IT -; - XOR A ; SIGNAL SUCCESS - RET ; AND DONE -; -; -; -IDE_INITUNIT: - LD (IDE_UNIT),A ; SET ACTIVE UNIT - - CALL IDE_SELUNIT ; SELECT UNIT - RET NZ ; ABORT IF ERROR - - LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT - LD (HL),IDE_TOFAST ; USE FAST TIMEOUT DURING INIT - - CALL IDE_PROBE ; DO PROBE - CALL Z,IDE_INITDEV ; IF FOUND, ATTEMPT TO INIT DEVICE - - LD HL,IDE_TIMEOUT ; POINT TO TIMEOUT - LD (HL),IDE_TONORM ; BACK TO NORMAL TIMEOUT - - RET -; -; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT -; UNIT IS SPECIFIED IN IDE_UNIT -; REGISTER A IS DESTROYED -; -IDE_SELUNIT: - LD A,(IDE_UNIT) ; GET UNIT - CP IDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) - JP NC,IDE_INVUNIT ; HANDLE INVALID UNIT -; -#IF (IDEMODE == IDEMODE_DIDE) - ; SELECT PRIMARY/SECONDARY INTERFACE FOR DIDE HARDWARE -#ENDIF -; - ; DETERMINE AND SAVE DRIVE/HEAD VALUE FOR SELECTED UNIT - PUSH HL ; SAVE HL - LD A,(IDE_UNIT) ; GET CURRENT UNIT - AND $01 ; LS BIT DETERMINES MASTER/SLAVE - LD HL,IDE_DRVSEL - CALL ADDHLA - LD A,(HL) ; LOAD DRIVE/HEAD VALUE - POP HL ; RECOVER HL - LD (IDE_DRVHD),A ; SAVE IT -; - XOR A ; SIGNAL SUCCESS - RET ; AND DONE -; -; -; -IDE_PROBE: -#IF (IDETRACE >= 3) - CALL IDE_PRTPREFIX - PRTS(" PROBE$") ; LABEL FOR IO ADDRESS -#ENDIF -; - LD A,(IDE_DRVHD) - OUT (IDE_IO_DRVHD),A - DCALL PC_SPACE - DCALL PRTHEXBYTE - - CALL DELAY ; DELAY ~16US -; - DCALL IDE_REGDUMP -; - ;JR IDE_PROBE1 ; *DEBUG* -; -IDE_PROBE0: - CALL IDE_WAITBSY ; WAIT FOR BUSY TO CLEAR - JP NZ,IDE_NOMEDIA ; CONVERT TIMEOUT TO NO MEDIA AND RETURN -; - DCALL IDE_REGDUMP -; - ; CHECK STATUS - IN A,(IDE_IO_STAT) ; GET STATUS - DCALL PC_SPACE - DCALL PRTHEXBYTE ; IF DEBUG, PRINT STATUS - OR A ; SET FLAGS TO TEST FOR ZERO - JP Z,IDE_NOMEDIA -; - ; CHECK SIGNATURE - DCALL PC_SPACE - IN A,(IDE_IO_COUNT) - DCALL PRTHEXBYTE - CP $01 - JP NZ,IDE_NOMEDIA - DCALL PC_SPACE - IN A,(IDE_IO_SECT) - DCALL PRTHEXBYTE - CP $01 - JP NZ,IDE_NOMEDIA - DCALL PC_SPACE - IN A,(IDE_IO_CYLLO) - DCALL PRTHEXBYTE - CP $00 - JP NZ,IDE_NOMEDIA - DCALL PC_SPACE - IN A,(IDE_IO_CYLHI) - DCALL PRTHEXBYTE - CP $00 - JP NZ,IDE_NOMEDIA -; -IDE_PROBE1: - ; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS - IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD (HL),IDE_TYPEATA ; SET THE DEVICE TYPE - XOR A ; SIGNAL SUCCESS - RET ; DONE, NOTE THAT A=0 AND Z IS SET -; -; (RE)INITIALIZE DEVICE -; -IDE_INITDEV: -; - IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD A,(HL) ; GET THE DEVICE TYPE - OR A ; SET FLAGS - JP Z,IDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS -; - ; CLEAR OUT UNIT SPECIFIC DATA, BUT PRESERVE THE EXISTING - ; VALUE OF THE UNIT TYPE WHICH WAS ESTABLISHED BY THE DEVICE - ; PROBES WHEN THE IDE BUS WAS RESET - PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE - PUSH HL ; SAVE UNIT TYPE FIELD POINTER - IDE_DPTR(0) ; SET HL TO START OF UNIT DATA - LD BC,IDE_UDLEN - XOR A - CALL FILL - POP HL ; RECOVER UNIT TYPE FIELD POINTER - POP AF ; RECOVER UNIT TYPE VALUE - LD (HL),A ; AND PUT IT BACK -; -#IF (IDE8BIT) - LD A,IDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO -#ELSE - LD A,IDE_FEAT_DISABLE8BIT ; FEATURE VALUE = DISABLE 8-BIT PIO -#ENDIF - - CALL IDE_SETFEAT ; SET FEATURE - RET NZ ; BAIL OUT ON ERROR -; - CALL IDE_IDENTIFY ; EXECUTE IDENTIFY COMMAND - RET NZ ; BAIL OUT ON ERROR -; - LD DE,HB_WRKBUF ; POINT TO BUFFER - DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING -; - ; DETERMINE IF CF DEVICE - LD HL,HB_WRKBUF ; FIRST WORD OF IDENTIFY DATA HAS CF FLAG - LD A,$8A ; FIRST BYTE OF MARKER IS $8A - CP (HL) ; COMPARE - JR NZ,IDE_INITDEV1 ; IF NO MATCH, NOT CF - INC HL - LD A,$84 ; SECOND BYTE OF MARKER IS $84 - CP (HL) ; COMPARE - JR NZ,IDE_INITDEV1 ; IF NOT MATCH, NOT CF - IDE_DPTR(IDE_CFFLAG) ; POINT HL TO CF FLAG FIELD - LD A,$FF ; SET FLAG VALUE TO NON-ZERO (TRUE) - LD (HL),A ; SAVE IT -; -IDE_INITDEV1: - ; GET DEVICE CAPACITY AND SAVE IT - IDE_DPTR(IDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD - PUSH HL ; SAVE POINTER - LD HL,HB_WRKBUF ; POINT TO BUFFER START - LD A,120 ; OFFSET OF SECTOR COUNT - CALL ADDHLA ; POINT TO ADDRESS OF SECTOR COUNT - CALL LD32 ; LOAD IT TO DE:HL - POP BC ; RECOVER POINTER TO CAPACITY ENTRY - CALL ST32 ; SAVE CAPACITY -; - ; RESET CARD STATUS TO 0 (OK) - IDE_DPTR(IDE_STAT) ; HL := ADR OF STATUS, AF TRASHED - XOR A ; A := 0 (STATUS = OK) - LD (HL),A ; SAVE IT -; - RET ; RETURN, A=0, Z SET -; -; -; -IDE_CHKDEVICE: - IDE_DPTR(IDE_STAT) - LD A,(HL) - OR A - RET Z ; RETURN IF ALL IS WELL -; - ; ATTEMPT TO REINITIALIZE HERE??? - JP IDE_ERR - RET -; -; -; -IDE_WAITRDY: - LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS - LD B,A ; PUT IN OUTER LOOP VAR -IDE_WAITRDY1: - LD DE,(IDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR -IDE_WAITRDY2: - IN A,(IDE_IO_STAT) ; READ STATUS - LD C,A ; SAVE IT - AND %11000000 ; ISOLATE BUSY AND RDY BITS - XOR %01000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - RET Z ; ALL SET, RETURN WITH Z SET - DEC DE - LD A,D - OR E - JR NZ,IDE_WAITRDY2 ; INNER LOOP RETURN - DJNZ IDE_WAITRDY1 ; OUTER LOOP RETURN - JP IDE_RDYTO ; EXIT WITH RDYTO ERR -; -; -; -IDE_WAITDRQ: - LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS - LD B,A ; PUT IN OUTER LOOP VAR -IDE_WAITDRQ1: - LD DE,(IDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR -IDE_WAITDRQ2: - IN A,(IDE_IO_STAT) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER - LD C,A ; SAVE IT - AND %10001000 ; TO FILL (OR READY TO FILL) - XOR %00001000 - RET Z - DEC DE - LD A,D - OR E - JR NZ,IDE_WAITDRQ2 - DJNZ IDE_WAITDRQ1 - JP IDE_DRQTO ; EXIT WITH BUFTO ERR -; -; -; -IDE_WAITBSY: - LD A,(IDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS - LD B,A ; PUT IN OUTER LOOP VAR -IDE_WAITBSY1: - LD DE,(IDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR -IDE_WAITBSY2: - IN A,(IDE_IO_STAT) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER ; 11TS - LD C,A ; SAVE IT ; 4TS - AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS - RET Z ; 5TS - DEC DE ; 6TS - LD A,D ; 4TS - OR E ; 4TS - JR NZ,IDE_WAITBSY2 ; 12TS - DJNZ IDE_WAITBSY1 ; ----- - JP IDE_BSYTO ; EXIT WITH BSYTO ERR ; 52TS -; -;============================================================================= -; ERROR HANDLING AND DIAGNOSTICS -;============================================================================= -; -; ERROR HANDLERS -; -IDE_INVUNIT: - LD A,IDE_STINVUNIT - JR IDE_ERR2 ; SPECIAL CASE FOR INVALID UNIT -; -IDE_NOMEDIA: - LD A,IDE_STNOMEDIA - JR IDE_ERR -; -IDE_CMDERR: - LD A,IDE_STCMDERR - JR IDE_ERR -; -IDE_IOERR: - LD A,IDE_STIOERR - JR IDE_ERR -; -IDE_RDYTO: - LD A,IDE_STRDYTO - JR IDE_ERR -; -IDE_DRQTO: - LD A,IDE_STDRQTO - JR IDE_ERR -; -IDE_BSYTO: - LD A,IDE_STBSYTO - JR IDE_ERR -; -IDE_ERR: - PUSH HL ; IS THIS NEEDED? - PUSH AF ; SAVE INCOMING STATUS - IDE_DPTR(IDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED - POP AF ; RESTORE INCOMING STATUS - LD (HL),A ; UPDATE STATUS - POP HL ; IS THIS NEEDED? -IDE_ERR2: -#IF (IDETRACE >= 2) - CALL IDE_PRTSTAT - CALL IDE_REGDUMP -#ENDIF - OR A ; SET FLAGS - RET -; -; -; -IDE_PRTERR: - RET Z ; DONE IF NO ERRORS - ; FALL THRU TO IDE_PRTSTAT -; -; PRINT STATUS STRING (STATUS NUM IN A) -; -IDE_PRTSTAT: - PUSH AF - PUSH DE - PUSH HL - OR A - LD DE,IDE_STR_STOK - JR Z,IDE_PRTSTAT1 - INC A - LD DE,IDE_STR_STINVUNIT - JR Z,IDE_PRTSTAT2 ; INVALID UNIT IS SPECIAL CASE - INC A - LD DE,IDE_STR_STNOMEDIA - JR Z,IDE_PRTSTAT1 - INC A - LD DE,IDE_STR_STCMDERR - JR Z,IDE_PRTSTAT1 - INC A - LD DE,IDE_STR_STIOERR - JR Z,IDE_PRTSTAT1 - INC A - LD DE,IDE_STR_STRDYTO - JR Z,IDE_PRTSTAT1 - INC A - LD DE,IDE_STR_STDRQTO - JR Z,IDE_PRTSTAT1 - INC A - LD DE,IDE_STR_STBSYTO - JR Z,IDE_PRTSTAT1 - LD DE,IDE_STR_STUNK -IDE_PRTSTAT1: - CALL IDE_PRTPREFIX ; PRINT UNIT PREFIX - JR IDE_PRTSTAT3 -IDE_PRTSTAT2: - CALL NEWLINE - PRTS("IDE:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT -IDE_PRTSTAT3: - CALL PC_SPACE ; FORMATTING - CALL WRITESTR - POP HL - POP DE - POP AF - RET -; -; PRINT ALL REGISTERS DIRECTLY FROM DEVICE -; DEVICE MUST BE SELECTED PRIOR TO CALL -; -IDE_REGDUMP: - PUSH AF - PUSH BC - CALL PC_SPACE - CALL PC_LBKT - LD C,IDE_IO_CMD - LD B,7 -IDE_REGDUMP1: - IN A,(C) - CALL PRTHEXBYTE - DEC C - DEC B - CALL NZ,PC_SPACE - JR NZ,IDE_REGDUMP1 - CALL PC_RBKT - POP BC - POP AF - RET -; -; PRINT DIAGNONSTIC PREFIX -; -IDE_PRTPREFIX: - PUSH AF - CALL NEWLINE - PRTS("IDE$") - LD A,(IDE_UNIT) - ADD A,'0' - CALL COUT - CALL PC_COLON - POP AF - RET -; -; -; -#IF (DSKYENABLE) -IDE_DSKY: - LD HL,DSKY_HEXBUF ; POINT TO DSKY BUFFER - IN A,(IDE_IO_DRVHD) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER - IN A,(IDE_IO_CYLHI) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER - IN A,(IDE_IO_CYLLO) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER - IN A,(IDE_IO_SECT) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - CALL DSKY_HEXOUT ; SEND IT TO DSKY - RET -#ENDIF -; -;============================================================================= -; STRING DATA -;============================================================================= -; -IDE_STR_STOK .TEXT "OK$" -IDE_STR_STINVUNIT .TEXT "INVALID UNIT$" -IDE_STR_STNOMEDIA .TEXT "NO MEDIA$" -IDE_STR_STCMDERR .TEXT "COMMAND ERROR$" -IDE_STR_STIOERR .TEXT "IO ERROR$" -IDE_STR_STRDYTO .TEXT "READY TIMEOUT$" -IDE_STR_STDRQTO .TEXT "DRQ TIMEOUT$" -IDE_STR_STBSYTO .TEXT "BUSY TIMEOUT$" -IDE_STR_STUNK .TEXT "UNKNOWN ERROR$" -; -IDE_STR_NO .TEXT "NO$" -; -;============================================================================= -; DATA STORAGE -;============================================================================= -; -IDE_TIMEOUT .DB IDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC -IDE_TOSCALER .DW CPUMHZ * 961 ; WAIT FUNCS SCALER FOR CPU SPEED -; -IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS -IDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK -; -IDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO -IDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER -; -; UNIT SPECIFIC DATA STORAGE -; -IDE_UDATA .FILL IDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES -IDE_DLEN .EQU $ - IDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS -IDE_UDLEN .EQU IDE_DLEN / IDE_UNITCNT ; LENGTH OF PER UNIT DATA -; -;============================================================================= -; HELPER ROUTINES -;============================================================================= -; -; IMPLEMENTATION FOR MACRO IDE_DPTR -; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA -; HL := ADR OF IDE_UNITDATA[(IDE_UNIT)][(SP)] -; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET -; AF IS TRASHED -; -IDE_DPTRIMP: - LD HL,IDE_UDATA ; POINT TO START OF UNIT DATA ARRAY - LD A,(IDE_UNIT) ; GET CURRENT UNIT NUM - RLCA ; MULTIPLY BY - RLCA ; ... SIZE OF PER UNIT DATA - RLCA ; ... (8 BYTES) - EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS - ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM - INC HL ; BUMP HL TO NEXT REAL INSTRUCTION - EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA - JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN diff --git a/Source/HBIOS/md.asm b/Source/HBIOS/md.asm index 522253c6..d01d75c7 100644 --- a/Source/HBIOS/md.asm +++ b/Source/HBIOS/md.asm @@ -3,7 +3,32 @@ ; MD DISK DRIVER (MEMORY DISK) ;================================================================================================== ; -MD_UNITCNT .EQU 2 +; MD DEVICE CONFIGURATION +; +MD_DEVCNT .EQU 2 ; NUMBER OF MD DEVICES SUPPORTED +MD_CFGSIZ .EQU 6 ; SIZE OF CFG TBL ENTRIES +; +MD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +MD_STAT .EQU 1 ; OFFSET OF STATUS (BYTE) +MD_LBA .EQU 2 ; OFFSET OF LBA (DWORD) +; +; DEVICE CONFIG TABLE (RAM DEVICE FIRST TO MAKE IT ALWAYS FIRST DRIVE) +; +MD_CFGTBL: + ; DEVICE 1 (RAM) + .DB 1 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DW 0,0 ; CURRENT LBA + ; DEVICE 0 (ROM) + .DB 0 ; DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DW 0,0 ; CURRENT LBA +; +#IF ($ - MD_CFGTBL) != (MD_DEVCNT * MD_CFGSIZ) + .ECHO "*** INVALID MD CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER ; ; ; @@ -18,102 +43,77 @@ MD_INIT: CALL PRTDEC PRTS("KB$") ; -; SETUP THE DISPATCH TABLE ENTRIES -; - LD B,$01 ; PHYSICAL UNIT=1 (RAM) - LD C,DIODEV_MD ; DEVICE TYPE - LD DE,MD_RAMDAT ; UNIT 1 DATA BLOB ADDRESS - CALL DIO_ADDENT ; ADD ENTRY - LD B,$00 ; PHYSICAL UNIT=0 (ROM) - LD C,DIODEV_MD ; DEVICE TYPE - LD DE,MD_ROMDAT ; UNIT 0 DATA BLOB ADDRESS - CALL DIO_ADDENT ; ADD ENTRY -; - XOR A ; INIT SUCCEEDED - RET ; RETURN -; -; -; -MD_ROMDAT: ; ROM UNIT DATA BLOB - .DB 0 ; UNIT NUMBER IS 0 -; -MD_RAMDAT: ; RAM UNIT DATA BLOB - .DB 0 ; UNIT NUMBER IS 1 -; -; -; -MD_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP MD_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (MD_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,MD_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,MD_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,MD_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,MD_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,MD_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,MD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,MD_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,MD_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,MD_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,MD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,MD_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,MD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +; SETUP THE DIO TABLE ENTRIES +; + LD BC,MD_FNTBL + LD DE,MD_CFGTBL + PUSH BC + CALL DIO_ADDENT + POP BC + LD DE,MD_CFGTBL + MD_CFGSIZ + CALL DIO_ADDENT +; + XOR A ; INIT SUCCEEDED + RET ; RETURN +; +; +; +MD_FNTBL: + .DW MD_STATUS + .DW MD_RESET + .DW MD_SEEK + .DW MD_READ + .DW MD_WRITE + .DW MD_VERIFY + .DW MD_FORMAT + .DW MD_DEVICE + .DW MD_MEDIA + .DW MD_DEFMED + .DW MD_CAP + .DW MD_GEOM +#IF (($ - MD_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID MD FUNCTION TABLE ***\n" +#ENDIF +; +; ; MD_VERIFY: MD_FORMAT: MD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; INVALID SUB-FUNCTION ; ; ; MD_STATUS: - XOR A ; ALWAYS OK + XOR A ; ALWAYS OK RET ; ; ; MD_RESET: - XOR A ; ALWAYS OK + XOR A ; ALWAYS OK RET ; ; ; MD_CAP: - LD A,C ; DEVICE/UNIT IS IN C - AND $0F ; ISOLATE UNIT NUM - JR Z,MD_CAP0 ; UNIT 0 - DEC A ; TRY UNIT 1 - JR Z,MD_CAP1 ; UNIT 1 - CALL PANIC ; PANIC ON INVALID UNIT + LD A,(IY+MD_DEV) ; GET DEVICE NUMBER + OR A ; SET FLAGS + JR Z,MD_CAP0 ; UNIT 0 + DEC A ; TRY UNIT 1 + JR Z,MD_CAP1 ; UNIT 1 + CALL PANIC ; PANIC ON INVALID UNIT MD_CAP0: LD A,(HCB + HCB_ROMBANKS) ; POINT TO ROM BANK COUNT JR MD_CAP2 MD_CAP1: LD A,(HCB + HCB_RAMBANKS) ; POINT TO RAM BANK COUNT MD_CAP2: - SUB 4 ; SUBTRACT OUT RESERVED BANKS - LD H,A ; H := # BANKS - LD E,64 ; # 512 BYTE BLOCKS / BANK - CALL MULT8 ; HL := TOTAL # 512 BYTE BLOCKS - LD DE,0 ; NEVER EXCEEDS 64K, ZERO HIGH WORD + SUB 4 ; SUBTRACT OUT RESERVED BANKS + LD H,A ; H := # BANKS + LD E,64 ; # 512 BYTE BLOCKS / BANK + CALL MULT8 ; HL := TOTAL # 512 BYTE BLOCKS + LD DE,0 ; NEVER EXCEEDS 64K, ZERO HIGH WORD XOR A RET ; @@ -122,51 +122,53 @@ MD_CAP2: MD_GEOM: ; RAM/ROM DISKS ALLOW CHS STYLE ACCESS BY EMULATING ; A DISK DEVICE WITH 1 HEAD AND 16 SECTORS / TRACK. - CALL MD_CAP ; HL := CAPACITY IN BLOCKS - LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT - LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION - LD B,4 ; PREPARE TO DIVIDE BY 16 + CALL MD_CAP ; HL := CAPACITY IN BLOCKS + LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT + LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION + LD B,4 ; PREPARE TO DIVIDE BY 16 MD_GEOM1: - SRL H ; SHIFT H - RR L ; SHIFT L - DJNZ MD_GEOM1 ; DO 4 BITS TO DIVIDE BY 16 - XOR A ; SIGNAL SUCCESS - RET ; DONE + SRL H ; SHIFT H + RR L ; SHIFT L + DJNZ MD_GEOM1 ; DO 4 BITS TO DIVIDE BY 16 + XOR A ; SIGNAL SUCCESS + RET ; DONE ; ; ; MD_DEVICE: - LD D,DIODEV_MD ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - LD A,C ; PHYSICAL UNIT TO A - OR A ; SET FLAGS - LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES - JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE - LD C,%00101000 ; USE RAM DISK ATTRIBUTES + LD D,DIODEV_MD ; D := DEVICE TYPE + LD A,(IY+MD_DEV) ; GET DEVICE NUMBER + LD E,A ; PUT IN E FOR RETURN + OR A ; SET FLAGS + LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES + JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE + LD C,%00101000 ; USE RAM DISK ATTRIBUTES MD_DEVICE1: - XOR A ; SIGNAL SUCCESS + XOR A ; SIGNAL SUCCESS RET ; ; ; MD_MEDIA: - LD A,MID_MDROM ; SET MEDIA TYPE TO ROM - ADD A,C ; ADJUST BASED ON DEVICE - LD E,A ; RESULTANT MEDIA IT TO E - LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE - XOR A ; SIGNAL SUCCESS + LD A,(IY+MD_DEV) ; GET DEVICE NUM + ADD A,MID_MDROM ; OFFSET BY MD ROM + LD E,A ; RESULTANT MEDIA ID TO E + LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE + XOR A ; SIGNAL SUCCESS RET ; ; ; MD_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 + 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 (IY+MD_LBA+0),L ; SAVE NEW LBA + LD (IY+MD_LBA+1),H ; ... + LD (IY+MD_LBA+2),E ; ... + LD (IY+MD_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN ; ; @@ -182,7 +184,7 @@ MD_READ: MD_WRITE: LD BC,MD_WRSEC ; GET ADR OF SECTOR WRITE FUNC LD (MD_RWFNADR),BC ; SAVE IT AS PENDING IO FUNC - LD A,(MD_UNIT) ; GET UNIT NUMBER + LD A,(IY+MD_DEV) ; GET DEVICE NUMBER OR A ; SET FLAGS TO TEST FOR ROM (UNIT 0) JR NZ,MD_RW ; NOT ROM, SO OK TO WRITE, CONTINUE LD E,0 ; UNIT IS READ ONLY, ZERO SECTORS WRITTEN @@ -203,12 +205,11 @@ MD_RW1: LD HL,(MD_RWFNADR) ; GET PENDING IO FUNCTION ADDRESS CALL JPHL ; ... AND CALL IT JR NZ,MD_RW2 ; IF ERROR, SKIP INCREMENT - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,MD_LBA ; LBA OFFSET IN CFG ENTRY + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,MD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -227,51 +228,51 @@ MD_RW3: ; ; MD_RDSEC: - CALL MD_IOSETUP ; SETUP FOR MEMORY COPY + CALL MD_IOSETUP ; SETUP FOR MEMORY COPY #IF (MDTRACE >= 2) LD (MD_SRC),HL LD (MD_DST),DE LD (MD_LEN),BC #ENDIF PUSH BC - LD C,A ; SOURCE BANK - LD B,BID_BIOS ; DESTINATION BANK IS RAM BANK 1 (HBIOS) + LD C,A ; SOURCE BANK + LD B,BID_BIOS ; DESTINATION BANK IS RAM BANK 1 (HBIOS) #IF (MDTRACE >= 2) LD (MD_SRCBNK),BC CALL MD_PRT #ENDIF - LD A,C ; GET SOURCE BANK - LD (HB_SRCBNK),A ; SET IT - LD A,B ; GET DESTINATION BANK - LD (HB_DSTBNK),A ; SET IT + LD A,C ; GET SOURCE BANK + LD (HB_SRCBNK),A ; SET IT + LD A,B ; GET DESTINATION BANK + LD (HB_DSTBNK),A ; SET IT POP BC - CALL HB_BNKCPY ; DO THE INTERBANK COPY + CALL HB_BNKCPY ; DO THE INTERBANK COPY XOR A RET ; ; ; MD_WRSEC: - CALL MD_IOSETUP ; SETUP FOR MEMORY COPY - EX DE,HL ; SWAP SRC/DEST FOR WRITE + CALL MD_IOSETUP ; SETUP FOR MEMORY COPY + EX DE,HL ; SWAP SRC/DEST FOR WRITE #IF (MDTRACE >= 2) LD (MD_SRC),HL LD (MD_DST),DE LD (MD_LEN),BC #ENDIF PUSH BC - LD C,BID_BIOS ; SOURCE BANK IS RAM BANK 1 (HBIOS) - LD B,A ; DESTINATION BANK + LD C,BID_BIOS ; SOURCE BANK IS RAM BANK 1 (HBIOS) + LD B,A ; DESTINATION BANK #IF (MDTRACE >= 2) LD (MD_SRCBNK),BC CALL MD_PRT #ENDIF - LD A,C ; GET SOURCE BANK - LD (HB_SRCBNK),A ; SET IT - LD A,B ; GET DESTINATION BANK - LD (HB_DSTBNK),A ; SET IT + LD A,C ; GET SOURCE BANK + LD (HB_SRCBNK),A ; SET IT + LD A,B ; GET DESTINATION BANK + LD (HB_DSTBNK),A ; SET IT POP BC - CALL HB_BNKCPY ; DO THE INTERBANK COPY + CALL HB_BNKCPY ; DO THE INTERBANK COPY XOR A RET ; @@ -289,8 +290,8 @@ MD_WRSEC: ; SO THE HIGH WORD (HSTLBAHI) IS IGNORED ; ; EACH RAM/ROM BANK IS 32K BY DEFINITION AND EACH SECTOR IS 512 -; BYTES BY DEFINITION. SO, EACH RAM/ROM BANK CONTAINS 64 SECTORS -; (32,768 / 512 = 64). THEREFORE, YOU CAN THINK OF LBA AS +; BYTES BY DEFINITION. SO, EACH RAM/ROM BANK CONTAINS 64 SECTORS +; (32,768 / 512 = 64). THEREFORE, YOU CAN THINK OF LBA AS ; 00000BBB:BBOOOOOO IS WHERE THE 'B' BITS REPRESENT THE BANK NUMBER ; AND THE 'O' BITS REPRESENT THE SECTOR NUMBER WITHIN THE BANK. ; @@ -307,7 +308,8 @@ MD_WRSEC: ; DEALING WITH 512 BYTE BOUNDARIES. ; MD_IOSETUP: - LD HL,(HSTLBALO) ; HL := LOW WORD OF LBA + LD L,(IY+MD_LBA+0) ; HL := LOW WORD OF LBA + LD H,(IY+MD_LBA+1) ; ... ; ALIGN BITS TO EXTRACT BANK NUMBER FROM H SLA L ; LEFT SHIFT ONE BIT RL H ; FULL WORD @@ -315,7 +317,7 @@ MD_IOSETUP: RL H ; FULL WORD LD C,H ; BANK NUMBER FROM H TO C ; GET BANK NUM TO A AND SET FLAG Z=ROM, NZ=RAM - LD A,(MD_UNIT) ; DEVICE/UNIT TO A + LD A,(IY+MD_DEV) ; DEVICE TO A AND $01 ; ISOLATE LOW BIT, SET ZF LD A,C ; BANK VALUE INTO A PUSH AF ; SAVE IT FOR NOW @@ -348,9 +350,9 @@ MD_PRT: CALL NEWLINE - LD DE,MDSTR_PREFIX + LD DE,MDSTR_PREFIX CALL WRITESTR - + CALL PC_SPACE LD DE,MDSTR_SRC CALL WRITESTR @@ -359,7 +361,7 @@ MD_PRT: CALL PC_COLON LD BC,(MD_SRC) CALL PRTHEXWORD - + CALL PC_SPACE LD DE,MDSTR_DST CALL WRITESTR @@ -368,13 +370,13 @@ MD_PRT: CALL PC_COLON LD BC,(MD_DST) CALL PRTHEXWORD - + CALL PC_SPACE LD DE,MDSTR_LEN CALL WRITESTR LD BC,(MD_LEN) CALL PRTHEXWORD - + POP HL POP DE POP BC @@ -386,7 +388,6 @@ MD_PRT: ; MD_RWFNADR .DW 0 ; -MD_UNIT .DB 0 MD_DSKBUF .DW 0 ; MD_SRCBNK .DB 0 diff --git a/Source/HBIOS/ppide.asm b/Source/HBIOS/ppide.asm index 0b19a89e..9494dcf8 100644 --- a/Source/HBIOS/ppide.asm +++ b/Source/HBIOS/ppide.asm @@ -31,7 +31,7 @@ PPIDE_IO_CTL .EQU PPIDE_IO_BASE + 2 ; IDE ADDRESS BUS AND CONTROL SIGNALS (8255 PPIDE_IO_PPI .EQU PPIDE_IO_BASE + 3 ; 8255 CONTROL PORT ; ; THE CONTROL PORT OF THE 8255 IS PROGRAMMED AS NEEDED TO READ OR WRITE -; DATA ON THE IDE BUS. PORT C OF THE 8255 IS ALWAYS IN OUTPUT MODE BECAUSE +; DATA ON THE IDE BUS. PORT C OF THE 8255 IS ALWAYS IN OUTPUT MODE BECAUSE ; IT IS DRIVING THE ADDRESS BUS AND CONTROL SIGNALS. PORTS A & B WILL BE ; PLACED IN READ OR WRITE MODE DEPENDING ON THE DIRECTION OF THE DATA BUS. ; @@ -39,7 +39,7 @@ PPIDE_DIR_READ .EQU %10010010 ; IDE BUS DATA INPUT MODE PPIDE_DIR_WRITE .EQU %10000000 ; IDE BUS DATA OUTPUT MODE ; ; PORT C OF THE 8255 IS USED TO DRIVE THE IDE INTERFACE ADDRESS BUS -; AND VARIOUS CONTROL SIGNALS. THE CONSTANTS BELOW REFLECT THESE +; AND VARIOUS CONTROL SIGNALS. THE CONSTANTS BELOW REFLECT THESE ; ASSIGNMENTS. ; PPIDE_CTL_DA0 .EQU %00000001 ; DRIVE ADDRESS BUS - BIT 0 (DA0) @@ -54,7 +54,7 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; +-----------------------------------------------------------------------+ ; | CONTROL BLOCK REGISTERS (CS3FX) | ; +-----------------------+-------+-------+-------------------------------+ -; | REGISTER | PORT | DIR | DESCRIPTION | +; | REGISTER | PORT | DIR | DESCRIPTION | ; +-----------------------+-------+-------+-------------------------------+ ; | PPIDE_REG_ALTSTAT | 0x06 | R | ALTERNATE STATUS REGISTER | ; | PPIDE_REG_CTRL | 0x06 | W | DEVICE CONTROL REGISTER | @@ -64,7 +64,7 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; +-----------------------+-------+-------+-------------------------------+ ; | COMMAND BLOCK REGISTERS (CS1FX) | ; +-----------------------+-------+-------+-------------------------------+ -; | REGISTER | PORT | DIR | DESCRIPTION | +; | REGISTER | PORT | DIR | DESCRIPTION | ; +-----------------------+-------+-------+-------------------------------+ ; | PPIDE_REG_DATA | 0x00 | R/W | DATA INPUT/OUTPUT | ; | PPIDE_REG_ERR | 0x01 | R | ERROR REGISTER | @@ -74,7 +74,7 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; | PPIDE_REG_CYLLO | 0x04 | R/W | CYLINDER NUM REGISTER (LSB) | ; | PPIDE_REG_CYLHI | 0x05 | R/W | CYLINDER NUM REGISTER (MSB) | ; | PPIDE_REG_DRVHD | 0x06 | R/W | DRIVE/HEAD REGISTER | -; | PPIDE_REG_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) | +; | PPIDE_REG_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) | ; | PPIDE_REG_LBA1* | 0x04 | R/W | LBA BYTE 1 (BITS 8-15) | ; | PPIDE_REG_LBA2* | 0x05 | R/W | LBA BYTE 2 (BITS 16-23) | ; | PPIDE_REG_LBA3* | 0x06 | R/W | LBA BYTE 3 (BITS 24-27) | @@ -85,9 +85,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; ; === STATUS REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR | +; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; BSY: BUSY @@ -101,9 +101,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; ; === ERROR REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF | +; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; (VALID WHEN ERR BIT IS SET IN STATUS REGISTER) ; @@ -118,9 +118,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; ; === DRIVE/HEAD / LBA3 REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 | +; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; L: 0 = CHS ADDRESSING, 1 = LBA ADDRESSING @@ -129,9 +129,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; ; === DEVICE CONTROL REGISTER === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +-------+-------+-------+-------+-------+-------+-------+-------+ -; | X | X | X | X | 1 | SRST | ~IEN | 0 | +; | X | X | X | X | 1 | SRST | ~IEN | 0 | ; +-------+-------+-------+-------+-------+-------+-------+-------+ ; ; SRST: SOFTWARE RESET @@ -140,22 +140,22 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED) ; CONTROL VALUES TO USE WHEN ACCESSING THE VARIOUS IDE DEVICE REGISTERS ; PPIDE_REG_DATA .EQU PPIDE_CTL_CS1FX | $00 ; DATA INPUT/OUTPUT (R/W) -PPIDE_REG_ERR .EQU PPIDE_CTL_CS1FX | $01 ; ERROR REGISTER (R) -PPIDE_REG_FEAT .EQU PPIDE_CTL_CS1FX | $01 ; FEATURES REGISTER (W) -PPIDE_REG_COUNT .EQU PPIDE_CTL_CS1FX | $02 ; SECTOR COUNT REGISTER (R/W) -PPIDE_REG_SECT .EQU PPIDE_CTL_CS1FX | $03 ; SECTOR NUMBER REGISTER (R/W) -PPIDE_REG_CYLLO .EQU PPIDE_CTL_CS1FX | $04 ; CYLINDER NUM REGISTER (LSB) (R/W) -PPIDE_REG_CYLHI .EQU PPIDE_CTL_CS1FX | $05 ; CYLINDER NUM REGISTER (MSB) (R/W) -PPIDE_REG_DRVHD .EQU PPIDE_CTL_CS1FX | $06 ; DRIVE/HEAD REGISTER (R/W) +PPIDE_REG_ERR .EQU PPIDE_CTL_CS1FX | $01 ; ERROR REGISTER (R) +PPIDE_REG_FEAT .EQU PPIDE_CTL_CS1FX | $01 ; FEATURES REGISTER (W) +PPIDE_REG_COUNT .EQU PPIDE_CTL_CS1FX | $02 ; SECTOR COUNT REGISTER (R/W) +PPIDE_REG_SECT .EQU PPIDE_CTL_CS1FX | $03 ; SECTOR NUMBER REGISTER (R/W) +PPIDE_REG_CYLLO .EQU PPIDE_CTL_CS1FX | $04 ; CYLINDER NUM REGISTER (LSB) (R/W) +PPIDE_REG_CYLHI .EQU PPIDE_CTL_CS1FX | $05 ; CYLINDER NUM REGISTER (MSB) (R/W) +PPIDE_REG_DRVHD .EQU PPIDE_CTL_CS1FX | $06 ; DRIVE/HEAD REGISTER (R/W) PPIDE_REG_LBA0 .EQU PPIDE_CTL_CS1FX | $03 ; LBA BYTE 0 (BITS 0-7) (R/W) PPIDE_REG_LBA1 .EQU PPIDE_CTL_CS1FX | $04 ; LBA BYTE 1 (BITS 8-15) (R/W) PPIDE_REG_LBA2 .EQU PPIDE_CTL_CS1FX | $05 ; LBA BYTE 2 (BITS 16-23) (R/W) PPIDE_REG_LBA3 .EQU PPIDE_CTL_CS1FX | $06 ; LBA BYTE 3 (BITS 24-27) (R/W) -PPIDE_REG_STAT .EQU PPIDE_CTL_CS1FX | $07 ; STATUS REGISTER (R) -PPIDE_REG_CMD .EQU PPIDE_CTL_CS1FX | $07 ; COMMAND REGISTER (EXECUTE) (W) -PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3FX | $06 ; ALTERNATE STATUS REGISTER (R) -PPIDE_REG_CTRL .EQU PPIDE_CTL_CS3FX | $06 ; DEVICE CONTROL REGISTER (W) -PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R) +PPIDE_REG_STAT .EQU PPIDE_CTL_CS1FX | $07 ; STATUS REGISTER (R) +PPIDE_REG_CMD .EQU PPIDE_CTL_CS1FX | $07 ; COMMAND REGISTER (EXECUTE) (W) +PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3FX | $06 ; ALTERNATE STATUS REGISTER (R) +PPIDE_REG_CTRL .EQU PPIDE_CTL_CS3FX | $06 ; DEVICE CONTROL REGISTER (W) +PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R) ; #IF (PPIDETRACE >= 3) #DEFINE DCALL CALL @@ -169,7 +169,7 @@ PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R) ; PPIDE2: SECONDARY MASTER ; PPIDE3: SECONDARY SLAVE ; -PPIDE_UNITCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE +PPIDE_DEVCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE ; ; COMMAND BYTES ; @@ -207,31 +207,53 @@ PPIDE_DRVSEL: PPIDE_DRVMASTER .DB %11100000 ; LBA, MASTER DEVICE PPIDE_DRVSLAVE .DB %11110000 ; LBA, SLAVE DEVICE ; -; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN PPIDE_UNITDATA) -; SEE PPIDE_UNITDATA IN DATA STORAGE BELOW +; PPIDE DEVICE CONFIGURATION +; +PPIDE_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS +; +PPIDE_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +PPIDE_STAT .EQU 1 ; LAST STATUS (BYTE) +PPIDE_TYPE .EQU 2 ; DEVICE TYPE (BYTE) +PPIDE_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE) +PPIDE_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +PPIDE_LBA .EQU 8 ; OFFSET OF LBA (DWORD) +; +PPIDE_CFGTBL: + ; DEVICE 0, PRIMARY MASTER + .DB 0 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA + ; DEVICE 1, PRIMARY SLAVE + .DB 1 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +; +#IF ($ - PPIDE_CFGTBL) != (PPIDE_DEVCNT * PPIDE_CFGSIZ) + .ECHO "*** INVALID PPIDE CONFIG TABLE ***\n" +#ENDIF ; -PPIDE_STAT .EQU 0 ; LAST STATUS (1 BYTE) -PPIDE_TYPE .EQU 1 ; DEVICE TYPE (1 BYTE) -PPIDE_CAPACITY .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES) -PPIDE_CFFLAG .EQU 6 ; CF FLAG (1 BYTE), NON-ZERO=CF - + .DB $FF ; END MARKER ; ; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL ; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING ; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES -; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED. +; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED. ; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY ; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO -; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255. +; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255. ; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS. ; PPIDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS PPIDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS ; -; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA -; -#DEFINE PPIDE_DPTR(FIELD) CALL PPIDE_DPTRIMP \ .DB FIELD -; ;============================================================================= ; INITIALIZATION ENTRY POINT ;============================================================================= @@ -255,10 +277,6 @@ PPIDE_INIT: #IF (PPIDE8BIT) PRTS(" 8BIT$") #ENDIF - PRTS(" UNITS=$") - LD A,PPIDE_UNITCNT - CALL PRTDECB -; CALL PPIDE_DETECT ; CHECK FOR HARDWARE JR Z,PPIDE_INIT00 ; CONTINUE IF PRESENT ; @@ -268,45 +286,46 @@ PPIDE_INIT: RET ; PPIDE_INIT00: + PRTS(" DEVICES=$") + LD A,PPIDE_DEVCNT + CALL PRTDECB ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,PPIDE_UNITCNT ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX + LD B,PPIDE_DEVCNT ; LOOP CONTROL + LD IY,PPIDE_CFGTBL ; START OF CFG TABLE PPIDE_INIT0: - PUSH BC ; SAVE LOOP CONTROL - LD B,C ; PHYSICAL UNIT - LD C,DIODEV_PPIDE ; 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 PPIDE_INIT0 ; LOOP UNTIL DONE + PUSH BC ; SAVE LOOP CONTROL + LD BC,PPIDE_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE + LD BC,PPIDE_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ PPIDE_INIT0 ; LOOP AS NEEDED ; ; INITIALIZE THE PPIDE INTERFACE NOW CALL PPIDE_RESET ; DO HARDWARE SETUP/INIT RET NZ ; ABORT IF RESET FAILS ; ; DEVICE DISPLAY LOOP - LD B,PPIDE_UNITCNT ; LOOP ONCE PER UNIT - LD C,0 ; C IS UNIT INDEX + LD B,PPIDE_DEVCNT ; LOOP ONCE PER DEVICE + LD IY,PPIDE_CFGTBL ; START OF CFG TABLE PPIDE_INIT1: - LD A,C ; UNIT NUM TO ACCUM PUSH BC ; SAVE LOOP CONTROL CALL PPIDE_INIT2 ; DISPLAY UNIT INFO + LD BC,PPIDE_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY POP BC ; RESTORE LOOP CONTROL - INC C ; INCREMENT UNIT INDEX DJNZ PPIDE_INIT1 ; LOOP UNTIL DONE RET ; DONE ; PPIDE_INIT2: - LD (PPIDE_UNIT),A ; SET CURRENT UNIT -; ; CHECK FOR BAD STATUS - PPIDE_DPTR(PPIDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED - LD A,(HL) - OR A - JP NZ,PPIDE_PRTSTAT + LD A,(IY+PPIDE_STAT) ; GET STATUS + OR A ; SET FLAGS + JP NZ,PPIDE_PRTSTAT ; EXIT VIA PRINT STATUS ; CALL PPIDE_PRTPREFIX ; PRINT DEVICE PREFIX ; @@ -316,18 +335,15 @@ PPIDE_INIT2: ; ; PRINT LBA/NOLBA CALL PC_SPACE ; FORMATTING - LD HL,HB_WRKBUF ; POINT TO BUFFER START - LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG - ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS - LD A,(HL) ; GET THE BYTE - BIT 1,A ; CHECK THE LBA BIT + BIT 1,(IY+PPIDE_FLAGS) ; TEST LBA FLAG LD DE,PPIDE_STR_NO ; POINT TO "NO" STRING CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED PRTS("LBA$") ; PRINT "LBA" REGARDLESS ; ; PRINT STORAGE CAPACITY (BLOCK COUNT) PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - PPIDE_DPTR(PPIDE_CAPACITY) ; SET HL TO ADR OF DEVICE CAPACITY + LD A,PPIDE_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 ; GET THE CAPACITY VALUE CALL PRTHEX32 ; PRINT HEX VALUE ; @@ -352,7 +368,7 @@ PPIDE_DETECT: ; TEST FOR PPI EXISTENCE ; WE SETUP THE PPI TO WRITE, THEN WRITE A VALUE OF ZERO ; TO PORT A (DATALO), THEN READ IT BACK. IF THE PPI IS THERE - ; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE ZERO. SINCE + ; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE ZERO. SINCE ; WE ARE IN WRITE MODE, AN IDE CONTROLLER WILL NOT BE ABLE TO ; INTERFERE WITH THE VALUE BEING READ. LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE @@ -367,48 +383,30 @@ PPIDE_DETECT: RET ; AND RETURN ; ;============================================================================= -; FUNCTION DISPATCH ENTRY POINT +; DRIVER FUNCTION TABLE ;============================================================================= ; -PPIDE_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP PPIDE_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (PPIDE_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,PPIDE_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,PPIDE_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,PPIDE_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,PPIDE_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,PPIDE_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,PPIDE_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,PPIDE_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,PPIDE_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,PPIDE_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,PPIDE_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,PPIDE_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,PPIDE_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +PPIDE_FNTBL: + .DW PPIDE_STATUS + .DW PPIDE_RESET + .DW PPIDE_SEEK + .DW PPIDE_READ + .DW PPIDE_WRITE + .DW PPIDE_VERIFY + .DW PPIDE_FORMAT + .DW PPIDE_DEVICE + .DW PPIDE_MEDIA + .DW PPIDE_DEFMED + .DW PPIDE_CAP + .DW PPIDE_GEOM +#IF (($ - PPIDE_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID PPIDE FUNCTION TABLE ***\n" +#ENDIF ; PPIDE_VERIFY: PPIDE_FORMAT: PPIDE_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; NOT IMPLEMENTED ; ; ; @@ -446,14 +444,12 @@ PPIDE_IO1: PUSH BC ; SAVE COUNTERS LD HL,(PPIDE_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS CALL JPHL ; ... AND CALL IT - CALL PPIDE_RDSEC ; READ NEXT SECTOR JR NZ,PPIDE_IO2 ; IF ERROR, SKIP INCREMENT - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,PPIDE_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,PPIDE_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -473,43 +469,20 @@ PPIDE_IO3: ; PPIDE_STATUS: ; RETURN UNIT STATUS - PPIDE_DPTR(PPIDE_STAT) ; HL := ADR OF STATUS, AF TRASHED - LD A,(HL) ; GET STATUS OF SELECTED UNIT + LD A,(IY+PPIDE_STAT) ; GET STATUS OF SELECTED DEVICE OR A ; SET FLAGS RET ; AND RETURN ; -; PPIDE_SENSE -; -PPIDE_SENSE: - ; THE ONLY WAY TO RESET AN IDE DEVICE IS TO RESET - ; THE ENTIRE INTERFACE. SO, TO HANDLE POSSIBLE HOT - ; SWAP WE DO THAT, THEN RESELECT THE DESIRED UNIT AND - ; CONTINUE. - CALL PPIDE_RESET ; RESET ALL DEVICES ON BUS -; - PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS - OR A ; SET FLAGS -#IF (PPIDETRACE == 1) - CALL PPIDE_PRTERR ; PRINT ANY ERRORS -#ENDIF - LD E,MID_HD ; ASSUME WE ARE OK - RET Z ; RETURN IF GOOD INIT - LD E,MID_NONE ; SIGNAL NO MEDA - RET ; AND RETURN -; ; ; PPIDE_DEVICE: LD D,DIODEV_PPIDE ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - PPIDE_DPTR(PPIDE_CFFLAG) ; POINT TO CF FLAG - LD A,(HL) ; GET FLAG - OR A ; SET ACCUM FLAGS + LD E,(IY+PPIDE_DEV) ; E := PHYSICAL DEVICE NUMBER + BIT 0,(IY+PPIDE_FLAGS) ; TEST CF BIT IN FLAGS LD C,%00000000 ; ASSUME NON-REMOVABLE HARD DISK JR Z,PPIDE_DEVICE1 ; IF Z, WE ARE DONE LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH -PPIDE_DEVICE1: +PPIDE_DEVICE1: XOR A ; SIGNAL SUCCESS RET ; @@ -521,10 +494,9 @@ PPIDE_MEDIA: JR Z,PPIDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA ; ; GET CURRENT STATUS - PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+PPIDE_STAT) ; GET STATUS OR A ; SET FLAGS - JR NZ,PPIDE_MEDIA1 ; ERROR ACTIVE, TO RIGHT TO RESET + JR NZ,PPIDE_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET ; ; USE IDENTIFY COMMAND TO CHECK DEVICE LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT @@ -539,8 +511,7 @@ PPIDE_MEDIA1: CALL PPIDE_RESET ; RESET IDE INTERFACE ; PPIDE_MEDIA2: - PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+PPIDE_STAT) ; GET STATUS OR A ; SET FLAGS LD D,0 ; NO MEDIA CHANGE DETECTED LD E,MID_HD ; ASSUME WE ARE OK @@ -551,22 +522,24 @@ PPIDE_MEDIA2: ; ; PPIDE_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 + 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 (IY+PPIDE_LBA+0),L ; SAVE NEW LBA + LD (IY+PPIDE_LBA+1),H ; ... + LD (IY+PPIDE_LBA+2),E ; ... + LD (IY+PPIDE_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN ; ; ; PPIDE_CAP: - PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+PPIDE_STAT) ; GET STATUS PUSH AF ; SAVE IT - PPIDE_DPTR(PPIDE_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT - CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL + LD A,PPIDE_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL LD BC,512 ; 512 BYTES PER BLOCK POP AF ; RECOVER STATUS OR A ; SET FLAGS @@ -635,8 +608,6 @@ PPIDE_IDENTIFY: ; ; PPIDE_RDSEC: - CALL PPIDE_CHKDEVICE - RET NZ ; #IF (PPIDETRACE >= 3) CALL PPIDE_PRTPREFIX @@ -659,8 +630,6 @@ PPIDE_RDSEC: ; ; PPIDE_WRSEC: - CALL PPIDE_CHKDEVICE - RET NZ ; #IF (PPIDETRACE >= 3) CALL PPIDE_PRTPREFIX @@ -685,19 +654,19 @@ PPIDE_SETADDR: ; SEND 3 LOWEST BYTES OF LBA IN REVERSE ORDER ; IDE_IO_LBA3 HAS ALREADY BEEN SET ; HSTLBA2-0 --> IDE_IO_LBA2-0 - LD A,(HSTLBA + 2) + LD A,(IY+PPIDE_LBA+2) DCALL PC_SPACE DCALL PRTHEXBYTE CALL PPIDE_OUT .DB PPIDE_REG_LBA2 - LD A,(HSTLBA + 1) + LD A,(IY+PPIDE_LBA+1) DCALL PC_SPACE DCALL PRTHEXBYTE CALL PPIDE_OUT .DB PPIDE_REG_LBA1 - LD A,(HSTLBA + 0) + LD A,(IY+PPIDE_LBA+0) DCALL PC_SPACE DCALL PRTHEXBYTE CALL PPIDE_OUT @@ -763,7 +732,6 @@ PPIDE_GETBUF: LD D,A ; D := READ ASSERTED ; ; LOOP SETUP - ;LD HL,(PPIDE_DSKBUF) ; LOCATION OF BUFFER LD B,0 ; 256 ITERATIONS LD C,PPIDE_IO_DATALO ; SETUP C WITH IO PORT (LSB) ; @@ -822,7 +790,6 @@ PPIDE_PUTBUF: LD D,A ; D := WRITE ASSERTED ; ; LOOP SETUP - ;LD HL,(PPIDE_DSKBUF) ; LOCATION OF BUFFER LD B,0 ; 256 ITERATIONS LD C,PPIDE_IO_DATALO ; SETUP C WITH IO PORT (LSB) ; @@ -914,28 +881,26 @@ PPIDE_RESET: LD DE,150000/16 ; ~???MS CALL VDELAY ; - ; CLEAR OUT ALL DATA (FOR ALL UNITS) - LD HL,PPIDE_UDATA - LD BC,PPIDE_UDLEN - XOR A - CALL FILL + ;; CLEAR OUT ALL DATA (FOR ALL UNITS) + ;LD HL,PPIDE_UDATA + ;LD BC,PPIDE_UDLEN + ;XOR A + ;CALL FILL ; - LD A,(PPIDE_UNIT) ; GET THE CURRENT UNIT SELECTION - PUSH AF ; AND SAVE IT + PUSH IY ; SAVE CURRENT DEVICE CFG PTR ; ; PROBE / INITIALIZE ALL UNITS - LD B,PPIDE_UNITCNT ; NUMBER OF UNITS TO TRY - LD C,0 ; UNIT INDEX FOR LOOP + LD B,PPIDE_DEVCNT ; NUMBER OF UNITS TO TRY + LD IY,PPIDE_CFGTBL ; START OF CFG TABLE PPIDE_RESET1: - LD A,C ; UNIT NUMBER TO A - PUSH BC + PUSH BC ; SAVE LOOP CONTROL CALL PPIDE_INITUNIT ; PROBE/INIT UNIT - POP BC - INC C ; NEXT UNIT + LD BC,PPIDE_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC DJNZ PPIDE_RESET1 ; LOOP AS NEEDED ; - POP AF ; RECOVER ORIGINAL UNIT NUMBER - LD (PPIDE_UNIT),A ; AND SAVE IT + POP IY ; RECOVER DEVICE CFG PTR ; XOR A ; SIGNAL SUCCESS RET ; AND DONE @@ -943,34 +908,28 @@ PPIDE_RESET1: ; ; PPIDE_INITUNIT: - LD (PPIDE_UNIT),A ; SET ACTIVE UNIT - CALL PPIDE_SELUNIT ; SELECT UNIT RET NZ ; ABORT IF ERROR - ;LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT - ;LD (HL),PPIDE_TOFAST ; USE FAST TIMEOUT DURING INIT - LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT LD (HL),PPIDE_TONORM ; SET NORMAL TIMEOUT CALL PPIDE_PROBE ; DO PROBE CALL Z,PPIDE_INITDEV ; IF FOUND, ATTEMPT TO INIT DEVICE - ;LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT - ;LD (HL),PPIDE_TONORM ; BACK TO NORMAL TIMEOUT - RET ; ; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT ; PPIDE_SELUNIT: - LD A,(PPIDE_UNIT) ; GET UNIT - CP PPIDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) - JP NC,PPIDE_INVUNIT ; HANDLE INVALID UNIT -; +#IF (PPIDETRACE >= 3) + CALL PPIDE_PRTPREFIX + PRTS(" SELUNIT$") +#ENDIF PUSH HL ; SAVE HL, IT IS DESTROYED BELOW - LD A,(PPIDE_UNIT) ; GET CURRENT UNIT + PUSH IY + POP BC + LD A,(IY+PPIDE_DEV) ; GET DEVICE AND $01 ; LS BIT DETERMINES MASTER/SLAVE LD HL,PPIDE_DRVSEL CALL ADDHLA @@ -995,7 +954,7 @@ PPIDE_PROBE: .DB PPIDE_REG_DRVHD DCALL PC_SPACE DCALL PRTHEXBYTE - + CALL DELAY ; DELAY ~16US ; ; IN A,(PPIDE_REG_STAT) ; GET STATUS @@ -1069,8 +1028,8 @@ PPIDE_PROBE0: ; PPIDE_PROBE1: ; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS - PPIDE_DPTR(PPIDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD (HL),PPIDE_TYPEATA ; SET THE DEVICE TYPE + LD A,PPIDE_TYPEATA ; TYPE = ATA + LD (IY+PPIDE_TYPE),A ; SET IT IN INSTANCE DATA XOR A ; SIGNAL SUCCESS RET ; DONE, NOTE THAT A=0 AND Z IS SET ; @@ -1078,23 +1037,32 @@ PPIDE_PROBE1: ; PPIDE_INITDEV: ; - PPIDE_DPTR(PPIDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED - LD A,(HL) ; GET THE DEVICE TYPE + LD A,(IY+PPIDE_TYPE) ; GET THE DEVICE TYPE OR A ; SET FLAGS JP Z,PPIDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS ; ; CLEAR OUT UNIT SPECIFIC DATA, BUT PRESERVE THE EXISTING ; VALUE OF THE UNIT TYPE WHICH WAS ESTABLISHED BY THE DEVICE ; PROBES WHEN THE PPIDE BUS WAS RESET - PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE - PUSH HL ; SAVE UNIT TYPE FIELD POINTER - PPIDE_DPTR(0) ; SET HL TO START OF UNIT DATA - LD BC,PPIDE_UDLEN - XOR A - CALL FILL - POP HL ; RECOVER UNIT TYPE FIELD POINTER - POP AF ; RECOVER UNIT TYPE VALUE - LD (HL),A ; AND PUT IT BACK + ;PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE + ;LD A,(IY+PPIDE_DEV) ; GET CURRENT DEVICE NUMBER + ;PUSH AF ; ... AND SAVE IT + ;;PUSH HL ; SAVE UNIT TYPE FIELD POINTER + ;;PPIDE_DPTR(0) ; SET HL TO START OF UNIT DATA + ;;LD BC,PPIDE_UDLEN + ;;XOR A + ;;CALL FILL + ;;POP HL ; RECOVER UNIT TYPE FIELD POINTER + ;;POP AF ; RECOVER UNIT TYPE VALUE + ;PUSH IY ; SET HL TO + ;POP HL ; ... START OF DEVICE INSTANCE DATA + ;LD BC,PPIDE_CFGSIZ ; SIZE OF CONFGI DATA TO CLEAR + ;XOR A ; FILL WITH ZERO + ;CALL FILL ; DO IT + ;POP AF ; RECOVER DEVICE NUMBER VALUE + ;LD (IY+PPIDE_DEV),A ; ... AND PUT IT BACK + ;POP AF ; RECOVER DEVICE TYPE VALUE + ;LD (IY+PPIDE_TYPE),A ; ... AND PUT IT BACK ; #IF (PPIDE8BIT) LD A,PPIDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO @@ -1116,6 +1084,9 @@ PPIDE_INITDEV: LD DE,HB_WRKBUF ; POINT TO BUFFER DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING ; + XOR A + LD (IY+PPIDE_FLAGS),0 ; CLEAR FLAGS + ; DETERMINE IF CF DEVICE LD HL,HB_WRKBUF ; FIRST WORD OF IDENTIFY DATA HAS CF FLAG LD A,$8A ; FIRST BYTE OF MARKER IS $8A @@ -1125,13 +1096,19 @@ PPIDE_INITDEV: LD A,$84 ; SECOND BYTE OF MARKER IS $84 CP (HL) ; COMPARE JR NZ,PPIDE_INITDEV1 ; IF NOT MATCH, NOT CF - PPIDE_DPTR(PPIDE_CFFLAG) ; POINT HL TO CF FLAG FIELD - LD A,$FF ; SET FLAG VALUE TO NON-ZERO (TRUE) - LD (HL),A ; SAVE IT + SET 0,(IY+PPIDE_FLAGS) ; SET FLAGS BIT FOR CF MEDIA ; PPIDE_INITDEV1: + ; DETERMINE IF LBA CAPABLE + LD A,(HB_WRKBUF+98+1) ; GET BYTE WITH LBA BIT FROM BUFFER + BIT 1,A ; CHECK THE LBA BIT + JR Z,PPIDE_INITDEV2 ; NOT SET, BYPASS + SET 1,(IY+PPIDE_FLAGS) ; SET FLAGS BIT FOR LBA +; +PPIDE_INITDEV2: ; GET DEVICE CAPACITY AND SAVE IT - PPIDE_DPTR(PPIDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD + LD A,PPIDE_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED PUSH HL ; SAVE POINTER LD HL,HB_WRKBUF ; POINT TO BUFFER START LD A,120 ; OFFSET OF SECTOR COUNT @@ -1141,18 +1118,16 @@ PPIDE_INITDEV1: CALL ST32 ; SAVE CAPACITY ; ; RESET CARD STATUS TO 0 (OK) - PPIDE_DPTR(PPIDE_STAT) ; HL := ADR OF STATUS, AF TRASHED XOR A ; A := 0 (STATUS = OK) - LD (HL),A ; SAVE IT + LD (IY+PPIDE_STAT),A ; SAVE IT ; RET ; RETURN, A=0, Z SET ; ; ; PPIDE_CHKDEVICE: - PPIDE_DPTR(PPIDE_STAT) - LD A,(HL) - OR A + LD A,(IY+PPIDE_STAT) ; GET STATUS + OR A ; SET FLAGS RET Z ; RETURN IF ALL IS WELL ; ; ATTEMPT TO REINITIALIZE HERE??? @@ -1168,23 +1143,23 @@ PPIDE_WAITRDY1: LD DE,(PPIDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR PPIDE_WAITRDY2: ;IN A,(PPIDE_REG_STAT) ; READ STATUS - CALL PPIDE_IN - .DB PPIDE_REG_STAT - LD C,A ; SAVE IT - AND %11000000 ; ISOLATE BUSY AND RDY BITS + CALL PPIDE_IN + .DB PPIDE_REG_STAT + LD C,A ; SAVE IT + AND %11000000 ; ISOLATE BUSY AND RDY BITS XOR %01000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - RET Z ; ALL SET, RETURN WITH Z SET - DEC DE - LD A,D - OR E - JR NZ,PPIDE_WAITRDY2 ; INNER LOOP RETURN - DJNZ PPIDE_WAITRDY1 ; OUTER LOOP RETURN - JP PPIDE_RDYTO ; EXIT WITH RDYTO ERR + RET Z ; ALL SET, RETURN WITH Z SET + DEC DE + LD A,D + OR E + JR NZ,PPIDE_WAITRDY2 ; INNER LOOP RETURN + DJNZ PPIDE_WAITRDY1 ; OUTER LOOP RETURN + JP PPIDE_RDYTO ; EXIT WITH RDYTO ERR ; ; ; PPIDE_WAITDRQ: - LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS + LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS LD B,A ; PUT IN OUTER LOOP VAR PPIDE_WAITDRQ1: LD DE,(PPIDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR @@ -1206,24 +1181,24 @@ PPIDE_WAITDRQ2: ; ; PPIDE_WAITBSY: - LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS + LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS LD B,A ; PUT IN OUTER LOOP VAR PPIDE_WAITBSY1: LD DE,(PPIDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR PPIDE_WAITBSY2: ;IN A,(PPIDE_REG_STAT) ; READ STATUS CALL PPIDE_IN ; 17TS + 170TS - .DB PPIDE_REG_STAT ; 0TS - LD C,A ; SAVE IT ; 4TS - AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS - RET Z ; 5TS - DEC DE ; 6TS - LD A,D ; 4TS - OR E ; 4TS - JR NZ,PPIDE_WAITBSY2 ; 12TS - DJNZ PPIDE_WAITBSY1 ; ----- - JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR ; 229TS -; + .DB PPIDE_REG_STAT ; 0TS + LD C,A ; SAVE IT ; 4TS + AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS + RET Z ; 5TS + DEC DE ; 6TS + LD A,D ; 4TS + OR E ; 4TS + JR NZ,PPIDE_WAITBSY2 ; 12TS + DJNZ PPIDE_WAITBSY1 ; ----- + JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR ; 229TS +; ; ; PPIDE_IN: @@ -1233,16 +1208,16 @@ PPIDE_IN: PUSH BC ; SAVE INCOMING BC ; 11TS LD B,(HL) ; GET CTL PORT VALUE ; 7TS LD C,PPIDE_IO_CTL ; SETUP PORT TO WRITE ; 7TS - OUT (C),B ; SET ADDRESS LINES ; 12TS - SET 6,B ; TURN ON WRITE BIT ; 8TS - OUT (C),B ; ASSERT WRITE LINE ; 12TS + OUT (C),B ; SET ADDRESS LINES ; 12TS + SET 6,B ; TURN ON WRITE BIT ; 8TS + OUT (C),B ; ASSERT WRITE LINE ; 12TS ;NOP ;NOP IN A,(PPIDE_IO_DATALO) ; GET DATA VALUE FROM DEVICE ; 11TS ;NOP ;NOP - RES 6,B ; CLEAR WRITE BIT ; 8TS - OUT (C),B ; DEASSERT WRITE LINE ; 12TS + RES 6,B ; CLEAR WRITE BIT ; 8TS + OUT (C),B ; DEASSERT WRITE LINE ; 12TS POP BC ; RECOVER INCOMING BC ; 10TS INC HL ; POINT PAST PARM ; 6TS EX (SP),HL ; RESTORE STACK ; 19TS @@ -1309,12 +1284,8 @@ PPIDE_BSYTO: JR PPIDE_ERR ; PPIDE_ERR: - PUSH HL ; IS THIS NEEDED? - PUSH AF ; SAVE INCOMING STATUS - PPIDE_DPTR(PPIDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED - POP AF ; RESTORE INCOMING STATUS - LD (HL),A ; UPDATE STATUS - POP HL ; IS THIS NEEDED? + LD (IY+PPIDE_STAT),A ; SAVE NEW STATUS +; PPIDE_ERR2: #IF (PPIDETRACE >= 2) CALL PPIDE_PRTSTAT @@ -1410,7 +1381,7 @@ PPIDE_PRTPREFIX: PUSH AF CALL NEWLINE PRTS("PPIDE$") - LD A,(PPIDE_UNIT) + LD A,(IY+PPIDE_DEV) ; GET CURRENT DEVICE NUM ADD A,'0' CALL COUT CALL PC_COLON @@ -1426,14 +1397,14 @@ PPIDE_DSKY: LD (HL),A ; SAVE IN BUFFER INC HL ; INCREMENT BUFFER POINTER IN A,(PPIDE_REG_CYLHI) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER IN A,(PPIDE_REG_CYLLO) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - INC HL ; INCREMENT BUFFER POINTER + LD (HL),A ; SAVE IN BUFFER + INC HL ; INCREMENT BUFFER POINTER IN A,(PPIDE_REG_SECT) ; GET DRIVE/HEAD - LD (HL),A ; SAVE IN BUFFER - CALL DSKY_HEXOUT ; SEND IT TO DSKY + LD (HL),A ; SAVE IN BUFFER + CALL DSKY_HEXOUT ; SEND IT TO DSKY RET #ENDIF ; @@ -1457,40 +1428,11 @@ PPIDE_STR_NO .TEXT "NO$" ; DATA STORAGE ;============================================================================= ; -PPIDE_TIMEOUT .DB PPIDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC -PPIDE_TOSCALER .DW CPUMHZ * 218 ; WAIT FUNCS SCALER FOR CPU SPEED -; -PPIDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS -PPIDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS -PPIDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK -; -PPIDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO -PPIDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER +PPIDE_TIMEOUT .DB PPIDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC +PPIDE_TOSCALER .DW CPUMHZ * 218 ; WAIT FUNCS SCALER FOR CPU SPEED ; -; UNIT SPECIFIC DATA STORAGE -; -PPIDE_UDATA .FILL PPIDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES -PPIDE_DLEN .EQU $ - PPIDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS -PPIDE_UDLEN .EQU PPIDE_DLEN / PPIDE_UNITCNT ; LENGTH OF PER UNIT DATA -; -;============================================================================= -; HELPER ROUTINES -;============================================================================= +PPIDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS +PPIDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS +PPIDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK ; -; IMPLEMENTATION FOR MACRO PPIDE_DPTR -; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA -; HL := ADR OF PPIDE_UNITDATA[(PPIDE_UNIT)][(SP)] -; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET -; AF IS TRASHED -; -PPIDE_DPTRIMP: - LD HL,PPIDE_UDATA ; POINT TO START OF UNIT DATA ARRAY - LD A,(PPIDE_UNIT) ; GET CURRENT UNIT NUM - RLCA ; MULTIPLY BY - RLCA ; ... SIZE OF PER UNIT DATA - RLCA ; ... (8 BYTES) - EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS - ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM - INC HL ; BUMP HL TO NEXT REAL INSTRUCTION - EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA - JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN +PPIDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER diff --git a/Source/HBIOS/ppp.asm b/Source/HBIOS/ppp.asm index 0f06b90f..5d2e595c 100644 --- a/Source/HBIOS/ppp.asm +++ b/Source/HBIOS/ppp.asm @@ -100,7 +100,7 @@ PPP_INITPPP: LD A,%11000010 ; PPI MODE 2 (BI HANDSHAKE), PC0-2 OUT, PB IN OUT (PPP_PPICTL),A ; NOTE: ALL OUTPUTS SET TO LOGIC ZERO ON MODE CHANGE CALL DELAY ; PROBABLY NOT NEEDED - + ; RESET PROPELLER LD A,%00000101 ; SET PC2 (ASSERT PROP RESET LINE) OUT (PPP_PPICTL),A @@ -346,18 +346,16 @@ PPPCON_QUERY: ; ; PPPCON_DEVICE: - LD D,CIODEV_PPPCON ; D := DEVICE TYPE - LD E,0 ; E := DEVICE NUM, ALWAYS 0 - LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA - XOR A ; SIGNAL SUCCESS + LD D,CIODEV_PPPCON ; D := DEVICE TYPE + LD E,0 ; E := DEVICE NUM, ALWAYS 0 + LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA + XOR A ; SIGNAL SUCCESS RET ; ;================================================================================================== ; PARPORTPROP SD CARD DRIVER ;================================================================================================== ; -PPPSD_UNITCNT .EQU 1 -; ; SD CARD TYPE ; PPPSD_TYPEUNK .EQU 0 ; CARD TYPE UNKNOWN/UNDETERMINED @@ -380,25 +378,78 @@ PPPSD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET PPPSD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR PPPSD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA ; +; PPPSD DEVICE CONFIGURATION +; +PPPSD_DEVCNT .EQU 1 ; ONE DEVICE SUPPORTED +PPPSD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS +; +PPPSD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +PPPSD_STAT .EQU 1 ; LAST STATUS (BYTE) +PPPSD_TYPE .EQU 2 ; DEVICE TYPE (BYTE) +PPPSD_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE) +PPPSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +PPPSD_LBA .EQU 8 ; OFFSET OF LBA (DWORD) +; +PPPSD_CFGTBL: + ; DEVICE 0 + .DB 0 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +; +#IF ($ - PPPSD_CFGTBL) != (PPPSD_DEVCNT * PPPSD_CFGSIZ) + .ECHO "*** INVALID PPPSD CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER +; ; SD CARD INITIALIZATION ; PPPSD_INIT: ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,0 ; PHYSICAL UNIT - LD C,DIODEV_PPPSD ; DEVICE TYPE - LD DE,0 ; UNIT DATA BLOB ADDRESS - CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD B,PPPSD_DEVCNT ; LOOP CONTROL + LD IY,PPPSD_CFGTBL ; START OF CFG TABLE +PPPSD_INIT0: + PUSH BC ; SAVE LOOP CONTROL + LD BC,PPPSD_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD BC,PPPSD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ PPPSD_INIT0 ; LOOP AS NEEDED +; + ; INITIALIZE INDIVIDUAL UNIT(S) AND DISPLAY DEVICE INVENTORY + LD B,PPPSD_DEVCNT ; INIT LOOP COUNTER TO DEVICE COUNT + LD IY,PPPSD_CFGTBL ; START OF CFG TABLE +PPPSD_INIT1: + PUSH BC ; SAVE LOOP COUNTER/INDEX + CALL PPPSD_INITUNIT ; INITIALIZE IT +#IF (PPPSDTRACE < 2) + CALL NZ,PPPSD_PRTSTAT ; IF ERROR, SHOW IT +#ENDIF + LD BC,PPPSD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE LOOP CONTROL + DJNZ PPPSD_INIT1 ; DECREMENT LOOP COUNTER AND LOOP AS NEEDED +; + RET ; DONE +; ; +; +PPPSD_INITUNIT: ; REINITIALIZE THE CARD HERE CALL PPPSD_INITCARD -#IF (PPPSDTRACE < 2) - JP NZ,PPPSD_PRTSTAT ; IF ERROR, SHOW IT -#ENDIF + RET NZ ; - CALL NEWLINE - PRTS("PPPSD:$") + CALL PPPSD_PRTPREFIX ; ; PRINT CARD TYPE PRTS(" TYPE=$") @@ -406,7 +457,8 @@ PPPSD_INIT: ; ; PRINT STORAGE CAPACITY (BLOCK COUNT) PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - LD HL,PPPSD_BLKCNT ; POINT TO BLOCK COUNT + LD A,PPPSD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 ; GET THE CAPACITY VALUE CALL PRTHEX32 ; PRINT HEX VALUE ; @@ -422,45 +474,27 @@ PPPSD_INIT: ; ; ; -PPPSD_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP PPPSD_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (PPPSD_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,PPPSD_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,PPPSD_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,PPPSD_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,PPPSD_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,PPPSD_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,PPPSD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,PPPSD_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,PPPSD_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,PPPSD_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,PPPSD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,PPPSD_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,PPPSD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +PPPSD_FNTBL: + .DW PPPSD_STATUS + .DW PPPSD_RESET + .DW PPPSD_SEEK + .DW PPPSD_READ + .DW PPPSD_WRITE + .DW PPPSD_VERIFY + .DW PPPSD_FORMAT + .DW PPPSD_DEVICE + .DW PPPSD_MEDIA + .DW PPPSD_DEFMED + .DW PPPSD_CAP + .DW PPPSD_GEOM +#IF (($ - PPPSD_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID PPPSD FUNCTION TABLE ***\n" +#ENDIF ; PPPSD_VERIFY: PPPSD_FORMAT: PPPSD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; INVALID SUB-FUNCTION ; ; ; @@ -498,7 +532,7 @@ PPPSD_IO: PPPSD_IO1: PUSH BC ; SAVE COUNTERS - + #IF (PPPSDTRACE >= 3) CALL PPPSD_PRTPREFIX #ENDIF @@ -506,13 +540,11 @@ PPPSD_IO1: LD HL,(PPPSD_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS CALL JPHL ; ... AND CALL IT JR NZ,PPPSD_IO2 ; BAIL OUT ON ERROR - - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,PPPSD_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,PPPSD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -550,14 +582,14 @@ PPPSD_RDSEC: CALL PC_SPACE CALL PRTHEXBYTE #ENDIF - + OR A ; SET FLAGS JR Z,PPPSD_RDSEC1 - + ; HANDLE ERROR CALL PPPSD_GETDSKSTAT ; GET FULL ERROR CODE JP PPPSD_ERRCMD ; RETURN VIA ERROR HANDLER - + PPPSD_RDSEC1: ; GET THE SECTOR DATA LD D,PPP_CMDDSKGET ; COMMAND = DSKGET @@ -627,23 +659,23 @@ PPPSD_WRSEC1: ; REPORT SD CARD READY STATE ; PPPSD_STATUS: - LD A,(PPPSD_STAT) ; GET THE CURRENT READY STATUS + LD A,(IY+PPPSD_STAT) ; GET THE CURRENT READY STATUS OR A RET ; ; ; PPPSD_RESET: - XOR A ; ALWAYS OK + XOR A ; ALWAYS OK RET ; ; ; PPPSD_DEVICE: - LD D,DIODEV_PPPSD ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD - XOR A ; SIGNAL SUCCESS + LD D,DIODEV_PPPSD ; D := DEVICE TYPE + LD E,(IY+PPPSD_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD + XOR A ; SIGNAL SUCCESS RET ; ; SETUP FOR SUBSEQUENT ACCESS @@ -663,21 +695,24 @@ PPPSD_MEDIA: ; ; PPPSD_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 + 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 (IY+PPPSD_LBA+0),L ; SAVE NEW LBA + LD (IY+PPPSD_LBA+1),H ; ... + LD (IY+PPPSD_LBA+2),E ; ... + LD (IY+PPPSD_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN ; ; ; PPPSD_CAP: - LD HL,PPPSD_BLKCNT ; GET BLOCK COUNT - CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL + LD A,PPPSD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL LD BC,512 ; 512 BYTES PER BLOCK - LD A,(PPPSD_STAT) ; GET CURRENT STATUS + LD A,(IY+PPPSD_STAT) ; GET CURRENT STATUS OR A ; SET FLAGS RET ; @@ -693,22 +728,16 @@ PPPSD_GEOM: LD E,16 ; SECTORS / TRACK = 16 RET ; DONE, A STILL HAS PPPSD_CAP STATUS ; -; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT -; UNIT IS SPECIFIED IN A -; -PPPSD_SELUNIT: - XOR A ; SIGNAL SUCCESS - RET ; DONE -; ; REINITIALIZE THE SD CARD ; PPPSD_INITCARD: - ; CLEAR ALL STATUS DATA - LD HL,PPPSD_UNITDATA - LD BC,PPPSD_UNITDATALEN - XOR A - CALL FILL - + ;; CLEAR ALL STATUS DATA + ;LD HL,PPPSD_UNITDATA + ;LD BC,PPPSD_UNITDATALEN + ;XOR A + ;CALL FILL +; + ; RESET INTERFACE, RETURN WITH NZ ON FAILURE #IF (PPPSDTRACE >= 3) CALL PPPSD_PRTPREFIX PRTS(" RESET$") @@ -728,7 +757,7 @@ PPPSD_INITCARD: OR A JR Z,PPPSD_INITCARD1 - + ; HANDLE ERROR CALL PPPSD_GETDSKSTAT ; GET FULL ERROR CODE ;JP PPPSD_ERRCMD ; HANDLE ERRORS @@ -755,10 +784,10 @@ PPPSD_INITCARD1: ; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED ; PPPSD_CHKCARD: - LD A,(PPPSD_STAT) ; GET STATUS + LD A,(IY+PPPSD_STAT) ; GET STATUS OR A ; SET FLAGS - CALL NZ,PPPSD_INITCARD ; INIT CARD IF NOT READY - RET ; RETURN WITH STATUS IN A + RET Z ; IF ALL GOOD, DONE + JP PPPSD_INITCARD ; OTHERWISE, REINIT ; ; ; @@ -802,7 +831,7 @@ PPPSD_GETTYPE: CALL PPP_SNDCMD ; SEND COMMAND RET NZ ; ABORT ON ERROR CALL PPP_GETBYTE ; GET DISK TYPE VALUE - LD (PPPSD_CARDTYPE),A ; SAVE IT + LD (IY+PPPSD_TYPE),A ; SAVE IT #IF (PPPSDTRACE >= 3) CALL PC_SPACE @@ -824,8 +853,9 @@ PPPSD_GETCAP: CALL PPP_SNDCMD ; SEND COMMAND RET NZ ; ABORT ON ERROR + LD A,PPPSD_MEDCAP ; OFFSET OF CAPACITY + CALL LDHLIYA ; HL := IY + A, REG A TRASHED LD B,4 ; GET 4 BYTES - LD HL,PPPSD_BLKCNT PPPSD_GETCAP1: CALL PPP_GETBYTE LD (HL),A @@ -834,7 +864,8 @@ PPPSD_GETCAP1: #IF (PPPSDTRACE >= 3) CALL PC_SPACE - LD HL,PPPSD_BLKCNT + LD A,PPPSD_MEDCAP ; OFFSET OF CAPACITY + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 CALL PRTHEX32 #ENDIF @@ -883,12 +914,14 @@ PPPSD_SENDBLK: #IF (PPPSDTRACE >= 3) CALL PC_SPACE - LD HL,HSTLBA + LD A,PPPSD_LBA ; OFFSET OF LBA + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 CALL PRTHEX32 #ENDIF - LD HL,HSTLBA + LD A,PPPSD_LBA ; OFFSET OF LBA + CALL LDHLIYA ; HL := IY + A, REG A TRASHED LD B,4 PPPSD_SENDBLK1: LD A,(HL) @@ -948,7 +981,8 @@ PPPSD_WRTPROT: JR PPPSD_ERR2 ; DO NOT UPDATE UNIT STATUS! ; PPPSD_ERR: - LD (PPPSD_STAT),A ; UPDATE STATUS + LD (IY+PPPSD_STAT),A ; UPDATE STATUS +; PPPSD_ERR2: #IF (PPPSDTRACE >= 2) CALL PPPSD_PRTSTAT @@ -1006,7 +1040,7 @@ PPPSD_PRTSTAT1: CALL PPPSD_PRTPREFIX ; PRINT UNIT PREFIX CALL PC_SPACE ; FORMATTING CALL WRITESTR - LD A,(PPPSD_STAT) + LD A,(IY+PPPSD_STAT) CP PPPSD_STCMDERR CALL Z,PPPSD_PRTSTAT2 POP HL @@ -1037,14 +1071,20 @@ PPPSD_PRTERRCODE: ; PRINT DIAGNONSTIC PREFIX ; PPPSD_PRTPREFIX: + PUSH AF CALL NEWLINE - PRTS("PPPSD0:$") + PRTS("PPPSD$") + LD A,(IY+PPPSD_DEV) ; GET CURRENT DEVICE NUM + ADD A,'0' + CALL COUT + CALL PC_COLON + POP AF RET ; ; PRINT THE CARD TYPE ; PPPSD_PRTTYPE: - LD A,(PPPSD_CARDTYPE) + LD A,(IY+PPPSD_TYPE) LD DE,PPPSD_STR_TYPEMMC CP PPPSD_TYPEMMC JR Z,PPPSD_PRTTYPE1 @@ -1089,16 +1129,10 @@ PPPSD_STR_TYPESDXC .TEXT "SDXC$" ; DATA STORAGE ;============================================================================= ; -PPPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS +PPPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS ; -PPPSD_UNIT .DB 0 PPPSD_DSKBUF .DW 0 ; -PPPSD_UNITDATA: -PPPSD_STAT .DB 0 PPPSD_DSKSTAT .DB 0 -PPPSD_ERRCODE .DB $00, $00, $00, $00 -PPPSD_CARDTYPE .DB 0 -PPPSD_BLKCNT .DB $00, $00, $00, $00 ; ASSUME 1GB (LITTLE ENDIAN DWORD) +PPPSD_ERRCODE .DW 0,0 PPPSD_CSDBUF .FILL 16,0 -PPPSD_UNITDATALEN .EQU $ - PPPSD_UNITDATA diff --git a/Source/HBIOS/prp.asm b/Source/HBIOS/prp.asm index f1065623..57c159d5 100644 --- a/Source/HBIOS/prp.asm +++ b/Source/HBIOS/prp.asm @@ -130,8 +130,8 @@ PRPCON_INIT: ;LD B,0 ; PHYSICAL UNIT IS ZERO ;LD C,CIODEV_PRPCON ; DEVICE TYPE ;LD DE,0 ; UNIT DATA BLOB ADDRESS - LD D,0 ; PHYSICAL UNIT IS ZERO - LD E,CIODEV_PRPCON ; DEVICE TYPE + LD D,0 ; PHYSICAL UNIT IS ZERO + LD E,CIODEV_PRPCON ; DEVICE TYPE LD BC,PRPCON_DISPATCH ; BC := DISPATCH ADDRESS CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED LD (HCB + HCB_CRTDEV),A ; SET OURSELVES AS THE CRT DEVICE @@ -219,18 +219,16 @@ PRPCON_QUERY: ; ; PRPCON_DEVICE: - LD D,CIODEV_PRPCON ; D := DEVICE TYPE - LD E,0 ; E := DEVICE NUM, ALWAYS 0 - LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA - XOR A ; SIGNAL SUCCESS + LD D,CIODEV_PRPCON ; D := DEVICE TYPE + LD E,0 ; E := DEVICE NUM, ALWAYS 0 + LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA + XOR A ; SIGNAL SUCCESS RET ; ;================================================================================================== ; PROPIO SD CARD DRIVER ;================================================================================================== ; -PRPSD_UNITCNT .EQU 1 -; ; IO PORT ADDRESSES ; PRPSD_DSKCMD .EQU PRP_IOBASE + 2 @@ -277,22 +275,76 @@ PRPSD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET PRPSD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR PRPSD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA ; +; PRPSD DEVICE CONFIGURATION +; +PRPSD_DEVCNT .EQU 1 ; ONE DEVICE SUPPORTED +PRPSD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS +; +PRPSD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +PRPSD_STAT .EQU 1 ; LAST STATUS (BYTE) +PRPSD_TYPE .EQU 2 ; DEVICE TYPE (BYTE) +PRPSD_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE) +PRPSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +PRPSD_LBA .EQU 8 ; OFFSET OF LBA (DWORD) +; +PRPSD_CFGTBL: + ; DEVICE 0 + .DB 0 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +; +#IF ($ - PRPSD_CFGTBL) != (PRPSD_DEVCNT * PRPSD_CFGSIZ) + .ECHO "*** INVALID PRPSD CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER +; ; SD CARD INITIALIZATION ; PRPSD_INIT: ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,0 ; PHYSICAL UNIT - LD C,DIODEV_PRPSD ; DEVICE TYPE - LD DE,0 ; UNIT DATA BLOB ADDRESS - CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD B,PRPSD_DEVCNT ; LOOP CONTROL + LD IY,PRPSD_CFGTBL ; START OF CFG TABLE +PRPSD_INIT0: + PUSH BC ; SAVE LOOP CONTROL + LD BC,PRPSD_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD BC,PRPSD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ PRPSD_INIT0 ; LOOP AS NEEDED +; + ; INITIALIZE INDIVIDUAL UNIT(S) AND DISPLAY DEVICE INVENTORY + LD B,PRPSD_DEVCNT ; INIT LOOP COUNTER TO DEVICE COUNT + LD IY,PRPSD_CFGTBL ; START OF CFG TABLE +PRPSD_INIT1: + PUSH BC ; SAVE LOOP COUNTER/INDEX + CALL PRPSD_INITUNIT ; INITIALIZE IT +#IF (PRPSDTRACE < 2) + CALL NZ,PRPSD_PRTSTAT ; IF ERROR, SHOW IT +#ENDIF + LD BC,PRPSD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE LOOP CONTROL + DJNZ PRPSD_INIT1 ; DECREMENT LOOP COUNTER AND LOOP AS NEEDED +; + RET ; DONE +; +; ; +PRPSD_INITUNIT: ; REINITIALIZE THE CARD HERE CALL PRPSD_INITCARD -#IF (PRPSDTRACE < 2) - JP NZ,PRPSD_PRTSTAT ; IF ERROR, SHOW IT -#ENDIF + RET NZ ; CALL PRPSD_PRTPREFIX ; @@ -302,7 +354,8 @@ PRPSD_INIT: ; ; PRINT STORAGE CAPACITY (BLOCK COUNT) PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL - LD HL,PRPSD_BLKCNT ; POINT TO BLOCK COUNT + LD A,PRPSD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 ; GET THE CAPACITY VALUE CALL PRTHEX32 ; PRINT HEX VALUE ; @@ -318,45 +371,27 @@ PRPSD_INIT: ; ; ; -PRPSD_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP PRPSD_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (PRPSD_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,PRPSD_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,PRPSD_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,PRPSD_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,PRPSD_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,PRPSD_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,PRPSD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,PRPSD_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,PRPSD_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,PRPSD_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,PRPSD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,PRPSD_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,PRPSD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +PRPSD_FNTBL: + .DW PRPSD_STATUS + .DW PRPSD_RESET + .DW PRPSD_SEEK + .DW PRPSD_READ + .DW PRPSD_WRITE + .DW PRPSD_VERIFY + .DW PRPSD_FORMAT + .DW PRPSD_DEVICE + .DW PRPSD_MEDIA + .DW PRPSD_DEFMED + .DW PRPSD_CAP + .DW PRPSD_GEOM +#IF (($ - PRPSD_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID PRPSD FUNCTION TABLE ***\n" +#ENDIF ; PRPSD_VERIFY: PRPSD_FORMAT: PRPSD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; INVALID SUB-FUNCTION ; ; ; @@ -394,7 +429,7 @@ PRPSD_IO: PRPSD_IO1: PUSH BC ; SAVE COUNTERS - + #IF (PRPSDTRACE >= 3) CALL PRPSD_PRTPREFIX #ENDIF @@ -402,13 +437,11 @@ PRPSD_IO1: LD HL,(PRPSD_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS CALL JPHL ; ... AND CALL IT JR NZ,PRPSD_IO2 ; BAIL OUT ON ERROR - - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,PRPSD_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,PRPSD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -439,13 +472,13 @@ PRPSD_RDSEC: LD A,PRPSD_CMDREAD ; READ COMMAND CALL PRPSD_SNDCMD ; ... AND SEND COMMAND RET NZ ; BAIL OUT ON ERROR - + LD C,PRPSD_DSKIO ; SET PORT LD B,0 ; SET LOOP COUNTER FOR 256 ITER LD HL,(PRPSD_DSKBUF) ; SET BUF ADR INIR ; READ 256 BYTES INIR ; ... AND AGAIN FOR 512 TOTAL - + XOR A ; SIGNAL SUCCESS RET ; @@ -476,30 +509,30 @@ PRPSD_WRSEC: LD A,PRPSD_CMDWRITE ; WRITE COMMAND CALL PRPSD_SNDCMD ; SEND IT RET NZ ; BAIL OUT ON ERROR - + XOR A ; SIGNAL SUCCESS RET ; RETURN ; ; ; PRPSD_STATUS: - LD A,(PRPSD_STAT) ; GET THE CURRENT STATUS + LD A,(IY+PRPSD_STAT) ; GET STATUS OF SELECTED DEVICE OR A RET ; ; ; PRPSD_RESET: - XOR A ; ALWAYS OK + XOR A ; ALWAYS OK RET ; ; ; PRPSD_DEVICE: - LD D,DIODEV_PRPSD ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD - XOR A ; SIGNAL SUCCESS + LD D,DIODEV_PRPSD ; D := DEVICE TYPE + LD E,(IY+PRPSD_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD + XOR A ; SIGNAL SUCCESS RET ; ; PRPSD_SENSE @@ -518,21 +551,24 @@ PRPSD_MEDIA: ; ; PRPSD_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 + 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 (IY+PRPSD_LBA+0),L ; SAVE NEW LBA + LD (IY+PRPSD_LBA+1),H ; ... + LD (IY+PRPSD_LBA+2),E ; ... + LD (IY+PRPSD_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN ; ; ; PRPSD_CAP: - LD HL,PRPSD_BLKCNT ; POINT TO BLOCK COUNT - CALL LD32 ; GET THE CURRENT CAPACITY TO DE:HL + LD A,PRPSD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL LD BC,512 ; 512 BYTES PER BLOCK - LD A,(PRPSD_STAT) ; GET CURRENT STATUS + LD A,(IY+PRPSD_STAT) ; GET STATUS OR A ; SET FLAGS RET ; @@ -546,24 +582,16 @@ PRPSD_GEOM: 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 - XOR A ; SIGNAL SUCCESS RET ; DONE, A STILL HAS PRPSD_CAP STATUS ; -; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT -; UNIT IS SPECIFIED IN A -; -PRPSD_SELUNIT: - XOR A ; SIGNAL SUCCESS - RET ; DONE -; ; ; PRPSD_INITCARD: - ; CLEAR ALL STATUS DATA - LD HL,PRPSD_UNITDATA - LD BC,PRPSD_UNITDATALEN - XOR A - CALL FILL + ;; CLEAR ALL STATUS DATA + ;LD HL,PRPSD_UNITDATA + ;LD BC,PRPSD_UNITDATALEN + ;XOR A + ;CALL FILL ; ; RESET INTERFACE, RETURN WITH NZ ON FAILURE #IF (PRPSDTRACE >= 3) @@ -607,10 +635,10 @@ PRPSD_INITCARD: ; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED ; PRPSD_CHKCARD: - LD A,(PRPSD_STAT) ; GET STATUS + LD A,(IY+PRPSD_STAT) ; GET CURRENT STATUS OR A ; SET FLAGS RET Z ; IF ALL GOOD, DONE - JP NZ,PRPSD_INITCARD ; OTHERWISE, REINIT + JP PRPSD_INITCARD ; OTHERWISE, REINIT ; ; ; @@ -661,7 +689,7 @@ PRPSD_GETTYPE: RET NZ IN A,(PRPSD_DSKIO) - LD (PRPSD_CARDTYPE),A + LD (IY+PRPSD_TYPE),A #IF (PRPSDTRACE >= 3) CALL PC_SPACE @@ -684,12 +712,14 @@ PRPSD_GETCAP: LD C,PRPSD_DSKIO ; FROM PROPIO DISK PORT LD B,4 ; 4 BYTES - LD HL,PRPSD_BLKCNT ; TO PRPSD_BLKCNT + LD A,PRPSD_MEDCAP ; ... OF CAPACITY + CALL LDHLIYA ; HL := IY + A, REG A TRASHED INIR #IF (PRPSDTRACE >= 3) CALL PC_SPACE - LD HL,PRPSD_BLKCNT + LD A,PRPSD_MEDCAP ; ... OF CAPACITY + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 CALL PRTHEX32 #ENDIF @@ -817,13 +847,15 @@ PRPSD_SETBLK: #IF (PRPSDTRACE >= 3) CALL PC_SPACE - LD HL,HSTLBA + LD A,PRPSD_LBA ; OFFSET OF LBA + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 CALL PRTHEX32 #ENDIF LD C,PRPSD_DSKIO ; SEND TO DISK I/O PORT LD B,4 ; 4 BYTES - LD HL,HSTLBA ; OF LBA + LD A,PRPSD_LBA ; OFFSET OF LBA + CALL LDHLIYA ; HL := IY + A, REG A TRASHED OTIR RET ; @@ -874,12 +906,13 @@ PRPSD_WRTPROT: JR PRPSD_ERR2 ; DO NOT UPDATE UNIT STATUS! ; PRPSD_ERR: - LD (PRPSD_STAT),A ; UPDATE STATUS + LD (IY+PRPSD_STAT),A ; UPDATE STATUS +; PRPSD_ERR2: #IF (PRPSDTRACE >= 2) CALL PRPSD_PRTSTAT #ENDIF - OR A ; SET FLAGS + OR A ; SET FLAGS RET ; ; @@ -932,7 +965,7 @@ PRPSD_PRTSTAT1: CALL PRPSD_PRTPREFIX ; PRINT UNIT PREFIX CALL PC_SPACE ; FORMATTING CALL WRITESTR - LD A,(PRPSD_STAT) + LD A,(IY+PRPSD_STAT) CP PRPSD_STCMDERR CALL Z,PRPSD_PRTSTAT2 POP HL @@ -963,28 +996,34 @@ PRPSD_PRTERRCODE: ; PRINT DIAGNONSTIC PREFIX ; PRPSD_PRTPREFIX: + PUSH AF CALL NEWLINE - PRTS("PRPSD0:$") + PRTS("PRPSD$") + LD A,(IY+PRPSD_DEV) ; GET CURRENT DEVICE NUM + ADD A,'0' + CALL COUT + CALL PC_COLON + POP AF RET ; ; PRINT THE CARD TYPE ; PRPSD_PRTTYPE: - LD A,(PRPSD_CARDTYPE) + LD A,(IY+PRPSD_TYPE) LD DE,PRPSD_STR_TYPEMMC CP PRPSD_TYPEMMC - JR Z,PRPSD_INIT1 + JR Z,PRPSD_PRTTYPE1 LD DE,PRPSD_STR_TYPESDSC CP PRPSD_TYPESDSC - JR Z,PRPSD_INIT1 + JR Z,PRPSD_PRTTYPE1 LD DE,PRPSD_STR_TYPESDHC CP PRPSD_TYPESDHC - JR Z,PRPSD_INIT1 + JR Z,PRPSD_PRTTYPE1 LD DE,PRPSD_STR_TYPESDXC CP PRPSD_TYPESDXC - JR Z,PRPSD_INIT1 + JR Z,PRPSD_PRTTYPE1 LD DE,PRPSD_STR_TYPEUNK -PRPSD_INIT1: +PRPSD_PRTTYPE1: JP WRITESTR ; ;============================================================================= @@ -1005,11 +1044,11 @@ PRPSD_STR_STRDYTO .TEXT "READY TIMEOUT$" PRPSD_STR_STINITTO .TEXT "INITIALIZATION TIMEOUT$" PRPSD_STR_STCMDTO .TEXT "COMMAND TIMEOUT$" PRPSD_STR_STCMDERR .TEXT "COMMAND ERROR$" -PRPSD_STR_STDATAERR .TEXT "DATA ERROR$" +PRPSD_STR_STDATAERR .TEXT "DATA ERROR$" PRPSD_STR_STDATATO .TEXT "DATA TIMEOUT$" PRPSD_STR_STCRCERR .TEXT "CRC ERROR$" -PRPSD_STR_STNOMEDIA .TEXT "NO MEDIA$" -PRPSD_STR_STWRTPROT .TEXT "WRITE PROTECTED$" +PRPSD_STR_STNOMEDIA .TEXT "NO MEDIA$" +PRPSD_STR_STWRTPROT .TEXT "WRITE PROTECTED$" PRPSD_STR_STUNK .TEXT "UNKNOWN$" ; PRPSD_STR_TYPEUNK .TEXT "UNK$" @@ -1022,22 +1061,16 @@ PRPSD_STR_TYPESDXC .TEXT "SDXC$" ; DATA STORAGE ;============================================================================= ; -PRP_FWVER .DB $00, $00, $00, $00 ; MMNNBBB (M=MAJOR, N=MINOR, B=BUILD) +PRP_FWVER .DW 0,0 ; MMNNBBB (M=MAJOR, N=MINOR, B=BUILD) ; -PRPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS +PRPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS ; -PRPSD_UNIT .DB 0 PRPSD_DSKBUF .DW 0 ; -PRPSD_UNITDATA: -PRPSD_STAT .DB 0 PRPSD_DSKSTAT .DB 0 -PRPSD_ERRCODE .DB $00, $00, $00, $00 -PRPSD_CARDTYPE .DB 0 -PRPSD_BLKCNT .DB $00, $00, $00, $00 ; ASSUME 1GB (LITTLE ENDIAN DWORD) +PRPSD_ERRCODE .DW 0,0 PRPSD_CSDBUF .FILL 16,0 -PRPSD_UNITDATALEN .EQU $ - PRPSD_UNITDATA ; PRPSD_CMD .DB 0 ; -PRPSD_TIMEOUT .DW $0000 ; FIX: MAKE THIS CPU SPEED RELATIVE +PRPSD_TIMEOUT .DW $0000 ; FIX: MAKE THIS CPU SPEED RELATIVE diff --git a/Source/HBIOS/rf.asm b/Source/HBIOS/rf.asm index 60a37e8e..6652790b 100644 --- a/Source/HBIOS/rf.asm +++ b/Source/HBIOS/rf.asm @@ -15,98 +15,102 @@ RF_AL .EQU 1 RF_AH .EQU 2 RF_ST .EQU 3 ; +; MD DEVICE CONFIGURATION +; +RF_DEVCNT .EQU RFCNT ; NUMBER OF RF DEVICES SUPPORTED +RF_CFGSIZ .EQU 6 ; SIZE OF CFG TBL ENTRIES +; +RF_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +RF_STAT .EQU 1 ; OFFSET OF STATUS (BYTE) +RF_LBA .EQU 2 ; OFFSET OF LBA (DWORD) +; +; DEVICE CONFIG TABLE (RAM DEVICE FIRST TO MAKE IT ALWAYS FIRST DRIVE) +; +RF_CFGTBL: + ; DEVICE 0 ($A0) + .DB 0 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DW 0,0 ; CURRENT LBA +#IF (RF_DEVCNT >= 2) + ; DEVICE 1 ($A4) + .DB 1 ; DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DW 0,0 ; CURRENT LBA +#ENDIF +; +#IF ($ - RF_CFGTBL) != (RF_DEVCNT * RF_CFGSIZ) + .ECHO "*** INVALID RF CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER +; ; ; RF_INIT: CALL NEWLINE ; FORMATTING PRTS("RF: UNITS=$") - LD A,RFCNT + LD A,RF_DEVCNT CALL PRTDECB ; -; SETUP THE DISPATCH TABLE ENTRIES +; SETUP THE DIO TABLE ENTRIES ; -; -; SETUP THE DISPATCH TABLE ENTRIES -; - LD B,RFCNT ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX + LD B,RF_DEVCNT ; LOOP CONTROL + LD IY,RF_CFGTBL ; START OF CFG TABLE 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 + PUSH BC ; SAVE LOOP CONTROL + LD BC,RF_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD BC,RF_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ RF_INIT0 ; LOOP AS NEEDED +; + XOR A ; INIT SUCCEEDED + RET ; RETURN +; +; +; +RF_FNTBL: + .DW RF_STATUS + .DW RF_RESET + .DW RF_SEEK + .DW RF_READ + .DW RF_WRITE + .DW RF_VERIFY + .DW RF_FORMAT + .DW RF_DEVICE + .DW RF_MEDIA + .DW RF_DEFMED + .DW RF_CAP + .DW RF_GEOM +#IF (($ - RF_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID MD FUNCTION TABLE ***\n" +#ENDIF ; RF_VERIFY: RF_FORMAT: RF_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; INVALID SUB-FUNCTION ; ; ; RF_STATUS: - XOR A ; STATUS ALWAYS OK + XOR A ; STATUS ALWAYS OK RET ; ; ; RF_RESET: - XOR A ; ALWAYS OK + 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 + LD HL,$2000 ; 8192 BLOCKS OF 512 BYTES XOR A RET ; @@ -125,33 +129,35 @@ RF_GEOM: ; ; 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 + LD D,DIODEV_RF ; D := DEVICE TYPE + LD E,(IY+RF_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%00110000 ; C := ATTRIBUTES, NON-REMOVALBE RAM FLOPPY + XOR A ; SIGNAL SUCCESS RET ; ; ; RF_MEDIA: - LD E,MID_RF ; RAM FLOPPY 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: +; +; +; +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 + LD (IY+RF_LBA+0),L ; SAVE NEW LBA + LD (IY+RF_LBA+1),H ; ... + LD (IY+RF_LBA+2),E ; ... + LD (IY+RF_LBA+3),D ; ... XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; -; -; +; +; RF_READ: LD BC,RF_RDSEC ; GET ADR OF SECTOR READ FUNC LD (RF_RWFNADR),BC ; SAVE IT AS PENDING IO FUNC @@ -183,12 +189,11 @@ RF_RW1: LD HL,(RF_RWFNADR) ; GET PENDING IO FUNCTION ADDRESS CALL JPHL ; ... AND CALL IT JR NZ,RF_RW2 ; IF ERROR, SKIP INCREMENT - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,MD_LBA ; OFFSET OF LBA VALUE + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,RF_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -235,8 +240,8 @@ RF_WRSEC: ; ; RF_SETIO: - LD A,(RF_UNIT) ; GET DEVICE/UNIT - AND $0F ; ISOLATE UNIT NUM + LD A,(IY+RF_DEV) ; GET DEVICE NUM + OR A ; SET FLAGS JR NZ,RF_SETIO1 LD A,RF_U0IO JR RF_SETIO3 @@ -246,7 +251,7 @@ RF_SETIO1: LD A,RF_U1IO JR RF_SETIO3 RF_SETIO2: - CALL PANIC ; INVALID UNIT + CALL PANIC ; INVALID UNIT RF_SETIO3: LD (RF_IO),A RET @@ -257,9 +262,9 @@ RF_SETADR: LD A,(RF_IO) OR RF_AL LD C,A - LD A,(HSTLBALO) + LD A,(IY+RF_LBA+0) OUT (C),A - LD A,(HSTLBALO+1) + LD A,(IY+RF_LBA+1) INC C OUT (C),A RET @@ -280,5 +285,4 @@ RF_CHKWP: RF_IO .DB 0 RF_RWFNADR .DW 0 ; -RF_UNIT .DB 0 RF_DSKBUF .DW 0 diff --git a/Source/HBIOS/sd.asm b/Source/HBIOS/sd.asm index 0c3e82ae..b7a192db 100644 --- a/Source/HBIOS/sd.asm +++ b/Source/HBIOS/sd.asm @@ -54,33 +54,33 @@ ; === R1 RESPONSE === ; ALL COMMAND RESPONSES START WITH R1 ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +---+---+---+---+---+---+---+---+ ; | 0 | X | X | X | X | X | X | X | ; +---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -; | | | | | | | -; | | | | | | +--- IDLE -; | | | | | +------- ERASE RESET -; | | | | +----------- ILLEGAL COMMAND -; | | | +--------------- COM CRC ERROR -; | | +------------------- ERASE SEQUENCE ERROR -; | +----------------------- ADDRESS ERROR +; | | | | | | | +; | | | | | | +--- IDLE +; | | | | | +------- ERASE RESET +; | | | | +----------- ILLEGAL COMMAND +; | | | +--------------- COM CRC ERROR +; | | +------------------- ERASE SEQUENCE ERROR +; | +----------------------- ADDRESS ERROR ; +--------------------------- PARAMETER ERROR ; ; === DATA ERROR TOKEN === ; -; 7 6 5 4 3 2 1 0 +; 7 6 5 4 3 2 1 0 ; +---+---+---+---+---+---+---+---+ ; | 0 | 0 | 0 | 0 | X | X | X | X | ; +---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -; | | | | -; | | | +--- ERROR - GENERAL OR UNKNOWN ERROR -; | | +------- CC ERROR - INTERNAL CARD CONTROLER ERROR -; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA -; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD +; | | | | +; | | | +--- ERROR - GENERAL OR UNKNOWN ERROR +; | | +------- CC ERROR - INTERNAL CARD CONTROLER ERROR +; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA +; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD ; #IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD -SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE??? SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC @@ -91,7 +91,7 @@ SD_DO .EQU %10000000 ; RTC:7 IS DATA OUT (CARD -> CPU) #ENDIF ; #IF (SDMODE == SDMODE_N8) ; UNMODIFIED N8-2511 -SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE??? SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC @@ -102,7 +102,7 @@ SD_DO .EQU %01000000 ; RTC:6 IS DATA OUT (CARD -> CPU) #ENDIF ; #IF (SDMODE == SDMODE_CSIO) ; N8-2312 -SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE SD_CS .EQU %00000100 ; RTC:2 IS SELECT @@ -111,7 +111,7 @@ SD_TRDR .EQU Z180_TRDR #ENDIF ; #IF (SDMODE == SDMODE_PPI) ; PPISD -SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_PPIBASE .EQU PPIBASE ; BASE IO PORT FOR PPI SD_PPIB .EQU PPIBASE + 1 ; PPI PORT B (INPUT: DOUT) SD_PPIC .EQU PPIBASE + 2 ; PPI PORT C (OUTPUT: CS, CLK, DIN) @@ -126,7 +126,7 @@ SD_DO .EQU %10000000 ; PPIB:7 IS DATA OUT (CARD -> CPU) #ENDIF ; #IF (SDMODE == SDMODE_UART) -SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU SIO_MCR ; UART MCR PORT (OUTPUT: CS, CLK, DIN) SD_OPRDEF .EQU %00001100 ; QUIESCENT STATE SD_INPREG .EQU SIO_MSR ; INPUT REGISTER IS MSR @@ -137,7 +137,7 @@ SD_DO .EQU %00100000 ; UART MSR:5 IS DATA OUT (CARD -> CPU) #ENDIF ; #IF (SDMODE == SDMODE_DSD) ; DUAL SD -SD_UNITCNT .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU $08 ; DEDICATED OPERATIONS REGISTER SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE SD_INPREG .EQU SD_OPRREG ; INPUT REGISTER IS OPRREG @@ -150,7 +150,7 @@ SD_DO .EQU %00000001 ; RTC:0 IS DATA OUT (CARD -> CPU) #ENDIF ; #IF (SDMODE == SDMODE_MK4) ; MARK IV (CSIO STYLE INTERFACE) -SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) +SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU MK4_SD ; DEDICATED MK4 SDCARD REGISTER SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE SD_CS .EQU %00000100 ; SELECT ACTIVE @@ -198,16 +198,42 @@ SD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET SD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR SD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA ; -; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN SD_UNITDATA) -; SEE SD_UNITDATA IN DATA STORAGE BELOW -; -SD_STAT .EQU 0 ; LAST STATUS (1 BYTE) -SD_TYPE .EQU 1 ; CARD TYPE (1 BYTE) -SD_CAPACITY .EQU 2 ; CARD CAPACITY (1 DWORD/4 BYTES) +; IDE DEVICE CONFIGURATION +; +SD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS +; +SD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +SD_STAT .EQU 1 ; LAST STATUS (BYTE) +SD_TYPE .EQU 2 ; DEVICE TYPE (BYTE) +SD_FLAGS .EQU 3 ; FLAG BITS (BYTE) +SD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +SD_LBA .EQU 8 ; OFFSET OF LBA (DWORD) +; +SD_CFGTBL: + ; DEVICE 0, PRIMARY MASTER + .DB 0 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#IF (SD_DEVCNT >= 2) + ; DEVICE 1, PRIMARY SLAVE + .DB 1 ; DRIVER DEVICE NUMBER + .DB 0 ; DEVICE STATUS + .DB 0 ; DEVICE TYPE + .DB 0 ; FLAGS BYTE + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#ENDIF ; -; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA +#IF ($ - SD_CFGTBL) != (SD_DEVCNT * SD_CFGSIZ) + .ECHO "*** INVALID SD CONFIG TABLE ***\n" +#ENDIF ; -#DEFINE SD_DPTR(FIELD) CALL SD_DPTRIMP \ .DB FIELD + .DB $FF ; END MARKER ; ;============================================================================= ; INITIALIZATION ENTRY POINT @@ -216,29 +242,6 @@ SD_CAPACITY .EQU 2 ; CARD CAPACITY (1 DWORD/4 BYTES) SD_INIT: CALL NEWLINE ; FORMATTING PRTS("SD:$") - CALL SD_PROBE ; CHECK FOR HARDWARE - JR Z,SD_INIT00 ; CONTINUE IF PRESENT -; - ; HARDWARE NOT PRESENT - PRTS(" NOT PRESENT$") - OR $FF ; SIGNAL FAILURE - RET -; -SD_INIT00: -; -; SETUP THE DISPATCH TABLE ENTRIES -; - LD B,SD_UNITCNT ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX -SD_INIT0: - PUSH BC ; SAVE LOOP CONTROL - LD B,C ; PHYSICAL UNIT - LD C,DIODEV_SD ; 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 SD_INIT0 ; LOOP UNTIL DONE ; #IF (SDMODE == SDMODE_JUHA) PRTS(" MODE=JUHA$") @@ -313,32 +316,53 @@ SD_INIT0: CALL PRTHEXBYTE #ENDIF ; - PRTS(" UNITS=$") - LD A,SD_UNITCNT + CALL SD_PROBE ; CHECK FOR HARDWARE + JR Z,SD_INIT00 ; CONTINUE IF PRESENT +; + ; HARDWARE NOT PRESENT + PRTS(" NOT PRESENT$") + OR $FF ; SIGNAL FAILURE + RET +; +SD_INIT00: +; +; SETUP THE DISPATCH TABLE ENTRIES +; + PRTS(" DEVICES=$") + LD A,SD_DEVCNT CALL PRTDECB +; +; SETUP THE DISPATCH TABLE ENTRIES +; + LD B,SD_DEVCNT ; LOOP CONTROL + LD IY,SD_CFGTBL ; START OF CFG TABLE +SD_INIT0: + PUSH BC ; SAVE LOOP CONTROL + LD BC,SD_FNTBL ; BC := FUNC TABLE ADR + PUSH IY ; CFG ENTRY POINTER + POP DE ; COPY TO DE + CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED + LD BC,SD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE BC + DJNZ SD_INIT0 ; LOOP AS NEEDED ; ; INITIALIZE THE SD INTERFACE NOW CALL SD_SETUP ; DO HARDWARE SETUP/INIT RET NZ ; ABORT ON ERROR ; - ; CLEAR OUT ALL DATA (FOR ALL UNITS) - LD HL,SD_UNITDATA - LD BC,SD_DATALEN - XOR A - CALL FILL -; - ; INITIALIZE INDIVIDUAL UNIT(S) - LD B,SD_UNITCNT ; INIT LOOP COUNTER TO UNIT COUNT - LD C,0 ; INIT UNIT INDEX TO ZERO + ; INITIALIZE INDIVIDUAL UNIT(S) AND DISPLAY DEVICE INVENTORY + LD B,SD_DEVCNT ; INIT LOOP COUNTER TO DEVICE COUNT + LD IY,SD_CFGTBL ; START OF CFG TABLE SD_INIT1: PUSH BC ; SAVE LOOP COUNTER/INDEX - LD A,C ; UNIT ID TO A CALL SD_INITUNIT ; INITIALIZE IT #IF (SDTRACE < 2) CALL NZ,SD_PRTSTAT ; IF ERROR, SHOW IT #ENDIF - POP BC ; RESTORE LOOP COUNTER/INDEX - INC C ; INCREMENT UNIT INDEX + LD BC,SD_CFGSIZ ; SIZE OF CFG ENTRY + ADD IY,BC ; BUMP IY TO NEXT ENTRY + POP BC ; RESTORE LOOP CONTROL DJNZ SD_INIT1 ; DECREMENT LOOP COUNTER AND LOOP AS NEEDED ; RET ; DONE @@ -346,8 +370,6 @@ SD_INIT1: ; INITIALIZE UNIT DESIGNATED IN ACCUM ; SD_INITUNIT - LD (SD_UNIT),A ; SET CURRENT UNIT -; CALL SD_SELUNIT ; SELECT UNIT RET NZ ; ABORT ON ERROR ; @@ -357,9 +379,7 @@ SD_INITUNIT CALL SD_PRTPREFIX ; ; PRINT CARD TYPE - PRTS(" TYPE=$") - SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF - LD A,(HL) + LD A,(IY+SD_TYPE) ; GET CARD TYPE VALUE TO A LD DE,SD_STR_TYPEMMC CP SD_TYPEMMC JR Z,SD_INITUNIT1 @@ -406,23 +426,25 @@ SD_INITUNIT2: INC HL ; POINT TO NEXT BYTE DJNZ SD_INITUNIT2 ; LOOP FOR ALL 5 BYTES ; - PRTS(" BLOCKS=0x$") ; LABEL - SD_DPTR(SD_CAPACITY) ; SET HL TO ADR OF CARD CAPACITY, TRASHES AF - CALL LD32 ; GET THE VALUE - CALL PRTHEX32 ; PRINT IT -; - ; CONVERT VALUE TO MEGABYTES AND PRINT IT - LD B,11 ; SHIFT 11 BITS TO CONVERT FROM - CALL SRL32 ; ... 512 BYTE BLOCKS TO MEGABYTES -; - PRTS(" SIZE=$") ; PRINT LABEL - CALL PRTDEC ; PRINT VALUE + ; PRINT STORAGE CAPACITY (BLOCK COUNT) + PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL + LD A,SD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CAPACITY VALUE + CALL PRTHEX32 ; PRINT HEX VALUE +; + ; PRINT STORAGE SIZE IN MB + PRTS(" SIZE=$") ; PRINT FIELD LABEL + LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB + CALL SRL32 ; RIGHT SHIFT + CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED) PRTS("MB$") ; PRINT SUFFIX ; ; CHECK FOR WRITE PROTECT AND NOTIFY USER IF SO CALL SD_CHKWP ; WRITE PROTECTED? RET Z ; IF NOT, DONE PRTS(" WP$") ; NOTIFY USER +; RET ; DONE ; ;---------------------------------------------------------------------- @@ -457,48 +479,30 @@ SD_PROBE: RET ; AND RETURN ; ;============================================================================= -; FUNCTION DISPATCH ENTRY POINT +; DRIVER FUNCTION TABLE ;============================================================================= ; -SD_DISPATCH: - ; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER - LD A,C ; DEVICE/UNIT FROM C - AND $0F ; ISOLATE UNIT NUM - CP SD_UNITCNT - CALL NC,PANIC ; PANIC IF TOO HIGH - LD (SD_UNIT),A ; SAVE IT -; - ; DISPATCH ACCORDING TO DISK SUB-FUNCTION - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,SD_STATUS ; SUB-FUNC 0: STATUS - DEC A - JP Z,SD_RESET ; SUB-FUNC 1: RESET - DEC A - JP Z,SD_SEEK ; SUB-FUNC 2: SEEK - DEC A - JP Z,SD_READ ; SUB-FUNC 3: READ SECTORS - DEC A - JP Z,SD_WRITE ; SUB-FUNC 4: WRITE SECTORS - DEC A - JP Z,SD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS - DEC A - JP Z,SD_FORMAT ; SUB-FUNC 6: FORMAT TRACK - DEC A - JP Z,SD_DEVICE ; SUB-FUNC 7: DEVICE REPORT - DEC A - JP Z,SD_MEDIA ; SUB-FUNC 8: MEDIA REPORT - DEC A - JP Z,SD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA - DEC A - JP Z,SD_CAP ; SUB-FUNC 10: REPORT CAPACITY - DEC A - JP Z,SD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY +SD_FNTBL: + .DW SD_STATUS + .DW SD_RESET + .DW SD_SEEK + .DW SD_READ + .DW SD_WRITE + .DW SD_VERIFY + .DW SD_FORMAT + .DW SD_DEVICE + .DW SD_MEDIA + .DW SD_DEFMED + .DW SD_CAP + .DW SD_GEOM +#IF (($ - SD_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID IDE FUNCTION TABLE ***\n" +#ENDIF ; SD_VERIFY: SD_FORMAT: SD_DEFMED: - CALL PANIC ; INVALID SUB-FUNCTION + CALL PANIC ; INVALID SUB-FUNCTION ; ; ; @@ -516,9 +520,11 @@ SD_WRITE: ; SD_IO: LD (SD_CMDVAL),A ; SAVE THE SD CARD COMMAND + LD (SD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS LD A,E ; GET BLOCK COUNT REQUESTED LD (SD_BLKCNT),A ; ... AND SAVE IT - LD (SD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + OR A ; SET FLAGS + RET Z ; ZERO SECTOR I/O, RETURN W/ E=0 & A=0 #IF (IDETRACE == 1) LD HL,SD_PRTERR ; SET UP SD_PRTERR PUSH HL ; ... TO FILTER ALL EXITS @@ -541,12 +547,11 @@ SD_IO1: LD C,A ; ... AND PUT IN C CALL SD_SECTIO ; DO SECTOR I/O JR NZ,SD_IO2 ; IF ERROR, SKIP INCREMENT - LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA - PUSH HL ; SAVE POINTER - CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL - CALL INC32 ; INCREMENT LBA FOR NEXT I/O - POP BC ; RECOVER LBA POINTER INTO BC - CALL ST32 ; AND SAVE IT + ; INCREMENT LBA + LD A,SD_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE + ; INCREMENT DMA LD HL,SD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR INC (HL) ; BUMP DMA BY INC (HL) ; ... 512 BYTES @@ -565,9 +570,8 @@ SD_IO3: ; ; SD_STATUS: - ; RETURN UNIT STATUS - SD_DPTR(SD_STAT) ; HL := ADR OF STATUS, AF TRASHED - LD A,(HL) ; GET STATUS OF SELECTED UNIT + ; RETURN DEVICE STATUS + LD A,(IY+SD_STAT) ; GET STATUS OF SELECTED DEVICE OR A ; SET FLAGS RET ; AND RETURN ; @@ -586,10 +590,10 @@ SD_RESET: ; ; SD_DEVICE: - LD D,DIODEV_SD ; D := DEVICE TYPE - LD E,C ; E := PHYSICAL UNIT - LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD - XOR A ; SIGNAL SUCCESS + LD D,DIODEV_SD ; D := DEVICE TYPE + LD E,(IY+SD_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD + XOR A ; SIGNAL SUCCESS RET ; ; @@ -599,10 +603,10 @@ SD_MEDIA: OR A ; SET FLAGS JR Z,SD_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA ; - SD_DPTR(SD_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + ; GET CURRENT STATUS + LD A,(IY+SD_STAT) ; GET STATUS OR A ; SET FLAGS - JR NZ,SD_MEDIA1 ; ERROR ACTIVE, TO RIGHT TO RESET + JR NZ,SD_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET ; ; USE SEND_CSD TO CHECK CARD CALL SD_SELUNIT ; SET CUR UNIT @@ -620,8 +624,7 @@ SD_MEDIA1: CALL SD_RESET ; RESET CARD ; SD_MEDIA2: - SD_DPTR(SD_STAT) ; HL := ADR OF STATUS, AF TRASHED - LD A,(HL) ; GET STATUS OF SELECTED UNIT + LD A,(IY+SD_STAT) ; GET STATUS OR A ; SET FLAGS LD D,0 ; NO MEDIA CHANGE DETECTED LD E,MID_HD ; ASSUME WE ARE OK @@ -636,19 +639,21 @@ SD_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 + LD (IY+SD_LBA+0),L ; SAVE NEW LBA + LD (IY+SD_LBA+1),H ; ... + LD (IY+SD_LBA+2),E ; ... + LD (IY+SD_LBA+3),D ; ... XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ; ; SD_CAP: - SD_DPTR(SD_STAT) ; POINT TO UNIT STATUS - LD A,(HL) ; GET STATUS + LD A,(IY+SD_STAT) ; GET STATUS PUSH AF ; SAVE IT - SD_DPTR(SD_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT - CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL + LD A,SD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL LD BC,512 ; 512 BYTES PER BLOCK POP AF ; RECOVER STATUS OR A ; SET FLAGS @@ -674,11 +679,11 @@ SD_GEOM: ; SD_INITCARD: ; - ; CLEAR OUT UNIT SPECIFIC DATA - SD_DPTR(0) ; SET HL TO START OF UNIT DATA - LD BC,SD_UNITDATALEN - XOR A - CALL FILL + ;; CLEAR OUT UNIT SPECIFIC DATA + ;SD_DPTR(0) ; SET HL TO START OF UNIT DATA + ;LD BC,SD_UNITDATALEN + ;XOR A + ;CALL FILL ; CALL SD_CHKCD ; CHECK CARD DETECT JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO @@ -697,9 +702,7 @@ SD_INITCARD1: RET NZ ; ABORT IF FAILED ; SD_INITCARD2: - SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF - LD A,SD_TYPESDSC ; ASSUME SDSC CARD TYPE - LD (HL),A ; SAVE IT + LD (IY+SD_TYPE),SD_TYPESDSC ; ASSUME SDSC CARD TYPE ; ; CMD8 IS REQUIRED FOR V2 CARDS. FAILURE HERE IS OK AND ; JUST MEANS THAT IT IS A V1 CARD @@ -822,8 +825,7 @@ SD_INITCARD4A: LD C,SD_TYPESDXC ; OTHERWISE, THIS IS SDXC CARD ; SD_INITCARD5: - SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF - LD (HL),C ; SAVE IT + LD (IY+SD_TYPE),C ; SAVE CARD TYPE #IF (SDTRACE >= 3) CALL SD_PRTPREFIX @@ -832,7 +834,7 @@ SD_INITCARD5: LD A,C CALL PRTHEXBYTE #ENDIF - +; ; SET OUR DESIRED BLOCK LENGTH (512 BYTES) LD A,SD_CMD_SET_BLOCKLEN ; SET_BLOCKLEN CALL SD_INITCMD ; SETUP COMMAND BUFFER @@ -874,8 +876,7 @@ SD_INITCARD5: #ENDIF ; ; GET SIZE OF DEVICE IN BLOCKS - SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF - LD A,(HL) ; GET CARD TYPE + LD A,(IY+SD_TYPE) ; GET CARD TYPE OR A ; SET FLAGS CALL Z,PANIC ; PANIC IF CARD TYPE UNKNOWN CP SD_TYPESDHC ; COMPARE TO SDHC (V2) @@ -949,19 +950,19 @@ SD_INITCARD8: ; GET SIZE FOR V2 CARD CALL SLA32 ; SHIFT THE 32 BIT VALUE JR SD_INITCARD9 ; CONTINUE ; -SD_INITCARD9: ; COMMON CODE TO RECORD RESULTANT SIZE (IN DE:HL) - ; SAVE DERIVED CAPACITY VALUE +SD_INITCARD9: + ; SAVE DERIVED CAPACITY VALUE IN DE:HL PUSH HL ; SAVE HL - SD_DPTR(SD_CAPACITY) ; SET HL TO ADR OF CARD CAPACITY, TRASHES AF + LD A,SD_MEDCAP ; OFFSET TO CAPACITY FIELD + CALL LDHLIYA ; HL := IY + A, REG A TRASHED PUSH HL ; MOVE ADDRESS POP BC ; ... TO BC POP HL ; RECOVER HL CALL ST32 ; SAVE THE CAPACITY VALUE (DWORD) ; ; RESET CARD STATUS TO 0 (OK) - SD_DPTR(SD_STAT) ; HL := ADR OF STATUS, AF TRASHED XOR A ; A := 0 (STATUS = OK) - LD (HL),A ; SAVE IT + LD (IY+SD_STAT),A ; SAVE IT ; RET ; RETURN, A=0, Z SET @@ -1004,23 +1005,22 @@ SD_SECTIO3: ; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED ; SD_CHKCARD: - ; FIX: NEED TO CHECK FOR CARD DETECT HERE AND + ; FIX: NEED TO CHECK CARD DETECT HERE AND ; HANDLE AS ERROR. ; - SD_DPTR(SD_STAT) ; HL = ADR OF STATUS, AF TRASHED - LD A,(HL) ; GET CURRENT STATUS + LD A,(IY+SD_STAT) ; GET CURRENT STATUS OR A ; SET FLAGS RET Z ; RETURN WITH A=0 AND Z SET JP SD_INITCARD ; OTHERWISE INIT CARD ; -; CONVERT LBA ADDRESS IN HSTLBA TO CARD SPECIFIC ADDRESS IN CMD PARMS +; CONVERT LBA ADDRESS TO CARD SPECIFIC ADDRESS IN CMD PARMS ; V1 CARDS REQUIRE BYTE ADDRESSING, SO A TRANSLATION IS DONE IN THAT CASE ; SD_SETADDR: - SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF - LD A,(HL) ; GET CARD TYPE + LD A,(IY+SD_TYPE) ; GET CARD TYPE PUSH AF ; SAVE IT - LD HL,HSTLBA ; POINT TO INCOMING LBA VALUE + LD A,SD_LBA ; OFFSET OF LBA VALUE + CALL LDHLIYA ; HL := IY + A, REG A TRASHED CALL LD32 ; LOAD IT TO DE:HL, AF IS TRASHED POP AF ; GET CARD TYPE BACK CP SD_TYPESDHC ; IS IT V2 OR BETTER? @@ -1334,10 +1334,7 @@ SD_OPRMSK .EQU (SD_CS | SD_CLK | SD_DI) ; UNIT IS SPECIFIED IN A ; SD_SELUNIT: - LD A,(SD_UNIT) -; - CP SD_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) - JP NC,SD_INVUNIT ; HANDLE INVALID UNIT + LD A,(IY+SD_DEV) ; GET CURRENT DEVICE ; #IF (SDMODE == SDMODE_DSD) ; SELECT REQUESTED UNIT @@ -1538,12 +1535,7 @@ SD_WRTPROT: JR SD_ERR2 ; DO NOT UPDATE UNIT STATUS! ; SD_ERR: - PUSH HL ; IS THIS NEEDED? - PUSH AF ; SAVE INCOMING STATUS - SD_DPTR(SD_STAT) ; GET STATUS ADR IN HL, AF TRASHED - POP AF ; RESTORE INCOMING STATUS - LD (HL),A ; UPDATE STATUS - POP HL ; IS THIS NEEDED? + LD (IY+SD_STAT),A ; SAVE NEW STATUS SD_ERR2: #IF (SDTRACE >= 2) CALL SD_PRTSTAT @@ -1659,14 +1651,14 @@ SD_REGDUMP1: ; PRINT DIAGNONSTIC PREFIX ; SD_PRTPREFIX: + PUSH AF CALL NEWLINE PRTS("SD$") - PUSH AF - LD A,(SD_UNIT) + LD A,(IY+SD_DEV) ; GET CURRENT DEVICE NUM ADD A,'0' CALL COUT - POP AF CALL PC_COLON + POP AF RET ; ; DISPLAY COMMAND, LOW ORDER WORD OF PARMS, AND RC @@ -1710,11 +1702,11 @@ SD_STR_STRDYTO .TEXT "READY TIMEOUT$" SD_STR_STINITTO .TEXT "INITIALIZATION TIMEOUT$" SD_STR_STCMDTO .TEXT "COMMAND TIMEOUT$" SD_STR_STCMDERR .TEXT "COMMAND ERROR$" -SD_STR_STDATAERR .TEXT "DATA ERROR$" +SD_STR_STDATAERR .TEXT "DATA ERROR$" SD_STR_STDATATO .TEXT "DATA TIMEOUT$" SD_STR_STCRCERR .TEXT "CRC ERROR$" -SD_STR_STNOMEDIA .TEXT "NO MEDIA$" -SD_STR_STWRTPROT .TEXT "WRITE PROTECTED$" +SD_STR_STNOMEDIA .TEXT "NO MEDIA$" +SD_STR_STWRTPROT .TEXT "WRITE PROTECTED$" SD_STR_STUNK .TEXT "UNKNOWN$" SD_STR_TYPEUNK .TEXT "UNK$" SD_STR_TYPEMMC .TEXT "MMC$" @@ -1744,37 +1736,12 @@ SD_CMDCRC .DB 0 ; CRC SD_RC .DB 0 ; RETURN CODE FROM CMD SD_TOK .DB 0 ; TOKEN FROM DATA XFR ; -SD_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO -SD_DSKBUF .DW 0 ; ACTIVE DISK BUFFER -; -; UNIT SPECIFIC DATA STORAGE -; -SD_UNITDATA .FILL SD_UNITCNT * 8, 0 ; PER UNIT DATA, 8 BYTES -SD_DATALEN .EQU $ - SD_UNITDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS -SD_UNITDATALEN .EQU SD_DATALEN / SD_UNITCNT ; LENGTH OF PER UNIT DATA +SD_DSKBUF .DW 0 ; ADR OF ACTIVE DISK BUFFER ; ;============================================================================= ; HELPER ROUTINES ;============================================================================= ; -; IMPLEMENTATION FOR MACRO SD_DPTR -; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA -; HL := ADR OF SD_UNITDATA[(SD_UNIT)][(SP)] -; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET -; AF IS TRASHED -; -SD_DPTRIMP: - LD HL,SD_UNITDATA ; POINT TO START OF UNIT DATA ARRAY - LD A,(SD_UNIT) ; GET CURRENT UNIT NUM - RLCA ; MULTIPLY BY - RLCA ; ... SIZE OF PER UNIT DATA - RLCA ; ... (8 BYTES) - EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS - ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM - INC HL ; BUMP HL TO NEXT REAL INSTRUCTION - EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA - JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN -; ; MSB<-->LSB MIRROR BITS IN A, RESULT IN C ; MIRROR: diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 48bafc61..1a8372a0 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -35,6 +35,11 @@ PLT_MK4 .EQU 5 ; MARK IV PLT_UNA .EQU 6 ; UNA BIOS PLT_RC .EQU 7 ; RC2014 ; +; FOUNCTION GROUP FUNCTION COUNTS +; +CIO_FNCNT .EQU 7 +DIO_FNCNT .EQU 12 +; #IF (PLATFORM != PLT_UNA) #INCLUDE "hbios.inc" #ENDIF diff --git a/Source/HBIOS/util.asm b/Source/HBIOS/util.asm index e4f297b3..11a87e3c 100644 --- a/Source/HBIOS/util.asm +++ b/Source/HBIOS/util.asm @@ -385,6 +385,16 @@ _REGDMP: CALL PC_COLON LD BC,(REGDMP_SP) CALL PRTHEXWORD ; SP + + CALL PC_COLON + PUSH IX + POP BC + CALL PRTHEXWORD ; IX + + CALL PC_COLON + PUSH IY + POP BC + CALL PRTHEXWORD ; IY CALL PC_RBKT CALL PC_SPACE diff --git a/Source/HBIOS/vga_old.asm b/Source/HBIOS/vga_old.asm deleted file mode 100644 index ce807594..00000000 --- a/Source/HBIOS/vga_old.asm +++ /dev/null @@ -1,773 +0,0 @@ -;====================================================================== -; VGA DRIVER FOR RBC PROJECT -; -; WRITTEN BY: WAYNE WARTHEN -- 5/29/2017 -;====================================================================== -; -; TODO: -; -;====================================================================== -; VGA DRIVER - CONSTANTS -;====================================================================== -; -VGA_BASE .EQU $E0 -; -VGA_KBDDATA .EQU VGA_BASE + $00 ; KBD CTLR DATA PORT -VGA_KBDST .EQU VGA_BASE + $01 ; KBD CTLR STATUS/CMD PORT -VGA_REG .EQU VGA_BASE + $02 ; SELECT CRTC REGISTER -VGA_DATA .EQU VGA_BASE + $03 ; READ/WRITE CRTC DATA -VGA_CFG .EQU VGA_BASE + $04 ; VGA3 BOARD CFG REGISTER -VGA_HI .EQU VGA_BASE + $05 ; BOARD RAM HI ADDRESS -VGA_LO .EQU VGA_BASE + $06 ; BOARD RAM LO ADDRESS -VGA_DAT .EQU VGA_BASE + $07 ; BOARD RAM BYTE R/W -; -VGA_ROWS .EQU 25 -VGA_COLS .EQU 80 -; -#DEFINE DEFREGS REGS_VGA -; -TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER -; -;====================================================================== -; VGA DRIVER - INITIALIZATION -;====================================================================== -; -VGA_INIT: - LD IY,VGA_IDAT ; POINTER TO INSTANCE DATA -; - CALL NEWLINE ; FORMATTING - PRTS("VGA: IO=0x$") - LD A,VGA_REG - CALL PRTHEXBYTE - CALL VGA_PROBE ; CHECK FOR HW PRESENCE - JR Z,VGA_INIT1 ; CONTINUE IF HW PRESENT -; - ; HARDWARE NOT PRESENT - PRTS(" NOT PRESENT$") - OR $FF ; SIGNAL FAILURE - RET -; -VGA_INIT1: - ; DISPLAY CONSOLE DIMENSIONS - LD A,VGA_COLS - CALL PC_SPACE - CALL PRTDECB - LD A,'X' - CALL COUT - LD A,VGA_ROWS - CALL PRTDECB - PRTS(" TEXT$") - - ; HARDWARE INITIALIZATION - CALL VGA_CRTINIT ; SETUP THE VGA CHIP REGISTERS - CALL VGA_LOADFONT ; LOAD FONT DATA FROM ROM TO VGA STRORAGE - CALL VGA_VDARES - CALL KBD_INIT ; INITIALIZE KEYBOARD DRIVER - - ; ADD OURSELVES TO VDA DISPATCH TABLE - LD BC,VGA_DISPATCH ; BC := DISPATCH ADDRESS - LD DE,VGA_IDAT ; DE := VGA INSTANCE DATA PTR - CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED - - ; INITIALIZE EMULATION - LD C,A ; C := ASSIGNED VIDEO DEVICE NUM - LD DE,VGA_DISPATCH ; DE := DISPATCH ADDRESS - LD HL,VGA_IDAT ; HL := VGA INSTANCE DATA PTR - CALL TERM_ATTACH ; DO IT - - XOR A ; SIGNAL SUCCESS - RET -; -;====================================================================== -; VGA DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS -;====================================================================== -; -VGA_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JP Z,VGA_VDAINI ; $40 - DEC A - JP Z,VGA_VDAQRY ; $41 - DEC A - JP Z,VGA_VDARES ; $42 - DEC A - JP Z,VGA_VDADEV ; $43 - DEC A - JP Z,VGA_VDASCS ; $44 - DEC A - JP Z,VGA_VDASCP ; $45 - DEC A - JP Z,VGA_VDASAT ; $46 - DEC A - JP Z,VGA_VDASCO ; $47 - DEC A - JP Z,VGA_VDAWRC ; $48 - DEC A - JP Z,VGA_VDAFIL ; $49 - DEC A - JP Z,VGA_VDACPY ; $4A - DEC A - JP Z,VGA_VDASCR ; $4B - DEC A - JP Z,KBD_STAT ; $4C - DEC A - JP Z,KBD_FLUSH ; $4D - DEC A - JP Z,KBD_READ ; $4E - CALL PANIC - -VGA_VDAINI: - ; RESET VDA - ; CURRENTLY IGNORES VIDEO MODE AND BITMAP DATA - CALL VGA_VDARES ; RESET VDA - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDAQRY: - LD C,$00 ; MODE ZERO IS ALL WE KNOW - LD D,VGA_ROWS ; ROWS - LD E,VGA_COLS ; COLS - LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDARES: - LD A,$07 ; ATTRIBUTE IS STANDARD WHITE ON BLACK - LD (VGA_ATTR),A ; SAVE IT - XOR A ; ZERO (REVEVERSE, UNDERLINE, BLINK) - LD (VGA_RUB),A ; SAVE IT - - LD DE,0 ; ROW = 0, COL = 0 - CALL VGA_XY ; SEND CURSOR TO TOP LEFT - LD A,' ' ; BLANK THE SCREEN - LD DE,$800 ; FILL ENTIRE BUFFER - CALL VGA_FILL ; DO IT - LD DE,0 ; ROW = 0, COL = 0 - CALL VGA_XY ; SEND CURSOR TO TOP LEFT - - LD HL,$0404 ; SET VIDEO ENABLE BIT - CALL VGA_SETCFG ; DO IT - - XOR A - RET - -VGA_VDADEV: - LD D,VDADEV_VGA ; D := DEVICE TYPE - LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDASCS: - CALL PANIC ; NOT IMPLEMENTED (YET) - -VGA_VDASCP: - CALL VGA_XY ; SET CURSOR POSITION - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDASAT: - ; INCOMING IS: -----RUB (R=REVERSE, U=UNDERLINE, B=BLINK) - ; - ; JUST SAVE THE VALUE AND FALL THROUGH. ONLY REVERSE IS - ; SUPPORTED WHICH IS IMPLEMENTED BELOW. - LD A,E - LD (VGA_RUB),A ; SAVE IT - JR VGA_VDASCO2 ; IMPLEMENT SETTING - -VGA_VDASCO: - ; INCOMING IS: IBGRIBGR (I=INTENSITY, B=BLUE, G=GREEN, R=RED) - ; TRANSFORM TO: -RGBIRGB (DISCARD INTENSITY BIT IN HIGH NIBBLE) - ; - ; A := INVERTED E, SO A IS RGBIRGBI (F/B) - LD B,8 ; DO 8 BITS -VGA_VDASCO1: - RRC E ; LOW BIT OF E ROTATED RIGHT INTO CF - RLA ; CF ROTATED LEFT INTO LOW BIT OF A - DJNZ VGA_VDASCO1 ; DO FOR ALL 8 BITS - ; LS A X 3 TO SWAP F/B BITS, SO A IS IRGBIRGB (B/F) - RLCA - RLCA - RLCA - ; MASK FOR RELEVANT BITS, SO A IS 0R0B0R0B - AND %01010101 - ; SAVE A IN C AND SET A = E - LD C,A - LD A,E - ; MASK FOR RELEVANT BITS, SO A IS 00G0I0G0 - AND %00101010 - ; COMBINE WITH SAVED - OR E - ; SAVE NEW ATTR VALUE - LD (VGA_ATTR),A ; AND SAVE THE RESULT -VGA_VDASCO2: - ; CHECK FOR REVERSE VIDEO - LD A,(VGA_RUB) ; GET RUB SETTING - BIT 2,A ; REVERSE IS BIT 2 - JR Z,VGA_VDASCO3 ; DONE IF REVERSE VID NOT SET - ; IMPLEMENT REVERSE VIDEO - LD A,(VGA_ATTR) ; GET ATTRIBUTE - PUSH AF ; SAVE IT - AND %00001000 ; ISOLATE INTENSITY BIT - LD E,A ; SAVE IN E - POP AF ; GOT ATTR BACK - RLCA ; SWAP FG/BG COLORS - RLCA - RLCA - RLCA - AND %01110111 ; REMOVE HIGH BITS - OR E ; COMBINE WITH PREVIOUS INTENSITY BIT - LD (VGA_ATTR),A ; SAVE NEW VALUE -VGA_VDASCO3: - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDAWRC: - LD A,E ; CHARACTER TO WRITE GOES IN A - CALL VGA_PUTCHAR ; PUT IT ON THE SCREEN - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDAFIL: - LD A,E ; FILL CHARACTER GOES IN A - EX DE,HL ; FILL LENGTH GOES IN DE - CALL VGA_FILL ; DO THE FILL - XOR A ; SIGNAL SUCCESS - RET - -VGA_VDACPY: - ; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS VGA_POS - ; BLKCPY USES: HL=SOURCE, DE=DEST, BC=COUNT - PUSH HL ; SAVE LENGTH - CALL VGA_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL - POP BC ; RECOVER LENGTH IN BC - LD DE,(VGA_POS) ; PUT DEST IN DE - JP VGA_BLKCPY ; DO A BLOCK COPY - -VGA_VDASCR: - LD A,E ; LOAD E INTO A - OR A ; SET FLAGS - RET Z ; IF ZERO, WE ARE DONE - PUSH DE ; SAVE E - JP M,VGA_VDASCR1 ; E IS NEGATIVE, REVERSE SCROLL - CALL VGA_SCROLL ; SCROLL FORWARD ONE LINE - POP DE ; RECOVER E - DEC E ; DECREMENT IT - JR VGA_VDASCR ; LOOP -VGA_VDASCR1: - CALL VGA_RSCROLL ; SCROLL REVERSE ONE LINE - POP DE ; RECOVER E - INC E ; INCREMENT IT - JR VGA_VDASCR ; LOOP -; -;====================================================================== -; VGA DRIVER - PRIVATE DRIVER FUNCTIONS -;====================================================================== -; -;---------------------------------------------------------------------- -; SET BOARD CONFIGURATON REGISTER -; MASK IN H, VALUE IN L -;---------------------------------------------------------------------- -; -VGA_SETCFG: - PUSH AF ; PRESERVE AF - LD A,H ; MASK IN ACCUM - CPL ; INVERT IT - LD H,A ; BACK TO H - LD A,(VGA_CFGV) ; GET CURRENT CONFIG VALUE - AND H ; RESET ALL TARGET BITS - OR L ; SET TARGET BITS - LD (VGA_CFGV),A ; SAVE NEW VALUE - OUT (VGA_CFG),A ; AND WRITE IT TO REGISTER - POP AF ; RESTORE AF - RET -; -;---------------------------------------------------------------------- -; UPDATE CRTC REGISTERS -; VGA_REGWR WRITES VALUE IN A TO VDU REGISTER SPECIFIED IN C -;---------------------------------------------------------------------- -; -VGA_REGWR: - PUSH AF ; SAVE VALUE TO WRITE - LD A,C ; SET A TO VGA REGISTER TO SELECT - OUT (VGA_REG),A ; WRITE IT TO SELECT THE REGISTER - POP AF ; RESTORE VALUE TO WRITE - OUT (VGA_DATA),A ; WRITE IT - RET -; -VGA_REGWRX: - LD A,H ; SETUP MSB TO WRITE - CALL VGA_REGWR ; DO IT - INC C ; NEXT CVDU REGISTER - LD A,L ; SETUP LSB TO WRITE - JR VGA_REGWR ; DO IT & RETURN -; -;---------------------------------------------------------------------- -; READ CRTC REGISTERS -; VGA_REGRD READS VDU REGISTER SPECIFIED IN C AND RETURNS VALUE IN A -;---------------------------------------------------------------------- -; -VGA_REGRD: - LD A,C ; SET A TO VGA REGISTER TO SELECT - OUT (VGA_REG),A ; WRITE IT TO SELECT THE REGISTER - IN A,(VGA_DATA) ; READ IT - RET -; -VGA_REGRDX: - CALL VGA_REGRD ; GET VALUE FROM REGISTER IN C - LD H,A ; SAVE IN H - INC C ; BUMP TO NEXT REGISTER OF PAIR - CALL VGA_REGRD ; READ THE VALUE - LD L,A ; SAVE IT IN L - RET -; -;---------------------------------------------------------------------- -; WRITE VIDEO RAM -; VGA_MEMWR WRITES VALUE IN A TO ADDRESS IN DE -; VGA_MEMWRX WRITES VALUE IN HL TO ADDRESS IN DE -;---------------------------------------------------------------------- -; -VGA_MEMWR: - LD C,VGA_HI - OUT (C),D - INC C - OUT (C),E - INC C - OUT (C),A - RET -; -VGA_MEMWRX: - LD C,VGA_HI - OUT (C),D - INC C - OUT (C),E - INC C - OUT (C),H - INC E - DEC C - OUT (C),E - INC C - OUT (C),L - DEC E - RET -; -;---------------------------------------------------------------------- -; READ VIDEO RAM -; VGA_MEMRD READS VALUE IN DE TO A -; VGA_MEMRDX READS VALUE IN DE TO HL -;---------------------------------------------------------------------- -; -VGA_MEMRD: - LD C,VGA_HI - OUT (C),D - INC C - OUT (C),E - INC C - IN A,(C) - RET -; -VGA_MEMRDX: - LD C,VGA_HI - OUT (C),D - INC C - OUT (C),E - INC C - IN H,(C) - INC E - DEC C - OUT (C),E - INC C - IN L,(C) - DEC E - RET -; -;---------------------------------------------------------------------- -; PROBE FOR VGA HARDWARE -;---------------------------------------------------------------------- -; -; ON RETURN, ZF SET INDICATES HARDWARE FOUND -; -VGA_PROBE: - LD DE,0 ; POINT TO FIRST BYTE OF VRAM - LD A,$A5 ; INITIAL TEST VALUE - LD B,A ; SAVE IN B - CALL VGA_MEMWR ; WRITE IT - INC E ; NEXT BYTE OF VRAM - CPL ; INVERT TEST VALUE - CALL VGA_MEMWR ; WRITE IT - DEC E ; BACK TO FIRST BYTE OF VRAM - CALL VGA_MEMRD ; READ IT - CP B ; CHECK FOR TEST VALUE - RET NZ ; RETURN NZ IF FAILURE - INC E ; SECOND VRAM BYTE - CALL VGA_MEMRD ; READ IT - CPL ; INVERT IT - CP B ; CHECK FOR INVERTED TEST VALUE - RET ; RETURN WITH ZF SET BASED ON CP -; -;---------------------------------------------------------------------- -; CRTC DISPLAY CONTROLLER CHIP INITIALIZATION -;---------------------------------------------------------------------- -; -VGA_CRTINIT: - LD HL,$FF00 ; ZERO ALL CFG BITS - CALL VGA_SETCFG ; DO IT - - CALL VGA_RES ; RESET CRTC (ALL REGS TO ZERO) - - LD HL,DEFREGS ; HL = POINTER TO TABLE OF REG VALUES -VGA_CRTINIT1: - LD A,(HL) ; FIRST BYTE IS REG ADR - LD C,A ; PUT IN C FOR LATER - INC A ; TEST FOR END MARKER ($FF) - RET Z ; IF EQUAL, DONE - INC HL ; NEXT BYTE - LD A,(HL) ; SECOND BYTE IS REG VAL - INC HL ; HL TO NEXT ENTRY - CALL VGA_REGWR ; WRITE REGISTER VALUE - JR VGA_CRTINIT1 ; LOOP -; -VGA_RES: - LD C,0 ; START WITH REG ZERO - LD B,40 ; CLEAR 40 REGISTERS -VGA_RES1: - XOR A ; VALUE IS ZERO - CALL VGA_REGWR ; SET VALUE - INC C ; NEXT REGISTER - DJNZ VGA_RES1 ; LOOP TILL DONE - RET ; DONE -; -VGA_CRTCDUMP: - LD C,0 ; START WITH REG ZERO - LD B,40 ; CLEAR 40 REGISTERS -VGA_CRTCDUMP1: - CALL VGA_REGRD ; SET VALUE - CALL PRTHEXBYTE - CALL PC_SPACE - INC C ; NEXT REGISTER - DJNZ VGA_CRTCDUMP1 ; LOOP TILL DONE - RET ; DONE -; -;---------------------------------------------------------------------- -; LOAD FONT DATA -;---------------------------------------------------------------------- -; -VGA_LOADFONT: - LD HL,$7000 ; CLEAR FONT PAGE NUM - CALL VGA_SETCFG - - LD DE,$7000 ; PAGE 7 OF VIDEO RAM - LD HL,FONT_HI ; START OF FONT DATA -VGA_LOADFONT1: - LD A,(HL) ; GET NEXT BYTE - CALL VGA_MEMWR ; MEM(DE) := A - INC HL ; NEXT FONT BYTE - INC DE ; NEXT MEM BYTE - LD A,D - CP $80 ; CHECK FOR END - JR NZ,VGA_LOADFONT1 ; LOOP - LD HL,$7070 ; SET FONT PAGE NUM TO 7 - CALL VGA_SETCFG - RET ; DONE -; -;---------------------------------------------------------------------- -; SET CURSOR POSITION TO ROW IN D AND COLUMN IN E -;---------------------------------------------------------------------- -; -VGA_XY: - CALL VGA_XY2IDX ; CONVERT ROW/COL TO BUF IDX - LD (VGA_POS),HL ; SAVE THE RESULT (DISPLAY POSITION) - LD C,14 ; CURSOR POSITION REGISTER PAIR - JP VGA_REGWRX ; DO IT AND RETURN -; -;---------------------------------------------------------------------- -; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL -; D=ROW, E=COL -;---------------------------------------------------------------------- -; -VGA_XY2IDX: - LD A,E ; SAVE COLUMN NUMBER IN A - LD H,D ; SET H TO ROW NUMBER - LD E,VGA_COLS ; SET E TO ROW LENGTH - CALL MULT8 ; MULTIPLY TO GET ROW OFFSET - LD E,A ; GET COLUMN BACK - ADD HL,DE ; ADD IT IN - RET ; RETURN -; -;---------------------------------------------------------------------- -; WRITE VALUE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR -;---------------------------------------------------------------------- -; -VGA_PUTCHAR: - ; SETUP DE WITH BUFFER ADDRESS - LD DE,(VGA_POS) ; GET CURRENT POSITION - RL E ; MULTIPLY BY 2 - RL D ; ... 2 BYTES PER CHAR - ; SETUP CHAR/ATTR IN HL - LD H,A ; CHARACTER - LD A,(VGA_ATTR) ; ATTRIBUTE - LD L,A ; ... TO L - ; WRITE CHAR & ATTR - CALL VGA_MEMWRX - ; UPDATE CURRENT POSITION - LD HL,(VGA_POS) ; GET CURSOR POSITION - INC HL ; INCREMENT - LD (VGA_POS),HL ; SAVE NEW POSITION - LD C,14 ; CURSOR POSITION REGISTER PAIR - JP VGA_REGWRX ; DO IT AND RETURN -; -;---------------------------------------------------------------------- -; FILL AREA IN BUFFER WITH SPECIFIED CHARACTER AND CURRENT COLOR/ATTRIBUTE -; STARTING AT THE CURRENT FRAME BUFFER POSITION -; A: FILL CHARACTER -; DE: NUMBER OF CHARACTERS TO FILL -;---------------------------------------------------------------------- -; -VGA_FILL: - PUSH DE ; COUNT ON STACK - LD H,A ; H = CHAR - LD A,(VGA_ATTR) ; GET CUR ATTR - LD L,A ; PUT INT L - - ; SETUP DE WITH INITIAL BUFFER ADDRESS - LD DE,(VGA_POS) ; GET CURRENT POSITION - RL E ; MULTIPLY BY 2 - RL D ; ... 2 BYTES PER CHAR - LD C,VGA_HI - -VGA_FILL1: - OUT (C),D ; SET HI ADDR - INC C ; POINT TO LO ADDR REG - -VGA_FILL2: - EX (SP),HL ; HL = COUNT, SAVE CHAR/ATTR - LD A,H ; CHECK FOR - OR L ; ... ZERO - JR Z,VGA_FILL3 ; ALL DONE - DEC HL ; DEC COUNT - EX (SP),HL ; HL = CHAR/ATTR, COUNT ON STACK - - - OUT (C),E ; SET LO ADDR - INC C ; POINT TO DATA REG - - OUT (C),H ; OUTPUT CHAR - INC E ; INC ADDR - DEC C ; POINT TO LO ADDR REG - OUT (C),E ; UPDATE LO ADDR - INC C ; POINT TO DATA REG - OUT (C),L ; OUTPUT ATTR - - DEC C ; POINT TO LO ADDR REG - INC E ; INC ADDR LO - JR NZ,VGA_FILL2 ; IF NO CF, SHORT LOOP - - DEC C ; POINT TO HI ADDR REG - INC D ; INC ADDR HI - JR VGA_FILL1 ; FULL LOOP - -VGA_FILL3: - POP DE ; CLEAR STACK - RET -; -;---------------------------------------------------------------------- -; SCROLL ENTIRE SCREEN FORWARD BY ONE LINE (CURSOR POSITION UNCHANGED) -;---------------------------------------------------------------------- -; -VGA_SCROLL: - ; CLEAR LINE ABOUT TO BE EXPOSED - LD DE,(VGA_POS) - PUSH DE - LD DE,0 + (VGA_ROWS * VGA_COLS) - LD (VGA_POS),DE - LD DE,VGA_COLS - LD A,' ' - CALL VGA_FILL - POP DE - LD (VGA_POS),DE - - ; USE BLOCK COPY TO SCROLL UP ONE LINE - LD HL,VGA_COLS - LD DE,0 - LD BC,0 + ((VGA_ROWS) * VGA_COLS) - CALL VGA_BLKCPY - - RET -; -;---------------------------------------------------------------------- -; REVERSE SCROLL ENTIRE SCREEN BY ONE LINE (CURSOR POSITION UNCHANGED) -;---------------------------------------------------------------------- -; -VGA_RSCROLL: - ; USE BLOCK COPY TO SCROLL DOWN ONE LINE - LD HL,0 + ((VGA_ROWS - 1) * VGA_COLS) - 1 ; SRC IS EOS - 1 LINE - LD DE,0 + ((VGA_ROWS) * VGA_COLS) - 1 ; DEST IS EOS - LD BC,0 + ((VGA_ROWS - 1) * VGA_COLS) ; LENGTH IS ROWS - 1 - CALL VGA_RBLKCPY - - ; CLEAR TOP LINE - LD DE,(VGA_POS) - PUSH DE - LD DE,0 - LD (VGA_POS),DE - LD DE,VGA_COLS - LD A,' ' - CALL VGA_FILL - POP DE - LD (VGA_POS),DE - - RET -; -;---------------------------------------------------------------------- -; BLOCK COPY BC BYTES FROM HL TO DE -;---------------------------------------------------------------------- -; -VGA_BLKCPY: - ; ADJUST POINTERS FOR 2 BYTE WIDTH (CHAR & ATTR) - RL E - RL D - RL L - RL H - -VGA_BLKCPY1: - - PUSH BC ; SAVE COUNT - - ; BA = (HL), HL INCREMENTED - LD C,VGA_HI ; C := VGA_HI - OUT (C),H ; VGA_HI := SOURCE HI (H) - INC C ; C := VGA_LO - OUT (C),L ; VGA_LO := SOURCE LO (L) - INC C ; C := VGA_DATA - IN B,(C) ; B := EVEN DATA BYTE (CHAR) - INC HL ; INC SOURCE PTR - DEC C ; C := VGA_LO - OUT (C),L ; VGA_LO := SOURCE LO (L), VGA_HI IS UNCHANGED! - INC C ; C := VGA_DATA - IN A,(C) ; A := ODD DATA BYTE (ATTR) - INC HL ; INC SOURCE PTR - - ; (DE) = BA, DE INCREMENTED - LD C,VGA_HI ; C := VGA_HI - OUT (C),D ; VGA_HI := DEST HI (D) - INC C ; C := VGA_LO - OUT (C),E ; VGA_LO := DEST LO (E) - INC C ; C := VGA_DATA - OUT (C),B ; EVEN DATA BYTE (CHAR) := B - INC DE ; INC DEST PTR - DEC C ; C := VGA_LO - OUT (C),E ; VGA_LO := DEST LO (E), VGA_HI IS UNCHANGED - INC C ; C := VGA_DATA - OUT (C),A ; ODD DATA BYTE (ATTR) := A - INC DE ; INC DEST PTR - - ; CHECK COUNT AND LOOP TILL DONE - POP BC ; RECOVER COUNT - DEC BC ; DEC COUNT - LD A,B ; CHECK COUNT - OR C ; ... FOR ZERO - JR NZ,VGA_BLKCPY1 ; LOOP TILL DONE - - RET ; DONE -; -VGA_RBLKCPY: - ; ADJUST POINTERS FOR 2 BYTE WIDTH (CHAR & ATTR) - RL E - RL D - RL L - RL H - - ; ADJUST TO POINT TO SECOND BYTE OF PAIR (ATTR) - INC E - INC L - -VGA_RBLKCPY1: - - PUSH BC ; SAVE COUNT - - ; BA = (HL), HL INCREMENTED - LD C,VGA_HI ; C := VGA_HI - OUT (C),H ; VGA_HI := SOURCE HI (H) - INC C ; C := VGA_LO - OUT (C),L ; VGA_LO := SOURCE LO (L) - INC C ; C := VGA_DATA - IN A,(C) ; A := ODD DATA BYTE (ATTR) - DEC HL ; DEC SOURCE PTR - DEC C ; C := VGA_LO - OUT (C),L ; VGA_LO := SOURCE LO (L), VGA_HI IS UNCHANGED! - INC C ; C := VGA_DATA - IN B,(C) ; B := EVEN DATA BYTE (CHAR) - DEC HL ; DEC SOURCE PTR - - ; (DE) = BA, DE INCREMENTED - LD C,VGA_HI ; C := VGA_HI - OUT (C),D ; VGA_HI := DEST HI (D) - INC C ; C := VGA_LO - OUT (C),E ; VGA_LO := DEST LO (E) - INC C ; C := VGA_DATA - OUT (C),A ; ODD DATA BYTE (ATTR) := A - DEC DE ; DEC DEST PTR - DEC C ; C := VGA_LO - OUT (C),E ; VGA_LO := DEST LO (E), VGA_HI IS UNCHANGED - INC C ; C := VGA_DATA - OUT (C),B ; EVEN DATA BYTE (CHAR) := B - DEC DE ; DEC DEST PTR - - ; CHECK COUNT AND LOOP TILL DONE - POP BC ; RECOVER COUNT - DEC BC ; DEC COUNT - LD A,B ; CHECK COUNT - OR C ; ... FOR ZERO - JR NZ,VGA_RBLKCPY1 ; LOOP TILL DONE - - RET ; DONE -; -;================================================================================================== -; VGA DRIVER - DATA -;================================================================================================== -; -VGA_ATTR .DB 0 ; CURRENT COLOR -VGA_POS .DW 0 ; CURRENT DISPLAY POSITION -VGA_CFGV .DB 0 ; CURRENT BOARD CONFIG VALUE -VGA_RUB .DB 0 ; REVERSE/UNDERLINE/BLINK (-----RUB) -; -; ATTRIBUTE ENCODING: -; BIT 7: ALT FONT -; BIT 6: BG REG -; BIT 5: BG GREEN -; BIT 4: BG BLUE -; BIT 3: FG INTENSITY -; BIT 2: FG RED -; BIT 1: FG GREEN -; BIT 0: FG BLUE -; -;=============================================================================== -; DEFAULT REGISTER VALUES -;=============================================================================== -; -REGS_VGA: - .DB 0,100 - 1 ; HORZ TOT - 1 - .DB 1,80 ; HORZ DISP - .DB 2,80 + 2 ; HORZ DISP + HORZ FP - .DB 3,(2 << 4) | (12 & $0F) ; VERT SW, HORZ SW - .DB 4,28 - 1 ; VERT TOT - 1 - .DB 5,1 ; VERT TOT ADJ - .DB 6,25 ; VERT DISP - .DB 7,25 + 1 ; VERT DISP + VERT FP - .DB 9,16 - 1 ; CHAR HEIGHT - 1 - .DB 10,(13 | $60) ; CURSOR START & CURSOR BLINK - .DB 11,14 ; CURSOR END - .DB 12,($0000 >> 8) & $FF ; SCRN 1 START (HI) - .DB 13,($0000 & $FF) ; SCRN 1 START (LO) - .DB 30,0 ; CONTROL 1 - .DB 31,0 ; CONTROL 2 - .DB 33,0 ; CONTROL 3 - .DB $FF ; END MARKER -; -;================================================================================================== -; VGA DRIVER - INSTANCE DATA -;================================================================================================== -; -VGA_IDAT: - .DB VGA_KBDST - .DB VGA_KBDDATA