; SERIAL2.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_) 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, Revised Apr 9, '08
;
;Apr 2, '08 - Interrupts disabled in SER_CHAR


	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

    GOTO MAIN

    ORG 0x004

    GOTO INTSERV


MAIN:
	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,

    BCF INTCON, GIE	; now, turn interrupts off

  	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

    BSF INTCON, GIE
   	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

INTSERV:
    RETFIE

    END