
; CC5X Version 3.1I, Copyright (c) B Knudsen Data
; C compiler for the PICmicro family
; ************  18. Mar 2006  14:45  *************

	processor  16F877
	radix  DEC

INDF        EQU   0x00
PCL         EQU   0x02
STATUS      EQU   0x03
FSR         EQU   0x04
PORTA       EQU   0x05
TRISA       EQU   0x85
PORTB       EQU   0x06
TRISB       EQU   0x86
PCLATH      EQU   0x0A
Carry       EQU   0
Zero_       EQU   2
RP0         EQU   5
RP1         EQU   6
IRP         EQU   7
GIE         EQU   7
PORTC       EQU   0x07
PORTD       EQU   0x08
PORTE       EQU   0x09
TMR1H       EQU   0x0F
T1CON       EQU   0x10
RCSTA       EQU   0x18
TXREG       EQU   0x19
RCREG       EQU   0x1A
TRISC       EQU   0x87
TRISD       EQU   0x88
TRISE       EQU   0x89
TXSTA       EQU   0x98
SPBRG       EQU   0x99
ADCON1      EQU   0x9F
EEDATA      EQU   0x10C
EEADR       EQU   0x10D
EEDATH      EQU   0x10E
EEADRH      EQU   0x10F
EECON2      EQU   0x18D
PEIE        EQU   6
TMR1IF      EQU   0
TXIF        EQU   4
RCIF        EQU   5
EEIF        EQU   4
CREN        EQU   4
TMR1IE      EQU   0
RCIE        EQU   5
RD          EQU   0
WR          EQU   1
WREN        EQU   2
EEPGD       EQU   7
RX_In       EQU   0x3B
satellites_in_view EQU   0x40
gps_hours   EQU   0x42
gps_minutes EQU   0x43
gps_seconds EQU   0x44
gps_ampm    EQU   1
local_hour  EQU   0x45
pure_gps_hours EQU   0x46
high_hours  EQU   0x47
low_hours   EQU   0x48
high_minutes EQU   0x49
low_minutes EQU   0x4A
high_seconds EQU   0x4B
low_seconds EQU   0x4C
rt_seconds  EQU   0x4D
s1_save     EQU   0x70
s2          EQU   0x20
s3          EQU   0x21
sv_FSR      EQU   0x22
x           EQU   0x24
m           EQU   0x25
temp        EQU   0x26
display_number EQU   0x27
my_byte     EQU   0x2A
C1cnt       EQU   0x34
C2tmp       EQU   0x35
C3cnt       EQU   0x34
C4tmp       EQU   0x35
C5rem       EQU   0x38
time_error  EQU   0
num         EQU   0x25
chan        EQU   0x26
temp_hours  EQU   0x24
temp_ampm   EQU   0
gps_offset  EQU   0x24
x_2         EQU   0x25
C6cnt       EQU   0x26
C7tmp       EQU   0x27
C8cnt       EQU   0x26
C9tmp       EQU   0x27
C10cnt      EQU   0x26
C11tmp      EQU   0x27
C12cnt      EQU   0x26
C13tmp      EQU   0x27
C14rem      EQU   0x28
C15cnt      EQU   0x26
C16tmp      EQU   0x27
C17cnt      EQU   0x26
C18tmp      EQU   0x27
C19rem      EQU   0x28
C20cnt      EQU   0x26
C21tmp      EQU   0x27
C22cnt      EQU   0x26
C23tmp      EQU   0x27
C24rem      EQU   0x28
C25cnt      EQU   0x26
C26tmp      EQU   0x27
digit       EQU   0x34
channel     EQU   0x35
e_address   EQU   0x24
e_data      EQU   0x26
e_address_2 EQU   0x27
temp_GIE    EQU   0
nate        EQU   0x36
counter     EQU   0x7F
x_3         EQU   0x36
nate_2      EQU   0x26
my_byte_2   EQU   0x27
i           EQU   0x29
k           EQU   0x2A
m_2         EQU   0x2B
temp_2      EQU   0x2C
high_byte   EQU   0x2D
low_byte    EQU   0x2E
C27cnt      EQU   0x36
C28tmp      EQU   0x37
C29cnt      EQU   0x36
C30tmp      EQU   0x37
C31cnt      EQU   0x36
C32tmp      EQU   0x37
C33rem      EQU   0x39
x_4         EQU   0x27
y_2         EQU   0x29
z_2         EQU   0x2A
ci          EQU   0x36

	GOTO main

  ; FILE C:\Global\Code\16F877A\SFE-WallClock\SFE-WallClock-v01.C
			;/*
			;    3-6-06
			;    Copyright Spark Fun Electronics© 2006
			;    Nathan Seidle 
			;    spark@sparkfun.com
			;    
			;    Multi-channel control of 12V Sign String/LEDs
			;
			;    Basically we are going to read GPS time data from the Lassen iQ and display it
			;    on a series of very large 7-segment displays.
			;
			;    I used the 4511 7-segment binary decoder coupled with the ULN2003 driver. The 
			;    binary decoder can't handle the 50-100mA that the LED strings will draw, but the
			;    ULN2003 can handle 500mA per channel! Huge. 
			;
			;    I used RJ45 jacks on either end so that I could use very cheap, pre-terminated
			;    CAT5 cable to run power and signal to the 7-segment wall panels. I am not entirely
			;    sure UL would approve ;), but it'll get the job done.
			;
			;    There are 6 drivers so we can control up to 6 7-segment displays. Adding more is not
			;    a problem, just addtional I/O boards.
			;    
			;*/
			;//#define Clock_8MHz
			;//#define Baud_9600
			;
			;#define STATUS_LED      PORTE.0
			;
			;#define BUTTON_UP       PORTE.1
			;#define BUTTON_DOWN     PORTE.2
			;#define BUTTON_SELECT   PORTA.4
			;
			;#define OFF 0
			;#define ON  1
			;
			;#define DRIVER1         PORTD.0
			;#define DRIVER2         PORTD.1
			;#define DRIVER3         PORTD.2
			;#define DRIVER4         PORTD.3
			;#define DRIVER5         PORTD.4
			;#define DRIVER6         PORTD.5
			;
			;#define CONTROL1        PORTB.0
			;#define CONTROL2        PORTB.1
			;#define CONTROL3        PORTB.2
			;#define CONTROL4        PORTB.3
			;
			;#define AM  0
			;#define PM  1
			;#define SPOT_LOCAL_HOUR 1
			;
			;#define PUSHED  0
			;
			;#define TRUE    1
			;#define FALSE   0
			;
			;#include "\Global\Code\C\16F877.h" // Device hardware map
			;#include "\Global\Code\C\int16CXX.H" // Device interrupt definitions
			;
			;//#pragma config |= 0x2902
			;#pragma origin 4 //Used for boot loading and interrupts
	ORG 0x0004
			;
			;//Global Variables
			;//============================
			;uns8 RX_In; //Pointer to the next free position
			;
			;//Receiver buffer
			;#define FIFO_SIZE   96
			;
			;#pragma rambank 2
			;uns8 RX_Array[FIFO_SIZE]; //Receive buffer 1
			;//$GPGGA,185407.00,4000.0907,N,10514.2805,W,1,06,1.51,01622,M,-020,M,,*5E
			;//$GPVTG,000.0,T,349.4,M,000.0,N,000.0,K,A*29
			;#pragma rambank 0
			;
			;uns8 m_seconds;
			;uns8 seconds;
			;uns16 total_seconds; //Used in VB for thresholds
			;
			;uns8 satellites_in_view;
			;bit gps_lock;
			;uns8 gps_hours;
			;uns8 gps_minutes;
			;uns8 gps_seconds;
			;bit gps_ampm;
			;uns8 local_hour;
			;uns8 pure_gps_hours;
			;
			;uns8 high_hours;
			;uns8 low_hours;
			;uns8 high_minutes;
			;uns8 low_minutes;
			;uns8 high_seconds;
			;uns8 low_seconds;
			;
			;uns8 rt_seconds;
			;//============================
			;//End Global Variables
			;
			;//Interrupt Vectors
			;//============================
			;interrupt serverX( void)
			;{
serverX
			;    int_save_registers
	MOVWF s1_save
	SWAPF STATUS,W
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVWF s2
	MOVF  PCLATH,W
	MOVWF s3
	CLRF  PCLATH
			;    char sv_FSR = FSR;  // save FSR if required
	MOVF  FSR,W
	MOVWF sv_FSR
			;
			;    if(RCIF) //Receive interrupt
	BTFSS 0x0C,RCIF
	GOTO  m001
			;    {
			;        RX_In++;
	INCF  RX_In,1
			;        if(RX_In == FIFO_SIZE) RX_In = 0;
	MOVF  RX_In,W
	XORLW .96
	BTFSC 0x03,Zero_
	CLRF  RX_In
			;        
			;        RX_Array[RX_In] = RCREG; //Clears interrupt flag
	MOVLW .16
	ADDWF RX_In,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  RCREG,W
	MOVWF INDF
			;
			;        CREN = 0;
	BCF   0x18,CREN
			;        CREN = 1;
	BSF   0x18,CREN
			;    }
			;
			;    if (TMR1IF) //RTC 32kHz xtal
m001	BTFSS 0x0C,TMR1IF
	GOTO  m002
			;    {
			;        TMR1H = 0x80; //TMR1L = 0x00; //No need to reset the Low byte, let it run
	MOVLW .128
	MOVWF TMR1H
			;        
			;        rt_seconds++; //Real Time
	INCF  rt_seconds,1
			;
			;        TMR1IF = 0; 
	BCF   0x0C,TMR1IF
			;    }
			;
			;    FSR = sv_FSR;               // restore FSR if saved
m002	MOVF  sv_FSR,W
	MOVWF FSR
			;    int_restore_registers 
	MOVF  s3,W
	MOVWF PCLATH
	SWAPF s2,W
	MOVWF STATUS
	SWAPF s1_save,1
	SWAPF s1_save,W
			;}
	RETFIE
			;//============================
			;
			;//Function definitions
			;//============================
			;//#include "d:\Pics\code\Delay.c"   // Delays
			;//#include "d:\Pics\code\Stdio.c"   // Print routines
			;
			;void boot_up(void);
			;void delay_ms(uns16 x);
			;
			;void put_number(uns8 digit, uns8 channel);
			;void gps_parser(void);
			;void set_time(void);
			;void time_printer(void);
			;void loop_printer(void);
			;void colon_control(void);
			;
			;uns8 onboard_eeread(uns8 e_address);
			;void onboard_eewrite(uns8 e_data, uns8 e_address);
			;
			;void putc(uns8);
			;uns8 getc(void);
			;uns8 scanc(void);
			;uns8 bin2Hex(char x);
			;void printf(const char *nate, int16 my_byte);
			;
			;//============================
			;//End Function Definitions
			;
			;void main()
			;{
_const1
	MOVWF ci
	MOVLW .0
	BSF   0x03,RP1
	MOVWF EEADRH
	BCF   0x03,RP1
	RRF   ci,W
	ANDLW .127
	ADDLW .75
	BSF   0x03,RP1
	MOVWF EEADR
	BTFSC 0x03,Carry
	INCF  EEADRH,1
	BSF   0x03,RP0
	BSF   0x18C,EEPGD
	BSF   0x18C,RD
	NOP  
	NOP  
	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC ci,0
	GOTO  m003
	BSF   0x03,RP1
	MOVF  EEDATA,W
	ANDLW .127
	BCF   0x03,RP1
	RETURN
m003	BSF   0x03,RP1
	RLF   EEDATA,W
	RLF   EEDATH,W
	BCF   0x03,RP1
	RETURN
	DW    0x32D3
	DW    0x3A74
	DW    0x3769
	DW    0x1067
	DW    0x336F
	DW    0x39E6
	DW    0x3A65
	DW    0x103A
	DW    0x3950
	DW    0x39E5
	DW    0x1073
	DW    0x32F3
	DW    0x32EC
	DW    0x3A63
	DW    0x3A20
	DW    0x106F
	DW    0x3C65
	DW    0x3A69
	DW    0x50A
	DW    0x500
	DW    0x218A
	DW    0x3975
	DW    0x32F2
	DW    0x3A6E
	DW    0x2420
	DW    0x3AEF
	DW    0x1072
	DW    0x103D
	DW    0x3225
	DW    0x1300
	DW    0x500
	DW    0x3AC3
	DW    0x3972
	DW    0x3765
	DW    0x1074
	DW    0x34D4
	DW    0x32ED
	DW    0x1D20
	DW    0x12A0
	DW    0x1D64
	DW    0x1280
	DW    0x1764
	DW    0x1000
	DW    0x26C1
	DW    0x1000
	DW    0x26D0
	DW    0x1000
	DW    0x30D3
	DW    0x39F4
	DW    0x1D20
	DW    0x3225
	DW    0x680
	DW    0x3853
	DW    0x3961
	DW    0x106B
	DW    0x3AC6
	DW    0x106E
	DW    0x3645
	DW    0x31E5
	DW    0x3974
	DW    0x376F
	DW    0x31E9
	DW    0x6F3
	DW    0x2380
	DW    0x29D0
	DW    0x2BA0
	DW    0x3661
	DW    0x106C
	DW    0x3643
	DW    0x31EF
	DW    0x106B
	DW    0x1876
	DW    0x6B1
	DW    0x0
main
			;    uns8 choice;
			;    
			;    boot_up();
	BCF   0x03,RP0
	BCF   0x03,RP1
	CALL  boot_up
			;
			;    colon_control(); //Un-Comment out this line if this board is controlling the colons
	CALL  colon_control
			;
			;    //Used for testing
			;    //==============================
			;    satellites_in_view = 5;
	MOVLW .5
	MOVWF satellites_in_view
			;
			;    high_hours = 1;
	MOVLW .1
	MOVWF high_hours
			;    low_hours = 1;
	MOVWF low_hours
			;    high_minutes = 4;
	MOVLW .4
	MOVWF high_minutes
			;    low_minutes = 6;
	MOVLW .6
	MOVWF low_minutes
			;    high_seconds = 3;
	MOVLW .3
	MOVWF high_seconds
			;    low_seconds = 9;
	MOVLW .9
	MOVWF low_seconds
			;
			;    time_printer();
	CALL  time_printer
			;
			;    while(1);
m004	GOTO  m004
			;    loop_printer();
	CALL  loop_printer
			;    //==============================
			;    
			;    while(1)
			;    {
			;        if (RX_In > 90)
m005	MOVLW .91
	SUBWF RX_In,W
	BTFSS 0x03,Carry
	GOTO  m005
			;        {
			;            gps_parser();
	BSF   0x03,RP0
	CALL  gps_parser
			;            
			;            time_printer();
	BCF   0x03,RP0
	CALL  time_printer
			;
			;            if (BUTTON_UP == 0 && BUTTON_DOWN == 0) set_time();
	BTFSC PORTE,1
	GOTO  m006
	BTFSS PORTE,2
	CALL  set_time
			;
			;            STATUS_LED ^= 1;
m006	MOVLW .1
	XORWF PORTE,1
			;        }
			;    }
	GOTO  m005
			;  
			;}//End Main
			;
			;//This function is meant for the colon control
			;//Let's just flash the colon dots 
			;//Or maybe just turn them on
			;void colon_control(void)
			;{
colon_control
			;    
			;    while(1)
			;    {
			;        //Turn on all channels
			;        put_number(8, 1);
m007	MOVLW .8
	MOVWF digit
	MOVLW .1
	CALL  put_number
			;        put_number(8, 2);
	MOVLW .8
	MOVWF digit
	MOVLW .2
	CALL  put_number
			;        put_number(8, 3);
	MOVLW .8
	MOVWF digit
	MOVLW .3
	CALL  put_number
			;        put_number(8, 4);
	MOVLW .8
	MOVWF digit
	MOVLW .4
	CALL  put_number
			;        put_number(8, 5);
	MOVLW .8
	MOVWF digit
	MOVLW .5
	CALL  put_number
			;        put_number(8, 6);
	MOVLW .8
	MOVWF digit
	MOVLW .6
	CALL  put_number
			;        
			;        delay_ms(1000); //Pause a second
	MOVLW .232
	MOVWF x_4
	MOVLW .3
	MOVWF x_4+1
	CALL  delay_ms
			;        
			;        //Turn off all channels
			;        put_number(10, 1);
	MOVLW .10
	MOVWF digit
	MOVLW .1
	CALL  put_number
			;        put_number(10, 2);
	MOVLW .10
	MOVWF digit
	MOVLW .2
	CALL  put_number
			;        put_number(10, 3);
	MOVLW .10
	MOVWF digit
	MOVLW .3
	CALL  put_number
			;        put_number(10, 4);
	MOVLW .10
	MOVWF digit
	MOVLW .4
	CALL  put_number
			;        put_number(10, 5);
	MOVLW .10
	MOVWF digit
	MOVLW .5
	CALL  put_number
			;        put_number(10, 6);
	MOVLW .10
	MOVWF digit
	MOVLW .6
	CALL  put_number
			;        
			;        delay_ms(1000);
	MOVLW .232
	MOVWF x_4
	MOVLW .3
	MOVWF x_4+1
	CALL  delay_ms
			;    }
	GOTO  m007
			;}
			;
			;//This function just prints from 0 to 999,999 very fast
			;void loop_printer(void)
			;{
loop_printer
			;    uns8 x = 0, m, temp;
	CLRF  x
			;    uns24 display_number;
			;    uns24 my_byte;
			;    uns8 decimal_output[7];
			;    
			;    //Clear the current cells
			;    put_number(10, 1);
	MOVLW .10
	MOVWF digit
	MOVLW .1
	CALL  put_number
			;    put_number(10, 2);
	MOVLW .10
	MOVWF digit
	MOVLW .2
	CALL  put_number
			;    put_number(10, 3);
	MOVLW .10
	MOVWF digit
	MOVLW .3
	CALL  put_number
			;    put_number(10, 4);
	MOVLW .10
	MOVWF digit
	MOVLW .4
	CALL  put_number
			;    put_number(10, 5);
	MOVLW .10
	MOVWF digit
	MOVLW .5
	CALL  put_number
			;    put_number(10, 6);
	MOVLW .10
	MOVWF digit
	MOVLW .6
	CALL  put_number
			;
			;    display_number = 334576;
	MOVLW .240
	MOVWF display_number
	MOVLW .26
	MOVWF display_number+1
	MOVLW .5
	MOVWF display_number+2
			;    
			;    while(1)
			;    {
			;        
			;        display_number++;
m008	INCFSZ display_number,1
	GOTO  m009
	INCF  display_number+1,1
	BTFSC 0x03,Zero_
	INCF  display_number+2,1
			;        
			;        if (display_number > 999999)
m009	MOVLW .15
	SUBWF display_number+2,W
	BTFSS 0x03,Carry
	GOTO  m011
	BTFSS 0x03,Zero_
	GOTO  m010
	MOVLW .66
	SUBWF display_number+1,W
	BTFSS 0x03,Carry
	GOTO  m011
	BTFSS 0x03,Zero_
	GOTO  m010
	MOVLW .64
	SUBWF display_number,W
	BTFSS 0x03,Carry
	GOTO  m011
			;        {
			;            display_number = 0;
m010	CLRF  display_number
	CLRF  display_number+1
	CLRF  display_number+2
			;
			;            put_number(10, 1);
	MOVLW .10
	MOVWF digit
	MOVLW .1
	CALL  put_number
			;            put_number(10, 2);
	MOVLW .10
	MOVWF digit
	MOVLW .2
	CALL  put_number
			;            put_number(10, 3);
	MOVLW .10
	MOVWF digit
	MOVLW .3
	CALL  put_number
			;            put_number(10, 4);
	MOVLW .10
	MOVWF digit
	MOVLW .4
	CALL  put_number
			;            put_number(10, 5);
	MOVLW .10
	MOVWF digit
	MOVLW .5
	CALL  put_number
			;            put_number(10, 6);
	MOVLW .10
	MOVWF digit
	MOVLW .6
	CALL  put_number
			;        }
			;        
			;        my_byte = display_number;
m011	MOVF  display_number,W
	MOVWF my_byte
	MOVF  display_number+1,W
	MOVWF my_byte+1
	MOVF  display_number+2,W
	MOVWF my_byte+2
			;
			;        //Divide number by a series of 10s
			;        for(m = 6 ; my_byte > 0 ; m--)
	MOVLW .6
	MOVWF m
m012	MOVF  my_byte,W
	IORWF my_byte+1,W
	IORWF my_byte+2,W
	BTFSC 0x03,Zero_
	GOTO  m019
			;        {
			;            temp = my_byte % (uns16)10;
	MOVF  my_byte,W
	MOVWF C2tmp
	MOVF  my_byte+1,W
	MOVWF C2tmp+1
	MOVF  my_byte+2,W
	MOVWF C2tmp+2
	CLRF  temp
	MOVLW .24
	MOVWF C1cnt
m013	RLF   C2tmp,1
	RLF   C2tmp+1,1
	RLF   C2tmp+2,1
	RLF   temp,1
	BTFSC 0x03,Carry
	GOTO  m014
	MOVLW .10
	SUBWF temp,W
	BTFSS 0x03,Carry
	GOTO  m015
m014	MOVLW .10
	SUBWF temp,1
m015	DECFSZ C1cnt,1
	GOTO  m013
			;            decimal_output[m] = temp;
	MOVLW .45
	ADDWF m,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  temp,W
	MOVWF INDF
			;            my_byte = my_byte / (uns16)10;               
	MOVF  my_byte,W
	MOVWF C4tmp
	MOVF  my_byte+1,W
	MOVWF C4tmp+1
	MOVF  my_byte+2,W
	MOVWF C4tmp+2
	CLRF  C5rem
	MOVLW .24
	MOVWF C3cnt
m016	RLF   C4tmp,1
	RLF   C4tmp+1,1
	RLF   C4tmp+2,1
	RLF   C5rem,1
	BTFSC 0x03,Carry
	GOTO  m017
	MOVLW .10
	SUBWF C5rem,W
	BTFSS 0x03,Carry
	GOTO  m018
m017	MOVLW .10
	SUBWF C5rem,1
	BSF   0x03,Carry
m018	RLF   my_byte,1
	RLF   my_byte+1,1
	RLF   my_byte+2,1
	DECFSZ C3cnt,1
	GOTO  m016
			;        }
	DECF  m,1
	GOTO  m012
			;    
			;        for(m++ ; m < 7 ; m++)
m019	INCF  m,1
m020	MOVLW .7
	SUBWF m,W
	BTFSC 0x03,Carry
	GOTO  m021
			;        {
			;            put_number(decimal_output[m], 7 - m); 
	MOVLW .45
	ADDWF m,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  INDF,W
	MOVWF digit
	MOVF  m,W
	SUBLW .7
	CALL  put_number
			;            //putc(bin2Hex(decimal_output[m]));
			;        }
	INCF  m,1
	GOTO  m020
			;
			;        //printf(" - %d\n", display_number);
			;        //delay_ms(5);
			;        STATUS_LED ^= 1;
m021	MOVLW .1
	XORWF PORTE,1
			;    }
	GOTO  m008
			;
			;}
			;
			;//Check all the numbers to make sure we are kosher, then put them out to the clock cells
			;//Do any kind of special effects here
			;void time_printer(void)
			;{
time_printer
			;    bit time_error = FALSE;
	BCF   0x24,time_error
			;    
			;    if (gps_hours > 12) time_error = TRUE;
	MOVLW .13
	SUBWF gps_hours,W
	BTFSC 0x03,Carry
	BSF   0x24,time_error
			;    if (satellites_in_view > 10) time_error = TRUE;
	MOVLW .11
	SUBWF satellites_in_view,W
	BTFSC 0x03,Carry
	BSF   0x24,time_error
			;    
			;    if (time_error == TRUE)
	BTFSS 0x24,time_error
	GOTO  m025
			;    {
			;        //Display a roving error condition on the clock
			;        
			;        uns8 num, chan;
			;        
			;        for(num = 0 ; num < 10 ; num++)
	CLRF  num
m022	MOVLW .10
	SUBWF num,W
	BTFSC 0x03,Carry
	GOTO  m026
			;        {
			;            for(chan = 1 ; chan < 7 ; chan++)
	MOVLW .1
	MOVWF chan
m023	MOVLW .7
	SUBWF chan,W
	BTFSC 0x03,Carry
	GOTO  m024
			;            {
			;                put_number(10, 6);
	MOVLW .10
	MOVWF digit
	MOVLW .6
	CALL  put_number
			;                put_number(10, 5);
	MOVLW .10
	MOVWF digit
	MOVLW .5
	CALL  put_number
			;                put_number(10, 4);
	MOVLW .10
	MOVWF digit
	MOVLW .4
	CALL  put_number
			;                put_number(10, 3);
	MOVLW .10
	MOVWF digit
	MOVLW .3
	CALL  put_number
			;                put_number(10, 2);
	MOVLW .10
	MOVWF digit
	MOVLW .2
	CALL  put_number
			;                put_number(10, 1);
	MOVLW .10
	MOVWF digit
	MOVLW .1
	CALL  put_number
			;                
			;                put_number(num, chan);
	MOVF  num,W
	MOVWF digit
	MOVF  chan,W
	CALL  put_number
			;                
			;                delay_ms(250);
	MOVLW .250
	MOVWF x_4
	CLRF  x_4+1
	CALL  delay_ms
			;            }
	INCF  chan,1
	GOTO  m023
			;        }
m024	INCF  num,1
	GOTO  m022
			;    }
			;    else
			;    {
			;        //Hour
			;        put_number(high_hours, 6); //High hour on channel 6
m025	MOVF  high_hours,W
	MOVWF digit
	MOVLW .6
	CALL  put_number
			;        put_number(low_hours, 5); 
	MOVF  low_hours,W
	MOVWF digit
	MOVLW .5
	CALL  put_number
			;        put_number(high_minutes, 4);
	MOVF  high_minutes,W
	MOVWF digit
	MOVLW .4
	CALL  put_number
			;        put_number(low_minutes, 3);
	MOVF  low_minutes,W
	MOVWF digit
	MOVLW .3
	CALL  put_number
			;        put_number(high_seconds, 2);
	MOVF  high_seconds,W
	MOVWF digit
	MOVLW .2
	CALL  put_number
			;        put_number(low_seconds, 1);
	MOVF  low_seconds,W
	MOVWF digit
	MOVLW .1
	GOTO  put_number
			;
			;    }
			;    
			;}
m026	RETURN
			;
			;//Set time allows the user to select the local offset from UTC time
			;//as well as select between 12 and 24 hour representation
			;void set_time(void)
			;{
set_time
			;    
			;    uns8 temp_hours;
			;    bit temp_ampm;
			;    
			;    printf("Setting offset: Press select to exit\n\n", 0);
	CLRF  nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;    
			;    //Blink something for 3 seconds
			;//    delay_ms(3000);
			;
			;    while(BUTTON_UP == PUSHED || BUTTON_DOWN == PUSHED); //Wait for user to remove their finger
m027	BTFSS PORTE,1
	GOTO  m027
	BTFSS PORTE,2
	GOTO  m027
			;
			;    while(1)
			;    {
			;        //Convert UTC hours to local current time using local_hour
			;        //======================================
			;        temp_hours = pure_gps_hours;
m028	MOVF  pure_gps_hours,W
	MOVWF temp_hours
			;        
			;        if(temp_hours < local_hour)
	MOVF  local_hour,W
	SUBWF temp_hours,W
	BTFSC 0x03,Carry
	GOTO  m029
			;            temp_hours += 24; //add 24 and then subtract local offset
	MOVLW .24
	ADDWF temp_hours,1
			;    
			;        temp_hours -= local_hour;
m029	MOVF  local_hour,W
	SUBWF temp_hours,1
			;        
			;        if(temp_hours > 12) //Get rid of military time
	MOVLW .13
	SUBWF temp_hours,W
	BTFSS 0x03,Carry
	GOTO  m030
			;        { 
			;            temp_hours -= 12; 
	MOVLW .12
	SUBWF temp_hours,1
			;            temp_ampm = PM;
	BSF   0x25,temp_ampm
			;        }
			;        else
	GOTO  m031
			;            temp_ampm = AM;
m030	BCF   0x25,temp_ampm
			;        //======================================
			;    
			;        printf("\n\nCurrent Hour = %d", temp_hours);
m031	MOVLW .39
	MOVWF nate_2
	MOVF  temp_hours,W
	MOVWF my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;        if(temp_ampm == AM) printf(" AM",0);
	BTFSC 0x25,temp_ampm
	GOTO  m032
	MOVLW .85
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;        if(temp_ampm == PM) printf(" PM",0);
m032	BTFSS 0x25,temp_ampm
	GOTO  m033
	MOVLW .89
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;
			;        //printf("  Current Offset = %d", local_hour);
			;
			;
			;        while(BUTTON_UP != PUSHED && BUTTON_DOWN != PUSHED && BUTTON_SELECT != PUSHED); //Wait for user to press button
m033	BTFSS PORTE,1
	GOTO  m034
	BTFSS PORTE,2
	GOTO  m034
	BTFSC PORTA,4
	GOTO  m033
			;        
			;        if(BUTTON_SELECT == PUSHED) break;
m034	BTFSS PORTA,4
	GOTO  m037
			;        if(BUTTON_UP == PUSHED) local_hour--;
	BTFSS PORTE,1
	DECF  local_hour,1
			;        if(BUTTON_DOWN == PUSHED) local_hour++;
	BTFSS PORTE,2
	INCF  local_hour,1
			;        
			;        while(BUTTON_UP == PUSHED || BUTTON_DOWN == PUSHED || BUTTON_SELECT == PUSHED); //Wait for user to release button
m035	BTFSS PORTE,1
	GOTO  m035
	BTFSS PORTE,2
	GOTO  m035
	BTFSS PORTA,4
	GOTO  m035
			;
			;        if (local_hour == 255) local_hour = 23;
	INCFSZ local_hour,W
	GOTO  m036
	MOVLW .23
	MOVWF local_hour
			;        if (local_hour == 24) local_hour = 0;
m036	MOVF  local_hour,W
	XORLW .24
	BTFSS 0x03,Zero_
	GOTO  m028
	CLRF  local_hour
			;    }
	GOTO  m028
			;    
			;    onboard_eewrite(local_hour, SPOT_LOCAL_HOUR);
m037	MOVF  local_hour,W
	MOVWF e_data
	MOVLW .1
	GOTO  onboard_eewrite
			;    
			;}
			;
			;//GPS Parser pulls out the lock, the number of satellites, and the current time
			;void gps_parser(void)
			;{
gps_parser
			;
			;//$GPGGA,185407.00,4000.0907,N,10514.2805,W,1,06,1.51,01622,M,-020,M,,*5E
			;//$GPVTG,000.0,T,349.4,M,000.0,N,000.0,K,A*29
			;
			;    //Turn off RX interrupts while parsing
			;    RCIE = 0;
	BCF   0x8C,RCIE
			;
			;    uns8 gps_offset, x;
			;
			;    //Find the offset
			;    for(gps_offset = 0 ; gps_offset < FIFO_SIZE ; gps_offset++)
	BCF   0x03,RP0
	CLRF  gps_offset
m038	MOVLW .96
	SUBWF gps_offset,W
	BTFSC 0x03,Carry
	GOTO  m040
			;        if(RX_Array[gps_offset] == '$') //Look for $
	MOVLW .16
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	XORLW .36
	BTFSS 0x03,Zero_
	GOTO  m039
			;            if(RX_Array[gps_offset + 5] == 'A') //We found GGA
	MOVLW .21
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	XORLW .65
	BTFSC 0x03,Zero_
			;                break;
	GOTO  m040
			;    
			;    //Error check 1
			;    if(gps_offset == FIFO_SIZE)
m039	INCF  gps_offset,1
	GOTO  m038
m040	MOVF  gps_offset,W
	XORLW .96
	BTFSS 0x03,Zero_
	GOTO  m041
			;    {
			;        printf("&", 0);
	MOVLW .59
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;        goto EXIT;
	GOTO  m062
			;    }
			;
			;    //Convert GPS Time to Integers
			;    //======================================
			;    gps_hours = RX_Array[gps_offset + 7]; // '1'
m041	MOVLW .23
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	MOVWF gps_hours
			;    gps_hours -= '0'; //1
	MOVLW .48
	SUBWF gps_hours,1
			;    gps_hours *= 10; //10
	BCF   0x03,Carry
	RLF   gps_hours,W
	MOVWF C7tmp
	CLRF  gps_hours
	MOVLW .5
	MOVWF C6cnt
m042	MOVF  C7tmp,W
	ADDWF gps_hours,1
	DECFSZ C6cnt,1
	GOTO  m042
			;    
			;    gps_hours += RX_Array[gps_offset + 8]; // 10 + '8'
	MOVLW .24
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	ADDWF gps_hours,1
			;    gps_hours -= '0'; //18
	MOVLW .48
	SUBWF gps_hours,1
			;    
			;    gps_minutes = RX_Array[gps_offset + 9]; //'3'
	MOVLW .25
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	MOVWF gps_minutes
			;    gps_minutes -= '0'; //3
	MOVLW .48
	SUBWF gps_minutes,1
			;    gps_minutes *= 10; //30
	BCF   0x03,Carry
	RLF   gps_minutes,W
	MOVWF C9tmp
	CLRF  gps_minutes
	MOVLW .5
	MOVWF C8cnt
m043	MOVF  C9tmp,W
	ADDWF gps_minutes,1
	DECFSZ C8cnt,1
	GOTO  m043
			;    
			;    gps_minutes += RX_Array[gps_offset + 10]; //30 + '4'
	MOVLW .26
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	ADDWF gps_minutes,1
			;    gps_minutes -= '0'; //34
	MOVLW .48
	SUBWF gps_minutes,1
			;
			;    gps_seconds = RX_Array[gps_offset + 11]; //'3'
	MOVLW .27
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	MOVWF gps_seconds
			;    gps_seconds -= '0'; //3
	MOVLW .48
	SUBWF gps_seconds,1
			;    gps_seconds *= 10; //30
	BCF   0x03,Carry
	RLF   gps_seconds,W
	MOVWF C11tmp
	CLRF  gps_seconds
	MOVLW .5
	MOVWF C10cnt
m044	MOVF  C11tmp,W
	ADDWF gps_seconds,1
	DECFSZ C10cnt,1
	GOTO  m044
			;    
			;    gps_seconds += RX_Array[gps_offset + 12]; //30 + '4'
	MOVLW .28
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	ADDWF gps_seconds,1
			;    gps_seconds -= '0'; //34
	MOVLW .48
	SUBWF gps_seconds,1
			;    //======================================
			;
			;    //Convert SIV to Integers
			;    //======================================
			;    satellites_in_view = RX_Array[gps_offset + 45]; //'6' Satellites
	MOVLW .61
	ADDWF gps_offset,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVF  INDF,W
	MOVWF satellites_in_view
			;    satellites_in_view -= '0'; //6
	MOVLW .48
	SUBWF satellites_in_view,1
			;    //======================================
			;
			;    //Convert UTC hours to local current time using local_hour
			;    //======================================
			;    pure_gps_hours = gps_hours;
	MOVF  gps_hours,W
	MOVWF pure_gps_hours
			;    
			;    if(gps_hours < local_hour)
	MOVF  local_hour,W
	SUBWF gps_hours,W
	BTFSC 0x03,Carry
	GOTO  m045
			;        gps_hours += 24; //add 24 and then subtract local offset
	MOVLW .24
	ADDWF gps_hours,1
			;
			;    gps_hours -= local_hour;
m045	MOVF  local_hour,W
	SUBWF gps_hours,1
			;    
			;    if(gps_hours > 12) //Get rid of military time
	MOVLW .13
	SUBWF gps_hours,W
	BTFSS 0x03,Carry
	GOTO  m046
			;    { 
			;        gps_hours -= 12; 
	MOVLW .12
	SUBWF gps_hours,1
			;        gps_ampm = PM;
	BSF   0x41,gps_ampm
			;    }
			;    else
	GOTO  m047
			;        gps_ampm = AM;
m046	BCF   0x41,gps_ampm
			;    //======================================
			;
			;    //Convert the integers to individual integers
			;    //======================================
			;    high_hours = gps_hours / 10;
m047	MOVF  gps_hours,W
	MOVWF C13tmp
	CLRF  C14rem
	MOVLW .8
	MOVWF C12cnt
m048	RLF   C13tmp,1
	RLF   C14rem,1
	MOVLW .10
	SUBWF C14rem,W
	BTFSS 0x03,Carry
	GOTO  m049
	MOVLW .10
	SUBWF C14rem,1
	BSF   0x03,Carry
m049	RLF   high_hours,1
	DECFSZ C12cnt,1
	GOTO  m048
			;    low_hours = gps_hours % 10;
	MOVF  gps_hours,W
	MOVWF C16tmp
	CLRF  low_hours
	MOVLW .8
	MOVWF C15cnt
m050	RLF   C16tmp,1
	RLF   low_hours,1
	MOVLW .10
	SUBWF low_hours,W
	BTFSS 0x03,Carry
	GOTO  m051
	MOVLW .10
	SUBWF low_hours,1
m051	DECFSZ C15cnt,1
	GOTO  m050
			;    
			;    high_minutes = gps_minutes / 10;
	MOVF  gps_minutes,W
	MOVWF C18tmp
	CLRF  C19rem
	MOVLW .8
	MOVWF C17cnt
m052	RLF   C18tmp,1
	RLF   C19rem,1
	MOVLW .10
	SUBWF C19rem,W
	BTFSS 0x03,Carry
	GOTO  m053
	MOVLW .10
	SUBWF C19rem,1
	BSF   0x03,Carry
m053	RLF   high_minutes,1
	DECFSZ C17cnt,1
	GOTO  m052
			;    low_minutes = gps_minutes % 10;
	MOVF  gps_minutes,W
	MOVWF C21tmp
	CLRF  low_minutes
	MOVLW .8
	MOVWF C20cnt
m054	RLF   C21tmp,1
	RLF   low_minutes,1
	MOVLW .10
	SUBWF low_minutes,W
	BTFSS 0x03,Carry
	GOTO  m055
	MOVLW .10
	SUBWF low_minutes,1
m055	DECFSZ C20cnt,1
	GOTO  m054
			;    
			;    high_seconds = gps_seconds / 10;
	MOVF  gps_seconds,W
	MOVWF C23tmp
	CLRF  C24rem
	MOVLW .8
	MOVWF C22cnt
m056	RLF   C23tmp,1
	RLF   C24rem,1
	MOVLW .10
	SUBWF C24rem,W
	BTFSS 0x03,Carry
	GOTO  m057
	MOVLW .10
	SUBWF C24rem,1
	BSF   0x03,Carry
m057	RLF   high_seconds,1
	DECFSZ C22cnt,1
	GOTO  m056
			;    low_seconds = gps_seconds % 10;
	MOVF  gps_seconds,W
	MOVWF C26tmp
	CLRF  low_seconds
	MOVLW .8
	MOVWF C25cnt
m058	RLF   C26tmp,1
	RLF   low_seconds,1
	MOVLW .10
	SUBWF low_seconds,W
	BTFSS 0x03,Carry
	GOTO  m059
	MOVLW .10
	SUBWF low_seconds,1
m059	DECFSZ C25cnt,1
	GOTO  m058
			;    //======================================
			;
			;    //Debug printing
			;    //======================================
			;
			;/*
			;    printf("\nRaw: ", 0);
			;    for(x = 0 ; x < FIFO_SIZE ; x++)
			;        printf("%u", RX_Array[x]);
			;    printf("\n\n", 0);
			;*/
			;    printf("\nCurrent Time : %d:", gps_hours);
	MOVLW .61
	MOVWF nate_2
	MOVF  gps_hours,W
	MOVWF my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;    printf("%d.", gps_minutes);
	MOVLW .81
	MOVWF nate_2
	MOVF  gps_minutes,W
	MOVWF my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;    printf("%d", gps_seconds);
	MOVLW .56
	MOVWF nate_2
	MOVF  gps_seconds,W
	MOVWF my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;
			;    if(gps_ampm == AM) printf(" AM",0);
	BTFSC 0x41,gps_ampm
	GOTO  m060
	MOVLW .85
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;    if(gps_ampm == PM) printf(" PM",0);
m060	BTFSS 0x41,gps_ampm
	GOTO  m061
	MOVLW .89
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;
			;    printf(" Sats :%d", satellites_in_view); //Satellites
m061	MOVLW .93
	MOVWF nate_2
	MOVF  satellites_in_view,W
	MOVWF my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;    
			;EXIT:
			;
			;    //All done, now we need to clear the RX buffer
			;    for(x = 0 ; x < FIFO_SIZE ; x++)
m062	CLRF  x_2
m063	MOVLW .96
	SUBWF x_2,W
	BTFSC 0x03,Carry
	GOTO  m064
			;        RX_Array[x] = '0';
	MOVLW .16
	ADDWF x_2,W
	MOVWF FSR
	BSF   0x03,IRP
	MOVLW .48
	MOVWF INDF
	INCF  x_2,1
	GOTO  m063
			;    
			;    RX_In = 0;
m064	CLRF  RX_In
			;
			;    CREN = 0;
	BCF   0x18,CREN
			;    CREN = 1; //This clears the jam-up in the RX buffer
	BSF   0x18,CREN
			;
			;    //W = RCREG;
			;    RCIE = 1;
	BSF   0x03,RP0
	BSF   0x8C,RCIE
			;    
			;}
	RETURN
			;
			;//Put a specific number onto a specific channel
			;void put_number(uns8 digit, uns8 channel)
			;{
put_number
	MOVWF channel
			;    PORTB = digit;
	MOVF  digit,W
	MOVWF PORTB
			;    
			;    switch(channel)
	MOVF  channel,W
	XORLW .1
	BTFSC 0x03,Zero_
	GOTO  m065
	XORLW .3
	BTFSC 0x03,Zero_
	GOTO  m066
	XORLW .1
	BTFSC 0x03,Zero_
	GOTO  m067
	XORLW .7
	BTFSC 0x03,Zero_
	GOTO  m068
	XORLW .1
	BTFSC 0x03,Zero_
	GOTO  m069
	XORLW .3
	BTFSC 0x03,Zero_
	GOTO  m070
	GOTO  m071
			;    {
			;        case 1:
			;            DRIVER1 = 0;
m065	BCF   PORTD,0
			;            DRIVER1 = 1;
	BSF   PORTD,0
			;            break;
	GOTO  m071
			;        case 2:
			;            DRIVER2 = 0;
m066	BCF   PORTD,1
			;            DRIVER2 = 1;
	BSF   PORTD,1
			;            break;
	GOTO  m071
			;        case 3:
			;            DRIVER3 = 0;
m067	BCF   PORTD,2
			;            DRIVER3 = 1;
	BSF   PORTD,2
			;            break;
	GOTO  m071
			;        case 4:
			;            DRIVER4 = 0;
m068	BCF   PORTD,3
			;            DRIVER4 = 1;
	BSF   PORTD,3
			;            break;
	GOTO  m071
			;        case 5:
			;            DRIVER5 = 0;
m069	BCF   PORTD,4
			;            DRIVER5 = 1;
	BSF   PORTD,4
			;            break;
	GOTO  m071
			;        case 6:
			;            DRIVER6 = 0;
m070	BCF   PORTD,5
			;            DRIVER6 = 1;
	BSF   PORTD,5
			;            break;
			;    }
			;    
			;}
m071	RETURN
			;
			;//Init vars and ports
			;void boot_up(void)
			;{
boot_up
			;
			;    //Blank all segments
			;    PORTB = 0b.0011.1111;
	MOVLW .63
	MOVWF PORTB
			;    PORTD = 0b.0000.0000;
	CLRF  PORTD
			;    PORTD = 0b.0011.1111;
	MOVWF PORTD
			;    
			;    //Turn all ports to Digital Outputs
			;    ADCON1 = 0b.0000.0111;
	MOVLW .7
	BSF   0x03,RP0
	MOVWF ADCON1
			;
			;    PORTA = 0b.0000.0000;
	BCF   0x03,RP0
	CLRF  PORTA
			;    TRISA = 0b.0001.0000;  //0 = Output, 1 = Input (BUTTON_SELECT on RA4)
	MOVLW .16
	BSF   0x03,RP0
	MOVWF TRISA
			;
			;    PORTB = 0b.0011.1111;
	MOVLW .63
	BCF   0x03,RP0
	MOVWF PORTB
			;    TRISB = 0b.0000.0000;  //0 = Output, 1 = Input (CONTROL1-4 on RB0-3)
	BSF   0x03,RP0
	CLRF  TRISB
			;
			;    PORTC = 0b.0000.0000;
	BCF   0x03,RP0
	CLRF  PORTC
			;    TRISC = 0b.1000.0011;  //0 = Output, 1 = Input (RX on RC7) (RTC Xtal on RC0/1)
	MOVLW .131
	BSF   0x03,RP0
	MOVWF TRISC
			;
			;    PORTD = 0b.0000.0000;
	BCF   0x03,RP0
	CLRF  PORTD
			;    TRISD = 0b.0000.0000;  //0 = Output, 1 = Input (DRIVER1-6 on RD0-5)
	BSF   0x03,RP0
	CLRF  TRISD
			;    PORTD = 0b.0011.1111;
	MOVLW .63
	BCF   0x03,RP0
	MOVWF PORTD
			;
			;    PORTE = 0b.0000.0110;
	MOVLW .6
	MOVWF PORTE
			;    TRISE = 0b.0000.0110;  //0 = Output, 1 = Input (Buttons on RE1/2 Status LED on RE0)
	BSF   0x03,RP0
	MOVWF TRISE
			;    
			;    //Setup the hardware UART module
			;    //=============================================================
			;    //SPBRG = 31; //20MHz for 9600 inital communication baud rate
			;    SPBRG = 64; //20MHz for 4800 inital communication baud rate
	MOVLW .64
	MOVWF SPBRG
			;    
			;    TXSTA = 0b.0010.0000; //8-bit asych mode, *normal* speed uart enabled
	MOVLW .32
	MOVWF TXSTA
			;    RCSTA = 0b.1001.0000; //Serial port enable, 8-bit asych continous receive mode
	MOVLW .144
	BCF   0x03,RP0
	MOVWF RCSTA
			;    //=============================================================
			;
			;    local_hour = onboard_eeread(SPOT_LOCAL_HOUR);
	MOVLW .1
	CALL  onboard_eeread
	BCF   0x03,RP1
	MOVWF local_hour
			;    if(local_hour > 24)
	MOVLW .25
	SUBWF local_hour,W
	BTFSS 0x03,Carry
	GOTO  m072
			;    {
			;        local_hour = 2; //Default to the middle of the ocean
	MOVLW .2
	MOVWF local_hour
			;        onboard_eewrite(local_hour, SPOT_LOCAL_HOUR);
	MOVWF e_data
	MOVLW .1
	CALL  onboard_eewrite
			;    }
			;    
			;    //Setup interrupts
			;    //=============================================================
			;    TMR1IF = 0;
m072	BCF   0x0C,TMR1IF
			;    T1CON = 0b.0000.1111; //Enable Timer1 for the watch crystal for sleep and rt mode
	MOVLW .15
	MOVWF T1CON
			;    TMR1IE = 1;
	BSF   0x03,RP0
	BSF   0x8C,TMR1IE
			;
			;    RCIE = 1; //RX Interrupt
	BSF   0x8C,RCIE
			;    PEIE = 1;
	BSF   0x0B,PEIE
			;    GIE = 1;
	BSF   0x0B,GIE
			;    //=============================================================
			;    
			;    printf("\rSpark Fun Electronics\r", 0);
	MOVLW .103
	BCF   0x03,RP0
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	CALL  printf
			;    printf("GPS Wall Clock v01\r", 0);
	MOVLW .127
	MOVWF nate_2
	CLRF  my_byte_2
	CLRF  my_byte_2+1
	GOTO  printf
			;}    
			;
			;//Reads e_data from the onboard eeprom at e_address
			;//Reads e_data from the onboard eeprom at e_address
			;uns8 onboard_eeread(uns8 e_address)
			;{
onboard_eeread
	MOVWF e_address
			;    EEPGD = 0; //Read from EEPROM memory and not program memory
	BSF   0x03,RP0
	BSF   0x03,RP1
	BCF   0x18C,EEPGD
			;    EEADR = e_address; //Set the address to read
	BCF   0x03,RP0
	BCF   0x03,RP1
	BSF   0x03,RP1
	MOVWF EEADR
			;    RD = 1; //Read it
	BSF   0x03,RP0
	BSF   0x18C,RD
			;
			;    return(EEDATA); //Read that EEPROM value
	BCF   0x03,RP0
	MOVF  EEDATA,W
	RETURN
			;}    
			;
			;//Write e_data to the onboard eeprom at e_address
			;void onboard_eewrite(uns8 e_data, uns8 e_address)
			;{
onboard_eewrite
	MOVWF e_address_2
			;    bit temp_GIE = GIE;
	BCF   0x28,temp_GIE
	BTFSC 0x0B,GIE
	BSF   0x28,temp_GIE
			;    
			;    EEPGD = 0; //Read from EEPROM memory and not program memory
	BSF   0x03,RP0
	BSF   0x03,RP1
	BCF   0x18C,EEPGD
			;    
			;    EEIF = 0; //Clear the write completion intr flag
	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x0D,EEIF
			;    EEADR = e_address; //Set the address
	BSF   0x03,RP1
	MOVWF EEADR
			;    EEDATA = e_data; //Give it the data
	BCF   0x03,RP1
	MOVF  e_data,W
	BSF   0x03,RP1
	MOVWF EEDATA
			;    WREN = 1; //Enable EE Writes
	BSF   0x03,RP0
	BSF   0x18C,WREN
			;    GIE = 0; //Disable Intrs
	BCF   0x0B,GIE
			;    
			;    //Specific EEPROM write steps
			;    EECON2 = 0x55;
	MOVLW .85
	MOVWF EECON2
			;    EECON2 = 0xAA;
	MOVLW .170
	MOVWF EECON2
			;    WR = 1;
	BSF   0x18C,WR
			;    //Specific EEPROM write steps
			;
			;    while(WR == 1); //Wait for write to complete
m073	BTFSC 0x18C,WR
	GOTO  m073
			;    WREN = 0; //Disable EEPROM Writes
	BCF   0x18C,WREN
			;
			;    GIE = temp_GIE; //Set GIE to its original state
	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x28,temp_GIE
	BCF   0x0B,GIE
	BTFSC 0x28,temp_GIE
	BSF   0x0B,GIE
			;}
	RETURN
			;
			;//Sends nate to the Transmit Register
			;void putc(uns8 nate)
			;{
putc
	MOVWF nate
			;    while(TXIF == 0);
m074	BTFSS 0x0C,TXIF
	GOTO  m074
			;    TXREG = nate;
	MOVF  nate,W
	MOVWF TXREG
			;}
	RETURN
			;
			;uns8 getc(void)
			;{
getc
			;    while(RCIF == 0);
	BCF   0x03,RP0
	BCF   0x03,RP1
m075	BTFSS 0x0C,RCIF
	GOTO  m075
			;    return (RCREG);
	MOVF  RCREG,W
	RETURN
			;}    
			;
			;uns8 scanc(void)
			;{
scanc
			;    uns16 counter = 0;
	CLRF  counter
	CLRF  counter+1
			;    
			;    while(RCIF == 0)
	BCF   0x03,RP0
	BCF   0x03,RP1
m076	BTFSC 0x0C,RCIF
	GOTO  m077
			;    {
			;        counter++;
	INCF  counter,1
	BTFSC 0x03,Zero_
	INCF  counter+1,1
			;        if(counter == 1000) return 0;
	MOVF  counter,W
	XORLW .232
	BTFSS 0x03,Zero_
	GOTO  m076
	MOVF  counter+1,W
	XORLW .3
	BTFSS 0x03,Zero_
	GOTO  m076
	RETLW .0
			;    }
			;    
			;    return (RCREG);
m077	MOVF  RCREG,W
	RETURN
			;}    
			;
			;//Returns ASCII Decimal and Hex values
			;uns8 bin2Hex(char x)
			;{
bin2Hex
	MOVWF x_3
			;   skip(x);
	MOVLW .4
	MOVWF PCLATH
	MOVF  x_3,W
	ADDWF PCL,1
			;   #pragma return[16] = "0123456789ABCDEF"
	RETLW .48
	RETLW .49
	RETLW .50
	RETLW .51
	RETLW .52
	RETLW .53
	RETLW .54
	RETLW .55
	RETLW .56
	RETLW .57
	RETLW .65
	RETLW .66
	RETLW .67
	RETLW .68
	RETLW .69
	RETLW .70
			;}
			;
			;//Prints a string including variables
			;void printf(const char *nate, int16 my_byte)
			;{
printf
			;  
			;    uns8 i, k, m, temp;
			;    uns8 high_byte = 0, low_byte = 0;
	CLRF  high_byte
	CLRF  low_byte
			;    uns8 y, z;
			;    
			;    uns8 decimal_output[5];
			;    
			;    for(i = 0 ; ; i++)
	CLRF  i
			;    {
			;        //delay_ms(3);
			;        
			;        k = nate[i];
m078	MOVF  i,W
	ADDWF nate_2,W
	CALL  _const1
	MOVWF k
			;
			;        if (k == '\0') 
	MOVF  k,1
	BTFSC 0x03,Zero_
			;            break;
	GOTO  m104
			;
			;        else if (k == '%') //Print var
	XORLW .37
	BTFSS 0x03,Zero_
	GOTO  m102
			;        {
			;            i++;
	INCF  i,1
			;            k = nate[i];
	MOVF  i,W
	ADDWF nate_2,W
	CALL  _const1
	MOVWF k
			;
			;            if (k == '\0') 
	MOVF  k,1
	BTFSC 0x03,Zero_
			;                break;
	GOTO  m104
			;            else if (k == '\\') //Print special characters
	XORLW .92
	BTFSS 0x03,Zero_
	GOTO  m079
			;            {
			;                i++;
	INCF  i,1
			;                k = nate[i];
	MOVF  i,W
	ADDWF nate_2,W
	CALL  _const1
	MOVWF k
			;                
			;                putc(k);
	CALL  putc
			;                
			;
			;            } //End Special Characters
			;            else if (k == 'b') //Print Binary
	GOTO  m103
m079	MOVF  k,W
	XORLW .98
	BTFSS 0x03,Zero_
	GOTO  m084
			;            {
			;                for( m = 0 ; m < 8 ; m++ )
	CLRF  m_2
m080	MOVLW .8
	SUBWF m_2,W
	BTFSC 0x03,Carry
	GOTO  m103
			;                {
			;                    if (my_byte.7 == 1) putc('1');
	BTFSS my_byte_2,7
	GOTO  m081
	MOVLW .49
	CALL  putc
			;                    if (my_byte.7 == 0) putc('0');
m081	BTFSC my_byte_2,7
	GOTO  m082
	MOVLW .48
	CALL  putc
			;                    if (m == 3) putc(' ');
m082	MOVF  m_2,W
	XORLW .3
	BTFSS 0x03,Zero_
	GOTO  m083
	MOVLW .32
	CALL  putc
			;                    
			;                    my_byte = my_byte << 1;
m083	BCF   0x03,Carry
	RLF   my_byte_2,1
	RLF   my_byte_2+1,1
			;                }
	INCF  m_2,1
	GOTO  m080
			;            } //End Binary               
			;            else if (k == 'd') //Print Decimal
m084	MOVF  k,W
	XORLW .100
	BTFSS 0x03,Zero_
	GOTO  m098
			;            {
			;                //Print negative sign and take 2's compliment
			;                
			;                if(my_byte < 0)
	BTFSS my_byte_2+1,7
	GOTO  m087
			;                {
			;                    putc('-');
	MOVLW .45
	CALL  putc
			;                    my_byte *= -1;
	MOVF  my_byte_2,W
	MOVWF C28tmp
	MOVF  my_byte_2+1,W
	MOVWF C28tmp+1
	MOVLW .16
	MOVWF C27cnt
m085	BCF   0x03,Carry
	RLF   my_byte_2,1
	RLF   my_byte_2+1,1
	RLF   C28tmp,1
	RLF   C28tmp+1,1
	BTFSS 0x03,Carry
	GOTO  m086
	DECF  my_byte_2+1,1
	DECF  my_byte_2,1
	INCFSZ my_byte_2,W
	INCF  my_byte_2+1,1
m086	DECFSZ C27cnt,1
	GOTO  m085
			;                }
			;                
			;                
			;                if (my_byte == 0)
m087	MOVF  my_byte_2,W
	IORWF my_byte_2+1,W
	BTFSS 0x03,Zero_
	GOTO  m088
			;                    putc('0');
	MOVLW .48
	CALL  putc
			;                else
	GOTO  m103
			;                {
			;                    //Divide number by a series of 10s
			;                    for(m = 4 ; my_byte > 0 ; m--)
m088	MOVLW .4
	MOVWF m_2
m089	BTFSC my_byte_2+1,7
	GOTO  m096
	MOVF  my_byte_2,W
	IORWF my_byte_2+1,W
	BTFSC 0x03,Zero_
	GOTO  m096
			;                    {
			;                        temp = my_byte % (uns16)10;
	MOVF  my_byte_2,W
	MOVWF C30tmp
	MOVF  my_byte_2+1,W
	MOVWF C30tmp+1
	CLRF  temp_2
	MOVLW .16
	MOVWF C29cnt
m090	RLF   C30tmp,1
	RLF   C30tmp+1,1
	RLF   temp_2,1
	BTFSC 0x03,Carry
	GOTO  m091
	MOVLW .10
	SUBWF temp_2,W
	BTFSS 0x03,Carry
	GOTO  m092
m091	MOVLW .10
	SUBWF temp_2,1
m092	DECFSZ C29cnt,1
	GOTO  m090
			;                        decimal_output[m] = temp;
	MOVLW .49
	ADDWF m_2,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  temp_2,W
	MOVWF INDF
			;                        my_byte = my_byte / (uns16)10;               
	MOVF  my_byte_2,W
	MOVWF C32tmp
	MOVF  my_byte_2+1,W
	MOVWF C32tmp+1
	CLRF  C33rem
	MOVLW .16
	MOVWF C31cnt
m093	RLF   C32tmp,1
	RLF   C32tmp+1,1
	RLF   C33rem,1
	BTFSC 0x03,Carry
	GOTO  m094
	MOVLW .10
	SUBWF C33rem,W
	BTFSS 0x03,Carry
	GOTO  m095
m094	MOVLW .10
	SUBWF C33rem,1
	BSF   0x03,Carry
m095	RLF   my_byte_2,1
	RLF   my_byte_2+1,1
	DECFSZ C31cnt,1
	GOTO  m093
			;                    }
	DECF  m_2,1
	GOTO  m089
			;                
			;                    for(m++ ; m < 5 ; m++)
m096	INCF  m_2,1
m097	MOVLW .5
	SUBWF m_2,W
	BTFSC 0x03,Carry
	GOTO  m103
			;                        putc(bin2Hex(decimal_output[m]));
	MOVLW .49
	ADDWF m_2,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  INDF,W
	CALL  bin2Hex
	CALL  putc
	INCF  m_2,1
	GOTO  m097
			;                }
			;    
			;            } //End Decimal
			;            else if (k == 'h') //Print Hex
m098	MOVF  k,W
	XORLW .104
	BTFSS 0x03,Zero_
	GOTO  m100
			;            {
			;                //New trick 3-15-04
			;                putc('0');
	MOVLW .48
	CALL  putc
			;                putc('x');
	MOVLW .120
	CALL  putc
			;                
			;                if(my_byte > 0x00FF)
	BTFSC my_byte_2+1,7
	GOTO  m099
	MOVF  my_byte_2+1,1
	BTFSC 0x03,Zero_
	GOTO  m099
			;                {
			;                    putc(bin2Hex(my_byte.high8 >> 4));
	SWAPF my_byte_2+1,W
	ANDLW .15
	CALL  bin2Hex
	CALL  putc
			;                    putc(bin2Hex(my_byte.high8 & 0b.0000.1111));
	MOVLW .15
	ANDWF my_byte_2+1,W
	CALL  bin2Hex
	CALL  putc
			;                }
			;
			;                putc(bin2Hex(my_byte.low8 >> 4));
m099	SWAPF my_byte_2,W
	ANDLW .15
	CALL  bin2Hex
	CALL  putc
			;                putc(bin2Hex(my_byte.low8 & 0b.0000.1111));
	MOVLW .15
	ANDWF my_byte_2,W
	CALL  bin2Hex
	CALL  putc
			;
			;                /*high_byte.3 = my_byte.7;
			;                high_byte.2 = my_byte.6;
			;                high_byte.1 = my_byte.5;
			;                high_byte.0 = my_byte.4;
			;            
			;                low_byte.3 = my_byte.3;
			;                low_byte.2 = my_byte.2;
			;                low_byte.1 = my_byte.1;
			;                low_byte.0 = my_byte.0;
			;        
			;                putc('0');
			;                putc('x');
			;            
			;                putc(bin2Hex(high_byte));
			;                putc(bin2Hex(low_byte));*/
			;            } //End Hex
			;            else if (k == 'f') //Print Float
	GOTO  m103
m100	MOVF  k,W
	XORLW .102
	BTFSS 0x03,Zero_
	GOTO  m101
			;            {
			;                putc('!');
	MOVLW .33
	CALL  putc
			;            } //End Float
			;            else if (k == 'u') //Print Direct Character
	GOTO  m103
m101	MOVF  k,W
	XORLW .117
	BTFSS 0x03,Zero_
	GOTO  m103
			;            {
			;                //All ascii characters below 20 are special and screwy characters
			;                //if(my_byte > 20) 
			;                    putc(my_byte);
	MOVF  my_byte_2,W
	CALL  putc
			;            } //End Direct
			;                        
			;        } //End Special Chars           
			;
			;        else
	GOTO  m103
			;            putc(k);
m102	MOVF  k,W
	CALL  putc
			;    }    
m103	INCF  i,1
	GOTO  m078
			;}
m104	RETURN
			;
			;//General short delay
			;void delay_ms(uns16 x)
			;{
delay_ms
			;    uns8 y, z;
			;    //Clocks out to 1.00ms per 1ms
			;    //9.99 ms per 10ms
			;    for ( ; x > 0 ; x--)
m105	MOVF  x_4,W
	IORWF x_4+1,W
	BTFSC 0x03,Zero_
	GOTO  m110
			;        for ( y = 0 ; y < 4 ; y++)
	CLRF  y_2
m106	MOVLW .4
	SUBWF y_2,W
	BTFSC 0x03,Carry
	GOTO  m109
			;            for ( z = 0 ; z < 176 ; z++);
	CLRF  z_2
m107	MOVLW .176
	SUBWF z_2,W
	BTFSC 0x03,Carry
	GOTO  m108
	INCF  z_2,1
	GOTO  m107
m108	INCF  y_2,1
	GOTO  m106
m109	DECF  x_4,1
	INCF  x_4,W
	BTFSC 0x03,Zero_
	DECF  x_4+1,1
	GOTO  m105
m110	RETURN

	END


; *** KEY INFO ***

; 0x0004 P0   40 word(s)  1 % : serverX
; 0x03D6 P0   72 word(s)  3 % : boot_up
; 0x0559 P0   24 word(s)  1 % : delay_ms
; 0x03AD P0   41 word(s)  2 % : put_number
; 0x0288 P0  293 word(s) 14 % : gps_parser
; 0x0239 P0   79 word(s)  3 % : set_time
; 0x01E6 P0   83 word(s)  4 % : time_printer
; 0x013D P0  169 word(s)  8 % : loop_printer
; 0x0102 P0   59 word(s)  2 % : colon_control
; 0x041E P0   13 word(s)  0 % : onboard_eeread
; 0x042B P0   34 word(s)  1 % : onboard_eewrite
; 0x044D P0    6 word(s)  0 % : putc
; 0x0453 P0    6 word(s)  0 % : getc
; 0x0459 P0   20 word(s)  0 % : scanc
; 0x046D P0   21 word(s)  1 % : bin2Hex
; 0x0482 P0  215 word(s) 10 % : printf
; 0x00DF P0   35 word(s)  1 % : main
; 0x002C P0  105 word(s)  5 % : _const1

; RAM usage: 143 bytes (28 local), 225 bytes free
; Maximum call level: 3 (+1 for interrupt)
;  Codepage 0 has 1390 word(s) :  67 %
;  Codepage 1 has    0 word(s) :   0 %
;  Codepage 2 has    0 word(s) :   0 %
;  Codepage 3 has    0 word(s) :   0 %
; Total of 1316 code words (16 %)
