Code:
MODE	btfss	REPEAT,1	; bit 1 a '1' for on (on/off flag)
	goto	SET_1		; was off so turn on
	btfsc	REPEAT,3	; speedo on/off flag
	goto	BYSPD
	btfss	REPEAT,2	; speedometer or alarm set mode
	goto	SET_2		; repeat1 status same, repeat2 =1
BYSPD	bcf	REPEAT,1	; if set then clear on/off flag
	bcf	REPEAT,2	; clear speedometer flag
	bcf	INTCON,INTE	; clear interrupt enable for RB0
	clrf	PULSE_CNT	; clear pulse counter
	clrf	TIME_CNT1	; clear time counter 1
	clrf	TIME_CNT2	; clear time counter 2 	
	goto 	WAIT
SET_2	bsf	REPEAT,2	; set speedometer flag
	goto	NO_SET1
SET_1	bsf	REPEAT,1	; if clear then set on/off flag
NO_SET1	bsf	INTCON,INTE	; set interrupt enable for RB0 
	goto	WAIT

UP	movf	DISP1,w		; display1 to w register
	xorlw  	0x05		; compare with decimal'5' 
	btfss	STATUS,Z	; skip next instruction if Disp <9 decimal
	goto	UP_1		; increase display1

; check for maximum on display

	movf	DISP2,w		; look at display 2
	xorlw	0x05		; compare with a 5 
	btfss	STATUS,Z	; is it 5 then check DISP3
	goto	DISP_UP
	movf	DISP3,w		; look at disp3
	xorlw	0x02		; compare with a 1
	btfsc	STATUS,Z	; is it a 2
	goto	WAIT		; maximum of 255 on display so stop counting up

; digit overflow 

DISP_UP	clrf	DISP1		; Disp value cleared as it was beyond BCD range (0-9)
	movf	DISP2,w		; display2 value to w
	xorlw	0x09		; compare with decimal'9' (H'9') 	
	btfss	STATUS,Z	; skip next instruction if Disp <9 decimal
	goto	UP_2		; increase display2
	clrf	DISP2		; Disp value cleared as it was beyond BCD range (0-9)
	goto 	UP_3		; increase display3
		
UP_1	movlw	0x05		; a 5 in the display (count by 5's)
	movwf	DISP1		; display1 increased
	goto	WAIT
UP_2	incf	DISP2,f		; display2 increased
	goto	WAIT
UP_3	incf	DISP3,f		; display3 increased
	goto	WAIT

DOWN	movf	DISP1,w		; display1 to w register
	xorlw	0x00		; compare with decimal'0' to see if was zero	
	btfss	STATUS,Z	; skip next instruction if Disp 0 decimal
	goto	DN_1		; decrease display1

; check for display minimum

	movf	DISP2,w		; look at display 2
	xorlw	0x00		; compare with 0
	btfss	STATUS,Z	; 
	goto	DISP_DN		; not 0 so can count down
	movf	DISP3,w		; look at display 3
	xorlw	0x00		; compare with 0
	btfsc	STATUS,Z
	goto 	WAIT		; do not decrease beyond 000

DISP_DN	movlw	H'05'		; place a 5 in display1
	movwf	DISP1		; disp1 = 5
	movf	DISP2,w		; display2 value to w
	xorlw	0x00		; compare with decimal'0' to see if 0	
	btfss	STATUS,Z	; skip next instruction if Disp 0 decimal
	goto	DN_2		; decrease display2
	movlw	H'09'		; Disp value = 9
	movwf	DISP2
	goto 	DN_3		; decrease display3
		
DN_1	clrf	DISP1		; display1 decreased to 0
	goto	WAIT
DN_2	decf	DISP2,f		; display2 decreased
	goto	WAIT
DN_3	decf	DISP3,f		; display3 decreased
	
; wait period (delay plus EEPROM write time)

; delay loop plus apply tone to piezo alarm as switch press acknowledgement

WAIT	bsf	INTCON,GIE	; allow global interrupts
	movlw	D'100'		; set delay period for repeat of value 2 delay (sets key
				; acknowledge tone frequency) 
	movwf	VALUE_1		; VALUE_1 = w
	movlw	D'50'		; set delay period value 2 (also sets key acknowledge tone period)
LOOP_1	movwf	VALUE_2		; VALUE_2 = w
LOOP_2	decfsz	VALUE_2,f	; decrease VALUE_2, skip if zero
	goto 	LOOP_2
	btfsc	PORTA,3		; alarm output check if high or low
	goto	CLR_T
	bsf	PORTA,3		; alarm out high
DEC_V1	decfsz	VALUE_1,f	; decrease VALUE_1, skip if zero
	goto	LOOP_1	
	bsf	PORTA,3		; alarm out high
	goto 	DELTME		; delay time
CLR_T	bcf	PORTA,3		; alarm out low
	goto	DEC_V1
	
; more delay time 

DELTME	movlw	D'50'		; set delay period 
	movwf	VALUE_1		; VALUE_1 = w
	movlw	D'255'		; set delay period value 2 
LP_1	movwf	VALUE_2		; VALUE_2 = w
LP_2	decfsz	VALUE_2,f	; decrease VALUE_2, skip if zero
	goto 	LP_2
	decfsz	VALUE_1,f	; decrease VALUE_1, skip if zero
	goto	LP_1	
	
; EEPROM write. Store new display values in EEPROM
	
EPWRT	movlw	EEPROM1		; address for EEPROM1
	movwf	EEADR		; address to write
	movf	DISP1,w		; display1 data to w
	call 	EWRITE		; EEPROM write sequence
	movlw	EEPROM2		; address for EEPROM2
	movwf	EEADR		; address for write
	movf	DISP2,w
	call	EWRITE
	movlw	EEPROM3		; address for EEPROM3
	movwf	EEADR		; address for write
	movf	DISP3,w
	call	EWRITE
	movlw	EEPROM4		; address for EEPROM4
	movwf	EEADR		; address to write to
	movf	REPEAT,w	; repeat values (bit 0 is alarm repeat, bit 1 is on/off)
	call 	EWRITE

; when a new speed setting is selected recalculate speed equivalent value
 	
	bcf	INTCON,GIE	; disable interrupts
	call	SPDEQIV		; recalculate speed equivalent value
	bsf	INTCON,GIE	; enable interrupts
	goto	CLOSED		; out from EEPROM write

; subroutine to write to EEPROM

EWRITE	bcf	FLAG_1,6	; EEPROM write repeat flag
	movwf	TEMP_2		; store w in temporary storage
EWRIT	movf	TEMP_2,w	; place value in w (used for read data sequence) 
	movwf	EEDATA		; data register
	bcf	INTCON,GIE	; disable interrupts
	bsf	STATUS,RP0	; select bank 1
	bsf	EECON1,WREN	; enable write
	movlw	0x55		; place 55H in w for write sequence
	movwf 	EECON2 		; write 55H to EECON2
	movlw 	0xAA		; AAH to w
	movwf	EECON2		; write AA to EECON2
	bsf	EECON1,WR	; set WR bit and begin write sequence
	bsf	INTCON,GIE	; enable interrupts
	bcf	EECON1,WREN	; clear WREN bit
WRITE	btfsc	EECON1,WR	; skip if write complete WR=0 when write complete
	goto 	WRITE		; not written yet
	bcf	EECON1,EEIF	; clear write interrupt flag 
	
; read EEPROM DATA and check if written correctly
	
	bsf 	STATUS,RP0	; select memory bank 1
	bsf	EECON1,RD	; read EEPROM
RD_AGN	nop
	btfsc	EECON1,RD	; skip if RD low (read complete)
	goto 	RD_AGN		; wait for low RD	
	bcf	STATUS,RP0	; select bank 0
	movf	EEDATA,w	; EEPROM value in w
	subwf	EEDATA,w	; compare read value with value stored
	btfsc	STATUS,z	; skip if not the same
	return			; value correctly written 
	btfsc	FLAG_1,6	; write repeat bit, skip if clear and rewrite
	return
	bsf	FLAG_1,6	; set repeat flag rewrite once only 
	goto 	EWRIT		; rewrite as not written correctly
	
; wait for switch to open (must test for closed switch when RA0, RA1 and RA2 are low
; because switch will appear open at RA4 when switch pull down via RA0-RA2 is high) 	

CLOSED	bcf	FLAG_1,1	; clear flag that indicates switch closed
	call	ON		; check for closed switch
	call	ON		; do three times to return to original switch closure
	call	ON		;
	call	ON 		; do again just in case missed an interrupt during call
	call	ON 		; do again just in case missed one interrupt during call
	btfsc	FLAG_1,1	; was switch closed 	
	goto 	CLOSED		; yes go to check again
	goto 	SWITCH		; switch open so out
 
; subroutine to wait for switch to reopen
	
ON	bcf	INTCON,T0IE	; prevent multiplex update
	bcf	FLAG_1,0	; clear flag that indicates update interrupt for display
	
RE_CHK	btfsc	PORTA,4		; check if switch closed
	goto	OPEN
	bsf	FLAG_1,1	; switch closed so set flag
	bsf	INTCON,T0IE	; allow multiplex interrupt
	goto	RE_CHK 		; closed so check till open 
OPEN	bcf	FLAG_1,0	; clear multiplex update flag wait for next multiplex update
	bsf 	INTCON,T0IE	; allow multiplex update
FLG_TST	btfss	FLAG_1,0	; is flag set indicating a new interrupt for multiplexing
	goto 	FLG_TST		; wait 
	return

; calibrate routine

CALIBRT	btfss	REPEAT,1	; is on/off flag on
	goto	WAIT		; no calibration allowed when speed alarm unit is off
	btfsc	REPEAT,2	; is speedometer on
	goto	WAIT		; no calibration if speedometer mode
	bcf	INTCON,GIE	; disable interrupts
	clrf	PULSE_CNT	; clear pulse counter
	clrf	TIME_CNT1	; clear time counter 1
	clrf	TIME_CNT2	; clear time counter 2 	
	bsf	FLAG_1,7	; calibrate flag set
	bcf	INTCON,T0IF	; clear timer interrupt flag
	bcf	INTCON,INTF	; clear interrupt flag
	bsf	INTCON,GIE	; allow interrupts
FLG1_CK	btfsc	FLAG_1,7	; wait for end of calibrate, skip if end
	goto	FLG1_CK		; recheck flag 1 bit 7 (cleared at end of calibration)

; store new calibration count numbers in EEPROM	

	movlw	EEPROM5		; address for EEPROM5
	movwf	EEADR		; address to write
	movf	TIME_CNT3,w	; counter 3 to w
	call 	EWRITE		; EEPROM write sequence
	movlw	EEPROM6		; address for EEPROM6
	movwf	EEADR		; address to write
	movf	TIME_CNT4,w	; counter 4 to w
	call 	EWRITE		; EEPROM write sequence	
	goto	SWITCH		; check for a new closed switch 

; Subroutine to convert from 8-bit binary to 2-digit BCD (packed)
; Binary value is in BIN_0  
; Result in BCD is in BCD_0 & BCD_1.  
; BCD_0 is MSB, BCD_1 is LSB

BCD	bcf	STATUS,c	; clear carry bit
	movlw	D'8'
	movwf	CNT_8		; 8 in count
	clrf	BCD_0
	clrf	BCD_1		; set BCD registers to 0 
LOOPBCD	rlf	BIN_0,f		; shift left binary registers
	rlf	BCD_1,f		; MSB shift left

	rlf	BCD_0,f		; LSB shift left BCD registers
	decfsz	CNT_8,f		; reduce count value return when 0
	goto	DECADJ		; continue decimal adjust
	return			; completed decimal to BCD operation

; subroutine decimal adjust

DECADJ	movlw	BCD_1		; BCD LSB address
	movwf	FSR		; pointer for BCD1
	call	ADJBCD		; subroutine to adjust BCD
	movlw	BCD_0		; BCD MS address
	movwf	FSR		; pointer for BCD0
	call	ADJBCD
	goto	LOOPBCD

; subroutine adjust BCD

ADJBCD	movlw	0x03		; w has 03 
	addwf	INDF,w		; add 03 to BCDx register (x is 0-1)
	movwf	TEMP		; store w
	btfsc	TEMP,3		; test if >7
	movwf	INDF		; save as LS digit
	movlw	0x30		; 3 for MSbyte
	addwf	INDF,w		; add 30 to BCDx register
	movwf	TEMP		; store w in temp
	btfsc	TEMP,7		; test if >7
	movwf	INDF		; save as MS digit
	return			; end subroutine

	
	end