; EEPROM_1.ASM
;
; Illustrates how to initialize EEPROM using the assembler, how to read 
; from EEPROM and write to EEPROM.  Note that this EEPROM is the EEPROM 
; on the 16C84.
;
; EEPROM location 00 is initialized to 100 decimal in the assembler using
; DE directive.  Each time function dec_count is called, the program 
; decrements this value and checks to see if it is at zero.  Such an 
; arrangement might be used to limit the number of accesses and might 
; be used with a debit card.
;
; Program continually flashes LED on RB.0 at about 250 ms on and 250 msec 
; off.  Loops indefinitely.  However, counter in EEPROM is decremented on
; each pass.  Program locks when EEPROM counter is decremented to zero. 
;
; Note that even if power is turned off prior to the completion of 100
; flashes, the latest EEPROM value will be retained for the subsequent 
; run of the program.
;
; copyright, Peter H. Anderson, MSU, June 7, '97
;

	LIST p=16c84
#include <p16c84.inc>	
	__CONFIG 11h

TEMP	EQU 0CH
LOOP1	EQU 0DH		;note that general purpose registers begin at 0CH
LOOP2	EQU 0EH

	ORG 000H	;program code to start at 000H

	BCF STATUS, RP1
	BSF STATUS, RP0		; switch to bank 1 and
				; make all bits on Portb outputs

	CLRF TRISB		; make all PortB bits outputs

	BCF STATUS, RP0		; back to data bank 0

TOP
	CALL DEC_COUNT
	SUBLW	0		; to test for zero
	BTFSC STATUS, Z
	GOTO LOCK
	; otherwise, the program continues.  flash LED
PROGRAM	
	BCF PORTB, 0		; turn LED on
	MOVLW .250
	CALL DELAY
	BSF PORTB, 1		; turn it off
	CALL DELAY
	GOTO TOP

LOCK			; but, if the counter is decremented to zero
	GOTO LOCK	; endless loop

;;;;;;

DEC_COUNT	; reads counter value in eeprom (EE_COUNT), decrements it, 
		; writes back to eeprom.  Returns value of EE_COUNT in W

	MOVLW .00
	MOVWF EEADR
	CALL READ_EEPROM	; fetch EE count, decrement and write it
	MOVWF TEMP		; mov to temp to decrement
	DECF TEMP, W
	CALL WRITE_EEPROM	; write the new value to eeprom
	CALL READ_EEPROM	; fetch EE count to return to calling
program
	RETURN

READ_EEPROM	; reads eeprom data at location specified in EEADR
		; returns the value in W
	
	BSF STATUS, RP0		; bank 1
	BSF EECON1, RD		; set the RD bit
	BCF STATUS, RP0		; back to bank 0
	MOVF EEDATA, W		; fetch value of EEDATA
	RETURN

WRITE_EEPROM	; writes value in W to location specified in EEADR
	
	MOVWF EEDATA		; W -> EEDATA
	BSF STATUS, RP0		; bank 1
	BCF INTCON, GIE		; disable interrupts

	BSF EECON1, WREN	; write enable bit set
	MOVLW 55H		; go through required sequence
	MOVWF EECON2		
	MOVLW 0AAH
	MOVWF EECON2
	
	BSF EECON1, WR		; begin write sequence
	MOVLW .20
	CALL DELAY		; delay for 20 ms
	BCF EECON1, WREN	; disable any further writes	
	BSF INTCON, GIE		; enable interrupts
	BCF STATUS, RP0		; back to bank 0
	RETURN
	

DELAY	; delays for number of ms in W

	MOVWF 	LOOP1
OUTTER
	MOVLW	.110	; close to 1.0 msec delay when set to .110
	MOVWF 	LOOP2
INNER
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ	LOOP2, F	; decrement and leave result in LOOP2 
				; skip next statement if zero
	GOTO INNER
	DECFSZ 	LOOP1, F
	GOTO OUTTER
	RETURN

	ORG 2100H	; starting point of EEPROM on 16C84
	DE 64H		; EEPROM location initialized to 100 decimal

	END