	;; Some definitions
	
		.equ	DPS		,0x86
		.equ	CKCON		,0x8e
		.equ    OUT2BUF         ,0x7dc0
		.equ    PORTBCFG        ,0x7f94
		.equ    OUTB            ,0x7f97
		.equ    PINSB           ,0x7f9A
		.equ    OUT2CS          ,0x7fc8
		.equ    OUT2BC          ,0x7fc9
		.equ    OEB             ,0x7f9d


	;; Interrupt vectors

		.org	0x00
		ljmp	start

		.org	0x0b
		ljmp	timer0_int

		.org	0x1b
		ljmp	timer1_int
	
	;; Internal memory allocation
	
		.org	0x60	; keep 0x60 -- 0x7f
stack:		.skip	0x20	; for stack area
		.org	0x80	; keep 0x80 -- 0x9f
data:		.skip	0x20	; for data area


	;; Initialize
	
		.org	0x200

start:		mov	SP,#stack-1
		mov	R1,#data
		mov	R2,#0b10000000
		mov	TMOD,#0b00010001
		mov	TCON,#0b01010000
		mov	a,CKCON
		setb	acc.3
		clr	acc.4
		mov	CKCON,a
		setb	EA
		setb	IE.1

		mov	a,#0x00
		mov	dptr,#PORTBCFG
		movx	@dptr,a

		mov	a,#0x00
		mov	dptr,#OUTB
		movx	@dptr,a

		mov	a,#0xff
		mov	dptr,#OEB
		movx	@dptr,a

	
		mov	a,#0xdc
		mov	R0,#data+1
		mov	@R0,a
		mov	a,#0xff
	
		mov	R0,#data+3
		mov	@R0,a
		mov	R0,#data+5
		mov	@R0,a
		mov	R0,#data+7
		mov	@R0,a
		mov	R0,#data+9
		mov	@R0,a
		mov	R0,#data+11
		mov	@R0,a
		mov	R0,#data+13
		mov	@R0,a
		mov	R0,#data+15
		mov	@R0,a

		mov	a,#0x80
		mov	R0,#data+17
		mov	@R0,a

		mov	a,#0xd7
		mov	R0,#data+0
		mov	@R0,a
	
		mov	a,#0xff
		mov	R0,#data+2
		mov	@R0,a
		mov	R0,#data+4
		mov	@R0,a
		mov	R0,#data+6
		mov	@R0,a
		mov	R0,#data+8
		mov	@R0,a
		mov	R0,#data+10
		mov	@R0,a
		mov	R0,#data+12
		mov	@R0,a
		mov	R0,#data+14
		mov	@R0,a

		mov	a,#0x00
		mov	R0,#data+16
		mov	@R0,a
	
		mov	TH0,#0xff
		mov	TL0,#0xf0

		mov	TH1,#0xff
		mov	TL1,#0xff

		mov	R6,#0
		mov	B,#0
	
	;; main routine
	
loop:		mov	dptr,#OUT2CS
		movx	a,@dptr
		jb	acc.1,loop	; busy-keep checking

service_OUT2:	mov	dptr,#OUT2BC	; R6 is counter 
		movx	a,@dptr		; for number of recieved data
		mov	R6,a
		mov	dptr,#OUT2BUF

letter:		movx	a,@dptr
		jb	acc.7,first_byte ; if 7th bit is 1,it is 1st byte
		jb	B.0,second_byte	 ; if not ,and if last data is 1st byte, it is 2nd byte.
		jb	B.1,third_byte   ; if not ,and if last data if 2nd byte, it is 3rd byte.
		mov	B,#0             ;  or, it should be neglected.
		sjmp	next_data

first_byte:	mov	B,#1	; mount 1st byte at R3
		mov	R3,a
		sjmp	next_data
	
second_byte:	mov	R4,a	; mount 2nd byte at R4
		mov	B,#2
		sjmp	next_data

third_byte:	mov	R5,a	; mount 3rd byte at R5
		mov	a,R4	
		anl	a,#0b00000001
		rr	a	
		orl	a,R5	
		cpl	a	
		mov	R5,a	; R4.1 and R5.[0-6] is low side byte of width of pulse.

		mov	a,R4
		clr	acc.0
		rr	a
		mov	R4,a
		mov	a,R3
		rr	a
		rr	a
		anl	a,#0b11000000
		orl	a,R4
		cpl	a
		mov	R4,a	; R4.[1-6] and R5.[0,1] is high side byte of width of pulse.

		mov	a,R3
		rr	a
		anl	a,#0b00011110
		add	a,#data
		mov	R0,a
		mov	a,R5

		clr	EA
		mov	@R0,a
		inc	R0
		mov	a,R4
		mov	@R0,a
		setb	EA
	
		mov	B,#0
		
next_data:	inc	dptr
		djnz	R6,letter

		mov	dptr,#OUT2BC	; load anything to byte count to re-arm
 		mov	a,#1		; any value
 		movx	@dptr,a		
  		sjmp	loop	

	;; Timer0,1 Interrupt

timer1_int:	push	ACC

		mov	a,R1
		jz	wait_end

		clr	TR1
		mov	a,#0x00
		mov	TL1,a
		mov	a,#0xff
		mov	TH1,a
		setb	TR1
		mov	R1,#0
	
		pop	ACC
		reti

wait_end:	mov	R1,#data+16
		clr	TR1
		mov	a,@R1
		mov	TL1,a
		inc	R1
		mov	a,@R1
		mov	TH1,a
		setb	TR1

		clr	IE.3
		setb	IE.1

		mov	R1,#data
		mov	R2,#0b10000000

		pop	ACC
	
timer0_int:	push	ACC
		mov	DPS,#1

		clr	a
		mov	dptr,#OUTB
		movx	@dptr,a
	
set_pulse:	mov	a,R1
		subb	a,#data+15
		jz	wait
		sjmp	regular_task
	
wait:		mov	R2,#0

		clr	IE.1
		setb	IE.3
		sjmp	t0int_end
		
regular_task:	mov	a,R2
		rl	a
		mov	R2,a
	
		clr	TR0
		mov	a,@R1
		mov	TL0,a
		inc	R1
		mov	a,@R1
		mov	TH0,a
	
		inc	R1
		cpl	a
		jz	set_pulse
		setb	TR0	

t0int_end:	mov	a,R2
		mov	dptr,#OUTB
		movx	@dptr,a

		mov	DPS,#0
		pop	ACC
		reti
	
		.end
	