sio.asm
flypie_Ace-2019/testrom/sio.asm
	INCLUDE "IODEFS.H"
	INCLUDE "SYSVARS.H"
	INCLUDE "DEBUGMACROS.H"

	INCLUDE "QUEUEMACRO.H"

	SEGMENT CODE ; MAKE IT THE CURRENT SECTION

;--------------------------
	PUBLIC 	INIT_SIO

	PUBLIC 	SIOAINT_TBE,SIOAINT_ESC,SIOAINT_RCA,SIOAINT_SRC,SEND_STR_A
	
	PUBLIC 	SIOBINT_TBE,SIOBINT_ESC,SIOBINT_RCA,SIOBINT_SRC,SEND_STR_B
	PUBLIC	SIOTOTXBUFFB,SIORCVCHARB

	EXTERN 	SIOINTTBL,INTTBL, TxQB2Scr

	extern FAddtoQueue,FReadfromQueue

	; FOR RR0
	
RX_CHR_AVAILABLE		EQU	00000001B
INT_PENDING				EQU	00000010B ;
TX_BUFFER_EMPTY			EQU	00000100B
DCD						EQU	00001000B
SYNC_HUNT				EQU	00010000B
CTS						EQU	00100000B
TX_UNDERRUN_EOM			EQU	01000000B
BREAK_ABORT				EQU	10000000B

	;FOR RR1
ALL_SENT				EQU	00000001B
X1						EQU	00000010B
X2						EQU	00000100B
X3						EQU	00001000B
PARITY_ERROR			EQU	00010000B
RX_OVERRUN_ERROR		EQU	00100000B
CRC_FRAMING_ERROR		EQU	01000000B
END_OF_FRAME			EQU	10000000B

; FOR WR0

REGISTER_0				EQU	00000000B
REGISTER_1				EQU	00000001B
REGISTER_2				EQU	00000010B
REGISTER_3				EQU	00000011B
REGISTER_4				EQU	00000100B
REGISTER_5				EQU	00000101B
REGISTER_6				EQU	00000110B
REGISTER_7				EQU	00000111B


NULL_CMD				EQU	00111000B
SEND_ABORT				EQU	00001000B
RESET_EXT_STATUS_INTS	EQU	00010000B
CHANNEL_RESET			EQU	00011000B
ENABLE_INT_NEXT_RX_CHR	EQU	00100000B
RESET_TXINT_PENDING		EQU	00101000B
ERROR_RESET_LATCHES		EQU	00110000B
RETURN_FROM_INT			EQU	00111000B

RESET_RX_CRC_CHECKER	EQU	01000000B
RESET_TX_CRC_GENERATOR	EQU	10000000B
RESET_TX_UNDERRUN		EQU	11000000B

; FOR WR1

EXT_INT_ENABLE			EQU	00000001B
TX_INT_ENABLE			EQU	00000010B
STATUS_AFFECTS_VECTOR	EQU	00000100B

RX_INT_DISABLE			EQU	00000000B
RX_INT_ON_FIRST_CHR		EQU 00001000B
INT_ON_ALL_RX_CHR_P		EQU 00010000B ; (PARITY AFFECTS VECTOR
INT_ON_ALL_RX_CHR		EQU 00011000B ; (PARITY DOES NOT AFFECT
WAIT_READY_ON_R_T		EQU 00100000B
WAIT_READY_FUNCTION		EQU 01000000B
WAIT_READY_ENABLE		EQU 10000000B

; FOR WR2

;THIS  IS ONLY USED ON CHANNEL B TO SET THE INT VECTOR

; FOR WR3

RX_ENABLE				EQU 00000001B
SYNC_CHR_LOAD_INHIBIT	EQU	00000010B
ADDRESS_SEARCH_MODE		EQU	00000100B
RX_CRC_ENABLE			EQU	00001000B
ENTER_HUNT_PHASE		EQU	00010000B
AUTO_ENABLES			EQU	00100000B
RX_5_BITS_PER_CHR		EQU	00000000B
RX_7_BITS_PER_CHR		EQU	01000000B
RX_6_BITS_PER_CHR		EQU	10000000B
RX_8_BITS_PER_CHR		EQU	11000000B


; FOR WR4

NO_PARITY				EQU 00000000B
PARITY_ENABLE			EQU 00000001B
PARITY_EVEN_ODD			EQU	00000010B

SYNC_MODES_ENABLE		EQU	00000000B
RT1_STOP_BIT_CHR		EQU	00000100B
RT1_2_STOP_BIT_CHR		EQU	00001000B
RT2_STOP_BIT_CHR		EQU	00001100B

RT8_BIT_SYNC_CHR		EQU	00000000B
RT16_BIT_SYNC_CHR		EQU	00010000B
SDLC_MODE				EQU	00100000B
EXT_SYNC_MODE			EQU	00110000B

X1_CLOCK_MODE			EQU	00000000B
X16_CLOCK_MODE			EQU	01000000B
X32_CLOCK_MODE			EQU	10000000B
X64_CLOCK_MODE			EQU	11000000B

; FOR WR5

TX_CRC_ENABLE			EQU 00000001B
RTS						EQU	00000010B
SDLC_CRC_16				EQU	00000100B
TX_ENABLE				EQU	00001000B
SEND_BREAK				EQU	00010000B
TX_5_BITS_PER_CHR		EQU	00000000B
TX_7_BITS_PER_CHR		EQU	00100000B
TX_6_BITS_PER_CHR		EQU	01000000B
TX_8_BITS_PER_CHR		EQU	01100000B
DTR						EQU	10000000B


; FOR WR6

SYNC_BIT_0				EQU 00000001B
SYNC_BIT_1				EQU 00000010B
SYNC_BIT_2				EQU 00000100B
SYNC_BIT_3				EQU 00001000B
SYNC_BIT_4				EQU 00010000B
SYNC_BIT_5				EQU 00100000B
SYNC_BIT_6				EQU 01000000B
SYNC_BIT_7				EQU 10000000B

; FOR WR7

SYNC_BIT_8				EQU 000000001B
SYNC_BIT_9				EQU 000000010B
SYNC_BIT_10				EQU 000000100B
SYNC_BIT_11				EQU 000001000B
SYNC_BIT_12				EQU 000010000B
SYNC_BIT_13				EQU 000100000B
SYNC_BIT_14				EQU 001000000B
SYNC_BIT_15				EQU 010000000B

INIT_SIO:

	;PROGRAM THE SIO

	STROUTXY 08H,0BH, "INITSIO", 7 

	; THE FOLLOWINGS ARE SETTINGS FOR CHANNEL A

	;SET UP TX AND RX:
	DOOUT SIOACMD, CHANNEL_RESET								;WRITE INTO WR0: CHANNEL RESET

	; SET UP THE INT VECTOR	PAGE17 SIO TECH REF
	; THE FOLLOWINGS ARE SETTINGS FOR CHANNEL B
	
	DOOUT SIOBCMD, ERROR_RESET_LATCHES							;WRITE INTO WR0: CHANNEL RESET

	DOOUT SIOBCMD, CHANNEL_RESET								;WRITE INTO WR0: CHANNEL RESET

	DOOUT SIOBCMD, REGISTER_4|RESET_EXT_STATUS_INTS				;WRITE INTO WR0: ERROR RESET, SELECT WR0
	DOOUT SIOBCMD, X64_CLOCK_MODE|RT1_STOP_BIT_CHR|NO_PARITY	;44H WRITE INTO : CLKX16,1 STOP BIT, NO PARITY

	DOOUT SIOBCMD, REGISTER_5									;WRITE INTO WR0: SELECT 
	DOOUT SIOBCMD, TX_8_BITS_PER_CHR|TX_ENABLE					;DTR ACTIVE, TX 8BIT, BREAK OFF, TX ON, RTS INACTIVE

	DOOUT SIOBCMD, REGISTER_1									;WRITE INTO WR0: SELECT 
	DOOUT SIOBCMD, STATUS_AFFECTS_VECTOR|INT_ON_ALL_RX_CHR|TX_INT_ENABLE|EXT_INT_ENABLE
	
	LD	HL,SIOINTTBL
	LD	DE,INTTBL
	SBC HL,DE

	DOOUT SIOBCMD, REGISTER_2									;WRITE INTO WR0: SELECT WR2
	DOOUT SIOBCMD, L											;WRITE INTO WR2: CMD LINE INT VECT (SEE INT VEC TABLE) ;BITS D3,D2,D1 ARE CHANGED ACCORDING TO RX CONDITION

	
	DOOUT SIOBCMD, REGISTER_3									;WRITE INTO WR0: SELECT 
	DOOUT SIOBCMD, RX_8_BITS_PER_CHR|RX_ENABLE					;44H WRITE INTO : CLKX16,1 STOP BIT, NO PARITY

	STROUTXY 8H,04H, "           ", 11
 	
	RET

;PORT A INT HANDLERS

	.ifdef AAA
SIOAINT_TBE:
	PUSH AF	; BACKUP AF

	CALL SIOA_TBE
	STROUTXY 8H,0EH, "SIOAINT_TBE", 11 
	
	POP AF
	EI
	RETI

SIOAINT_ESC
	PUSH AF	; BACKUP AF

	STROUTXY 8H,0EH, "SIOAINT_ESC", 11 
;EXTERNAL STATUS
	DOOUT SIOACMD, REGISTER_0
	DOIN  SIOACMD, H

	POP AF
	EI
	RETI

SIOAINT_RCA:
	PUSH AF	; BACKUP AF

	CALL A_SEND_CHAR

	STROUTXY 8H,0EH, "SIOAINT_RCA", 11 

	POP AF
	EI
	RETI

SIOAINT_SRC:
	PUSH AF	; BACKUP AF

;SPECIAL RECEIVE CONDITION
	STROUTXY 8H,0EH, "SIOAINT_SRC", 11 

	DOOUT SIOACMD, ERROR_RESET_LATCHES

	POP AF
	EI
	RETI

A_RTS_OFF:
	DOOUT SIOACMD, REGISTER_5	;WRITE INTO WR0: ERROR RESET, SELECT WR0
	DOOUT SIOACMD, DTR|TX_8_BITS_PER_CHR|TX_ENABLE	;8 BITS/TX CHAR; TX ENABLE; RTS DISABLE
	RET

A_RTS_ON:
	DOOUT SIOACMD,REGISTER_5	; 
	DOOUT SIOACMD,DTR|TX_8_BITS_PER_CHR|TX_ENABLE|RTS	; 8 BITS/TX CHAR; TX ENABLE; RTS ENABLE
	RET

A_SEND_CHAR:
	PUSH AF
	PUSH HL
	PUSH BC
	CALL A_RTS_OFF

	LD 	BC,SIOADATA
	OUT (BC),A	; ECHO CHAR TO TRANSMITTER

	STROUTXY 08H,0DH, "A_SEND_CHAR", 11 
	LD		HL,25B4H
	INC		(HL)

	LD		HL,25B6H
	LD		(HL),A

	QUADOUT 0,13,SYSCLOCK

	LD		HL,25B4H
	LD		A,(SYSCLOCK)
	BIT 7,A
	JR NZ ,A_NORTS
	CALL A_RTS_OFF
	LD		(HL),'0'
	JR 		A_CARRYON
A_NORTS:
	LD		(HL),'1'
A_CARRYON:
	CALL 	A_RTS_ON

	pop	BC
	POP HL
	POP AF
	RET

SIOA_TBE:
	PUSH AF	; BACKUP AF
	PUSH BC	; BACKUP AF
	PUSH DE	; BACKUP AF
	PUSH HL	; BACKUP AF
	PUSH IY	; BACKUP AF

;TEST.C:16: IF (NEXTIN != NEXTOUT)
	LD	A,(SIOANEXTIN)
	LD	IY,SIOANEXTOUT
	SUB	A,(IY)
	JR	Z,SIOAINT_TBE_EXIT
;TEST.C:18: UART1_SENDDATA8(UBUFFER[NEXTOUT++]);
	LD	BC, SIOATXBUFF
	LD	E, (IY)
	INC	(IY)
	LD	L, E
	LD	H, 00H
	ADD	HL, BC
	LD	A, (HL)

	CALL A_SEND_CHAR

;TEST.C:19: NEXTOUT &= 0X1F;
	LD	IY, SIOANEXTOUT
	LD	A, (IY)
	AND	A, 01FH
	LD	(IY), A

SIOAINT_TBE_EXIT:

	POP IY	
	POP HL	
	POP DE	
	POP BC	
	POP AF
	RET	
; ---------------------------------
; FUNCTION UARTSENDCHAR
; ---------------------------------
SIOSENDCHARA: ; CHAR TO SEND IS IN A
;TEST.C:32: UBUFFER[NEXTIN++] = BYTE;
	PUSH AF;
	LD	A,(SIOANEXTIN)
	LD	IY, SIOANEXTOUT
	SUB	A,(IY+0)
	JR	Z,ISEMPTYA

	LD D,0
	JP FLAGSETA
ISEMPTYA:
	LD D,1

FLAGSETA:
	LD	IY, SIOANEXTIN
	LD	C, (IY)
	INC	(IY)
	LD	HL, SIOATXBUFF
	LD	B, 00H
	ADD	HL, BC

	POP AF
	LD	(HL), A
;TEST.C:33: NEXTIN &= 0X01F;
	LD	IY, SIOANEXTIN
	LD	A, (IY)
	AND	A, SERIALTXBUFFLEN-1
	LD	(IY), A

	LD	A,D
	JR	NZ,EXITTHISA

	CALL SIOA_TBE

EXITTHISA:
	RET

	.else

SIOAINT_TBE:
SIOAINT_ESC:
SIOAINT_RCA:
SIOAINT_SRC:
	reti

SEND_STR_A:
	ret

	.endif

SIOBINT_TBE:			;Transmit Buffer Empty 
	PUSH AF	; BACKUP AF

	DOOUT 		SIOBCMD,RESET_TXINT_PENDING

	STROUTXY 	8H,0EH, "SIOBINT_TBE", 11 
	QUADOUT 	0,0EH, SYSCLOCK

	QueueEmpty TxQBReadPos,TxQBWritePos

	cp 1
	jr	z,NOQEUE
	CALL		SIOB_TBE
NOQEUE:
;;	la	a,1
	ld	HL,TxBIdle
	ld	(HL),1
	POP 		AF
	EI
	RETI

SIOBINT_ESC:	;External/Status Change
	PUSH 	AF	; BACKUP AF
	PUSH 	BC	; BACKUP AF
	PUSH 	DE	; BACKUP AF
	PUSH 	HL	; BACKUP AF

;EXTERNAL STATUS
	STROUTXY 08H,0FH, "SIOBINT_ESC", 11 
	QUADOUT 0,0FH, SYSCLOCK

	DOOUT 	SIOBCMD, REGISTER_0
	DOIN  	SIOBCMD, D
	HOUTXY 	08H,14H,D

	LD		HL,25F8H
	LD 		(HL),D

	COUTXY 	08H,14H, 'X'
	COUTXY 	08H,14H, 'X'
	COUTXY 	0AH,14H, 'X'
	COUTXY 	0BH,14H, 'X'
	COUTXY 	0CH,14H, 'X'
	COUTXY 	0DH,14H, 'X'
	COUTXY 	0EH,14H, 'X'
	COUTXY 	0FH,14H, 'X'

	BIT		0,D
	JR		Z,BIT0R
;	Receive Character Available
	DOIN 	SIOBDATA,A	;Read
	COUTXY 	08H,14H, '0'
BIT0R:
	BIT		1,D
	JR		Z,BIT1R
;	Interrupt Pending
	COUTXY 	09H,14H, '1'
BIT1R:
	BIT		2,D
	JR		Z,BIT2R
;	Transmit Buffer Empty
	DOOUT SIOBCMD, RESET_TXINT_PENDING
	COUTXY 	0AH,14H, '2'
BIT2R:
	BIT		3,D
	JR		Z,BIT3R
;	Data Carrier Detect
	COUTXY 	0BH,14H, '3'
BIT3R:
	BIT		4,D
	JR		Z,BIT4R
;	Sync/Hunt
	COUTXY 	0CH,14H, '4'
BIT4R:
	BIT		5,D
	JR		Z,BIT5R
;	CTS
	COUTXY 	0DH,14H, '5'
BIT5R:
	BIT		6,D
	JR		Z,BIT6R
;	UNDERRUN EOM
	COUTXY 	0EH,14H, '6'
BIT6R:
	BIT		7,D
	JR		Z,BIT7R
;	BREAK/ABORT
	COUTXY 	0FH,14H, '7'
BIT7R:	
	DOOUT 	SIOBCMD, REGISTER_1
	DOIN  	SIOBCMD, D
	LD		HL,25F9H
	LD 		(HL),D

	DOOUT 	SIOBCMD, REGISTER_2
	DOIN  	SIOBCMD, D
	LD		HL,25FAH
	LD 		(HL),D

	DOOUT 	SIOBCMD, RESET_EXT_STATUS_INTS
	DOOUT	SIOBCMD, ERROR_RESET_LATCHES

	POP 	HL
	POP 	DE
	POP		BC
	POP 	AF
	EI
	RETI

SIOBINT_RCA:	;Receive Character Available
	PUSH 	AF	; BACKUP AF
	PUSH 	HL	; BACKUP HL
	PUSH 	DE	; BACKUP DE

	DOIN 	SIOBDATA,D

	AddtoQueue D,RxQB,RxQBReadPos,RxQBWritePos

	HOUTXY 	14H,10H,D

	DOOUT SIOBCMD, REGISTER_0
	DOIN  SIOBCMD, D
	HOUTXY 	17H,10h,D

	DOOUT SIOBCMD, REGISTER_1
	DOIN  SIOBCMD, D
	HOUTXY 	1AH,10h,D

	DOOUT SIOBCMD, REGISTER_2
	DOIN  SIOBCMD,D
	HOUTXY 	1DH,10h,D
	
	STROUTXY 08H,10H,"SIOBINT_RCA", 11 
	QUADOUT 0,10H,SYSCLOCK

	POP	DE
	POP HL
	POP AF
	EI
	RETI

SIOBINT_SRC:	;Special Receive Condition
	PUSH AF	; BACKUP AF

	STROUTXY 08H, 11H, "SIOBINT_SRC", 11

	QUADOUT 0,11H, SYSCLOCK

	DOOUT SIOBCMD, REGISTER_0
	DOIN  SIOBCMD, H
	HOUTXY 14H,11h,H

	LD	A,H
	TST	6
	JR	NZ,NORESNEEDED
	DOOUT 	SIOBCMD, RESET_TX_UNDERRUN
NORESNEEDED:
	DOOUT SIOBCMD, REGISTER_1
	DOIN  SIOBCMD, H
	HOUTXY 17H,11h,H
	
	;SPECIAL RECEIVE CONDITION

	DOOUT 	SIOBCMD, RESET_EXT_STATUS_INTS
	DOOUT	SIOBCMD, ERROR_RESET_LATCHES
	
	POP AF
	EI
	RETI


	;-------------------------------------------------------------------------------
; SERIAL MANAGEMENT

B_RTS_OFF:
	DOOUT SIOBCMD, REGISTER_5	;WRITE INTO WR0: ERROR RESET, SELECT WR0
	DOOUT SIOBCMD, DTR|TX_8_BITS_PER_CHR|TX_ENABLE	;8 BITS/TX CHAR; TX ENABLE; RTS DISABLE
	RET

B_RTS_ON:
	DOOUT SIOBCMD,REGISTER_5	; 
	DOOUT SIOBCMD,DTR|TX_8_BITS_PER_CHR|TX_ENABLE|RTS	; 8 BITS/TX CHAR; TX ENABLE; RTS ENABLE
	RET

SIO_B_DI:
	;DISABLE SIO CHANNEL A RX
	DOOUT SIOBCMD,REGISTER_3	; WRITE INTO WR0: SELECT 
	DOOUT SIOBCMD,SYNC_CHR_LOAD_INHIBIT|RX_ENABLE	; WRITE INTO : RX DISABLE;
	RET

B_SEND_CHAR:
	PUSH AF
	PUSH HL
	PUSH BC
	CALL B_RTS_OFF

	ld HL,TxBIdle
	ld (HL),0
	
	LD BC,SIOBDATA
	OUT (BC),A	

	STROUTXY 08H, 0DH, "B_SEND_CHAR", 11 
	LD		HL,25B4H
	INC		(HL)

	LD		HL,25B6H
	LD		(HL),A

	QUADOUT 0,13,SYSCLOCK

	LD		HL,25B4H
	LD		A,(SYSCLOCK)
	BIT 7,A
	JR NZ ,B_NORTS
	CALL B_RTS_OFF
	LD		(HL),'0'
	JR 		B_CARRYON
B_NORTS:
	LD		(HL),'1'
B_CARRYON:
	CALL 	B_RTS_ON

	pop	BC
	POP HL
	POP AF
	RET



SIOB_TBE:	
	PUSH BC	; BACKUP AF
	PUSH DE	; BACKUP AF
	PUSH HL	; BACKUP AF
	PUSH IY	; BACKUP AF

	ReadfromQueue TxQB,TxQBReadPos,TxQBWritePos

	LD	A,B
	cp 	0
	jr	z,NOCHAR

	LD		A,C
	call	B_SEND_CHAR
	
	JP	CARRYON

NOCHAR:
;	STROUTXY 0h,12H, "NCHRTBE", 7 
	ld HL,TxBIdle
	ld (HL),1

CARRYON:
	POP IY	
	POP HL	
	POP DE	
	POP BC	 

	RET	
	

	
; ---------------------------------
; FUNCTION UARTSENDCHAR
; ---------------------------------
SIOTOTXBUFFB: ; CHAR TO SEND IS IN A
;TEST.C:32: UBUFFER[NEXTIN++] = BYTE;

	AddtoQueue a,TxQB,TxQBReadPos,TxQBWritePos
	cp 0
	jr	z,THISFULL
	
	STROUTXY 18H, 0DH, "!QF", 3	
	LD		A,(TxQBWritePos)
	HOUTXY 1BH, 0DH, A

	ld HL,TxBIdle
	ld a,(HL)
	cp	1
	jr	nz,EXITTHISB
	DI
	CALL SIOB_TBE
	EI
	jp	EXITTHISB
THISFULL:
	STROUTXY 18H, 0DH, " QF", 3	

EXITTHISB:
	RET


CHR2BUFFB:
	RET

SEND_STR_B:
	PUSH AF
	PUSH HL
	PUSH DE
	PUSH BC

AGAIN:
	LD	A,0
	CP (HL)
	JR Z,LEAVE
	CALL CHR2BUFFB
	INC	HL
	JR	AGAIN

LEAVE:
	POP BC
	POP DE
	POP HL
	POP AF

	RET


SIORCVCHARB: ;A set valid data C = data

	ReadfromQueue RxQB,RxQBReadPos,RxQBWritePos

	ld	a,b
	cp 	0
	jr	z,EMPTYB
	LD	A,1
	jp	LEAVERCVB
EMPTYB:
	LD	A,0	; Queue Empty
LEAVERCVB:
	RET


