;-------------------------------------------------------------------------------
;
;                          LCD COMMANDS
;-------------------------------------------------------------------------------
;              LCD PINS
;   RS   R/W  DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0   Function  (Time)
;-------------------------------------------------------------------------------
;    0    0   0   0   0   0   0   0   0   1     Display clear        (1,6ms)
;    0    0   0   0   0   0   0   0   1   x     Display, cursor home (1,6ms)
;    0    0   0   0   0   0   0   1  I/D  S     Entry mode set       (40us)
;    0    0   0   0   0   0   1   D   C   B     Display ON/OFF       (40us)
;    0    0   0   0   0   1  S/C R/L  x   x     Display/Cursor shift (40us)
;    0    0   0   0   1   DL  N   x   x   x     Function set         (40us)
;    0    0   0   1   ------ CG ADDR ------     CG RAM address set   (40us)
;    0    0   1   ------- DD ADDR ---------     DD RAM address set   (40us)
;    1    0   --------- Write data --------     CG/DD RAM data write (40us)
;-------------------------------------------------------------------------------
;    0    1   BF  ----- Address counter ---     Busy flag/Addr cnt read (0)
;    1    1   ---------- Read data --------     CG/DD RAM data read  (40us)
;-------------------------------------------------------------------------------
;
;		I/D=1 Increment, I/D=0 Decrement
;		S=1 display shift, S=0 display fix
;    	D=1 display on, D=0 display off
;    	C=1 cursor on, C=0 cursor off
;    	B=1 Character Blink, B=0 No Blink
;    	S/C=1 display step, S/C=0 Cursor step
;    	R/L=1 shift Right, R/L=0 Shift left
;    	DL=1 8 bit, DL=0 4 bit interface
;    	N=1 2line display, N=0 1 line display
;    	CG ADDR : Character  generator RAM addr.
;    	DD ADDR : Display Data RAM Addr.
;
;-------------------------------------------------------------------------------
	
		List	p=16F627				;Processor type
		include	"P16F627.INC"			;Regs def.


		__config _CP_OFF &_PWRTE_ON &_WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _MCLRE_OFF  

;-------------------------------------------------------------------------------
	cblock 0x20      						;variables
		it_cnt								;1 sec counter
		second								;second counter
		stat									;semaphore status counter 
		l_cnt									;loop counter
		blink									;1 sec blink
		Port_b								;Shadow of PORTB
		Pointer
		flag
		Timer1
		Timer2
		Timer3
		temp
		count
		Displ
		W_TEMP								;W temp while It
		STATUS_TEMP							;Status temp while It

	endc
;-------------------------------------------------------------------------------

#define Led blink,0
#define max flag,0
#define	E	PORTA,0x07	; Display "E"
#define	RS	PORTA,0x06	; Display "RS"
;-------------------------------------------------------------------------------                    

				org	0x00				;Reset vector
				goto	Init
				org	0x04				;interrupt vector
				goto	Interrupt

;-------------------------------------------------------------------------------
Table			addwf	PCL,F			;Jmp addr + w
				retlw	b'01001000'		;RygGyr
				retlw	b'01001000'		;RygGyr
				retlw	b'01101000'		;RYgGyr
				retlw	b'00010010'		;ryGgyR
				retlw	b'00010010'		;ryGgyR
				retlw	b'00010110'		;ryGgYR
;-------------------------------------------------------------------------------
LCD_Table1		addwf	PCL,1
				dt	"Cycle ",0			;
LCD_Table2		addwf	PCL,1
				dt	"State ",0			;
;-------------------------------------------------------------------------------
				
Interrupt   	
PUSH 			movwf 	W_TEMP 			; Copy W to TEMP register,
				swapf 	STATUS, W 		; Swap status to be saved into W
				movwf 	STATUS_TEMP 	; Save status to STATUS_TEMP register
				btfss	INTCON,INTF	   	;INT it?
				goto	TMR0_it			;No -> tmr0 It
				bcf		INTCON,INTF		;Clear INTF
TMR0_it			btfss	INTCON,T0IF		;TMR0 It?
				goto	Done_it			;No -> done
				bcf		INTCON,T0IF	 	;Clear flag TMR0
				movlw 	~.39
           		movwf 	TMR0      		;init TMR0 w. 39 for 10 mS interrupt 
				decfsz 	it_cnt,F		;Decrement it_cnt
				goto	Done_it			;
				movlw	.100			;
				movwf	it_cnt	 		;init it_cnt
				incf	second,F			;
				movlw	0xFF			;
				xorwf	blink,f			;
				movlw	.10				;
				subwf	second,w		;
				bnz		Done_it			;
				clrf	second			;
				incf	stat,F			;
				movlw	.6				;
				subwf	stat,w			;
				bnz		Done_it			;
				clrf	stat			;
				movlw	.4				;
				subwf	l_cnt,w			;
				bnz		loop_out		;
				incf	l_cnt,F			;
loop_out		bsf		max				;		
				
Done_it			
POP 			swapf 	STATUS_TEMP, W 	; Swap nibbles in STATUS_TEMP register
										; and place result into W
				movwf 	STATUS 			; Move W into STATUS register
										; (sets bank to original state)
				swapf 	W_TEMP, F 		; Swap nibbles in W_TEMP and place result in W_TEMP
				swapf 	W_TEMP, W 		; Swap nibbles in W_TEMP and place result into W				
				retfie					;Return to main loop
;-------------------------------------------------------------------------------
		
Init	       	movlw	0x07			;
				movwf	CMCON			;comparators off
				clrf 	PORTA			;Clear PORTA
				clrf 	PORTB			;Clear PORTB
				bsf		STATUS,RP0		;Bank 1
				movlw	b'00110000'
				movwf	TRISA			;RA0-RA3, RA6-RA7 OUT, RA4-RA5 Input
				movlw	b'00000001'
				movwf	TRISB			;RB7-RB1 OUT, RB0/INT in
				movlw	b'00000111'
				movwf	OPTION_REG		;Prescaler  256 for TMR0, 
										;RB0/INT falling edge
				bcf		STATUS,RP0		;Bank 0		                                                                         

				clrf	second			;
				clrf	stat			;
				clrf	blink			;
				clrf	flag			;
;-------------------------------------------------------------------------------
; LCD Init
;
				movlw	10						; 10 ms
				call	Del						; LCD Powerup Wait
				movlw   0x28              		; 28h, 4 bit interface set
		        call    Write_c
				movlw	10						; 10 ms
		        call    Del						; Busy flag Wait
		        movlw   0x28
		        call    Write_c
		        movlw   0x06              		; 06h, Entry mode set: increment
		        call    Write_c
		        movlw   0x0C              		; 0dh, Display on, cursor/blink off
		        call    Write_c
		        movlw   0x10              		; 10h, Display/cursor shift: cursor
		        call    Write_c
		
				movlw	2						; 2 ms delay
		        call    Del						; Busy flag Wait
;				goto	ddone
				movlw	b'01000000'				; CG Address =0
		        call    Write_c
				movlw	0x28
				movwf	count
				clrf	temp
ddone   		movlw   0x01               		; 01h, Display clear
        		call    Write_c
;-------------------------------------------------------------------------------
; Data to LCD
;
		        movlw   0x80            		; LCD Addr = 0 (+128), First LCD Line
		        call    Write_c
				clrf	Pointer
Start1			movf	Pointer,0
				call	LCD_Table1				; Get Character
				movwf	Displ
				tstf	Displ
		 		bz		st2
				movfw	Displ
		        call    Write					; Put to LCD
				incf	Pointer,1				; Pointer to Next Char.
				goto	Start1					; No, Jmp Start1
				movlw 	~.39
           		movwf 	TMR0      		;init TMR0 w. 34 for 10 mS interrupt (39 for 4MHz Xtal)
				movlw	.100
				movwf	it_cnt	 		;Init IT Counter
				movlw	b'10110000'
				movwf	INTCON			;Enable  RB0/INT , TMR0, GIE
;-------------------------------------------------------------------------------
Loop			nop
				movfw	PORTB			;Read PORTB
				andlw	b'10000000'		;Mask RB7
				movwf	Port_b			;Save to mirror
				movfw	stat			
				call	Table			;Read actual Outputs
				andlw	b'01111110'		;Mask active Bits
				iorwf	Port_b,w		;
				movwf	PORTB			;
				goto 	Loop

;-------------------------------------------------------------------------------
st2
        movlw   0xC0             		; LCD Addr = 40h (+128), 2nd. Line
        call    Write_c
		clrf	Pointer
Start2	movf	Pointer,0
		call	LCD_Table2
		movwf	Displ
		tstf	Displ
;		bz	read_tc
		movfw	Displ
        call    Write
		incf	Pointer,1
		goto	Start2
;-------------------------------------------------------------------------------
; LCD 4 bit Write Step by Step:
; -----------------
;   1/   RS, R/W set
;   2/   Data High Nible Out
;   3/   E=1
;   4/   Delay (100us)
;   5/   E=0
;   2/   Data Low Nible Out
;   3/   E=1
;   4/   Delay (100us)
;   5/   E=0
;
Write_c	bcf		RS
Write   movwf	Displ
		movlw	0xf0
		andwf	PORTA,f
		swapf	Displ,w
		andlw	0x0f
		iorwf   PORTA,f
		bsf     E
		nop
        bcf     E
		movlw	0xf0
		andwf	PORTA,f
		movfw	Displ
		andlw	0x0f
		iorwf   PORTA,f
		bsf     E
		nop
        bcf     E
        call    Del100					; Busy flag Wait
		bsf		RS
        return

;-------------------------------------------------------------------------------
Del100  movlw   29						; 100us Delay
        movwf   Timer1
Del1	decfsz  Timer1,f
        goto    Del1
        return
;-------------------------------------------------------------------------------
Del1m   clrf    Timer1					; 1ms Delay
        movlw	10
		movwf   Timer2
Del21   call	Del100
        decfsz  Timer2,f
        goto    Del21
        return
;-------------------------------------------------------------------------------
Del		movwf	Timer3					; Delay = w x 1ms
Delr	call	Del1m
		decfsz	Timer3,f
		goto	Delr
		return
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------


;-------------------------------------------------------------------------------
				end					

