;15EEP-w.asm
;WWW.MWFTR.COM/book.html
;Charles Kim
;This program is to read a 10-digit telephone number
;And store them in to EEPROM Data Memory
;
;EEPROM has 256 Byte
;Therefore This PROGRAM allows to read maximum 25 phone numbers
;But for programming simplicity it allows only 24 numbers (0x18=0001 1000)
;
;A companion program 15EEP-r.asm retrieves the number of phone numbers
; from the result of this program
;
;one phone number only
;
;PC--->W--->EEPROM  (WRITING)
;
;
;
;Asynchronouse mode
;
;
;Terminal set up: 8N1 19200

        list P = 16F877
INDF	EQU	0x00		;Indirect Register
INTCON	EQU	0x0b
STATUS	EQU	0x03
PIR2	EQU	0x0d
FSR	EQU	0x04		;File Selection Register (Indirect addr)
TXSTA	EQU	0x98		;TX status and control
RCSTA	EQU	0x18		;RX status and control
SPBRG	EQU	0x99		;Baud Rate assignment
TXREG	EQU	0x19		;USART TX Register
RXREG	EQU	0x1A		;USART RX Register
PIR1	EQU	0x0C		;USART RX/TX buffer status (empty or full)
RCIF	EQU	0x05		;PIR1<5>: RX Buffer 1-Full  0-Empty
TXIF	EQU	0x04		;PIR1<4>: TX Buffer 1-empty 0-full
TXMODE	EQU	0x20		;TXSTA=00100000 : 8-bit, Async
RXMODE	EQU	0x90		;RCSTA=10010000 : 8-bit, enable port, enable RX
BAUD	EQU	0x0F		;0x0F (19200), 0x1F (9600)
RP0	EQU	0x05		;STATUS<5>
RP1	EQU	0x06		;STATUS<6>
;for EEPROM
EEADR	EQU	0x10d		;BANK 2
EEDATA	EQU	0x10c		;BANK 2
EECON1	EQU 	0x18c		;BANK 3
EECON2	EQU	0x18d		;BANK 3
EEPGD	EQU	0x07		;for EECON1
WR	EQU	0x01		;for EECON1
RD	EQU	0x00		;for EECON1
WREN	EQU	0x02		;for EECON1
GIE	EQU	0x07		;for INTCON
EEIF	EQU	0x04		;for PIR2
;

;RAM for DELAY SUBROUTINE
CBLOCK	0x20
		Kount120us   ;Delay count (number of instr cycles for delay)
		Kount100us
		Kount1ms
		Kount10ms
		Kount1s
		Kount10s
		Kount1m
		TEN		;ten digit
		COUNT		; for counting up to 24 numbers (0x18)
        ENDC			;end of ram block

;RAM for Banner Printing on a Monitor
	CBLOCK	0x30
		EMB1
		EMB2
		EMB3
		EMB4
		EMB5
		EMB6
		EMB7
		EMB8
		EMB9
		EMB10
		EMB11
		EMB12
		EMB13
		EMB14		
		EMB15		;0x3f
	ENDC

;The Next 5 lines must be here
;because of bootloader arrangement
;Bootloader first execute the first 4 addresses
;then jump to the address what the execution directs 
;=========================================================
        org 	0x0000      	;line 1
	GOTO	START		;line 2 ($0000)
	NOP			;line 3 ($0001)
	NOP			;line 4 ($0002)
	NOP			;line 5 ($0003)
;======================================================
;start of the program from $4000
START	call 	delay1s
	call 	delay1s
	call	Async_mode		;RX TX initialization
;
;Sending data by Software Polling
	banksel	EMB1

; Write Banner Characters into RAM area
	movlw	'T'
	movwf	EMB1
	movlw	'Y'	
	movwf	EMB2
	movlw	'P'	
	movwf	EMB3
	movlw	'E'
	movwf   EMB4
	movlw	0x20		;SPACE
	movwf	EMB5
	movlw	'P'	
	movwf	EMB6
	movlw	'H'		
	movwf	EMB7
	movlw	'O'		
	movwf	EMB8
	movlw	'N'		
	movwf	EMB9
	movlw   'E'
	movwf   EMB10
	movlw	0x20		;space
	movwf	EMB11
	movlw	'N'		;i
	movwf	EMB12
	movlw	'O'		;n
	movwf	EMB13
	movlw	':'		;g
	movwf	EMB14	
	movlw	0x20		;space
	movwf	EMB15
;starting logo: TYPE!
;======================================================
;Type Inquiry 
	banksel	COUNT
	movlw	0x0		;
	movwf	COUNT		;initialize COUNT

	banksel	EEADR
	movlw	0x0
	movwf	EEADR		;EEADR initialization at 0x00
again
	banksel	FSR
	movlw	0x30
	movwf	FSR		;Pointer @0x30

	banksel	PIR1
TXPOLL2	
	btfss	PIR1, TXIF
	goto	TXPOLL2		;if full, wait
	movf	INDF,0		;W is the content of (FSR)
	movwf	TXREG
	incf	FSR
	btfss	FSR, 0x06	;0100 0000 is the the next of 0011 1111
	goto	TXPOLL2
;	call	delay1s
;Banner Printing Finished
;
;Reading Phone Number Part
	movlw	0x00
	movwf	TEN		;10 - digit
RXPOLL	btfss	PIR1, RCIF	;RX Buffer Full?  (i.e. Data Received?)
	goto 	RXPOLL
	movf	RXREG,0		;received data  to W
;echo the data		
ECHO	btfss	PIR1, TXIF
	goto	ECHO		;if full, wait
	movwf	TXREG		;echo the character from Terminal
;now WRITING to EEPROM
	call	EEWRITE
	banksel	TEN
	incf	TEN		
	btfss	TEN, 0x03
	goto 	RXPOLL
	btfss   TEN, 0x01
	goto 	RXPOLL
;TYPE LF and CR
	call	CRLF
	incf	COUNT
	btfss	COUNT, 0x04
	goto 	again
	btfss   COUNT, 0x03
	goto 	again
fini	nop
	goto	fini
	
;
;
;
;EEWRITE subroutine
EEWRITE
	banksel	EEDATA
	movwf	EEDATA		;writing to EEPROM

	banksel	EECON1
	bcf	EECON1, EEPGD	;point to DATA Memory
	bsf	EECON1, WREN	;Enable it
;Required Sequence
	bcf	INTCON, GIE	;Disable Interrupt
	movlw	0x55
	movwf	EECON2
	movlw	0xaa
	movwf	EECON2
	bsf	EECON1, WR	;Begin to WRITE
	bsf	INTCON, GIE	;Enable Interrupt
;End of the Sequence
;Check if WR bit is cleared
WAIT	btfsc	EECON1,WR
	goto 	WAIT
	bcf	EECON1, WREN	;DISABLE WRITING
;End of Writing
;Clear the EEIF bit of PIR2 (Write Complete Interrupt)
;BANK 0
	banksel	PIR2
	bcf	PIR2, EEIF
	banksel	EEADR
	incf	EEADR
	RETURN

;========================================================
;RX TX Initialization with Asyc Mode
;Async_mode Subroutine
Async_mode
	banksel	SPBRG 
	movlw	baud		;B'00001111' (19200)
	movwf	SPBRG	
	banksel	TXSTA	
	movlw	TXMODE		;B'00100000' Async Mode
	movwf	TXSTA
	banksel	RCSTA
	movlw	RXMODE		;B'10010000' Enable Port
	movwf	RCSTA
	return


;CRLF subroutine
CRLF	
	banksel	PIR1
;LF	btfss	PIR1, TXIF
;	goto	LF	
;	movlw	0x0A
;	movwf	TXREG		
CR      btfss   PIR1, TXIF
	goto    CR
	movlw   0x0D
        movwf	TXREG
LF2	btfss	PIR1, TXIF
	goto	LF2	
	movlw	0x0A
	movwf	TXREG	
	return

;DELAY SUBROUTINE 
;==========================================================
;DELAY SUBROUTINES 


; 1 instruction cycle for 20MHz clock is 0.2 us
; Therefore 120 uS delay needs 600 instuction cycles
;  600 =199*3 +3 ---->Kount=199=0xC7
;  or  =198*3 +6 ---->Kount=198=0xC6
;  or  =197*3 +9 ---->Kount=197=0xC5

Delay120us
	banksel	Kount120us
	movlw	H'C5'		;D'197'
	movwf	Kount120us
R120us	decfsz	Kount120us
	goto	R120us
	return
;
;100us delay needs 500 instruction cycles
;  500 =166*3 +2 ---->Kount=166=0xA6
;  or  =165*3 +5 ---->Kount=165=0xA5
;  or  =164*3 +8 ---->Kount=164=0xA4
Delay100us
	banksel	Kount100us
	movlw	H'A4'
	movwf	Kount100us
R100us	decfsz	Kount100us
	goto	R100us
	return

;
;10ms delay
; call 100 times of 100 us delay  (with some time discrepancy)
Delay10ms 
	banksel	Kount10ms
	movlw	H'64'	;100
	movwf	Kount10ms
R10ms	call	delay100us
	decfsz	Kount10ms
	goto	R10ms
	return
;
;
	
;1 sec delay
;call 100 times of 10ms delay
Delay1s
	banksel	Kount1s
	movlw	H'64'
	movwf	Kount1s
R1s	call	Delay10ms
	decfsz	Kount1s
	goto	R1s
	return
;
;
;10 s delay
;call 10 tiems of 1 s delay
Delay10s
	banksel	Kount10s
	movlw	H'0A'		;10
	movwf	Kount10s
R10s	call	Delay1s
	decfsz	Kount10s
	goto	R10s
	return
;
;1 min delay
;call	60 times of 1 sec delay
Delay1m
	banksel	Kount1m
	movlw	H'3C'	;60
	movwf	Kount1m
R1m	call	Delay1s
	decfsz	Kount1m
	goto	R1m
	return
;======================================================


        END

