forked from MirrorRepos/RomWBW
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.
506 lines
13 KiB
506 lines
13 KiB
;
|
|
;==================================================================================================
|
|
; 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
|
|
; 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)
|
|
; | | | +---------- 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)
|
|
;
|
|
; 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_PREINIT:
|
|
;
|
|
; SETUP THE DISPATCH TABLE ENTRIES
|
|
;
|
|
LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180
|
|
LD C,0 ; PHYSICAL UNIT INDEX
|
|
ASCI_PREINIT1:
|
|
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_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
|
|
PRTS("ASCI0: IO=0x$") ; PREFIX
|
|
LD A,Z180_TDR0 ; LOAD TDR PORT ADDRESS
|
|
CALL PRTHEXBYTE ; PRINT IT
|
|
|
|
CALL PC_COMMA ; FORMATTING
|
|
LD A,Z180_RDR0 ; LOAD RDR PORT ADDRESS
|
|
CALL PRTHEXBYTE ; PRINT IT
|
|
|
|
PRTS(" MODE=$") ; FORMATTING
|
|
LD DE,(ASCI0_CONFIG) ; LOAD CONFIG
|
|
CALL PS_PRTSC0 ; PRINT IT
|
|
;
|
|
; ASCI1
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("ASCI1: IO=0x$") ; PREFIX
|
|
LD A,Z180_TDR1 ; LOAD TDR PORT ADDRESS
|
|
CALL PRTHEXBYTE ; PRINT IT
|
|
|
|
CALL PC_COMMA ; FORMATTING
|
|
LD A,Z180_RDR1 ; LOAD RDR PORT ADDRESS
|
|
CALL PRTHEXBYTE ; PRINT IT
|
|
|
|
PRTS(" MODE=$") ; FORMATTING
|
|
LD DE,(ASCI1_CONFIG) ; LOAD CONFIG
|
|
CALL PS_PRTSC0 ; PRINT IT
|
|
;
|
|
XOR A
|
|
RET
|
|
;
|
|
; DISPATCH TO SPECIFIC ASCI UNIT
|
|
;
|
|
ASCI_DISPATCH:
|
|
PUSH IY ; PUSH UNIT DATA WORD
|
|
POP AF ; POP TO AF, A := DEVICE NUM
|
|
OR A ; SET FLAGS
|
|
JP Z,ASCI0
|
|
DEC A
|
|
JP Z,ASCI1
|
|
CALL PANIC
|
|
;
|
|
; ASCI 0 FUNCTIONS
|
|
;
|
|
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
|
|
DEC A
|
|
JP Z,ASCI0_INITDEV
|
|
DEC A
|
|
JP Z,ASCI0_QUERY
|
|
DEC A
|
|
JP Z,ASCI0_DEVICE
|
|
CALL PANIC
|
|
;
|
|
ASCI0_IN:
|
|
CALL ASCI0_IST
|
|
OR A
|
|
JR Z,ASCI0_IN
|
|
IN0 A,(Z180_RDR0) ; READ THE CHAR
|
|
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
|
|
;
|
|
ASCI0_INITDEV:
|
|
; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT)
|
|
LD A,D ; TEST DE FOR
|
|
AND E ; ... VALUE OF -1
|
|
INC A ; ... SO Z SET IF -1
|
|
JR NZ,ASCI0_INITDEV1 ; IF NEW CONFIG (NOT -1), IMPLEMENT IT
|
|
LD DE,(ASCI0_CONFIG) ; OTHERWISE, LOAD EXISTING CONFIG
|
|
;
|
|
ASCI0_INITDEV1:
|
|
; DETERMINE APPROPRIATE CNTLB VALUE (BASED ON BAUDRATE & CPU SPEED)
|
|
LD A,D ; BYTE W/ ENCODED BAUD RATE
|
|
AND $1F ; ISOLATE BITS
|
|
LD L,A ; MOVE TO L
|
|
LD H,0 ; CLEAR MSB
|
|
PUSH DE ; SAVE CONFIG
|
|
CALL ASCI_CNTLB ; DERIVE CNTLB VALUE IN C
|
|
POP DE ; RESTORE CONFIG
|
|
;CALL TSTPT
|
|
RET NZ ; ABORT ON ERROR
|
|
;
|
|
LD B,$64 ; B := DEFAULT CNTLB VALUE
|
|
|
|
; DATA BITS
|
|
LD A,E ; LOAD CONFIG BYTE
|
|
AND $03 ; ISOLATE DATA BITS
|
|
CP $03 ; 8 DATA BITS?
|
|
JR Z,ASCI0_INITDEV2 ; IF SO, NO CHG, CONTINUE
|
|
RES 2,B ; RESET CNTLA BIT 2 FOR 7 DATA BITS
|
|
|
|
ASCI0_INITDEV2:
|
|
; STOP BITS
|
|
BIT 2,E ; TEST STOP BITS CONFIG BIT
|
|
JR Z,ASCI0_INITDEV3 ; IF CLEAR, NO CHG, CONTINUE
|
|
SET 0,B ; SET CNTLA BIT 0 FOR 2 STOP BITS
|
|
|
|
ASCI0_INITDEV3:
|
|
; PARITY ENABLE
|
|
BIT 3,E ; TEST PARITY ENABLE CONFIG BIT
|
|
JR Z,ASCI0_INITDEV4 ; NO PARITY, SKIP ALL PARITY CHGS
|
|
SET 1,B ; SET CNTLA BIT 1 FOR PARITY ENABLE
|
|
|
|
; PARITY EVEN/ODD
|
|
BIT 4,E ; TEST EVEN PARITY CONFIG BIT
|
|
JR NZ,ASCI0_INITDEV4 ; EVEN PARITY, NO CHG, CONTINUE
|
|
SET 4,C ; SET CNTLB BIT 4 FOR ODD PARITY
|
|
|
|
ASCI0_INITDEV4:
|
|
; IMPLEMENT CONFIGURATION
|
|
LD A,$66 ; LOAD DEFAULT ASEXT VALUE
|
|
OUT0 (Z180_ASEXT0),A ; SET IT
|
|
LD A,B ; FINAL CNTLA VALUE TO ACCUM
|
|
OUT0 (Z180_CNTLA0),A ; WRITE TO CNTLA REGISTER
|
|
LD A,C ; FINAL CNTLB VALUE TO ACCUM
|
|
OUT0 (Z180_CNTLB0),A ; WRITE TO CNTLA REGISTER
|
|
;
|
|
LD (ASCI0_CONFIG),DE ; RECORD UPDATED CONFIG
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
ASCI0_QUERY:
|
|
LD DE,(ASCI0_CONFIG)
|
|
XOR A
|
|
RET
|
|
;
|
|
ASCI0_DEVICE:
|
|
LD D,CIODEV_ASCI ; D := DEVICE TYPE
|
|
LD E,0 ; E := PHYSICAL UNIT
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; ASCI 1 FUNCTIONS
|
|
;
|
|
ASCI1:
|
|
LD A,B ; GET REQUESTED FUNCTION
|
|
AND $0F ; ISOLATE SUB-FUNCTION
|
|
JR Z,ASCI1_IN
|
|
DEC A
|
|
JR Z,ASCI1_OUT
|
|
DEC A
|
|
JR Z,ASCI1_IST
|
|
DEC A
|
|
JR Z,ASCI1_OST
|
|
DEC A
|
|
JP Z,ASCI1_INITDEV
|
|
DEC A
|
|
JP Z,ASCI1_QUERY
|
|
DEC A
|
|
JP Z,ASCI1_DEVICE
|
|
CALL PANIC
|
|
;
|
|
ASCI1_IN:
|
|
CALL ASCI1_IST
|
|
OR A
|
|
JR Z,ASCI1_IN
|
|
IN0 A,(Z180_RDR1) ; READ THE CHAR
|
|
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
|
|
;
|
|
ASCI1_INITDEV:
|
|
; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT)
|
|
LD A,D ; TEST DE FOR
|
|
AND E ; ... VALUE OF -1
|
|
INC A ; ... SO Z SET IF -1
|
|
JR NZ,ASCI1_INITDEV1 ; IF NEW CONFIG (NOT -1), IMPLEMENT IT
|
|
LD DE,(ASCI1_CONFIG) ; OTHERWISE, LOAD EXISTING CONFIG
|
|
;
|
|
ASCI1_INITDEV1:
|
|
; DETERMINE APPROPRIATE CNTLB VALUE (BASED ON BAUDRATE & CPU SPEED)
|
|
LD A,D ; BYTE W/ ENCODED BAUD RATE
|
|
AND $1F ; ISOLATE BITS
|
|
LD L,A ; MOVE TO L
|
|
LD H,0 ; CLEAR MSB
|
|
PUSH DE ; SAVE CONFIG
|
|
CALL ASCI_CNTLB ; DERIVE CNTLB VALUE
|
|
POP DE ; RESTORE CONFIG
|
|
;CALL TSTPT
|
|
RET NZ ; ABORT ON ERROR
|
|
;
|
|
LD B,$64 ; B := DEFAULT CNTLB VALUE
|
|
|
|
; DATA BITS
|
|
LD A,E ; LOAD CONFIG BYTE
|
|
AND $03 ; ISOLATE DATA BITS
|
|
CP $03 ; 8 DATA BITS?
|
|
JR Z,ASCI1_INITDEV2 ; IF SO, NO CHG, CONTINUE
|
|
RES 2,B ; RESET CNTLA BIT 2 FOR 7 DATA BITS
|
|
|
|
ASCI1_INITDEV2:
|
|
; STOP BITS
|
|
BIT 2,E ; TEST STOP BITS CONFIG BIT
|
|
JR Z,ASCI1_INITDEV3 ; IF CLEAR, NO CHG, CONTINUE
|
|
SET 0,B ; SET CNTLA BIT 0 FOR 2 STOP BITS
|
|
|
|
ASCI1_INITDEV3:
|
|
; PARITY ENABLE
|
|
BIT 3,E ; TEST PARITY ENABLE CONFIG BIT
|
|
JR Z,ASCI1_INITDEV4 ; NO PARITY, SKIP ALL PARITY CHGS
|
|
SET 1,B ; SET CNTLA BIT 1 FOR PARITY ENABLE
|
|
|
|
; PARITY EVEN/ODD
|
|
BIT 4,E ; TEST EVEN PARITY CONFIG BIT
|
|
JR NZ,ASCI1_INITDEV4 ; EVEN PARITY, NO CHG, CONTINUE
|
|
SET 4,C ; SET CNTLB BIT 4 FOR ODD PARITY
|
|
|
|
ASCI1_INITDEV4:
|
|
; IMPLEMENT CONFIGURATION
|
|
LD A,$66 ; LOAD DEFAULT ASEXT VALUE
|
|
OUT0 (Z180_ASEXT1),A ; SET IT
|
|
LD A,B ; FINAL CNTLA VALUE TO ACCUM
|
|
OUT0 (Z180_CNTLA1),A ; WRITE TO CNTLA REGISTER
|
|
LD A,C ; FINAL CNTLB VALUE TO ACCUM
|
|
OUT0 (Z180_CNTLB1),A ; WRITE TO CNTLA REGISTER
|
|
;
|
|
LD (ASCI1_CONFIG),DE ; RECORD UPDATED CONFIG
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
ASCI1_QUERY:
|
|
LD DE,(ASCI1_CONFIG)
|
|
XOR A
|
|
RET
|
|
;
|
|
ASCI1_DEVICE:
|
|
LD D,CIODEV_ASCI ; D := DEVICE TYPE
|
|
LD E,1 ; E := PHYSICAL UNIT
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; LOCAL DATA
|
|
;
|
|
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
|
|
; EXIT: C = CNTLB VALUE, A=0/Z IFF SUCCESS
|
|
;
|
|
; DESIRED DIVISOR == CPUHZ / BAUD
|
|
; 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 = 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
|
|
; SS := LOG2(X)
|
|
;
|
|
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
|
|
;CALL TSTPT
|
|
RET NZ ; ABORT ON ERROR
|
|
PUSH HL ; HL HAS (BAUD / 75), SAVE IT
|
|
LD HL,(CB_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
|
|
POP DE ; RESTORE (BAUD / 75)
|
|
RET NZ ; ABORT IF REMAINDER
|
|
PUSH BC ; MOVE WORKING VALUE
|
|
POP HL ; ... BACK TO HL
|
|
CALL DIV16 ; BC := X / (BAUD / 75)
|
|
;CALL TSTPT
|
|
RET NZ ; ABORT IF REMAINDER
|
|
;
|
|
; DETERMINE PS BIT BY ATTEMPTING DIVIDE BY 3
|
|
PUSH BC ; SAVE WORKING VALUE ON STACK
|
|
PUSH BC ; MOVE WORKING VALUE
|
|
POP HL ; ... TO HL
|
|
LD DE,3 ; SETUP TO DIVIDE BY 3
|
|
CALL DIV16 ; BC := X / 3, REM IN HL, ZF
|
|
;CALL TSTPT
|
|
POP HL ; HL := PRIOR WORKING VALUE
|
|
LD E,0 ; INIT E := 0 AS WORKING CNTLB VALUE
|
|
JR NZ,ASCI_CNTLB1 ; DID NOT WORK, LEAVE PS==0, SKIP AHEAD
|
|
SET 5,E ; SET PS BIT
|
|
PUSH BC ; MOVE NEW WORKING
|
|
POP HL ; ... VALUE TO HL
|
|
;
|
|
ASCI_CNTLB1:
|
|
;CALL TSTPT
|
|
; DETERMINE DR BIT BY ATTEMPTING DIVIDE BY 4
|
|
LD A,L ; LOAD LSB OF WORKING VALUE
|
|
AND $03 ; ISOLATE LOW ORDER BITS
|
|
JR NZ,ASCI_CNTLB2 ; NOT DIVISIBLE BY 4, SKIP AHEAD
|
|
SET 3,E ; SET PS BIT
|
|
SRL H ; DIVIDE HL BY 4
|
|
RR L ; ...
|
|
SRL H ; ...
|
|
RR L ; ...
|
|
;
|
|
ASCI_CNTLB2:
|
|
;CALL TSTPT
|
|
; DETERMINE SS BITS BY RIGHT SHIFTING AND INCREMENTING
|
|
LD B,7 ; LOOP COUNTER, MAX VALUE OF SS IS 7
|
|
LD C,E ; MOVE WORKING CNTLB VALUE TO C
|
|
ASCI_CNTLB3:
|
|
BIT 0,L ; CAN WE SHIFT AGAIN?
|
|
JR NZ,ASCI_CNTLB4 ; NOPE, DONE
|
|
SRL H ; IMPLEMENT THE
|
|
RR L ; ... SHIFT OPERATION
|
|
INC C ; INCREMENT SS BITS
|
|
DJNZ ASCI_CNTLB3 ; LOOP IF MORE SHIFTING POSSIBLE
|
|
;
|
|
; AT THIS POINT HL MUST BE EQUAL TO 1 OR WE FAILED!
|
|
DEC HL ; IF HL == 1, SHOULD BECOME ZERO
|
|
LD A,H ; TEST HL
|
|
OR L ; ... FOR ZERO
|
|
RET NZ ; ABORT IF NOT ZERO
|
|
;
|
|
ASCI_CNTLB4:
|
|
;CALL TSTPT
|
|
XOR A
|
|
RET
|
|
;
|
|
|