; SERIAL.ASM
; serial.asm
; 
;
; Initializes PORTC, 6 to output high (idle).
; Outputs four messages to the LCD using bit bang 9600 baud.
; followed by a 5 second delay.
;
; The LCD is cleared and the process repeated.
;
; Useful routines for Morgan students;
;
; The general idea of OUT_STR_0 and the associated lookup table.
; 
;     SER_INIT - brings PORTC, 6 to output one - idle
;     SER_CHAR - outputs the content of W at 9600 baud 
; 
;     DELAY_SECS
;     DELAY_MS
;     DELAY_10US
;
;Peter H. Anderson, Mar 3, '08

	LIST p=16f887
#include <p16f887.inc>	

        __CONFIG    _CONFIG1, 0x28e4 
	__CONFIG    _CONFIG2, 0x3eff 


N		EQU 0x20

NUM_SECS    	EQU 0x70	
NUM_MS		EQU 0x71	
NUM_10US	EQU 0x72

_CH		EQU 0x73
_NUM_BITS	EQU 0x74
_DLY		EQU 0x75

	ORG 0x000	;program code to start at 000H


	BSF STATUS, 5		; switch to bank 1 and
				
	MOVLW 0x61	
	MOVWF OSCCON		; internal clock, 4 MHz

	MOVLW 0xff
	MOVWF TRISB
   
   	BCF OPTION_REG, 7	

	BCF STATUS, RP0		; back to data bank 0

   	BSF STATUS, 5
    	BSF STATUS, 6
   	CLRF ANSELH
    	BCF STATUS, 5
    	BCF STATUS, 6

	CALL SER_INIT

TOP:        
	BTFSC PORTB, 0
	GOTO TOP
	CALL OUT_STR_0
	CALL OUT_STR_1
	CALL OUT_STR_2
	CALL OUT_STR_3

	MOVLW .5
	CALL DELAY_SECS
   
        
   	MOVLW '?'
	CALL SER_CHAR
	MOVLW 'f'
	CALL SER_CHAR
	GOTO TOP
        
OUT_STR_0:
        CLRF N
OUT_STR_01:        
        MOVF N, W
        CALL LOOK_STR_0
        ADDLW 0
        BTFSC STATUS, Z
        RETURN
        CALL SER_CHAR
        INCF N, F
        GOTO OUT_STR_01
        
OUT_STR_1:
        CLRF N
OUT_STR_11:        
        MOVF N, W
        CALL LOOK_STR_1
        ADDLW 0
        BTFSC STATUS, Z
        RETURN
        CALL SER_CHAR
        INCF N, F
        GOTO OUT_STR_11       
        
OUT_STR_2:
        CLRF N
OUT_STR_21:        
        MOVF N, W
        CALL LOOK_STR_2
        ADDLW 0
        BTFSC STATUS, Z
        RETURN
        CALL SER_CHAR
        INCF N, F
        GOTO OUT_STR_21      
        
        
OUT_STR_3:
        CLRF N
OUT_STR_31:        
        MOVF N, W
        CALL LOOK_STR_3
        ADDLW 0
        BTFSC STATUS, Z
        RETURN
        CALL SER_CHAR
        INCF N, F
        GOTO OUT_STR_31

LOOK_STR_0:
        ADDWF PCL, F
        DT "?f  Welcome", 0
LOOK_STR_1:
        ADDWF PCL, F
        DT "?nMicro Processors", 0
LOOK_STR_2:
        ADDWF PCL, F
        DT "?nFeb 25, '08", 0
LOOK_STR_3:
        ADDWF PCL, F
        DT "?nI Love Morgan", 0
        
                    
SER_INIT:
   	BSF STATUS, 5
   	BCF TRISC, 6
    BCF STATUS, 5
    BSF PORTC, 6
   	MOVLW .250
   	CALL DELAY_MS
	RETURN

SER_CHAR:
; 9600 TTL, 
  	MOVWF _CH
  	MOVLW .9
  	MOVWF _NUM_BITS

  	BCF STATUS, C

SER_CHAR_1:

  	BTFSS STATUS, C
  	BCF PORTC, 6
  	BTFSC STATUS, C
  	BSF PORTC, 6
  	MOVLW .32
  	MOVWF _DLY

SER_CHAR_2:
   	DECFSZ _DLY, F
   	GOTO SER_CHAR_2
   	RRF _CH, F
   	DECFSZ _NUM_BITS, F
   	GOTO SER_CHAR_1

   
   	BSF PORTC, 6  ; stop bit
   	MOVLW .100
   	MOVWF _DLY

SER_CHAR_3:
	DECFSZ _DLY, F  
   	GOTO SER_CHAR_3
   
   	RETURN

DELAY_SECS:
	MOVWF NUM_SECS
DELAY_SECS_1:
	MOVLW .250
	CALL DELAY_MS
	MOVLW .250
	CALL DELAY_MS
	MOVLW .250
	CALL DELAY_MS
	MOVLW .250
	CALL DELAY_MS 
	DECFSZ NUM_SECS, F
	GOTO DELAY_SECS_1
	RETURN 
 
DELAY_MS:		; delay.  number of ms passed in W
 	MOVWF NUM_MS
DELAY_MS_1:        
	MOVLW .100     
	CALL DELAY_10US
	
	DECFSZ NUM_MS, F
	GOTO DELAY_MS_1
	RETURN

DELAY_10US:		; delay.  number of 10us passed in W
	MOVWF NUM_10US	
DELAY_10US_1:	
	CLRWDT	; 7 ~
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ NUM_10US, F
	GOTO DELAY_10US_1
	RETURN
		      	    
        END