;file name : P2051BIOS.asm
	LLCHAR	?

MAXIND	EQU	17
TIME_OUT EQU	25	;receive time out 時間 : 25 * 22 msec = 550 msec

FLG_TIMEOUT 	REG	20H.0	;Time out flag
FLG_ERROR 	REG	20H.1	;PROGRAM ERROR

VS	REG	P3.1	; VS=1 RST=5V , VS=0 RST=12V
XINC	REG	P3.7

RBUFFER	EQU	30H
RB1	EQU	31H
RB2	EQU	32H
RB3	EQU	33H
RB4	EQU	34H
RB5	EQU	35H
RB6	EQU	36H
RB7	EQU	37H
RB8	EQU	38H
RB9	EQU	39H
RBA	EQU	3AH
RBB	EQU	3BH
RBC	EQU	3CH
RBD	EQU	3DH
RBE	EQU	3EH
RBF	EQU	3FH
RBG	EQU	40H

TBUFFER	EQU	41H
TB1	EQU	42H
TB2	EQU	43H
TB3	EQU	44H

TINDEX	EQU	45H
RINDEX	EQU	46H

TIME_OUT_COUNTER EQU	47H


	ORG	00H
	JMP	BEGIN

	ORG	03H	;/INT0	IE0
	RETI

	ORG	0BH
	JMP	TIME0

	ORG	23H
	JMP	COMM
;---------------------------------------------------------------------
BEGIN:
	MOV	SP,#60H
	MOV	A,#21H		;TIME0 MODE #1 ,Timer 1 MODE #2
	MOV	TMOD,A		;
	MOV	SCON,#50H	;設定 Serial Mode 1
	MOV	TH1,#FDH	;TH1=TL1 = 256 - (freq / (32 * 12 * BAUD))
	MOV	TL1,#FDH	;BAUD RATE = 9600 ; 使用振盪頻率:11.059 MHz
	SETB	TR1		;啟動 Timer1
	SETB	TR0		;啟動 Timer0
	MOV	PCON,#00H	;SMOD = 0 不使用倍頻
	MOV	IE,#92H		;允許 Serial port ,,TIMER0 中斷

	MOV	TINDEX,#TBUFFER
	MOV	RINDEX,#RBUFFER
;------------------------------------------------------------------------
START:
	MOV	P3,#FFH
	MOV	P1,#FFH
	

	MOV	R4,#32
	MOV	DPTR,#MSG1
	CALL	SEND_STRING

;--------------------------------------------------------
?10
	MOV	A,RINDEX				
	CJNE	A,#RBUFFER+17,?20
?20	JNC	?30		;
	JMP	?10
	
?30	MOV	RINDEX,#RBUFFER		; RINDEX 歸零
	MOV	A,RBUFFER

	CJNE	A,#'L',?40		; LINK TEST
	MOV	A,#'K'
	CALL	DELAY50MS
	CALL	SEND_CHAR
	JMP	?10

?40	CJNE	A,#'E',?50		;ERASE COMMAND
	CALL	DELAY50MS
	CALL	ERASE_FLASH
	JMP	?10

?50	CJNE	A,#'C',?60		;CHECK BLANK
	CALL	DELAY50MS
	CALL	CHECK_BLANK
	JMP	?10
	
?60	CJNE	A,#'R',?70		;READ FLASH
	CALL	DELAY50MS
	CALL	READ_FLASH
	JMP	?10

?70	CJNE	A,#'P',?80		;PROGRAMMING
	CALL	PROGRAMMING
	JMP	?10

?80	CJNE	A,#'U',?90		;PROGRAMMING LUCK BIT
	CALL	LUCK_BIT
	JMP	?10

?90	CJNE	A,#'V',?A0		;VERIFY -> SEND 32 BYTES
	CALL	VERIFY
	JMP	?10

?A0
	JMP	?10
;========================================================
VERIFY:			;THE SAME READ_FLASH BUT SEND 32 BYTES
	CLR	P3.3
	CLR	P3.4
	SETB	P3.5

	SETB	VS	;RST=5V
	SETB	P3.2	;PRG=1
	
	MOV	R4,#32
?20	MOV	A,P1

	CALL	SEND_CHAR

	CLR	XINC
	SETB	XINC

	DJNZ	R4,?20
	RET
;========================================================
LUCK_BIT:
	SETB	P3.2	;PRG=1
	SETB	P3.3
	SETB	P3.4

	MOV	A,RB1
	CJNE	A,#'1',?10	;LUCK BIT 1
	SETB	P3.5
	SJMP	?30

?10	CJNE	A,#'2',?50	;LUCK BIT 2
	CLR	P3.5

?30	CLR	VS	;RST=12V

	CALL	DELAY40US

	CLR	P3.2	;PRG=0
	CALL	DELAY50MS
	SETB	P3.2	;PRG=1

	CALL	DELAY40US
	SETB	VS	;RST=5V

	CALL	DELAY2MS

	RET

	MOV	A,#'K'
	CALL	SEND_CHAR

?50	MOV	A,#'N'
	CALL	SEND_CHAR
	RET
;========================================================
PROGRAMMING:
	CLR	P3.3
	SETB	P3.4
	SETB	P3.5
	SETB	P3.2	;PRG=1
	MOV	R0,#RB1
	MOV	R2,#0

	MOV	R4,#16

?10	CLR	VS	;RST=12V

	MOV	A,@R0
	MOV	P1,A

	CALL	DELAY40US

	CLR	P3.2	;PRG=0
	CALL	DELAY100US
	SETB	P3.2	;PRG=1

	CALL	DELAY40US

	SETB	VS	;RST=5V
	CALL	DELAY2MS
	
;	MOV	P1,#FFH
;	CLR	P3.4
;	MOV	A,P1
;	CALL	SEND_CHAR
;	SETB	P3.4

	
?30	CLR	XINC
	INC	R0
	SETB	XINC
	
	DJNZ	R4,?10

	CALL	SEND_CHAR
	
	RET
;========================================================
READ_FLASH:
	CLR	P3.3
	CLR	P3.4
	SETB	P3.5

	SETB	VS	;RST=5V
	SETB	P3.2	;PRG=1
	
	MOV	A,RB1
?1K	CJNE	A,#'A',?2KR
	MOV	R5,#4
	SJMP	?10

?2KR	CJNE	A,#'B',?4KR
	MOV	R5,#8
	SJMP	?10

?4KR	CJNE	A,#'C',?50
	MOV	R5,#16

?10	MOV	R4,#0
?20	MOV	A,P1

	CALL	SEND_CHAR

	
	CLR	XINC
	SETB	XINC


	DJNZ	R4,?20
	DJNZ	R5,?10
	RET

?50	MOV	A,#'N'
	CALL	SEND_CHAR
	RET
;========================================================
CHECK_BLANK:
	CLR	P3.3
	CLR	P3.4
	SETB	P3.5

	SETB	VS	;RST=5V
	SETB	P3.2	;PRG=1
	
	MOV	A,RB1
?1K	CJNE	A,#'A',?2K	
	MOV	R5,#4
	SJMP	?10

?2K	CJNE	A,#'B',?4K
	MOV	R5,#8
	SJMP	?10

?4K	CJNE	A,#'C',?50
	MOV	R5,#16


?10	MOV	R4,#0
?20	MOV	A,P1
	CJNE	A,#FFH,?50

	SETB	XINC
	CLR	XINC

	DJNZ	R4,?20
	DJNZ	R5,?10
	
	MOV	A,#'K'
	SJMP	?60

?50	MOV	A,#'N'

?60	CALL	SEND_CHAR
	RET
;========================================================
ERASE_FLASH:
	SETB	P3.3
	CLR	P3.4
	CLR	P3.5
		
	CLR	VS	;RST=12V

	CALL	DELAY40US

	CLR	P3.2	;PRG=0
	CALL	DELAY50MS
	SETB	P3.2	;PRG=1

	CALL	DELAY40US

	SETB	VS	;RST=5V

	MOV	A,#'K'
	CALL	SEND_CHAR
	
	RET
;========================================================
SEND_STRING:		;INPUT R4 CHAR NUMBER,DPTR
	PUSH	A
?5	CLR	A		;SEND STRING
	MOVC	A,@A+DPTR
	CALL	SEND_CHAR
	INC	DPTR
	DJNZ	R4,?5
	POP	A
	RET
;=======================================================
SEND_CHAR:		;INPUT A
	PUSH	IE
	MOV	IE,#0
	CLR	TR1

	SETB	P3.0		;STOP BIT
	MOV	B,#96/2-2
	DJNZ	B,$

	CLR	P3.0		;STRAT BIT
	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.0,?00
	SETB	P3.0
	JMP	?01
?00	CLR	P3.0
?01	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.1,?10
	SETB	P3.0
	JMP	?11
?10	CLR	P3.0
?11	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.2,?20
	SETB	P3.0
	JMP	?21
?20	CLR	P3.0
?21	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.3,?30
	SETB	P3.0
	JMP	?31
?30	CLR	P3.0
?31	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.4,?40
	SETB	P3.0
	JMP	?41
?40	CLR	P3.0
?41	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.5,?50
	SETB	P3.0
	JMP	?51
?50	CLR	P3.0
?51	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.6,?60
	SETB	P3.0
	JMP	?61
?60	CLR	P3.0
?61	MOV	B,#96/2-2
	DJNZ	B,$

	JNB	ACC.7,?70
	SETB	P3.0
	JMP	?71
?70	CLR	P3.0
?71	MOV	B,#96/2-2
	DJNZ	B,$

	SETB	P3.0		;STOP BIT
	MOV	B,#96/2-2
	DJNZ	B,$

	SETB	TR1
	POP	IE
	RET
;========================================================
COMM:	;Serial Communication interrupt
	PUSH	ACC
	PUSH	PSW
	PUSH	0
	JBC	TI,?Z0

;receive
?50R				;Receive

	MOV	TIME_OUT_COUNTER,#TIME_OUT	;
	CLR	FLG_TIMEOUT

	CLR	RI
	MOV	A,RINDEX				
	CJNE	A,#RBUFFER+17,?51
?51	JNC	?Z0		;若 RINDEX >= MAX_INDEX 則不再接收
	
	MOV	A,SBUF
	MOV	R0,RINDEX
	MOV	@R0,A
	INC	RINDEX

?Z0	POP	0
	POP	PSW
	POP	ACC
	RETI

;========================================================
TIME0:			;Timer0 interrupt 22 MSEC (11.059MHZ)
	PUSH	PSW
	PUSH	A

	MOV	TH0,#>(65535-20000)	;
	MOV	TL0,#<(65535-20000)	;
	SETB	TR0

	JB	FLG_TIMEOUT,?EXIT	;Time out 事件只發生一次

	MOV	A,TIME_OUT_COUNTER
	JNZ	?NOTIMEOUT
	
	MOV	RINDEX,#RBUFFER		; Time out -> RINDEX 歸零
	SETB	FLG_TIMEOUT

	SJMP	?EXIT	

?NOTIMEOUT
	DEC	TIME_OUT_COUNTER

?EXIT	POP	A
	POP	PSW
	RETI
;========================================================
DELAY50MS:
	PUSH	B
	PUSH	A

	MOV	B,#100
?10	MOV	A,#0
	DJNZ	A,$
	DJNZ	B,?10

	POP	A
	POP	B
	RET
;========================================================
DELAY2MS:
	PUSH	B
	PUSH	A

	MOV	B,#4
?10	MOV	A,#0
	DJNZ	A,$
	DJNZ	B,?10

	POP	A
	POP	B
	RET
;========================================================
DELAY40US:
	PUSH	A
	MOV	A,#20-4
	DJNZ	A,$
	POP	A
	RET
;========================================================
DELAY100US:
	PUSH	A
	MOV	A,#50-4
	DJNZ	A,$
	POP	A
	RET
;========================================================
MSG1	DB	"Finetech 0000000000000000                 "

	END