;**************************************************************************
; SERIAL HANDLER FOR INTERNAL USART ON THE PIC 16C7X 
;
; BRHG=0 (LOW SPEED AND NO ERRORS)
; SPBRG = OSC/(64*9600) -1 = 0 (for 57600) 2 (for 19200)
;**************************************************************************

INIT_USART:             ;FOR 9600 N81 (TRANSMIT)
BSF STATUS,RP0          ;BANK ONE
MOVLW B'00100000'       ;SET TXSTA FOR ASYNC OPERATION
MOVWF TXSTA             ;AND TO A LOW SPEED
MOVLW .11               ;SET SPBRG VALUE (4800)
MOVWF SPBRG             ; ''
BCF STATUS,RP0          ;BANK ZERO
MOVLW B'10000000'       ;ENABLE PORT FOR RX AND TX
MOVWF RCSTA             ; ''
BSF RCSTA,CREN          ;ENABLE CONTINUOUS RECEIVE

RETURN                  ;RETURN FROM ROUTINE



CLRTX:
BTFSC PIR1,TXIF             ;TEST THE INTERRUPT FLAG
return                      ;WHEN CLEAR, CARRY ON
GOTO CLRTX                  ;TEST IT AGAIN

;********************* Internal Usart code end ***************


;***************************************************************
; SOFTWARE USART WITH INTERRUPTS. USES TIMER0 AND COUNTER
;***************************************************************

;********* INITIALIZATION ************

INIT_SWUSART:
BSF SERIAL,RXF             ;SET THE RX FLAG
BSF SWTXPIN                ;PULL UP THE TXPIN
BSF STATUS,RP0             ;BANK1
BSF OPTREG,5               ;SELECT COUNTER MODE
BSF OPTREG,T0SE            ;INCREMENT ON FALLING EDGE
BCF STATUS,RP0             ;BANK0
MOVLW 0XFFH                ;LOAD COUNTER
MOVWF TMR0                 ;WITH FF
BSF INTCON,GIE             ;SET GLOBAL INTERRUPT
BSF INTCON,T0IE            ;SET INTERRUPT WE NEED
BCF SERIAL,CLR             ;SET THE CLEAR FLAG
RETURN


;********* SW_RX WE RECEIVE A BIT HERE **********
SW_RX:
BTFSC SERIAL,STP             ;TEST FOR STOP BIT
GOTO SW_STP                  ;GOTO STOP BIT
BTFSS SERIAL,STRT            ;TEST FOR THE START BIT
GOTO SW_START                ;START BIT
RRF SWRXREG,F                ;ROTATE THE RX REG
MOVFW PORTA                  ;READ PORT A
MOVWF ASHADOW                ;SAVE READING
BTFSC ASHADOW,4              ;READ THE PIN
GOTO SWRXSET                 ;PIN IS SET
; NOP
; NOP                        ;TIMING ADJUSTMENT
BCF SWRXREG,7                ;CLEAR THE RX BIT
GOTO SWRXCONT                ;CARRY ON



SWRXSET:
BSF SWRXREG,7                 ;SET THE RX BIT
GOTO SWRXCONT                 ;CARRY ON



SWRXCONT:
DECF BITS                     ;DECREMENT THE BITS
SKPNZ                         ;SKIP NEXT INST IF NOT ZERO
BSF SERIAL,STP                ;SET THE STOP BIT
MOVLW .191                    ;TMR DELAY
MOVWF TMR0                    ;LOAD THE TIMER
RETURN                        ;END OF RX ROUTINE



SW_START:
BSF STATUS,RP0                 ;BANK 1
BCF OPTREG,T0CS                ;SET TO TIMER MODE
BCF STATUS,RP0                 ;BANK 0
MOVLW .161                     ;START BIT TIME
MOVWF TMR0                     ;INTO TIMER
BSF SERIAL,CLR                 ;SET THE CLEAR FLAG
BSF SERIAL,STRT                ;SET THE STRT FLAG
MOVLW .8                       ;SET UP FOR 8 BIT RECEPTION
MOVWF BITS                     ; '' ''
RETURN




SW_STP:
BSF STATUS,RP0                 ;BANK 1
BSF OPTREG,T0CS                ;SET COUNTER MODE
BCF STATUS,RP0                 ;BANK 0
MOVLW 0XFFH                    ;SET TO FF
MOVWF TMR0                     ;LOAD INTO TIMER
BCF SERIAL,CLR                 ;CLEAR THE SERIAL FLAG
BCF SERIAL,RXF
BCF SERIAL,STP
BCF SERIAL,STRT
RETURN

SW_TX:
BCF SERIAL,RXF                 ;CLEAR THE RX FLAG
MOVLW .1                       ;SET TIMER TO LOW VALUE
MOVWF TMR0                     ; ''
BSF STATUS,RP0                 ;BANK 1
BCF OPTREG,T0CS                ;SET TO TIMER MODE
BCF STATUS,RP0                 ;BANK 0
BSF SERIAL,TXF                 ;SET THE TX FLAG
BTFSC SERIAL,STP               ;TEST FOR STOP BIT
GOTO SW_TSTP                   ;GOTO STOP BIT
BTFSS SERIAL,STRT              ;TEST FOR THE START BIT
GOTO SW_TSTART                 ;START BIT

BTFSC SWTXREG,0                ;READ THE DATA
GOTO SWTXSET                   ;PIN IS SET
GOTO SWTXCLR                   ;CLEAR THE TX BIT
GOTO SWTXCONT                  ;CARRY ON
SWTXCLR:
NOP
BCF SWTXPIN                    ;SET THE TX PIN
GOTO SWTXCONT                  ;CONTINUE



SWTXSET:
NOP
NOP
BSF SWTXPIN                     ;SET THE TX PIN
GOTO SWTXCONT                   ;CONTINUE

SWTXCONT:
MOVLW .193                      ;DELAY TIME
MOVWF TMR0                      ;SET TIMER
DECF BITS,F                     ;DECREMENT THE NUMBER OF BITS
SKPNZ                           ;SKIP NEXT INSTRUCTION IF NOT ZERO
GOTO SET_STOP                   ;SET THE STOP BIT
RRF SWTXREG,F                   ;ROTATE THE DATA TO BE SENT
RETURN

SET_STOP:
BSF SERIAL,STP                  ;SET THE STOP BIT
RETURN

SW_TSTART:
BCF SWTXPIN                     ;
NOP
MOVLW .192                      ;DELAY TIME
MOVWF TMR0                      ;SET TIMER
MOVLW .8                        ;8BITS TO SEND
MOVWF BITS                      ;SAVE IN BITS
BSF SERIAL,STRT                 ;SET SRT FLAG
BSF SERIAL,CLR                  ;SET THE CLEAR FLAG
RETURN

SW_TSTP:
BTFSC SERIAL,STP2               ;TEST FOR END OF STOP BIT
GOTO SWTSTP2                    ;GOTO THE END

NOP
NOP
NOP
BCF SWTXPIN                     ;
MOVLW .189                      ;DELAY TIME
MOVWF TMR0                      ;SET TIMER
BTFSC SERIAL,STP2               ;TEST FOR END OF STOP BIT
GOTO SWTSTP2                    ;GOTO THE END

BSF SERIAL,STP2                 ;SET THE END OF THE STOP BIT
RETURN

SWTSTP2:
BSF SWTXPIN                     ;
BSF STATUS,RP0                  ;BANK 1
BSF OPTREG,T0CS                 ;SET COUNTER MODE
BCF STATUS,RP0                  ;BANK 0
MOVLW 0XFFH                     ;SET TO FF
MOVWF TMR0                      ;LOAD INTO TIMER
BCF SERIAL,STP                  ;CLEAR STOP BIT FLAG
BCF SERIAL,STRT                 ;CLEAR START BIT
BCF SERIAL,TXF                  ;CLEAR TX FLAG
; MOVLW .250
; CALL MDELAY
; MOVLW .250
; CALL MDELAY
; MOVLW .250
; CALL MDELAY
; MOVLW .250
; CALL MDELAY
BCF SERIAL,CLR                  ;CLEAR THE IN USE FLAG
; bsf serial,rxf
RETURN

SWCLRTX:
BTFSS SERIAL,CLR                ;TEST IF USART IS IN USE
RETURN                          ;WHEN CLEAR, CARRY ON
GOTO SWCLRTX                    ;TEST IT AGAIN