Browse Source

Revised Serial Device Config Routines

patch
Wayne Warthen 10 years ago
parent
commit
97a09a6e33
  1. 13
      Source/HBIOS/Config/plt_mk4.asm
  2. 9
      Source/HBIOS/Config/plt_n8.asm
  3. 1
      Source/HBIOS/Config/plt_sbc.asm
  4. 1
      Source/HBIOS/Config/plt_zeta.asm
  5. 279
      Source/HBIOS/asci.asm
  6. 79
      Source/HBIOS/decode.asm
  7. 70
      Source/HBIOS/encode.asm
  8. 3
      Source/HBIOS/hbios.asm
  9. 1
      Source/HBIOS/loader.asm
  10. 10
      Source/HBIOS/std.asm
  11. 52
      Source/HBIOS/uart.asm
  12. 33
      Source/HBIOS/util.asm
  13. 193
      Source/HBIOS/xio.asm

13
Source/HBIOS/Config/plt_mk4.asm

@ -7,7 +7,6 @@
; ;
CPUOSC .EQU 18432000 ; CPU OSC FREQ CPUOSC .EQU 18432000 ; CPU OSC FREQ
RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!!
CONBAUD .EQU 38400 ; CONSOLE BAUDRATE AT STARTUP
DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE)
; ;
CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP
@ -32,8 +31,8 @@ UART3IOB .EQU $D8 ; IOBASE (4UART PORT D)
UART3CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.) UART3CFG .EQU DEFSERCFG ; CONFIG (BAUDRATE, DATA BITS, PARITY, STOP BITS, ETC.)
; ;
ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT
ASCI0BAUD .EQU CONBAUD ; ASCI0 BAUDRATE (IMPLEMENTED BY Z180_ASCIB0)
ASCI1BAUD .EQU CONBAUD ; ASCI1 BAUDRATE (IMPLEMENTED BY Z180_ASCIB1)
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 VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT
CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT
@ -95,18 +94,14 @@ BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTE
BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE
BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT
; ;
; 18.432MHz OSC @ FULL SPEED, 38.4Kbps
; 18.432MHz OSC @ FULL SPEED
; ;
Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2 Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3)
Z180_IOWAIT .EQU 0 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .EQU 0 ; IO WAIT STATES TO INSERT (0-3)
Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT
Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT
; ;
; 18.432MHz OSC @ DOUBLE SPEED, 38.4Kbps
; 18.432MHz OSC @ DOUBLE SPEED
; ;
;Z180_CLKDIV .EQU 2 ; 0=OSC/2, 1=OSC, 2=OSC*2 ;Z180_CLKDIV .EQU 2 ; 0=OSC/2, 1=OSC, 2=OSC*2
;Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) ;Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3)
;Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3) ;Z180_IOWAIT .EQU 1 ; IO WAIT STATES TO INSERT (0-3)
;Z180_ASCIB0 .EQU 21H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT
;Z180_ASCIB1 .EQU 21H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT

9
Source/HBIOS/Config/plt_n8.asm

@ -7,7 +7,6 @@
; ;
CPUOSC .EQU 18432000 ; CPU OSC FREQ CPUOSC .EQU 18432000 ; CPU OSC FREQ
RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!!
CONBAUD .EQU 38400 ; CONSOLE BAUDRATE AT STARTUP
DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE)
; ;
CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP
@ -23,8 +22,8 @@ UARTENABLE .EQU FALSE ; TRUE FOR UART SUPPORT (N8 USES ASCI DRIVER)
UARTCNT .EQU 0 ; NUMBER OF UARTS UARTCNT .EQU 0 ; NUMBER OF UARTS
; ;
ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT ASCIENABLE .EQU TRUE ; TRUE FOR Z180 ASCI SUPPORT
ASCI0BAUD .EQU CONBAUD ; ASCI0 BAUDRATE (IMPLEMENTED BY Z180_ASCIB0)
ASCI1BAUD .EQU CONBAUD ; ASCI1 BAUDRATE (IMPLEMENTED BY Z180_ASCIB1)
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 VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT
CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT
@ -82,8 +81,6 @@ BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTE
BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE
BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT BOOT_DEFAULT .EQU 'Z' ; SELECTION TO INVOKE AT TIMEOUT
; ;
Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC/1
Z180_CLKDIV .EQU 1 ; 0=OSC/2, 1=OSC, 2=OSC*2
Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3) Z180_MEMWAIT .EQU 1 ; MEMORY WAIT STATES TO INSERT (0-3)
Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3) Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3)
Z180_ASCIB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT
Z180_ASCIB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT

1
Source/HBIOS/Config/plt_sbc.asm

@ -7,7 +7,6 @@
; ;
CPUOSC .EQU 8000000 ; CPU OSC FREQ CPUOSC .EQU 8000000 ; CPU OSC FREQ
RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!!
CONBAUD .EQU 38400 ; CONSOLE BAUDRATE AT STARTUP
DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE)
; ;
CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP

1
Source/HBIOS/Config/plt_zeta.asm

@ -7,7 +7,6 @@
; ;
CPUOSC .EQU 20000000 ; CPU OSC FREQ CPUOSC .EQU 20000000 ; CPU OSC FREQ
RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!!
CONBAUD .EQU 38400 ; CONSOLE BAUDRATE AT STARTUP
DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE)
; ;
CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP

279
Source/HBIOS/asci.asm

@ -3,74 +3,38 @@
; ASCI DRIVER (Z180 SERIAL PORTS) ; ASCI DRIVER (Z180 SERIAL PORTS)
;================================================================================================== ;==================================================================================================
; ;
; BAUD RATE PROGRAMMING:
; Given a known clock speed (PHI) and target Baud Rate (BAUD):
;
; Divisor = PHI / BAUD
;
; Program PS, DR, SS bits based on divisor table lookup
;
; Divisor = PHI / BAUD
; Lookup = PHI / BAUD / 160
;
; To allow easier computation:
;
; Let xPHI = PHI / 1000 (PHI is always divisible by 1000)
; Let xBAUD = BAUD / 100 (BAUD is always divisible by 100)
; xPHI will always fit in 2 byte int
; xBAUD will always fit in 2 byte int
;
; Lookup = (xPHI >> 4) / xBAUD
;
; If failure to match, fallback to 9600 baud and try again
;
; Lookup PS Bit PS Div DR Bit DR Div SS Bits SS Div Divisor CNTLB
; 1 0 10 0 16 0 1 160 XX0X0000
; 2 0 10 0 16 1 2 320 XX0X0001
; 3 1 30 0 16 0 1 480 XX1X0000
; 4 0 10 0 16 2 4 640 XX0X0010
; 6 1 30 0 16 1 2 960 XX1X0001
; 8 0 10 0 16 3 8 1280 XX0X0011
; 12 1 30 0 16 2 4 1920 XX1X0010
; 16 0 10 0 16 4 16 2560 XX0X0100
; 24 1 30 0 16 3 8 3840 XX1X0011
; 32 0 10 0 16 5 32 5120 XX0X0101
; 48 1 30 0 16 4 16 7680 XX1X0100
; 64 0 10 0 16 6 64 10240 XX0X0110
; 96 1 30 0 16 5 32 15360 XX1X0101
; 128 0 10 1 64 5 32 20480 XX0X1101
; 192 1 30 0 16 6 64 30720 XX1X0110
; 256 0 10 1 64 6 64 40960 XX0X1110
; 384 1 30 1 64 5 32 61440 XX1X1101
; 768 1 30 1 64 6 64 122880 XX1X1110
;
ASCI_LKUP:
; LOOKUP CNTLB VAL
; ------ ----------
.DW 1 \ .DB %00000000
.DW 2 \ .DB %00000001
.DW 3 \ .DB %00100000
.DW 4 \ .DB %00000010
.DW 6 \ .DB %00100001
.DW 8 \ .DB %00000011
.DW 12 \ .DB %00100010
.DW 16 \ .DB %00000100
.DW 24 \ .DB %00100011
.DW 32 \ .DB %00000101
.DW 48 \ .DB %00100100
.DW 64 \ .DB %00000110
.DW 96 \ .DB %00100101
.DW 128 \ .DB %00001101
.DW 192 \ .DB %00100110
.DW 256 \ .DB %00001110
.DW 384 \ .DB %00101101
.DW 768 \ .DB %00101110
;
ASCI_LKUPCNT .EQU ($ - ASCI_LKUP) / 3
;
; CNTLB0/1:
; STAT:
; 7 6 5 4 3 2 1 0
; R O P F R C T T
; 0 0 0 0 0 0 0 0 DEFAULT VALUES
; | | | | | | | |
; | | | | | | | +-- TIE: TRANSMIT INTERRUPT ENABLE
; | | | | | | +---- TDRE: TRANSMIT DATA REGISTER EMPTY
; | | | | | +------ DCD0/CTS1E: CH0 CARRIER DETECT, CH1 CTS ENABLE
; | | | | +-------- RIE: RECEIVE INTERRUPT ENABLE
; | | | +---------- FE: FRAMING ERROR
; | | +------------ PE: PARITY ERROR
; | +-------------- OVRN: OVERRUN ERROR
; +---------------- RDRF: RECEIVE DATA REGISTER FULL
;
; CNTLA:
; 7 6 5 4 3 2 1 0
; M R T R E M M M
; 0 1 1 0 0 1 0 0 DEFAULT VALUES
; | | | | | | | |
; | | | | | | | +-- MOD0: STOP BITS: 0=1 BIT, 1=2 BITS
; | | | | | | +---- MOD1: PARITY: 0=NONE, 1=ENABLED
; | | | | | +------ MOD2: DATA BITS: 0=7 BITS, 1=8 BITS
; | | | | +-------- MPBR/EFR: MULTIPROCESSOR BIT RECEIVE / ERROR FLAG RESET
; | | | +---------- RTS0/CKA1D: CH0 RTS, CH1 CLOCK DISABLE
; | | +------------ TE: TRANSMITTER ENABLE
; | +-------------- RE: RECEIVER ENABLE
; +---------------- MPE: MULTI-PROCESSOR MODE ENABLE
;
; CNTLB:
; 7 6 5 4 3 2 1 0 ; 7 6 5 4 3 2 1 0
; T M P R D S S S ; T M P R D S S S
; 0 0 X 0 X X X X DEFAULT VALUES
; | | | | | | | | ; | | | | | | | |
; | | | | | + + +-- SS: SOURCE/SPEED SELECT (R/W) ; | | | | | + + +-- SS: SOURCE/SPEED SELECT (R/W)
; | | | | +-------- DR: DIVIDE RATIO (R/W) ; | | | | +-------- DR: DIVIDE RATIO (R/W)
@ -79,9 +43,19 @@ ASCI_LKUPCNT .EQU ($ - ASCI_LKUP) / 3
; | +-------------- MP: MULTIPROCESSOR MODE (R/W) ; | +-------------- MP: MULTIPROCESSOR MODE (R/W)
; +---------------- MPBT: MULTIPROCESSOR BIT TRANSMIT (R/W) ; +---------------- MPBT: MULTIPROCESSOR BIT TRANSMIT (R/W)
; ;
;
;
;
; ASEXT:
; 7 6 5 4 3 2 1 0
; R D C X B F D S
; 0 1 1 0 0 1 1 0 DEFAULT VALUES
; | | | | | | | |
; | | | | | | | +-- SEND BREAK
; | | | | | | +---- BREAK DETECT (RO)
; | | | | | +------ BREAK FEATURE ENABLE
; | | | | +-------- BRG MODE
; | | | +---------- X1 BIT CLK ASCI
; | | +------------ CTS0 DISABLE
; | +-------------- DCD0 DISABLE
; +---------------- RDRF INT INHIBIT
; ;
ASCI_INIT: ASCI_INIT:
; ;
@ -89,7 +63,7 @@ ASCI_INIT:
; ;
LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180 LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180
LD C,0 ; PHYSICAL UNIT INDEX LD C,0 ; PHYSICAL UNIT INDEX
ASCI_INIT0:
ASCI_INIT1:
PUSH BC ; SAVE LOOP CONTROL PUSH BC ; SAVE LOOP CONTROL
LD D,C ; PHYSICAL UNIT LD D,C ; PHYSICAL UNIT
LD E,CIODEV_ASCI ; DEVICE TYPE LD E,CIODEV_ASCI ; DEVICE TYPE
@ -97,7 +71,7 @@ ASCI_INIT0:
CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
POP BC ; RESTORE LOOP CONTROL POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT PHYSICAL UNIT INC C ; NEXT PHYSICAL UNIT
DJNZ ASCI_INIT0 ; LOOP UNTIL DONE
DJNZ ASCI_INIT1 ; LOOP UNTIL DONE
; ;
; ASCI0 ; ASCI0
CALL NEWLINE ; FORMATTING CALL NEWLINE ; FORMATTING
@ -108,23 +82,31 @@ ASCI_INIT0:
CALL PC_COMMA CALL PC_COMMA
LD A,Z180_RDR0 LD A,Z180_RDR0
CALL PRTHEXBYTE CALL PRTHEXBYTE
PRTS(" BAUD=$")
LD DE,ASCI0BAUD >> 16 ; SET DE:HL TO
LD HL,ASCI0BAUD & $FFFF ; ... BAUD RATE
LD BC,HB_BCDTMP ; POINT TO TEMP BCD
CALL BIN2BCD ; CONVERT TO BCD
CALL PRTBCD ; AND PRINT IT
CALL PC_SPACE ; FORMATTING
LD DE,ASCI0CFG ; LOAD CONFIG
CALL PS_PRTSC0 ; PRINT IT
LD HL,ASCI0CFG ; 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 ASCI_CNTLB ; DERIVE CNTLB VALUE
;CALL TSTPT
JR Z,ASCI_INIT2 ; IMPLEMENT IF NO ERROR
PRTS(" ERROR!$")
JR ASCI_INIT3 ; DO NEXT UNIT
#IF (PLATFORM != PLT_MK4)
ASCI_INIT2:
LD A,66H LD A,66H
OUT0 (Z180_ASEXT0),A OUT0 (Z180_ASEXT0),A
LD A,64H LD A,64H
OUT0 (Z180_CNTLA0),A OUT0 (Z180_CNTLA0),A
LD A,Z180_ASCIB0
LD A,C
OUT0 (Z180_CNTLB0),A OUT0 (Z180_CNTLB0),A
#ENDIF
;
ASCI_INIT3:
; ASCI1 ; ASCI1
CALL NEWLINE ; FORMATTING CALL NEWLINE ; FORMATTING
PRTS("ASCI1: IO=0x$") PRTS("ASCI1: IO=0x$")
@ -133,22 +115,32 @@ ASCI_INIT0:
CALL PC_COMMA CALL PC_COMMA
LD A,Z180_RDR1 LD A,Z180_RDR1
CALL PRTHEXBYTE CALL PRTHEXBYTE
PRTS(" BAUD=$")
LD DE,ASCI0BAUD >> 16 ; SET DE:HL TO
LD HL,ASCI0BAUD & $FFFF ; ... BAUD RATE
LD BC,HB_BCDTMP ; POINT TO TEMP BCD
CALL BIN2BCD ; CONVERT TO BCD
CALL PRTBCD ; AND PRINT IT
#IF (PLATFORM != PLT_MK4)
CALL PC_SPACE ; FORMATTING
LD DE,ASCI1CFG ; LOAD CONFIG
CALL PS_PRTSC0 ; PRINT IT
LD HL,ASCI1CFG ; 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 ASCI_CNTLB ; DERIVE CNTLB VALUE
;CALL TSTPT
JR Z,ASCI_INIT4 ; IMPLEMENT IF NO ERROR
PRTS(" ERROR!$")
JR ASCI_INIT5 ; DO NEXT UNIT
ASCI_INIT4:
LD A,66H LD A,66H
OUT0 (Z180_ASEXT1),A OUT0 (Z180_ASEXT1),A
LD A,64H LD A,64H
OUT0 (Z180_CNTLA1),A OUT0 (Z180_CNTLA1),A
LD A,Z180_ASCIB1
LD A,C
OUT0 (Z180_CNTLB1),A OUT0 (Z180_CNTLB1),A
#ENDIF
ASCI_INIT5:
XOR A
RET RET
; ;
; CHARACTER DEVICE DRIVER ENTRY ; CHARACTER DEVICE DRIVER ENTRY
@ -238,8 +230,9 @@ ASCI0_INITDEV:
; ;
; ;
ASCI0_QUERY: ASCI0_QUERY:
LD DE,ASCI0BAUD >> 16
LD HL,ASCI0BAUD & $FFFF
LD DE,ASCI0CFG
;LD DE,ASCI0BAUD >> 16
;LD HL,ASCI0BAUD & $FFFF
XOR A XOR A
RET RET
; ;
@ -330,8 +323,9 @@ ASCI1_INITDEV:
; ;
; ;
ASCI1_QUERY: ASCI1_QUERY:
LD DE,ASCI1BAUD >> 16
LD HL,ASCI1BAUD & $FFFF
;LD DE,ASCI1BAUD >> 16
;LD HL,ASCI1BAUD & $FFFF
LD DE,ASCI1CFG
XOR A XOR A
RET RET
; ;
@ -342,3 +336,100 @@ ASCI1_DEVICE:
LD E,1 ; E := PHYSICAL UNIT LD E,1 ; E := PHYSICAL UNIT
XOR A ; SIGNAL SUCCESS XOR A ; SIGNAL SUCCESS
RET RET
;
; DERIVE A CNTLB VALUE BASED ON AN ENCODED BAUD RATE AND CURRENT CPU SPEED
; ENTRY: HL = ENCODED BAUD RATE
; EXIT: C = CNTLB VALUE, A=0, Z SET INDICATES SUCCESS
;
; GIVEN DIVISOR = CLK HZ / BAUD
; LET LOOKUP = DIVISOR / 160
; LOOKUP = CLK / BAUD / 160
; LET KCLK = CLK / 1000, SO CLK = KCLK * 1000
; LOOKUP = KCLK * 1000 / BAUD / 160
; OR, LOOKUP = (KCLK / 12) / (BAUD / 75)
;
; SO, WE USE (CPUKHZ / 12) / (BAUD RATE / 75) TO GET LOOKUP VALUE
; THEN LOOKUP THE CORRECT CNTLB0 VALUE
;
ASCI_CNTLB:
LD DE,1 ; USE DECODE CONSTANT OF 1 TO GET BAUD RATE ALREADY DIVIDED BY 75
CALL DECODE ; DECODE THE BAUDATE INTO DE:HL, DE IS DISCARDED
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 DE,12 ; PREPARE TO DIVIDE BY 12
CALL DIV16 ; BC := (CPU CLK KHZ / 12), REMAINDER IN HL, ZF
POP DE ; RESTORE DENOMINATOR
JR NZ,ASCI_CNTLB2 ; ABORT IF REMAINDER
PUSH BC ; MOVE VALUE
POP HL ; ... TO HL NUMERATOR
CALL DIV16 ; BC := LOOKUP VALUE, REMAINDER IN HL, ZF
JR NZ,ASCI_CNTLB2 ; ABORT IF REMAINDER
PUSH BC ; MOVE LOOKUP VALUE
POP DE ; TO DE
LD B,ASCI_LKUPCNT ; INIT LOOP COUNT
LD HL,ASCI_LKUP ; POINT TO START OF TABLE
ASCI_CNTLB0:
LD A,(HL) ; GET BYTE TO COMPARE
INC HL ; INCREMENT HL FOR NEXT
CP E ; COMPARE LSB
JR NZ,ASCI_CNTLB1 ; NO MATCH, LOOP
LD A,(HL) ; GET BYTE TO COMPARE
CP D ; COMPARE MSB
JR NZ,ASCI_CNTLB1 ; NO MATCH, LOOP
; MATCH FOUND
INC HL ; POINT TO CNTLB VALUE
LD C,(HL) ; LOAD IN C
XOR A ; SIGNAL SUCCESS
RET ; AND DONE
ASCI_CNTLB1:
INC HL ; BUMP TO
INC HL ; ... NEXT ENTRY
DJNZ ASCI_CNTLB0 ; LOOP IF MORE TO CHECK
ASCI_CNTLB2:
OR $FF ; NOT FOUND, SET ERROR
RET ; AND RETURN
;
; LOOKUP PS BIT PS DIV DR BIT DR DIV SS BITS SS DIV DIVISOR CNTLB
; ------ ------ ------ ------ ------ ------- ------ ------- --------
; 1 0 10 0 16 0 1 160 XX0X0000
; 2 0 10 0 16 1 2 320 XX0X0001
; 3 1 30 0 16 0 1 480 XX1X0000
; 4 0 10 0 16 2 4 640 XX0X0010
; 6 1 30 0 16 1 2 960 XX1X0001
; 8 0 10 0 16 3 8 1280 XX0X0011
; 12 1 30 0 16 2 4 1920 XX1X0010
; 16 0 10 0 16 4 16 2560 XX0X0100
; 24 1 30 0 16 3 8 3840 XX1X0011
; 32 0 10 0 16 5 32 5120 XX0X0101
; 48 1 30 0 16 4 16 7680 XX1X0100
; 64 0 10 0 16 6 64 10240 XX0X0110
; 96 1 30 0 16 5 32 15360 XX1X0101
; 128 0 10 1 64 5 32 20480 XX0X1101
; 192 1 30 0 16 6 64 30720 XX1X0110
; 256 0 10 1 64 6 64 40960 XX0X1110
; 384 1 30 1 64 5 32 61440 XX1X1101
; 768 1 30 1 64 6 64 122880 XX1X1110
;
ASCI_LKUP: ; LOOKUP CNTLB VAL
.DW 1 \ .DB %00000000
.DW 2 \ .DB %00000001
.DW 3 \ .DB %00100000
.DW 4 \ .DB %00000010
.DW 6 \ .DB %00100001
.DW 8 \ .DB %00000011
.DW 12 \ .DB %00100010
.DW 16 \ .DB %00000100
.DW 24 \ .DB %00100011
.DW 32 \ .DB %00000101
.DW 48 \ .DB %00100100
.DW 64 \ .DB %00000110
.DW 96 \ .DB %00100101
.DW 128 \ .DB %00001101
.DW 192 \ .DB %00100110
.DW 256 \ .DB %00001110
.DW 384 \ .DB %00101101
.DW 768 \ .DB %00101110
;
ASCI_LKUPCNT .EQU ($ - ASCI_LKUP) / 3

79
Source/HBIOS/decode.asm

@ -0,0 +1,79 @@
;
;==================================================================================================
; DECODE 32-BIT VALUES FROM A 5-BIT SHIFT-ENCODED VALUE
;==================================================================================================
;
; Copyright (C) 2014 John R. Coffman. All rights reserved.
; Provided for hobbyist use on the Z180 SBC Mark IV board.
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; THE FUNCTION(S) IN THIS FILE ARE BASED ON LIKE FUNCTIONS CREATED BY JOHN COFFMAN
; IN HIS UNA BIOS PROJECT. THEY ARE INCLUDED HERE BASED ON GPLV3 PERMISSIBLE USE.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 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
; The encoded value is stored as 5 bits: YXXXX
; At present, C=75 for baud rate encoding and C=3 for CPU OSC encoding
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DECODE
;
; Enter with:
; HL = word to be decoded (5-bits) FXXXX
; F=extra 3 factor, XXXX=shift factor, reg H must be zero
; DE = encode divisor OSC_DIV = 3, or BAUD_DIV = 75
;
; Exit with:
; DE:HL = decoded value
; A = non-zero on error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
DECODE:
LD A,H ; SET TO TEST
LD C,$FF ; PRESUME ERROR CONDITION
OR A ; TEST FOR ZERO
JR NZ,DECODE9 ; NOT AN ENCODED VALUE
LD A,L ; GET LOW ORDER 5 BITS
CP 32 ; TEST FOR ERROR
JR NC,DECODE9 ; ERROR RETURN IF NOT BELOW
; ARGUMENT HL IS VALIDATED
LD H,D
LD L,E ; COPY TO HL
CP 16
JR C,DECODE2 ; IF < 16, NO 3 FACTOR
ADD HL,DE ; INTRODUCE FACTOR OF 3
ADD HL,DE ; **
DECODE2:
LD DE,0 ; ZERO THE HIGH ORDER
AND 15 ; MASK TO 4 BITS
JR Z,DECODE8 ; GOOD EXIT
LD C,B ; SAVE B-REG
LD B,A ;
DECODE3:
ADD HL,HL ; SHIFT LEFT BY 1, SET CARRY
RL E
RL D ; **
DJNZ DECODE3
LD B,C ; RESTORE B-REG
DECODE8:
LD C,0 ; SIGNAL GOOD RETURN
DECODE9:
LD A,C ; ERROR CODE TEST
OR A ; ERROR CODE IN REG-C AND Z-FLAG
RET

70
Source/HBIOS/encode.asm

@ -1,74 +1,14 @@
; ;
;================================================================================================== ;==================================================================================================
; FUNCTIONS TO ENCODE/DECODE 32-BIT VALUES TO/FROM A 5-BIT SHIFT-ENCODED VALUE
; ENCODE 32-BIT VALUES TO A 5-BIT SHIFT-ENCODED VALUE
;================================================================================================== ;==================================================================================================
; ;
; THE FUNCTIONS IN THIS FILE ARE BASED ON LIKE FUNCTIONS CREATED BY JOHN COFFMAN
; IN HIS UNA BIOS PROJECT. THEY ARE INCLUDED HERE BASED ON GPLV3 PERMISSIBLE USE.
;
; Copyright (C) 2014 John R. Coffman. All rights reserved.
; Provided for hobbyist use on the Z180 SBC Mark IV board.
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DECODE
;
; Enter with:
; HL = word to be decoded (5-bits) FXXXX
; F=extra 3 factor, XXXX=shift factor, reg H must be zero
; DE = encode divisor OSC_DIV = 3, or BAUD_DIV = 75
;
; Exit with:
; DE:HL = decoded value
; A = non-zero on error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
DECODE:
LD A,H ; SET TO TEST
LD C,$FF ; PRESUME ERROR CONDITION
OR A ; TEST FOR ZERO
JR NZ,DECODE9 ; NOT AN ENCODED VALUE
LD A,L ; GET LOW ORDER 5 BITS
CP 32 ; TEST FOR ERROR
JR NC,DECODE9 ; ERROR RETURN IF NOT BELOW
; ARGUMENT HL IS VALIDATED
LD H,D
LD L,E ; COPY TO HL
CP 16
JR C,DECODE2 ; IF < 16, NO 3 FACTOR
ADD HL,DE ; INTRODUCE FACTOR OF 3
ADD HL,DE ; **
DECODE2:
LD DE,0 ; ZERO THE HIGH ORDER
AND 15 ; MASK TO 4 BITS
JR Z,DECODE8 ; GOOD EXIT
LD C,B ; SAVE B-REG
LD B,A ;
DECODE3:
ADD HL,HL ; SHIFT LEFT BY 1, SET CARRY
RL E
RL D ; **
DJNZ DECODE3
LD B,C ; RESTORE B-REG
DECODE8:
LD C,0 ; SIGNAL GOOD RETURN
DECODE9:
LD A,C ; ERROR CODE TEST
OR A ; ERROR CODE IN REG-C AND Z-FLAG
RET
; 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
; The encoded value is stored as 5 bits: YXXXX
; At present, C=75 for baud rate encoding and C=3 for CPU OSC encoding
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ENCODE ; ENCODE

3
Source/HBIOS/hbios.asm

@ -1773,7 +1773,7 @@ SIZ_TERM .EQU $ - ORG_TERM
#INCLUDE "util.asm" #INCLUDE "util.asm"
#INCLUDE "time.asm" #INCLUDE "time.asm"
#INCLUDE "bcd.asm" #INCLUDE "bcd.asm"
#INCLUDE "encode.asm"
#INCLUDE "decode.asm"
#INCLUDE "xio.asm" #INCLUDE "xio.asm"
; ;
#IF (DSKYENABLE) #IF (DSKYENABLE)
@ -2263,6 +2263,7 @@ PS_PRTSC:
INC A ; SET Z IF DE == $FF INC A ; SET Z IF DE == $FF
JP Z,PS_PRTNUL ; $FF == NO CONFIG DEFINED JP Z,PS_PRTNUL ; $FF == NO CONFIG DEFINED
; ;
PS_PRTSC0:
; PRINT BAUD RATE ; PRINT BAUD RATE
PUSH DE ; PRESERVE DE PUSH DE ; PRESERVE DE
LD A,D LD A,D

1
Source/HBIOS/loader.asm

@ -163,6 +163,7 @@ STR_BOOT .DB "RomWBW$"
; IMBED DIRECT SERIAL I/O ROUTINES ; IMBED DIRECT SERIAL I/O ROUTINES
; ;
#INCLUDE "xio.asm" #INCLUDE "xio.asm"
#INCLUDE "decode.asm"
; ;
;______________________________________________________________________________________________________________________ ;______________________________________________________________________________________________________________________
; ;

10
Source/HBIOS/std.asm

@ -121,6 +121,9 @@ SER_PARSPACE .EQU 7 << 3
SER_STOP1 .EQU 0 << 2 SER_STOP1 .EQU 0 << 2
SER_STOP2 .EQU 1 << 2 SER_STOP2 .EQU 1 << 2
; ;
; SEREIAL BAUD RATES ENCODED AS V = 75 * 2^X * 3^Y
; AND STORED AS 5 BITS: YXXXX
;
SER_BAUD300 .EQU $02 << 8 SER_BAUD300 .EQU $02 << 8
SER_BAUD600 .EQU $03 << 8 SER_BAUD600 .EQU $03 << 8
SER_BAUD1200 .EQU $04 << 8 SER_BAUD1200 .EQU $04 << 8
@ -131,6 +134,8 @@ SER_BAUD19200 .EQU $08 << 8
SER_BAUD38400 .EQU $09 << 8 SER_BAUD38400 .EQU $09 << 8
SER_BAUD76800 .EQU $0A << 8 SER_BAUD76800 .EQU $0A << 8
SER_BAUD115200 .EQU $19 << 8 SER_BAUD115200 .EQU $19 << 8
SER_BAUD230400 .EQU $1A << 8
SER_BAUD460800 .EQU $1B << 8
; ;
SER_XON .EQU 1 << 6 SER_XON .EQU 1 << 6
SER_DTR .EQU 1 << 7 SER_DTR .EQU 1 << 7
@ -146,9 +151,8 @@ SER_19200_8N1 .EQU SER_BAUD19200 | SER_DATA8 | SER_PARNONE | SER_STOP1
SER_38400_8N1 .EQU SER_BAUD38400 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_38400_8N1 .EQU SER_BAUD38400 | SER_DATA8 | SER_PARNONE | SER_STOP1
SER_76800_8N1 .EQU SER_BAUD76800 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_76800_8N1 .EQU SER_BAUD76800 | SER_DATA8 | SER_PARNONE | SER_STOP1
SER_115200_8N1 .EQU SER_BAUD115200 | SER_DATA8 | SER_PARNONE | SER_STOP1 SER_115200_8N1 .EQU SER_BAUD115200 | SER_DATA8 | SER_PARNONE | SER_STOP1
;
;UF_FIFO .EQU $01 ; BIT 0 IS FIFO ENABLE
;UF_AFC .EQU $02 ; BIT 1 IS AUTO FLOW CONTROL ENABLE
SER_230400_8N1 .EQU SER_BAUD230400 | SER_DATA8 | SER_PARNONE | SER_STOP1
SER_460800_8N1 .EQU SER_BAUD460800 | SER_DATA8 | SER_PARNONE | SER_STOP1
; ;
#INCLUDE "build.inc" ; INCLUDE USER CONFIG, ADD VARIANT, TIMESTAMP, & ROMSIZE #INCLUDE "build.inc" ; INCLUDE USER CONFIG, ADD VARIANT, TIMESTAMP, & ROMSIZE
; ;

52
Source/HBIOS/uart.asm

@ -210,7 +210,7 @@ UART_INITDEV:
LD A,D LD A,D
AND E AND E
INC A INC A
JR Z,UART_INITDEV1 ; IF DE == -1, BYPASS UPDATE
JR Z,UART_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG
; ;
; UDPATE CONFIG BYTES ; UDPATE CONFIG BYTES
LD (IY + 4),E ; SAVE LOW WORD LD (IY + 4),E ; SAVE LOW WORD
@ -218,6 +218,8 @@ UART_INITDEV:
; ;
UART_INITDEV1: UART_INITDEV1:
; START OF UART INITIALIZATION, SET BAUD RATE ; START OF UART INITIALIZATION, SET BAUD RATE
LD E,(IY + 4) ; GET LOW WORD
LD D,(IY + 5) ; GET HI WORD
CALL UART_COMPDIV ; COMPUTE DIVISOR TO BC CALL UART_COMPDIV ; COMPUTE DIVISOR TO BC
LD A,80H ; DLAB IS BIT 7 OF LCR LD A,80H ; DLAB IS BIT 7 OF LCR
UART_OUTP(UART_LCR) ; DLAB ON UART_OUTP(UART_LCR) ; DLAB ON
@ -253,7 +255,7 @@ UART_INITDEV1:
JR UART_INITDEV3 ; NO EFT, SKIP AHEAD JR UART_INITDEV3 ; NO EFT, SKIP AHEAD
; ;
UART_INITDEV2: UART_INITDEV2:
; WE HAVE AN EFR CAPABLE CHIP, SET AUTOFLOW
; WE HAVE AN EFR CAPABLE CHIP, SET AUTOFLOW IN EFR REGISTER
UART_INP(UART_LCR) ; GET CURRENT LCR VALUE UART_INP(UART_LCR) ; GET CURRENT LCR VALUE
PUSH AF ; SAVE IT PUSH AF ; SAVE IT
LD A,$BF ; VALUE TO ACCESS EFR LD A,$BF ; VALUE TO ACCESS EFR
@ -441,7 +443,7 @@ UART_COMPDIV:
; FIRST WE DECODE THE BAUDRATE, BUT WE USE A CONSTANT OF 1 INSTEAD ; FIRST WE DECODE THE BAUDRATE, BUT WE USE A CONSTANT OF 1 INSTEAD
; OF THE NORMAL 75. THIS PRODUCES (BAUDRATE / 75). ; OF THE NORMAL 75. THIS PRODUCES (BAUDRATE / 75).
; ;
LD A,(IY + 5) ; GET SECOND CONFIG BYTE
LD A,D ; GET CONFIG MSB
AND $1F ; ISOLATE ENCODED BAUD RATE AND $1F ; ISOLATE ENCODED BAUD RATE
LD L,A ; PUT IN L LD L,A ; PUT IN L
LD H,0 ; H IS ALWAYS ZERO LD H,0 ; H IS ALWAYS ZERO
@ -479,47 +481,11 @@ UART_PRTCFG:
OR A ; SET FLAGS OR A ; SET FLAGS
RET Z ; IF ZERO, NOT PRESENT RET Z ; IF ZERO, NOT PRESENT
; ;
; PRINT BAUD RATE
CALL PC_SPACE
LD A,(IY + 5) ; GET SECOND CONFIG BYTE
AND $1F ; ISOLATE ENCODED BAUD RATE
LD L,A ; PUT IN L
LD H,0 ; H IS ALWAYS ZERO
LD DE,75 ; BAUD RATE DECODE CONSTANT
CALL DECODE ; DE:HL := BAUD RATE
LD BC,HB_BCDTMP ; POINT TO TEMP BCD BUF
CALL BIN2BCD ; CONVERT TO BCD
CALL PRTBCD ; AND PRINT IN DECIMAL
;
; PRINT DATA BITS
CALL PC_COMMA ; FORMATTING
LD A,(IY + 4) ; GET CONFIG BYTE
AND $03 ; ISOLATE DATA BITS VALUE
ADD A,'5' ; CONVERT TO CHARACTER
CALL COUT ; AND PRINT
;
; PRINT PARITY
CALL PC_COMMA ; FORMATTING
LD A,(IY + 4) ; GET CONFIG BYTE
RLCA ; SHIFT RELEVANT BITS
RLCA ; ...
RLCA ; ...
AND $07 ; AND ISOLATE DATA BITS VALUE
LD HL,UART_PAR_MAP ; CHARACTER LOOKUP TABLE
CALL ADDHLA ; APPLY OFFSET
LD A,(HL) ; GET CHARACTER
CALL COUT ; AND PRINT
;
; PRINT STOP BITS
CALL PC_COMMA ; FORMATTING
LD A,(IY + 4) ; GET CONFIG BYTE
RLCA ; SHIFT RELEVANT BITS
RLCA ; ...
AND $01 ; AND ISOLATE DATA BITS VALUE
ADD A,'1' ; MAKE IT A CHARACTER
CALL COUT ; AND PRINT
CALL PC_SPACE ; FORMATTING
LD E,(IY + 4) ; LOAD CONFIG
LD D,(IY + 5) ; ... WORD TO DE
CALL PS_PRTSC0 ; PRINT CONFIG
; ;
;;
; ; PRINT FEATURES ENABLED ; ; PRINT FEATURES ENABLED
; LD A,(UART_FEAT) ; LD A,(UART_FEAT)
; BIT UART_FIFO,A ; BIT UART_FIFO,A

33
Source/HBIOS/util.asm

@ -693,22 +693,16 @@ MULT8X16_2:
; RET ; RET
;=============================================================== ;===============================================================
; ;
; COMPUTE HL / DE = BC W/ REMAINDER IN HL
; COMPUTE HL / DE = BC W/ REMAINDER IN HL & ZF
; ;
DIV16: DIV16:
; HL -> AC
LD A,H
LD C,L
; SETUP
LD HL,0
LD B,16
;
LD A,H ; HL -> AC
LD C,L ; ...
LD HL,0 ; INIT HL
LD B,16 ; INIT LOOP COUNT
DIV16A: DIV16A:
; LOOP
; .DB $CB,$31 ; SLL C
SLA C
SET 0,C
SCF
RL C
RLA RLA
ADC HL,HL ADC HL,HL
SBC HL,DE SBC HL,DE
@ -716,14 +710,13 @@ DIV16A:
ADD HL,DE ADD HL,DE
DEC C DEC C
DIV16B: DIV16B:
DJNZ DIV16A
; AC -> BC
LD B,A
RET
DJNZ DIV16A ; LOOP AS NEEDED
LD B,A ; AC -> BC
LD A,H ; SET ZF
OR L ; ... BASED ON REMAINDER
RET ; DONE
; ;
; INTEGER DIVIDES DE:HL BY C
; INTEGER DIVIDE DE:HL BY C
; RESULT IN DE:HL, REMAINDER IN A ; RESULT IN DE:HL, REMAINDER IN A
; CLOBBERS F, B ; CLOBBERS F, B
; ;

193
Source/HBIOS/xio.asm

@ -23,7 +23,7 @@ SIO_DLL .EQU UART0IOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
SIO_DLM .EQU UART0IOB + 1 ; DLAB=1: DIVISOR LATCH (MS) SIO_DLM .EQU UART0IOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
; ;
#ENDIF #ENDIF
;
XIO_INIT: ; MINIMAL UART INIT XIO_INIT: ; MINIMAL UART INIT
#IF (PLATFORM == PLT_UNA) #IF (PLATFORM == PLT_UNA)
@ -32,25 +32,41 @@ XIO_INIT: ; MINIMAL UART INIT
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4)) #IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
; ASCI0
LD A,66H
OUT0 (Z180_ASEXT0),A
LD A,64H
OUT0 (Z180_CNTLA0),A
LD A,Z180_ASCIB0
OUT0 (Z180_CNTLB0),A
; INIT ASCI0 WITH BASIC VALUES AND FAILSAFE DIVISOR
LD A,$66 ; IGNORE CTS/DCD, NO BREAK DETECT
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
OUT0 (Z180_CNTLB0),A ; -> CNTLB0
; TRY TO IMPLEMENT CONFIGURED BAUD RATE
LD HL,ASCI0CFG ; 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 NZ,XIO_INIT1 ; BYPASS ON FAILURE
LD A,C ; PUT INT C
OUT0 (Z180_CNTLB0),A ; AND SET THE VALUE
#ENDIF #ENDIF
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2)) #IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
XIO_DIV .EQU (UARTOSC / (16 * CONBAUD))
;XIO_DIV .EQU (UARTOSC / (16 * CONBAUD))
LD DE,UART0CFG ; SERIAL CONFIG WORD
CALL XIO_COMPDIV ; COMPUTE DIVISOR TO BC
LD A,$80 ; LCR := DLAB ON LD A,$80 ; LCR := DLAB ON
OUT (SIO_LCR),A ; SET LCR OUT (SIO_LCR),A ; SET LCR
LD A,XIO_DIV % $100 ; BAUD RATE DIVISOR (LSB)
;LD A,XIO_DIV % $100 ; BAUD RATE DIVISOR (LSB)
LD A,C ; LOW BYTE OF DIVISOR
OUT (SIO_DLL),A ; SET DIVISOR (LSB) OUT (SIO_DLL),A ; SET DIVISOR (LSB)
LD A,XIO_DIV / $100 ; BAUD RATE DIVISOR (MSB)
;LD A,XIO_DIV / $100 ; BAUD RATE DIVISOR (MSB)
LD A,B ; HIGH BYTE OF DIVISOR
OUT (SIO_DLM),A ; SET DIVISOR (MSB) OUT (SIO_DLM),A ; SET DIVISOR (MSB)
LD A,03H ; VALUE FOR LCR AND MCR LD A,03H ; VALUE FOR LCR AND MCR
OUT (SIO_LCR),A ; LCR := 3, DLAB OFF, 8 DATA, 1 STOP, NO PARITY OUT (SIO_LCR),A ; LCR := 3, DLAB OFF, 8 DATA, 1 STOP, NO PARITY
@ -60,6 +76,7 @@ XIO_DIV .EQU (UARTOSC / (16 * CONBAUD))
#ENDIF #ENDIF
XIO_INIT1:
RET RET
; ;
XIO_CRLF: ; OUTPUT A NEWLINE XIO_CRLF: ; OUTPUT A NEWLINE
@ -115,3 +132,157 @@ XIO_OUTS: ; OUTPUT '$' TERMINATED STRING AT ADDRESS IN HL
CALL XIO_OUTC ; OTHERWISE, WRITE IT CALL XIO_OUTC ; OTHERWISE, WRITE IT
INC HL ; POINT TO NEXT BYTE INC HL ; POINT TO NEXT BYTE
JR XIO_OUTS ; AND LOOP JR XIO_OUTS ; AND LOOP
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
;
; COMPUTE DIVISOR TO BC
;
XIO_COMPDIV:
; WE WANT TO DETERMINE A DIVISOR FOR THE UART CLOCK
; THAT RESULTS IN THE DESIRED BAUD RATE.
; BAUD RATE = UART CLK / DIVISOR, OR TO SOLVE FOR DIVISOR
; DIVISOR = UART CLK / BAUDRATE.
; THE UART CLOCK IS THE UART OSC PRESCALED BY 16. ALSO, WE CAN
; TAKE ADVANTAGE OF ENCODED BAUD RATES ALWAYS BEING A FACTOR OF 75.
; SO, WE CAN USE (UART OSC / 16 / 75) / (BAUDRATE / 75)
;
; FIRST WE DECODE THE BAUDRATE, BUT WE USE A CONSTANT OF 1 INSTEAD
; OF THE NORMAL 75. THIS PRODUCES (BAUDRATE / 75).
;
LD A,D ; GET CONFIG MSB
AND $1F ; ISOLATE ENCODED BAUD RATE
LD L,A ; PUT IN L
LD H,0 ; H IS ALWAYS ZERO
LD DE,1 ; USE 1 FOR ENCODING CONSTANT
CALL DECODE ; DE:HL := BAUD RATE, ERRORS IGNORED
EX DE,HL ; DE := (BAUDRATE / 75), DISCARD HL
LD HL,UARTOSC / 16 / 75 ; HL := (UART OSC / 16 / 75)
JP XIO_DIV16 ; BC := HL/DE == DIVISOR AND RETURN
;
#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))
;
; DERIVE A CNTLB VALUE BASED ON AN ENCODED BAUD RATE AND CURRENT CPU SPEED
; ENTRY: HL = ENCODED BAUD RATE
; EXIT: C = CNTLB VALUE, A=0, Z SET INDICATES SUCCESS
;
; GIVEN DIVISOR = CLK HZ / BAUD
; LET LOOKUP = DIVISOR / 160
; LOOKUP = CLK / BAUD / 160
; LET KCLK = CLK / 1000, SO CLK = KCLK * 1000
; LOOKUP = KCLK * 1000 / BAUD / 160
; OR, LOOKUP = (KCLK / 12) / (BAUD / 75)
;
; SO, WE USE (CPUKHZ / 12) / (BAUD RATE / 75) TO GET LOOKUP VALUE
; THEN LOOKUP THE CORRECT CNTLB0 VALUE
;
XIO_CNTLB:
LD DE,1 ; USE DECODE CONSTANT OF 1 TO GET BAUD RATE ALREADY DIVIDED BY 75
CALL DECODE ; DECODE THE BAUDATE INTO DE:HL, DE IS DISCARDED
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 DE,12 ; PREPARE TO DIVIDE BY 12
CALL XIO_DIV16 ; BC := (CPU CLK KHZ / 12), REMAINDER IN HL, ZF
POP DE ; RESTORE DENOMINATOR
JR NZ,XIO_CNTLB2 ; ABORT IF REMAINDER
PUSH BC ; MOVE VALUE
POP HL ; ... TO HL NUMERATOR
CALL XIO_DIV16 ; BC := LOOKUP VALUE, REMAINDER IN HL, ZF
JR NZ,XIO_CNTLB2 ; ABORT IF REMAINDER
PUSH BC ; MOVE LOOKUP VALUE
POP DE ; TO DE
LD B,XIO_LKUPCNT ; INIT LOOP COUNT
LD HL,XIO_LKUP ; POINT TO START OF TABLE
XIO_CNTLB0:
LD A,(HL) ; GET BYTE TO COMPARE
INC HL ; INCREMENT HL FOR NEXT
CP E ; COMPARE LSB
JR NZ,XIO_CNTLB1 ; NO MATCH, LOOP
LD A,(HL) ; GET BYTE TO COMPARE
CP D ; COMPARE MSB
JR NZ,XIO_CNTLB1 ; NO MATCH, LOOP
; MATCH FOUND
INC HL ; POINT TO CNTLB VALUE
LD C,(HL) ; LOAD IN C
XOR A ; SIGNAL SUCCESS
RET ; AND DONE
XIO_CNTLB1:
INC HL ; BUMP TO
INC HL ; ... NEXT ENTRY
DJNZ XIO_CNTLB0 ; LOOP IF MORE TO CHECK
XIO_CNTLB2:
OR $FF ; NOT FOUND, SET ERROR
RET ; AND RETURN
;
; LOOKUP PS BIT PS DIV DR BIT DR DIV SS BITS SS DIV DIVISOR CNTLB
; ------ ------ ------ ------ ------ ------- ------ ------- --------
; 1 0 10 0 16 0 1 160 XX0X0000
; 2 0 10 0 16 1 2 320 XX0X0001
; 3 1 30 0 16 0 1 480 XX1X0000
; 4 0 10 0 16 2 4 640 XX0X0010
; 6 1 30 0 16 1 2 960 XX1X0001
; 8 0 10 0 16 3 8 1280 XX0X0011
; 12 1 30 0 16 2 4 1920 XX1X0010
; 16 0 10 0 16 4 16 2560 XX0X0100
; 24 1 30 0 16 3 8 3840 XX1X0011
; 32 0 10 0 16 5 32 5120 XX0X0101
; 48 1 30 0 16 4 16 7680 XX1X0100
; 64 0 10 0 16 6 64 10240 XX0X0110
; 96 1 30 0 16 5 32 15360 XX1X0101
; 128 0 10 1 64 5 32 20480 XX0X1101
; 192 1 30 0 16 6 64 30720 XX1X0110
; 256 0 10 1 64 6 64 40960 XX0X1110
; 384 1 30 1 64 5 32 61440 XX1X1101
; 768 1 30 1 64 6 64 122880 XX1X1110
;
XIO_LKUP: ; LOOKUP CNTLB VAL
.DW 1 \ .DB %00000000
.DW 2 \ .DB %00000001
.DW 3 \ .DB %00100000
.DW 4 \ .DB %00000010
.DW 6 \ .DB %00100001
.DW 8 \ .DB %00000011
.DW 12 \ .DB %00100010
.DW 16 \ .DB %00000100
.DW 24 \ .DB %00100011
.DW 32 \ .DB %00000101
.DW 48 \ .DB %00100100
.DW 64 \ .DB %00000110
.DW 96 \ .DB %00100101
.DW 128 \ .DB %00001101
.DW 192 \ .DB %00100110
.DW 256 \ .DB %00001110
.DW 384 \ .DB %00101101
.DW 768 \ .DB %00101110
;
XIO_LKUPCNT .EQU ($ - XIO_LKUP) / 3
;
#ENDIF

Loading…
Cancel
Save