- ;----------------------------------------------------------------------; 
- ; bike3.asm   Combines: Time , Dist, Av velocity, Inst Vel   
- ;             Fred Maher             1st March 2002   
- ;   BASIC BICYCLE  COMPUTER WITH THESE FUNCTIONS               
- ;----------------------------------------------------------------------; 
-   
- ; 1          Trip Time    HRS:MIN:SEC 
- ; 2          Trip Dist    000km 00m 
- ; 3          Trip AvSpd   00.00km/hr 
- ; 4          Speed        00.00km/hr     
-   
-   
-   
-   
-   
- ;---------------------------------------------------------------------                
- ;-------                 HEADER                ---------- 
- ;--------------------------------------------------------------------- 
-   
- ;                      LCD MESSAGES 
- ; position at beginning of 1st line col 0  movlw H'80  
- ; position at beginning of second line     movlw H'C0' 
-         
-   
-       LIST P=16F84           ;  16F84 Runs at 4.096 MHz 
-       INCLUDE "p16f84A.inc" 
-       __CONFIG    _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON   
-    
-       ERRORLEVEL -224        ;  suppress annoying message because of tris 
-       ERRORLEVEL -302        ;  suppress message because of page change 
-   
- ; Define Information 
-      #DEFINE RS PORTA, 2 
-      #DEFINE E  PORTA, 3 
-     ;#DEFINE TOGGLESW PORTB, 6  ; not used at the moment 
-     ;#DEFINE LED PORTB, 5 
- ;  Macro 
-   
- ;---------------------------------------------------------------  
-             CBLOCK     0CH   ;  0C to 4F = 67 
- ;--------------------------------------------------------------- 
-   
- ;                   MATH ROUTINES     
-   
- ;                16 X16 Mult , --> 32 
- ;     mah mal x mbh mbl = mq4 mq3 mq2 mq1 ( mq4 highest) 
-  mq4 
-  mq3 
-  mq2 
-  mq1         
-  mbh 
-  mbl 
-  mah 
-  mal  
- ;                   16 / 16 Div --> 16 
-  denlo           
-  denhi      
-  numlo             
-  numhi     
-  rmdrlo              
-  rmdrhi            
-  reshi 
-  reslo 
-  ;temp       also used in nybble 
-   
- ; Addition 16+16 out max 65536 (no carry) 
- ; Subtraction q1_16-q2_16 out r_16; neg numbers not allowed 
-             
-  q1hi                    
-  q1lo              
-  q2hi                             
-  q2lo              
-  rhi               
-  rlo               
- ;------------    Distance         ----------------------- 
-   
-  dtotlo       ; total trip distance in metres 
-  dtothi           ; dtothi/lo hold a max of 65km 536m,   
-  dtothi2      ; with this added max now 16777km  
-  dist54       ; corrects +2m every 54m (27x2.0747 =56) 
-  dm 
-  dm1000 
-  dm10000 
-  dm100000 
-   
- ;------------   Average velocity Vav    -------------------  
-   
-  ;vavhi 
-  ;vavlo 
-  ;divrat 
-  ;stemphi     ;second info passed to stemphi/lo 
-  ;stemplo     
-  ;dtemphi     ;dist info passed to dtemphi/lo    
-  ;dtemplo 
-  m 
-  m10 
-  m100 
-  m1000 
- ;---------   Time and trip time        -------------------- 
- ; 
-  sectotlo        ; total trip seconds  
-  sectothi        ; max 65536 = aprox 18hrs   
-  sec             ; seconds digit 
-  sec10           ; 10's of second digit 
-  min             ; minutes digit 
-  min10           ; 10's of minutes digit 
-  hr              ; hours digit 
-  hr10            ; 10's of hours digit 
-  oldsec          ; holds last value of sec 
-  cntmsec         ; count ms 
-  TMR18           ; TMR0 217* TMR18 18 = 1 SEC 
-   
- ;----        isr interrupt service routine push pop  ------- 
-  w_temp          ; W isr var 
-  status_temp     ; STATUS isr var 
-  fsr_temp        ; FSR isr var 
-   
-   
- ; ---------  Instantaneous Velocity  Vin  -------------------- 
-  vinhi 
-  vinlo 
-  sectemp 
-  oldtemp 
-  totmslo 
-  totmshi 
-  totms2lo 
-  totms2hi 
-  mshi 
-  mslo 
-  spdflg   ; 1st pass =0 2nd pass =1, diff is time between pulses 
-   
-    
-   
- ;--------         Miscellaneous     ------------------ 
-  temp            ; a temporary used in divide and nybble  
-  count 
-  menu 
-   
-   
-   
-        ENDC     ; end of definition block 
- ;------------------------------------------------------------------- 
-   
-            
-    ORG 0        ; start at location 0 
-    goto main    ; jump over to main routine        
-    ORG 4 
-    goto Isr     ; jump to interrupt routine 
-   
-   
- ;----------------------------------------------------------------------; 
- ;                           The Main routine                           ; 
- ;----------------------------------------------------------------------; 
-   
- ; --------       THE   MAIN MODULES    --------- 
-   
-       ;  Isr       stores elapsed TRIP time and generates hr:min:sec 
-       ;  Disptime  TRIP time, to max 99:59:59 
-       ;  Dist      Calculates total TRIP distance 
-       ;  Dispdist  TRIP distance to a max of 999km 999m 
-       ;  Velav     Average velocity, Totdist/totsecs max 99km/hr  
-       ;  Dispvav   Average TRIP speed up to  99.99 km/hr 
-       ;  Velocity  Speed   2m/(time diff of pulse2-pulse1) 
-       ;  Dispd     Speed  up to 99.99km/hr 
-         
- ; NOTE. Speed is your  calculated velocity  every second 
-         
- ; --------    more to come??? NO, running out of space         --------- 
-   
-   
- ;----------------------------------------------------------------------- 
- ;                           M A I N  
- ;----------------------------------------------------------------------- 
-   
-   
- main: 
-        call Init               ; Initialize ports, set up timer 
-        call Initlcd          ; Initialize the LCD DUMMY 
-   
-    
- Initend:     
-   
-   
- ;------------------------------------------------------------------ 
- ; Changesec Changewhlpulse wait for interrupts  newsec or newwheelpulse 
- ; ----------------------------------------------------------------- 
-   
-         clrf menu   ; initially set to 0 menu loop 
-         clrf spdflg  ; Initially = 0 2nd =  sub for time  zero  
-                          ; every new sec, set to zero  
-   
- ;              CHANGESEC  LOOPS TILL SEC CHANGES   
-     
-       ;clrw                          ;DUMMY  
-       ;xorwf sec,w              ;DUMMY  
-       ;btfsc STATUS,2       ;DUMMY  
-       ;incf sec,f               ;DUMMY  
-   
- Changesec:               ;loops checking new sec and new wheel pulse  
-      movf  oldsec, w  
-      xorwf sec,w      
-                   ; if equal, w= 0 and Z bit=1 
-     btfsc STATUS,2    ; test Z bit 
-     goto  Changesec  ; no change, loop 
-     movf  sec,w          ; sec has  increased, update 
-     movwf oldsec       ; sec and oldsec are = again  
-     incf  menu,f          ; increases menu every sec  
-                    
-   
-             ; Note1, sectotlo/hi are updated every sec in ISR module 
-             ; Note2, Decimal time also created in ISR module 
-                              ; but time display for LCD  controlled  
-                              ; the automatic menu below 
-           
-       call Disptime   ;TRIP time,  will appear on LCD top line 
-   
- Changewhp:          ; 1st detected wheelpulse starts menu sequence                  
-                                      
-       clrf PORTB 
-       bcf PORTB,5   ; start with green LED off 
- loop: 
-       btfss PORTB, 4  ;(PUT BTFSC FOR TEST); i/p hi,?DUMMY 
-       goto loop            ; not yet 
-                                  ; i/p hi detected  
-                  ;green LED flashes with every wheel pulse     
-       bsf PORTB, 5    ; LED on 
-                                 ; wait a while to make sure switch has  
-                                 ; settled    
-       movlw D'10'      ; wait about 10 msec 
-       call nmsec 
-           
-       btfsc PORTB, 4  ; will be lo (0) when finished 
-       goto $ -1            ; still low 
-                                 ; now must wait a make sure bouncing stopped 
-       movlw D'10'       ; 10 milliseconds 
-       call nmsec 
-                                 ; and check again 
-       btfsc PORTB, 4 ; if set, not finished 
-       goto $ -5            ; still hi start debounce  wait again 
- Tp1:                         ; green LED ready for next wheel pulse 
-       bcf PORTB,5        ; i.e. LED off 
-       movf PORTB,w  ; reading to clear 
-          
-    
-                                          
- ;              AUTOMATIC MENU: (LCD Top line always time)   
- ;              -------------- 
-                 ; menu s at 10sec intervals in rotation 
-                 ; Speed            menu  1 to 10 
-                 ; Dist ance       menu 11 to 20 
-                 ; Velav Avg vel menu 21 to 30  
-           
-                           ; MENU 0 TO 10 
-   
- ; as speed ( Speed) is stand alone, no sense in calculating it 
- ; if it is not going to be displayed when menu is >10. 
- ; BUT if SPEED AVERAGING IS TO BE USED,  kill off  the lines below that bypass 
- ; the SPEED calc module 
-   
- Menucheck: 
-       movlw 0x0A          ;check menu > 10  (to meet >10 AND =<20) 
-       subwf menu,w 
-       btfss STATUS,C   ;compare with 10 
-       goto $+2               ;menucount =< 10 not yet got to 11 jump to Speed 
-       goto Distblk  
-        
-       call Speed            ; Calculates instant speed,(time between pulses) 
-       movlw 0x0A         ; DUMMY, was  movlw 0xA 
-       subwf menu,w 
-       btfss STATUS,C  ;compare with 10 
-       call Spdflgcheck  ;menucount =< 10 ; also see 0-1 spdflg   
-       goto Distblk 
-   
- Spdflgcheck: 
-       clrw   
-       xorwf spdflg,w 
-       btfsc STATUS,Z 
-       call Dispd        ;menucount =< 10 AND  spdflg =1 
-       Return 
-   
- Distblk: 
-       call Dist        ;menucount  > 10 skip Dispd update Dist 
-   
-   
-                                   ; MENU 11 TO 20 
-       movlw 0x0A       ;check menu > 10  (to meet >10 AND =<20) 
-       subwf menu,w 
-       btfss STATUS,C   ;compare with 10 
-       goto $+5         ;menucount =< 10 not yet got to 11 jump to velav 
-       movlw 0x14 
-       subwf menu,w 
-       btfss STATUS,C   ;compare with 20 
-       call Dispdist    ;menucount =< 20   
-       call Velav       ;menucount  > 20 skip dispdist update  Velav 
-   
-   
-                           ; MENU 20 TO 30 
-       movlw 0x14         ;check menu > 20  (to meet >20 AND =<30) 
-       subwf menu,w 
-       btfss STATUS,C  ;compare with 20 
-       goto $+5             ;menucount =< 20 not yet got to 21 jump to NEXT 
-       movlw 0x1E 
-       subwf menu,w 
-       btfss STATUS,C  ;compare with 30 
-       call Dispvav         ;menucount =< 30  
-       movlw 0x1F        ;if it has reached 31 reset menu, before return   
-       xorwf menu,w       
-       btfss STATUS,Z    
-       goto $ +2           ; not 31 goto changewhp1 direct  
-       clrf menu           ; is 31, reset menu before changewhp1 
-   
- Menuend:  
-                                ; before changewhp jump, check that sec has not updated 
-                                ; if it has , jump back to changesec routine 
-       movf  oldsec, w  
-       xorwf sec,w          ; if equal, w= 0 and Z bit=1 
-       btfsc STATUS,2   ; test Z bit 
-       goto  Changewhp ; no sec change, check whpulse change  
-       goto  Changesec  ; a new sec starts measurements   
-    
-                                    ; loop while NOT newsec 
- ; --------------------------------------------------------------- 
- ;                          End Main 
- ; ---------------------------------------------------------------- 
-   
-      
-   
-   
-   
-   
-   
-   
- ;----------------------------------------------------------------------; 
- ; ISR, increments TMR0 by 1 every 256 ľsec. Basically just             ; 
- ; reset the INTCON and TMR0 bits. The FSR,w, STATUS push pop kept      ; 
- ;----------------------------------------------------------------------; 
- Isr: 
-             movwf w_temp             ; save W 
-             swapf STATUS,W        ; save status 
-             movwf status_temp      ; without changing flags 
-             swapf FSR,W               ; save FSR 
-             movwf fsr_temp           ; without changing flags 
-   
-                                      ;256us * 217 * 18 = 0.999936 sec.    
-                                      ;1hr_err = 0.23sec or 1 sec in 4hr 
-   
-   ;The time loop starts  with TMR0 loaded with  (256-217)=39 After 217 
-   ;steps interrupt is set, TMR0 rolls to zero and the TMR18 inc +1   
-   
-             movlw D'39'           ;39 = 0x27  
-             movwf TMR0 
-             incf  TMR18,f 
-             movlw D'18'          ; DUMMY18 = 0x12  
-             xorwf TMR18,w    ; if equal, w= 0 and Z bit=1 
-             btfss STATUS,2   ; test Z bit 
-             goto  restore        ; NOT 18 so pop stack and return to main  
- Firstsec: 
-             clrf  TMR18          ; is 18. set TMR18 to zero and INC sec             
-             incf  sec,f             ; also inc sectot (eventually lo and hi) 
-   
-             incf  sectotlo,f      ; check sectot lo 00->inc hi 
-             clrw 
-            xorwf sectotlo,w   ; if equal, w= 0 and Z bit=1 
-             btfsc STATUS,2 
-             incf sectothi,f      ; increases every 256 x sectotlo 
-    
-             movlw 0xA          ; check if =10  
-            xorwf sec,w          ; if equal, w= 0 and Z bit=1 
-            btfss STATUS,2   ; test Z bit 
-            goto  restore        ; NOT 10 so pop stack and return to main  
-   
-             clrf sec               ; is 10. set sec to zero and inc sec10 
-             incf sec10,f         
-             movlw 0x6         ; = 0x6 
-             xorwf sec10,w   ; if equal, w= 0 and Z bit=1 
-             btfss STATUS,2  ; test Z bit 
-             goto  restore      ; NOT 6 so pop stack and return to main  
-   
-   
-             clrf  sec10         ; is 6. set sec10  to zero and INC min             
-             incf  min,f 
-             movlw 0xA       ; check if =10  
-             xorwf min,w     ; if equal, w= 0 and Z bit=1 
-             btfss STATUS,2  ; test Z bit 
-             goto  restore        ; NOT 10 so pop stack and return to main  
-   
-             clrf min                ; is 10. set sec to zero and inc min10 
-             incf min10,f         
-             movlw 0x6          ;= 0x6 
-            xorwf min10,w     ; if equal, w= 0 and Z bit=1 
-            btfss STATUS,2  ; test Z bit 
-             goto  restore      ; NOT 6 so pop stack and return to main  
-   
-             clrf  min10         ; is 6. set min10  to zero and INC hr             
-             incf  hr,f 
-             movlw 0xA        ;check if =10  
-             xorwf hr,w         ; if equal, w= 0 and Z bit=1 
-             btfss STATUS,2  ; test Z bit 
-             goto  restore       ; NOT 10 so pop stack and return to main  
-   
-             clrf hr                   ; is 10. set hr to zero and inc hr10 
-             incf hr10,f         
-             movlw 0xA          ;= 10 
-             xorwf hr10,w       ; if equal, w= 0 and Z bit=1 
-            btfss STATUS,2  ; test Z bit 
-             goto  restore      ; NOT 10 so pop stack and return to main    
-   
-                               
-                               
-             clrf sec              ; is ten (99hr 59min 59sec +1sec) we are at MAX 
-             clrf sec10          ;all reset to zero and start again 
-             clrf min 
-             clrf min10 
-             clrf hr 
-             clrf hr10 
-             clrf TMR18 
-             clrf oldsec  
-             goto restore 
-   
- restore:  
-             swapf status_temp,W      ; get original status back 
-             movwf STATUS             ; into status register 
-             swapf fsr_temp,W         ; get original fsr back 
-             movwf FSR                  ; into status register 
-             swapf w_temp,f           ; old no flags trick again 
-             swapf w_temp,W         ; to restore W 
-             bcf INTCON,T0IF        ; clear the TMR0 interrupt flag 
-             retfie                           ; finished, reset GIE 
-   
- ;----------------------------------------------------------------------; 
- ;                       Initialize the ports                           ; 
- ;----------------------------------------------------------------------; 
- Init: 
-             clrf   PORTA 
-             clrf   PORTB 
-   
-             movlw B'00000000'          ;  Porta all outputs 
-             tris PORTA 
-   
-             movlw B'01010000'          ; 7o 6i-Wire 5o-LED 4i-multivib,  
-             tris PORTB                     ; 0to3lcd 
-   
-   
-             movlw B'00000111'          ;  opt pull-ups enabled                                     
-                                                      ;  opt prescaler assigned to TMR18 
-                                                      ;  opt prescaler set to 1:256 
-             option                               ;  opt rolls over each 125th second 
-                              
-   
-  movlw 0                                       ;  zero out all registers 
-   
-      
-  clrf m 
-  clrf m10 
-  clrf m100 
-  clrf m1000 
-  clrf dm 
-  clrf dm1000 
-  clrf dm10000 
-  clrf dm100000  
-   
-  clrf totmshi 
-  clrf totmslo 
-  clrf totms2hi 
-  clrf totms2lo 
-  clrf dist54 
-   
-             
-  clrf hr10 
-  clrf hr 
-  clrf min10                 
-  clrf min 
-  clrf oldsec 
-  clrf sec10 
-  clrf sec 
-  clrf sectotlo 
-  clrf dtotlo 
-  clrf dtothi 
-  clrf sectotlo 
-  clrf sectothi 
-  clrf TMR18   ; when this reaches 18, 1 sec has elapsed          
-              
-     
-             ; TMR0 has to start at 256-217 :39, so that the first rollover 
-             ; with prescaler 256, happens in 217*256us =0.055552sec 
-             ; The TMR18 incs each roll and after 18  1 sec has elapsed 
-             movlw 0x27       ; D39   
-             movwf TMR0    ; set to D39 217 counts later 256,  
-                                      ; TMR0 resets and inc TMR18 in Isr loop 
-   
-            clrf  INTCON      ; START WITH ALL AT 0 
-         
-                                   ; movlw B'10100000'          ; GIE set T0IE set, T0IF cleared 
-           movlw B'10100000' ; Set:GIE,T0IE,RBIE Clrd:T0IF,RBIF 
-           movwf INTCON      ; ready to detect interrupts in ISR 
-           return 
-   
- ;----------------------------------------------------------------------; 
- ;                 Initialize the LCD                                   ; 
- ;----------------------------------------------------------------------; 
- Initlcd: 
-   movlw D'40' 
-   call   nmsec                  ;  Wait 40 msecs before Reset 
-   bcf    RS                       ;  send an 8 bit instruction 
-   movlw  0x03                 ;  Reset Command 
-   
-   call   NybbleOut          ;  Send the Nybble 
-   call   Dlay5                  ;  Wait 5 msecs before Sending Again 
-   
-   call EStrobe 
-   call Dlay160                ;  Wait 160 usecs before Sending 2nd Time 
-   call EStrobe 
-   call Dlay160                ;  Wait 160 usecs before Sending 3rd Time 
-   bcf    RS                     ;  send an 8 bit instruction 
-   movlw  0x02               ;  Set 4 Bit Mode 
-   
-   call   NybbleOut               
-   call Dlay160 
-   movlw  0x028                  ;  4 bit, 2 Line, 5x7 font 
-   call   SendINS 
-   movlw  0x010                  ;  display shift off 
-   call   SendINS 
-   movlw  0x001                  ;  Clear the Display RAM 
-   call   SendINS 
-   call   Dlay5                      ;  Note, Can take up to 4.1 msecs 
-   movlw  0x006                  ;  increment cursor 
-   call   SendINS 
-   movlw  0x00C                 ;  display on cursor off 
-   call   SendINS 
-   return 
-   
- ;----------------------------------------------------------------------; 
- ;              Send the character in W out to the LCD                  ; 
- ;----------------------------------------------------------------------; 
- SendASCII 
-   addlw '0'                     ;  Send nbr as ASCII character 
-   
- SendCHAR:                  ;  Send the Character to the LCD 
-   movwf  temp               ;  Save the temporary Value 
-   swapf  temp, w           ;  Send the High Nybble 
-   bsf    RS                     ;  RS = 1 
-   call   NybbleOut 
-   movf   temp, w            ;  Send the Low Nybble 
-   bsf    RS 
-   call   NybbleOut 
-   return 
-   
- ;------------------------------------------------------------- 
- ;              ES strobe 
- ;------------------------------------------------------------- 
- EStrobe:                ;  Strobe the "E" Bit 
-   
-   bsf    E 
-   bcf    E 
-   return 
- ;----------------------------------------------------------------------; 
- ;              Send an instruction in W out to the LCD                 ; 
- ;----------------------------------------------------------------------; 
- SendINS:                  ;  Send the Instruction to the LCD 
-   movwf  temp           ;  Save w  
-   swapf  temp, w       ;  send Hi Nybble 
-   bcf    RS                 ;  RS to 0 
-   call   NybbleOut 
-   movf   temp, w        ;  Send Lo Nybble 
-   bcf    RS 
-   call   NybbleOut 
-   return 
-   
- ;----------------------------------------------------------------------; 
- ;              Send the nibble in W out to the LCD                     ; 
- ;----------------------------------------------------------------------; 
- NybbleOut:              ;  Send a Nybble to the LCD 
-   movwf  PORTB          
-   call EStrobe          ;  Strobe out the LCD Data 
-   bsf    E  
-   call Dlay160          ;  delay for 160 usec 
-   return 
-   
- ;----------------------------------------------------------------------; 
- ;                   Output the message on the LCD                      ; 
- ;----------------------------------------------------------------------; 
- OutMessage1: 
-   movwf  FSR                    ;  Point at first letter 
- OutLoop: 
-   movf   FSR, w                 ;  Get pointer into W 
-   incf   FSR, f                     ;  Set up for next letter 
-   call   Dispmsg1               ;  Get character to output 
-   iorlw  0                            ;  At the End of the Message? 
-   btfsc  STATUS, Z            ;  Skip if not at end 
-   return                              ;  Yes - Equal to Zero 
-   call   SendCHAR             ;  Output the ASCII Character 
-   goto   OutLoop                ;  Get the next character 
-   
- ;----------------------------------------------------------------------; 
- ;                    Data for message to be output                     ; 
- ;----------------------------------------------------------------------; 
- Dispmsg1:                         ;  Message to Output 
-   addwf  PCL, f                  ;  Output the Characters 
-   dt     "Bike Computer", 0  
-   
- Dispmsg2:                       ;  Message to Output 
-   addwf  PCL, f                 ;  Output the Characters 
-   dt     "Dist", 0   
-   
- Dispmsg3:  
-   addwf PCL,f                 ; message to output 
-   dt     " Av speed:",0      ; output characters 
-   
-  ;----------------------------------------------------------------------; 
-  ;                        time delay routines                           ; 
-  ;----------------------------------------------------------------------; 
- ;Note . The original application needed precise times  the  delay code that 
-  ; follows. But the Simple  Bike application does NOT use the routines for 
-  ; any CRITICAL time measurement. 
-   
- Dlay160:     
-   movlw D'41'                ;  delay about 160 usec 
-   
- micro4:      
-  addlw H'FF'                ;  subtract 1  'W' 
-  btfss STATUS,Z         ;  skip when you reach zero 
-  goto micro4                ;  more loops 
-  return                      
-   
- Dlay5:       
-  movlw 5                     ;  delay for 5 milliseconds      
-  goto $ + 2 
- msec250:     
-  movlw D'250'              ; delay for 250 milliseconds 
-   
-                             ; --- N millisecond delay routine --- 
- nmsec:       
-  movwf cntmsec            ; delay for N (you put in W) millisec 
- msecloop:    
-  movlw D'254'               ; load takes .9765625 microsec 
-  call micro4                  ; by itself CALL takes ... 
-                                     ; about 1ms 
-                                          
-  nop                             ; 1usec  
-  decfsz cntmsec, f       ; .98 skip not taken, else 1.95 
-  goto msecloop           ; 1.95 here: total ~1000 / loop 
-  return                         ; final time through ~999 to here 
-                                    ; overhead in and out ignored 
-   
-                                   ; this block is functional for tests, but not used in bike 
- Dlay1sec:          ; this is a marker routine to see where 
-  call msec250             ; the prg is at. 
- ; bsf  LED  
-  call msec250          ;flash led on portb pin6 
- ;bcf  LED  
-  call msec250 
- ; bsf  LED  
-  call msec250   ; finishes with green led lit 
-  return  
-   
- ;----------------------------------------------------------------------; 
- ;                       Display the Time                               ; 
- ;----------------------------------------------------------------------; 
- Disptime: 
-     
-  movlw H'80'        ;  position at beginning of first line 
-  call SendINS 
-  movf hr10, W      ;  tens of hours 
-  call SendASCII 
-  movf hr, W          ;  hours 
-  call SendASCII 
-  movlw ":"          
-  call SendCHAR 
-  movf min10, W    ;  tens of minutes 
-  call SendASCII 
-  movf min, W        ;  minutes 
-  call SendASCII 
-  movlw ":" 
-  call SendCHAR 
-  movf sec10, W    ;  tens of seconds 
-  call SendASCII 
-  movf sec, W       ;  seconds 
-  call SendASCII 
-  movlw " " 
-  call SendCHAR   ; the h m s really not needed 
-  movlw "h" 
-  call SendCHAR 
-  movlw "m" 
-  call SendCHAR 
-  movlw "s" 
-  call SendCHAR 
-  movlw " " 
-  call SendCHAR 
-   
- Dispend: 
-               RETURN 
-   
- ;---------------------------------------------------- 
- ;               End of display time 
- ;---------------------------------------------------- 
-   
-   
- ;----------------------------------------------------------------------; 
- ;                    Display the Distance , (trip distance at moment)                               ; 
- ;----------------------------------------------------------------------; 
- Dispdist:        
-  movlw H'C0'       ;  position at beginning of second line 
-  call SendINS 
-   
-  movf dm100000, W     ;  0 of 065km 536m 
-  call SendASCII 
-   
-  movf dm10000, W      ;  6 of 065km 536m 
-  call SendASCII 
-   
-   
-  movf dm1000, W       ;  5 of 065km 536m 
-  call SendASCII 
-   
-  movlw "k"                 ;  k of 065km 536m 
-  call SendCHAR 
-  movlw "m"                ;  m of 065km 536m 
-  call SendCHAR 
-  movlw " "                  ;  " " of 065km 536m 
-  call SendCHAR 
-   
-  movf  dm100- ,W         ;   5-  of 065km 536m 
-  call SendASCII 
-   
-  movf  dm10- ,W          ;   3-  of 065km 536m 
-  call SendASCII 
-  movf dm, W             ;  6 of 065km 536m 
-  call SendASCII 
-               
-  movlw "m"               ;  m of 065km 536m     
-  call SendCHAR 
-   
-  movlw " "                 ; " "   
-  call SendCHAR 
-  movlw "D"               ; "D "   
-  call SendCHAR 
-  movlw "i"                ; " i"   
-  call SendCHAR 
-  movlw "s"               ; "s "   
-  call SendCHAR 
-  movlw "t"                ; " t"   
-  call SendCHAR 
-  movlw " "               ; " " ( to wipe screen)  
-  call SendCHAR   
-   
- Distend: 
-               RETURN 
-   
-    
- ;  
- ;---------------------------------------------------------------------* 
- ;                Multiplication  16x16 Out32 
- ;---------------------------------------------------------------------* 
- Mult16x16:  
-         clrf mq4 
-         clrf mq3 
-         clrf mq2 
-         clrf mq1 
-   
-    
-         bsf mq2, 7 
- Mu1: 
-         rrf mah, f 
-         rrf mal, f 
-         skpc 
-         goto Mu2 
-         movf mbl, w 
-         addwf mq3, f 
-         movf mbh, w 
-         skpnc 
-         incfsz mbh, w 
-         addwf mq4, f 
- Mu2: 
-         rrf mq4, f 
-         rrf mq3, f 
-         rrf mq2, f 
-         rrf mq1, f 
-         skpc 
-         goto Mu1 
-   
- Endmult16: 
-       clrf mbh 
-       clrf mbl 
-       clrf mah 
-       clrf mal 
-   
-         Return 
-   
-   
-          
-   
- ;---------------------------------------------------------------------* 
- ;            End Multiplication   16x16 Out32 
- ;---------------------------------------------------------------------* 
-   
- ;---------------------------------------------------------------------* 
- ;       New routine Division  16/16 Out 16 
- ; ---------------------------------------------------------------------* 
- ; Finally:- Result 000AH in reshi/lo, remainder 0096H in rmdrhi/lo 
- ; so, checking end of division A=10 and 96H/E1H= 150/225 =0.666  OK 
-   
- Div:  
-        call    D_divS          ; remainder in Rmdr. 
- Divend: 
-           nop 
-           return 
- D_divS: 
-         call    setup 
-         clrf    rmdrhi 
-         clrf    rmdrlo 
- dloop: 
-       bcf     STATUS,C 
-         rlf     reslo, f 
-         rlf     reshi, f 
-         rlf     rmdrlo, f 
-         rlf     rmdrhi, f 
-         movf    denhi,w 
-         subwf   rmdrhi,w      ;check if a>c 
-         btfss   STATUS,Z 
-         goto    nochk 
-         movf    denlo,w 
-         subwf   rmdrlo,w      ;if msb equal then check lsb 
- nochk: 
-         btfss   STATUS,C    ;carry set if c>a 
-         goto    nogo 
-         movf    denlo,w        ;c-a into c 
-         subwf   rmdrlo, f 
-         btfss   STATUS,C 
-         decf    rmdrhi, f 
-         movf    denhi,w 
-         subwf   rmdrhi, f 
-         bsf     STATUS,C    ;shift a 1 into b (result) 
- nogo: 
-                 rlf     numlo,f 
-         rlf     numhi,f 
-         decfsz  temp, f        ;loop untill all bits checked 
-         goto    dloop 
-   
- setup: 
-                 movlw   .16             ; for 16 shifts 
-         movwf   temp 
-         movf    numhi,w      ;move Num to Res 
-         movwf   reshi 
-         movf    numlo,w 
-         movwf   reslo 
-         clrf    numhi 
-         clrf    numlo 
-         retlw   0 
-    
-  ;--------------------------End Div 16 by 16---------------------------- 
-   
-   
-   
-         return 
-          
- ;---------------------------------------------------------------------* 
- ; END DIVISION  16/16 OUT 16 
- ;--------------------------------------------------------------- 
-   
- ;---------------------------------------------------------------------* 
- ; START Addition  16-16 OUT 16 
- ;--------------------------------------------------------------- 
- Add:  ; R = q1 + q2 
-   
-         movf q1lo, W 
-         addwf q2lo, W 
-         movwf rlo 
-   
-         movf q1hi, W 
-         btfsc STATUS, C 
-         addlw .1                ; If A Carry Occurred, Add 1 
-   
-         addwf q2hi, W 
-         movwf rhi 
-         ;clrf q1hi                  ; added this to stop next user summing; 
-         ;clrf q1lo 
-         ;clrf q2hi 
-         ;clrf q2lo 
-          
-         Return 
-   
- ;---------------------------------------------------------------------* 
- ; END Addition  16-16 OUT 16 
- ;--------------------------------------------------------------- 
-   
-   
-   
- ;---------------------------------------------------------------------* 
- ; START Subtraction  16-16 OUT 16 
- ;--------------------------------------------------------------- 
-   
-   
- Sub:    ; R = q1 - q2 
-   
-         movf q2lo, W 
-         subwf q1lo, W   ; W = q1lo - q2lo 
-         movwf rlo 
-   
-         btfss STATUS, C 
-         Goto Borrow 
-         Goto Sub1 
- Borrow: 
-         Decf q1hi, F 
-          
- Sub1: 
-         movf q2hi, W 
-         subwf q1hi, W   ; W = q1hi - q2hi 
-         movwf rhi 
-   
-         Return 
-   
- ;--------------------------------------------------------------- 
- ; END Subtraction  16-16 OUT 16 
- ;--------------------------------------------------------------- 
-   
-   
-   
-   
-   
-   
- ;--------------------------------------------------------------- 
- ;                 Dist = counting wheel pulses  
- ;--------------------------------------------------------------- 
-   
- Dist:                ; whlcirc = 2.0747, for initial test =2 
-                       ;   
-                       ; movlw 0x2          ; <-- don't forget, this is just for 26"wheel 
-                       ; movwf whlcirc  ; start count at 0 and inc till same as whlcirc 
-                       ; (range will be 1 to 4 m) 
-     
-          clrf count     ;  count can be 2 or 4 in this 26" case 
-   
- Whloop:            ; although the distance pulses ( in this example) jump in steps of 2m 
-                          ; the m counter has to increase in 1's to catch the 
-                  ; decimal rollover  10 to 0  
-                          ; so count, here, is stepped  0 to 2 (whlcirc) 
-                          ; Also, when the dist54 var increases 54m, COUNT adds an  extra 2m   
-                          ; to the hex and decimal totals, before resetting to zero. 
-                 ; Note that as dist54 is in the loop it will also receive  
-                  ; the 2m increase so it  really  counts to 56 (54 +2). 
-    
-   
-        movlw 0x2               ; wheel circumference  of 26 inch 
-        xorwf count,w          ; if equal, w= 0 and Z bit=1 
-        btfsc STATUS,2      ; test Z bit 
-        goto DistanceEnd    ; they are the same, so jump distanceEnd and return   
-        goto Mcount            ; NOT  yet = whlcirc, so inc mcount by 1 and  return   
-   
- Mcount:       ; Distance to decimal for display , i/p m, o/p 000km 000m  
-             ; starts  with m, m10, m100, m1000 , m10000, m100000 = 0 
-             ; Later correct m every 54m (add 2m ???? ) 
-   
-       incf dm,f  
-       movlw D'10'       
-       xorwf dm,w           ; if equal, w= 0 and Z bit=1 
-       btfss STATUS,2   ; test Z bit 
-       goto Mcountend   ; NOT 0 so return 
-   
-       clrf dm  
-       movlw D'10'      
-       xorwf  dm10- ,w      ;  if-  equal, w=  0-  and Z bit= 1
-       btfss STATUS,2   ; test Z bit 
-       goto Mcountend   ; NOT 0 so return 
-   
-       movlw D'10'       
-       xorwf  dm100- ,w     ;  if-  equal, w=  0-  and Z bit= 1
-       btfss STATUS,2   ; test Z bit 
-       goto Mcountend   ; NOT 0 so return 
-   
-     incf dm1000,f  
-       movlw D'10'          
-       xorwf dm1000,w    ; if equal, w= 0 and Z bit=1 
-       btfss STATUS,2   ; test Z bit 
-       goto Mcountend   ; NOT 0 so return 
-   
-       clrf dm1000 
-       incf dm10000,f  
-       movlw D'10'        
-       xorwf dm10000,w   ; if equal, w= 0 and Z bit=1 
-       btfss STATUS,2   ; test Z bit 
-       goto Mcountend   ; NOT 0 so return  
-        
-       clrf dm10000 
-       incf dm100000,f  
-       movlw D'10'          
-       xorwf dm100000,w  ; if equal, w= 0 and Z bit=1 
-       btfss STATUS,2      ; test Z bit 
-       goto Mcountend      ; NOT 0 so return  
-       clrf dm                     ; is distmax, reset to 0       
-       clrf dm1000 
-       clrf dm10000  
-       clrf dm100000 
-   
-       goto Mcountend  ; see if whpl  update is now finished 
-   
-   
-   
-           
- Mcountend:  ;update the hex counters dtot /lo/hi/hi2 
-       incf dtotlo,f 
-       clrw  
-       xorwf dtotlo,w       ; if equal, w= 0 and Z bit=1 
-       btfss STATUS,2   ; test Z bit 
-       goto Dtotend        ; dtotlo NOT 0  
-       incf dtothi,f           ; add 1, dtotlo is 0  
-       clrw 
-       xorwf dtothi,w      ; if equal, w= 0 and Z bit=1 
-       btfss STATUS,2   ; test Z bit 
-       goto Dtotend        ; dtothi NOT 0  
-       incf dtothi2,f         ; add 1, dtothi is 0  
-   
- Dtotend: 
-       movlw D'54' 
-       movwf numhi       ; not in use here, use to store 54 
-       movf  dist54,w                       
-       subwf numhi,w 
-       btfsc STATUS,C       
-       goto  Noextra      ; dist54=< 53, don't freeze COUNT 
-       movlw D'56'        ; dist54>53   add 2 extra counts 
-       movwf numhi      ; not in use here to store 56 
-       movf  dist54,w                       
-       subwf numhi,w 
-       btfsc STATUS,C               
-       goto  Extra          ; dist54=< 56, freeze COUNT 
-       clrf dist54 
-       goto Noextra 
-   
-   
-   
- Noextra: 
-      incf dist54,f 
-      incf count,f  
-     goto Whloop  
-   
- Extra:                          ; an extra loop BUT count is NOT increased  
-     incf dist54,f  
-    goto Whloop      
-   
- DistanceEnd:  ;  All conversion loops have executed and  
-                        ; only left to display in decimal, when ed 
-                   ;   
-         
-   return          ; BACK TO MAIN 
-   
-   
- ;-------------------------------------------------------------------------- 
- ;              End of Trip  Distance calculation Module 
- ;-------------------------------------------------------------------------- 
-   
-   
- ;----------------------------------------------------------    
- ;     Calculate Average velocity  Velav = totdist/totsec                     
- ;----------------------------------------------------------- 
- ; 1st time round distto = 0 and sectot =0. 
- ; Disttot lo/hi zero is prob OKbut test sec=0. If zero return 
- Velav:  
-   
-           
-      clrw 
-      xorwf sectotlo,w 
-      btfss STATUS,Z 
-      goto  Spdstart     ; not 0, onto Avspeed calc 
-      clrw                ; lo was 0, but hi byte may not be  
-      xorwf sectothi,w 
-      btfss STATUS,Z      
-      goto  Spdstart     ; was not 0, onto Avspeed calc 
-       ;incf  sectotlo,f   ; DUMMY 
-       ;goto  Spdstart   ; DUMMY 
-       return             ; was also 0, abort module  wait for sec inc 
-   
-                 ; to slow down the number of whpul in the test we add Dummies    
- Spdstart:                 ; for test delay incf sec and sectot, gives 7.2km/hr 
-               
-        
-       ;incf  sec,f        ; DUMMY 
-       ;incf sectotlo,f      ; DUMMY  
-    
-   
- ;Lpstart:  
-       movlw 0x07                 ; 1800   comp hi bytes 
-       subwf dtothi,w 
-       btfsc STATUS,C       
-       goto  Divratio      ;  dtothi is > 1800hi and needs dividing 
-                          ;  we suppose that the hibyte test is sufficient, 
-                  ;  it may not be true. e.g hi's the same but lo's diff 
-                                 ;  pass dtot to m1000,m100 
-     movf dtothi,w        ; dtothi <1800 
-     movwf m1000 
-     movf dtotlo,w 
-     movwf m100         ; m1000,m100 hold dtothi/lo ( no div needed) 
-     movf  sectothi,w     
-     movwf m10 
-     movf sectotlo,w 
-     movwf m             ; m10,m hold sectothi/lo ( no div needed)    
-   
-                        ; note, this is dtot to m1000,m100 not needing division 
-     goto  Ratend       ; if divratio is needed, then m1000,m100 is used there  
-   
- Divratio:                   ; enter variables and 1800 
-   
-       movf  dtothi,w 
-       movwf numhi  
-       movf  dtotlo,w 
-       movwf numlo 
-       movlw 0x07 
-       movwf denhi 
-       movlw 0x08 
-       movwf denlo 
-       call  Div 
-       incf  reslo,w    ; reslo holds INT of Divratio +1 
-       movwf count   ; not used at the moment  
-       movf  dtothi,w ; divide dtothi/lo by count 
-       movwf numhi  
-       movf  dtotlo,w 
-       movwf numlo 
-       clrf  denhi  
-       movf  count,w  ; e.g. D 37 
-       movwf denlo 
-       call  Div          ; we need parking space for results, REuse the m1000 etc 
-       movf  reshi,w    
-       movwf m1000 ;  
-       movf  reslo,w 
-       movwf m100   ; m1000, m100 =dtot/count 
-                             ; repeat for sectot 
-       movf  sectothi,w 
-       movwf numhi  
-       movf  sectotlo,w 
-       movwf numlo 
-       clrf  denhi  
-       movf  count,w    ; e.g D 37 
-       movwf denlo 
-       call  Div 
-       movf  reshi,w 
-       movwf m10   
-       movf  reslo,w 
-       movwf m         ; m10, m =sectot/count 
- Ratend: 
-   
-  ;    WE CAN NOW DO DTOT/SECTOT x3.6  as we have SCALED TO AVOID OVERFLOW 
-   
-  ;                m1000,m100   x 36   (top line) 
-  ;     Vav=   -------------------------                      = Average speed in km/hr 
-   
-  ;               m10,m        x 10   (bottom line)         ;     36(24H), 10(AH)  
-   
-   
-   
-       movf m1000,w     ; MULT dtot, top line,  by 24H 
-       movwf mah 
-       movf m100,w 
-       movwf mal 
-       clrf  mbh 
-       movlw 0x24 
-       movwf mbl 
-       call  Mult16x16  ; ( store top line result in the same variables) 
-       movf  mq2,w 
-       movwf m1000  
-       movf  mq1,w 
-       movwf m100    ;  dtot x 36 
-   
-      movf m10,w      ; MULT sectot, bottom line,  by AH 
-      movwf mah 
-      movf m,w 
-      movwf mal 
-       clrf  mbh 
-       movlw 0xA 
-       movwf mbl 
-       call  Mult16x16 ; ( store bottom line result in the same variables) 
-       movf  mq2,w 
-       movwf m10  
-       movf  mq1,w 
-       movwf m         ;  sectot x 10 
- Tp3: 
-   
-        ; As we are reusing variables, trying to show where the results to here are being held 
-  ;                                      m1000,m100       
-  ;   We now have as  Average speed     ----- ---------       km/hr 
-  ;                                                              m10,m 
-   
-   
-    ;the AVERAGE SPEED AT LAST 
-   
-       movf  m1000,w  ; dtotx36/sectotx10 
-       movwf numhi  
-       movf  m100,w   
-       movwf numlo 
-       movf  m10,w 
-       movwf denhi    ; needed below for decimal place 
-      movf  m,w 
-      movwf denlo    ; needed below for decimal place  
-      call  Div 
-                              ; denhi/lo can chanfge as the div routine reuses bits 
-                     ; so we reestablish previous denom values before losing 
-     movf  m10,w 
-     movwf denhi 
-     movf  m,w 
-     movwf denlo   ; we can now write over m and m10   
-                          
-     movf  reshi,w  ;will be zero 
-                    ;(bikes don't exceed 256km/hr normally)  
-     movf  reslo,w  ; reuse variables m10 INT and later m FRAC 
-     movwf m10     ;we have integer part of Vav Average speed 
-                      
-     
-   
-                          ; rmdrhi/lo holds decimal fraction.we will only use 1 decimal place.   
-                 ; so mult the rmdrhi,lo x10  before dividing by denhi/lo 
-         
-   
-   movf  rmdrhi,w     ; mult top by 10  
-   movwf mah 
-   movf  rmdrlo,w 
-   movwf mal           ; rmdr in tot storage 
-   clrf  mbh 
-   movlw 0xA 
-   movwf mbl 
-   call  Mult16x16  ; rmdrhi,lo x 10 
-                             ; top line is now  mq2,mq1 ( nothing in mq4,mq3)   
-                             ; Bottom line..remember we already have loaded 
-                            ; the denominator above which says   
-                             ; " needed below for decimal place"   
- Tp4: 
- movf mq2,w       ;rmdrhi,w       
-     movwf numhi 
-     movf  mq1,w        ;rmdrlo,w      
-     movwf numlo        
-     call Div                ; div for the decimal( just 1 place), in reslo 
-                 ; reshi,reslo holds decimal place results 
-                                 ; m10+m are  av speed as INT+DEC but in hex 
-                                ; now change to decimal. 
-                                ; m10 and m are going to be wiped, but there is no 
-                                ;divide routine so for INT +FRAC we use reshi reslo  
-       movf  m10,w 
-       movwf reshi      ; OK? yes reshi +reslo = INT+FRAC in hex, convert          
-          
-   
- Vavh2d: 
-   
-      clrf m 
-      clrf m10 
-     clrf count 
-   
- Vavloh2d:                ; m is 2nd dec, use m10 
-        movf  count,w 
-        xorwf reslo,w  
-        btfsc STATUS,Z  
-        goto  Vavloend                 
-        incf  count,f 
-          incf  m10,f 
-        movlw 0xA          
-        xorwf m10,w 
-        btfss STATUS,Z 
-        goto Vavloh2d 
-        clrf m10 
-        incf m,f 
-        goto Vavloh2d 
-   
- Vavloend: 
-   
-       clrf m100 
-       clrf m1000 
-       clrf count 
-   
- Vavhih2d: 
-        movf  count,w 
-        xorwf reshi,w 
-        btfsc STATUS,Z 
-        goto  Vavhiend                  
-        incf  count,f 
-        incf  m100,f 
-        movlw 0xA          
-        xorwf m100,w 
-        btfss STATUS,Z 
-        goto Vavhih2d 
-        clrf m100 
-        incf m1000,f 
-        goto Vavhih2d 
-   
- Vavhiend:                 ; We have Vav as: INT m1000,m100 and FRAC  m10,m with Frac 
-         
-         
-   
- Vavend: 
-          nop 
-          return 
-   
-   
- ;----------------------------------------------------------------------; 
- ;                    Display the Average velocity                               ; 
- ;----------------------------------------------------------------------; 
- Dispvav: 
-          
-  movlw H'C0'       ;  position at beginning of second line 
-  call SendINS 
-   
-   
-   
-  movf m1000, W     ;    x0 tens of km 
-  call SendASCII 
-    
-   
-  movf m100,W         ;   0x ones of km 
-  call SendASCII 
-   
-  movlw "."                 ;  "." punto decimal   
-  call SendCHAR 
-   
-  movf m10,W             ;  "0.x0" decimal 
-  call SendASCII 
-  movf m, W              ;  "0.0x" decimal 
-  call SendASCII 
-               
-  movlw "k"                   ;  k   
-  call SendCHAR 
-  movlw "m"                 ;  m   
-  call SendCHAR 
-   
-  movlw "/"                   ;  / 
-  call SendCHAR 
-   
-  movlw "h"                  ;  h 
-  call SendCHAR 
-  movlw "r"                   ;  r 
-  call SendCHAR 
-   
-  movlw " "                   ;  " " 
-  call SendCHAR 
-   
-  movlw "V"                ;  V 
-  call SendCHAR 
-  movlw "e"                  ;  e 
-  call SendCHAR  
-   
-  movlw "l"                  ;  l 
-  call SendCHAR 
-  movlw "A"                 ;  A 
-  call SendCHAR 
-   
-   
-  movlw "v"                 ;  v 
-  call SendCHAR 
-  movlw "g"                 ;  g 
-  call SendCHAR  
-  movlw " "                   ;  " " 
-  call SendCHAR 
-    
-   
- Dispvavend: 
-                 
-   Return                    ; to change seconds for next second 
-        
- ;--------------END OF AV SPEED------------------- 
-   
-   
-   
-   
-   
-   
-   
-     
-   
-   
- ; ---------------------------------------------------------------        
- ;                   Instantaneous Speed   
- ;-----------------------------------------------------------------        
-  ;  Previous time values  are subtracted    the present 
-  ;  sec, TMR18, TMR0 values.  
-  ;  This time difference is the time between 
-  ; wheel pulses. This in turn for 26" wheel is a distance of 2.0747m 
-  ; is covered in totms 
- ; ---------------------------------------------------------------        
- ;                   Instantaneous Speed   
- ;-----------------------------------------------------------------        
- ; Note sec can only move between  0 and 9, 10 is a new 0  
- ; We start by reading sec, TMR18, TMR0 TO GET START TIME 
-   
- Speed: 
-   
-                          
- Spdflg0:                  ; FIRST TIMEwith spdflg=0, second time with spdflg=1 
-                               ; First time captures timezero 0 in ms in totms 
-         clrw 
-         xorwf spdflg,w 
-         btfss STATUS ,Z 
-         goto Spdflg1    ; spdflg is not 0, this is the second time 
-       call Summs 
-       movf  mshi,w 
-       movwf totmshi   
-       movf  mslo,w 
-       movwf totmslo 
-       incf spdflg,f  ; (spdflg = 1 for  SECOND TIME) 
-       return   ;jump back to main menu 
-        
- Summs:   ; this routine is common to the first and second time 
-       movf sec,w     ; spdflg = 0 
-       movwf mbl      ; sec can only be in range 0 to 9  
-       clrf  mbh 
-       movlw 0x03                ; 1000 = 03E8 
-       movwf mah   
-       movlw 0xE8                ; 1000 = 03E8 
-       movwf mal   
-         call  Mult16x16 ;  
-       movf  mq2,w    ; hi byte 
-       movwf mshi  
-       movf  mq1,w    ; lo byte 
-       movwf mslo 
-        
-         movf  TMR18,w 
-         movwf mal 
-         clrf  mah  
-       movlw D'56' 
-       movwf mbl 
-       clrf  mbh 
-         call  Mult16x16 ;  after themult we add 
-         movf  mshi,w 
-         movwf q1hi      
-         movf  mslo,w 
-         movwf q1lo     
-         movf  mq2,w 
-         movwf q2hi      
-         movf  mq1,w 
-         movwf q2lo     
-         call  Add 
-         movf  rhi,w 
-         movwf mshi 
-         movf  rlo,w 
-         movwf mslo   ; sum  (sec +TMR18) 
-                          ;TMR0 is a little more complex as we have to subtract39 
-                          ; before we can calculate ms in TMR0 
-         movf  TMR0,w 
-         movwf q1lo 
-         clrf  q1hi  
-         movlw  D'39' 
-         movwf q2lo 
-         clrf q2hi 
-         call Sub 
-         movf rlo, w 
-         movwf numlo 
-         clrf  numhi 
-         movlw 0x4 
-         movwf denlo 
-         clrf  denhi 
-         call  Div 
-   
-         movf  mshi,w 
-         movwf q1hi      
-         movf  mslo,w 
-         movwf q1lo     
-         movf  reshi,w 
-         movwf q2hi      
-         movf  reslo,w 
-         movwf q2lo     
-         call  Add    
-         movf  rhi,w 
-         movwf mshi 
-         movf  rlo,w 
-         movwf mslo ;   ( SEC +TMR18+ TMR0) in ms mshi/lo 
-   
-         RETURN     ; Summs 
- Summsend: 
-   
-   
-   
-   
- Spdflg1: ; SECOND TIME is with spdflg =1 
-                          ; Second time captures timezero to  2nd Pulse  
-                      ; in ms, store  in totms2 
-                      ; for test we add 250ms to simulate time between 
-                      ; wheel pulses 
-                      ; 250ms delay 
-       ;movlw D'63'   ; DUMMY FOR TEST 
-       ;call nmsec     ; DUMMY FOR TEST              
-   
-         call Summs 
-   
-       movf  mshi,w   ;  
-       movwf totms2hi ;   
-       movf  mslo,w    ;   
-       movwf totms2lo  ;  
-   
-   
- ; totms2 should be larger than totms,however if totms2 has just rolled, 
- ; then add 10000 to tot2  
-   
- Testtot2: 
-        movf  totms2hi,w 
-        subwf totmshi,w 
-        btfss STATUS,C   ;compare for greater 
-        goto  Diffms     ;totms2 > totms  no add 10000 needed 
-        movlw 0xA        ;totms2 < totms, add 10000, hex 2710 
-          movlw 0x27 
-        movwf q1hi 
-          movlw 0x10 
-        movwf q1lo  
-        movf totms2hi,w 
-          movwf q2hi    
-        movf totms2lo,w 
-          movwf q2lo 
-        call  Add     ; tot2 +10000 
-          movf  rhi,w 
-        movwf totms2hi 
-          movf  rlo,w 
-        movwf totms2lo  ; tot2 = tot2+10000 
-   
-   
-                 
- Diffms:  
-   
-   
-      ; sub  (tot2-tot1)for time between wheel pulses 
-   
-         movf   totms2hi,w  ; 
-       movwf  q1hi   
-         movf   totms2lo,w 
-       movwf  q1lo       
-   
-         movf   totmshi,w 
-       movwf  q2hi   
-         movf   totmslo,w 
-       movwf  q2lo      
-       call   Sub  ; result is  time diff, stored in rhi, rlo 
- tp2: 
-    ; we are almost ready to divide dist/time for speed 
-    ; complete equation is dist/time x3.6 
-    ; to avoid as far as possible fractions we multiply before divide 
-    ; but this time, better divide first. 
-   
-    ; 2000            36        <--- this is more than 65536 
-    ; ----       x    -------- 
-    ; denhi/lo         10    ( denhi/lo is sub result rhi/lo) 
-   
-    ; so we can divide by 10 and x by 36 ( always,) 
-    ; so top  line is simply 7200. 
-    ; we finally have 7200/(denhi/lo) , SPEED IN HEX 
-   
-   
-       movf   rhi,w 
-         movwf  denhi 
-       movf   rlo,w 
-         movwf  denlo  ; denom is time in hex 
-       movlw  0x1C   ; 7200, hex 1C20 
-       movwf  numhi 
-       movlw  0x20   ; 7200, hex 1C20 
-       movwf  numlo  
-         call Div  
-                     ; the result , res, is  more than 1  
-                         ;and a remainder rmdr/den 
-                     ;we now have 6 free variables 
-                     ; mshi/lo  for INT hex speed lo is enough 
-                         ; totmshi/lo 
-                         ; totms2hi/lo     
-                     ;we will reuse to convert  hex to decimal 
-   
-         movf  reslo,w  
-       movwf mshi   ; INT part of hex speed ( hi, because FRAC will be in lo) 
-   
-                     ;we will only use 1 decimal of  
-                         ;the hex speed remainder, so 1st  rmdrx10   
-                     ;  so next calculation is 
-   
-                           ; 10 x rmdrhi/lo 
-                     ; --------------- 
-                       ; denhi/lo  
-   
-       movf rmdrhi,w 
-       movwf mah 
-       movf rmdrlo,w 
-       movwf mal 
-         clrf  mbh 
-         movlw 0x0A 
-         movwf mbl 
-       call  Mult16x16  ;( ten times top)   
-       movf  mq2,w 
-       movwf numhi  
-       movf  mq1,w 
-       movwf numlo  ; the den is previously loaded so divide for  
-                    ; decimal part of speed ( still in hex) 
-         call  Div    ; we only use 1 decimal, so just use lo of Div result 
-       movf  reslo,w 
-       movwf mslo    ; FRAC  of speed in hex 
-                    ; now convert speed to decimal form 
-                    ; i.e. mshi, mslo --> 99.9 km/hr 
-   
- Spdh2d: 
-   
-         clrf m 
-         clrf m10 
-         clrf m100 
-         clrf m1000 
-         clrf count 
-   
-   
- Spdlo: 
-        movf  count,w 
-        xorwf mslo,w  
-        btfsc STATUS,Z  
-        goto  Spdhicnt                 
-        incf  count,f 
-          incf  m10,f 
-        movlw 0xA          
-        xorwf m10,w 
-        btfss STATUS,Z 
-        goto Spdlo  
-        clrf m10 
-        incf m,f 
-        goto Spdlo  
-   
- Spdhicnt: 
-         clrf m100     
-         clrf m1000 
-         clrf count 
-   
- Spdhi: 
-        movf  count,w 
-        xorwf mshi,w 
-        btfsc STATUS,Z 
-        goto  Spdhiend                  
-        incf  count,f 
-          incf  m100,f 
-        movlw 0xA          
-        xorwf m100,w 
-        btfss STATUS,Z 
-        goto Spdhi  
-        clrf m100 
-        incf m1000,f 
-        goto Spdhi  
-   
- Spdhiend:; We have filled m1000,m100 with INT and m10,m with Frac, of Vin. 
-          ; Note we only need m10 ( 1 decimal place) 
-       clrf spdflg ; reset to 0 for next pair of pulses 
-   
-   
-   
-   
-   
-   
-   
-      ; incf spdflg,f  ; (spdflg = 1 for  SECOND TIME) 
-   
-         return 
- ; ---------------------------------------------------------------** 
- ;                         End of Instantaneous Speed 
- ; ---------------------------------------------------------------**  
-   
-   
-   
- Dispd: 
- ;----------------------------------------------------------------------; 
- ;                    Display the Instantaneous Speed (Speed)                               ; 
- ;----------------------------------------------------------------------; 
-          
-  movlw H'C0'       ;  position at beginning of second line 
-  call SendINS 
-   
-   
-   
-  movf m1000, W     ;    x0 tens of km 
-  call SendASCII 
-    
-   
-  movf m100,W         ;   0x ones of km 
-  call SendASCII 
-   
-  movlw "."         ;  "." punto decimal   
-  call SendCHAR 
-   
-  movf m10,W     ;  "0.x0" decimal 
-  call SendASCII 
-  movf m, W      ;  "0.0x" decimal 
-  call SendASCII 
-               
-  movlw "k"         ;  k   
-  call SendCHAR 
-  movlw "m"         ;  m   
-  call SendCHAR 
-   
-  movlw "/"         ;  / 
-  call SendCHAR 
-   
-  movlw "h"         ;  h 
-  call SendCHAR 
-  movlw "r"         ;  r 
-  call SendCHAR 
-   
-   
-  movlw " "         ;  " " 
-  call SendCHAR 
-   
-  movlw "S"         ;  S 
-  call SendCHAR 
-  movlw "p"         ;  p 
-  call SendCHAR  
-   
-  movlw "e"         ;  e 
-  call SendCHAR 
-  movlw "e"         ;  e 
-  call SendCHAR 
-   
-   
-  movlw "d"         ;  d 
-  call SendCHAR 
-    
- Dispdend: 
-                 
-   Return    ; to change seconds for next second 
-        
- ;--------------END OF Inst SPEED------------------- 
-   
-      end  
- ;----------------------------------------------------- 
- ;             bike computer program end  ....enjoy 
- ;----------------------------------------------------- 
-   
-   
-   
- ;                    WORK IN HAND 
-   
- ; CLEAN UP  SPEED,  readout still a little jumpy,  
- ; can try integrating but need more space. Next version 
-   
- ;           Coventions used in the program text.  
-  ;Variables all small letters , exceptions, those defined  
-  ; by microchip. e.g. STATUS 
-  ;Labels: First letter always a Capital, exceptions imported 
-  ; routines 
-  ; Test points. These have  a comment DUMMY, the value of the code 
-  ; has/had been changed for testing or simulating.  If YOU want  
-  ;to polish  these points should be useful for value changes 
-  ; example. In ISR the D'18' value to reach a sec is very slow. 
-  ;Use for test , say 2, and you get going about 10 times  faster. 
-  ;Also LCD INIT: can be bypassed to debug quicker 
-   
-   
- ;------------------------------------------------------------------------ 
- ;                   End of the Simple Bike Computer 
- ;------------------------------------------------------------------------