; basic configuration

;
        Title "lcd1 for ap0201."
;
        list P = 16F877
;
        include "p16f877.inc"  ; use definition file for 16F877
;
;	__CONFIG b'11111101111001' 



;
; memory - counters and max timing values in memory + rot value list
        CBLOCK 0x20   ; RAM starts at address 20h
var1
var2
count1
count2
count3
count4
slcnt
slflag
datal
datah
addrl
addrh
adchi
adclo
data1
address
	ENDC
indf	equ 0x00


	ORG 0x0000 ;reset vector
	clrf 0x3 ;zero status
	movlw 0x00 ;high byte of long jump
	movwf 0xA ;zero PCLATH
	goto start

start   movlw b'00000000'       ; all port pins = low
        movwf PORTA
        movlw b'00000000'
        movwf PORTC
        movlw b'00000000'
        movwf PORTD
        movlw b'00000000'
        movwf PORTE
	bcf STATUS,RP1
        bsf STATUS,RP0  ; set RAM Page 1 for TRIS registers

; INITIALISE PORTS
; binary used to see individual pin IO status

        movlw b'11101111'       ; IO pins
        movwf TRISA
        movlw b'00000000'
        movwf TRISB
        movlw b'00000000'
        movwf TRISC	; ???? serial?
        movlw b'00000000' ;in and out
        movwf TRISD
        movlw b'00000000'
        movwf TRISE
        movlw b'1000010'       ; analog pins
        movwf ADCON1

        bcf STATUS,RP0  ; back to RAM page 0

	movlw 0x00
	movwf addrl
	movwf addrh	
	movlw 0x10
	movwf count3

;deal with charging/sleep stuff

      movlw 0xff ; sleepcount
      movwf slcnt

;if below 3.9v (?) RA0 sleep
    call adcget
    ; if adc result less than 3.9v sleep
    btfsc adchi,1
    btfss adchi,0
    call schlaf
    
;lcd test hello
     call blanks
     call del_5
     call initlcd	
loop call self	;self display code and loop here
     call disp16
     movlw 0x10
     movwf count4
loop1	    call testsleep
	    call del_5
	    decfsz count4,f 
     goto loop1
     goto loop

testsleep call testsleep1
	  btfss slflag,0
	  goto rstsleep
	  decfsz slcnt,f
	  return
	  call schlaf
rstsleep  movlw 0xff
	  movwf slcnt
	  return

testsleep1	 bcf slflag,0
	  call adcget
	  btfss adchi,1
	  bsf slflag,0
	  btfsc adchi,0
	  return
	  btfsc adclo,7
	  return
	  bsf slflag,0
	  return

adcget	  bcf STATUS,C
	  movlw b'10000001'
	  movwf ADCON0
	  clrf delay
wait1	  decfsz delay,f
	  goto wait1
sample	  bcf PIR1,ADIF
	  bsf ADCON0,GO
wait2	  decfsz delay,f
	  goto wait2
wait3	  btfsc ADCON0,GO
	  goto wait3
getval	  movf ADRESH,w
	  movwf adchi
	  bcf STATUS,RP1
	  bsf STATUS,RP1
	  movf ADRESL,w
	  bcf STATUS,RP0
	  movwf adclo
	  return

initlcd	
	bcf PORTE,1
	bcf PORTB,0	;ale low 
	bcf PORTE,2	; en low
	bcf PORTE,0	;rs low for control
	call del_125
	movlw 0x38
	movwf PORTD
	call pulse
	movlw 0x0c
	movwf PORTD
	call pulse
	movlw 0x06
	movwf PORTD
	call pulse
	call del_5
	return

del_125	movlw 0x2a
	movwf count1
repeat	decfsz count1,f
	goto repeat
	return

del_5	movlw 0x29
	movwf count2
delay	call del_125
	decfsz count2,f
	goto delay
	return

pulse	bsf PORTE,2
	nop
	bcf PORTE,2
	call del_125
	return

blanks	movlw 0x10
	movwf count1
	movlw 0x30
	movwf FSR
	movlw 0x20
store	movwf indf
	decfsz count1,f
	goto incfsr
	return
incfsr	incf FSR,f
	goto store

self	; loop through writing 16 bytes to 0x30 +
	movlw 0x08
	movwf count1
	movlw 0x30
	movwf FSR
store2		movf addrl,w
	bsf STATUS,RP1
	bcf STATUS,RP0
	movwf EEADR
	movlw 0x00
	movwf EEADRH
	bsf STATUS,RP0
	bsf EECON1,EEPGD
	bsf EECON1,RD
	nop
	nop
	bcf STATUS,RP0
	movf EEDATA,w
	bcf STATUS,RP1
	movwf datal
	bsf STATUS,RP1
	movf EEDATH,w
	bcf STATUS,RP1
	movwf datah

	;test nv writing
	movlw 0x00
	movwf address
	call pgwr
	movf datal,w
	movwf data1	
	call nvwr

	;clear data bus for testing
	movlw 0x00
	movwf PORTD
	movwf data1

	call pgwr
	call nvrd
	movf data1,w
	movwf indf
	incf FSR,f
;	movf datah,w
	movlw 0x20
	movwf indf
	incf FSR,f
	incf addrl,f
	decfsz count1,f
	goto store2
	decfsz count3,f
	return
reset1	movlw 0x00
	movwf addrl
	movlw 0x10
	movwf count3
	return

disp16	
	bcf PORTE,1
	bcf PORTB,0	;ale low 
	bcf PORTE,2
	bcf PORTE,0
	movlw 0x80
	movwf PORTD
	call pulse
	bsf PORTE,0
	call del_125
	movlw 0x30
	movwf FSR
getchar	movf 0x00,w
	movwf PORTD
	call pulse
	movlw 0x37
	subwf FSR,w
	btfsc STATUS,Z
	goto half
	movlw 0x3f
	subwf FSR,w
	btfsc STATUS,Z
	return
	incf FSR,f
	goto getchar
half	bcf PORTE,0
	call del_125
	movlw 0xc0
	movwf PORTD
	call pulse
	bsf PORTE,0
	incf FSR,f
	call del_125
	goto getchar

reset2	bcf PORTB,0
	bcf PORTE,2
	bsf PORTE,1
	bsf PORTE,0
	return

pgwr	;test write page w to latch
	call reset2
	bsf PORTB,0
	movwf PORTD
	nop
	nop
	bcf PORTB,0
	return

nvwr	call reset2
	call addr
	bcf PORTE,1
	movf data1,w
	movwf PORTD
	nop
	nop
	bsf PORTE,1
	return

nvrd	call reset2
	call addr
	;portd input
	bcf STATUS,RP1
        bsf STATUS,RP0 
        movlw b'11111111'
        movwf TRISD
	bcf STATUS,RP0
	bcf PORTE,0
	nop
	nop
	movf PORTD,w
	movwf data1
	bsf PORTE,0
	bcf STATUS,RP1
        bsf STATUS,RP0 
        movlw b'00000000'
        movwf TRISD
	bcf STATUS,RP0
	return

addr	bcf STATUS,C
	rlf address,f
	bcf address,0
	movf address,w
	movwf PORTB
	return

schlaf	;set ra4 as input then sleep
	bcf STATUS,RP1
        bsf STATUS,RP0  ; set RAM Page 1 for TRIS registers

        movlw b'11111111'       ; IO pins
        movwf TRISA
        bcf STATUS,RP0  ; back to RAM page 0	
	sleep
	return	

	end

