mirror of https://github.com/wwarthen/RomWBW.git
46 changed files with 1011 additions and 26 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,890 @@ |
|||||
|
; |
||||
|
;============================================================================= |
||||
|
; S100 ESP32 SD DISK DRIVER |
||||
|
;============================================================================= |
||||
|
; |
||||
|
; DISK DEVICE DRIVER FOR THE S100 ESP32-BASED SD INTERFACE FOUND |
||||
|
; ON THE S100 2CF+1CF BOARD AND THE DUAL SD BOARD AS DESIGNED BY |
||||
|
; JOHN MONAHAN. |
||||
|
; |
||||
|
; http://www.s100computers.com/My%20System%20Pages/IDE%202CF+SD%20Board/IDE%202CF+1SD%20Board.htm |
||||
|
; http://www.s100computers.com/My%20System%20Pages/Dual%20SD%20card%20Board/Dual%20SD%20card%20Board.htm |
||||
|
; |
||||
|
; |
||||
|
; TODO: |
||||
|
; - ADD TIMEOUT TO DETECTION!!! |
||||
|
; - ADD CARD DETECT FUNCTIONALITY |
||||
|
; |
||||
|
; NOTES: |
||||
|
; |
||||
|
; THE ESP32 IMPLEMENTS AN INTELLIGENT SD CARD CONTROLLER THAT HANDLES |
||||
|
; ALL OF THE SD CARD INTIALIZATION AND LOW-LEVEL I/O. IT EXPOSES A |
||||
|
; COMMAND/RESPONSE PROTOCOL. THE DUAL SD BOARD SUPPORTS TWO SD CARD |
||||
|
; DEVICES. SEPARATE INIT AND SELECT COMMANDS ARE PROVIDED TO HANDLE |
||||
|
; THIS AS NEEDED. THE 2CF+1SD SUPPORTS ONLY A SINGLE SD CARD DEVICE. |
||||
|
; ONLY THE INIT/SELECT COMMANDS WITH A "0" SUFFIX CAN BE USED. |
||||
|
; |
||||
|
; TWO SEQUENTIAL I/O ADDRESSES ARE IMPLEMENTED. THE FIRST IS |
||||
|
; FOR STATUS AND THE SECOND IS FOR COMMAND & DATA EXCHANGE. |
||||
|
; |
||||
|
; === STATUS REGISTER (READ) === |
||||
|
; |
||||
|
; 7 6 5 4 3 2 1 0 |
||||
|
; +-------+-------+-------+-------+-------+-------+-------+-------+ |
||||
|
; | XIN | ERR | DSW | CS1 | CS0 | CD1 | CD0 | XOUT | |
||||
|
; +-------+-------+-------+-------+-------+-------+-------+-------+ |
||||
|
; |
||||
|
; XIN: DATA READ FROM ESP32 PENDING |
||||
|
; ERR: ERROR ACTIVE |
||||
|
; DSW: OLED DISPLAY ACTIVATION |
||||
|
; CS1: SD CARD 1 CHIP SELECT |
||||
|
; CS0: SD CARD 0 CHIP SELECT |
||||
|
; CD1: SD CARD 1 MEDIA PRESENT (CARD DETECT) |
||||
|
; CD0: SD CARD 0 MEDIA PRESENT (CARD DETECT) |
||||
|
; XOUT: DATA WRITE TO ESP32 PENDING |
||||
|
; |
||||
|
; === STATUS REGISTER (WRITE) === |
||||
|
; |
||||
|
; 7 6 5 4 3 2 1 0 |
||||
|
; +-------+-------+-------+-------+-------+-------+-------+-------+ |
||||
|
; | XIN | | | | | | | XOUT | |
||||
|
; +-------+-------+-------+-------+-------+-------+-------+-------+ |
||||
|
; |
||||
|
; XIN: UNUSED??? |
||||
|
; XOUT: ACTIVATE WRITE TO ESP32 |
||||
|
; |
||||
|
ESPSD_IO_STATUS .EQU 0 ; OFFSET OF STATUS PORT FROM BASE I/O ADDRESS |
||||
|
ESPSD_IO_DATA .EQU 1 ; OFFSET OF DATA PORT FROM BASE I/O ADDRESS |
||||
|
; |
||||
|
ESPSD_CMD_INIT0 .EQU $80 ; Initialize primary SD Card |
||||
|
ESPSD_CMD_INIT1 .EQU $81 ; INITIALIZE SECONDARY SD CARD |
||||
|
ESPSD_CMD_SEL0 .EQU $82 ; (RE)SELECT PRIMARY SD CARD |
||||
|
ESPSD_CMD_SEL1 .EQU $83 ; (RE)SELECT SECONDARY SD CARD |
||||
|
ESPSD_CMD_SETLBA .EQU $84 ; SET LBA FOR SUBSEQUENT I/O |
||||
|
ESPSD_CMD_READ .EQU $85 ; READ SECTOR FROM SELECTED SD CARD AT CURRENT LBA |
||||
|
ESPSD_CMD_WRITE .EQU $86 ; WRITE SECTOR TO SELECTED SD CARD AT CURRENT LBA |
||||
|
ESPSD_CMD_FORMAT .EQU $87 ; FORMAT SECTOR ON SELECTED SD CARD AT CURRENT LBA |
||||
|
ESPSD_CMD_RESET .EQU $88 ; RESET ESP32 MODULE |
||||
|
; |
||||
|
; ESPSD DEVICE STATUS CODES |
||||
|
; |
||||
|
ESPSD_STOK .EQU 0 |
||||
|
ESPSD_STINVUNIT .EQU -1 |
||||
|
ESPSD_STNOMEDIA .EQU -2 |
||||
|
ESPSD_STCMDERR .EQU -3 |
||||
|
ESPSD_STIOERR .EQU -4 |
||||
|
ESPSD_STRDYTO .EQU -5 |
||||
|
ESPSD_STDRQTO .EQU -6 |
||||
|
ESPSD_STBSYTO .EQU -7 |
||||
|
ESPSD_STNOTSUP .EQU -8 |
||||
|
ESPSD_STNOTRDY .EQU -9 |
||||
|
; |
||||
|
; IDE DEVICE CONFIGURATION |
||||
|
; |
||||
|
ESPSD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES |
||||
|
; |
||||
|
; PER DEVICE DATA OFFSETS |
||||
|
; |
||||
|
ESPSD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) |
||||
|
ESPSD_ROLE .EQU 1 ; 0=PRIMARY, 1=SECONDARY |
||||
|
ESPSD_IOBASE .EQU 2 ; IO BASE ADDRESS (BYTE) |
||||
|
ESPSD_STAT .EQU 3 ; LAST STATUS (BYTE) |
||||
|
ESPSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) |
||||
|
ESPSD_LBA .EQU 8 ; OFFSET OF LBA (DWORD) |
||||
|
; |
||||
|
ESPSD_CFGTBL: |
||||
|
; |
||||
|
#IF (ESPSDCNT >= 1) |
||||
|
; |
||||
|
ESPSD_DEV0P: ; DEVICE 0, PRIMARY |
||||
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) |
||||
|
.DB 0 ; PRIMARY |
||||
|
.DB ESPSD0BASE ; IO BASE ADDRESS |
||||
|
.DB ESPSD_STNOTRDY ; DEVICE STATUS |
||||
|
.DW $0000,$0001 ; DEVICE CAPACITY |
||||
|
.DW 0,0 ; CURRENT LBA |
||||
|
; |
||||
|
DEVECHO "ESPSD: IO=" |
||||
|
DEVECHO ESPSD0BASE |
||||
|
DEVECHO ", PRIMARY" |
||||
|
DEVECHO "\n" |
||||
|
; |
||||
|
#IF (ESPSD0DUAL) |
||||
|
; |
||||
|
ESPSD_DEV0S: ; DEVICE 0, SECONDARY |
||||
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) |
||||
|
.DB 1 ; SECONDARY |
||||
|
.DB ESPSD0BASE ; IO BASE ADDRESS |
||||
|
.DB ESPSD_STNOTRDY ; DEVICE STATUS |
||||
|
.DW $0000,$0001 ; DEVICE CAPACITY |
||||
|
.DW 0,0 ; CURRENT LBA |
||||
|
; |
||||
|
DEVECHO "ESPSD: IO=" |
||||
|
DEVECHO ESPSD0BASE |
||||
|
DEVECHO ", SECONDARY" |
||||
|
DEVECHO "\n" |
||||
|
; |
||||
|
#ENDIF |
||||
|
; |
||||
|
#ENDIF |
||||
|
; |
||||
|
#IF (ESPSDCNT >= 2) |
||||
|
; |
||||
|
ESPSD_DEV1P: ; DEVICE 1, PRIMARY |
||||
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) |
||||
|
.DB 0 ; PRIMARY |
||||
|
.DB ESPSD1BASE ; IO BASE ADDRESS |
||||
|
.DB ESPSD_STNOTRDY ; DEVICE STATUS |
||||
|
.DW $0000,$0001 ; DEVICE CAPACITY |
||||
|
.DW 0,0 ; CURRENT LBA |
||||
|
; |
||||
|
DEVECHO "ESPSD: IO=" |
||||
|
DEVECHO ESPSD1BASE |
||||
|
DEVECHO ", PRIMARY" |
||||
|
DEVECHO "\n" |
||||
|
; |
||||
|
#IF (ESPSD1DUAL) |
||||
|
; |
||||
|
ESPSD_DEV1S: ; DEVICE 1, SECONDARY |
||||
|
.DB $FE ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) |
||||
|
.DB 1 ; SECONDARY |
||||
|
.DB ESPSD1BASE ; IO BASE ADDRESS |
||||
|
.DB ESPSD_STNOTRDY ; DEVICE STATUS |
||||
|
.DW $0000,$0001 ; DEVICE CAPACITY |
||||
|
.DW 0,0 ; CURRENT LBA |
||||
|
; |
||||
|
DEVECHO "ESPSD: IO=" |
||||
|
DEVECHO ESPSD1BASE |
||||
|
DEVECHO ", SECONDARY" |
||||
|
DEVECHO "\n" |
||||
|
; |
||||
|
#ENDIF |
||||
|
; |
||||
|
#ENDIF |
||||
|
; |
||||
|
#IF ($ - ESPSD_CFGTBL) != (ESPSDCNT * 2 * ESPSD_CFGSIZ) |
||||
|
.ECHO "*** INVALID ESPSD CONFIG TABLE ***\n" |
||||
|
#ENDIF |
||||
|
; |
||||
|
.DB $FF ; END OF TABLE MARKER |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; INITIALIZATION ENTRY POINT |
||||
|
;============================================================================= |
||||
|
; |
||||
|
ESPSD_INIT: |
||||
|
; |
||||
|
XOR A ; ZERO ACCUM |
||||
|
LD (ESPSD_DEVNUM),A ; INIT DEV UNIT NUM FOR DYNAMIC ASSIGNMENT |
||||
|
LD IY,ESPSD_CFGTBL ; POINT TO START OF CONFIG TABLE |
||||
|
; |
||||
|
ESPSD_INIT1: |
||||
|
LD A,(IY) ; LOAD FIRST BYTE TO CHECK FOR END |
||||
|
CP $FF ; CHECK FOR END OF TABLE VALUE |
||||
|
JR NZ,ESPSD_INIT2 ; IF NOT END OF TABLE, CONTINUE |
||||
|
XOR A ; SIGNAL SUCCESS |
||||
|
RET ; AND RETURN |
||||
|
; |
||||
|
ESPSD_INIT2: |
||||
|
CALL NEWLINE ; FORMATTING |
||||
|
PRTS("ESPSD:$") ; TAG |
||||
|
; |
||||
|
PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS |
||||
|
LD A,(IY+ESPSD_IOBASE) ; GET IO BASE ADDRES |
||||
|
CALL PRTHEXBYTE ; DISPLAY IT |
||||
|
; |
||||
|
BIT 0,(IY+ESPSD_ROLE) ; GET ROLE BIT |
||||
|
JR NZ,ESPSD_INIT2A ; JUMP IF SECONDARY |
||||
|
PRTS(" PRIMARY$") ; SHOW PRIMATY |
||||
|
JR ESPSD_INIT2B ; JUMP AHEAD |
||||
|
ESPSD_INIT2A: |
||||
|
PRTS(" SECONDARY$") ; SHOW SECONDARY |
||||
|
ESPSD_INIT2B: |
||||
|
CALL ESPSD_DETECT ; PROBE FOR INTERFACE |
||||
|
JR Z,ESPSD_INIT3 ; GOT IT, MOVE ON TO INIT UNITS |
||||
|
PRTS(" NOT PRESENT$") ; SHOW NOT PRESENT |
||||
|
JR ESPSD_INIT4 ; SKIP CFG ENTRY |
||||
|
; |
||||
|
ESPSD_INIT3: |
||||
|
CALL ESPSD_INIT5 ; REGISTER & INIT DEVICE |
||||
|
; |
||||
|
ESPSD_INIT4: |
||||
|
LD DE,ESPSD_CFGSIZ ; SIZE OF CFG TABLE ENTRY |
||||
|
ADD IY,DE ; BUMP POINTER |
||||
|
JP ESPSD_INIT1 ; AND LOOP |
||||
|
; |
||||
|
ESPSD_INIT5: |
||||
|
; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE |
||||
|
LD A,(ESPSD_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN |
||||
|
LD (IY+ESPSD_DEV),A ; UPDATE IT |
||||
|
INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN |
||||
|
LD (ESPSD_DEVNUM),A ; SAVE IT |
||||
|
; |
||||
|
; ADD UNIT TO GLOBAL DISK UNIT TABLE |
||||
|
LD BC,ESPSD_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 |
||||
|
; |
||||
|
CALL ESPSD_INITDEV ; INITIALIZE DEVICE |
||||
|
#IF (ESPSDTRACE < 2) |
||||
|
JP NZ,ESPSD_PRTSTAT |
||||
|
#ENDIF |
||||
|
RET NZ |
||||
|
; |
||||
|
CALL ESPSD_PRTPREFIX ; TAG FOR ACTIVE DEVICE |
||||
|
; |
||||
|
; PRINT STORAGE CAPACITY (BLOCK COUNT) |
||||
|
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL |
||||
|
LD A,ESPSD_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 PRTDEC32 ; PRINT DWORD IN DECIMAL |
||||
|
PRTS("MB$") ; PRINT SUFFIX |
||||
|
; |
||||
|
XOR A ; SUCCESS |
||||
|
RET |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; DRIVER FUNCTION TABLE |
||||
|
;============================================================================= |
||||
|
; |
||||
|
ESPSD_FNTBL: |
||||
|
.DW ESPSD_STATUS |
||||
|
.DW ESPSD_RESET |
||||
|
.DW ESPSD_SEEK |
||||
|
.DW ESPSD_READ |
||||
|
.DW ESPSD_WRITE |
||||
|
.DW ESPSD_VERIFY |
||||
|
.DW ESPSD_FORMAT |
||||
|
.DW ESPSD_DEVICE |
||||
|
.DW ESPSD_MEDIA |
||||
|
.DW ESPSD_DEFMED |
||||
|
.DW ESPSD_CAP |
||||
|
.DW ESPSD_GEOM |
||||
|
#IF (($ - ESPSD_FNTBL) != (DIO_FNCNT * 2)) |
||||
|
.ECHO "*** INVALID IDE FUNCTION TABLE ***\n" |
||||
|
#ENDIF |
||||
|
; |
||||
|
ESPSD_VERIFY: |
||||
|
ESPSD_FORMAT: |
||||
|
ESPSD_DEFMED: |
||||
|
SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED |
||||
|
RET |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_READ: |
||||
|
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR |
||||
|
|
||||
|
;;;CALL NEWLINE |
||||
|
;;;LD A,'R' |
||||
|
;;;CALL COUT |
||||
|
;;;CALL PRTHEXWORDHL |
||||
|
|
||||
|
LD A,ESPSD_CMD_READ ; SETUP FOR BLOCK READ CMD |
||||
|
JP ESPSD_IO ; CONTINUE TO GENERIC IO ROUTINE |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_WRITE: |
||||
|
CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR |
||||
|
|
||||
|
;;;CALL NEWLINE |
||||
|
;;;LD A,'W' |
||||
|
;;;CALL COUT |
||||
|
;;;CALL PRTHEXWORDHL |
||||
|
|
||||
|
LD A,ESPSD_CMD_WRITE ; SETUP FOR BLOCK WRITE CMD |
||||
|
JP ESPSD_IO ; CONTINUE TO GENERIC IO ROUTINE |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_STATUS: |
||||
|
;;;LD A,'S' |
||||
|
;;;CALL COUT |
||||
|
; RETURN UNIT STATUS |
||||
|
LD A,(IY+ESPSD_STAT) ; GET STATUS OF SELECTED DEVICE |
||||
|
OR A ; SET FLAGS |
||||
|
RET ; AND RETURN |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_RESET: |
||||
|
;;;LD A,'R' |
||||
|
;;;CALL COUT |
||||
|
CALL ESPSD_INITDEV ; REINITIALIZE UNIT |
||||
|
OR A ; SET RESULT FLAGS |
||||
|
RET |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_DEVICE: |
||||
|
;;;LD A,'D' |
||||
|
;;;CALL COUT |
||||
|
LD D,DIODEV_ESPSD ; D := DEVICE TYPE |
||||
|
LD E,(IY+ESPSD_DEV) ; E := PHYSICAL DEVICE NUMBER |
||||
|
LD C,%00110010 ; C := ATTRIBUTES, REMOVABLE, SD CARD |
||||
|
LD H,0 ; H := MODE |
||||
|
LD L,(ESPSD_IOBASE) ; L := BASE I/O ADDRESS |
||||
|
XOR A ; SIGNAL SUCCESS |
||||
|
RET |
||||
|
; |
||||
|
; ESPSD_GETMED |
||||
|
; |
||||
|
ESPSD_MEDIA: |
||||
|
;;;LD A,'M' |
||||
|
;;;CALL COUT |
||||
|
LD A,E ; GET FLAGS |
||||
|
OR A ; SET FLAGS |
||||
|
JR Z,ESPSD_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA |
||||
|
; |
||||
|
CALL ESPSD_INITDEV ; REINITIALIZE DEVICE |
||||
|
; |
||||
|
ESPSD_MEDIA1: |
||||
|
LD A,(IY+ESPSD_STAT) ; 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 |
||||
|
LD A,ERR_NOMEDIA ; NO MEDIA ERROR |
||||
|
OR A ; SET FLAGS |
||||
|
RET ; AND RETURN |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_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 (IY+ESPSD_LBA+0),L ; SAVE NEW LBA |
||||
|
LD (IY+ESPSD_LBA+1),H ; ... |
||||
|
LD (IY+ESPSD_LBA+2),E ; ... |
||||
|
LD (IY+ESPSD_LBA+3),D ; ... |
||||
|
XOR A ; SIGNAL SUCCESS |
||||
|
RET ; AND RETURN |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_CAP: |
||||
|
;;;LD A,'C' |
||||
|
;;;CALL COUT |
||||
|
LD A,(IY+ESPSD_STAT) ; GET STATUS |
||||
|
PUSH AF ; SAVE IT |
||||
|
LD A,ESPSD_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 |
||||
|
RET |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_GEOM: |
||||
|
;;;LD A,'G' |
||||
|
;;;CALL COUT |
||||
|
; 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 ESPSD_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 ESPSD_CAP STATUS |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; FUNCTION SUPPORT ROUTINES |
||||
|
;============================================================================= |
||||
|
; |
||||
|
; ON RETURN, ZF SET INDICATES HARDWARE FOUND |
||||
|
; |
||||
|
ESPSD_DETECT: |
||||
|
; WE USE A DUMMY SETLBA COMMAND TO TEST FOR PRESENCE |
||||
|
LD HL,0 ; IRRELEVANT |
||||
|
JP ESPSD_SETLBA ; PASS OFF TO SETLBA |
||||
|
; |
||||
|
; INITIALIZE DEVICE |
||||
|
; |
||||
|
ESPSD_INITDEV: |
||||
|
CALL ESPSD_INITCARD ; PERFORM DEVICE INIT |
||||
|
JP NZ,ESPSD_NOMEDIA ; CONVERT TO NO MEDIA ERROR |
||||
|
; |
||||
|
; GET CAPACITY |
||||
|
; NOT CURRENTLY AVAILABLE IN ESP32 API |
||||
|
; CAPACITY IS HARD-CODED ABOVE AT API MAX OF $10000 BLOCKS |
||||
|
; |
||||
|
; RESET STATUS |
||||
|
LD A,ESPSD_STOK |
||||
|
LD (IY+ESPSD_STAT),A |
||||
|
XOR A |
||||
|
RET |
||||
|
; |
||||
|
; COMMON SECTOR I/O |
||||
|
; |
||||
|
ESPSD_IO: |
||||
|
LD (ESPSD_CMDVAL),A ; SAVE THE COMMAND |
||||
|
LD (ESPSD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS |
||||
|
; |
||||
|
; CHECK FOR ERROR STATUS AND REINIT? |
||||
|
; |
||||
|
#IF (ESPSDTRACE == 1) |
||||
|
LD HL,ESPSD_PRTERR ; SET UP SD_PRTERR |
||||
|
PUSH HL ; ... TO FILTER ALL EXITS |
||||
|
#ENDIF |
||||
|
; |
||||
|
; SELECT PRI/SEC DEVICE |
||||
|
CALL ESPSD_SELECT ; SELECT DEVICE |
||||
|
JP NZ,ESPSD_ERR ; ON ERROR, RECORD AND BAIL OUT |
||||
|
;CALL LDELAY ; *DEBUG* |
||||
|
; |
||||
|
; SET LBA |
||||
|
LD A,ESPSD_LBA ; OFFSET OF LBA VALUE |
||||
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED |
||||
|
CALL HB_DSKACT ; SHOW ACTIVITY |
||||
|
CALL LD32 ; LOAD IT TO DE:HL, AF IS TRASHED |
||||
|
CALL ESPSD_SETLBA ; SEND LBA TO DEVICE |
||||
|
;JP ESPSD_IOERR ; *DEBUG* |
||||
|
JP NZ,ESPSD_ERR ; ON ERROR, RECORD AND BAIL OUT |
||||
|
;CALL LDELAY ; *DEBUG* |
||||
|
; |
||||
|
; PERFORM BLOCK READ/WRITE |
||||
|
LD HL,(ESPSD_DSKBUF) ; RECOVER THE DISK BUFFER ADR |
||||
|
LD A,(ESPSD_CMDVAL) ; GET ORIGINAL CMD |
||||
|
CP ESPSD_CMD_READ ; READ? |
||||
|
JR NZ,ESPSD_IO2 ; IF NOT, SKIP AHEAD |
||||
|
CALL ESPSD_BLKREAD ; DO THE READ |
||||
|
JR ESPSD_IO3 ; CONTINUE |
||||
|
ESPSD_IO2: |
||||
|
CALL ESPSD_BLKWRITE ; DO THE WRITE |
||||
|
ESPSD_IO3: |
||||
|
JP NZ,ESPSD_ERR ; ON ERROR, RECORD AND BAIL OUT |
||||
|
;CALL LDELAY ; *DEBUG* |
||||
|
; |
||||
|
; INCREMENT LBA |
||||
|
LD A,ESPSD_LBA ; LBA OFFSET |
||||
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED |
||||
|
CALL INC32HL ; INCREMENT THE VALUE |
||||
|
; |
||||
|
; INCREMENT DMA |
||||
|
LD HL,ESPSD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR |
||||
|
INC (HL) ; BUMP DMA BY |
||||
|
INC (HL) ; ... 512 BYTES |
||||
|
; |
||||
|
; CLEAN UP |
||||
|
LD HL,(ESPSD_DSKBUF) ; CURRENT DMA TO HL |
||||
|
XOR A ; SIGNAL SUCCESS |
||||
|
RET ; AND DONE |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; COMMAND PROCESSING |
||||
|
;============================================================================= |
||||
|
; |
||||
|
; INITIALIZE DEVICE |
||||
|
; |
||||
|
ESPSD_INITCARD: |
||||
|
LD A,ESPSD_CMD_INIT0 ; INIT PRIMARY DEVICE |
||||
|
ADD A,(IY+ESPSD_ROLE) ; ADJUST FOR PRI/SEC |
||||
|
JR ESPSD_RUNCMD ; USE COMMON CMD ROUTINE |
||||
|
; |
||||
|
; (RE)SELECT DEVICE |
||||
|
; |
||||
|
ESPSD_SELECT: |
||||
|
LD A,ESPSD_CMD_SEL0 ; INIT PRIMARY DEVICE |
||||
|
ADD A,(IY+ESPSD_ROLE) ; ADJUST FOR PRI/SEC |
||||
|
JR ESPSD_RUNCMD ; USE COMMON CMD ROUTINE |
||||
|
; |
||||
|
; SIMPLE COMMAND COMMON CODE |
||||
|
; |
||||
|
ESPSD_RUNCMD: |
||||
|
LD E,A ; PUT IN E |
||||
|
CALL ESPSD_CMD_SLOW ; SEND COMMAND |
||||
|
RET NZ ; HANDLE ERROR |
||||
|
CALL ESPSD_GETBYTE_SLOW ; GET RESULT |
||||
|
RET NZ ; HANDLE ERROR |
||||
|
LD A,E ; RESULT TO ACCUM |
||||
|
OR A ; SET FLAGS |
||||
|
RET Z ; RETURN SUCCESS |
||||
|
LD A,ESPSD_STNOTRDY ; CALL THIS A NOT READY ERR |
||||
|
OR A ; SET FLAGS |
||||
|
RET ; DONE |
||||
|
; |
||||
|
; SET CURRENT LBA TO VALUE IN DE:HL |
||||
|
; HIGH WORD (DE) IS CURRENTLY IGNORED BECAUSE API ONLY SUPPORTS |
||||
|
; A 16-BIT LBA. |
||||
|
; |
||||
|
ESPSD_SETLBA: |
||||
|
LD E,ESPSD_CMD_SETLBA |
||||
|
CALL ESPSD_CMD_SLOW |
||||
|
RET NZ |
||||
|
LD E,H |
||||
|
CALL ESPSD_PUTBYTE_SLOW |
||||
|
RET NZ |
||||
|
LD E,L |
||||
|
CALL ESPSD_PUTBYTE_SLOW |
||||
|
RET NZ |
||||
|
CALL ESPSD_GETBYTE_SLOW |
||||
|
RET NZ |
||||
|
LD A,E ; RESULT TO ACCUM |
||||
|
OR A ; SET FLAGS |
||||
|
RET Z ; GOOD RETURN |
||||
|
LD A,ESPSD_STIOERR ; CALL THIS AN IO ERROR |
||||
|
OR A |
||||
|
RET |
||||
|
; |
||||
|
; BLOCK READ 512 BYTES TO ADDRESS IN HL |
||||
|
; |
||||
|
ESPSD_BLKREAD: |
||||
|
LD E,ESPSD_CMD_READ |
||||
|
CALL ESPSD_CMD_SLOW |
||||
|
RET NZ |
||||
|
; |
||||
|
LD B,0 ; LOOP COUNTER |
||||
|
ESPSD_BLKREAD1: |
||||
|
PUSH BC |
||||
|
CALL ESPSD_GETBYTE_SLOW |
||||
|
RET NZ |
||||
|
LD (HL),E |
||||
|
INC HL |
||||
|
CALL ESPSD_GETBYTE_SLOW |
||||
|
RET NZ |
||||
|
LD (HL),E |
||||
|
INC HL |
||||
|
POP BC |
||||
|
DJNZ ESPSD_BLKREAD1 |
||||
|
; |
||||
|
CALL ESPSD_GETBYTE_SLOW ; GET RESULT |
||||
|
RET NZ ; HANDLE ERROR |
||||
|
LD A,E ; RESULT TO ACCUM |
||||
|
OR A ; SET FLAGS |
||||
|
RET Z ; GOOD RETURN |
||||
|
LD A,ESPSD_STIOERR ; CALL THIS AN IO ERROR |
||||
|
OR A ; SET FLAGS |
||||
|
RET ; DONE |
||||
|
; |
||||
|
; BLOCK WRITE |
||||
|
; |
||||
|
ESPSD_BLKWRITE: |
||||
|
LD E,ESPSD_CMD_WRITE |
||||
|
CALL ESPSD_CMD_SLOW |
||||
|
RET NZ |
||||
|
; |
||||
|
LD B,0 ; LOOP COUNTER |
||||
|
ESPSD_BLKWRITE1: |
||||
|
PUSH BC |
||||
|
LD E,(HL) |
||||
|
INC HL |
||||
|
CALL ESPSD_PUTBYTE_SLOW |
||||
|
RET NZ |
||||
|
LD E,(HL) |
||||
|
INC HL |
||||
|
CALL ESPSD_PUTBYTE_SLOW |
||||
|
RET NZ |
||||
|
POP BC |
||||
|
DJNZ ESPSD_BLKWRITE1 |
||||
|
; |
||||
|
CALL ESPSD_GETBYTE_SLOW ; GET RESULT |
||||
|
RET NZ ; HANDLE ERROR |
||||
|
LD A,E ; RESULT TO ACCUM |
||||
|
OR A ; SET FLAGS |
||||
|
RET Z ; GOOD RETURN |
||||
|
LD A,ESPSD_STIOERR ; CALL THIS AN IO ERROR |
||||
|
OR A ; SET FLAGS |
||||
|
RET ; DONE |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; HARDWARE INTERFACE ROUTINES |
||||
|
;============================================================================= |
||||
|
; |
||||
|
; SEND COMMAND BYTE IN E TO ESP32 |
||||
|
; |
||||
|
ESPSD_CMD: |
||||
|
PUSH DE |
||||
|
LD E,$33 |
||||
|
CALL ESPSD_PUTBYTE |
||||
|
POP DE |
||||
|
RET NZ |
||||
|
JR ESPSD_PUTBYTE |
||||
|
; |
||||
|
; SEND COMMAND BYTE IN E TO ESP32 |
||||
|
; |
||||
|
ESPSD_CMD_SLOW: |
||||
|
PUSH DE |
||||
|
LD E,$33 |
||||
|
CALL ESPSD_PUTBYTE_SLOW |
||||
|
POP DE |
||||
|
RET NZ |
||||
|
JR ESPSD_PUTBYTE_SLOW |
||||
|
; |
||||
|
; WRITE BYTE IN E TO ESP32 |
||||
|
; RETURN STATUS IN A (0=SUCCESS) |
||||
|
; |
||||
|
ESPSD_PUTBYTE: |
||||
|
#IF (ESPSDTRACE >= 3) |
||||
|
CALL PC_GT |
||||
|
#ENDIF |
||||
|
LD B,0 |
||||
|
LD C,(IY+ESPSD_IOBASE) |
||||
|
ESPSD_PUTBYTE1: |
||||
|
IN A,(C) |
||||
|
BIT 0,A |
||||
|
JR Z,ESPSD_PUTBYTE2 |
||||
|
;JR ESPSD_PUTBYTE1 ; *DEBUG* |
||||
|
DJNZ ESPSD_PUTBYTE1 |
||||
|
LD A,ESPSD_STBSYTO |
||||
|
OR A |
||||
|
RET |
||||
|
ESPSD_PUTBYTE2: |
||||
|
INC C |
||||
|
OUT (C),E |
||||
|
; |
||||
|
#IF (ESPSDTRACE >= 3) |
||||
|
LD A,E |
||||
|
CALL PRTHEXBYTE |
||||
|
#ENDIF |
||||
|
; |
||||
|
XOR A |
||||
|
RET |
||||
|
; |
||||
|
; WRITE BYTE TO ESP32 FROM E WITH EXTRA LONG TIMEOUT |
||||
|
; |
||||
|
ESPSD_PUTBYTE_SLOW: |
||||
|
PUSH HL |
||||
|
LD HL,$1000 ; *TODO* TUNE THIS VALUE!!! |
||||
|
ESPSD_PUTBYTE_SLOW1: |
||||
|
PUSH HL |
||||
|
CALL ESPSD_PUTBYTE |
||||
|
POP HL |
||||
|
JR Z,ESPSD_PUTBYTE_SLOW_Z |
||||
|
DEC HL |
||||
|
LD A,H |
||||
|
OR L |
||||
|
JR NZ,ESPSD_PUTBYTE_SLOW1 |
||||
|
LD A,ESPSD_STBSYTO |
||||
|
ESPSD_PUTBYTE_SLOW_Z: |
||||
|
;CALL PC_SPACE ; *DEBUG* |
||||
|
;CALL PRTHEXWORDHL ; *DEBUG* |
||||
|
POP HL |
||||
|
OR A ; SET FLAGS |
||||
|
RET |
||||
|
; |
||||
|
; READ BYTE FROM ESP32 INTO E |
||||
|
; RETURN STATUS IN A (0=SUCCESS) |
||||
|
; |
||||
|
ESPSD_GETBYTE: |
||||
|
#IF (ESPSDTRACE >= 3) |
||||
|
CALL PC_LT |
||||
|
#ENDIF |
||||
|
LD B,0 |
||||
|
LD C,(IY+ESPSD_IOBASE) |
||||
|
ESPSD_GETBYTE1: |
||||
|
IN A,(C) |
||||
|
BIT 7,A |
||||
|
JR NZ,ESPSD_GETBYTE2 |
||||
|
DJNZ ESPSD_GETBYTE1 |
||||
|
LD A,ESPSD_STBSYTO |
||||
|
OR A |
||||
|
RET |
||||
|
ESPSD_GETBYTE2: |
||||
|
INC C |
||||
|
IN E,(C) |
||||
|
; |
||||
|
#IF (ESPSDTRACE >= 3) |
||||
|
LD A,E |
||||
|
CALL PRTHEXBYTE |
||||
|
#ENDIF |
||||
|
; |
||||
|
XOR A |
||||
|
RET |
||||
|
; |
||||
|
; READ BYTE FROM ESP32 INTO E WITH EXTRA LONG TIMEOUT |
||||
|
; |
||||
|
ESPSD_GETBYTE_SLOW: |
||||
|
PUSH HL |
||||
|
LD HL,$1000 ; *TODO* TUNE THIS VALUE??? |
||||
|
ESPSD_GETBYTE_SLOW1: |
||||
|
PUSH HL |
||||
|
CALL ESPSD_GETBYTE |
||||
|
POP HL |
||||
|
JR Z,ESPSD_GETBYTE_SLOW_Z |
||||
|
DEC HL |
||||
|
LD A,H |
||||
|
OR L |
||||
|
JR NZ,ESPSD_GETBYTE_SLOW1 |
||||
|
LD A,ESPSD_STBSYTO |
||||
|
ESPSD_GETBYTE_SLOW_Z: |
||||
|
;CALL PC_SPACE ; *DEBUG* |
||||
|
;CALL PRTHEXWORDHL ; *DEBUG* |
||||
|
POP HL |
||||
|
OR A ; SET FLAGS |
||||
|
RET |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; ERROR HANDLING AND DIAGNOSTICS |
||||
|
;============================================================================= |
||||
|
; |
||||
|
; ERROR HANDLERS |
||||
|
; |
||||
|
ESPSD_INVUNIT: |
||||
|
LD A,ESPSD_STINVUNIT |
||||
|
JR ESPSD_ERR2 ; SPECIAL CASE FOR INVALID UNIT |
||||
|
; |
||||
|
ESPSD_NOMEDIA: |
||||
|
LD A,ESPSD_STNOMEDIA |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_CMDERR: |
||||
|
LD A,ESPSD_STCMDERR |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_IOERR: |
||||
|
LD A,ESPSD_STIOERR |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_RDYTO: |
||||
|
LD A,ESPSD_STRDYTO |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_DRQTO: |
||||
|
LD A,ESPSD_STDRQTO |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_BSYTO: |
||||
|
LD A,ESPSD_STBSYTO |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_NOTSUP: |
||||
|
LD A,ESPSD_STNOTSUP |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_NOTRDY: |
||||
|
LD A,ESPSD_STNOTRDY |
||||
|
JR ESPSD_ERR |
||||
|
; |
||||
|
ESPSD_ERR: |
||||
|
LD (IY+ESPSD_STAT),A ; SAVE NEW STATUS |
||||
|
; |
||||
|
ESPSD_ERR2: |
||||
|
#IF (ESPSDTRACE >= 2) |
||||
|
CALL ESPSD_PRTSTAT |
||||
|
#ENDIF |
||||
|
OR A ; SET FLAGS |
||||
|
RET |
||||
|
; |
||||
|
; |
||||
|
; |
||||
|
ESPSD_PRTERR: |
||||
|
RET Z ; DONE IF NO ERRORS |
||||
|
; FALL THRU TO ESPSD_PRTSTAT |
||||
|
; |
||||
|
; PRINT FULL DEVICE STATUS LINE |
||||
|
; |
||||
|
ESPSD_PRTSTAT: |
||||
|
PUSH AF |
||||
|
PUSH DE |
||||
|
PUSH HL |
||||
|
LD A,(IY+ESPSD_STAT) |
||||
|
CP ESPSD_STINVUNIT |
||||
|
JR Z,ESPSD_PRTSTAT2 ; INVALID UNIT IS SPECIAL CASE |
||||
|
CALL ESPSD_PRTPREFIX ; PRINT UNIT PREFIX |
||||
|
JR ESPSD_PRTSTAT3 |
||||
|
ESPSD_PRTSTAT2: |
||||
|
CALL NEWLINE |
||||
|
PRTS("ESPSD:$") ; NO UNIT NUM IN PREFIX FOR INVALID UNIT |
||||
|
ESPSD_PRTSTAT3: |
||||
|
CALL PC_SPACE ; FORMATTING |
||||
|
CALL ESPSD_PRTSTATSTR |
||||
|
POP HL |
||||
|
POP DE |
||||
|
POP AF |
||||
|
RET |
||||
|
; |
||||
|
; PRINT STATUS STRING |
||||
|
; |
||||
|
ESPSD_PRTSTATSTR: |
||||
|
PUSH AF |
||||
|
PUSH DE |
||||
|
LD A,(IY+ESPSD_STAT) |
||||
|
OR A |
||||
|
LD DE,ESPSD_STR_STOK |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STINVUNIT |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STNOMEDIA |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STCMDERR |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STIOERR |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STRDYTO |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STDRQTO |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STBSYTO |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STNOTSUP |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
INC A |
||||
|
LD DE,ESPSD_STR_STNOTRDY |
||||
|
JR Z,ESPSD_PRTSTATSTR1 |
||||
|
LD DE,ESPSD_STR_STUNK |
||||
|
ESPSD_PRTSTATSTR1: |
||||
|
CALL WRITESTR |
||||
|
POP DE |
||||
|
POP AF |
||||
|
RET |
||||
|
; |
||||
|
; PRINT DIAGNONSTIC PREFIX |
||||
|
; |
||||
|
ESPSD_PRTPREFIX: |
||||
|
PUSH AF |
||||
|
CALL NEWLINE |
||||
|
PRTS("ESPSD$") |
||||
|
LD A,(IY+ESPSD_DEV) ; GET CURRENT DEVICE NUM |
||||
|
CP $FE ; NOT YET ASSIGNED? |
||||
|
JR Z,ESPSD_PRTPREFIX1 ; SKIP DEV NUM IF SO |
||||
|
CALL PRTDECB |
||||
|
ESPSD_PRTPREFIX1: |
||||
|
CALL PC_COLON |
||||
|
POP AF |
||||
|
RET |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; STRING DATA |
||||
|
;============================================================================= |
||||
|
; |
||||
|
ESPSD_STR_STOK .TEXT "OK$" |
||||
|
ESPSD_STR_STINVUNIT .TEXT "INVALID UNIT$" |
||||
|
ESPSD_STR_STNOMEDIA .TEXT "NO MEDIA$" |
||||
|
ESPSD_STR_STCMDERR .TEXT "COMMAND ERROR$" |
||||
|
ESPSD_STR_STIOERR .TEXT "IO ERROR$" |
||||
|
ESPSD_STR_STRDYTO .TEXT "READY TIMEOUT$" |
||||
|
ESPSD_STR_STDRQTO .TEXT "DRQ TIMEOUT$" |
||||
|
ESPSD_STR_STBSYTO .TEXT "BUSY TIMEOUT$" |
||||
|
ESPSD_STR_STNOTSUP .TEXT "NOT SUPPORTED$" |
||||
|
ESPSD_STR_STNOTRDY .TEXT "NOT READY$" |
||||
|
ESPSD_STR_STUNK .TEXT "UNKNOWN ERROR$" |
||||
|
; |
||||
|
;============================================================================= |
||||
|
; DATA STORAGE |
||||
|
;============================================================================= |
||||
|
; |
||||
|
ESPSD_CMDVAL .DB 0 ; PENDING COMMAND FOR IO FUCNTIONS |
||||
|
ESPSD_DSKBUF .DW 0 ; ACTIVE DISK BUFFER |
||||
|
; |
||||
|
ESPSD_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT |
||||
Loading…
Reference in new issue