;2rxtx-v1.asm
;WWW.MWFTR.COM/book.html
;Charles Kim
;This program uses the builtin RX and TX pins of 16F877
;
;The program types on PC screen the character typed from keyboard
;
;Asynchronouse mode
;
;The first Code for RS232 communication
;Betweeb PC and PIC chip
;
;
;PC's Hyper Terminal Set-Up: 8N1 19200
;Baud: 		19200
;Data Bit:	8
;Parity: 	None
;Stop Bit:	1
;Control: 	None

        list P = 16F877

STATUS	EQU	0x03
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
RCREG	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)

	
;

;RAM for DELAY SUBROUTINE
   
	CBLOCK	0x20
		Kount120us   ;Delay count (number of instr cycles for delay)
		Kount100us
		Kount1ms
		Kount10ms
		Kount1s
		Kount10s
		Kount1m
	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 $0004
START	call 	delay10ms
	call 	delay10ms
	call	Async_mode		;RX TX initialization
;
;
;Promptor Transmit
TXPOLL
	banksel	PIR1
	btfss	PIR1, TXIF	; Check if TX buffer is empty
	goto	TXPOLL
	banksel	TXREG
	movlw	'>'		;>
	movwf	TXREG		; Place the character to TX buffer


;Ready for a key-in from the terminal
RXPOLL
	banksel	PIR1
	btfss	PIR1, RCIF	;RX Buffer Full?  (i.e. Data Received?)
	goto 	RXPOLL
	banksel	RCREG
	movf	RCREG,0		;received data  to W

;echo the data
		
ECHO	
	banksel	PIR1	
	btfss	PIR1, TXIF	;Is TX buffer Empty?
	goto	ECHO		;if full, wait
	banksel	TXREG
	movwf	TXREG		;echo the character from Terminal
ECHOcr	
	banksel	PIR1		;TX buffer check
	btfss	PIR1, TXIF
	goto	ECHOcr		;if full, wait
	banksel	TXREG
	movlw	H'0D'		;CR
	movwf	TXREG		;
ECHOLF
	banksel	PIR1
	btfss	PIR1, TXIF
	goto	ECHOLF
	banksel	TXREG
	movlw	H'0A'		;LF (Line Feed)
	movwf	TXREG

	goto	TXPOLL



;========================================================
;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

;==========================================================
;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

