;ヒューズビット　上位：C9、下位：Ｅ０
;**** includes **** 
.include "m8def.inc"

;*****************************
;* レジスタ変数　設定 *
;*****************************

.def	temp1	= r20
.def	temp2	= r21
.def	temp3	= r22
.def	temp4	= r23
.def	lcd_data= r24

;*****************************
;*　 ビット　設定　　*
;*****************************

;**  PORTB  ***



;**  PORTD  **
;.equ		= 0
.equ	lcd_rs	= 1
.equ	lcd_rw	= 2
.equ	lcd_enb	= 3
.equ	lcd_db4 = 4
.equ	lcd_db5 = 5
.equ	lcd_db6 = 6
.equ	lcd_db7 = 7


		
;*********************
;* 割込みベクター *
;*********************

.cseg

	rjmp	start		; Reset Handle

.org 0x13


;*********************
;* メイン プログラム *
;*********************
start:

	ldi	temp1,low(RAMEND)
	out	SPL,temp1
	ldi	temp1,high(RAMEND)
	out	SPH,temp1	;init Stack Pointer 
	

	ldi	temp1,0xff
	out	DDRD,temp1	; pd0~7 out port
	ldi	temp1,0x00	; pd0~7 clear	
	out	PORTD,temp1	


; LCD - Initialize LCD controller

lcd_init:
	ldi	temp1,15	; wait for 15+ms
	rcall	wait_ms		; /
	rcall	lcd_int		; /
	ldi	temp1,5		; Wait for 4.1ms+
	rcall	wait_ms		; /
	rcall	lcd_int		; /
	ldi	temp1,100 	;wait for 100us+
	rcall	wait_us		; /
	rcall	lcd_int		; /

	ldi	lcd_data,0x20
	rcall	lcd_cmd
	ldi	temp1,100 	;wait for 100us+
	rcall	wait_us		; /
	ldi	lcd_data,0x28	; Data=4bit, Line=2, Font=5x7
	rcall	lcd_cmd		; /
	ldi	lcd_data,0x0c	; Display=ON, Cursor=OFF, Blink=OFF
	rcall	lcd_cmd		; /
	ldi	lcd_data,6	; Increment, No shift
	rcall	lcd_cmd		; /
	ldi	lcd_data,1	; clear ,homepos
	rcall	lcd_cmd

	ldi	lcd_data,0x80
 	rcall	lcd_cmd


	ldi	r16,33
lt:
	mov	lcd_data,r16
	rcall	lcd_dsp
	ldi	temp1,150
	rcall	wait_ms
	ldi	temp1,150
	rcall	wait_ms
	inc	r16
	cpi	r16,49
	brne	lt
	
	ldi	lcd_data,0xc0
 	rcall	lcd_cmd
lt1:
	mov	lcd_data,r16
	rcall	lcd_dsp
	ldi	temp1,150
	rcall	wait_ms
	ldi	temp1,150
	rcall	wait_ms
	inc	r16
	cpi	r16,65
	brne	lt1
main:

	
	rjmp	main
TIM1_OVF:
	reti	
	
;****************************

;-----------------------------------------------;
; LCD - Send a data/cmd into LCD
	;PORTD   7   6   5   4   3   2    1   0
	;write   <-data(H/L)->  enb r/w  rs   0
	;read   BF / address                  -
lcd_int:	; Internal reset
	ldi	lcd_data,0x30	; RS = "L",RW = "L",E = "L",data='0011'
	out	PORTD,lcd_data	
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTD,lcd_enb	; E = "L"
	ret

lcd_dsp:
	rcall	lcd_bfch
	ldi	temp3,2		; RS = "H",RW = "L",E = "L",data='xxxx'
	rjmp	lcd_cmd1
lcd_cmd:
	rcall	lcd_bfch
	ldi	temp3,0		; RS = "L",RW = "L",E = "L",data='xxxx'
lcd_cmd1:
	mov	temp2,lcd_data
	swap	temp2
	andi	temp2,0xf0	;data_L save
	andi	lcd_data,0xf0   ;data_H set
	or	lcd_data,temp3
	out	PORTD,lcd_data	; PORTD = data_H,RS,RW
	sbi	PORTD,lcd_enb	; E = "H"
	mov	lcd_data,temp2	; 
	or	lcd_data,temp3	;data_L set
	nop						
	cbi	PORTD,lcd_enb	; E = "L"
	nop			; I/O delay				
	out	PORTD,lcd_data	; PORTD = data_L,RS,RW
					
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	nop			; I/O delay
	cbi	PORTD,lcd_enb	; E = "L"
	ret

lcd_bfch:
	cbi	DDRD,lcd_db7	; lcd_db7 = INPUT
	sbi	PORTD,lcd_db7	; pullup
	sbi	PORTD,lcd_rw	; RW = "H"
	cbi	PORTD,lcd_rs	; RS = "L"
lcd_bfch1:
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp1,PIND
	cbi	PORTD,lcd_enb	; E = "L"
	nop
	nop
	sbi	PORTD,lcd_enb	; E = "H"
	nop			; I/O delay
	nop			; I/O delay
	in	temp2,PIND
	cbi	PORTD,lcd_enb	; E = "L"

	andi	temp1,0x80	; Wait until busy flag becomes zero.
	brne	lcd_bfch1
	sbi	DDRD,lcd_db7	; lcd_db7 = OUTPUT
	cbi	PORTD,lcd_db7	; clear
	ret

wait_us:	;base 12.8MHz	
				;temp1　us (13clocks)
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks
	nop			; 1clocks		
	dec	temp1		; 1clocks
	brne	wait_us		; 2clocks
	ret			; 

wait_ms:
				;temp1　ms
	ldi	temp2,200	;64*200=12800clocks

wait_ms_01:
	ldi	temp3,15	;1clocks  4*(15+1)=64
wait_ms_02:
	nop			; 1clocks
	dec	temp3		; 1clocks
	brne	wait_ms_02	; 2clocks

	dec	temp2		; 1clocks
	brne	wait_ms_01	; 2clocks

	dec	temp1		; 1clocks	
	brne	wait_ms		; 2clocks
	ret
