You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

270 lines
5.5 KiB

;
;==================================================================================================
; 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:
; 7 6 5 4 3 2 1 0
; T M P R D S S S
; | | | | | | | |
; | | | | | + + +-- SS: SOURCE/SPEED SELECT (R/W)
; | | | | +-------- DR: DIVIDE RATIO (R/W)
; | | | +---------- PEO: PARITY EVEN ODD (R/W)
; | | +------------ PS: ~CTS/PS: CLEAR TO SEND(R) / PRESCALE(W)
; | +-------------- MP: MULTIPROCESSOR MODE (R/W)
; +---------------- MPBT: MULTIPROCESSOR BIT TRANSMIT (R/W)
;
;
;
; CHARACTER DEVICE DRIVER ENTRY
; A: RESULT (OUT), CF=ERR
; B: FUNCTION (IN)
; C: CHARACTER (IN/OUT)
; E: DEVICE/UNIT (IN)
;
ASCI_DISPATCH:
LD A,C ; GET DEVICE/UNIT
AND $0F ; ISOLATE UNIT
JP Z,ASCI0
DEC A
JP Z,ASCI1
CALL PANIC
;
ASCI0:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,ASCI0_IN
DEC A
JP Z,ASCI0_OUT
DEC A
JP Z,ASCI0_IST
DEC A
JP Z,ASCI0_OST
CALL PANIC
;
;
;
ASCI_INIT:
; ASCI0
PRTS("ASCI0: IO=0x$")
LD A,Z180_TDR0
CALL PRTHEXBYTE
CALL PC_COMMA
LD A,Z180_RDR0
CALL PRTHEXBYTE
; PRTS(" BAUD=$")
; LD HL,ASCI0BAUD / 10
; CALL PRTDEC
; PRTC('0')
#IF (PLATFORM != PLT_MK4)
LD A,66H
OUT0 (Z180_ASEXT0),A
LD A,64H
OUT0 (Z180_CNTLA0),A
LD A,Z180_ASCIB0
OUT0 (Z180_CNTLB0),A
#ENDIF
; ASCI1
CALL NEWLINE
PRTS("ASCI1: IO=0x$")
LD A,Z180_TDR1
CALL PRTHEXBYTE
CALL PC_COMMA
LD A,Z180_RDR1
CALL PRTHEXBYTE
; PRTS(" BAUD=$")
; LD HL,ASCI1BAUD / 10
; CALL PRTDEC
; PRTC('0')
#IF (PLATFORM != PLT_MK4)
LD A,66H
OUT0 (Z180_ASEXT1),A
LD A,64H
OUT0 (Z180_CNTLA1),A
LD A,Z180_ASCIB1
OUT0 (Z180_CNTLB1),A
#ENDIF
RET
;
;
;
ASCI0_IN:
CALL ASCI0_IST
OR A
JR Z,ASCI0_IN
IN0 A,(Z180_RDR0) ; READ THE CHAR FROM THE ASCI
LD E,A
RET
;
;
;
ASCI0_IST:
; CHECK FOR ERROR FLAGS
IN0 A,(Z180_STAT0)
AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR
JR Z,ASCI0_IST1 ; ALL IS WELL, CHECK FOR DATA
; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!!
IN0 A,(Z180_CNTLA0)
RES 3,A ; CLEAR EFR (ERROR FLAG RESET)
OUT0 (Z180_CNTLA0),A
ASCI0_IST1: ; CHECK FOR STAT0.RDRF (DATA READY)
IN0 A,(Z180_STAT0) ; READ LINE STATUS REGISTER
AND $80 ; TEST IF DATA IN RECEIVE BUFFER
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL CHAR READY, A = 1
RET
;
;
;
ASCI0_OUT:
CALL ASCI0_OST
OR A
JR Z,ASCI0_OUT
LD A,E
OUT0 (Z180_TDR0),A
RET
;
ASCI0_OST:
IN0 A,(Z180_STAT0)
AND $02
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL BUFFER EMPTY, A = 1
RET
;
;
;
ASCI1:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JR Z,ASCI0_IN
DEC A
JR Z,ASCI0_OUT
DEC A
JR Z,ASCI0_IST
DEC A
JR Z,ASCI0_OST
CALL PANIC
;
;
;
ASCI1_IN:
CALL ASCI1_IST
OR A
JR Z,ASCI1_IN
IN0 A,(Z180_RDR1) ; READ THE CHAR FROM THE ASCI
LD E,A
RET
;
;
;
ASCI1_IST:
; CHECK FOR ERROR FLAGS
IN0 A,(Z180_STAT1)
AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR
JR Z,ASCI1_IST1 ; ALL IS WELL, CHECK FOR DATA
; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!!
IN0 A,(Z180_CNTLA1)
RES 3,A ; CLEAR EFR (ERROR FLAG RESET)
OUT0 (Z180_CNTLA1),A
ASCI1_IST1: ; CHECK FOR STAT0.RDRF (DATA READY)
IN0 A,(Z180_STAT1) ; READ LINE STATUS REGISTER
AND $80 ; TEST IF DATA IN RECEIVE BUFFER
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL CHAR READY, A = 1
RET
;
;
;
ASCI1_OUT:
CALL ASCI1_OST
OR A
JR Z,ASCI1_OUT
LD A,E
OUT0 (Z180_TDR1),A
RET
;
ASCI1_OST:
IN0 A,(Z180_STAT1)
AND $02
JR Z,ASCI1_OST
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL BUFFER EMPTY, A = 1
RET