; Simpson-Lawarence 900GD Windlass Interface
;	By David V. Fansler
;		181B Bennett Road
;		Arapahoe, NC  28510
;		252-249-1945
;		dfansler@mindspring.com
;
;		Created: Sept 1, 2001
;		Last Updated: March 19, 2002
;
;		This interface prgram uses additional hardware placed inside the
;		900GD windlass.  This consists of a hall effect sensor and two
;		magnets on the final drive gear, placed 180 degrees apart.
;		With 5/16 inch chain this neatly works out to 12 inches per
;		revolution of the final gear, or a resolution of 6 inches per
;		magnetic pulse sensed by the hall effect sensor.  At no load,
;		the output from the windlass is a 20 ms pulse (positive) every
;		200 ms.  The inital design called for two hall effect sensors
;		placed in the windlass with a small angular seperation.
;		Determing which pulsed first would determine the rotational
;		direction of the windlass.  This idea was superceeded by a
;		simplier concept of monitoring the Up & Down lines to the
;		windlass relay for direction, and monitoring one of the hall
;		effect sensors for rotation.  The rode length is saved in EEROM
;		for non-volitle storage.  The EEROM is updated after a
;		change in rode length, and the length has not changed in the
;		last 5 seconds
;
;		The program incorporates a debounce routine on the hall effect
;		sensor which may not be needed as the sensor includes a built in
;		hystersis.
;
;		When on, the windlass interface outputs the current rode length
;		at one second intervals.  The output is RS-232 (19.2k-8-n-1).
;		The interface also receives three commands via RS-232, HOLD,
;		CONTINUE and ZERO.  When the HOLD command is received, the
;		interface will ignore the Up & Down lines and any changes to
;		the hall effect sensor.  This is so the capstan can be used
;		without affecting the length of the chain rode.  A CONTINUE
;		command has the interface resume notmal operation of monitoring
;		the windlass.  A ZERO command will set the rode length to
;		000.0 feet.
;
;		Command Structure
;			Output:$WLxxxxCR  where $WL is the indentifing header,
;						xxxx is length of rode in Hundreds Tens Ones and
;						Tenths of feet (implied decimal) and CR is a
;						terminating carriage return.
;			Input: $WLHOLDCR where $WL is the indentifing header,
;						HOLD is the command to stop monitoring the
;						windlass, and CR is a terminating carriage return.
;					 $WLCONTCR where $WL is the indentifing header,
;						CONT is the command to resume monitoring the
;						windlass, and CR is a terminating carriage return.
;					 $WLZEROCR where $WL is the indentifing header,
;						ZERO is the command to set the rode length to
;						0000, and CR is a terminating carriage return.
;
;
;		PIC16F873 Device Info
;			Reset starts execution at locaion 0000h
;			Interrupts will start execution at the address location
;				provided at address 0004h.
;			Program memory is:
;					Page 0  0005h - 07ffh
;					Page 1  0800h - 0fffh
;
;			Data Memory is in 4 banks, addressed by RP1:RP0.  Each bank
;				is 128 bytes long with the lower locations of each bank
;				reserved for Special Functionn Registers.
;				Bank 0 00h-1fh SFR, 20h - 7fh GPR
;				Bank 1 80h-9fh SFR, a0h - ffh GPR  Locations f0h-ffh can
;					be addresses at 70h-7fh.
;				Bank 2 100h-17fh SFR, 120h - 17fh GPR  Locations 170h-17fh can
;					be addresses at 70h-7fh.
;				Bank 3 180h-19fh SFR, 1f0h - 1ffh GPR  Locations 1f0h-1ffh can
;					be addresses at 70h-7fh.
;
;	Configuration Word
;		Bit 0 - 0	HS Oscillator
;		Bit 1 - 1	HS Oscillator
;		Bit 2 - 0	WDT disabled
;		Bit 3 - 0	Power-up Timer Enabled
;		Bit 4 - CP0
;		Bit 5 - CP1
;		Bit 6 - 0 	Brown-out Reset diabled
;		Bit 7 - 0	In-circuit Programming disabled
;		Bit 8 - 1 	Data EEPROM code protection off
;		Bit 9 - 1	Can not write to unprotected program memory
;		Bit 10 - 1	Unimplemented
;		Bit 11 - 1	In-circuit debugger disabled
;		Bit 12 - 1 	Code protection off (duplicate in Bit 4)
;		Bit 13 - 1	Code protection off (duplicate in Bit 5)
;
	include 'C:\pictools\16f873.inc'
	FUSES _HS_OSC
	FUSES _WDT_OFF
	FUSES _CP_OFF
;	FUSES _PWRT_OFF
	FUSES _BODEN_OFF
;	FUSES _MCLR_OFF
; ACKDT=5091    ACKEN=4091    ACKSTAT=6091  ADCON0=001F
; ADCON1=009F   ADCS0=601F    ADCS1=701F    ADIE=608C
; ADIF=600C     ADON=001F     ADRES=001E    ADRESH=001E
; BF=0094       BOD_OFF=FFBF  BOD_ON=FFFF   BOR=008E
; BOR_OFF=FFBF  BOR_ON=FFFF   BRGH=2098
; C=0003        CCP1CON=0017  CCP1IE=208C   CCP1IF=200C
; CCP1M0=0017   CCP1M1=1017   CCP1M2=2017   CCP1M3=3017
; CCPR1H=0016   CCPR1L=0015   CCP1X=5017    CCP1Y=4017
; CCP2CON=001D  CCP2IE=008D   CCP2IF=000D   CCP2M0=001D
; CCP2M1=101D   CCP2M2=201D   CCP2M3=301D   CCP2X=501D
; CCP2Y=401D    CCPR2H=001C   CCPR2L=001B   CHS0=301F
; CHS1=401F     CHS2=501F     CKP=4014      CPD_OFF=FFFF
; CPD_ON=FEFF   CREN=4018     CSRC=7098
; DA=5094       DC=1003       DEBUG_OFF=FFFF  DEBUG_ON=F7FF
; EEADR=010D    EEADRH=010F   EECON1=018C   EECON2=018D
; EEDATA=010C   EEDATH=010E   EEPGD=718C    EERD=018C
; EERESL=009E   EEWR=118C
; FERR=2018     FSR=0004
; GCEN=7091     GIE=700B      GO_DONE=201F
; HS_OSC=FFFE
; IBF=7089      IBOV=5089     INDF=0000     INTCON=000B
; INDIRECT=0000 INTEDG=6081   INTE=400B     INTF=100B
; IRP=7003
; LVP_OFF=FF7F  LVP_ON=FFFF   LP_OSC=FFFC
; OBF=6009      OERR=1018     OPTION=0081
; P=4094        PCFG0=009F    PCFG1=109F    PCFG2=209F
; PCL=0002      PCLATH=000A   PCON=008E     PD=3003
; PIE1=008C     PIE2=008D     PEIE=600B     PEN=2091
; PIR1=000C     PIR2=000D     POR=108E      PORTA=0005
; PORTB=0006    PORTC=0007    PORTD=0008    PORTE=0009
; PR2=0092      PROTECT_HALF=DFDF           PROTECT_OFF=FFFF
; PROTECT_ON=CFCF  PROTECT_1_QTR=EFEF       PS0=0081
; PS1=1081      PS2=2081      PSA=3081      PSPIE=708C
; PSPIF=700C    PSPMODE=4089  PWRT_OFF=FFFF PWRT_ON=FFF7
; RA=0005       RB=0006       RBIE=300B     RBIF=000B
; RBPU=7081     RC=0007       RC89=6018     RCD8=0018
; RCEN=3091     RCIE=508C     RCIF=500C     RCSTA=0018
; RCREG=001A    RC_OSC=FFFF   RD=0008       RE=0009
; RP0=5003      RP1=6003      RSEN=1091     RW=2094
; S=3094        SEN=0091      SPBRG=0099    SPEN=7018
; SREN=5018     SSPADD=0093   SSPBUF=0013   SSPCON=0014
; SSPCON2=0091  SSPEN=5014    SSPIE=308C    SSPIF=300C
; SSPM0=0014    SSPM1=1014    SSPM2=2014    SSPM3=3014
; SSPOV=6014    SSPSTAT=0094  STATUS=0003   SYNC=4098
; T0CS=5081     T0SE=4081     T0IE=500B     T0IF=200B
; T1CKPS0=4010  T1CKPS1=5010  T1CON=0010    T1OSCEN=3010
; T1SYNC=2010   T2CKPS0=0012  T2CKPS1=1012  T2CON=0012
; TMR0=0001     TMR1CS=1010   TMR1IE=008C   TMR1IF=000C
; TMR1H=000F    TMR1L=000E    TMR1ON=0010   TMR2=0011
; TMR2IE=108C   TMR2IF=100C   TMR2ON=2012   TO=4003
; TOUTPS0=3012  TOUTPS1=4012  TOUTPS2=5012  TOUTPS3=6012
; TRISA=0085    TRISB=0086    TRISC=0087    TRISD=0088
; TRISE=0089    TRISE0=0089   TRISE1=1089   TRISE2=2089
; TRMT=1098     TX89=6098     TXD8=0098     TXEN=5098
; TXIE=408C     TXIF=400C     TXREG=0019    TXSTA=0098
; WCOL=7014     WDT_ON=FFFF   WDT_OFF=FFFB  WRERR=318C
; WREN=218C     WRTEN_OFF=FDFF  WRTEN_ON=FFFF
; XT_OSC=FFFD   xUA=1094
; Z=2003
;
;PORT A
;	0 - UP line
;	1 - DOWN line
;	2 - Pulse from Windlass
PA_TEMP equ 6fh			;temp register to read porta
W_TEMP equ	070h		;temp register for interrupts
STATUS_TEMP equ 071h	;temp register for interrupts
PCLATH_TEMP equ 072h	;temp register for interrupts
Flags equ 073h			;flag register
							;bit 0 5mS Flag
							;bit 1 HOLD Flag (0 = cont, 1 = hold)
							;bit 2 5 sec flag
							;bit 3 writing rode high when set
							;bit 4 RODE_LOW and eerom data the same when set
							;bit 5 RODE_HIGH and eerom data the same when set
							;bit 6 zero flag - write rode to eerom
							;bit 7 send HOLD via rs-232
ONE_SEC_CTR equ 074h	;counter for 1 second interval
MSEN_H_CTR equ 075h		;counter for magnetic sensor high
MSEN_L_CTR equ	076h	;counter for magnetic sensor low
RODE_LOW   equ	077h	;temp byte holder for lsb of rode
RODE_HIGH  equ	078h	;temp byte holder for msb of rode
FIVE_SEC_CTR equ 079h	;counter for 5 second interval
CHAR_OUT_PTR equ 07ah	;pointer to character # to output via rs-232
Five_mS_Cont equ 61		;tmr0 constant to load for 5mS
BUFFER_PTR equ 20h		;pointer to rs-232 input buffer (bank 0)
BUFFER_IN equ 21h		;start of rs-232 input buffer   (bank 0)
BUFFER_OUT equ 27h		;srate of rs-232 output buffer (bank 0)
BAUD_CONST equ 64		;constant for baud (19.2k high speed)
CR equ 0dh				;constant for carriage return
EEIF equ 400Dh			;define EE interrupt flag
BCLIF equ 300dh			;define Bus Collision int flag
RODE_LOW_TEMP equ 20h	;temp location for RODE Low (bank 2)
RODE_HIGH_TEMP equ 21h	;temp location for RODE High (bank 2)

	org 0000
T1
	goto START			;jump to start routine

	org 0004
INT_SRV
	movwf	W_TEMP			;copy W to temp register
	swapf	status,w		;swap status to be saved into W
	clrf status			;bank 0, regardless of current bank.  Clears IRP, RP1,RP0
	movwf STATUS_TEMP		;save status to bank 0 temp register
	movf pclath,w			;only required if usings pages 1,2 and/or 3
	movwf PCLATH_TEMP		;save pclath into w
	clrf	pclath			;page 0 regardless of current page
		;first check to see who caused the interrupt
	btfsc t0if			;was it timer 0?
	goto ServiceTMR0		;if so then jump
	btfsc TXIF			;was it TX clear to send?
	goto ServiceTX			;if so then jump
	btfsc RCIF			;was it RX input received?
	goto ServiceRX			;if so then jump
	btfsc EEIF			;was it EE Write Complete?
	goto ServiceEEWR		;if so then jump
	bcf intf			;clear RB0/INT flag
	bcf rbif			;clear RB Port change flag
	bcf pspif			;clear parallel slave port int flag
	bcf adif			;clear a/d int flag
	bcf sspif			;synchronous int flag
	bcf ccp1IF			;clear ccp1 int flag
	bcf tmr2if			;clear tmr2 int flag
	bcf tmr1if			;clear tmr1 int flag
	bcf bclif			;clear bus collision int flag
	bcf ccp2if			;clear ccp2 int flag
;	clrf intcon			;else clear all interrupts
	bsf t0ie			;re-enable timer 0

	;
INT_SRV_EXIT
	bcf RP0				;move to page 0
	bcf RP1				;
	movf	PCLATH_TEMP,w		;restore pclath
	movwf PCLATH			;move w into pclath
	swapf	STATUS_TEMP,w		;swap status_temp register into w
					;(sets bank to original state)
	movwf STATUS			;movew into status register
	swapf W_TEMP,F			;swap w_temp
	swapf W_TEMP,W			;wap w_temp into W
	retfie				;and return from interrupt

START
	call INIT_PORTS			;call to setup the ports
	call INIT_IRQ			;call to setup the interrupts

MAIN
	bcf RP0				;set to
	bcf RP1				;bank 0
	movlw 0				;load 0 into
	movwf MSEN_H_CTR		;into mag sen high ctr
	movwf MSEN_L_CTR		;into mag sen low ctr
	movwf ONE_SEC_CTR		;into one second counter
	bcf FLAGS,1			;clear HOLD flag
	call READ_RODE			;get the rode from eerom

HOLD_CHECK
	btfsc FLAGS,1			;check HOLD flag, if not set then skip
	goto HOLD_START			;else jump if set
	movf PORTA,0
	movwf PA_TEMP
	btfsc PORTA,0			;is UP line active?
	goto UP				;if so then jump
	movf PORTA,0
	movwf PA_TEMP
	btfsc PORTA,1			;is DOWN line active?
	goto DOWN			;if so then jump
	btfsc Flags,6			;is zero flag set
	call WRITE_RODE			;if so then write rode to eerom
	btfss FLAGS,0			;is 5 ms flag set?
	goto HOLD_CHECK			;if not then loop back
	goto HOLD_CHECK_1
HOLD_START
	call WRITE_RODE			;first write rode to eerom
HOLDING
	btfsc FLAGS,1			;check HOLD flag, if not set then skip
	goto HOLDING			;else jump if set
	goto MAIN			;hold clear so restart

HOLD_CHECK_1
;No UP or DOWN active, 5 ms flag set
	bcf FLAGS,0			;clear 5 ms flag
	incf ONE_SEC_CTR		;add one to the second counter
	btfsc PORTA,2			;is there a pulse from the windlass?
	goto MSEN_HIGH			;if so then jump
MSEN_LOW
	incf MSEN_L_CTR			;add one to the MSEN Low Counter
	movlw 3				;is MSEN Low Counter 3?
	subwf MSEN_L_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto MSEN_LOW_1			;it was not =3 so jump
	goto MSEN_LOW_2			;it was 3 so jump
MSEN_LOW_1				;MSEN_L_CTR was not = 3
	movlw 4				;is MSEN_L_CTR = 4?
	subwf MSEN_L_CTR,0		;store results in W
	btfss Z 			;if MSEN_L_CTR = 4 then skip
	goto ONE_SEC_CK			;not = 4 so jump
MSEN_LOW_2				;MSEN_L_CTR was = 3
	movlw 0				;load 0 into
	movwf MSEN_H_CTR		;into mag sen high ctr
	movlw 3				;load 3 into w
	movwf MSEN_L_CTR		;and into MSEN_L_CTR
	goto ONE_SEC_CK			;and jump
MSEN_HIGH
	incf MSEN_H_CTR			;add one to the MSEN High Counter
	movlw 3				;is MSEN High Counter 3?
	subwf MSEN_H_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto MSEN_HIGH_1		;it was not =3 so jump
	goto MSEN_HIGH_2		;it was 3 so jump
MSEN_HIGH_1				;MSEN_H_CTR was not = 3
	movlw 4				;is MSEN_H_CTR = 4?
	subwf MSEN_H_CTR,0		;store results in W
	btfss Z 			;if MSEN_H_CTR = 4 then skip
	goto ONE_SEC_CK			;not = 4 so jump
MSEN_HIGH_2				;MSEN_H_CTR was = 3
	movlw 0				;load 0 into
	movwf MSEN_L_CTR		;into mag sen low ctr
	movlw 3				;load 3 into w
	movwf MSEN_H_CTR		;and into MSEN_H_CTR
ONE_SEC_CK				; 1 sec = 200 *.005 sec
	movlw 200			;check for one second ctr = 200
	subwf ONE_SEC_CTR,0		;subtract and store in W
	btfss Z				;if it was 200, then skip
	goto HOLD_CHECK			;else was not 200 so jump
	movlw 0				;set ONE_SEC_CTR = 0
	movwf ONE_SEC_CTR		;
	call RODE_OUT			;call sub to output rode via rs-232
	movf FIVE_SEC_CTR,0		;move contents of FIVE_SEC_CTR into W
	btfsc Z				;if not zero then skip next step
	goto HOLD_CHECK			;else jump
	decfsz FIVE_SEC_CTR		;decrement 5 second counter, if 0 then skip
	goto HOLD_CHECK			;and loop back
	call WRITE_RODE			;if zero then write rode to eerom
	goto HOLD_CHECK			;and loop back


UP	;check for hold flag and then UP button pushed
	btfsc FLAGS,1			;check HOLD flag, if not set then skip
	goto HOLD_CHECK			;else jump if set
	movf 5,0
	movwf PA_TEMP
	btfss PORTA,0			;is UP line active?
	goto HOLD_CHECK			;if not then jump
	movlw 5				;set FIVE_SEC_CTR = 5
	movwf FIVE_SEC_CTR		;
	movf PORTA,0
	movwf PA_TEMP
	btfss PORTA,2			;is there a pulse from the windlass?
	goto UP_3			;if not then jump
	bsf PORTC, 0			;illuminate diagnostic LED
	movlw 3				;is MSEN_H_CTR = 3?
	subwf MSEN_H_CTR,0		;store result in W
	btfss Z				;if = then skip
	goto UP_5			;else jump
UP_1
	btfss FLAGS,0			;is 5 ms flag set?
	goto UP				;if not loop back
UP_2
	bcf FLAGS,0			;clear 5 ms flag
	incf ONE_SEC_CTR		;add one to the second counter
	movlw 200			;check for one second ctr = 200
	subwf ONE_SEC_CTR,0		;subtract and store in W
	btfss Z				;if it was 200, then skip
	goto UP				;else was not 200 so jump
	movlw 0				;set ONE_SEC_CTR = 0
	movwf ONE_SEC_CTR		;
	call RODE_OUT			;call sub to output rode via rs-232
	goto UP				;and loop back
UP_3
	bcf PORTC, 0			;extinquish diagnostic LED
	movlw 3				;is MSEN Low Counter 3?
	subwf MSEN_L_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto UP_4			;it was not =3 so jump
	goto UP_1			;it was = 3 so jump
UP_4
	btfss FLAGS,0			;is 5 ms flag set?
	goto UP				;if not loop back
	incf MSEN_L_CTR			;add one to the MSEN Low Counter
	movlw 2				;is MSEN Low Counter 2?
	subwf MSEN_L_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto UP_2			;it was not =2 so jump
	movlw 0				;load 0 into w
	movwf MSEN_H_CTR		;and into MSEN_H_CTR
	goto UP_2			;and jump
UP_5
	btfss FLAGS,0			;is 5 ms flag set?
	goto UP				;if not loop back
	incf MSEN_H_CTR			;add one to the MSEN High Counter
	movlw 2				;is MSEN High Counter 2?
	subwf MSEN_H_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto UP_2			;it was not =2 so jump
	movlw 0				;load 0 into w
	movwf MSEN_L_CTR		;and into MSEN_L_CTR
		;subtract 6" (.5) from rode - never less than 0000
	movlw 0				;compare msb of rode for 0
	addwf RODE_HIGH,0		;by adding 0 and checking Z flag
	btfss Z				;if 0 then skip
	goto UP_6			;not zero so jump
	movlw 0				;check lsb of rode for 0
	addwf RODE_LOW,0		;by adding and checking Z flag
	btfss Z				;if 0 then skip
	goto UP_6			;not zero so jump
	goto UP_2			;rode is zero, so just loop back
UP_6	;RODE_HIGH and/or RODE_LOW not = 0
	movf RODE_LOW, 0		;move low rode into w
	andlw 0fh			;0 out the upper nibble
	btfss Z				;if the low nibble = 0 then skip
	goto UP_7			;else the low nibble = 5 so jump
	movlw 5h			;change 10th's unit to 5
	addwf RODE_LOW			;by adding 5, store result in RODE_LOW
	movf RODE_LOW, 0		;move low rode into w
	andlw 0f0h			;0 out the lower nibble
	btfss Z				;is the upper nibble 0?
	goto UP_8			;not 0 so jump
	movlw 95h			;was 0 so set byte to 95
	movwf RODE_LOW			;and store in rode lsb
	movf RODE_HIGH,0		;move rode msb into w
	andlw 0fh			;mask off the high nibble
	btfss Z				;check for 10's unit being 0
	goto UP_9			;not zero so jump
	movf RODE_HIGH,0		;get high rode again
	andlw 0f0h			;mask off low nibble
	iorlw 09			;and or with 9 to set low nibble
	movwf RODE_HIGH			;and store back in RODE HIGH
	movlw 10h			;subtract one from 100's unit
	subwf RODE_HIGH			;
	goto UP_2			;and jump
UP_7	;RODE_LOW low nibble = 5
	movlw 0f0h			;set lower nibble to 0
	andwf RODE_LOW			;using AND function
	goto UP_2			;and jump
UP_8	;RODE_LOW, low nibble was 0, upper nibble not 0
	movlw 10h				;subtract one from upper nibble
	subwf RODE_LOW			;
	goto UP_2			;and jump
UP_9	;RODE_HIGH, borrow from RODE_LOW, 10's unit not 0
	movlw 01h			;subtract 1 from 10's unit
	subwf RODE_HIGH			;
	goto UP_2			;and jump


DOWN
	btfsc FLAGS,1			;check HOLD flag, if not set then skip
	goto HOLD_CHECK			;else jump if set
	movf PORTA,0
	movwf PA_TEMP
	btfss PORTA,1			;is DOWN line active?
	goto HOLD_CHECK			;if not then jump
	movlw 5				;set FIVE_SEC_CTR = 5
	movwf FIVE_SEC_CTR		;
	movf PORTA,0
	movwf PA_TEMP
	btfss PORTA,2			;is there a pulse from the windlass?
	goto DOWN_3			;if not then jump
	bsf PORTC, 0			;illuminate diagnostic LED
	movlw 3				;is MSEN_L_CTR = 3?
	subwf MSEN_L_CTR,0		;store result in W
	btfss Z				;if = then skip
	goto DOWN_5			;else jump
DOWN_1
	btfss FLAGS,0			;is 5 ms flag set?
	goto DOWN			;if not loop back
DOWN_2
	bcf FLAGS,0			;clear 5 ms flag
	incf ONE_SEC_CTR		;add one to the second counter
	movlw 200			;check for one second ctr = 200
	subwf ONE_SEC_CTR,0		;subtract and store in W
	btfss Z				;if it was 200, then skip
	goto DOWN			;else was not 200 so jump
	movlw 0				;set ONE_SEC_CTR = 0
	movwf ONE_SEC_CTR		;
	call RODE_OUT			;call sub to output rode via rs-232
	goto DOWN			;and loop back
DOWN_3
	bcf PORTC, 0			;extinquish diagnostic LED
	movlw 3				;is MSEN High Counter 3?
	subwf MSEN_H_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto DOWN_4			;it was not =3 so jump
	goto DOWN_1			;it was = 3 so jump
DOWN_4
	btfss FLAGS,0			;is 5 ms flag set?
	goto DOWN			;if not loop back
	incf MSEN_H_CTR			;add one to the MSEN High Counter
	movlw 2				;is MSEN High Counter 2?
	subwf MSEN_H_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto DOWN_2			;it was not =2 so jump
	movlw 0				;load 0 into w
	movwf MSEN_L_CTR		;and into MSEN_L_CTR
	goto DOWN_2			;and jump
DOWN_5	;MSEN Low,  MSEN_L_CTR < 3
	btfss FLAGS,0			;is 5 ms flag set?
	goto DOWN			;if not loop back
	incf MSEN_L_CTR			;add one to the MSEN Low Counter
	movlw 2				;is MSEN Low Counter 2?
	subwf MSEN_L_CTR,0		;store results in W
	btfss Z				;have to do a couple of steps to chk for 0
	goto DOWN_2			;it was not =2 so jump
	movlw 0				;load 0 into w
	movwf MSEN_H_CTR		;and into MSEN_H_CTR
		;add 6" (.5) to rode
DOWN_6	;check value of 10ths unit (0 or 5)
	movf RODE_LOW, 0		;move low rode into w
	andlw 0fh			;0 out the upper nibble
	btfss Z				;if the low nibble = 0 then skip
	goto DOWN_7			;else the low nibble = 5 so jump
	movlw 5h			;change 10th's unit to 5
	addwf RODE_LOW			;by adding 5, store result in RODE_LOW
	goto DOWN_2
DOWN_7	;RODE_LOW low nibble = 5
	movlw 0f0h			;set lower nibble to 0
	andwf RODE_LOW			;using AND function
	movf RODE_LOW,0			;move RODE Low into W
	andlw 0f0h			;0 out the lower nibble
	sublw 090h			;is the upper nibble 9?
	btfss Z				;check zero flag
	goto DOWN_8			;not 9 so jump
	movlw 0				;set uppper and lower nibble to 0
	movwf RODE_LOW			;in RODE Low
	movf RODE_HIGH,0		;move RODE High into W
	andlw 0fh			;mask off low nibble
	sublw 09			;is the lower nibble 9?
	btfss Z				;check zero flag after subtraction
	goto DOWN_9			;not 9 so jump
	movlw 0f0h			;else was 9, so set the low nibble to 0
	andwf RODE_HIGH			;and store in RODE_HIGH
	movf RODE_HIGH,0		;get RODE_HIGH into W
	andlw 0f0h			;mask off the high nibble
	subwf 090h			;check 100's digit for 9
	btfsc Z				;check Zero flag after subtraction
	goto DOWN_10			;was not 9 so jump
	movf RODE_HIGH,0		;was 9 so move RODE High into W
	andlw 0fh			;and set high nibble to 0
	movwf RODE_HIGH			;and store in W
	goto DOWN_2			;and jump
DOWN_8	;upper nibble of RODE_LOW not 9, lower = 5
	movlw 10h			;was not 9 so add 1 to one's unit
	addwf RODE_LOW			;in RODE Low (stores in rode_low
	goto DOWN_2			;and jump
DOWN_9	;lower nibble of RODE_HIGH not 9, upper nibble of RODE_LOW was 9
	movlw 1				;add one to 10's unit
	addwf RODE_HIGH			;and save in RODE_HIGH
	goto DOWN_2			;then jump
DOWN_10	;lower nibble of RODE_HIGH = 9, upper nibble not = 9
	movlw 010h			;add one to 100's unit
	addwf RODE_HIGH			;and save in RODE_HIGH
	goto DOWN_2			;and jump


RODE_OUT
	movlw 2				;set character pointer out to 1
	movwf CHAR_OUT_PTR		;
	bcf RP1				;bank 1
	bcf RP0				;bank 0
	movlw '$'			;load TSREG with $
	movwf TXREG			;and send
	bsf RP0				;bank 1
	bsf TXIE			;enable tx interrupts
	bcf RP0				;bank 0
	return				;and return to caller

READ_RODE
	;this routine reads the value of the rode from eerom and
	;places it into RODE_LOW and RODE_HIGH
	bcf RP0				;point to
	bsf RP1				;bank 2
	movlw 0				;point to low rode data in EEROM (00)
	movwf EEADRH			;High Address
	movwf EEADR			;Low Address to read
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf RD 				;Start read operation
	bcf RP0				;point to bank 2
	movf EEDATA, W			;move eedata into W
	movwf RODE_LOW			;and into RODE Low
	movlw 0				;point to high rode data in EEROM (01)
	movwf EEADRH			;High Address
	movlw 1				;point to high rode data in EEROM (01)
	movwf EEADR			;Low Address to read
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf RD 				;Start read operation
	bcf RP0				;point to bank 2
	movf EEDATA, W			;move eedata into W
	movwf RODE_HIGH			;and into RODE High
	bcf RP1				;point to bank 0
	return				;and return to caller

WRITE_RODE
	;this routine writes the current content of RODE_HIGH and
	;RODE_LOW into storage in the EEROM.  A comparison of the
	;RODE_LOW & RODE_HIGH are made to the values in EEROM first.
	;If either bytes are the same, then that byte is not written.
	;This is a 2 step routine.  The first is here, the second part
	;is an interrupt function.  If needed, the low byte is written first
	;within this function.  Completion of the write generates an
	;interrupt.  If the high byte needs to be written, it will be done
	;from the interrupt function.  If the low byte does not need to
	;be written, and the high byte does, then the high byte is written
	;in this function, and the interrupt function will only clear
	;the EEIF interrupt flag.

	bcf FLAGS,6			;clear zero flag
	bcf FLAGS,3			;make sure the write high rode flag is clear
	bcf FLAGS,4			;clear RODE_LOW = eerom flag
	bcf FLAGS,5			;clear RODE_HIGH = eerom flag
	;first compare value of RODE_HIGH, RODE_LOW with values
	;in eerom - if equal then abort write
	bcf RP0				;point to
	bsf RP1				;bank 2
	movlw 0				;point to low rode data in EEROM (00)
	movwf EEADRH			;High Address
	movwf EEADR			;Low Address to read
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf RD 				;Start read operation
	bcf RP0				;point to bank 2
	movf EEDATA, W			;move eedata into W
	subwf RODE_LOW,0		;subtract low eerom data from RODE_LOW
	btfsc Z				;if zero flag is not set then skip next step
	bsf FLAGS,4			;zero flag is set - low rode bytes are the same
	movlw 0				;point to high rode data in EEROM (01)
	movwf EEADRH			;High Address
	movlw 1				;point to high rode data in EEROM (01)
	movwf EEADR			;Low Address to read
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf RD 			 	;Start read operation
	bcf RP0				;point to bank 2
	movf EEDATA, W			;move eedata into W
	subwf RODE_HIGH,0		;subtract low eerom data from RODE_HIGH
	btfsc Z				;if zero flag is not set then skip next step
	bsf FLAGS,5			;zero flag is set - high rode bytes are the same
	btfss FLAGS,4			;are the low bytes the same, skip if they are
	goto WRITE_RODE_L		;else jump if they are not
	btfss FLAGS,5			;are the high bytes the same
	goto WRITE_RODE_H		;jump if they are not the same
	bcf FLAGS,4			;clear RODE_LOW = eerom flag
	bcf FLAGS,5			;clear RODE_HIGH = eerom flag
	bcf RP1				;point to bank 0
	return				;and return
WRITE_RODE_L
	bsf RP0				;point to
	bsf RP1				;bank 3
WRITE_RODE_L_1
	btfsc WR			;wait for write to finish
	goto WRITE_RODE_L_1		;loop back if still writing
	bcf RP0				;point to bank 2
	movlw 0				;set write address to 00
	movwf EEADR			;low address
	movwf EEADRH			;high address
	movf RODE_LOW,0			;move Rode Low into W
	movwf EEDATA			;and into SFR
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf WREN			;enable writes
	bcf GIE				;disable interrupts
	movlw 55h			;write 55h to EECON2
	movwf EECON2			;
	movlw 0aah			;write aah to EECON2
	movwf EECON2			;
	bsf WR				;start write operation
	bsf GIE				;enable interrupts
	bcf WREN			;Disable writes
	bcf RP0				;point to
	bcf RP1				;bank 0
	return				;and return to caller

WRITE_RODE_H
	bsf RP0				;point to
	bsf RP1				;bank 3
WRITE_RODE_H_1
	btfsc WR			;wait for write to finish
	goto WRITE_RODE_H_1		;loop back if still writing
	bsf FLAGS, 3			;set write high rode flag
	bcf RP0				;point to bank 2
	movlw 1				;set write address to 01
	movwf EEADR			;low address
	movlw 0				;set high address
	movwf EEADRH			;high address
	movf RODE_HIGH,0		;move Rode High into W
	movwf EEDATA			;and into SFR
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf WREN			;enable writes
	bcf GIE				;disable interrupts
	movlw 55h			;write 55h to EECON2
	movwf EECON2			;
	movlw 0aah			;write aah to EECON2
	movwf EECON2			;
	bsf WR				;start write operation
	bsf GIE				;enable interrupts
	bcf WREN			;Disable writes
	bcf RP0				;point to
	bcf RP1				;bank 0
	return				;and return to caller





INIT_PORTS
	;set Port A to digital inputs, Port B to inputs (not used)
	;set Port C to inputs (not used) except for USART (bits 6,7)
	bcf rp0				;point to
	bcf rp1				;bank 0
	movlw 1				;set rs-232 receive buffer
	movwf BUFFER_PTR		;pointer to 1st character
	clrf PORTA			;intitialize port a by clearing
					;data latches
	bsf RP0				;select bank 1
	movlw 07h			;configure all pins
	movwf ADCON1			;as digital inputs
	movlw 0ffh			;value used to initialize data direction
	movwf TRISA			;set all pins to inputs
	movlw 0ffh			;value used to initialize data direction
	movwf TRISB			;set all pins to inputs
	movlw 10111110b			;value used to initialize data direction
	movwf TRISC			;set pins 0 & 6 as out, all other in (bank1:87)
	movlw 04h			;set 8-bit transmit, should be for using BRGH
;	movlw 00h			;set 8-bit transmit,
	movwf TXSTA			;asynchronous mode, high speed
	movlw BAUD_CONST		;get the baud rate
	movwf SPBRG			;and set (bank1:99 TXSTA bit 6)
	bsf TXEN			;enable transmissions
	bsf RCIE			;enable receive interrupts (bank1:8C  PIE1.5)
	bcf RP0				;point to bank 0
	bsf SPEN			;enable serial port (bank 0:18 RCSTA.7)
	bsf CREN			;8-bit receive, receiver enabled (bank0:18 RCSTA.4)
	movlw 0				;load 0 into
	movwf Flags			;Flags register
	return				;return to caller

INIT_IRQ
	;setup timer 0 for a 5 ms interrupt.  Using a 20MHz oscillator
	;and a prescaler of 128, the timer should be pre loaded with a
	;value of 61.  This is calculated by 20MHz/4 = 5MHz.
	;5 MHz/128 prescaler = 25.6uS.  5ms/25.6uS = 195.  Finally
	;(256-61)*25.6us = 5ms.
	bsf rp0				;point to
	bcf rp1				;bank 1
	movlw	10000110B		;disable PB PU, Prescaler to Timer 0, 1:128
	movwf option			;and set in option register
	movlw 00010000B			;enable EEROM Interupt
	movwf PIE2			;and place in register
	bcf rp0				;select bank 0
	movlw 01100000B			;enable tmr0 int & peripheral int
	movwf intcon			;and place in register
	movlw 61			;preset value for timer 0
	movwf tmr0			;store
	retfie				;return to caller while enabling interrupts


ServiceTMR0
	movlw five_ms_cont		;get delay value for 5 ms
	movwf tmr0			;and load
	bcf t0if			;clear tmr0 interrupt flag
	bsf flags,0			;set 5 ms flag
	goto INT_SRV_EXIT		;goto exit ISR

ServiceEEWR
	bcf EEIF			;clear eerom interrupt flag
	btfsc FLAGS,3			;is the write RODE_HIGH flag set?
	goto ServiceEEWR_1		;if set then jump
	btfsc FLAGS,5			;are the high bytes the same
	goto ServiceEEWR_1		;if so then jump
	bsf FLAGS, 3			;else set write high rode flag
	bcf RP0				;point to
	bsf RP1				;bank 2
	movlw 1				;set write address to 01
	movwf EEADR			;low address
	movlw 0				;
	movwf EEADRH			;high address
	movf RODE_HIGH,0		;move Rode Low into W
	movwf EEDATA			;and into SFR
	bsf RP0				;point to bank 3
	bcf EEPGD			;point to Data memory
	bsf WREN			;enable writes
	movlw 55h			;write 55h to EECON2
	movwf EECON2			;
	movlw 0aah			;write aah to EECON2
	movwf EECON2			;
	bsf WR				;start write operation
	bcf WREN			;Disable writes
	goto INT_SRV_EXIT		;goto exit ISR
ServiceEEWR_1
	bcf FLAGS,3			;clear the write high rode flag
	bcf FLAGS,4			;clear RODE_LOW = eerom flag
	bcf FLAGS,5			;clear RODE_HIGH = eerom flag
	goto INT_SRV_EXIT		;goto exit ISR

ServiceTX
	;check bit position of CHAR_OUT_PTR as to which character to output
	;bit 1 is $, bit 2 is W, bit 3 is L, bit 4 is high nibble of MSB
	;bit 5 is low nibble of MSB, bit 6 is high nibble of LSB
	;bit 7 is low nibble of LSB, bit 8 is CR
	;note that the rode_out must be converted to ASCII by moving
	;the rode nibble to the low nibble and ORing with 30h
	btfsc FLAGS,7			;is the send HOLD set?
	goto ServiceTX_Hold		;if so then jump
	btfsc CHAR_OUT_PTR,0		;check for bit 1 set
	goto TX_1			;else jump
	btfsc CHAR_OUT_PTR,1		;check for bit 2 set
	goto TX_2			;else jump
	btfsc CHAR_OUT_PTR,2		;check for bit 3 set
	goto TX_3			;else jump
	btfsc CHAR_OUT_PTR,3		;check for bit 4 set
	goto TX_4			;else jump
	btfsc CHAR_OUT_PTR,4		;check for bit 5 set
	goto TX_5			;else jump
	btfsc CHAR_OUT_PTR,5		;check for bit 6 set
	goto TX_6			;else jump
	btfsc CHAR_OUT_PTR,6		;check for bit 7 set
	goto TX_7			;else jump
TX_8
	bsf rp0				;point to bank 1
	bcf TXIE			;disable TX interrupts
	bcf RP0				;point to bank 0
	movlw 0dh			;load W with a carriage return
	movwf TXREG			;and place in tx data register
	goto INT_SRV_EXIT		;goto exit ISR
TX_1
	movlw '$'			;load ASCII dollar sign
	movwf TXREG			;and place in tx data register
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_2
	movlw 'W'			;load ASCII 'W'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_3
	movlw 'L'			;load ASCII 'L'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_4
	swapf RODE_HIGH, 0		;swap nibbles, store in W
	andlw 0fh			;mask off high nibble in W
	iorlw 30h			;convert to ASCII
	movwf TXREG			;and place in tx register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_5
	movf RODE_HIGH, 0		;get RODE_HIGH into w
	andlw 0fh			;mask off high nibble in W
	iorlw 30h			;convert to ASCII
	movwf TXREG			;and place in tx register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_6
	swapf RODE_LOW, 0		;swap nibbles, store in W
	andlw 0fh			;mask off high nibble in W
	iorlw 30h			;convert to ASCII
	movwf TXREG			;and place in tx register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_7
	movf RODE_LOW, 0		;get RODE_LOW into w
	andlw 0fh			;mask off high nibble in W
	iorlw 30h			;convert to ASCII
	movwf TXREG			;and place in tx register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR

ServiceTX_Hold
	;check bit position of CHAR_OUT_PTR as to which character to output
	;bit 1 is $, bit 2 is W, bit 3 is L, bit 4 is H,
	;bit 5 is O, 6 is L
	;bit 7 is D, bit 8 is CR
	btfsc CHAR_OUT_PTR,0		;check for bit 1 set
	goto TX_H_1			;else jump
	btfsc CHAR_OUT_PTR,1		;check for bit 2 set
	goto TX_H_2			;else jump
	btfsc CHAR_OUT_PTR,2		;check for bit 3 set
	goto TX_H_3			;else jump
	btfsc CHAR_OUT_PTR,3		;check for bit 4 set
	goto TX_H_4			;else jump
	btfsc CHAR_OUT_PTR,4		;check for bit 5 set
	goto TX_H_5			;else jump
	btfsc CHAR_OUT_PTR,5		;check for bit 6 set
	goto TX_H_6			;else jump
	btfsc CHAR_OUT_PTR,6		;check for bit 7 set
	goto TX_H_7			;else jump
TX_H_8
	bsf rp0				;point to bank 1
	bcf TXIE			;disable TX interrupts
	bcf RP0				;point to bank 0
	movlw 0dh			;load W with a carriage return
	movwf TXREG			;and place in tx data register
	bcf FLAGS,7			;clear the send HOLD via rw232 flag
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_1
	movlw '$'			;load ASCII dollar sign
	movwf TXREG			;and place in tx data register
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_2
	movlw 'W'			;load ASCII 'W'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_3
	movlw 'L'			;load ASCII 'L'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_4
	movlw 'H'			;load ASCII 'L'
	movwf TXREG			;and place in tx register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_5
	movlw 'O'			;load ASCII 'L'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_6
	movlw 'L'			;load ASCII 'L'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
TX_H_7
	movlw 'D'			;load ASCII 'L'
	movwf TXREG			;and place in tx data register
	bcf C				;clear the carry flag
	rlf CHAR_OUT_PTR		;move pointer
	goto INT_SRV_EXIT		;goto exit ISR

ServiceRX
	;check bit position of BUFFER_PTR as to where to place
	;character in buffer
	;bit 1 is $, bit 2 is W, bit 3 is L, bit 4 is 1st char of command
	;bit 5 is 2nd char of cmd, bit 6 is 3rd char of cmd
	;bit 7 is 4th char of cmd, bit 8 is CR

	btfsc BUFFER_PTR,0		;check for bit 1 set
	goto RX_1			;else jump
	btfsc BUFFER_PTR,1		;check for bit 2 set
	goto RX_2			;else jump
	btfsc BUFFER_PTR,2		;check for bit 3 set
	goto RX_3			;else jump
	btfsc BUFFER_PTR,3		;check for bit 4 set
	goto RX_4			;else jump
	btfsc BUFFER_PTR,4		;check for bit 5 set
	goto RX_5			;else jump
	btfsc BUFFER_PTR,5		;check for bit 6 set
	goto RX_6			;else jump
	btfsc BUFFER_PTR,6		;check for bit 7 set
	goto RX_7			;else jump
	goto RX_8			;else goto RX_8
RX_1
	movf RCREG,0			;get received data into W
	xorlw '$'			;is it a dollar sign?
	btfss Z				;if so then skip next step
	goto INT_SRV_EXIT		;goto exit ISR
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;else it is a $, so move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_2
	movf RCREG,0			;get received data into W
	xorlw 'W'			;is it a W?
	btfss Z				;if so then skip next step
	goto RX_RESET			;goto reset RX due to wrong character
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_3
	movf RCREG,0			;get received data into W
	xorlw 'L'			;is it a L?
	btfss Z				;if so then skip next step
	goto RX_RESET			;goto reset RX due to wrong character
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_4
	movf RCREG,0			;get received data into W
	movwf BUFFER_IN			;and store data in buffer
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_5
	movf RCREG,0			;get received data into W
	movwf BUFFER_IN+1		;and store data in buffer
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_6
	movf RCREG,0			;get received data into W
	movwf BUFFER_IN+2		;and store data in buffer
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_7
	movf RCREG,0			;get received data into W
	movwf BUFFER_IN+3		;and store data in buffer
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer
	goto INT_SRV_EXIT		;goto exit ISR
RX_8
	movf RCREG,0			;get received data into W
	movwf BUFFER_IN+4		;and store data in buffer
	bcf C				;clear the carry bit
	rlf BUFFER_PTR			;move pointer

	;now check for which command has been sent
RC_CHECK
	movf BUFFER_IN,0		;get first command character
	xorlw 'H'			;is it an H?
	btfss Z				;if so then skip next step
	goto RC_CHECK_1			;not H so jump
	goto RC_HOLD			;is H so jump to check for HOLD
RC_CHECK_1
	movf BUFFER_IN,0		;get first command character
	xorlw 'C'			;is it an C?
	btfss Z				;if so then skip next step
	goto RC_CHECK_2			;not C so jump
	goto RC_CONT			;is C so jump to check for CONTINUE
RC_CHECK_2
	movf BUFFER_IN,0		;get first command character
	xorlw 'Z'			;is it an Z?
	btfss Z				;if so then skip next step
	goto RX_RESET			;not a Z so reset pointer and exit
	goto RC_ZERO			;is Z so jump to check for ZERO
RC_HOLD
	movf BUFFER_IN+1,0		;get second command character
	xorlw 'O'			;is it an O?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+2,0		;get second command character
	xorlw 'L'			;is it an L?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+3,0		;get second command character
	xorlw 'D'			;is it an D?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+4,0		;get second command character
	xorlw CR			;is it an carriage return?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	bsf FLAGS,1			;set the hold flag
	bsf FLAGS,7			;set the send HOLD via rs232 flag
	movlw 2				;set character pointer out to 1
	movwf CHAR_OUT_PTR		;
	bcf RP1				;bank 1
	bcf RP0				;bank 0
	movlw '$'			;load TSREG with $
	movwf TXREG			;and send
	bsf RP0				;bank 1
	bsf TXIE			;enable tx interrupts
	bcf RP0				;bank 0

	goto RX_RESET			;and jump
RC_CONT
	movf BUFFER_IN+1,0		;get second command character
	xorlw 'O'			;is it an O?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+2,0		;get second command character
	xorlw 'N'			;is it an N?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+3,0		;get second command character
	xorlw 'T'			;is it an T?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+4,0		;get second command character
	xorlw CR			;is it an carriage return?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	bcf FLAGS,1			;clear the hold flag
	goto RX_RESET			;and jump
RC_ZERO
	movf BUFFER_IN+1,0		;get second command character
	xorlw 'E'			;is it an E?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+2,0		;get second command character
	xorlw 'R'			;is it an R?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+3,0		;get second command character
	xorlw 'O'			;is it an O?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	movf BUFFER_IN+4,0		;get second command character
	xorlw CR			;is it an carriage return?
	btfss Z				;if so then skip next step
	goto RX_RESET			;else jump to reset buffer pointer
	bcf FLAGS,1			;clear the hold flag
	movlw 0				;reset the rode to zero
	movwf RODE_HIGH			;first the high byte
	movwf RODE_LOW			;and then the low byte
	bsf Flags,6			;set zero flag so main will write to eerom

RX_RESET
	movlw 1				;set rs-232 receive buffer
	movwf BUFFER_PTR		;pointer to 1st character
	goto INT_SRV_EXIT		;goto exit ISR

END
