Browse Source

Support Serial Ports on ESP32 Board

pull/357/head v3.3.0-dev.44
Wayne Warthen 2 years ago
parent
commit
8bc801d0a4
  1. 396
      Source/HBIOS/esp.asm
  2. 1
      Source/HBIOS/hbios.asm
  3. 1
      Source/HBIOS/hbios.inc
  4. 2
      Source/ver.inc
  5. 2
      Source/ver.lib

396
Source/HBIOS/esp.asm

@ -32,12 +32,25 @@ ESP_1_SPARE .EQU %00100000
; COMMAND OPCODES
;
ESP_CMD_NOP .EQU 0 ; NO OP
ESP_CMD_COUT .EQU 1 ; CHAR OUT
ESP_CMD_SOUT .EQU 2 ; STRING OUT
ESP_CMD_KIN .EQU 3 ; KEY IN
ESP_CMD_KST .EQU 4 ; KBD BUF STATUS
ESP_0_CMD_COUT .EQU 1 ; CHAR OUT
ESP_0_CMD_SOUT .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
;
; GLOBAL ESP INITIALIZATION
;
ESP_INIT:
@ -47,16 +60,63 @@ ESP_INIT:
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
JP NZ,WRITESTR
CALL WRITESTR
JR ESP_INIT2
;
; PRINT FIRMWARE VERSION
PRTS(" F/W=$")
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
;
;==================================================================================================
@ -71,24 +131,14 @@ ESP_DETECT:
;
; LOOK FOR SIGNATURE STARTING WITH "ESP"
CALL ESP_INWAIT ; ATTEMPT TO GET CHAR
;CALL PRTHEXBYTE
CP 'E'
RET NZ
CALL ESP_INWAIT ; ATTEMPT TO GET CHAR
;CALL PRTHEXBYTE
CP 'S'
RET NZ
CALL ESP_INWAIT ; ATTEMPT TO GET CHAR
;CALL PRTHEXBYTE
CP 'P'
RET
;LD DE,10 ; DELAY 160US
;CALL VDELAY ; ... TO ENSURE OUTPUT RDY SET
;IN A,(ESP_STAT) ; GET STATUS
;AND ESP_0_RDY ; ISOLATE OUTPUT READY BIT
;XOR ESP_0_RDY ; INVERT SO 0=FOUND
;RET ; DONE
;
; CLEAR ESP INPUT QUEUE
;
@ -98,9 +148,10 @@ ESP_CLR0:
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
RET NZ ; BAIL OUT IF TIMEOUT
IN A,(ESP_STAT) ; GET STATUS
AND ESP_0_RDY ; IS THERE MORE DATA?
AND (IY+ESP_CFG_RDYMSK) ; IS THERE MORE DATA?
RET Z ; IF NOT, DONE
IN A,(ESP_0_IO) ; GET CHAR
LD C,(IY+ESP_CFG_IO) ; ESP I/O PORT
IN A,(C) ; GET BYTE
DJNZ ESP_CLR0 ; LOOP TILL DONE
OR $FF ; SIGNAL FAILURE
RET
@ -115,7 +166,8 @@ ESP_PRTVER:
ESP_PRTVER1:
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
IN A,(ESP_STAT) ; GET STATUS
AND ESP_0_RDY ; ISOLATE OUTPUT READY BIT
;AND ESP_0_RDY ; ISOLATE OUTPUT READY BIT
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
@ -127,7 +179,8 @@ ESP_OUT:
PUSH AF ; SAVE VALUE
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
POP AF ; POP VALUE
OUT (ESP_0_IO),A ; SEND CHARACTER
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)
@ -142,7 +195,8 @@ ESP_INWAIT:
ESP_IN:
CALL ESP_WTNBSY ; WAIT TILL NOT BUSY
ESP_IN1:
IN A,(ESP_0_IO) ; GET BYTE
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
@ -153,8 +207,9 @@ ESP_IN1:
ESP_WTNBSY:
LD B,0 ; MAX TRIES
ESP_WTNBSY1:
IN A,(ESP_STAT) ; GET STATUS
AND ESP_0_BUSY ; IS ESP BUSY?
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
DJNZ ESP_WTNBSY1 ; ELSE LOOP
OR $FF ; SIGNAL TIMEOUT
@ -165,9 +220,10 @@ ESP_WTNBSY1:
ESP_WTBSY:
LD B,20 ; MAX TRIES
ESP_WTBSY1:
IN A,(ESP_STAT) ; GET STATUS
AND ESP_0_BUSY ; IS ESP BUSY?
XOR ESP_0_BUSY ; INVERT
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
@ -178,9 +234,10 @@ ESP_WTBSY1:
ESP_WTRDY:
LD B,0 ; MAX TRIES
ESP_WTRDY1:
IN A,(ESP_STAT) ; GET STATUS
AND ESP_0_RDY ; IS ESP READY TO OUTPUT
XOR ESP_0_RDY ; INVERT, 0=READY
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
OR $FF ; SIGNAL TIMEOUT
@ -188,8 +245,10 @@ ESP_WTRDY1:
;
;
;
ESP_STR_NOHW .TEXT " NOT PRESENT$"
ESP_STR_UPGRADE .TEXT " !!!UPGRADE REQUIRED!!!$"
ESP_PRES .DB 0 ; MODULE PRESENCE BITS
;
ESP_STR_NOHW .TEXT "NOT PRESENT$"
ESP_STR_UPGRADE .TEXT "!!!UPGRADE REQUIRED!!!$"
;
;==================================================================================================
; ESP32 CONSOLE DRIVER
@ -202,9 +261,26 @@ ESPCON_COLS .EQU 80 ; VGA DISPLAY COLS
;
;
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
;
; ANNOUNCE OURSLEVES
;
CALL NEWLINE
PRTS("ESPCON:$")
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
@ -216,14 +292,6 @@ ESPCON_INIT:
CALL PRTDECB
CALL PRTSTRD
.TEXT " TEXT (ANSI)$"
;
; ADD OURSELVES TO CIO DISPATCH TABLE
;
LD D,0 ; PHYSICAL UNIT IS ZERO
LD E,CIODEV_ESPCON ; DEVICE TYPE
LD BC,ESPCON_FNTBL ; BC := FUNCTION TABLE ADDRESS
CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
LD (HCB + HCB_CRTDEV),A ; SET OURSELVES AS THE CRT DEVICE
;
XOR A ; SIGNAL SUCCESS
RET
@ -247,7 +315,7 @@ ESPCON_FNTBL:
ESPCON_IN:
CALL ESPCON_IST
JR Z,ESPCON_IN
LD A,ESP_CMD_KIN ; KBD INPUT
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
@ -257,7 +325,7 @@ ESPCON_IN:
;
;
ESPCON_IST:
LD A,ESP_CMD_KST ; KBD BUF STATUS
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
@ -269,7 +337,7 @@ ESPCON_IST:
;
ESPCON_OUT:
PUSH DE
LD A,ESP_CMD_COUT ; CHAR OUT OPCODE
LD A,ESP_0_CMD_COUT ; CHAR OUT OPCODE
CALL ESP_OUT
POP DE
LD A,E
@ -280,7 +348,8 @@ ESPCON_OUT:
;
;
ESPCON_OST:
OR $FF ; SIGNAL OUTPUT QUEUE READY
XOR A ; ZERO ACCUM
INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION
RET ; RETURN
;
;
@ -301,14 +370,239 @@ ESPCON_QUERY:
;
ESPCON_DEVICE:
LD D,CIODEV_ESPCON ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
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,ESP_IOBASE ; L := BASE I/O ADDRESS
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:
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:
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
;
;=============================================================================
; DATA STORAGE
;=============================================================================
; 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
;
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
;
;
;
ESPSER_DEVCNT .DB 0 ; ESPSER DEVICES COUNT

1
Source/HBIOS/hbios.asm

@ -7390,6 +7390,7 @@ PS_SDDUART .TEXT "DUART$"
PS_SDZ2U .TEXT "Z2U$"
PS_SDLPT .TEXT "LPT$"
PS_SDESPCON .TEXT "ESPCON$"
PS_SDESPSER .TEXT "ESPSER$"
;
; CHARACTER SUB TYPE STRINGS
;

1
Source/HBIOS/hbios.inc

@ -314,6 +314,7 @@ CIODEV_DUART .EQU $90
CIODEV_Z2U .EQU $A0
CIODEV_LPT .EQU $B0
CIODEV_ESPCON .EQU $C0
CIODEV_ESPSER .EQU $D0
;
; SUB TYPES OF CHAR DEVICES
;

2
Source/ver.inc

@ -2,7 +2,7 @@
#DEFINE RMN 3
#DEFINE RUP 0
#DEFINE RTP 0
#DEFINE BIOSVER "3.3.0-dev.43"
#DEFINE BIOSVER "3.3.0-dev.44"
#define rmj RMJ
#define rmn RMN
#define rup RUP

2
Source/ver.lib

@ -3,5 +3,5 @@ rmn equ 3
rup equ 0
rtp equ 0
biosver macro
db "3.3.0-dev.43"
db "3.3.0-dev.44"
endm

Loading…
Cancel
Save