mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1046 lines
26 KiB
1046 lines
26 KiB
;
|
|
;=============================================================================
|
|
; 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:
|
|
; - AVOID RESELECTING PRI/SEC ON EVERY I/O CALL
|
|
; - REDUCE PUSH/POP CALLS IN GET/PUTBYTE, BLKREAD/WRITE
|
|
;
|
|
; 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.
|
|
;
|
|
; TWO SEQUENTIAL I/O ADDRESSES ARE IMPLEMENTED. THE FIRST IS
|
|
; FOR STATUS AND THE SECOND IS FOR COMMAND & DATA EXCHANGE.
|
|
;
|
|
; === STATUS REGISTER (READ) ===
|
|
|
|
; BIT 2SD 2CF+1SD
|
|
; ------ --------- ---------
|
|
; BIT-0 SENDACT SENDACT
|
|
; BIT-1 SD0_CD SD1_CD
|
|
; BIT-2 SD1_CD RCV
|
|
; BIT-3 /SD0_CS GPIO3
|
|
; BIT-4 /SD1_CS /ERROR
|
|
; BIT-5 DIAG /SD1_CS
|
|
; BIT-6 /ERROR GPIO47
|
|
; BIT-7 RCVRDY RCVRDY
|
|
;
|
|
; SENDACT: DATA OUTPUT TO ESP32 PENDING, XMIT REGISTER FULL
|
|
; RCVRDY: DATA FROM ESP32 READY TO READ
|
|
; SD0_CD: SD0 CARD DETECT
|
|
; SD1_CD: SD1 CARD DETECT
|
|
; SD0_CS: SD0 CHIP SELECT
|
|
; SD1_CS: SD1 CHIP SELECT
|
|
; ERROR: ERROR INDICATOR
|
|
; DIAG: DIAGNOSTIC SWITCH
|
|
; GPIOX: GPIO BIT LEVEL
|
|
;
|
|
; COMMAND/DATA EXCHANGES
|
|
; ----------------------
|
|
;
|
|
; ->CMD_INIT1, <-STATUS
|
|
; ->CMD_INIT2, <-STATUS
|
|
; ->CMD_SEL1, <-STATUS
|
|
; ->CMD_SEL2, <-STATUS
|
|
; ->CMD_SETTRKSEC, ->[Track (byte), Sector (byte)], <-STATUS
|
|
; ->CMD_READ, <-[Sector Data (512 bytes)], <-STATUS
|
|
; ->CMD_WRITE, ->[Sector Data (512 bytes)], <-STATUS
|
|
; ->CMD_FORMAT, <-STATUS
|
|
; ->CMD_RESET
|
|
;
|
|
; ADDED IN V1.4:
|
|
; ->CMD_FWVER, <-[BoardID (byte), Ver-Major (byte), Ver-Minor (byte)], <-STATUS
|
|
; ->CMD_SETLBA, ->[LBA value (4 bytes, MS first)], <-STATUS
|
|
; ->CMD_TYPE, <-[SD Card Type (1 byte)], <-STATUS
|
|
; ->CMD_CAP, <-[Sector Count (4 bytes, MS first)], <-STATUS
|
|
; ->CMD_CID, <-[CID Data (16 bytes), <-STATUS
|
|
; ->CMD_CSD, <-[CSD Data (16 bytes), <-STATUS
|
|
; ->CMD_DISP, ->[null terminated string], <-STATUS
|
|
; ->CMD_ECHO, ->[null terminated string], <-[null terminated string], <-STATUS
|
|
;
|
|
; IF AN ERROR OCCURS IN ANY COMMAND THAT RETURNS DATA BEFORE THE
|
|
; STATUS BYTE, THEN DUMMY PADDING DATA IS SENT BEFORE THE
|
|
; ERROR STATUS.
|
|
;
|
|
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_SETTRKSEC .EQU $84 ; SET TRACK/SECTOR 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_CMD_FWVER .EQU $90 ; REPORT ESP32 FIRMWARE VERSION
|
|
ESPSD_CMD_SETLBA .EQU $91 ; SET NEW CURRENT LBA (32-BIT)
|
|
ESPSD_CMD_TYPE .EQU $92 ; REPORT CARD TYPE OF SELECTED SD CARD
|
|
ESPSD_CMD_CAP .EQU $93 ; REPORT CAPACITY (SECTORS) OF SELECTED SD CARD
|
|
ESPSD_CMD_CID .EQU $94 ; REPORT CID DATA OF SELECTED SD CARD
|
|
ESPSD_CMD_CSD .EQU $95 ; REPORT CSD DATA OF SELECTED SD CARD
|
|
ESPSD_CMD_DISP .EQU $96 ; REPORT CSD DATA OF SELECTED SD CARD
|
|
ESPSD_CMD_ECHO .EQU $97 ; REPORT CSD DATA OF SELECTED SD CARD
|
|
;
|
|
ESPSD_STAT_OK .EQU $00 ; OPERATION COMPLETED OK
|
|
ESPSD_STAT_ERR .EQU $1A ; OPERATION FAILED
|
|
;
|
|
; BOARD IDS
|
|
;
|
|
ESPSD_BOARD_2CF1SD .EQU 1 ; 2CF+1SD
|
|
ESPSD_BOARD_2SD .EQU 2 ; 2SD
|
|
;
|
|
; ESPSD DEVICE STATUS CODES
|
|
;
|
|
ESPSD_STOK .EQU 0
|
|
ESPSD_STNOMEDIA .EQU -1
|
|
ESPSD_STIOERR .EQU -2
|
|
ESPSD_STTO .EQU -3
|
|
ESPSD_STNOTRDY .EQU -4
|
|
;
|
|
; IDE DEVICE CONFIGURATION
|
|
;
|
|
; PER DEVICE DATA OFFSETS IN CFG BLOCK
|
|
;
|
|
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_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES
|
|
;
|
|
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 PC_SPACE ; FORMATTING
|
|
CALL ESPSD_FWVER ; GET BOARD ID AND F/W VER
|
|
JR NZ,ESPSD_INIT3D ; HANDLE ERROR (IGNORE IT)
|
|
LD A,E ; BOARD ID
|
|
CP ESPSD_BOARD_2CF1SD ; 2CF+1SD?
|
|
JR NZ,ESPSD_INIT3A ; IF NOT, CHECK MORE
|
|
LD DE,ESPSD_STR_2CF1SD ; LOAD STRING
|
|
JR ESPSD_INIT3C ; SKIP TO PRINT
|
|
ESPSD_INIT3A:
|
|
CP ESPSD_BOARD_2SD ; 2SD?
|
|
JR NZ,ESPSD_INIT3B ; NOPE
|
|
LD DE,ESPSD_STR_2SD ; LOAD STRING
|
|
JR ESPSD_INIT3C ; SKIP TO PRINT
|
|
ESPSD_INIT3B:
|
|
LD DE,ESPSD_STR_UNKNOWN ; UNKNOWN BOARD
|
|
ESPSD_INIT3C:
|
|
CALL WRITESTR ; PRINT BOARD NAME
|
|
PRTS(" F/W V$")
|
|
LD A,H ; GET MAJOR VER
|
|
CALL PRTDEC8 ; PRINT IT
|
|
CALL PC_PERIOD ; SEPARATOR
|
|
LD A,L ; GET MINOR VER
|
|
CALL PRTDEC8 ; PRINT IT
|
|
;
|
|
ESPSD_INIT3D:
|
|
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:
|
|
; DO A BLIND READ TO RESET INPUT CHANNEL
|
|
LD C,(IY+ESPSD_IOBASE)
|
|
INC C
|
|
IN A,(C)
|
|
; WE USE A DUMMY SELECT COMMAND TO TEST FOR PRESENCE
|
|
LD A,ESPSD_CMD_SEL0
|
|
ADD A,(IY+ESPSD_ROLE)
|
|
JP ESPSD_RUNCMD
|
|
;
|
|
; INITIALIZE DEVICE
|
|
;
|
|
ESPSD_INITDEV:
|
|
; CHECK CARD DETECT
|
|
LD A,(IY+ESPSD_ROLE) ; GET ROLE
|
|
LD B,%00000010 ; MASK FOR PRIMARY
|
|
OR A ; TEST ROLE
|
|
JR Z,ESPSD_INITDEV1 ; IF PRIMARY, JUMP AHEAD
|
|
LD B,%00000100 ; MASK FOR SECONDARY
|
|
ESPSD_INITDEV1:
|
|
LD C,(IY+ESPSD_IOBASE) ; STATUS PORT
|
|
IN A,(C) ; GET STATUS
|
|
AND B ; APPLY MASK
|
|
JP Z,ESPSD_NOMEDIA ; IF NO CARD, HANDLE AS NO MEDIA
|
|
;
|
|
CALL ESPSD_INITCARD ; PERFORM DEVICE INIT
|
|
JP NZ,ESPSD_NOMEDIA ; CONVERT TO NO MEDIA ERROR
|
|
;
|
|
; 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
|
|
;
|
|
; SET LBA
|
|
LD A,ESPSD_LBA ; OFFSET OF LBA VALUE
|
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
|
|
CALL HB_DSKACT ; SHOW ACTIVITY
|
|
CALL ESPSD_SETLBA ; SEND LBA TO DEVICE
|
|
JP NZ,ESPSD_ERR ; ON ERROR, RECORD AND BAIL OUT
|
|
;
|
|
; 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
|
|
;
|
|
; 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:
|
|
; DO A BLIND READ TO RESET INPUT CHANNEL
|
|
LD C,(IY+ESPSD_IOBASE)
|
|
INC C
|
|
IN A,(C)
|
|
;
|
|
LD A,ESPSD_CMD_INIT0 ; INIT PRIMARY DEVICE
|
|
ADD A,(IY+ESPSD_ROLE) ; ADJUST FOR PRI/SEC
|
|
CALL ESPSD_RUNCMD ; USE COMMON CMD ROUTINE
|
|
RET NZ ; HANDLE ERROR
|
|
;
|
|
; GET CAPACITY
|
|
LD E,ESPSD_CMD_CAP ; GET CAPACITY COMMAND
|
|
CALL ESPSD_CMD_SLOW ; SEND IT
|
|
RET NZ ; HANDLE ERROR
|
|
;
|
|
|
|
|
|
LD A,ESPSD_MEDCAP ; OFFSET TO CAPACITY FIELD
|
|
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
|
|
LD A,4 ; START AT END FOR LITTLE ENDIAN
|
|
CALL ADDHLA ; BUMP PTR TO END OF DWORD
|
|
LD B,4 ; LOOP FOR 4 BYTES
|
|
;
|
|
ESPSD_INITCARD1:
|
|
DEC HL ; DEC POINTER
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
CALL ESPSD_GETBYTE_SLOW ; FIRST BYTE (MSB)
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
RET NZ ; HANDLE ERROR
|
|
LD (HL),E ; SAVE IT
|
|
DJNZ ESPSD_INITCARD1 ; LOOP AS NEEDED
|
|
;
|
|
JR ESPSD_GETRESULT ; EXIT VIA CMD RESULT HANDLER
|
|
;
|
|
; GET BOARD ID AND FIRMWARE VERSION
|
|
;
|
|
ESPSD_FWVER:
|
|
LD E,ESPSD_CMD_FWVER ; FWVER COMMAND
|
|
CALL ESPSD_CMD_SLOW ; SEND IT
|
|
RET NZ ; HANDLE ERROR
|
|
CALL ESPSD_GETBYTE_SLOW ; GET BOARD ID
|
|
RET NZ ; HANDLE ERROR
|
|
LD D,E ; SAVE IN D
|
|
CALL ESPSD_GETBYTE_SLOW ; GET VER MAJOR
|
|
RET NZ ; HANDLE ERROR
|
|
LD H,E ; PUT IN H
|
|
CALL ESPSD_GETBYTE_SLOW ; GET VER MINOR
|
|
RET NZ ; HANDLE ERROR
|
|
LD L,E ; PUT IN H
|
|
CALL ESPSD_GETBYTE_SLOW ; GET RESULT
|
|
RET NZ ; HANDLE ERROR
|
|
LD A,E ; RESULT TO ACCUM
|
|
LD E,D ; BOARD ID BACK TO E
|
|
OR A ; SET FLAGS
|
|
RET Z ; RETURN SUCCESS
|
|
LD A,ESPSD_STIOERR ; CALL THIS AN I/O ERR
|
|
OR A ; SET FLAGS
|
|
RET ; DONE
|
|
;
|
|
; (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
|
|
ESPSD_GETRESULT:
|
|
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 ; SETLBA COMMAND
|
|
CALL ESPSD_CMD_SLOW ; SEND IT
|
|
RET NZ ; HANDLE ERROR
|
|
LD A,4 ; LITTLE ENDIAN
|
|
CALL ADDHLA ; BUMP TO END OF LBA BYTES
|
|
LD B,4 ; LOOP TO SEND 4 BYTES
|
|
;
|
|
ESPSD_SETLBA1:
|
|
DEC HL ; DEC POINTER
|
|
LD E,(HL) ; GET NEXT BYTE TO SEND
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
CALL ESPSD_PUTBYTE_SLOW ; SEND BYTE
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
RET NZ ; HANDLE ERROR
|
|
DJNZ ESPSD_SETLBA1 ; LOOP AS NEEDED
|
|
;
|
|
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
|
|
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
|
|
|
|
#IF FALSE
|
|
ESPSD_BLKREAD1:
|
|
PUSH BC
|
|
CALL ESPSD_GETBYTE_SLOW
|
|
POP BC
|
|
RET NZ
|
|
LD (HL),E
|
|
INC HL
|
|
PUSH BC
|
|
CALL ESPSD_GETBYTE_SLOW
|
|
POP BC
|
|
RET NZ
|
|
LD (HL),E
|
|
INC HL
|
|
DJNZ ESPSD_BLKREAD1
|
|
#ELSE
|
|
LD C,(IY+ESPSD_IOBASE) ; SET IO PORT
|
|
INC C ; START W/ DATA PORT
|
|
CALL ESPSD_BLKREAD2 ; DO FIRST 256 BYTES
|
|
CALL ESPSD_BLKREAD2 ; DO SECOND 256 BYTES
|
|
#ENDIF
|
|
;
|
|
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
|
|
;
|
|
ESPSD_BLKREAD2:
|
|
; READ BYTES FAST (NO TIMEOUT CHECK)
|
|
DEC C ; BACK TO STATUS PORT
|
|
ESPSD_BLKREAD2A:
|
|
IN A,(C) ; GET STATUS
|
|
JP P,ESPSD_BLKREAD2A ; LOOP TILL DATA READY
|
|
; DOUBLE CHECK STATUS, FIRST READ CAN BE BOGUS
|
|
IN A,(C) ; GET STATUS
|
|
JP P,ESPSD_BLKREAD2A ; LOOP TILL DATA READY
|
|
; NOPS NEEDED FOR RELIABILITY
|
|
NOP \ NOP \ NOP \ NOP \ NOP \ NOP
|
|
INC C ; DATA PORT
|
|
INI ; GET BYTE, BUMP PTR
|
|
JR NZ,ESPSD_BLKREAD2 ; 256 TIMES
|
|
RET
|
|
;
|
|
; BLOCK WRITE
|
|
;
|
|
ESPSD_BLKWRITE:
|
|
LD E,ESPSD_CMD_WRITE
|
|
CALL ESPSD_CMD_SLOW
|
|
RET NZ
|
|
;
|
|
LD B,0 ; LOOP COUNTER
|
|
|
|
#IF FALSE
|
|
ESPSD_BLKWRITE1:
|
|
LD E,(HL)
|
|
INC HL
|
|
PUSH BC
|
|
CALL ESPSD_PUTBYTE_SLOW
|
|
POP BC
|
|
RET NZ
|
|
LD E,(HL)
|
|
INC HL
|
|
PUSH BC
|
|
CALL ESPSD_PUTBYTE_SLOW
|
|
POP BC
|
|
RET NZ
|
|
DJNZ ESPSD_BLKWRITE1
|
|
#ELSE
|
|
LD C,(IY+ESPSD_IOBASE) ; SET IO PORT
|
|
INC C ; START W/ DATA PORT
|
|
CALL ESPSD_BLKWRITE2 ; DO FIRST 256 BYTES
|
|
CALL ESPSD_BLKWRITE2 ; DO SECOND 256 BYTES
|
|
#ENDIF
|
|
;
|
|
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
|
|
;
|
|
ESPSD_BLKWRITE2:
|
|
; WRITE BYTES FAST (NO TIMEOUT CHECK)
|
|
DEC C ; BACK TO STATUS PORT
|
|
ESPSD_BLKWRITE2A:
|
|
IN A,(C) ; GET STATUS
|
|
RRA ; SEND RDY BIT TO CF
|
|
JR C,ESPSD_BLKWRITE2A ; LOOP WHILE XMIT FULL
|
|
; DOUBLE CHECK STATUS, FIRST READ CAN BE BOGUS
|
|
IN A,(C) ; GET STATUS
|
|
RRA ; SEND RDY BIT TO CF
|
|
JR C,ESPSD_BLKWRITE2A ; LOOP WHILE XMIT FULL
|
|
; NOPS NEEDED FOR RELIABILITY
|
|
NOP \ NOP \ NOP \ NOP \ NOP \ NOP
|
|
INC C ; DATA PORT
|
|
OUTI ; SEND BYTE, BUMP PTR
|
|
JR NZ,ESPSD_BLKWRITE2 ; 256 TIMES
|
|
RET
|
|
;
|
|
;=============================================================================
|
|
; HARDWARE INTERFACE ROUTINES
|
|
;=============================================================================
|
|
;
|
|
; SEND COMMAND BYTE IN E TO ESP32
|
|
;
|
|
ESPSD_CMD:
|
|
PUSH DE
|
|
LD E,$33 ; COMMAND PREFIX BYTE
|
|
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 ; COMMAND PREFIX BYTE
|
|
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 NZ,ESPSD_PUTBYTE1A
|
|
; DOUBLE CHECK STATUS, FIRST READ CAN BE BOGUS
|
|
IN A,(C)
|
|
BIT 0,A
|
|
JR NZ,ESPSD_PUTBYTE1A
|
|
JR ESPSD_PUTBYTE2
|
|
ESPSD_PUTBYTE1A:
|
|
DJNZ ESPSD_PUTBYTE1
|
|
LD A,ESPSD_STTO
|
|
OR A
|
|
RET
|
|
ESPSD_PUTBYTE2:
|
|
; NOPS NEEDED FOR RELIABILITY
|
|
NOP \ NOP \ NOP \ NOP \ NOP \ NOP
|
|
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,200 * CPUMHZ ; CPU SPEED SCALED TIMEOUT
|
|
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_STTO
|
|
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 Z,ESPSD_GETBYTE1A
|
|
; DOUBLE CHECK STATUS, FIRST READ CAN BE BOGUS
|
|
IN A,(C)
|
|
BIT 7,A
|
|
JR Z,ESPSD_GETBYTE1A
|
|
JR ESPSD_GETBYTE2
|
|
ESPSD_GETBYTE1A:
|
|
DJNZ ESPSD_GETBYTE1
|
|
LD A,ESPSD_STTO
|
|
OR A
|
|
RET
|
|
ESPSD_GETBYTE2:
|
|
; NOPS NEEDED FOR RELIABILITY
|
|
NOP \ NOP \ NOP \ NOP \ NOP \ NOP
|
|
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,200 * CPUMHZ ; CPU SPEED SCALED TIMEOUT
|
|
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_STTO
|
|
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_NOMEDIA:
|
|
LD A,ESPSD_STNOMEDIA
|
|
JR ESPSD_ERR
|
|
;
|
|
ESPSD_IOERR:
|
|
LD A,ESPSD_STIOERR
|
|
JR ESPSD_ERR
|
|
;
|
|
ESPSD_TO:
|
|
LD A,ESPSD_STTO
|
|
JR ESPSD_ERR
|
|
;
|
|
ESPSD_NOTRDY:
|
|
LD A,ESPSD_STNOTRDY
|
|
JR ESPSD_ERR
|
|
;
|
|
ESPSD_ERR:
|
|
LD (IY+ESPSD_STAT),A ; SAVE NEW STATUS
|
|
;
|
|
#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)
|
|
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_STNOMEDIA
|
|
JR Z,ESPSD_PRTSTATSTR1
|
|
INC A
|
|
LD DE,ESPSD_STR_STIOERR
|
|
JR Z,ESPSD_PRTSTATSTR1
|
|
INC A
|
|
LD DE,ESPSD_STR_STTO
|
|
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_STNOMEDIA .TEXT "NO MEDIA$"
|
|
ESPSD_STR_STIOERR .TEXT "IO ERROR$"
|
|
ESPSD_STR_STTO .TEXT "TIMEOUT$"
|
|
ESPSD_STR_STNOTRDY .TEXT "NOT READY$"
|
|
ESPSD_STR_STUNK .TEXT "UNKNOWN ERROR$"
|
|
;
|
|
ESPSD_STR_2CF1SD .TEXT "2CF+1SD$"
|
|
ESPSD_STR_2SD .TEXT "2SD$"
|
|
ESPSD_STR_UNKNOWN .TEXT "BOARD?$"
|
|
;
|
|
;=============================================================================
|
|
; 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
|
|
|