Browse Source

Revise Serial Driver Initialization

- Implement PREINIT
- Use detected CPU speed for initialization
pull/3/head
Wayne Warthen 10 years ago
parent
commit
a2566d4de5
  1. 14
      Source/HBIOS/Config/plt_mk4.asm
  2. 7
      Source/HBIOS/Config/plt_n8.asm
  3. 18
      Source/HBIOS/Config/plt_sbc.asm
  4. 6
      Source/HBIOS/Config/plt_zeta.asm
  5. 2
      Source/HBIOS/MakeBlankROM.ps1
  6. 58
      Source/HBIOS/asci.asm
  7. 55
      Source/HBIOS/encode.asm
  8. 267
      Source/HBIOS/hbios.asm
  9. 9
      Source/HBIOS/loader.asm
  10. 204
      Source/HBIOS/uart.asm
  11. 1
      Source/HBIOS/util.asm
  12. 205
      Source/HBIOS/xio.asm

14
Source/HBIOS/Config/plt_mk4.asm

@ -18,21 +18,9 @@ SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER
DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER
DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC
;
ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT
UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE)
UARTOSC .EQU 1843200 ; UART OSC FREQUENCY
UARTCNT .EQU 4 ; NUMBER OF UARTS
UART0IOB .EQU $C0 ; IOBASE (4UART PORT A)
UART0CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART1IOB .EQU $C8 ; IOBASE (4UART PORT B)
UART1CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART2IOB .EQU $D0 ; IOBASE (4UART PORT C)
UART2CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART3IOB .EQU $D8 ; IOBASE (4UART PORT D)
UART3CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
;
ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT
ASCI0CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
ASCI1CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
;
VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT
CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT

7
Source/HBIOS/Config/plt_n8.asm

@ -18,12 +18,9 @@ SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER
DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER
DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC
;
UARTENABLE .EQU FALSE ; TRUE FOR UART SUPPORT (N8 USES ASCI DRIVER)
UARTCNT .EQU 0 ; NUMBER OF UARTS
;
ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT
ASCI0CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
ASCI1CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE)
UARTOSC .EQU 1843200 ; UART OSC FREQUENCY
;
VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT
CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT

18
Source/HBIOS/Config/plt_sbc.asm

@ -18,25 +18,9 @@ SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER
DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER
DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC
;
ASCIENABLE .EQU FALSE ; TRUE FOR Z180 ASCI SUPPORT
UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE)
UARTOSC .EQU 1843200 ; UART OSC FREQUENCY
UARTCNT .EQU 7 ; NUMBER OF UARTS
UART0IOB .EQU $68 ; IOBASE (SBC ONBOARD UART)
UART0CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART1IOB .EQU $80 ; IOBASE (CASSETTE INTERFACE)
UART1CFG .EQU SER_300_8N1 ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART2IOB .EQU $48 ; IOBASE (MF/PIC)
UART2CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART3IOB .EQU $C0 ; IOBASE (4UART PORT A)
UART3CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART4IOB .EQU $C8 ; IOBASE (4UART PORT B)
UART4CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART5IOB .EQU $D0 ; IOBASE (4UART PORT C)
UART5CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
UART6IOB .EQU $D8 ; IOBASE (4UART PORT D)
UART6CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
;
ASCIENABLE .EQU FALSE ; TRUE FOR Z180 ASCI SUPPORT
;
VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT
CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT

6
Source/HBIOS/Config/plt_zeta.asm

@ -18,13 +18,9 @@ SIMRTCENABLE .EQU FALSE ; SIMH CLOCK DRIVER
DSRTCENABLE .EQU TRUE ; DS-1302 CLOCK DRIVER
DSRTCMODE .EQU DSRTCMODE_STD ; DSRTCMODE_STD, DSRTCMODE_MFPIC
;
ASCIENABLE .EQU FALSE ; TRUE FOR Z180 ASCI SUPPORT
UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE)
UARTOSC .EQU 1843200 ; UART OSC FREQUENCY
UARTCNT .EQU 1 ; NUMBER OF UARTS
UART0IOB .EQU $68 ; IOBASE (SBC ONBOARD UART)
UART0CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
;
ASCIENABLE .EQU FALSE ; TRUE FOR Z180 ASCI SUPPORT
;
VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT
CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT

2
Source/HBIOS/MakeBlankROM.ps1

@ -1,4 +1,4 @@
# Create a "dummy" rom image, filled with hex E5
# Create a "blank" rom disk image, filled with hex E5
#
Set-Content -Value ([byte[]](0xE5) * (512KB - 128KB)) -Encoding byte -Path 'Blank512KB.dat'
Set-Content -Value ([byte[]](0xE5) * (1MB - 128KB)) -Encoding byte -Path 'Blank1024KB.dat'

58
Source/HBIOS/asci.asm

@ -3,6 +3,13 @@
; ASCI DRIVER (Z180 SERIAL PORTS)
;==================================================================================================
;
; SETUP PARAMETER WORD:
; +-------+---+-------------------+ +---+---+-----------+---+-------+
; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 |
; +-------+---+---+---------------+ ----+---+-----------+---+-------+
; F E D C B A 9 8 7 6 5 4 3 2 1 0
; -- MSB (D REGISTER) -- -- LSB (E REGISTER) --
;
; STAT:
; 7 6 5 4 3 2 1 0
; R O P F R C T T
@ -57,13 +64,13 @@
; | +-------------- DCD0 DISABLE
; +---------------- RDRF INT INHIBIT
;
ASCI_INIT:
ASCI_PREINIT:
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180
LD C,0 ; PHYSICAL UNIT INDEX
ASCI_INIT1:
ASCI_PREINIT1:
PUSH BC ; SAVE LOOP CONTROL
LD D,C ; PHYSICAL UNIT
LD E,CIODEV_ASCI ; DEVICE TYPE
@ -71,7 +78,20 @@ ASCI_INIT1:
CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT PHYSICAL UNIT
DJNZ ASCI_INIT1 ; LOOP UNTIL DONE
DJNZ ASCI_PREINIT1 ; LOOP UNTIL DONE
;
LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG
CALL ASCI0_INITDEV ; INIT DEVICE
;
LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG
CALL ASCI1_INITDEV ; INIT DEVICE
;
XOR A ; SIGNAL SUCCESS
RET
;
;
;
ASCI_INIT:
;
; ASCI0
CALL NEWLINE ; FORMATTING
@ -86,13 +106,7 @@ ASCI_INIT1:
CALL PC_SPACE ; FORMATTING
LD DE,(ASCI0_CONFIG) ; LOAD CONFIG
CALL PS_PRTSC0 ; PRINT IT
LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG
CALL ASCI0_INITDEV ; INIT DEVICE
JR Z,ASCI_INIT2 ; SUCCESS, SKIP AHEAD
PRTS(" ERROR!$") ; DISPLAY ERROR
;
ASCI_INIT2:
; ASCI1
CALL NEWLINE ; FORMATTING
PRTS("ASCI1: IO=0x$") ; PREFIX
@ -106,13 +120,7 @@ ASCI_INIT2:
CALL PC_SPACE ; FORMATTING
LD DE,(ASCI1_CONFIG) ; LOAD CONFIG
CALL PS_PRTSC0 ; PRINT IT
LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG
CALL ASCI1_INITDEV ; INIT DEVICE
JR Z,ASCI_INIT3 ; SUCCESS, SKIP AHEAD
PRTS(" ERROR!$") ; DISPLAY ERROR
;
ASCI_INIT3:
XOR A
RET
;
@ -343,8 +351,8 @@ ASCI1_DEVICE:
;
; LOCAL DATA
;
ASCI0_CONFIG .DW ASCI0CFG ; SAVED CONFIG FOR ASCI0
ASCI1_CONFIG .DW ASCI1CFG ; SAVED CONFIG FOR ASCI1
ASCI0_CONFIG .DW DEFSERCFG ; SAVED CONFIG FOR ASCI0
ASCI1_CONFIG .DW DEFSERCFG ; SAVED CONFIG FOR ASCI1
;
; DERIVE A CNTLB VALUE BASED ON AN ENCODED BAUD RATE AND CURRENT CPU SPEED
; ENTRY: HL = ENCODED BAUD RATE
@ -366,9 +374,21 @@ ASCI_CNTLB:
;CALL TSTPT
RET NZ ; ABORT ON ERROR
PUSH HL ; HL HAS (BAUD / 75), SAVE IT
;LD HL,(HCB + HCB_CPUKHZ) ; GET CPU CLK IN KHZ
LD HL,CPUKHZ ; CPU CLK IN KHZ
LD HL,(HCB + HCB_CPUKHZ) ; GET CPU CLK IN KHZ
;LD HL,CPUKHZ ; CPU CLK IN KHZ
;LD HL,9216 ; *DEBUG*
; DUE TO THE LIMITED DIVISORS POSSIBLE WITH CNTLB, YOU PRETTY MUCH
; NEED TO USE A CPU SPEED THAT IS A MULTIPLE OF 128KHZ. BELOW, WE
; ATTEMPT TO ROUND THE CPU SPEED DETECTED TO A MULTIPLE OF 128KHZ
; WITH ROUNDING. THIS JUST MAXIMIZES POSSIBILITY OF SUCCESS COMPUTING
; THE DIVISOR.
LD DE,$0040 ; HALF OF 128 IS 64
ADD HL,DE ; ADD FOR ROUNDING
LD A,L ; MOVE TO ACCUM
AND $80 ; STRIP LOW ORDER 7 BITS
LD L,A ; ... AND PUT IT BACK
LD DE,12 ; PREPARE TO DIVIDE BY 12
CALL DIV16 ; BC := (CPU_KHZ / 12), REM IN HL, ZF
;CALL TSTPT

55
Source/HBIOS/encode.asm

@ -6,7 +6,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; An encoded value (V) is defined as V = C * 2^X * 3^Y
; where C is a prearranged constant, X is 0 or 1 and Y is 0-15
; where C is a prearranged constant, Y is 0 or 1 and X is 0-15
; The encoded value is stored as 5 bits: YXXXX
; At present, C=75 for baud rate encoding and C=3 for CPU OSC encoding
;
@ -24,37 +24,44 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
ENCODE:
; *** MAKE SURE INCOMING VALUE IS NOT ZERO???
; INCOMING VALUE OF ZERO IS A FAILURE
CALL ENCODE5 ; TEST DE:HL FOR ZERO
JR Z,ENCODE4 ; IF ZERO, FAILURE RETURN
;
; APPLY ENCODING DIVISOR
CALL DIV32X8 ; DE:HL / C (REMAINDER IN A)
OR A ; SET FLAGS TO TEST FOR ZERO
RET NZ ; ERROR IF NOT EVENLY DIVISIBLE
; APPLY DIV 3 IF POSSIBLE
LD BC,ENCODE_TMP ; SAVE WORKING VALUE
CALL ST32 ; ... IN TEMP
LD C,3 ; ATTEMPT DIVIDE
CALL DIV32X8 ; ... BY 3
OR A ; SET FLAGS TO TEST FOR ZERO
JR Z,ENCODE1 ; JUMP IF IT WORKED
LD HL,ENCODE_TMP ; FAILED, RESTORE
CALL LD32 ; ... PRIOR WORKING VALUE
LD C,0 ; INIT RESULT IN C W/O DIV 3 FLAG
JR ENCODE2
ENCODE1:
LD C,$10 ; INIT RESULT IN C W/ DIV 3 FLAG
;
; TEST DIVIDE BY 3 TO SEE IF IT IS POSSIBLE
PUSH DE ; SAVE WORKING
PUSH HL ; ... VALUE
LD C,3 ; DIVIDE BY 3
CALL DIV32X8 ; ... TEST
POP HL ; RESTORE WORKING
POP DE ; ... VALUE
;
; IMPLMEMENT DIVIDE BY 3 IF POSSIBLE
LD C,$00 ; INIT RESULT IN C W/ DEV 3 FLAG CLEAR
OR A ; SET FLAGS TO TEST FOR REMAINDER
JR NZ,ENCODE2 ; JUMP IF IT FAILED
;
; IF DIVIDE BY 3 WORKED, DO IT AGAIN FOR REAL
LD C,3 ; SETUP TO DIVIDE BY 3 AGAIN
CALL DIV32X8 ; DO IT
LD C,$10 ; INIT RESULT IN C W/ DIV 3 FLAG SET
;
ENCODE2:
; LOOP TO DETERMINE POWER OF 2
LD B,32
LD B,16 ; CAN ONLY REPRESENT UP TO 2^15
ENCODE3:
SRL D
RR E
RR H
RR L
JR C,ENCODE5 ; DONE, C HAS RESULT
SRL D ; RIGHT SHIFT DE:HL INTO CARRY
RR E ; ...
RR H ; ...
RR L ; ...
JR C,ENCODE5 ; IF CARRY, THEN DONE, C HAS RESULT
INC C ; BUMP THE RESULT VALUE
DJNZ ENCODE3
DJNZ ENCODE3 ; KEEP SHIFTING IF POSSIBLE
ENCODE4:
OR $FF ; SIGNAL ERROR
RET ; AND DONE
@ -65,6 +72,4 @@ ENCODE5:
OR L
OR D
OR E
RET ; RET W/ Z SET IF SUCCESSFUL
;
ENCODE_TMP .FILL 4,0 ; TEMP DWORD VALUE
RET ; RET W/ Z SET IF DE:HL == 0

267
Source/HBIOS/hbios.asm

@ -498,27 +498,7 @@ HB_START:
;
CALL DELAY_INIT ; INITIALIZE SPEED COMPENSATED DELAY FUNCTIONS
;
; ANNOUNCE HBIOS
;
;
; DISPLAY THE PRE-INITIALIZATION BANNER
;
CALL NEWLINE2
PRTX(STR_BANNER)
CALL NEWLINE2
PRTX(STR_PLATFORM)
PRTS(" @ $")
LD HL,(HCB + HCB_CPUKHZ)
CALL PRTD3M ; PRINT AS DECIMAL WITH 3 DIGIT MANTISSA
PRTS("MHz ROM=$")
LD HL,ROMSIZE
CALL PRTDEC
PRTS("KB RAM=$")
LD HL,RAMSIZE
CALL PRTDEC
PRTS("KB$")
;
; INITIALIZE HEAP STORAGE VARIABLES
; INITIALIZE HEAP STORAGE
;
LD DE,HB_END ; GET ADDRESS OF START OF HEAP
;
@ -540,6 +520,39 @@ HB_START:
LD A,$FF ; FILL WITH $FF
CALL FILL ; DO IT
;
; PRE-CONSOLE INITIALIZATION
;
#IF (ASCIENABLE)
CALL ASCI_PREINIT
#ENDIF
#IF (UARTENABLE)
CALL UART_PREINIT
#ENDIF
;
; PRIOR TO THIS POINT, CONSOLE I/O WAS DIRECTED TO HARDWARE (XIO.ASM).
; NOW THAT HBIOS IS READY, SET THE CONSOLE UNIT TO ACTIVATE CONSOLE I/O
; VIA HBIOS.
;
XOR A ; CONSOLE DEVICE IS UNIT #0 BY FIAT
LD (HCB + HCB_CONDEV),A ; SAVE IT, ACTIVATES CONSOLE ON HBIOS
;
; ANNOUNCE HBIOS
;
CALL NEWLINE2
PRTX(STR_BANNER)
CALL NEWLINE2
PRTX(STR_PLATFORM)
PRTS(" @ $")
LD HL,(HCB + HCB_CPUKHZ)
CALL PRTD3M ; PRINT AS DECIMAL WITH 3 DIGIT MANTISSA
PRTS("MHz ROM=$")
LD HL,ROMSIZE
CALL PRTDEC
PRTS("KB RAM=$")
LD HL,RAMSIZE
CALL PRTDEC
PRTS("KB$")
;
; PERFORM DEVICE INITIALIZATION
;
LD B,HB_INITTBLLEN
@ -565,13 +578,21 @@ INITSYS1:
;
LD HL,(HCB + HCB_HEAPTOP)
LD (HEAPCURB),HL
;
; PRIOR TO THIS POINT, CONSOLE I/O WAS DIRECTED TO HARDWARE (XIO.ASM).
; NOW THAT HBIOS IS READY, SET THE CONSOLE UNIT TO ACTIVATE CONSOLE I/O
; VIA HBIOS.
;
XOR A ; CONSOLE DEVICE IS UNIT #0 BY FIAT
LD (HCB + HCB_CONDEV),A ; SAVE IT, ACTIVATES CONSOLE ON HBIOS
;;
;; RUN THROUGH ALL SERIAL DEVICES AND PERFORM FULL INITIALIZATION
;;
; LD A,(CIO_CNT) ; GET SERIAL DEVICE COUNT
; LD B,A ; INIT LOOP COUNTER
; LD C,0 ; INIT UNIT INDEX
;INITSYS2:
; PUSH BC ; SAVE LOOP CONTROL
; LD B,BF_CIOINIT ; FUNC: INIT
; LD DE,-1 ; INIT W/ CURRENT CONFIG
; CALL CIO_DISPATCH ; CALL SERIAL UNIT DISPATCHER
; ;CALL NZ,????? ; IF ERROR, SHOW IT
; POP BC ; RESTORE LOOP CONTROL
; INC C ; NEXT UNIT
; DJNZ INITSYS2 ; LOOP TILL ALL UNITS DONE
;
; NOW SWITCH TO CRT CONSOLE IF CONFIGURED
;
@ -583,7 +604,7 @@ INITSYS1:
#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,INITSYS2 ; Z=SHORTED, BYPASS CONSOLE SWITCH
JR Z,INITSYS3 ; Z=SHORTED, BYPASS CONSOLE SWITCH
#ENDIF
;
; NOTIFY USER OF CONSOLE SWITCH ON BOOT CONSOLE
@ -599,7 +620,7 @@ INITSYS1:
PRTX(STR_BANNER)
#ENDIF
;
INITSYS2:
INITSYS3:
;
CALL PRTSUM ; PRINT UNIT/DEVICE SUMMARY TABLE
;
@ -1778,9 +1799,7 @@ SIZ_TERM .EQU $ - ORG_TERM
#INCLUDE "dsky.asm"
#ENDIF
;
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
;
; DETECT Z80 CPU SPEED USING DS-1302 RTC
; DETECT CPU SPEED USING DS-1302 RTC
;
HB_CPUSPD:
;
@ -1797,21 +1816,42 @@ HB_CPUSPD:
RET NZ
;
HB_CPUSPD1:
; WATT FOR AN INITIAL TICK TO ALIGN, THEN WAIT
; 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_WAITSECS ; WAIT FOR INITIAL SECS TICK
CALL HB_WAITSECS ; WAIT FOR SECS TICK AGAIN, COUNT INDE
CALL HB_RDSEC ; GET SECONDS
LD (HB_CURSEC),A ; AND INIT CURSEC
CALL HB_WAITSEC ; WAIT FOR SECONDS TICK
LD (HB_CURSEC),A ; SAVE NEW VALUE
CALL HB_WAITSEC ; WAIT FOR SECONDS TICK
; PUSH DE
; POP BC
; CALL NEWLINE
; CALL PRTHEXWORD
; POP BC
; DJNZ HB_CPUSPDX
;
LD A,H
OR L
RET Z ; FAILURE, USE DEFAULT CPU SPEED
;
; TIMES 4 (W/ ROUNDING) FOR CPU SPEED IN KHZ
INC HL
SRL H
RR L
; MOVE LOOP COUNT TO HL
PUSH DE
POP HL
;
; TIMES 4 FOR CPU SPEED IN KHZ
RES 0,L ; GRANULARITY
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
SLA L
RL H
#ENDIF
SLA L
RL H
SLA L
@ -1825,127 +1865,62 @@ HB_CPUSPD1:
;
RET
;
HB_WAITSECS:
HB_WAITSEC:
; WAIT FOR SECONDS TICK
; RETURN SECS VALUE IN A, LOOP COUNT IN DE
; LOOP TARGET IS 250 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4
LD HL,0 ; INIT LOOP COUNTER
CALL HB_RDSEC ; GET SECONDS
LD E,A ; SAVE IT
HB_WAITSECS1:
LD DE,0 ; INIT LOOP COUNTER
HB_WAITSEC1:
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
; LOOP TARGET IS 4000 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4
CALL DLY32
CALL DLY8
CALL DLY4
CALL DLY2
JP $ + 3 ; 10 TSTATES
; LD A,R ; 9 TSTATES
; INC BC ; 6 TSTATES
NOP ; 4 TSTATES
NOP ; 4 TSTATES
NOP ; 4 TSTATES
NOP ; 4 TSTATES
JP $ + 3 ; 10 TSTATES
JP $ + 3 ; 10 TSTATES
JP $ + 3 ; 10 TSTATES
;LD A,R ; 9 TSTATES
INC BC ; 6 TSTATES
;LD A,(BC) ; 7 TSTATES
;NOP ; 4 TSTATES
NOP ; 4 TSTATES
;
CALL HB_RDSEC ; GET SECONDS
INC HL ; BUMP COUNTER
CP E ; EQUAL?
RET NZ ; DONE IF TICK OCCURRED
LD A,H ; CHECK HL
OR L ; ... FOR OVERFLOW
RET Z ; TIMEOUT, SOMETHING IS WRONG
JR HB_WAITSECS1 ; LOOP
;
HB_RDSEC:
; READ SECONDS BYTE INTO A
LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG
CALL DSRTC_CMD ; SEND THE COMMAND
CALL DSRTC_GET ; READ THE REGISTER
CALL DSRTC_END ; FINISH IT
RET
;
#ELSE
;
RET ; NO RTC, ABORT
;
#ENDIF
;
#ENDIF
;
;
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
;
; DETECT Z180 CPU SPEED USING DS-1302 RTC
;
HB_CPUSPD:
;
#IF (DSRTCENABLE)
;
CALL DSRTC_TSTCLK ; IS CLOCK RUNNING?
JR Z,HB_CPUSPD1 ; YES, CONTINUE
; MAKE SURE CLOCK IS RUNNING
LD HL,DSRTC_TIMDEF
CALL DSRTC_TIM2CLK
LD HL,DSRTC_BUF
CALL DSRTC_WRCLK
CALL DSRTC_TSTCLK ; NOW IS CLOCK RUNNING?
RET NZ
;
HB_CPUSPD1:
; WATT FOR AN INITIAL TICK TO ALIGN, THEN WAIT
; FOR SECOND TICK AND TO GET A FULL ONE SECOND LOOP COUNT
CALL HB_WAITSECS ; WAIT FOR INITIAL SECS TICK
CALL HB_WAITSECS ; WAIT FOR SECS TICK AGAIN, COUNT INDE
;
LD A,H
OR L
RET Z ; FAILURE, USE DEFAULT CPU SPEED
;
; TIMES 8 FOR CPU SPEED IN KHZ
SLA L
RL H
SLA L
RL H
SLA L
RL H
;
LD (HCB + HCB_CPUKHZ),HL
LD DE,1000
CALL DIV16
LD A,C
LD (HCB + HCB_CPUMHZ),A
;
RET
;
HB_WAITSECS:
; WAIT FOR SECONDS TICK
; RETURN SECS VALUE IN A, LOOP COUNT IN DE
; LOOP TARGET IS 250 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4
LD HL,0 ; INIT LOOP COUNTER
CALL HB_RDSEC ; GET SECONDS
LD E,A ; SAVE IT
HB_WAITSECS1:
CALL DLY64
; LOOP TARGET IS 8000 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 8
;CALL DLY64
CALL DLY32
CALL DLY16
CALL DLY8
CALL DLY4
CALL DLY2
CALL DLY1 ; CALL (25TS) & RET (18TS) = 43TS
OR A ; 7 TSTATES
OR A ; 7 TSTATES
;OR A ; 7 TSTATES
;OR A ; 7 TSTATES
;OR A ; 7 TSTATES
NOP ; 6 TSTATES
NOP ; 6 TSTATES
NOP ; 6 TSTATES
NOP ; 6 TSTATES
;NOP ; 6 TSTATES
;NOP ; 6 TSTATES
;NOP ; 6 TSTATES
;NOP ; 6 TSTATES
#ENDIF
;
PUSH DE
CALL HB_RDSEC ; GET SECONDS
INC HL ; BUMP COUNTER
CP E ; EQUAL?
POP DE
INC DE ; BUMP COUNTER
LD HL,HB_CURSEC ; POINT TO COMP VALUE
CP (HL) ; TEST FOR CHANGE
RET NZ ; DONE IF TICK OCCURRED
LD A,H ; CHECK HL
OR L ; ... FOR OVERFLOW
LD A,D ; CHECK HL
OR E ; ... FOR OVERFLOW
RET Z ; TIMEOUT, SOMETHING IS WRONG
JR HB_WAITSECS1 ; LOOP
JR HB_WAITSEC1 ; LOOP
;
HB_RDSEC:
; READ SECONDS BYTE INTO A
LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG
LD C,$81 ; SECONDS REGISTER
CALL DSRTC_CMD ; SEND THE COMMAND
CALL DSRTC_GET ; READ THE REGISTER
CALL DSRTC_END ; FINISH IT
@ -1957,8 +1932,6 @@ HB_RDSEC:
;
#ENDIF
;
#ENDIF
;
; PRINT VALUE OF HL AS THOUSANDTHS, IE. 0.000
;
PRTD3M:
@ -2552,7 +2525,7 @@ COUT:
PUSH HL
;
; GET CURRENT CONSOLE UNIT
LD E,A ; OUTPUT CHAR TO E
LD E,A ; TEMPORARILY STASH OUTPUT CHAR IN E
LD A,(HCB + HCB_CONDEV) ; GET CONSOLE UNIT BYTE
CP $FF ; TEST FOR $FF (HBIOS NOT READY)
JR Z,COUT1 ; IF NOT READY, USE XIO
@ -2597,7 +2570,7 @@ CIN:
;
CIN1:
; USE XIO
CALL PANIC ; NOT YET SUPPORTED
CALL XIO_INC ; GET CHAR
;
CIN2:
;
@ -2627,7 +2600,7 @@ CST:
;
CST1:
; USE XIO
CALL PANIC ; NOT YET SUPPORTED
CALL XIO_IST ; GET STATUS
;
CST2:
; RESTORE REGISTERS (AF IS OUTPUT)
@ -2674,6 +2647,8 @@ STR_BANNER .DB "RetroBrew HBIOS v", BIOSVER, ", ", TIMESTAMP, "$"
STR_PLATFORM .DB PLATFORM_NAME, "$"
STR_SWITCH .DB "*** Activating CRT Console ***$"
;
HB_CURSEC .DB 0
;
HB_BCDTMP .FILL 5,0 ; TEMPORARY BCD NUMBER STORAGE
;
HB_WRKBUF .FILL 512,0 ; INTERNAL DISK BUFFER

9
Source/HBIOS/loader.asm

@ -214,13 +214,6 @@ PHASE2:
CALL XIO_DOT ; MARK PROGRESS
CALL HB_BNKCPY ; DO IT
CALL XIO_DOT ; MARK PROGRESS
;; HACK TO FLUSH THE OUTPUT FIFO
;XOR A
;CALL XIO_OUTC
;CALL XIO_OUTC
;CALL XIO_OUTC
;CALL XIO_OUTC
;
; INSTALL HCB INTO HBIOS CODE BANK
;
@ -233,8 +226,10 @@ PHASE2:
CALL HB_BNKCPY ; DO IT
CALL XIO_DOT ; MARK PROGRESS
;
;
; INITIALIZE HBIOS
;
CALL XIO_SYNC ; FLUSH OUTPUT FIFO
LD A,BID_BIOS ; HBIOS BANK
LD HL,0 ; ADDRESS 0 IS HBIOS INIT ENTRY ADDRESS
CALL HB_BNKCALL ; DO IT

204
Source/HBIOS/uart.asm

@ -3,19 +3,18 @@
; UART DRIVER (SERIAL PORT)
;==================================================================================================
;
; Setup Parameter Word:
; _______________________________ _______________________________
; | | | encoded || | | | | |
; | |rts| Baud Rate ||dtr|xon| parity |stp| 8/7/6 |
; |_______|___|___|_______________||___|___|___________|___|_______|
; 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
; D register E register
;
; _______________________________ _______________________________
; | | | || | | | | |
; | 0 0 |AFE|LP OT2 OT1 RTS DTR||DLB|BRK|STK EPS PEN|STB| WLS |
; |_______|___|___________________||___|___|___________|___|_______|
; 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
; SETUP PARAMETER WORD:
; +-------+---+-------------------+ +---+---+-----------+---+-------+
; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 |
; +-------+---+---+---------------+ ----+---+-----------+---+-------+
; F E D C B A 9 8 7 6 5 4 3 2 1 0
; -- MSB (D REGISTER) -- -- LSB (E REGISTER) --
;
; UART CONFIGURATION REGISTERS:
; +-------+---+-------------------+ +---+---+-----------+---+-------+
; | 0 0 |AFE|LP OT2 OT1 RTS DTR| |DLB|BRK|STK EPS PEN|STB| WLS |
; +-------+---+-------------------+ +---+---+-----------+---+-------+
; F E D C B A 9 8 7 6 5 4 3 2 1 0
; -- MCR -- -- LCR --
;
;
@ -46,20 +45,16 @@ UART_SCR .EQU 7 ; SCRATCH REGISTER (READ/WRITE)
UART_DLL .EQU 0 ; DLAB=1: DIVISOR LATCH (LS) (READ/WRITE)
UART_DLM .EQU 1 ; DLAB=1: DIVISOR LATCH (MS) (READ/WRITE)
UART_EFR .EQU 2 ; LCR=$BF: ENHANCED FEATURE REG (READ/WRITE)
;
UART_FIFO .EQU 0 ; FIFO ENABLE BIT
UART_AFC .EQU 1 ; AUTO FLOW CONTROL ENABLE BIT
;;
;UART_FIFO .EQU 0 ; FIFO ENABLE BIT
;UART_AFC .EQU 1 ; AUTO FLOW CONTROL ENABLE BIT
;
#DEFINE UART_INP(RID) CALL UART_INP_IMP \ .DB RID
#DEFINE UART_OUTP(RID) CALL UART_OUTP_IMP \ .DB RID
;
; CHARACTER DEVICE DRIVER ENTRY
; A: RESULT (OUT), CF=ERR
; B: FUNCTION (IN)
; C: CHARACTER (IN/OUT)
; E: DEVICE/UNIT (IN)
;
UART_INIT:
;
UART_PREINIT:
;
; INIT UART4 BOARD CONFIG REGISTER (NO HARM IF IT IS NOT THERE)
;
@ -68,11 +63,11 @@ UART_INIT:
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,UARTCNT ; LOOP CONTROL
LD B,UART_CNT ; LOOP CONTROL
LD C,0 ; PHYSICAL UNIT INDEX
XOR A ; ZERO TO ACCUM
LD (UART_DEV),A ; CURRENT DEVICE NUMBER
UART_INIT0:
UART_PREINIT0:
PUSH BC ; SAVE LOOP CONTROL
LD A,C ; PHYSICAL UNIT TO A
RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES)
@ -83,39 +78,28 @@ UART_INIT0:
PUSH HL ; SAVE IT
PUSH HL ; COPY CFG DATA PTR
POP IY ; ... TO IY
CALL UART_INITP ; HAND OFF TO GENERIC INIT CODE
CALL UART_INITUNIT ; HAND OFF TO GENERIC INIT CODE
POP DE ; GET ENTRY ADDRESS BACK, BUT PUT IN DE
POP BC ; RESTORE LOOP CONTROL
;
LD A,(IY + 1) ; GET THE UART TYPE DETECTED
OR A ; SET FLAGS
JR Z,UART_INIT1 ; SKIP IT IF NOTHING FOUND
JR Z,UART_PREINIT2 ; SKIP IT IF NOTHING FOUND
;
PUSH BC ; SAVE LOOP CONTROL
LD BC,UART_DISPATCH ; BC := DISPATCH ADDRESS
CALL NZ,CIO_ADDENT ; ADD ENTRY IF UART FOUND, BC:DE
POP BC ; RESTORE LOOP CONTROL
;
UART_INIT1:
UART_PREINIT2:
INC C ; NEXT PHYSICAL UNIT
DJNZ UART_INIT0 ; LOOP UNTIL DONE
DJNZ UART_PREINIT0 ; LOOP UNTIL DONE
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; UART INITIALIZATION ROUTINE
;
UART_INITP:
; WAIT FOR ANY IN-FLIGHT DATA TO BE SENT
LD B,0 ; LOOP TIMEOUT COUNTER
UART_INITP1:
UART_INP(UART_LSR) ; GET LINE STATUS REGISTER
BIT 6,A ; TEST BIT 6 (TRANSMITTER EMPTY)
JR NZ,UART_INITP2 ; EMPTY, CONTINUE
LD DE,100 ; DELAY 100 * 16US
CALL VDELAY ; NORMALIZE TIMEOUT TO CPU SPEED
DJNZ UART_INITP1 ; KEEP CHECKING UNTIL TIMEOUT
UART_INITP2:
UART_INITUNIT:
; DETECT THE UART TYPE
CALL UART_DETECT ; DETERMINE UART TYPE
LD (IY + 1),A ; ALSO SAVE IN CONFIG TABLE
@ -130,10 +114,36 @@ UART_INITP2:
; SET DEFAULT CONFIG
LD DE,-1 ; LEAVE CONFIG ALONE
CALL UART_INITDEV ; IMPLEMENT IT
JP UART_INITDEV ; IMPLEMENT IT AND RETURN
;
;
;
;
UART_INIT:
LD B,UART_CNT ; COUNT OF POSSIBLE UART UNITS
LD C,0 ; INDEX INTO UART CONFIG TABLE
UART_INIT1:
PUSH BC ; SAVE LOOP CONTROL
LD A,C ; PHYSICAL UNIT TO A
RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES)
RLCA ; ...
RLCA ; ... TO GET OFFSET INTO CFG TABLE
LD HL,UART_CFG ; POINT TO START OF CFG TABLE
CALL ADDHLA ; HL := ENTRY ADDRESS
PUSH HL ; COPY CFG DATA PTR
POP IY ; ... TO IY
LD A,(IY + 1) ; GET UART TYPE
OR A ; SET FLAGS
CALL NZ,UART_PRTCFG ; PRINT IF NOT ZERO
; DISPLAY UART CONFIG AND RETURN
JP UART_PRTCFG
POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT UNIT
DJNZ UART_INIT1 ; LOOP TILL DONE
;
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
;
;
@ -239,8 +249,9 @@ UART_INITDEV1:
LD A,%00100111 ; FIFO ENABLE & RESET, 64 BYTE FIFO ENABLE ON 750+
UART_OUTP(UART_FCR) ; DO IT
;
; SETUP LCR TO DEFAULT (DLAB IS CLEARED)
LD A,$03 ; DLAB OFF, 8 DATA, 1 STOP, NO PARITY
; SETUP LCR FROM SECOND CONFIG BYTE (DLAB IS CLEARED)
LD A,(IY + 4) ; GET CONFIG BYTE
AND ~$C0 ; ISOLATE PARITY, STOP/DATA BITS
UART_OUTP(UART_LCR) ; SAVE IT
;
; SETUP MCR FROM FIRST CONFIG BYTE
@ -248,10 +259,6 @@ UART_INITDEV1:
AND ~$1F ; REMOVE ENCODED BAUD RATE BITS
OR $03 ; FORCE RTS & DTR
UART_OUTP(UART_MCR) ; SAVE IT
;
; SPECIAL HANDLING FOR AFC ON UARTS WITH EFR REGISTER
BIT 5,A ; IS FLOW CONTOL REQUESTED?
JR Z,UART_INITDEV3 ; NOPE, SKIP AHEAD
;
; TEST FOR EFR CAPABLE CHIPS
LD A,(IY + 1) ; GET UART TYPE
@ -259,20 +266,26 @@ UART_INITDEV1:
JR Z,UART_INITDEV2 ; USE EFR REGISTER
CP UART_16850 ; 16850?
JR Z,UART_INITDEV2 ; USE EFR REGISTER
JR UART_INITDEV3 ; NO EFT, SKIP AHEAD
JR UART_INITDEV4 ; NO EFT, SKIP AHEAD
;
UART_INITDEV2:
; WE HAVE AN EFR CAPABLE CHIP, SET AUTOFLOW IN EFR REGISTER
; WE HAVE AN EFR CAPABLE CHIP, SET EFR REGISTER
UART_INP(UART_LCR) ; GET CURRENT LCR VALUE
PUSH AF ; SAVE IT
LD A,$BF ; VALUE TO ACCESS EFR
UART_OUTP(UART_LCR) ; SET VALUE IN LCR
LD A,$C0 ; ENABLE CTS/RTS FLOW CONTROL
LD A,(IY + 5) ; GET CONFIG BYTE
BIT 5,A ; AFC REQUESTED?
LD A,$C0 ; ASSUME AFC ON
JR NZ,UART_INITDEV3 ; YES, IMPLEMENT IT
XOR A ; NO AFC REQEUST, EFR := 0
;
UART_INITDEV3:
UART_OUTP(UART_EFR) ; SAVE IT
POP AF ; RECOVER ORIGINAL LCR VALUE
UART_OUTP(UART_LCR) ; AND SAVE IT
UART_OUTP(UART_LCR) ; AND PUT IT BACK
;
UART_INITDEV3:
UART_INITDEV4:
#IF (UART_DEBUG)
PRTS(" [$")
@ -327,7 +340,7 @@ UART_QUERY:
;
UART_DEVICE:
LD D,CIODEV_UART ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
LD E,(IY) ; E := PHYSICAL UNIT
XOR A ; SIGNAL SUCCESS
RET
;
@ -496,13 +509,13 @@ UART_PRTCFG:
; ; PRINT FEATURES ENABLED
; LD A,(UART_FEAT)
; BIT UART_FIFO,A
; JR Z,UART_INITP2
; JR Z,UART_INITUNIT2
; PRTS(" FIFO$")
;UART_INITP2:
;UART_INITUNIT2:
; BIT UART_AFC,A
; JR Z,UART_INITP3
; JR Z,UART_INITUNIT3
; PRTS(" AFC$")
;UART_INITP3:
;UART_INITUNIT3:
;
XOR A
RET
@ -570,67 +583,68 @@ UART_DEV .DB 0 ; DEVICE NUM USED DURING INIT
; UART PORT TABLE
;
UART_CFG:
#IF (UARTCNT >= 1)
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
; SBC/ZETA ONBOARD SERIAL PORT
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART0IOB ; IO PORT BASE (RBR, THR)
.DB UART0IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART0CFG ; LINE CONFIGURATION
.DB $68 ; IO PORT BASE (RBR, THR)
.DB $68 + UART_LSR ; LINE STATUS PORT (LSR)
.DW DEFSERCFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 2)
#IF (PLATFORM == PLT_SBC) | (PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; CASSETTE INTERFACE SERIAL PORT
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART1IOB ; IO PORT BASE (RBR, THR)
.DB UART1IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART1CFG ; LINE CONFIGURATION
.DB $80 ; IO PORT BASE (RBR, THR)
.DB $80 + UART_LSR ; LINE STATUS PORT (LSR)
.DW SER_300_8N1 ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 3)
#IF (PLATFORM == PLT_SBC)
; MF/PIC SERIAL PORT
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART2IOB ; IO PORT BASE (RBR, THR)
.DB UART2IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART2CFG ; LINE CONFIGURATION
.DB $48 ; IO PORT BASE (RBR, THR)
.DB $48 + UART_LSR ; LINE STATUS PORT (LSR)
.DW DEFSERCFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 4)
#IF (PLATFORM == PLT_SBC) | (PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; 4UART SERIAL PORT A
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART3IOB ; IO PORT BASE (RBR, THR)
.DB UART3IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART3CFG ; LINE CONFIGURATION
.DB $C0 ; IO PORT BASE (RBR, THR)
.DB $C0 + UART_LSR ; LINE STATUS PORT (LSR)
.DW DEFSERCFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 5)
#IF (PLATFORM == PLT_SBC) | (PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; 4UART SERIAL PORT B
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART4IOB ; IO PORT BASE (RBR, THR)
.DB UART4IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART4CFG ; LINE CONFIGURATION
.DB $C8 ; IO PORT BASE (RBR, THR)
.DB $C8 + UART_LSR ; LINE STATUS PORT (LSR)
.DW DEFSERCFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 6)
#IF (PLATFORM == PLT_SBC) | (PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; 4UART SERIAL PORT C
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART5IOB ; IO PORT BASE (RBR, THR)
.DB UART5IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART5CFG ; LINE CONFIGURATION
.DB $D0 ; IO PORT BASE (RBR, THR)
.DB $D0 + UART_LSR ; LINE STATUS PORT (LSR)
.DW DEFSERCFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 7)
#IF (PLATFORM == PLT_SBC) | (PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; 4UART SERIAL PORT D
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART6IOB ; IO PORT BASE (RBR, THR)
.DB UART6IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART6CFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
#IF (UARTCNT >= 8)
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
.DB 0 ; UART TYPE
.DB UART7IOB ; IO PORT BASE (RBR, THR)
.DB UART7IOB + UART_LSR ; LINE STATUS PORT (LSR)
.DW UART7CFG ; LINE CONFIGURATION
.DB $D8 ; IO PORT BASE (RBR, THR)
.DB $D8 + UART_LSR ; LINE STATUS PORT (LSR)
.DW DEFSERCFG ; LINE CONFIGURATION
.FILL 2,$FF ; FILLER
#ENDIF
;
UART_CNT .EQU ($ - UART_CFG) / 8

1
Source/HBIOS/util.asm

@ -643,7 +643,6 @@ DLY8: CALL DLY4
DLY4: CALL DLY2
DLY2: CALL DLY1
DLY1: RET
;
; MULTIPLY 8-BIT VALUES
; IN: MULTIPLY H BY E

205
Source/HBIOS/xio.asm

@ -9,21 +9,28 @@
;
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
;
SIO_RBR .EQU UART0IOB + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY)
SIO_THR .EQU UART0IOB + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY)
SIO_IER .EQU UART0IOB + 1 ; DLAB=0: INT ENABLE REG
SIO_IIR .EQU UART0IOB + 2 ; INT IDENT REGISTER (READ ONLY)
SIO_FCR .EQU UART0IOB + 2 ; FIFO CONTROL REG (WRITE ONLY)
SIO_LCR .EQU UART0IOB + 3 ; LINE CONTROL REG
SIO_MCR .EQU UART0IOB + 4 ; MODEM CONTROL REG
SIO_LSR .EQU UART0IOB + 5 ; LINE STATUS REG
SIO_MSR .EQU UART0IOB + 6 ; MODEM STATUS REG
SIO_SCR .EQU UART0IOB + 7 ; SCRATCH REGISTER
SIO_DLL .EQU UART0IOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
SIO_DLM .EQU UART0IOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
UARTIOB .EQU $68
;
SIO_RBR .EQU UARTIOB + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY)
SIO_THR .EQU UARTIOB + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY)
SIO_IER .EQU UARTIOB + 1 ; DLAB=0: INT ENABLE REG
SIO_IIR .EQU UARTIOB + 2 ; INT IDENT REGISTER (READ ONLY)
SIO_FCR .EQU UARTIOB + 2 ; FIFO CONTROL REG (WRITE ONLY)
SIO_LCR .EQU UARTIOB + 3 ; LINE CONTROL REG
SIO_MCR .EQU UARTIOB + 4 ; MODEM CONTROL REG
SIO_LSR .EQU UARTIOB + 5 ; LINE STATUS REG
SIO_MSR .EQU UARTIOB + 6 ; MODEM STATUS REG
SIO_SCR .EQU UARTIOB + 7 ; SCRATCH REGISTER
SIO_DLL .EQU UARTIOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
SIO_DLM .EQU UARTIOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
;
XIO_DIV .EQU (UARTOSC / (16 * CONBAUD))
;
#ENDIF
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
#ENDIF
XIO_INIT: ; MINIMAL UART INIT
#IF (PLATFORM == PLT_UNA)
@ -37,19 +44,19 @@ XIO_INIT: ; MINIMAL UART INIT
OUT0 (Z180_ASEXT0),A ; -> ASEXT0
LD A,$64 ; ENABLE XMT/RCV, 8 DATA, NO PARITY, 1 STOP
OUT0 (Z180_CNTLA0),A ; -> CNTLA0
LD A,$22 ; FAILSAFE VALUE, 9600 BAUD AT 18.432 MHZ
;LD A,$20 ; FAILSAFE VALUE, 9600 BAUD AT 18.432 MHZ
;LD A,$20 ; FAILSAFE VALUE, 38400 BAUD AT 18.432 MHZ
;LD A,$22 ; FAILSAFE VALUE, 9600 BAUD AT 18.432 MHZ
;OUT0 (Z180_CNTLB0),A ; -> CNTLB0
; TRY TO IMPLEMENT CONFIGURED BAUD RATE
LD HL,ASCI0CFG ; SERIAL CONFIG WORD
LD HL,DEFSERCFG ; SERIAL CONFIG WORD
LD A,H ; BYTE W/ ENCODED BAUD RATE
AND $1F ; ISOLATE BITS
LD L,A ; MOVE TO L
LD H,0 ; CLEAR MSB
CALL XIO_CNTLB ; DERIVE CNTLB VALUE
JR Z,XIO_INIT1 ; SUCCESS, IMPLEMENT IT
LD C,$22 ; FAILSAFE VALUE, 9600 BAUD AT 18.432 MHZ
LD C,$21 + Z180_CLKDIV ; FAILSAFE VALUE, 9600 BAUD IF OSC=18.432 MHZ
XIO_INIT1:
LD A,C ; MOVE VALUE TO ACCUM
@ -58,9 +65,7 @@ XIO_INIT1:
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
;XIO_DIV .EQU (UARTOSC / (16 * CONBAUD))
LD DE,UART0CFG ; SERIAL CONFIG WORD
LD DE,DEFSERCFG ; SERIAL CONFIG WORD
CALL XIO_COMPDIV ; COMPUTE DIVISOR TO BC
LD A,$80 ; LCR := DLAB ON
@ -81,7 +86,32 @@ XIO_INIT1:
RET
;
XIO_CRLF2:
XIO_SYNC: ; WAIT FOR FOR PENDING DATA IN FIFO TO CLEAR
;
#IF (PLATFORM == PLT_UNA)
; NOT SURE ANYTHING IS POSSIBLE HERE...
#ENDIF
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; IMPLEMENT THIS... OR MAYBE NOT.
#ENDIF
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
LD DE,CPUMHZ * 25 ; FAILSAFE TIMEOUT COUNTER
XIO_SYNC1:
IN A,(SIO_LSR) ; GET LINE STATUS REGISTER
BIT 6,A ; TEST BIT 6 (TRANSMITTER EMPTY)
JR NZ,XIO_SYNC2 ; EMPTY, MOVE ON
DEC DE ; DECREMENT TIMEOUT COUNTER
LD A,D ; TEST TIMEOUT COUNTER
OR E ; ... FOR ZERO
JR NZ,XIO_SYNC1 ; LOOP UNTIL TIMEOUT
XIO_SYNC2:
#ENDIF
RET
;
XIO_CRLF2: ; OUTPUT 2 NEWLINES
CALL XIO_CRLF ; SEND CRLF, FALL THRU FOR ANOTHER
XIO_CRLF: ; OUTPUT A NEWLINE
LD A,13 ; A = CR
@ -99,22 +129,24 @@ XIO_DOT: ; OUTPUT A DOT (MARK PROGRESS)
XIO_OUTC: ; OUTPUT BYTE IN A
#IF (PLATFORM == PLT_UNA)
PUSH BC ; PRESERVE BC
PUSH DE ; PRESERVE DE
LD BC,$0012 ; UNA UNIT = 0, FUNC = WRITE CHAR
LD E,A ; CHAR TO E
CALL $FFFD ; DO IT (RST 08 NOT SETUP YET)
POP DE ; RESTORE DE
POP BC ; RESTORE BC
RET ; DONE
#ENDIF
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
PUSH AF ; SAVE INCOMING BYTE
XIO_OUTC1:
IN0 A,(Z180_STAT0)
AND $02
JR Z,XIO_OUTC1
POP AF
OUT0 (Z180_TDR0),A
IN0 A,(Z180_STAT0) ; GET LINE STATUS
AND $02 ; ISOLATE TDRE
JR Z,XIO_OUTC1 ; LOOP TILL READY (EMPTY)
POP AF ; RECOVER INCOMING BYTE TO OUTPUT
OUT0 (Z180_TDR0),A ; WRITE THE CHAR TO ASCI
RET
#ENDIF
@ -129,6 +161,69 @@ XIO_OUTC1:
RET
#ENDIF
;
XIO_INC: ; INPUT BYTE TO A
#IF (PLATFORM == PLT_UNA)
PUSH BC ; PRESERVE BC
PUSH DE ; PRESERVE DE
LD BC,$0011 ; UNA UNIT = 0, FUNC = READ CHAR
CALL $FFFD ; DO IT (RST 08 NOT SETUP YET)
LD A,E ; CHAR TO A
POP DE ; RESTORE DE
POP BC ; RESTORE BC
RET ; DONE
#ENDIF
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
XIO_INC1:
IN0 A,(Z180_STAT0) ; READ LINE STATUS
AND $80 ; ISOLATE RDRF
JR Z,XIO_INC1 ; LOOP TILL CHAR AVAILABLE
IN0 A,(Z180_RDR0) ; READ THE CHAR
RET
#ENDIF
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
XIO_INC1:
IN A,(SIO_LSR) ; READ LINE STATUS REGISTER
AND $01 ; ISOLATE RDR
JR Z,XIO_INC1 ; LOOP TILL CHAR AVAILABLE
IN A,(SIO_RBR) ; READ THE CHAR
RET
#ENDIF
;
XIO_IST: ; INPUT STATUS TO A (NUM CHARS WAITING)
#IF (PLATFORM == PLT_UNA)
PUSH BC ; PRESERVE BC
PUSH DE ; PRESERVE DE
LD BC,$0013 ; UNA UNIT = 0, FUNC = READ CHAR
CALL $FFFD ; DO IT (RST 08 NOT SETUP YET)
LD A,E ; CHAR TO A
OR A ; UPDATE ZF
POP DE ; RESTORE DE
POP BC ; RESTORE BC
RET ; DONE
#ENDIF
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
IN0 A,(Z180_STAT0) ; READ LINE STATUS
AND $80 ; ISOLATE RDRF
RET Z ; NO CHARS WAITING, A=0, Z SET
LD A,1 ; SIGNAL 1 CHAR WAITING
OR A ; UPDATE ZF
RET
#ENDIF
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
IN A,(SIO_LSR) ; READ LINE STATUS REGISTER
AND $01 ; ISOLATE RDR
RET Z ; NO CHARS WAITING, A=0, Z SET
LD A,1 ; SIGNAL 1 CHAR WAITING
OR A ; UPDATE ZF
RET
#ENDIF
;
XIO_OUTS: ; OUTPUT '$' TERMINATED STRING AT ADDRESS IN HL
LD A,(HL) ; GET NEXT BYTE
CP '$' ; END OF STRING?
@ -165,29 +260,6 @@ XIO_COMPDIV:
;
#ENDIF
;
; COMPUTE HL / DE = BC W/ REMAINDER IN HL & ZF
;
XIO_DIV16:
LD A,H ; HL -> AC
LD C,L ; ...
LD HL,0 ; INIT HL
LD B,16 ; INIT LOOP COUNT
XIO_DIV16A:
SCF
RL C
RLA
ADC HL,HL
SBC HL,DE
JR NC,XIO_DIV16B
ADD HL,DE
DEC C
XIO_DIV16B:
DJNZ XIO_DIV16A ; LOOP AS NEEDED
LD B,A ; AC -> BC
LD A,H ; SET ZF
OR L ; ... BASED ON REMAINDER
RET ; DONE
;
;
;
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
@ -200,7 +272,7 @@ XIO_DIV16B:
; DUE TO ENCODING BAUD IS ALWAYS DIVISIBLE BY 75
; Z180 DIVISOR IS ALWAYS A FACTOR OF 160
;
; X = CPU_HZ / 160 / 75 ==> SIMPLIFIED ==> X = CPU_KHZ / 12
; X = (CPU_HZ / 160) / 75 ==> SIMPLIFIED ==> X = CPU_KHZ / 12
; X = X / (BAUD / 75)
; IF X % 3 == 0, THEN (PS=1, X := X / 3) ELSE PS=0
; IF X % 4 == 0, THEN (DR=1, X := X / 4) ELSE DR=0
@ -215,6 +287,18 @@ XIO_CNTLB:
;LD HL,(HCB + HCB_CPUKHZ) ; GET CPU CLK IN KHZ
LD HL,CPUKHZ ; CPU CLK IN KHZ
;LD HL,9216 ; *DEBUG*
; DUE TO THE LIMITED DIVISORS POSSIBLE WITH CNTLB, YOU PRETTY MUCH
; NEED TO USE A CPU SPEED THAT IS A MULTIPLE OF 128KHZ. BELOW, WE
; ATTEMPT TO ROUND THE CPU SPEED DETECTED TO A MULTIPLE OF 128KHZ
; WITH ROUNDING. THIS JUST MAXIMIZES OUR CHANCES OF SUCCESS COMPUTING
; THE DIVISOR.
LD DE,$0040 ; HALF OF 128 IS 64
ADD HL,DE ; ADD FOR ROUNDING
LD A,L ; MOVE TO ACCUM
AND $80 ; STRIP LOW ORDER 7 BITS
LD L,A ; ... AND PUT IT BACK
LD DE,12 ; PREPARE TO DIVIDE BY 12
CALL XIO_DIV16 ; BC := (CPU_KHZ / 12), REM IN HL, ZF
;CALL TSTPT
@ -277,3 +361,26 @@ XIO_CNTLB4:
RET
;
#ENDIF
;
; COMPUTE HL / DE = BC W/ REMAINDER IN HL & ZF
;
XIO_DIV16:
LD A,H ; HL -> AC
LD C,L ; ...
LD HL,0 ; INIT HL
LD B,16 ; INIT LOOP COUNT
XIO_DIV16A:
SCF
RL C
RLA
ADC HL,HL
SBC HL,DE
JR NC,XIO_DIV16B
ADD HL,DE
DEC C
XIO_DIV16B:
DJNZ XIO_DIV16A ; LOOP AS NEEDED
LD B,A ; AC -> BC
LD A,H ; SET ZF
OR L ; ... BASED ON REMAINDER
RET ; DONE

Loading…
Cancel
Save