;  ------RC5 Program Decoder------
;  RC5 program decoder is interrupt holder.
;  Input - bit SER (interrupt line), low active level.
;  Out - byte R37 (register R7 in bank 3),
;                  D0-D5 - command bits
;                  D6 - control bit of local keyboard
;                 (D6 does not change)
;                  D7 - control bit RC
;  Uses register bank 3
;  Delay values are selecting by defining CLK_KHZ (4000..24000KHz)
;  Main program must include:
;  SYS .EQU 000H
;  SER .EQU INT0 (or INT1)
;      .ORG 0003H ;INT0 vector (or 0013H ;INT1 vector)
;      LJMP RC5
;      INT0 (or INT1) enable, fall activating
;  RCTAB .DB ... (64 byte recoding table)

RC5_DF	.EQU B.0		;data flag
RC5_PF	.EQU B.1		;period flag
RC5_N	=(2*(CLK_KHZ/188)+1)/2
RC5_N1	=(2*(CLK_KHZ/249)+1)/2
RC5_N2	=(2*(CLK_KHZ/382)+1)/2
RC5_NT	=(2*(CLK_KHZ/135)+1)/2

RC5:      PUSH PSW		;RC5-code program decoding
	PUSH ACC
	PUSH B
	SETB RS0
	SETB RS1		;bank 3
	MOV R6,DPH
	MOV R5,DPL

	MOV B,#2
	MOV R2,#2		;system byte init for 7 received bits
	MOV R3,#4		;command byte init for 6 received bits
	MOV R0,#R32	;R32 address load

	MOV R1,#RC5_N
WLOW:	JB SER,WHIGH
	MOV R4,#16
	DJNZ R4,$
	DJNZ R1,WLOW	;wait up to 2362uS for SER = 1
	SJMP NORC5	;jump if time is over

WHIGH:	MOV R1,#RC5_N
SAMPLE:	MOV R4,#8
	DJNZ R4,$
SAM1:	MOV R4,#3
	DJNZ R4,$
SAM2:	MOV R4,#2
	DJNZ R4,$
SAM3:	MOV C,SER
	MOV ACC.0,C
	XRL A,B
	JNB ACC.0,TRANS
	DJNZ R1,SAMPLE	;sample SER up to 2362uS
	SJMP NORC5	;jump if time is over

TRANS:	CPL RC5_DF	;transition detected
	MOV A,R1
	ADD A,#-RC5_N1
	JC NORC5		;jump if <577.5uS
	MOV A,R1
	ADD A,#-RC5_N2
	JC TRANS1
	JB RC5_PF,NORC5	;jump if >1200uS
	SJMP STDATA
TRANS1:	CPL RC5_PF
	MOV R1,#RC5_N
	JB RC5_PF,SAM1
STDATA:	MOV C,RC5_DF
	MOV A,@R0
	RLC A		;save data bit
	MOV @R0,A
	MOV R1,#RC5_N
	JNC SAM2
	INC R0		;system done, begin command
	MOV A,R0
	MOV R1,#RC5_N
	JNB ACC.2,SAM3

	MOV R1,#RC5_N
WLW:	JB SER,TRM
	MOV R4,#16
	DJNZ R4,$
	DJNZ R1,WLW	;wait up to 2362uS for SER = 1
	SJMP NORC5	;jump if time is over

TRM:	MOV R1,#RC5_NT
TERM:	JNB SER,NORC5
	MOV R4,#16
	DJNZ R4,$
	DJNZ R1,TERM

	MOV A,R2		;system nom. and control bit in R2
	ANL A,#1FH
	CJNE A,#SYS,NORC5	;system number check

	MOV DPTR,#RCTAB	;table address load
	MOV A,R3		;command code load
	MOVC A,@A+DPTR	;recoding
	MOV R3,A		;new code store

	MOV A,R2		;system nom. and control bit in R2
	ANL A,#20H	;control bit separating
	RL A
	RL A		;D7-control bit RC
	ORL A,R3		;combine command code and control bit
	MOV R3,A		;store

	MOV A,R7
	ANL A,#40H	;save D6-control bit of local keyboard
	ORL A,R3		;combine command code and D6,D7
	MOV R7,A		;store command data

NORC5:
#IF SER=INT0		;interrupt flag clear
	CLR IE0
#ELSE
	CLR IE1
#ENDIF
	MOV DPL,R5
	MOV DPH,R6
	POP B
	POP ACC
	POP PSW
	RETI
