	list	P=16C84,R=DEC

;version jan 5,1995	additional comments added

INDIR	EQU	0x00
RTCC	EQU	0x01	; in bank 0
OPTREG	EQU	0x01	; in bank 1
PC	EQU	0x02
STATUS	EQU	0x03	; F3 Reg is STATUS Reg.
RP0	EQU	5
ZBIT	EQU	2
CARRY	EQU	0

FSR	EQU	0x04
Port_A	EQU	0x05	; in bank 0
TRISA	EQU	0x05	; in bank 1
Port_B	EQU	0x06	; in bank 0
TRISB	EQU	0x06	; in bank 1
EEDATA	EQU	0x08	; in bank 0
EECON1	EQU	0x08	; in bank 1
EEADR	EQU	0x09	; in bank 0
EECON2	EQU	0x09	; in bank 1
PCLATH	EQU	0x0A
INTCON	EQU	0x0B

REG0C	EQU	0x0C
REG0D	EQU	0x0D
REG0E	EQU	0x0E	;byte 1 in 74 mess
REG0F	EQU	0x0F	;byte 2 in 74 mess

REG10	EQU	0x10	;next 10 bytes used as buffer

REG12	EQU	0x12
REG13	EQU	0x13
REG14	EQU	0x14

REG1A	EQU	0x1A	;8 bytes key buffer
REG1B	EQU	0x1B
REG1C	EQU	0x1C
REG1D	EQU	0x1D
REG1E	EQU	0x1E
REG1F	EQU	0x1F
REG20	EQU	0x20
REG21	EQU	0x21

REG22	EQU	0x22
REG23	EQU	0x23
REG24	EQU	0x24
REG25	EQU	0x25	;length to xmit or rec
REG26	EQU	0x26
REG27	EQU	0x27
REG28	EQU	0x28
REG29	EQU	0x29

	ORG	0
START	GOTO	BEGIN

S1  	RETLW	0x01
S2  	RETLW	0xFF
S3	RETLW	0xFF
	RETURN

S5	CLRF	PCLATH
	ADDWF	PC
	GOTO	F70	;function 70
	GOTO	F72	;72
	GOTO	F74	;74
	GOTO	F76	;76
	GOTO	F78	;78
	GOTO	F7A	;7A
	GOTO	F7C	;7C
	GOTO	F7E	;7E
	GOTO	F80	;80
	GOTO	F7E	;82

S11	CLRF	PCLATH
	ADDWF	PC
	RETLW	0x06	;function 70
	RETLW	0x10	;72
	RETLW	0x20	;74
	RETLW	0x01	;76
	RETLW	0x08	;78
	RETLW	0x19	;7A
	RETLW	0x10	;7C
	RETLW	0x40	;7E
	RETLW	0x01	;80
	RETLW	0x40	;82

RTR	CLRF	PCLATH
	ADDWF	PC
	RETLW	0x3F
	RETLW	0x67
	RETLW	0x05
	RETLW	0x05
	RETLW	'M'
	RETLW	'A'
	RETLW	'S'
	RETLW	'T'
	RETLW	'E'
	RETLW	'M'
	RETLW	'Y'

S2A	CLRF	PCLATH
	ADDWF	PC
MESS0	RETLW	'M'
	RETLW	'A'
	RETLW	'S'
	RETLW	'T'
	RETLW	'E'
	RETLW	'R'

MESS2	RETLW	0xC0
	RETLW	0x53
	RETLW	0xF5
	RETLW	0x86
	RETLW	0x7D
	RETLW	0x83
	RETLW	0x53
	RETLW	0x6B
	RETLW	0xBC
	RETLW	0x6E
	RETLW	0x9E
	RETLW	0x8C
	RETLW	0x53
	RETLW	0xEF
	RETLW	0xE0
	RETLW	0xC2
	RETLW	0xE9
	RETLW	0xDD
	RETLW	0xCE
	RETLW	0xC8
	RETLW	0x74
	RETLW	0xD7
	RETLW	0xB6
	RETLW	0xDA
	RETLW	0xDA

	ORG	0x050
MESS3	RETLW	0xF8
	RETLW	'T'
	RETLW	'H'
	RETLW	'I'
	RETLW	'S'
	RETLW	' '
	RETLW	'S'
	RETLW	'H'
	RETLW	'O'
	RETLW	'W'
	RETLW	' '
	RETLW	'I'
	RETLW	'S'
	RETLW	' '
	RETLW	' '
	RETLW	'C'
	RETLW	'O'
	RETLW	'M'
	RETLW	'P'
	RETLW	'L'
	RETLW	'E'
	RETLW	'T'
	RETLW	'E'
	RETLW	' '
	RETLW	' '

MESS4	RETLW	0xD8
	RETLW	'T'
	RETLW	'H'
	RETLW	'I'
	RETLW	'S'
	RETLW	' '
	RETLW	'C'
	RETLW	'H'
	RETLW	'A'
	RETLW	'N'
	RETLW	'N'
	RETLW	'E'
	RETLW	'L'
	RETLW	' '
	RETLW	'I'
	RETLW	'S'
	RETLW	' '
	RETLW	'B'
	RETLW	'L'
	RETLW	'O'
	RETLW	'C'
	RETLW	'K'
	RETLW	'E'
	RETLW	'D'
	RETLW	' '

MESS5	RETLW	0xD8
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	'N'
	RETLW	'O'
	RETLW	'T'
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	'A'
	RETLW	'U'
	RETLW	'T'
	RETLW	'H'
	RETLW	'O'
	RETLW	'R'
	RETLW	'I'
	RETLW	'Z'
	RETLW	'E'
	RETLW	'D'
	RETLW	' '

MESS6	RETLW	0xCC
	RETLW	' '
	RETLW	' '
	RETLW	'S'
	RETLW	'C'
	RETLW	'A'
	RETLW	'N'
	RETLW	'N'
	RETLW	'I'
	RETLW	'N'
	RETLW	'G'
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	'W'
	RETLW	'A'
	RETLW	'I'
	RETLW	'T'
	RETLW	' '
	RETLW	' '
	RETLW	' '
	RETLW	' '

MESS7	RETLW	0xD8
	RETLW	' '
	RETLW	'D'
	RETLW	'E'
	RETLW	'C'
	RETLW	'R'
	RETLW	'Y'
	RETLW	'P'
	RETLW	'T'
	RETLW	'I'
	RETLW	'O'
	RETLW	'N'
	RETLW	' '
	RETLW	'N'
	RETLW	'O'
	RETLW	'T'
	RETLW	' '
	RETLW	'P'
	RETLW	'O'
	RETLW	'S'
	RETLW	'S'
	RETLW	'I'
	RETLW	'B'
	RETLW	'L'
	RETLW	'E'

SCD	CLRF	PCLATH
	ADDWF	PC
	RETLW	0x35
	RETLW	0x1C
	RETLW	0x62
	RETLW	0x0D
	RETLW	0x81
	RETLW	0x76
	RETLW	0x5A
	RETLW	0xE2
	RETLW	0xA8
	RETLW	0x28
	RETLW	0x05
	RETLW	0xE6
	RETLW	0x61
	RETLW	0x9C
	RETLW	0x09
	RETLW	0xF7
	RETLW	0xBD
	RETLW	0xA8
	RETLW	0xF6
	RETLW	0x54
	RETLW	0x28
	RETLW	0xD9
	RETLW	0x7A
	RETLW	0xCC
	RETLW	0x1F
	RETLW	0x93
	RETLW	0x0F
	RETLW	0x36
	RETLW	0xBF
	RETLW	0xE8
	RETLW	0x00
	RETLW	0x92
	RETLW	0xD2
	RETLW	0x7B
	RETLW	0x87
	RETLW	0x0E
	RETLW	0xAC
	RETLW	0xE4
	RETLW	0xA8
	RETLW	0x96
	RETLW	0xB6

BEGIN	CLRF	STATUS
	CLRF	FSR
	BSF	STATUS,RP0	;select bank 1
	MOVLW	0xFF
	MOVWF	Port_A	;RA is input
	MOVWF	Port_B	;RB is input
	MOVLW	0x5F	;OPTION REG=5F
	MOVWF	OPTREG
	BCF	Port_B,4	;RB4 output
	BCF	STATUS,RP0	;select bank 0
	CLRF	Port_A
	CLRF	Port_B
	CLRF	PCLATH
	CLRF	INTCON
	CLRF	REG23
	CLRF	REG22
	BSF	REG23,0
	MOVLW	11	;RTR 11 long
	MOVWF	REG25
L10B	MOVF	REG25,W
	SUBLW	11
	CALL	RTR	;get next char from RTR
	CALL	XMIT	;send char
	DECFSZ	REG25
	GOTO	L10B	;loop if not all char send

L111	CALL	RCHAR	;read 1st char
	ADDLW	0xAD
	BTFSS	STATUS,ZBIT
	GOTO	L111	;loop if not 53
	CALL	RCHAR	;get function code
	MOVWF	REG26	;save possible function code
	CALL	RCHAR	;get 1st addr byte
	BTFSS	STATUS,ZBIT
	GOTO	L111	;restart if not 00
	CALL	RCHAR	;get 2nd addr byte
	BTFSS	STATUS,ZBIT
	GOTO	L111	;restart if not 00
	CALL	RCHAR	;get length
	MOVWF	REG25
	BCF	STATUS,CARRY
	RRF	REG26,W
	BTFSC	STATUS,CARRY	;if function code bit0=1
	GOTO	O9001	;respond with 9001

	ADDLW	0xC8
	BTFSS	STATUS,CARRY
	GOTO	O9001

	ADDLW	0xF6
	BTFSC	STATUS,CARRY
	GOTO	O9001

	ADDLW	0x0A
	MOVWF	FSR
	CALL	S11	;check length byte
	XORWF	REG25,W
	BTFSS	STATUS,ZBIT
	GOTO	O9001	;exit if not ok

	MOVF	REG26,W
	CALL	XMIT	;respond with function code
	MOVF	FSR,W
	CALL	S5
	MOVLW	0x90	;respond with ok
	CALL	XMIT
	MOVLW	0x00
	CALL	XMIT
	GOTO	L111

O9001	MOVLW	0x90	;error response
	CALL	XMIT
	MOVLW	0x01
	CALL	XMIT
	GOTO	L111

;response to function 74 (read key message)
F74	CALL	CLRBUF	;clear key buffer
	BCF	REG23,6
	BCF	REG23,1
	CALL	RCHAR	;get 1st char
	MOVWF	REG0E
	CALL	RCHAR	;get 2nd char
	MOVWF	REG0F
	
	CALL	S1D8	;process bytes 1-2
	MOVWF	REG27
	MOVLW	REG1A
	MOVWF	FSR
	MOVF	REG0E,W
	CALL	S203
	MOVF	REG0F,W
	CALL	S203

	MOVLW	REG10	;process bytes 3-12
	MOVWF	REG25
L14E	MOVF	FSR,W
	MOVWF	REG26
	MOVF	REG25,W
	MOVWF	FSR
	CALL	RCHAR
	MOVWF	INDIR
	MOVWF	REG0C
	MOVF	REG26,W
	MOVWF	FSR
	MOVF	REG0C,W
	CALL	S203
	INCF	REG25
	MOVLW	REG1A	;10 bytes processed?
	XORWF	REG25,W
	BTFSS	STATUS,ZBIT
	GOTO	L14E	;loop if not

	MOVLW	15	;process bytes 13-27
	MOVWF	REG25
	BTFSC	REG23,4
	INCF	REG25
L162	CALL	RCHAR
	CALL	S203
	DECFSZ	REG25
	GOTO	L162

	MOVLW	4	;process bytes 28-31
	MOVWF	REG25
	BTFSC	REG23,4
	DECF	REG25
	CLRF	REG26
L16B	BTFSC	REG23,4
	GOTO	L171
	MOVF	REG26,W
	CALL	S203
	MOVF	REG26,W
	CALL	S203
L171	CALL	RCHAR
	MOVWF	REG26
	XORWF	INDIR,W
	BTFSS	STATUS,ZBIT
	BSF	REG23,6
	BTFSS	REG23,4
	GOTO	L17D
	MOVF	REG26,W
	CALL	S203
	MOVF	REG26,W
	CALL	S203
	GOTO	L182
L17D	INCF	FSR
	MOVLW	0x1A
	SUBWF	FSR
	BCF	FSR,3
	ADDWF	FSR
L182	DECFSZ	REG25
	GOTO	L16B

	MOVLW	0x15	;process byte 32
	BTFSS	REG23,4
	MOVLW	0x40
	MOVWF	REG25
	CALL	RCHAR
	MOVWF	REG26
L18A	MOVF	REG26,W
	CALL	S203
	DECFSZ	REG25
	GOTO	L18A
	INCF	REG22
	BTFSC	STATUS,ZBIT
	BSF	REG22,7
	BTFSS	REG23,6
	CLRF	REG22
	BTFSS	REG23,4
	GOTO	L1A9
	BTFSC	REG23,6
	GOTO	L1A0
	BSF	REG23,5
	CLRW
	CALL	REPR	;read eeprom
	XORWF	REG27,W
	BTFSC	STATUS,ZBIT
	RETLW	0x00

	MOVF	REG27,W
	CALL	WEPR	;write eeprom
	RETLW	0x00

L1A0	BTFSC	REG23,5
	BCF	REG24,0
	INCF	REG27
	MOVLW	0x19
	SUBWF	REG27,W
	BTFSC	STATUS,CARRY
	CLRF	REG27
	CALL	S237	;key buf=FF00...00
	RETLW	0x00

L1A9	CALL	S1
	BTFSC	STATUS,ZBIT
	GOTO	L1B6
	MOVWF	REG26
	BTFSS	REG22,1
	GOTO	L1B6
	MOVLW	8
	XORWF	REG23
	BCF	REG23,2
	BTFSS	REG26,1
	GOTO	L1B6
	BTFSC	REG23,3
	BSF	REG23,2
L1B6	BTFSC	REG23,6
	GOTO	L231	;key buf=0100...00

	BTFSC	REG23,2
	GOTO	L235	;key buf=5F5F...5F

	BTFSC	REG0E,5
	BTFSC	REG10,7
	RETLW	0x00

	BTFSC	REG14,5
	GOTO	CLRBUF	;key buf=0000...00

	MOVF	REG12,W
	IORWF	REG13,W
	BTFSC	REG14,4
	IORLW	1
	BTFSC	STATUS,ZBIT
	GOTO	L231	;key buf=0100...00

	BTFSC	REG23,3
	RETLW	0x00

	CALL	S3	;W=FF
	BTFSC	REG14,3
	CALL	S2	;W=FF
	MOVWF	REG0C
	BTFSC	REG14,2
	SWAPF	REG0C
	BTFSC	REG14,1
	RRF	REG0C
	BTFSC	REG14,1
	RRF	REG0C
	BTFSC	REG14,0
	RRF	REG0C
	BTFSS	REG0C,0
	BSF	REG23,1
	BTFSS	REG0C,0
	GOTO	L235	;key buf=5F5F...5F
	RETLW	0x00

S1D8	CALL	S1	;W=01
	MOVWF	REG26
	MOVF	REG0F,W	;W=2nd byte
	ADDLW	0xD5
	BTFSC	STATUS,CARRY
	GOTO	L1EE	;if >2A
	BTFSS	REG26,0
	GOTO	L1F1
	BSF	REG23,4
	BTFSC	REG24,0
	GOTO	L1EC
	BCF	REG23,5
	BSF	REG24,0
	CLRW
	CALL	REPR	;read eeprom
	MOVWF	REG27
	MOVLW	0x19
	SUBWF	REG27,W
	BTFSC	STATUS,CARRY
	CLRF	REG27
L1EC	MOVF	REG27,W
	RETURN

L1EE	BCF	REG23,4
	ADDLW	0xF8
	BTFSS	STATUS,CARRY
L1F1	RETLW	0x60
	BTFSS	REG26,0
	GOTO	L1F6
	BTFSC	REG23,3
	GOTO	L1FA
L1F6	ADDLW	0xF8
	BTFSS	STATUS,CARRY
	RETLW	0x68
	RETLW	0x78

L1FA	BTFSS	REG26,0
	GOTO	L1F6
	ADDLW	0xF8
	BTFSS	STATUS,CARRY
	RETLW	0x00

	ADDLW	0xF8
	BTFSS	STATUS,CARRY
	RETLW	0x20
	RETLW	0x40

S203	MOVWF	REG0C
	XORWF	INDIR
	BTFSS	REG23,4
	GOTO	L210
	INCF	INDIR
	MOVF	INDIR,W
	ANDLW	0x0F
	ADDWF	REG27,W
	MOVWF	REG0C
	CALL	SCD
	ADDLW	0x2A
	MOVWF	REG0C
	GOTO	L21D

L210	SWAPF	INDIR,W
	ANDLW	0x0F
	ADDWF	REG27,W
	CALL	S320
	ADDLW	0x3D
	MOVWF	REG0D
	MOVF	INDIR,W
	ANDLW	0x0F
	ADDLW	0x10
	ADDWF	REG27,W
	CALL	S320
	ADDLW	0x3D
	ADDWF	REG0D

L21D	INCF	FSR
	MOVLW	0x1A
	SUBWF	FSR
	BCF	FSR,3
	ADDWF	FSR
	BTFSS	REG23,4
	GOTO	L228
	MOVF	REG0C,W
	XORWF	INDIR
	INCF	INDIR
	RETURN

L228	COMF	REG0D
	RLF	REG0D,W
	RLF	REG0D,W
	ADDWF	REG0C
	SWAPF	REG0C
	RLF	REG0C,W
	RLF	REG0C,W
	XORWF	INDIR
	RETLW	0x00

L231	MOVLW	1	;key buf=0100...00
	MOVWF	REG1A
	CLRW
	GOTO	L23D	;clr key buffer except byte 0

L235	MOVLW	0x5F
	GOTO	L23C	;set key buffer to 5f

S237	MOVLW	0xFF	;key buf=FF00...00
	MOVWF	REG1A
	CLRW
	GOTO	L23D	;clr key buffer except byte 0

;clear key buffer
CLRBUF	CLRW
L23C	MOVWF	REG1A
L23D	MOVWF	REG1B
	MOVWF	REG1C
	MOVWF	REG1D
	MOVWF	REG1E
	MOVWF	REG1F
	MOVWF	REG20
	MOVWF	REG21
	RETURN

;response to function 78 (xmit key)
F78	MOVLW	REG1A
	MOVWF	FSR
L247	MOVF	INDIR,W
	CALL	XMIT
	INCF	FSR
	DECFSZ	REG25
	GOTO	L247
	BSF	REG23,0
	RETLW	0x00

;response to function 76 (read 1 byte)
F76	BTFSS	REG23,2
	BSF	REG23,7
	BCF	REG23,2

;response to function 80 (read 1 byte)
F80	CALL	RCHAR
	DECFSZ	REG25
	GOTO	F80
	RETLW	0x00

;response to function 72 (read 16 bytes)
F72	CALL	RCHAR
	MOVWF	REG0C
	DECF	REG25
	BTFSC	REG0C,0
	BCF	REG23,0
	GOTO	F80

;response to function 7C (xmit 16 bytes cardnr)
F7C	MOVF	REG23,W
	GOTO	L25E

;response to function 7E & 82 (xmit 64 bytes 00)
F7E	CLRW
L25E	CALL	XMIT
	DECFSZ	REG25
	GOTO	F7E
	RETLW	0x00

;response to function 70 (xmit 6 bytes cardnr)
F70	MOVLW	0
L263	MOVWF	FSR
	CALL	S2A
	CALL	XMIT
	INCF	FSR,W
	DECFSZ	REG25
	GOTO	L263
	RETLW	0x00

;response to function 7A (xmit 25 bytes message)
F7A	MOVLW	MESS2-MESS0
	BTFSS	REG23,0
	MOVLW	MESS3-MESS0	;this show is complete
	BTFSC	REG23,2
	MOVLW	MESS5-MESS0	;not authorized
	BTFSC	REG23,1
	MOVLW	MESS4-MESS0	;this channel is blocked
	MOVF	REG22
	BTFSC	STATUS,ZBIT
	GOTO	L27D
	BTFSS	REG0E,5
	GOTO	L27D
	MOVF	REG22,W
	BTFSC	REG23,4
	ADDLW	0x0D
	SUBLW	0x0D
	MOVLW	MESS6-MESS0	;scanning wait
	BTFSS	STATUS,CARRY
	MOVLW	MESS7-MESS0	;decryption not possible
L27D	GOTO	L263

;read eeprom addr(W) into W
REPR	BSF	STATUS,RP0	;select bank 1
L27F	BTFSC	EECON1,1
	GOTO	L27F	;wait until write complete
	BCF	STATUS,RP0	;select bank 0
	MOVWF	EEADR	;store address
	BSF	STATUS,RP0	;select bank 1
	BSF	EECON1,0	;set read
	BCF	STATUS,RP0	;select bank 0
	MOVF	EEDATA,W	;read eeprom data
	RETURN

;write W to eeprom
WEPR	BSF	STATUS,RP0	;select bank 1
L289	BTFSC	EECON1,1
	GOTO	L289	;wait until write complete
	BCF	STATUS,RP0	;select bank 0
	MOVWF	EEDATA	;store data
	BSF	STATUS,RP0	;select bank 1
	BSF	EECON1,2	;enable write
	MOVLW	0x55
	MOVWF	EECON2
	MOVLW	0xAA
	MOVWF	EECON2
	BSF	EECON1,1	;start write
	BCF	EECON1,2	;disable write
	BCF	STATUS,RP0	;select bank 0
	RETLW	0x00

L297	BSF	STATUS,RP0	;select bank 1
	MOVLW	0xFF
	MOVWF	TRISA	;port=input
	MOVWF	TRISB
	MOVWF	OPTREG
	CLRF	EECON1
	BCF	STATUS,RP0	;select bank 0
	CLRF	INTCON
	SLEEP

;xmit data from W
XMIT	MOVWF	REG0C	;put char to xmit in REG0c
	CALL	GENPAR	;get parity in W
	MOVWF	REG29	;save parity
	BCF	Port_B,7	;data is low
	MOVLW	15	;retry cnt
	MOVWF	REG28

L2A6	MOVLW	4	;startbit
	MOVWF	REG0D
L2A8	NOP		;delay
	NOP
	MOVLW	0x17
L2AB	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2AB
	DECFSZ	REG0D
	GOTO	L2A8

	BSF	STATUS,RP0	;select bank 1
	BCF	Port_B,7	;RB7 is output
	NOP		;delay
	MOVLW	0x16
L2B4	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2B4

	MOVLW	9	;8bits+parity to xmit
	MOVWF	REG0D
	RRF	REG29,W	;get parity
L2BA	RLF	REG0C	;data to xmit
	BTFSS	STATUS,CARRY
	BSF	Port_B,7	;send 1
	BTFSC	STATUS,CARRY
	BCF	Port_B,7	;send 0
	NOP		;bit delay
	MOVLW	0x16
L2C1	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2C1

	DECFSZ	REG0D
	GOTO	L2BA	;loop until 9 bits send
	NOP
	NOP
	NOP
	BSF	Port_B,7	;RB7 is input
	BCF	STATUS,RP0	;select bank 0
	MOVLW	0x0C	;delay
L2CC	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2CC

	BTFSC	6,7	;retry if data=low
	RETLW	0x00	;else return

	DECFSZ	REG28	;sleep if max retry
	GOTO	L2A6	;else retry

	GOTO	L297

;receive char into W
RCHAR	MOVLW	15	;retry cnt
	MOVWF	REG28
L2D6	BTFSC	6,7
	GOTO	L2D6	;loop if RB7=high

	NOP		;delay 1.5 bit
	NOP
	MOVLW	0x22
L2DB	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2DB

	MOVLW	8	;8 bits to receive
	MOVWF	REG0D
L2E0	BCF	STATUS,CARRY	;preset to 0
	BTFSS	Port_B,7	;skip if 1 received
	BSF	STATUS,CARRY	;set to 1
	RLF	REG0C	;shift received bit in REG0C
	NOP		;delay 1 bit
	NOP
	MOVLW	0x16
L2E7	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2E7

	DECFSZ	REG0D
	GOTO	L2E0	;loop if not 8 bits received

	NOP
	CLRF	REG0D
	BTFSS	6,7
	BSF	REG0D,0
	CALL	GENPAR
	XORWF	REG0D
	MOVF	REG0C,W
	BTFSS	REG0D,0	;check if parity ok
	RETURN		;return if so

	MOVLW	0x0C	;delay
L2F6	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2F6

	BCF	Port_B,7	;data=low
	BSF	STATUS,RP0	;select bank 1
	BCF	Port_B,7	;RB7=output
	NOP		;delay
	MOVLW	0x24
L2FE	ADDLW	0xFF
	BTFSS	STATUS,ZBIT
	GOTO	L2FE

	BSF	Port_B,7	;xmit data high
	BCF	STATUS,RP0	;select bank 0
	DECFSZ	REG28	;sleep if max retry
	GOTO	L2D6	;else retry
	GOTO	L297

; even parity in W
GENPAR	CLRW
	CALL	S308
S308	SWAPF	REG0C
	BTFSC	REG0C,0
	ADDLW	1
	BTFSC	REG0C,1
	ADDLW	1
	BTFSC	REG0C,2
	ADDLW	1
	BTFSC	REG0C,3
	ADDLW	1
	RETURN

	ORG	0x320
S320	BSF	PCLATH,0
	BSF	PCLATH,1
	ADDWF	PC
	RETLW	0x9C
	RETLW	0x08
	RETLW	0xCB
	RETLW	0x9E
	RETLW	0x3F
	RETLW	0xBC
	RETLW	0x19
	RETLW	0xBA
	RETLW	0x1B
	RETLW	0xDB
	RETLW	0xE5
	RETLW	0x17
	RETLW	0xFB
	RETLW	0x90
	RETLW	0x00
	RETLW	0x57
	RETLW	0xCC
	RETLW	0xA9
	RETLW	0x51
	RETLW	0xD0
	RETLW	0x5D
	RETLW	0x49
	RETLW	0xBF
	RETLW	0xDF
	RETLW	0x63
	RETLW	0xDC
	RETLW	0x52
	RETLW	0x7F
	RETLW	0xC0
	RETLW	0x50
	RETLW	0x94
	RETLW	0x1A
	RETLW	0x19
	RETLW	0xB5
	RETLW	0x79
	RETLW	0x12
	RETLW	0x8C
	RETLW	0x80
	RETLW	0xED
	RETLW	0x76
	RETLW	0x60
	RETLW	0x44
	RETLW	0x20
	RETLW	0xA3
	RETLW	0xC8
	RETLW	0x78
	RETLW	0x7C
	RETLW	0xE9
	RETLW	0x2A
	RETLW	0xFF
	RETLW	0x28
	RETLW	0x63
	RETLW	0x7D
	RETLW	0xFC
	RETLW	0x8A
	RETLW	0x72
	RETLW	0xF6
	RETLW	0xE7
	RETLW	0x0A
	RETLW	0x69
	RETLW	0xE3
	RETLW	0xE1
	RETLW	0xD7
	RETLW	0x32
	RETLW	0x0B
	RETLW	0x5E
	RETLW	0x10
	RETLW	0x69
	RETLW	0xBC
	RETLW	0x9C
	RETLW	0xA2
	RETLW	0x31
	RETLW	0x6F
	RETLW	0x47
	RETLW	0xBD
	RETLW	0x4E
	RETLW	0xF1
	RETLW	0x79
	RETLW	0x39
	RETLW	0xDC
	RETLW	0x84
	RETLW	0x73
	RETLW	0x66
	RETLW	0x7E
	RETLW	0xCF
	RETLW	0xC0
	RETLW	0x33
	RETLW	0x35
	RETLW	0x8D
	RETLW	0x18
	RETLW	0xB2
	RETLW	0x63
	RETLW	0x42
	RETLW	0x82
	RETLW	0x1C
	RETLW	0x70
	RETLW	0x28
	RETLW	0xAA
	RETLW	0x34
	RETLW	0xDD
	RETLW	0x77
	RETLW	0x4B
	RETLW	0x9A
	RETLW	0x39
	RETLW	0xEB
	RETLW	0x93
	RETLW	0x0F
	RETLW	0x31
	RETLW	0x49
	RETLW	0x4F
	RETLW	0x8B
	RETLW	0x06
	RETLW	0x6C
	RETLW	0xAF
	RETLW	0x23
	RETLW	0x05
	RETLW	0xC8
	RETLW	0xB5
	RETLW	0x00
	RETLW	0xDF
	RETLW	0x2F
	RETLW	0x7F
	RETLW	0x72
	RETLW	0x86
	RETLW	0xEE
	RETLW	0x78
	RETLW	0x9F
	RETLW	0x53
	RETLW	0xBC
	RETLW	0xC8
	RETLW	0xAD
	RETLW	0x14
	RETLW	0x09
	RETLW	0x60
	RETLW	0xA5
	RETLW	0x23
	RETLW	0x33
	RETLW	0x15
	RETLW	0x2A
	RETLW	0xE9
	RETLW	0x24
	RETLW	0x0C
	RETLW	0x05
	RETLW	0xCC
	RETLW	0x13
	RETLW	0x5C
	RETLW	0x53
	RETLW	0x65
	RETLW	0xF9
	RETLW	0xD1
	RETLW	0xC0
	RETLW	0xFC
	END

