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.
710 lines
16 KiB
710 lines
16 KiB
;
|
|
;==================================================================================================
|
|
; ESP32 DRIVER
|
|
;
|
|
; SUPPORTS DAN WERNER'S NHYODYNE (MBC) ESP32 MODULE
|
|
; https://github.com/danwerner21/nhyodyne/tree/main/Z80ESP
|
|
;==================================================================================================
|
|
;
|
|
; TODO:
|
|
; - CLEAR CONSOLE SCREEN AT INITIALIZATION
|
|
; - INITIALIZE BAUD/MODE OF SERIAL INTERFACES AT INITIALIZATION?
|
|
;
|
|
ESP_IOBASE .EQU $9C
|
|
ESP_0_IO .EQU ESP_IOBASE + 0
|
|
ESP_1_IO .EQU ESP_IOBASE + 1
|
|
ESP_STAT .EQU ESP_IOBASE + 2
|
|
;
|
|
; ESP STATUS PORT
|
|
; MSB X X S S S S S S
|
|
; | | | | | +- ESP0 READY OUTPUT
|
|
; | | | | +--- ESP0 BUSY
|
|
; | | | +----- ESP0 SPARE
|
|
; | | +------- ESP1 READY OUTPUT
|
|
; | +--------- ESP1 BUSY
|
|
; +----------- ESP1 SPARE
|
|
;
|
|
ESP_0_RDY .EQU %00000001
|
|
ESP_0_BUSY .EQU %00000010
|
|
ESP_0_SPARE .EQU %00000100
|
|
ESP_1_RDY .EQU %00001000
|
|
ESP_1_BUSY .EQU %00010000
|
|
ESP_1_SPARE .EQU %00100000
|
|
;
|
|
; COMMAND OPCODES
|
|
;
|
|
ESP_CMD_NOP .EQU 0 ; NO OP/SYNC
|
|
ESP_CMD_SYNC .EQU 0 ; NO OP/SYNC
|
|
ESP_0_CMD_COUT .EQU 1 ; CHAR OUT
|
|
ESP_0_CMD_CSTR .EQU 2 ; STRING OUT
|
|
ESP_0_CMD_KIN .EQU 3 ; KEY IN
|
|
ESP_0_CMD_KST .EQU 4 ; KBD BUF STATUS
|
|
ESP_CMD_SBAUD .EQU 6 ; SET SERIAL BAUD RATE
|
|
ESP_CMD_SMODE .EQU 7 ; SET SERIAL LINE MODE
|
|
ESP_CMD_SOUT .EQU 8 ; SERIAL BYTE OUT
|
|
ESP_CMD_SIN .EQU 10 ; SERIAL BYTE IN
|
|
ESP_CMD_SST .EQU 11 ; SERIAL INPUT STATUS
|
|
ESP_CMD_DISC .EQU $FF ; DISCOVER
|
|
;
|
|
; ESP CONFIG TABLE ENTRY OFFSETS
|
|
;
|
|
ESP_CFG_DEV .EQU 0 ; DEVICE NUMBER
|
|
ESP_CFG_IO .EQU 1 ; ESP I/O PORT
|
|
ESP_CFG_ST .EQU 2 ; ESP STATUS PORT
|
|
ESP_CFG_RDYMSK .EQU 3 ; ESP READY MASK
|
|
ESP_CFG_BSYMSK .EQU 4 ; ESP BUSY MASK
|
|
;
|
|
DEVECHO "ESP: IO="
|
|
DEVECHO ESP_IOBASE
|
|
DEVECHO "\n"
|
|
;
|
|
; GLOBAL ESP INITIALIZATION
|
|
;
|
|
ESP_INIT:
|
|
;
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("ESP: IO=0x$")
|
|
LD A,ESP_IOBASE
|
|
CALL PRTHEXBYTE
|
|
;
|
|
XOR A ; ZERO ACCUM
|
|
LD (ESP_PRES),A ; CLEAR MODULE PRESENCE BITS
|
|
;
|
|
; DETECT FIRST ESP32 MODULE
|
|
PRTS(" A=$")
|
|
LD IY,ESPSER0_CFG
|
|
CALL ESP_DETECT
|
|
JR Z,ESP_INIT1 ; FOUND
|
|
LD DE,ESP_STR_NOHW
|
|
CALL WRITESTR
|
|
JR ESP_INIT2
|
|
;
|
|
ESP_INIT1:
|
|
CALL ESP_PRTVER
|
|
|
|
LD A,(ESP_PRES)
|
|
SET 0,A
|
|
LD (ESP_PRES),A
|
|
|
|
;
|
|
ESP_INIT2:
|
|
; DETECT SECOND ESP32 MODULE
|
|
PRTS(" B=$")
|
|
LD IY,ESPSER1_CFG
|
|
CALL ESP_DETECT
|
|
JR Z,ESP_INIT3 ; FOUND
|
|
LD DE,ESP_STR_NOHW
|
|
CALL WRITESTR
|
|
JR ESP_INIT4
|
|
;
|
|
ESP_INIT3:
|
|
CALL ESP_PRTVER
|
|
|
|
LD A,(ESP_PRES)
|
|
SET 1,A
|
|
LD (ESP_PRES),A
|
|
|
|
;
|
|
ESP_INIT4:
|
|
; INITIALIZE FIRST MODULE CHILD DRIVERS
|
|
LD A,(ESP_PRES)
|
|
BIT 0,A
|
|
JR Z,ESP_INIT5
|
|
LD IY,ESPSER0_CFG
|
|
CALL ESPSER_INIT ; SERIAL INITIALIZATION
|
|
LD IY,ESPCON0_CFG
|
|
CALL ESPCON_INIT ; CONSOLE INITIALIZATION
|
|
;
|
|
ESP_INIT5:
|
|
; INITIALIZE SECOND MODULE CHILD DRIVERS
|
|
LD A,(ESP_PRES)
|
|
BIT 1,A
|
|
JR Z,ESP_INIT6
|
|
LD IY,ESPSER1_CFG
|
|
CALL ESPSER_INIT ; SERIAL INITIALIZATION
|
|
;
|
|
ESP_INIT6:
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; ESP32 INTERFACE FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
ESP_DETECT:
|
|
; TRY TO DETECT IF PORT IS FLOATING AND
|
|
; FAIL DETECTION IF SO
|
|
LD C,(IY+ESP_CFG_ST) ; ESP STATUS PORT
|
|
IN A,(C) ; READ IT
|
|
;CALL PC_SPACE ; *DEBUG*
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
AND %11100000 ; ISOLATE TOP 3 BITS
|
|
CP $00 ; ALWAYS ZERO IF PRESENT
|
|
RET NZ ; ABORT ON FAILURE
|
|
;
|
|
; ESP32 PROCESSOR MAY TAKE A FEW SECONDS TO START UP, SO
|
|
; HERE WE WAIT FOR BUSY TO CLEAR WITH ABOUT A 5 SECOND TIMEOUT
|
|
LD B,0 ; LOOP UP TO 256 TIMES
|
|
LD C,(IY+ESP_CFG_ST) ; ESP STATUS PORT
|
|
ESP_DETECT1:
|
|
IN A,(C) ; GET STATUS
|
|
AND (IY+ESP_CFG_BSYMSK) ; IS ESP BUSY?
|
|
JR Z,ESP_DETECT2 ; MOVE ALONG IF NOT BUSY
|
|
LD DE,1500 ; 1500 * 16US = 24MS
|
|
CALL VDELAY ; DELAY
|
|
DJNZ ESP_DETECT1 ; LOOP
|
|
OR $FF ; SIGNAL FAILURE
|
|
RET ; DONE
|
|
;
|
|
ESP_DETECT2:
|
|
CALL ESP_SYNC
|
|
;LD A,B ; *DEBUG*
|
|
;CALL PC_SPACE ; *DEBUG*
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
CALL ESP_CLR ; CLEAR ANY PENDING DATA
|
|
LD A,ESP_CMD_DISC ; DISCOVER COMMAND
|
|
CALL ESP_OUT ; SEND IT
|
|
;
|
|
; LOOK FOR SIGNATURE STARTING WITH "ESP"
|
|
CALL ESP_INWAIT ; ATTEMPT TO GET CHAR
|
|
;CALL PC_SPACE ; *DEBUG*
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
CP 'E'
|
|
RET NZ
|
|
CALL ESP_INWAIT ; ATTEMPT TO GET CHAR
|
|
;CALL PC_SPACE ; *DEBUG*
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
CP 'S'
|
|
RET NZ
|
|
CALL ESP_INWAIT ; ATTEMPT TO GET CHAR
|
|
;CALL PC_SPACE ; *DEBUG*
|
|
;CALL PRTHEXBYTE ; *DEBUG*
|
|
CP 'P'
|
|
RET
|
|
;
|
|
; CLEAR ESP INPUT QUEUE
|
|
;
|
|
ESP_CLR:
|
|
; LD B,0 ; MAX CHARS TO READ /Removed DDW
|
|
;ESP_CLR0: /Removed DDW
|
|
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
|
|
RET NZ ; BAIL OUT IF TIMEOUT
|
|
IN A,(ESP_STAT) ; GET STATUS
|
|
AND (IY+ESP_CFG_RDYMSK) ; IS THERE MORE DATA?
|
|
RET Z ; IF NOT, DONE
|
|
LD C,(IY+ESP_CFG_IO) ; ESP I/O PORT
|
|
IN A,(C) ; GET BYTE
|
|
JP ESP_CLR
|
|
; DJNZ ESP_CLR0 ; LOOP TILL DONE /Removed DDW
|
|
; OR $FF ; SIGNAL FAILURE /Removed DDW
|
|
; RET /Removed DDW
|
|
|
|
;
|
|
; RE-SYNC ESP (added DDW)
|
|
;
|
|
ESP_SYNC:
|
|
LD B,0 ; sync count -- WORST CASE PERFORMACE COULD BE IMPROVED BY REDUCING THIS VALUE
|
|
ESP_SYNC0:
|
|
PUSH BC
|
|
LD A,ESP_CMD_SYNC ; Sync ESP
|
|
CALL ESP_OUT ; SEND CMD OPCODE
|
|
POP BC
|
|
DJNZ ESP_SYNC0 ; LOOP TILL DONE
|
|
RET
|
|
;
|
|
; PRINT ESP VERSION STRING TO CONSOLE
|
|
;
|
|
ESP_PRTVER:
|
|
CALL ESP_SYNC
|
|
CALL ESP_CLR ; CLEAR ANY PENDING DATA
|
|
;LD DE,1000 ; SMALL DELAY HERE
|
|
;CALL VDELAY ; ... SEEMS TO HELP RELIABILITY
|
|
LD A,ESP_CMD_DISC ; DISCOVER COMMAND
|
|
CALL ESP_OUT ; SEND IT
|
|
CALL ESP_WTRDY ; WAIT FOR READY TO OUTPUT
|
|
ESP_PRTVER1:
|
|
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
|
|
IN A,(ESP_STAT) ; GET STATUS
|
|
AND (IY+ESP_CFG_RDYMSK) ; ISOLATE OUTPUT READY BIT
|
|
RET Z ; DONE IF NOTHING READY
|
|
CALL ESP_IN ; GET NEXT CHAR
|
|
CALL COUT ; PRINT CHAR
|
|
JR ESP_PRTVER1 ; LOOP
|
|
;
|
|
; SEND BYTE TO ESP
|
|
;
|
|
ESP_OUT:
|
|
PUSH AF ; SAVE VALUE
|
|
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
|
|
POP AF ; POP VALUE
|
|
LD C,(IY+ESP_CFG_IO) ; ESP I/O PORT
|
|
OUT (C),A ; SEND BYTE
|
|
JR ESP_WTBSY ; RETURN VIA WTBSY
|
|
;
|
|
; GET BYTE FROM ESP (BLOCKING)
|
|
;
|
|
ESP_INWAIT:
|
|
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
|
|
CALL ESP_WTRDY ; WAIT FOR READY TO OUTPUT
|
|
JP ESP_IN1 ; Added DDW
|
|
;
|
|
; GET BYTE FROM ESP (NON BLOCKING)
|
|
;
|
|
ESP_IN:
|
|
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
|
|
ESP_IN1:
|
|
LD C,(IY+ESP_CFG_IO) ; ESP I/O PORT
|
|
IN A,(C) ; GET BYTE
|
|
PUSH AF ; SAVE VALUE
|
|
CALL ESP_WTBSY ; WAIT TILL BUSY
|
|
POP AF ; RESTORE VALUE
|
|
RET ; AND RETURN
|
|
;
|
|
; WAIT FOR ESP TO BE NOT BUSY
|
|
;
|
|
ESP_WTNBSY:
|
|
LD B,0 ; MAX TRIES
|
|
;PUSH HL ; SAVE HL
|
|
;LD HL,0 ; MAX TRIES
|
|
ESP_WTNBSY1:
|
|
LD C,(IY+ESP_CFG_ST) ; ESP STATUS PORT
|
|
IN A,(C) ; GET STATUS
|
|
AND (IY+ESP_CFG_BSYMSK) ; IS ESP BUSY?
|
|
RET Z ; RETURN IF NOT BUSY
|
|
;JR Z,ESP_WTNBSY_Z ; RETURN IF NOT BUSY
|
|
DJNZ ESP_WTNBSY1 ; ELSE LOOP
|
|
;DEC HL ; DEC LOOP COUNTER
|
|
;LD A,H ; CHECK FOR
|
|
;OR L ; ... TIMEOUT
|
|
;JR NZ,ESP_WTNBSY1 ; LOOP AS NEEDED
|
|
;CALL PC_ASTERISK ; *DEBUG*
|
|
OR $FF ; SIGNAL TIMEOUT
|
|
;ESP_WTNBSY_Z:
|
|
;POP HL ; RECOVER HL
|
|
RET ; AND RETURN
|
|
;
|
|
; WAIT FOR ESP TO BE BUSY
|
|
;
|
|
ESP_WTBSY:
|
|
LD B,3 ; MAX TRIES
|
|
ESP_WTBSY1:
|
|
LD C,(IY+ESP_CFG_ST) ; ESP STATUS PORT
|
|
IN A,(C) ; GET STATUS
|
|
XOR $FF ; INVERT SO 0=BUSY
|
|
AND (IY+ESP_CFG_BSYMSK) ; IS ESP BUSY?
|
|
RET Z ; RETURN IF BUSY
|
|
DJNZ ESP_WTBSY1 ; ELSE LOOP
|
|
OR $FF ; SIGNAL TIMEOUT
|
|
RET ; AND RETURN
|
|
;;;;
|
|
;;;; WAIT FOR ESP TO BE READY TO OUTPUT
|
|
;;;;
|
|
;;;ESP_WTRDY:
|
|
;;; PUSH HL ; SAVE HL
|
|
;;; LD HL,0 ; MAX TRIES
|
|
;;;ESP_WTRDY1:
|
|
;;; LD C,(IY+ESP_CFG_ST) ; ESP STATUS PORT
|
|
;;; IN A,(C) ; GET STATUS
|
|
;;; XOR $FF ; INVERT SO 0=READY
|
|
;;; AND (IY+ESP_CFG_RDYMSK) ; IS ESP READY TO OUTPUT
|
|
;;; JR Z,ESP_WTRDY_Z ; RETURN IF READY
|
|
;;; DEC HL ; DEC LOOP COUNTER
|
|
;;; LD A,H ; CHECK FOR
|
|
;;; OR L ; ... TIMEOUT
|
|
;;; JR NZ,ESP_WTRDY1 ; LOOP AS NEEDED
|
|
;;; CALL PC_PERIOD ; *DEBUG*
|
|
;;; OR $FF ; SIGNAL TIMEOUT
|
|
;;;ESP_WTRDY_Z:
|
|
;;; POP HL ; RECOVER HL
|
|
;;; RET ; AND RETURN
|
|
;
|
|
; WAIT FOR ESP TO BE READY TO OUTPUT
|
|
;
|
|
ESP_WTRDY:
|
|
LD B,0 ; MAX TRIES
|
|
ESP_WTRDY1:
|
|
LD C,(IY+ESP_CFG_ST) ; ESP STATUS PORT
|
|
IN A,(C) ; GET STATUS
|
|
XOR $FF ; INVERT SO 0=READY
|
|
AND (IY+ESP_CFG_RDYMSK) ; IS ESP READY TO OUTPUT
|
|
RET Z ; RETURN IF READY
|
|
DJNZ ESP_WTRDY1 ; ELSE LOOP
|
|
;CALL PC_PERIOD ; *DEBUG*
|
|
CALL ESP_SYNC ; SOMETHING WENT WRONG, ENSURE SYNC (Added DDW)
|
|
OR $FF ; SIGNAL TIMEOUT
|
|
RET ; AND RETURN
|
|
;
|
|
;
|
|
;
|
|
ESP_PRES .DB 0 ; MODULE PRESENCE BITS
|
|
;
|
|
ESP_STR_NOHW .TEXT "NOT PRESENT$"
|
|
ESP_STR_UPGRADE .TEXT "!!!UPGRADE REQUIRED!!!$"
|
|
;
|
|
;==================================================================================================
|
|
; ESP32 CONSOLE DRIVER
|
|
;==================================================================================================
|
|
;
|
|
;
|
|
ESPCON_ROWS .EQU 25 ; VGA DISPLAY ROWS
|
|
ESPCON_COLS .EQU 80 ; VGA DISPLAY COLS
|
|
;
|
|
DEVECHO "ESPCON: ENABLED\n"
|
|
;
|
|
;
|
|
;
|
|
ESPCON_INIT:
|
|
LD A,(ESPCON_DEVCNT) ; GET ESPCON PHYSICAL DEVICE COUNT
|
|
LD (IY+ESP_CFG_DEV),A ; SAVE PHYSICAL UNIT NUMBER
|
|
INC A ; UPDATE COUNT
|
|
LD (ESPCON_DEVCNT),A ; SAVE COUNT
|
|
;
|
|
; ADD OURSELVES TO CIO DISPATCH TABLE
|
|
;
|
|
LD BC,ESPCON_FNTBL ; BC := FUNCTION TABLE ADDRESS
|
|
PUSH IY ; COPY CONFIG ENTRY PTR
|
|
POP DE ; ... TO DE
|
|
CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
|
|
;;;LD (HCB + HCB_CRTDEV),A ; SET OURSELVES AS THE CRT DEVICE
|
|
CALL CIO_SETCRT ; SET OURSELVES AS THE CRT DEVICE
|
|
;
|
|
; ANNOUNCE OURSLEVES
|
|
;
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("ESPCON$") ; NAME
|
|
LD A,(IY+ESP_CFG_DEV) ; GET PHYSICAL UNIT NUMBER
|
|
CALL PRTDECB ; UNIT STILL IN A FROM ABOVE
|
|
CALL PC_COLON ; FORMATTING
|
|
;
|
|
; DISPLAY CONSOLE DIMENSIONS
|
|
CALL PC_SPACE
|
|
LD A,ESPCON_COLS
|
|
CALL PRTDECB
|
|
LD A,'X'
|
|
CALL COUT
|
|
LD A,ESPCON_ROWS
|
|
CALL PRTDECB
|
|
CALL PRTSTRD
|
|
.TEXT " TEXT (ANSI)$"
|
|
;
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; DRIVER FUNCTION TABLE
|
|
;
|
|
ESPCON_FNTBL:
|
|
.DW ESPCON_IN
|
|
.DW ESPCON_OUT
|
|
.DW ESPCON_IST
|
|
.DW ESPCON_OST
|
|
.DW ESPCON_INITDEV
|
|
.DW ESPCON_QUERY
|
|
.DW ESPCON_DEVICE
|
|
#IF (($ - ESPCON_FNTBL) != (CIO_FNCNT * 2))
|
|
.ECHO "*** INVALID ESPCON FUNCTION TABLE ***\n"
|
|
#ENDIF
|
|
;
|
|
;
|
|
;
|
|
ESPCON_IN:
|
|
CALL ESPCON_IST
|
|
JR Z,ESPCON_IN
|
|
LD A,ESP_0_CMD_KIN ; KBD INPUT
|
|
CALL ESP_OUT ; SEND CMD OPCODE
|
|
CALL ESP_INWAIT ; GET KEY
|
|
LD E,A ; PUT IN E
|
|
XOR A ; SIGNAL SUCCES
|
|
RET ; AND DONE
|
|
;
|
|
;
|
|
;
|
|
ESPCON_IST:
|
|
CALL ESP_CLR ; CLEAR ANY PENDING DATA (Added DDW)
|
|
LD A,ESP_0_CMD_KST ; KBD BUF STATUS
|
|
CALL ESP_OUT ; SEND CMD OPCODE
|
|
CALL ESP_INWAIT ; GET BUF SIZE
|
|
OR A ; SET FLAGS
|
|
RET Z ; AND DONE
|
|
OR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPCON_OUT:
|
|
PUSH DE
|
|
LD A,ESP_0_CMD_COUT ; CHAR OUT OPCODE
|
|
CALL ESP_OUT
|
|
POP DE
|
|
LD A,E
|
|
CALL ESP_OUT ; SEND CHAR VALUE
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPCON_OST:
|
|
XOR A ; ZERO ACCUM
|
|
INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION
|
|
RET ; RETURN
|
|
;
|
|
;
|
|
;
|
|
ESPCON_INITDEV:
|
|
CALL ESP_CLR
|
|
CALL ESP_SYNC
|
|
; SYSCHKERR(ERR_NOTIMPL) Removed DDW
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPCON_QUERY:
|
|
LD DE,0
|
|
LD HL,0
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPCON_DEVICE:
|
|
LD D,CIODEV_ESPCON ; D := DEVICE TYPE
|
|
LD E,(IY+ESP_CFG_DEV) ; E := DEVICE NUM
|
|
LD C,$BF ; C := DEVICE TYPE, 0xBF IS PROP TERM
|
|
LD H,0 ; H := 0, DRIVER HAS NO MODES
|
|
LD L,(IY+ESP_CFG_IO) ; L := BASE I/O ADDRESS
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; ESPCON CONFIGURATION
|
|
;
|
|
ESPCON_CFG:
|
|
ESPCON0_CFG:
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
|
|
.DB ESP_0_IO ; ESP DATA PORT
|
|
.DB ESP_STAT ; ESP STATUS PORT
|
|
.DB ESP_0_RDY ; ESP READY BIT MASK
|
|
.DB ESP_0_BUSY ; ESP BUSY BIT MASK
|
|
;
|
|
;
|
|
;
|
|
ESPCON_DEVCNT .DB 0 ; ESPCON DEVICES COUNT
|
|
;
|
|
;==================================================================================================
|
|
; ESP32 SERIAL DRIVER
|
|
;==================================================================================================
|
|
;
|
|
ESPSER_LINECFG .EQU SER_115200_8N1
|
|
;
|
|
ESPSER_CFG_LINE .EQU 5
|
|
;
|
|
;
|
|
;
|
|
ESPSER_INIT:
|
|
LD A,(ESPSER_DEVCNT) ; GET ESPSER PHYSICAL DEVICE COUNT
|
|
LD (IY+ESP_CFG_DEV),A ; SAVE PHYSICAL UNIT NUMBER
|
|
INC A ; UPDATE COUNT
|
|
LD (ESPSER_DEVCNT),A ; SAVE COUNT
|
|
;
|
|
; ADD OURSELVES TO CIO DISPATCH TABLE
|
|
;
|
|
LD BC,ESPSER_FNTBL ; BC := FUNCTION TABLE ADDRESS
|
|
PUSH IY ; COPY CONFIG ENTRY PTR
|
|
POP DE ; ... TO DE
|
|
CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
|
|
;
|
|
; ANNOUNCE OURSLEVES
|
|
;
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("ESPSER$") ; NAME
|
|
LD A,(IY+ESP_CFG_DEV) ; GET PHYSICAL UNIT NUMBER
|
|
CALL PRTDECB ; UNIT STILL IN A FROM ABOVE
|
|
CALL PC_COLON ; FORMATTING
|
|
;
|
|
PRTS(" MODE=$") ; FORMATTING
|
|
LD E,(IY+ESPSER_CFG_LINE+0) ; FIRST CONFIG BYTE TO E
|
|
LD D,(IY+ESPSER_CFG_LINE+1) ; SECOND CONFIG BYTE TO D
|
|
CALL PS_PRTSC0 ; PRINT CONFIG
|
|
;
|
|
; TODO: PRINT SERIAL CONFIG
|
|
;
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; DRIVER FUNCTION TABLE
|
|
;
|
|
ESPSER_FNTBL:
|
|
.DW ESPSER_IN
|
|
.DW ESPSER_OUT
|
|
.DW ESPSER_IST
|
|
.DW ESPSER_OST
|
|
.DW ESPSER_INITDEV
|
|
.DW ESPSER_QUERY
|
|
.DW ESPSER_DEVICE
|
|
#IF (($ - ESPSER_FNTBL) != (CIO_FNCNT * 2))
|
|
.ECHO "*** INVALID ESPSER FUNCTION TABLE ***\n"
|
|
#ENDIF
|
|
;
|
|
;
|
|
;
|
|
ESPSER_IN:
|
|
CALL ESPSER_IST
|
|
JR Z,ESPSER_IN
|
|
LD A,ESP_CMD_SIN ; SERIAL INPUT
|
|
CALL ESP_OUT ; SEND CMD OPCODE
|
|
CALL ESP_INWAIT ; GET KEY
|
|
LD E,A ; PUT IN E
|
|
XOR A ; SIGNAL SUCCES
|
|
RET ; AND DONE
|
|
;
|
|
;
|
|
;
|
|
ESPSER_IST:
|
|
CALL ESP_CLR ; CLEAR ANY PENDING DATA (Added DDW)
|
|
LD A,ESP_CMD_SST ; SERIAL STATUS
|
|
CALL ESP_OUT ; SEND CMD OPCODE
|
|
CALL ESP_INWAIT ; GET BUF SIZE
|
|
OR A ; SET FLAGS
|
|
RET Z ; AND DONE
|
|
OR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPSER_OUT:
|
|
PUSH DE
|
|
LD A,ESP_CMD_SOUT ; CHAR OUT OPCODE
|
|
CALL ESP_OUT
|
|
POP DE
|
|
LD A,E
|
|
CALL ESP_OUT ; SEND CHAR VALUE
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPSER_OST:
|
|
XOR A ; ZERO ACCUM
|
|
INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION
|
|
RET ; RETURN
|
|
;
|
|
;
|
|
;
|
|
ESPSER_INITDEV:
|
|
CALL ESP_CLR
|
|
CALL ESP_SYNC
|
|
PUSH DE ; SAVE INCOMING CONFIG WORD
|
|
;
|
|
; XLATE NEW LINE MODE INTO C
|
|
LD A,E
|
|
AND %00111111 ; ISOLATE MODE BITS
|
|
LD C,0 ; 8N1 = 0
|
|
CP SER_DATA8 | SER_PARNONE | SER_STOP1
|
|
JR Z,ESPSER_INITDEV1 ; IF MATCH, DO IT
|
|
INC C ; 8E1 = 1
|
|
CP SER_DATA8 | SER_PAREVEN | SER_STOP1
|
|
JR Z,ESPSER_INITDEV1 ; IF MATCH, DO IT
|
|
INC C ; 8O1 = 2
|
|
CP SER_DATA8 | SER_PARODD | SER_STOP1
|
|
JR Z,ESPSER_INITDEV1 ; IF MATCH, DO IT
|
|
INC C ; 7N1 = 3
|
|
CP SER_DATA7 | SER_PARNONE | SER_STOP1
|
|
JR Z,ESPSER_INITDEV1 ; IF MATCH, DO IT
|
|
INC C ; 7E1 = 4
|
|
CP SER_DATA7 | SER_PAREVEN | SER_STOP1
|
|
JR Z,ESPSER_INITDEV1 ; IF MATCH, DO IT
|
|
INC C ; 7O1 = 5
|
|
CP SER_DATA7 | SER_PARODD | SER_STOP1
|
|
JR Z,ESPSER_INITDEV1 ; IF MATCH, DO IT
|
|
JR NZ,ESPSER_INITDEV_ERR ; ELSE FAIL
|
|
;
|
|
ESPSER_INITDEV1:
|
|
; DECODE NEW BAUD RATE INTO DE:HL
|
|
LD H,0
|
|
LD A,D
|
|
AND %00011111
|
|
LD L,A
|
|
LD DE,75
|
|
PUSH BC ; SAVE NEW LINE MODE
|
|
CALL DECODE ; DE:HL IS DECODED BAUD RATE
|
|
POP BC ; RESTORE NEW LINE MODE
|
|
JR NZ,ESPSER_INITDEV_ERR ; IF ERROR, FAIL
|
|
;
|
|
; PROGRAM NEW LINE MODE
|
|
PUSH BC
|
|
LD A,ESP_CMD_SMODE
|
|
CALL ESP_OUT
|
|
POP BC
|
|
LD A,C
|
|
;CALL PRTHEXBYTE
|
|
;CALL LDELAY
|
|
CALL ESP_OUT
|
|
;
|
|
; PROGRAM NEW BAUD RATE
|
|
LD A,ESP_CMD_SBAUD
|
|
CALL ESP_OUT
|
|
LD A,L
|
|
CALL ESP_OUT
|
|
LD A,H
|
|
CALL ESP_OUT
|
|
LD A,E
|
|
CALL ESP_OUT
|
|
LD A,D
|
|
CALL ESP_OUT
|
|
;
|
|
; SAVE NEW LINE CONFIG WORD
|
|
POP DE ; RESTORE CONFIG WORD
|
|
LD (IY+ESPSER_CFG_LINE+0),E ; FIRST CONFIG BYTE
|
|
LD (IY+ESPSER_CFG_LINE+1),D ; SECOND CONFIG BYTE
|
|
;
|
|
XOR A
|
|
RET
|
|
;
|
|
ESPSER_INITDEV_ERR:
|
|
POP DE ; THROW AWAY CONFIG WORD ON STACK
|
|
OR $FF
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPSER_QUERY:
|
|
LD E,(IY+ESPSER_CFG_LINE+0) ; FIRST CONFIG BYTE TO E
|
|
LD D,(IY+ESPSER_CFG_LINE+1) ; SECOND CONFIG BYTE TO D
|
|
LD HL,0
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
ESPSER_DEVICE:
|
|
LD D,CIODEV_ESPSER ; D := DEVICE TYPE
|
|
LD E,(IY+ESP_CFG_DEV) ; E := DEVICE NUM
|
|
LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232
|
|
LD H,0 ; H := 0, DRIVER HAS NO MODES
|
|
LD L,(IY+ESP_CFG_IO) ; L := BASE I/O ADDRESS
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; ESPSER CONFIGURATION
|
|
;
|
|
ESPSER_CFG:
|
|
ESPSER0_CFG:
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
|
|
.DB ESP_0_IO ; ESP DATA PORT
|
|
.DB ESP_STAT ; ESP STATUS PORT
|
|
.DB ESP_0_RDY ; ESP READY BIT MASK
|
|
.DB ESP_0_BUSY ; ESP BUSY BIT MASK
|
|
.DW ESPSER_LINECFG ; LINE CONFIGURATION
|
|
;
|
|
DEVECHO "ESPSER: DEVICE=0\n"
|
|
;
|
|
ESPSER1_CFG:
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
|
|
.DB ESP_1_IO ; ESP DATA PORT
|
|
.DB ESP_STAT ; ESP STATUS PORT
|
|
.DB ESP_1_RDY ; ESP READY BIT MASK
|
|
.DB ESP_1_BUSY ; ESP BUSY BIT MASK
|
|
.DW ESPSER_LINECFG ; LINE CONFIGURATION
|
|
;
|
|
DEVECHO "ESPSER: DEVICE=1\n"
|
|
;
|
|
;
|
|
;
|
|
ESPSER_DEVCNT .DB 0 ; ESPSER DEVICES COUNT
|
|
|