From 97a09a6e3396f48f60e02dfad75ab7e007e84e51 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Wed, 20 Apr 2016 22:06:32 -0700 Subject: [PATCH] Revised Serial Device Config Routines --- Source/HBIOS/Config/plt_mk4.asm | 13 +- Source/HBIOS/Config/plt_n8.asm | 9 +- Source/HBIOS/Config/plt_sbc.asm | 1 - Source/HBIOS/Config/plt_zeta.asm | 1 - Source/HBIOS/asci.asm | 297 ++++++++++++++++++++----------- Source/HBIOS/decode.asm | 79 ++++++++ Source/HBIOS/encode.asm | 70 +------- Source/HBIOS/hbios.asm | 3 +- Source/HBIOS/loader.asm | 1 + Source/HBIOS/std.asm | 10 +- Source/HBIOS/uart.asm | 52 +----- Source/HBIOS/util.asm | 49 +++-- Source/HBIOS/xio.asm | 193 ++++++++++++++++++-- 13 files changed, 507 insertions(+), 271 deletions(-) create mode 100644 Source/HBIOS/decode.asm diff --git a/Source/HBIOS/Config/plt_mk4.asm b/Source/HBIOS/Config/plt_mk4.asm index 061f509b..58ee3bff 100644 --- a/Source/HBIOS/Config/plt_mk4.asm +++ b/Source/HBIOS/Config/plt_mk4.asm @@ -7,7 +7,6 @@ ; CPUOSC .EQU 18432000 ; CPU OSC FREQ 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) ; 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.) ; 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 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_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_MEMWAIT .EQU 0 ; MEMORY 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_MEMWAIT .EQU 1 ; MEMORY 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 diff --git a/Source/HBIOS/Config/plt_n8.asm b/Source/HBIOS/Config/plt_n8.asm index b76ddf02..f8b10ce2 100644 --- a/Source/HBIOS/Config/plt_n8.asm +++ b/Source/HBIOS/Config/plt_n8.asm @@ -7,7 +7,6 @@ ; CPUOSC .EQU 18432000 ; CPU OSC FREQ 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) ; 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 ; 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 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_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_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 diff --git a/Source/HBIOS/Config/plt_sbc.asm b/Source/HBIOS/Config/plt_sbc.asm index a2eda248..8bce0e8a 100644 --- a/Source/HBIOS/Config/plt_sbc.asm +++ b/Source/HBIOS/Config/plt_sbc.asm @@ -7,7 +7,6 @@ ; CPUOSC .EQU 8000000 ; CPU OSC FREQ 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) ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP diff --git a/Source/HBIOS/Config/plt_zeta.asm b/Source/HBIOS/Config/plt_zeta.asm index 3329903d..cdaf4163 100644 --- a/Source/HBIOS/Config/plt_zeta.asm +++ b/Source/HBIOS/Config/plt_zeta.asm @@ -7,7 +7,6 @@ ; CPUOSC .EQU 20000000 ; CPU OSC FREQ 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) ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP diff --git a/Source/HBIOS/asci.asm b/Source/HBIOS/asci.asm index 0ff45d6d..00b4c101 100644 --- a/Source/HBIOS/asci.asm +++ b/Source/HBIOS/asci.asm @@ -3,74 +3,38 @@ ; 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 ; T M P R D S S S +; 0 0 X 0 X X X X DEFAULT VALUES ; | | | | | | | | ; | | | | | + + +-- SS: SOURCE/SPEED SELECT (R/W) ; | | | | +-------- DR: DIVIDE RATIO (R/W) @@ -79,25 +43,35 @@ ASCI_LKUPCNT .EQU ($ - ASCI_LKUP) / 3 ; | +-------------- MP: MULTIPROCESSOR MODE (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: ; ; SETUP THE DISPATCH TABLE ENTRIES ; - LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180 - LD C,0 ; PHYSICAL UNIT INDEX -ASCI_INIT0: - PUSH BC ; SAVE LOOP CONTROL - LD D,C ; PHYSICAL UNIT - LD E,CIODEV_ASCI ; DEVICE TYPE + LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180 + LD C,0 ; PHYSICAL UNIT INDEX +ASCI_INIT1: + PUSH BC ; SAVE LOOP CONTROL + LD D,C ; PHYSICAL UNIT + LD E,CIODEV_ASCI ; DEVICE TYPE LD BC,ASCI_DISPATCH ; BC := DISPATCH ADDRESS - CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED - POP BC ; RESTORE LOOP CONTROL - INC C ; NEXT PHYSICAL UNIT - DJNZ ASCI_INIT0 ; LOOP UNTIL DONE + 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 ; ; ASCI0 CALL NEWLINE ; FORMATTING @@ -108,23 +82,31 @@ ASCI_INIT0: CALL PC_COMMA LD A,Z180_RDR0 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,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 + +ASCI_INIT2: LD A,66H OUT0 (Z180_ASEXT0),A LD A,64H OUT0 (Z180_CNTLA0),A - LD A,Z180_ASCIB0 + LD A,C OUT0 (Z180_CNTLB0),A -#ENDIF -; + +ASCI_INIT3: ; ASCI1 CALL NEWLINE ; FORMATTING PRTS("ASCI1: IO=0x$") @@ -133,22 +115,32 @@ ASCI_INIT0: CALL PC_COMMA LD A,Z180_RDR1 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,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 -#IF (PLATFORM != PLT_MK4) +ASCI_INIT4: LD A,66H OUT0 (Z180_ASEXT1),A LD A,64H OUT0 (Z180_CNTLA1),A - LD A,Z180_ASCIB1 + LD A,C OUT0 (Z180_CNTLB1),A -#ENDIF +ASCI_INIT5: + XOR A RET ; ; CHARACTER DEVICE DRIVER ENTRY @@ -238,8 +230,9 @@ ASCI0_INITDEV: ; ; ASCI0_QUERY: - LD DE,ASCI0BAUD >> 16 - LD HL,ASCI0BAUD & $FFFF + LD DE,ASCI0CFG + ;LD DE,ASCI0BAUD >> 16 + ;LD HL,ASCI0BAUD & $FFFF XOR A RET ; @@ -330,8 +323,9 @@ ASCI1_INITDEV: ; ; ASCI1_QUERY: - LD DE,ASCI1BAUD >> 16 - LD HL,ASCI1BAUD & $FFFF + ;LD DE,ASCI1BAUD >> 16 + ;LD HL,ASCI1BAUD & $FFFF + LD DE,ASCI1CFG XOR A RET ; @@ -342,3 +336,100 @@ ASCI1_DEVICE: LD E,1 ; E := PHYSICAL UNIT XOR A ; SIGNAL SUCCESS 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 \ No newline at end of file diff --git a/Source/HBIOS/decode.asm b/Source/HBIOS/decode.asm new file mode 100644 index 00000000..15ea319d --- /dev/null +++ b/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 . +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; 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 diff --git a/Source/HBIOS/encode.asm b/Source/HBIOS/encode.asm index b8100921..4ef49a04 100644 --- a/Source/HBIOS/encode.asm +++ b/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 . -; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 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 diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 14c73dff..43554068 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1773,7 +1773,7 @@ SIZ_TERM .EQU $ - ORG_TERM #INCLUDE "util.asm" #INCLUDE "time.asm" #INCLUDE "bcd.asm" -#INCLUDE "encode.asm" +#INCLUDE "decode.asm" #INCLUDE "xio.asm" ; #IF (DSKYENABLE) @@ -2263,6 +2263,7 @@ PS_PRTSC: INC A ; SET Z IF DE == $FF JP Z,PS_PRTNUL ; $FF == NO CONFIG DEFINED ; +PS_PRTSC0: ; PRINT BAUD RATE PUSH DE ; PRESERVE DE LD A,D diff --git a/Source/HBIOS/loader.asm b/Source/HBIOS/loader.asm index c7a766e6..8e6889f1 100644 --- a/Source/HBIOS/loader.asm +++ b/Source/HBIOS/loader.asm @@ -163,6 +163,7 @@ STR_BOOT .DB "RomWBW$" ; IMBED DIRECT SERIAL I/O ROUTINES ; #INCLUDE "xio.asm" +#INCLUDE "decode.asm" ; ;______________________________________________________________________________________________________________________ ; diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 977b73e7..4b51aab8 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -121,6 +121,9 @@ SER_PARSPACE .EQU 7 << 3 SER_STOP1 .EQU 0 << 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_BAUD600 .EQU $03 << 8 SER_BAUD1200 .EQU $04 << 8 @@ -131,6 +134,8 @@ SER_BAUD19200 .EQU $08 << 8 SER_BAUD38400 .EQU $09 << 8 SER_BAUD76800 .EQU $0A << 8 SER_BAUD115200 .EQU $19 << 8 +SER_BAUD230400 .EQU $1A << 8 +SER_BAUD460800 .EQU $1B << 8 ; SER_XON .EQU 1 << 6 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_76800_8N1 .EQU SER_BAUD76800 | 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 ; diff --git a/Source/HBIOS/uart.asm b/Source/HBIOS/uart.asm index 93a009f0..685cd4a8 100644 --- a/Source/HBIOS/uart.asm +++ b/Source/HBIOS/uart.asm @@ -210,7 +210,7 @@ UART_INITDEV: LD A,D AND E INC A - JR Z,UART_INITDEV1 ; IF DE == -1, BYPASS UPDATE + JR Z,UART_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG ; ; UDPATE CONFIG BYTES LD (IY + 4),E ; SAVE LOW WORD @@ -218,6 +218,8 @@ UART_INITDEV: ; UART_INITDEV1: ; 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 LD A,80H ; DLAB IS BIT 7 OF LCR UART_OUTP(UART_LCR) ; DLAB ON @@ -253,7 +255,7 @@ UART_INITDEV1: JR UART_INITDEV3 ; NO EFT, SKIP AHEAD ; 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 PUSH AF ; SAVE IT 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 ; 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 LD L,A ; PUT IN L LD H,0 ; H IS ALWAYS ZERO @@ -479,47 +481,11 @@ UART_PRTCFG: OR A ; SET FLAGS 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 ; LD A,(UART_FEAT) ; BIT UART_FIFO,A diff --git a/Source/HBIOS/util.asm b/Source/HBIOS/util.asm index 0cdd76ef..284969a9 100644 --- a/Source/HBIOS/util.asm +++ b/Source/HBIOS/util.asm @@ -693,37 +693,30 @@ MULT8X16_2: ; RET ;=============================================================== ; -; COMPUTE HL / DE = BC W/ REMAINDER IN HL +; COMPUTE HL / DE = BC W/ REMAINDER IN HL & ZF ; 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: - ; LOOP -; .DB $CB,$31 ; SLL C - SLA C - SET 0,C - RLA - ADC HL,HL - SBC HL,DE - JR NC,DIV16B - ADD HL,DE - DEC C -DIV16B: - DJNZ DIV16A - - ; AC -> BC - LD B,A - - RET -; -; INTEGER DIVIDES DE:HL BY C + SCF + RL C + RLA + ADC HL,HL + SBC HL,DE + JR NC,DIV16B + ADD HL,DE + DEC C +DIV16B: + DJNZ DIV16A ; LOOP AS NEEDED + LD B,A ; AC -> BC + LD A,H ; SET ZF + OR L ; ... BASED ON REMAINDER + RET ; DONE +; +; INTEGER DIVIDE DE:HL BY C ; RESULT IN DE:HL, REMAINDER IN A ; CLOBBERS F, B ; diff --git a/Source/HBIOS/xio.asm b/Source/HBIOS/xio.asm index 74e91e9e..c410cb38 100644 --- a/Source/HBIOS/xio.asm +++ b/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) ; #ENDIF -; + XIO_INIT: ; MINIMAL UART INIT #IF (PLATFORM == PLT_UNA) @@ -32,25 +32,41 @@ XIO_INIT: ; MINIMAL UART INIT #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 #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 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) - 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) LD A,03H ; VALUE FOR LCR AND MCR 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 +XIO_INIT1: RET ; XIO_CRLF: ; OUTPUT A NEWLINE @@ -115,3 +132,157 @@ XIO_OUTS: ; OUTPUT '$' TERMINATED STRING AT ADDRESS IN HL CALL XIO_OUTC ; OTHERWISE, WRITE IT INC HL ; POINT TO NEXT BYTE 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