;   File:SAMPLE4.ASM
;    PIC: 16F877 @ 20Mhz
;   Date: 2-Feb-2003
; Author: Joe Farr
;---------------------------------------------------------------------
; Description:
; On receipt of a command from the PC, sends a block of 256
; ASCII codes (0 to 255) back to the PC.
;
; The PIC waits for a character before sending back the ASCII block
;
; Also, the ASCII code being sent has it's value echoed on PORT B
; which can be used to drive LED's if requried. Whilst at 20MHz this
; causes the LED's to flash very fast, they can be seen flicker giving
; positive proof that the program is running correctly.
;
;---------------------------------------------------------------------
; Config register bits from the TK3 Config PIC screen
; CP1  CP0  DBG  NIL  WRT  CPD  LVP  BOR  CP1 CP0  POR  WDT  OS1  OS0
;  1    1    1    1    1    1    0    0    1   1    0    0    1    0
; N.B. Logic 1/0 do NOT necessarily mean that the function is On/Off
; respectively - refer ro PIC '87 data sheet.
;---------------------------------------------------------------------
;
; I/O Port Usage Map
; PORT     Usage
;------------------------------------------
; A0 - A5  N/U
; B0       LED 0 (LSB)
; B1       LED 1
; B2       LED 2
; B3       LED 3
; B4       LED 4
; B5       LED 5
; B6       LED 6
; B7       LED 7 (MSB)
; C0 - C5  N/U
; C6 	   RS232 from PIC to Interface Card
; C7 	   RS232 from Interface Card to PIC
; D0 - D7  N/U
; E0 - E2  N/U
;---------------------------------------------------------------------

	LIST p=16f877,c=140,n=999
        errorlevel 1,-(305)
        include "p16f877.inc"


	org 	0
        clrf 	STATUS
        goto 	BootStart
        org 	4
ISR     goto 	5            	; Setup Interupt Address
	org 	5


BootStart
  	clrf  	PORTB

        bsf 	STATUS,RP0  	; set RAM Page 1 for TRIS registers
        movlw 	b'00000000'
        movwf   TRISB           ; set PORTB for all outputs

;
; Configure the baud rate generator
;
        movlw   d'64'           ; 19.2K Baud with 20MHz XTAL (See PIC data sheet for these values)
	movwf   SPBRG           ; In bank 1
        movlw   b'00100100'     ; BRGH = 1(High speed) & ASYNC transmission
        movwf   TXSTA           ; In bank 1
        bcf 	STATUS,RP0  	; back to RAM page 0
        movlw   b'10010000'     ; ASYNC reception
        movwf   RCSTA           ; In bank 0
        call 	FlushRXBuffer   ; Flush the RX buffer in bank 0

LoopAgain
        movlw   0x00
        movwf   PORTB           ; All PORTB bits off

WaitCom 			; Wait for any character to be received
        call 	FlushRXBuffer   ; Make sure that the RX buffer is empty
        call    RecLoop         ; Wait and read from serial - character returned in W

        			; Now transmit ASCII 0 - 255
        movlw   0x00            ; W = 0
SendNext
        call    TxByte          ; send W to serial port
        movwf   PORTB           ; Echo sent byte to PORTB
	addlw 	B'1'            ; W = W + 1
        btfss   STATUS,Z        ; Test Zero (Z) bit of STATUS - if 1 then we've reached zero
	goto    SendNext        ; Not at 0, send next character
        goto    LoopAgain       ; All characters send, go and restart

;
; Receive a character from RS232
; (This routine does not return until a character has been received)
; The received character is in the W register
;
RecLoop
        nop
        btfss   PIR1,RCIF       ; Check for any RX'd data
        goto 	RecLoop         ; Nothing RX'd
        movf    RCREG,W         ; Store the RX'd data in 'W'
        return

;
; Send a byte 'W' to the USART
;
TxByte
        nop
        btfss   PIR1,TXIF       ; TX Buffer empty yet ?
        goto    TxByte          ; No - Keep waiting
        movwf   TXREG           ; Now empty - send this character
        return

;
; Flush the contents of the RX Buffer
;
FlushRXBuffer
	movf    RCREG,W        	; Flush the RX buffer in bank 0
        movf    RCREG,W
	movf    RCREG,W
        return

        end                     ; end of program