; HOW TO CLEAR RAM (BANK1) USING INDIRECT ADDRESSING
	LFSR FSR0 ,0x100 		;
NEXT CLRF POSTINC0 			; Clear INDF  register and  inc pointer
	BTFSS FSR0H, 1 			; All done with  Bank1?
	GOTO NEXT 				; NO, clear next
CONTINUE 					; YES, continue


; READING A FLASH PROGRAM MEMORY WORD
	MOVLW CODE_ADDR_UPPER 		; Load TBLPTR with the base
	MOVWF TBLPTRU 				; address of the word
	MOVLW CODE_ADDR_HIGH
	MOVWF TBLPTRH
	MOVLW CODE_ADDR_LOW
	MOVWF TBLPTRL
	READ_WORD
	TBLRD*+ 					; read into TABLAT and increment
	MOVF TABLAT, W 				; get data
	MOVWF WORD_EVEN
	TBLRD*+ 					; read into TABLAT and increment
	MOVF TABLAT, W 				; get data
	MOVWF WORD_ODD


; ERASING A FLASH PROGRAM MEMORY ROW
	MOVLW CODE_ADDR_UPPER 		; load TBLPTR with the base
	MOVWF TBLPTRU 				; address of the memory block
	MOVLW CODE_ADDR_HIGH
	MOVWF TBLPTRH
	MOVLW CODE_ADDR_LOW
	MOVWF TBLPTRL
ERASE_ROW
	BSF EECON1,EEPGD 			; point to FLASH program memory
	BCF EECON1,CFGS 			; access FLASH program memory
	BSF EECON1,WREN 			; enable write to memory
	BSF EECON1,FREE 			; enable Row Erase operation
	BCF INTCON,GIE 				; disable interrupts
	MOVLW 55h
Required MOVWF EECON2 			; write 55h
Sequence MOVLW AAh
	MOVWF EECON2 				; write AAh
	BSF EECON1,WR 				; start erase (CPU stall)
	BSF INTCON,GIE 				; re-enable interrupts
	
; WRITING TO FLASH PROGRAM MEMORY
MOVLW D'64 ; number of bytes in erase block
MOVWF COUNTER
MOVLW BUFFER_ADDR_HIGH ; point to buffer
MOVWF FSR0H
MOVLW BUFFER_ADDR_LOW
MOVWF FSR0L
MOVLW CODE_ADDR_UPPER ; Load TBLPTR with the base
MOVWF TBLPTRU ; address of the memory block
MOVLW CODE_ADDR_HIGH
MOVWF TBLPTRH
MOVLW CODE_ADDR_LOW
MOVWF TBLPTRL
READ_BLOCK
TBLRD*+ ; read into TABLAT, and inc
MOVF TABLAT, W ; get data
MOVWF POSTINC0 ; store data
DECFSZ COUNTER ; done?
BRA READ_BLOCK ; repeat
MODIFY_WORD
MOVLW DATA_ADDR_HIGH ; point to buffer
MOVWF FSR0H
MOVLW DATA_ADDR_LOW
MOVWF FSR0L
MOVLW NEW_DATA_LOW ; update buffer word
MOVWF POSTINC0
MOVLW NEW_DATA_HIGH
MOVWF INDF0
ERASE_BLOCK
MOVLW CODE_ADDR_UPPER ; load TBLPTR with the base
MOVWF TBLPTRU ; address of the memory block
MOVLW CODE_ADDR_HIGH
MOVWF TBLPTRH
MOVLW CODE_ADDR_LOW
MOVWF TBLPTRL
BSF EECON1,EEPGD ; point to FLASH program memory
BCF EECON1,CFGS ; access FLASH program memory
BSF EECON1,WREN ; enable write to memory
BSF EECON1,FREE ; enable Row Erase operation
BCF INTCON,GIE ; disable interrupts
MOVLW 55h
MOVWF EECON2 ; write 55h
MOVLW AAh
MOVWF EECON2 ; write AAh
BSF EECON1,WR ; start erase (CPU stall)
BSF INTCON,GIE ; re-enable interrupts
TBLRD*- ; dummy read decrement
WRITE_BUFFER_BACK
MOVLW 8 ; number of write buffer groups of 8 bytes
MOVWF COUNTER_HI
MOVLW BUFFER_ADDR_HIGH ; point to buffer
MOVWF FSR0H
MOVLW BUFFER_ADDR_LOW
MOVWF FSR0L
PROGRAM_LOOP
MOVLW 8 ; number of bytes in holding register
MOVWF COUNTER
WRITE_WORD_TO_HREGS
MOVF POSTINC0, W ; get low byte of buffer data
MOVWF TABLAT ; present data to table latch
TBLWT+* ; write data, perform a short write
; to internal TBLWT holding register.
DECFSZ COUNTER ; loop until buffers are full
BRA WRITE_WORD_TO_HREGS
PROGRAM_MEMORY
BSF EECON1,EEPGD ; point to FLASH program memory
BCF EECON1,CFGS ; access FLASH program memory
BSF EECON1,WREN ; enable write to memory
BCF INTCON,GIE ; disable interrupts
MOVLW 55h
Required MOVWF EECON2 ; write 55h
Sequence MOVLW AAh
MOVWF EECON2 ; write AAh
BSF EECON1,WR ; start program (CPU stall)
BSF INTCON,GIE ; re-enable interrupts
DECFSZ COUNTER_HI ; loop until done
BRA PROGRAM_LOOP
BCF EECON1,WREN ; disable write to memory


; DATA EEPROM READ
MOVLW DATA_EE_ADDR 		;
MOVWF EEADR 			; Data Memory Address to read
BCF EECON1, EEPGD 		; Point to DATA memory
BCF EECON1, CFGS 		; Access program FLASH or Data EEPROM memory
BSF EECON1, RD 			; EEPROM Read
MOVF EEDATA, W 			; W = EEDATA


; DATA EEPROM WRITE
	MOVLW DATA_EE_ADDR 		;
	MOVWF EEADR 			; Data Memory Address to read
	MOVLW DATA_EE_DATA 		;
	MOVWF EEDATA 			; Data Memory Value to write
	BCF EECON1, EEPGD 		; Point to DATA memory
	BCF EECON1, CFGS 		; Access program FLASH or Data EEPROM memory
	BSF EECON1, WREN 		; Enable writes
	BCF INTCON, GIE 		; Disable interrupts
Required MOVLW 55h 			;
Sequence MOVWF EECON2 		; Write 55h
	MOVLW AAh ;
	MOVWF EECON2 			; Write AAh
	BSF EECON1, WR 			; Set WR bit to begin write
	BSF INTCON, GIE 		; Enable interrupts
. ; user code execution
.
.
	BCF EECON1, WREN 		; Disable writes on write complete (EEIF set)

; DATA EEPROM REFRESH ROUTINE
clrf EEADR ; Start at address 0
bcf EECON1,CFGS ; Set for memory
bcf EECON1,EEPGD ; Set for Data EEPROM
bcf INTCON,GIE ; Disable interrupts
bsf EECON1,WREN ; Enable writes
Loop ; Loop to refresh array
bsf EECON1,RD ; Read current address
movlw 55h ;
movwf EECON2 ; Write 55h
movlw AAh ;
movwf EECON2 ; Write AAh
bsf EECON1,WR ; Set WR bit to begin write
btfsc EECON1,WR ; Wait for write to complete
bra $-2
incfsz EEADR,F ; Increment address
bra Loop ; Not zero, do it again
bcf EECON1,WREN ; Disable writes
bsf INTCON,GIE ; Enable interrupts


; HOW TO CLEAR RAM (BANK1) USING INDIRECT ADDRESSING
	LFSR FSR0 ,0x100 		;
NEXT CLRF POSTINC0 			; Clear INDF  register and  inc pointer
	BTFSS FSR0H, 1 			; All done with  Bank1?
	GOTO NEXT 				; NO, clear next
CONTINUE 					; YES, continue

	
	
	
	
	
BSF EECON1,WR ; start erase (CPU stall)
BSF INTCON,GIE ; re-enable interrupts