
; CC5X Version 3.1J, Copyright (c) B Knudsen Data
; C compiler for the PICmicro family
; ************   4. Sep 2006   0:09  *************

	processor  16F871
	radix  DEC

INDF        EQU   0x00
TMR0        EQU   0x01
STATUS      EQU   0x03
FSR         EQU   0x04
PORTA       EQU   0x05
TRISA       EQU   0x85
PORTB       EQU   0x06
TRISB       EQU   0x86
T0CS        EQU   5
Carry       EQU   0
Zero_       EQU   2
RP0         EQU   5
RP1         EQU   6
IRP         EQU   7
T0IF        EQU   2
T0IE        EQU   5
GIE         EQU   7
OPTION_REG  EQU   0x81
PORTC       EQU   0x07
PORTD       EQU   0x08
PORTE       EQU   0x09
TMR1L       EQU   0x0E
TMR1H       EQU   0x0F
TMR2        EQU   0x11
RCSTA       EQU   0x18
TXREG       EQU   0x19
RCREG       EQU   0x1A
ADRESH      EQU   0x1E
ADCON0      EQU   0x1F
TRISC       EQU   0x87
TRISD       EQU   0x88
TRISE       EQU   0x89
TXSTA       EQU   0x98
SPBRG       EQU   0x99
ADRESL      EQU   0x9E
ADCON1      EQU   0x9F
PEIE        EQU   6
TMR1IF      EQU   0
TMR2IF      EQU   1
TXIF        EQU   4
RCIF        EQU   5
ADIF        EQU   6
TMR1ON      EQU   0
TMR1CS      EQU   1
T1OSCEN     EQU   3
T1CKPS0     EQU   4
T1CKPS1     EQU   5
TMR2ON      EQU   2
OERR        EQU   1
CREN        EQU   4
ADON        EQU   0
GO          EQU   2
ADCS0       EQU   6
ADCS1       EQU   7
TMR1IE      EQU   0
TMR2IE      EQU   1
TXIE        EQU   4
RCIE        EQU   5
ADIE        EQU   6
encoder_0   EQU   0
encoder_1   EQU   1
encoder_2   EQU   2
encoder_3   EQU   3
pwm_out_0   EQU   1
pwm_out_1   EQU   2
pwm_out_2   EQU   5
pwm_out_3   EQU   4
recv_buffer EQU   0x24
send_buffer EQU   0x2F
servo_pos   EQU   0x43
pwm_value   EQU   0x49
analog_low  EQU   0x4D
analog_high EQU   0x55
cur_analog  EQU   0x5D
servo_mode  EQU   0x5E
cur_servo   EQU   0x5F
pwm_cycle   EQU   0x60
cur_recv_byte EQU   0x61
cur_send_byte EQU   0x62
read_timeout EQU   0x63
reading_data EQU   0
wait_analog EQU   0x65
update_timeout EQU   0x66
running_counter EQU   0x67
recv_counter EQU   0x68
last_valid  EQU   1
last_encoder_0 EQU   2
last_encoder_1 EQU   3
last_encoder_2 EQU   4
last_encoder_3 EQU   5
last_dir    EQU   0x69
encoder_0_count EQU   0x6A
encoder_1_count EQU   0x6B
encoder_2_count EQU   0x6C
encoder_3_count EQU   0x6D
encoder_0_speed EQU   0x6E
encoder_low EQU   0x71
encoder_high EQU   0x75
run_count   EQU   0x6F
svrWREG     EQU   0x70
svrSTATUS   EQU   0x20
tmp         EQU   0x21
dir         EQU   0x21
s           EQU   0x21
C1cnt       EQU   0x22
s_2         EQU   0x21
C2cnt       EQU   0x22
mask        EQU   0x21
ch          EQU   0x23

	ORG 0x0003
	GOTO main

  ; FILE map_bot.c
			;
			;/*
			;    Robot Controller Source
			;	(C) 2006 Jason Hunt nulluser@gmail.com
			;
			;	Version 0.01
			;
			;	16f871.h has been modified as follows:
			;	
			;	// original
			;	// #pragma chip PIC16F871, core 14, code 2048, ram 32 : 0xBF /0 /3
			;
			;	#pragma chip PIC16F871, core 14, code 0x1F00, ram 32 : 0x1FF
			;	#pragma cdata[0] = 0x0180 + 0x0A // CLRF PCLATH, prepare for code page change
			;	#pragma cdata[1] = 0 // NOP
			;	#pragma cdata[2] = 0 // NOP
			;	#pragma resetVector 3 // start address for user program
			;
			;	This reserves space for the serial bootloader.
			;*/
			;
			;#include <int16cxx.h>
			;
			;#pragma chip PIC16f871
			;#pragma config |= 0x3FF2 			// For 20 mhz ceramic resinator
			;
			;
			;#define NUM_RECV_BYTES	11			// Bytes in control packet
			;#define NUM_SEND_BYTES	20			// Bytes in telemetery packet
			;
			;#define NUM_SERVOS	6	   		    // Number of servo outputs
			;
			;#define NUM_ANALOG 8
			;
			;/* Pin Assignments */
			;
			;#pragma bit led_0 @ PORTB.6
			;#pragma bit led_1 @ PORTB.7
			;
			;//#pragma bit encoder_0 @ PORTB.0 // digital in 0
			;//#pragma bit encoder_1 @ PORTA.4
			;//#pragma bit encoder_2 @ PORTE.0
			;//#pragma bit encoder_3 @ PORTE.1
			;
			;#pragma bit encoder_0 @ PORTD.0 // digital in 0
			;#pragma bit encoder_1 @ PORTD.1
			;#pragma bit encoder_2 @ PORTD.2
			;#pragma bit encoder_3 @ PORTD.3
			;
			;
			;//#pragma bit digital_in_4 @ PORTE.2
			;
			;//#pragma bit radio_in_0 @ PORTD.6
			;//#pragma bit radio_in_1 @ PORTD.7
			;
			;//#pragma bit open_collector_0 @ PORTB.4
			;//#pragma bit open_collector_1 @ PORTB.5
			;
			;/* Pin assignments for PWM */
			;#pragma bit pwm_out_0 @ PORTB.1
			;#pragma bit pwm_out_1 @ PORTB.2
			;#pragma bit pwm_out_2 @ PORTB.5
			;#pragma bit pwm_out_3 @ PORTB.4
			;
			;/* Data buffers for serial */
			;unsigned char recv_buffer[NUM_RECV_BYTES];
			;unsigned char send_buffer[NUM_SEND_BYTES];
			;
			;unsigned char servo_pos[NUM_SERVOS];		// Servo Positions
			;unsigned char pwm_value[4];					// PWM Dutysw
			;
			;unsigned char analog_low[8];				// Analog low bytes
			;unsigned char analog_high[8];				// Analog high bytes
			;
			;
			;unsigned char cur_analog;					// Current analog capture
			;
			;unsigned char servo_mode;			// Current state of the servo interrupt system
			;unsigned char cur_servo;			// Current servo 
			;unsigned char pwm_cycle;			// CUrrent PWM cutoff value
			;
			;unsigned char cur_recv_byte;		// Index of recv buffer
			;unsigned char cur_send_byte;		// Index of send buffer
			;unsigned char read_timeout;			// Timeout counter
			;bit reading_data;					// True if reading
			;
			;unsigned char wait_analog;			// True if waiting to start converstion
			;
			;unsigned char update_timeout;
			;
			;unsigned char running_counter;
			;unsigned char recv_counter;
			;bit last_valid;
			;
			;
			;bit last_encoder_0;
			;bit last_encoder_1;
			;bit last_encoder_2;
			;bit last_encoder_3;
			;
			;
			;
			;unsigned char last_dir;
			;
			;unsigned char encoder_0_count;
			;unsigned char encoder_1_count;
			;unsigned char encoder_2_count;
			;unsigned char encoder_3_count;
			;
			;unsigned char encoder_0_speed;
			;
			;
			;unsigned char encoder_low[4];
			;unsigned char encoder_high[4];
			;
			;
			;unsigned char run_count;
			;
			;/*******************
			;** Interrupt Code **
			;*******************/
			;
			;#pragma interruptSaveCheck  n
			;#pragma origin 4
	ORG 0x0004
			;
			;
			;
			;
			;
			;/* the ISR to update the servos */
			;interrupt ISR(void)
			;{
ISR
			;    int_save_registers
	MOVWF svrWREG
	SWAPF STATUS,W
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVWF svrSTATUS
			;
			;    if (RCIF)
	BTFSS 0x0C,RCIF
	GOTO  m011
			;    {
			;        RCIF = 0;
	BCF   0x0C,RCIF
			;		reading_data = 1;
	BSF   0x64,reading_data
			;		read_timeout = 0;
	CLRF  read_timeout
			;
			;		// Eat data and timeout if sync is off
			;		if (!last_valid)
	BTFSC 0x64,last_valid
	GOTO  m001
			;		{
			;			recv_buffer[cur_recv_byte++] = RCREG;  
	MOVLW .36
	ADDWF cur_recv_byte,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  RCREG,W
	MOVWF INDF
	INCF  cur_recv_byte,1
			;			cur_recv_byte = 0;
	CLRF  cur_recv_byte
			;		}
			;
			;
			;		// Send current telemetry data for the first char recevied
			;        // This will utilize full duplex for better transfer
			;		if (cur_recv_byte == 0 && last_valid)
m001	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  cur_recv_byte,1
	BTFSS 0x03,Zero_
	GOTO  m002
	BTFSS 0x64,last_valid
	GOTO  m002
			;		{	   
			;            // Package current telemetry data for transmittion
			;			// Start byte
			;		    send_buffer[0] = 0xff;
	MOVLW .255
	MOVWF send_buffer
			;
			;			// Low bytes of analog data
			;			send_buffer[1] = analog_low[0];
	MOVF  analog_low,W
	MOVWF send_buffer+1
			;			send_buffer[2] = analog_low[1];
	MOVF  analog_low+1,W
	MOVWF send_buffer+2
			;			send_buffer[3] = analog_low[2];
	MOVF  analog_low+2,W
	MOVWF send_buffer+3
			;			send_buffer[4] = analog_low[3];
	MOVF  analog_low+3,W
	MOVWF send_buffer+4
			;			send_buffer[5] = analog_low[4];
	MOVF  analog_low+4,W
	MOVWF send_buffer+5
			;			send_buffer[6] = analog_low[5];
	MOVF  analog_low+5,W
	MOVWF send_buffer+6
			;			send_buffer[7] = analog_low[6];
	MOVF  analog_low+6,W
	MOVWF send_buffer+7
			;			send_buffer[8] = analog_low[7];
	MOVF  analog_low+7,W
	MOVWF send_buffer+8
			;
			;			// Shift MSB of analog data to fit into two bytes
			;			send_buffer[9] = analog_high[0] | (analog_high[1]<<2) ;
	BCF   0x03,Carry
	RLF   analog_high+1,W
	ADDWF analog_high+1,W
	ADDWF analog_high+1,W
	IORWF analog_high,W
	MOVWF send_buffer+9
			;			send_buffer[9] += analog_high[2]<<4;
	SWAPF analog_high+2,W
	ANDLW .240
	ADDWF send_buffer+9,1
			;
			;			unsigned int tmp = analog_high[3] * 64;
	RRF   analog_high+3,W
	MOVWF tmp
	RRF   tmp,1
	RRF   tmp,1
	MOVLW .192
	ANDWF tmp,1
			;			send_buffer[9] += tmp;
	MOVF  tmp,W
	ADDWF send_buffer+9,1
			;
			;
			;			send_buffer[10] = analog_high[4] | (analog_high[5]<<2) ;
	BCF   0x03,Carry
	RLF   analog_high+5,W
	ADDWF analog_high+5,W
	ADDWF analog_high+5,W
	IORWF analog_high+4,W
	MOVWF send_buffer+10
			;			send_buffer[10] += analog_high[6]<<4;
	SWAPF analog_high+6,W
	ANDLW .240
	ADDWF send_buffer+10,1
			;
			;			tmp = analog_high[7] * 64;
	RRF   analog_high+7,W
	MOVWF tmp
	RRF   tmp,1
	RRF   tmp,1
	MOVLW .192
	ANDWF tmp,1
			;			send_buffer[10] += tmp;
	MOVF  tmp,W
	ADDWF send_buffer+10,1
			;
			;//			send_buffer[7] = analog_high[3] | (analog_high[4]<<2);
			;
			;			// Other telemetry data
			;//			send_buffer[8] =run_count;// encoder_0_speed;
			;
			;			send_buffer[11] = encoder_low[0];
	MOVF  encoder_low,W
	MOVWF send_buffer+11
			;			send_buffer[12] = encoder_high[0];
	MOVF  encoder_high,W
	MOVWF send_buffer+12
			;
			;			send_buffer[13] = encoder_low[1];
	MOVF  encoder_low+1,W
	MOVWF send_buffer+13
			;			send_buffer[14] = encoder_high[1];
	MOVF  encoder_high+1,W
	MOVWF send_buffer+14
			;
			;			send_buffer[15] = encoder_low[2];
	MOVF  encoder_low+2,W
	MOVWF send_buffer+15
			;			send_buffer[16] = encoder_high[2];
	MOVF  encoder_high+2,W
	MOVWF send_buffer+16
			;
			;			send_buffer[17] = encoder_low[3];
	MOVF  encoder_low+3,W
	MOVWF send_buffer+17
			;			send_buffer[18] = encoder_high[3];
	MOVF  encoder_high+3,W
	MOVWF send_buffer+18
			;
			;			// Stop byte
			;			send_buffer[19] = 0xff;
	MOVLW .255
	MOVWF send_buffer+19
			;
			;			TXIE = 1;					// Enable transmit to send packet 
	BSF   0x03,RP0
	BSF   0x8C,TXIE
			;		} 
			;
			;		// Last char in packet
			;        if (cur_recv_byte >= NUM_RECV_BYTES)
m002	MOVLW .11
	BCF   0x03,RP0
	BCF   0x03,RP1
	SUBWF cur_recv_byte,W
	BTFSS 0x03,Carry
	GOTO  m010
			;        {
			;			cur_recv_byte = 0;
	CLRF  cur_recv_byte
			;
			;
			;            if (recv_buffer[0] == 0xff && recv_buffer[NUM_RECV_BYTES-1] == 0xff)
	INCFSZ recv_buffer,W
	GOTO  m008
	INCFSZ recv_buffer+10,W
	GOTO  m008
			;            {
			;				// first byte is For digital controls.
			;
			;				unsigned char dir = recv_buffer[1] & 0x03;
	MOVLW .3
	ANDWF recv_buffer+1,W
	MOVWF dir
			;
			;				if (dir != last_dir && recv_buffer[2] != 0 && recv_buffer[3] != 0)
	MOVF  dir,W
	XORWF last_dir,W
	BTFSC 0x03,Zero_
	GOTO  m003
	MOVF  recv_buffer+2,1
	BTFSC 0x03,Zero_
	GOTO  m003
	MOVF  recv_buffer+3,1
	BTFSC 0x03,Zero_
	GOTO  m003
			;				{
			;	led_0 = !led_0;
	MOVLW .64
	XORWF PORTB,1
			;					last_dir = dir;
	MOVF  dir,W
	MOVWF last_dir
			;
			;					encoder_high[0] = 0;
	CLRF  encoder_high
			;					encoder_low[0] = 0;
	CLRF  encoder_low
			;
			;					encoder_high[1] = 0;
	CLRF  encoder_high+1
			;					encoder_low[1] = 0;
	CLRF  encoder_low+1
			;
			;					encoder_high[2] = 0;
	CLRF  encoder_high+2
			;					encoder_low[2] = 0;
	CLRF  encoder_low+2
			;
			;					encoder_high[3] = 0;
	CLRF  encoder_high+3
			;					encoder_low[3] = 0;
	CLRF  encoder_low+3
			;
			;				}
			;
			;				if (recv_buffer[1] & 0x01)
m003	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS recv_buffer+1,0
	GOTO  m004
			;				{
			;					pwm_value[0] = recv_buffer[2];
	MOVF  recv_buffer+2,W
	MOVWF pwm_value
			;					pwm_value[1] = 0;										
	CLRF  pwm_value+1
			;				}
			;				else
	GOTO  m005
			;				{
			;					pwm_value[0] = 0;
m004	BCF   0x03,RP0
	BCF   0x03,RP1
	CLRF  pwm_value
			;					pwm_value[1] = recv_buffer[2];
	MOVF  recv_buffer+2,W
	MOVWF pwm_value+1
			;				}
			;
			;				if (recv_buffer[1] & 0x02)
m005	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS recv_buffer+1,1
	GOTO  m006
			;				{
			;					pwm_value[2] = recv_buffer[3];
	MOVF  recv_buffer+3,W
	MOVWF pwm_value+2
			;					pwm_value[3] = 0;
	CLRF  pwm_value+3
			;				}
			;				else
	GOTO  m007
			;				{
			;					pwm_value[2] = 0;
m006	BCF   0x03,RP0
	BCF   0x03,RP1
	CLRF  pwm_value+2
			;					pwm_value[3] = recv_buffer[3];
	MOVF  recv_buffer+3,W
	MOVWF pwm_value+3
			;				}
			;
			;
			;				// Copy servo data
			;				servo_pos[0] = recv_buffer[4];
m007	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  recv_buffer+4,W
	MOVWF servo_pos
			;				servo_pos[1] = recv_buffer[5];
	MOVF  recv_buffer+5,W
	MOVWF servo_pos+1
			;				servo_pos[2] = recv_buffer[6];
	MOVF  recv_buffer+6,W
	MOVWF servo_pos+2
			;				servo_pos[3] = recv_buffer[7];
	MOVF  recv_buffer+7,W
	MOVWF servo_pos+3
			;				servo_pos[4] = recv_buffer[8];
	MOVF  recv_buffer+8,W
	MOVWF servo_pos+4
			;				servo_pos[5] = recv_buffer[9];
	MOVF  recv_buffer+9,W
	MOVWF servo_pos+5
			;
			;
			;				recv_counter++;
	INCF  recv_counter,1
			;	
			;				if (recv_counter >= 10)
	MOVLW .10
	SUBWF recv_counter,W
	BTFSC 0x03,Carry
			;				{
			;					recv_counter = 0;
	CLRF  recv_counter
			;					//led_1 = !led_1;
			;				}
			;
			;
			;				last_valid = 1;
	BCF   0x03,RP0
	BCF   0x03,RP1
	BSF   0x64,last_valid
			;             } 
			;			else 
	GOTO  m009
			;				last_valid = 0;
m008	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x64,last_valid
			;
			;			reading_data = 0;
m009	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x64,reading_data
			;
			;			update_timeout = 0; // Reset update timeout
	CLRF  update_timeout
			;
			;
			;		}
			;        else
	GOTO  m011
			;    		recv_buffer[cur_recv_byte++] = RCREG;  // Normal char for packet
m010	MOVLW .36
	BCF   0x03,RP0
	BCF   0x03,RP1
	ADDWF cur_recv_byte,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  RCREG,W
	MOVWF INDF
	INCF  cur_recv_byte,1
			;    } 
			;
			;    // Ready for TX byte
			;    if (TXIF && TXIE)
m011	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x0C,TXIF
	GOTO  m013
	BSF   0x03,RP0
	BTFSS 0x8C,TXIE
	GOTO  m013
			;    {
			;		// End of packet?
			;		if(cur_send_byte >= NUM_SEND_BYTES)
	MOVLW .20
	BCF   0x03,RP0
	SUBWF cur_send_byte,W
	BTFSS 0x03,Carry
	GOTO  m012
			;        {
			;			cur_send_byte = 0;					// Reset to first byte for next send
	CLRF  cur_send_byte
			;            TXIE = 0;							// Last byte has been sent, disable tx
	BSF   0x03,RP0
	BCF   0x8C,TXIE
			;		}
			;		else
	GOTO  m013
			;			TXREG = send_buffer[cur_send_byte++]; // Send next byte
m012	MOVLW .47
	BCF   0x03,RP0
	BCF   0x03,RP1
	ADDWF cur_send_byte,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  INDF,W
	MOVWF TXREG
	INCF  cur_send_byte,1
			;    }
			;
			;
			;    // check for timer zero interrupt
			;	if (T0IF)
m013	BTFSS 0x0B,T0IF
	GOTO  m021
			;	{
			;
			;		if (servo_mode == 0) // setupup for base pos wait
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  servo_mode,1
	BTFSS 0x03,Zero_
	GOTO  m016
			;		{
			;			servo_mode = 1; 					   // next trigger we will setup for base delay
	MOVLW .1
	MOVWF servo_mode
			;			OPTION = 4;   					   // reset back into 1:32 prescaled mode
	MOVLW .4
	BSF   0x03,RP0
	MOVWF OPTION_REG
			;
			;			TMR0 = 0xa0;   // set base time delay		
	MOVLW .160
	BCF   0x03,RP0
	MOVWF TMR0
			;			
			;			unsigned char s = 1 << cur_servo; // create mask
	MOVLW .1
	MOVWF s
	MOVF  cur_servo,W
	BTFSC 0x03,Zero_
	GOTO  m015
	MOVWF C1cnt
m014	BCF   0x03,Carry
	BCF   0x03,RP0
	BCF   0x03,RP1
	RLF   s,1
	DECFSZ C1cnt,1
	GOTO  m014
			;
			;	   		PORTC |= s; // turn this one on
m015	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  s,W
	IORWF PORTC,1
			;
			;		} else
	GOTO  m020
			;		if (servo_mode == 1) 					// setup for position hold
m016	BCF   0x03,RP0
	BCF   0x03,RP1
	DECFSZ servo_mode,W
	GOTO  m017
			;		{
			;    		servo_mode = 2;					// next mode will turn off and check for long delay
	MOVLW .2
	MOVWF servo_mode
			;			TMR0 = servo_pos[cur_servo];	// reset the timer to the pos
	MOVLW .67
	ADDWF cur_servo,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVF  INDF,W
	MOVWF TMR0
			;	
			;		} else
	GOTO  m020
			;		if (servo_mode == 2)					// setupfor next servo
m017	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  servo_mode,W
	XORLW .2
	BTFSS 0x03,Zero_
	GOTO  m020
			;		{
			;			servo_mode = 0;						// reset back to base mode
	CLRF  servo_mode
			;
			;			unsigned char s = 1 << cur_servo;  // create mask
	MOVLW .1
	MOVWF s_2
	MOVF  cur_servo,W
	BTFSC 0x03,Zero_
	GOTO  m019
	MOVWF C2cnt
m018	BCF   0x03,Carry
	BCF   0x03,RP0
	BCF   0x03,RP1
	RLF   s_2,1
	DECFSZ C2cnt,1
	GOTO  m018
			;
			;	  	    PORTC &= ~s; // turn the current servo off
m019	BCF   0x03,RP0
	BCF   0x03,RP1
	COMF  s_2,W
	ANDWF PORTC,1
			;	
			;			cur_servo++; // next servo
	INCF  cur_servo,1
			;		
			;			// Setup longer delay to fill the 20 ms window, 
			;			// we need to burn 11ms on average
			;			// 5Mhz clock, 0.0512 MS per increment at 1:256 prescaler
			;			// 11ms / 0.0512 ms = 215 cycles to burn, start time at 40
			;
			;			if (cur_servo == NUM_SERVOS)
	MOVF  cur_servo,W
	XORLW .6
	BTFSS 0x03,Zero_
	GOTO  m020
			;			{
			;				cur_servo = 0;	// reset back the first servo
	CLRF  cur_servo
			;
			;				OPTION = 7;
	MOVLW .7
	BSF   0x03,RP0
	MOVWF OPTION_REG
			;
			;				TMR0 = 40;		// set the value for the longer delay
	MOVLW .40
	BCF   0x03,RP0
	MOVWF TMR0
			;			}
			;		}
			;
			;	    T0IF = 0; // clear timer zero interrupt
m020	BCF   0x0B,T0IF
			;	} 
			;
			;    // check for timer one interrupt
			;	if (TMR1IF)	
m021	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x0C,TMR1IF
	GOTO  m026
			;	{
			;		TMR1L = 0x00;			// reset timer
	CLRF  TMR1L
			;		TMR1H = 0x80;
	MOVLW .128
	MOVWF TMR1H
			;
			;		running_counter++;
	INCF  running_counter,1
			;
			;
			;
			;
			;
			;		if (running_counter >= 20)
	MOVLW .20
	SUBWF running_counter,W
	BTFSS 0x03,Carry
	GOTO  m022
			;		{
			;run_count++;
	INCF  run_count,1
			;			encoder_0_speed = encoder_0_count;
	MOVF  encoder_0_count,W
	MOVWF encoder_0_speed
			;			encoder_0_count = 0;
	CLRF  encoder_0_count
			;	led_1 = !led_1;
	MOVLW .128
	XORWF PORTB,1
			;			running_counter = 0;
	CLRF  running_counter
			;		//	led_0 = !led_0;
			;		}
			;
			;        if (reading_data)
m022	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x64,reading_data
	GOTO  m023
			;        {
			;			read_timeout++;
	INCF  read_timeout,1
			;
			;			// The read has timed out
			;			if (read_timeout >= 4)
	MOVLW .4
	SUBWF read_timeout,W
	BTFSS 0x03,Carry
	GOTO  m023
			;			{
			;				reading_data = 0;				// reset reading
	BCF   0x64,reading_data
			;				cur_recv_byte = 0;				// reset to current byte
	CLRF  cur_recv_byte
			;				last_valid = 1;
	BSF   0x64,last_valid
			;	       }
			;		}
			;
			;
			;		// Update time out
			;		update_timeout++;
m023	BCF   0x03,RP0
	BCF   0x03,RP1
	INCF  update_timeout,1
			;
			;		// Too many timeouts have passed, kill motors
			;		if (update_timeout >= 30)
	MOVLW .30
	SUBWF update_timeout,W
	BTFSS 0x03,Carry
	GOTO  m024
			;		{
			;			update_timeout = 30;
	MOVLW .30
	MOVWF update_timeout
			;			pwm_value[0] = 0;
	CLRF  pwm_value
			;			pwm_value[1] = 0;
	CLRF  pwm_value+1
			;			pwm_value[2] = 0;
	CLRF  pwm_value+2
			;			pwm_value[3] = 0;
	CLRF  pwm_value+3
			;		}
			;
			;
			;		// Check for recevive error
			;    	if (OERR)
m024	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x18,OERR
	GOTO  m025
			;    	{
			;    		CREN = 0;  // reset recieve logic
	BCF   0x18,CREN
			;    		CREN = 1;
	BSF   0x18,CREN
			;    	}
			;
			;
			;
			;		TMR1IF = 0; // clear flag
m025	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x0C,TMR1IF
			;	} 
			;
			;	if (TMR2IF)	
m026	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x0C,TMR2IF
	GOTO  m044
			;	{
			;//		led_0 = encoder_0;
			;
			;		if (encoder_0 != last_encoder_0)
	BTFSC 0x08,encoder_0
	GOTO  m027
	BTFSC 0x64,last_encoder_0
	GOTO  m028
	GOTO  m029
m027	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x64,last_encoder_0
	GOTO  m029
			;		{
			;			encoder_low[0]++;
m028	INCF  encoder_low,1
			;
			;			if (encoder_low[0] == 0)
	BTFSC 0x03,Zero_
			;				encoder_high[0]++;
	INCF  encoder_high,1
			;
			;
			;			last_encoder_0 = encoder_0;
	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x64,last_encoder_0
	BTFSC 0x08,encoder_0
	BSF   0x64,last_encoder_0
			;			encoder_0_count++;
	INCF  encoder_0_count,1
			;		}
			;
			;		if (encoder_1 != last_encoder_1)
m029	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x08,encoder_1
	GOTO  m030
	BTFSC 0x64,last_encoder_1
	GOTO  m031
	GOTO  m032
m030	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x64,last_encoder_1
	GOTO  m032
			;		{
			;			encoder_low[1]++;
m031	INCF  encoder_low+1,1
			;
			;			if (encoder_low[1] == 0)
	BTFSC 0x03,Zero_
			;				encoder_high[1]++;
	INCF  encoder_high+1,1
			;
			;			last_encoder_1 = encoder_1;
	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x64,last_encoder_1
	BTFSC 0x08,encoder_1
	BSF   0x64,last_encoder_1
			;			encoder_1_count++;
	INCF  encoder_1_count,1
			;		}
			;
			;
			;		if (encoder_2 != last_encoder_2)
m032	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x08,encoder_2
	GOTO  m033
	BTFSC 0x64,last_encoder_2
	GOTO  m034
	GOTO  m035
m033	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x64,last_encoder_2
	GOTO  m035
			;		{
			;			encoder_low[2]++;
m034	INCF  encoder_low+2,1
			;
			;			if (encoder_low[2] == 0)
	BTFSC 0x03,Zero_
			;				encoder_high[2]++;
	INCF  encoder_high+2,1
			;
			;
			;			last_encoder_2 = encoder_2;
	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x64,last_encoder_2
	BTFSC 0x08,encoder_2
	BSF   0x64,last_encoder_2
			;			encoder_2_count++;
	INCF  encoder_2_count,1
			;		}
			;
			;		if (encoder_3 != last_encoder_3)
m035	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x08,encoder_3
	GOTO  m036
	BTFSC 0x64,last_encoder_3
	GOTO  m037
	GOTO  m038
m036	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSC 0x64,last_encoder_3
	GOTO  m038
			;		{
			;			encoder_low[3]++;
m037	INCF  encoder_low+3,1
			;
			;			if (encoder_low[3] == 0)
	BTFSC 0x03,Zero_
			;				encoder_high[3]++;
	INCF  encoder_high+3,1
			;
			;			last_encoder_3 = encoder_3;
	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x64,last_encoder_3
	BTFSC 0x08,encoder_3
	BSF   0x64,last_encoder_3
			;			encoder_3_count++;
	INCF  encoder_3_count,1
			;		}
			;
			;		pwm_cycle++;
m038	BCF   0x03,RP0
	BCF   0x03,RP1
	INCFSZ pwm_cycle,1
			;
			;		// Check for cycle starts.
			;		// Do not set the pin if the value is zero
			;		if (pwm_cycle == 0 && pwm_value[0]) pwm_out_0 = 1; 
	GOTO  m039
	MOVF  pwm_value,1
	BTFSS 0x03,Zero_
	BSF   0x06,pwm_out_0
			;		if (pwm_cycle == 0 && pwm_value[1]) pwm_out_1 = 1;
m039	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,1
	BTFSS 0x03,Zero_
	GOTO  m040
	MOVF  pwm_value+1,1
	BTFSS 0x03,Zero_
	BSF   0x06,pwm_out_1
			;		if (pwm_cycle == 0 && pwm_value[2]) pwm_out_2 = 1; 
m040	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,1
	BTFSS 0x03,Zero_
	GOTO  m041
	MOVF  pwm_value+2,1
	BTFSS 0x03,Zero_
	BSF   0x06,pwm_out_2
			;		if (pwm_cycle == 0 && pwm_value[3]) pwm_out_3 = 1;
m041	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,1
	BTFSS 0x03,Zero_
	GOTO  m042
	MOVF  pwm_value+3,1
	BTFSS 0x03,Zero_
	BSF   0x06,pwm_out_3
			;
			;		// turn outputs off after their duty has passed
			;		if (pwm_cycle > pwm_value[0]) pwm_out_0 = 0;
m042	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,W
	SUBWF pwm_value,W
	BTFSS 0x03,Carry
	BCF   0x06,pwm_out_0
			;		if (pwm_cycle > pwm_value[1]) pwm_out_1 = 0;
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,W
	SUBWF pwm_value+1,W
	BTFSS 0x03,Carry
	BCF   0x06,pwm_out_1
			;		if (pwm_cycle > pwm_value[2]) pwm_out_2 = 0;
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,W
	SUBWF pwm_value+2,W
	BTFSS 0x03,Carry
	BCF   0x06,pwm_out_2
			;		if (pwm_cycle > pwm_value[3]) pwm_out_3 = 0;
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVF  pwm_cycle,W
	SUBWF pwm_value+3,W
	BTFSS 0x03,Carry
	BCF   0x06,pwm_out_3
			;
			;	//	TMR2 = 0xe0; // reset timer  this is about 500 hz
			;
			;		TMR2 = 0xd0; // reset timer  this is about 500 hz
	MOVLW .208
	BCF   0x03,RP0
	BCF   0x03,RP1
	MOVWF TMR2
			;
			;	//	TMR2 = 0x20;
			;
			;		// See if we are waiting to start the A->D
			;		// Also, make sure it's not already running
			;		if (wait_analog && !GO)
	MOVF  wait_analog,1
	BTFSC 0x03,Zero_
	GOTO  m043
	BTFSC 0x1F,GO
	GOTO  m043
			;		{
			;			// Reduce wait count
			;			wait_analog--;
	DECF  wait_analog,1
			;
			;			// Done waiting, start the converter
			;			if (wait_analog == 0) 
	BTFSC 0x03,Zero_
			;                GO = 1;
	BSF   0x1F,GO
			;		}
			;
			;		TMR2IF = 0; // clear flag
m043	BCF   0x03,RP0
	BCF   0x03,RP1
	BCF   0x0C,TMR2IF
			;	}
			;
			;	// The analog to digital converter is done
			;    if (ADIF)
m044	BCF   0x03,RP0
	BCF   0x03,RP1
	BTFSS 0x0C,ADIF
	GOTO  m045
			;    {  
			;		// Save current values
			;		analog_low[cur_analog] = ADRESL;
	MOVLW .77
	ADDWF cur_analog,W
	MOVWF FSR
	BCF   0x03,IRP
	BSF   0x03,RP0
	MOVF  ADRESL,W
	MOVWF INDF
			;		analog_high[cur_analog] = ADRESH & 0x03;
	MOVLW .85
	BCF   0x03,RP0
	ADDWF cur_analog,W
	MOVWF FSR
	BCF   0x03,IRP
	MOVLW .3
	ANDWF ADRESH,W
	MOVWF INDF
			;
			;		// Setup for next analog channel
			;     	cur_analog++;
	INCF  cur_analog,1
			;
			;		// Wrap arund back to first
			;    	if (cur_analog >= NUM_ANALOG) cur_analog = 0;
	MOVLW .8
	SUBWF cur_analog,W
	BTFSC 0x03,Carry
	CLRF  cur_analog
			;
			;		// Create mask for new channel
			;    	unsigned char mask = cur_analog << 3;
	BCF   0x03,Carry
	BCF   0x03,RP0
	BCF   0x03,RP1
	RLF   cur_analog,W
	MOVWF mask
	BCF   0x03,Carry
	RLF   mask,1
	BCF   0x03,Carry
	RLF   mask,1
			;
			;    	ADCON0 &= 0b.1100.0111;
	MOVLW .199
	ANDWF ADCON0,1
			;    	ADCON0 |= mask; // mask off channel bits, and set new channel
	MOVF  mask,W
	IORWF ADCON0,1
			;
			;		// Setup to wait to fire the go signal
			;		wait_analog = 200;
	MOVLW .200
	MOVWF wait_analog
			;
			;		ADIF = 0;		// Clear flag
	BCF   0x0C,ADIF
			;    }
			;
			;    int_restore_registers
m045	BCF   0x03,RP0
	BCF   0x03,RP1
	SWAPF svrSTATUS,W
	MOVWF STATUS
	SWAPF svrWREG,1
	SWAPF svrWREG,W
			;}
	RETFIE
			;/* end of interrupt service routine */
			;
			;/**************************
			;** End of interrupt Code **
			;**************************/
			;
			;
			;/***********************
			;**	Serial functions **
			;***********************/
			;
			;/* Set the serial port to  9600 8N1 */
			;void setup_serial(void)
			;{
setup_serial
			;//	SPBRG = 129;   // divisor for 9600 baud
			;	SPBRG = 64;    // divisor for 19200 baud
	MOVLW .64
	BSF   0x03,RP0
	BCF   0x03,RP1
	MOVWF SPBRG
			;
			;    TXSTA = 0b.0010.0100;  // transmitt enable, high speed
	MOVLW .36
	MOVWF TXSTA
			;	RCSTA = 0b.1001.0000; // serial enable
	MOVLW .144
	BCF   0x03,RP0
	MOVWF RCSTA
			;
			;	char ch = RCREG;  // flush buffer
	MOVF  RCREG,W
	MOVWF ch
			;	ch = RCREG;
	MOVF  RCREG,W
	MOVWF ch
			;	ch = RCREG;
	MOVF  RCREG,W
	MOVWF ch
			;}
	RETURN
			;/* end of setup serial */
			;
			;
			;
			;
			;/*******************
			;** Initialization **
			;*******************/
			;
			;/* system startup */
			;void startup( void )
			;{
startup
			;	PORTA = 0;			// clear ports
	BCF   0x03,RP0
	BCF   0x03,RP1
	CLRF  PORTA
			;	PORTB = 0;
	CLRF  PORTB
			;	PORTC = 0;
	CLRF  PORTC
			;	PORTD = 0;
	CLRF  PORTD
			;	PORTE = 0;
	CLRF  PORTE
			;
			;	TRISA = 0b.1111.1111;	// all inputs
	MOVLW .255
	BSF   0x03,RP0
	MOVWF TRISA
			;	TRISB = 0b.0000.0001;	// bit 0 is digital in 2, bit 3 is led1
	MOVLW .1
	MOVWF TRISB
			;	TRISC = 0b.1000.0000;	// bit 7 is rx
	MOVLW .128
	MOVWF TRISC
			;//	TRISD = 0b.1100.0000;	// D6, D7 radio in, all others digital out
			;
			;	TRISD = 0b.0000.1111;	// D6, D7 radio in, all others digital out
	MOVLW .15
	MOVWF TRISD
			;
			;	TRISE = 0b.0000.0111;	// E0-E2 digital in
	MOVLW .7
	MOVWF TRISE
			;
			;
			;//		ADCON0 = 0b.1000.0001 | mask;
			;
			;	// clear core values before interrupts are turned on
			;
			;    running_counter = 0;
	BCF   0x03,RP0
	CLRF  running_counter
			;    recv_counter = 0;
	CLRF  recv_counter
			;
			;
			;	servo_mode = 0;			// finite state machine for servo control
	CLRF  servo_mode
			;	cur_servo = 0;			// current servo number
	CLRF  cur_servo
			;	pwm_cycle = 0;			// state of pwm system
	CLRF  pwm_cycle
			;
			;	pwm_value[0] = 0;
	CLRF  pwm_value
			;	pwm_value[1] = 0;
	CLRF  pwm_value+1
			;	pwm_value[2] = 0;
	CLRF  pwm_value+2
			;	pwm_value[3] = 0;
	CLRF  pwm_value+3
			;
			;
			;
			;	// setup timer 0
			;    OPTION = 4;				// prescaler divide by 16
	MOVLW .4
	BSF   0x03,RP0
	MOVWF OPTION_REG
			;	T0CS = 0;				// internel clock
	BCF   0x81,T0CS
			;    TMR0 = 0;				// clear the timer
	BCF   0x03,RP0
	CLRF  TMR0
			;    T0IE = 1;				// enable interrupt for timer 0
	BSF   0x0B,T0IE
			;
			;
			;	// setup timer 1
			;	TMR1L = 0;			// reset timer
	CLRF  TMR1L
			;	TMR1H = 0;
	CLRF  TMR1H
			;
			;	TMR1ON = 0; 			// shut off timer to modify values
	BCF   0x10,TMR1ON
			;
			;	T1CKPS1 = 1;			// setup prescaler
	BSF   0x10,T1CKPS1
			;	T1CKPS0 = 0;
	BCF   0x10,T1CKPS0
			;	T1OSCEN = 0;			// shut off oscillator
	BCF   0x10,T1OSCEN
			;
			;	TMR1CS = 0;				// internal clock
	BCF   0x10,TMR1CS
			;	TMR1IE = 1;				// enable interrupt
	BSF   0x03,RP0
	BSF   0x8C,TMR1IE
			;
			;	TMR1ON = 1; 			// turn timer on
	BCF   0x03,RP0
	BSF   0x10,TMR1ON
			;	TMR1IF = 0;				// clear interrupt flag
	BCF   0x0C,TMR1IF
			;
			;	TMR2 = 0xe0;
	MOVLW .224
	MOVWF TMR2
			;	TMR2ON = 1;				// enable timer 2
	BSF   0x12,TMR2ON
			;	TMR2IE = 1;
	BSF   0x03,RP0
	BSF   0x8C,TMR2IE
			;
			;	servo_pos[0] = 0x80;	// setup inital servo positions
	MOVLW .128
	BCF   0x03,RP0
	MOVWF servo_pos
			;	servo_pos[1] = 0x80;	
	MOVLW .128
	MOVWF servo_pos+1
			;	servo_pos[2] = 0x80;
	MOVLW .128
	MOVWF servo_pos+2
			;	servo_pos[3] = 0x80;	
	MOVLW .128
	MOVWF servo_pos+3
			;	servo_pos[4] = 0x80;	
	MOVLW .128
	MOVWF servo_pos+4
			;	servo_pos[5] = 0x80;
	MOVLW .128
	MOVWF servo_pos+5
			;
			;   update_timeout = 0;
	CLRF  update_timeout
			;
			;   reading_data = 0;
	BCF   0x64,reading_data
			;   read_timeout = 0;
	CLRF  read_timeout
			;   cur_recv_byte = 0; // Waiting for first byte
	CLRF  cur_recv_byte
			;   cur_send_byte = 0; // Waiting for first byte
	CLRF  cur_send_byte
			;	last_valid = 1;
	BSF   0x64,last_valid
			;
			;   RCIF = 0;	// Clear receive interrupt
	BCF   0x0C,RCIF
			;   RCIE = 1; 	// Enable receive interrupts
	BSF   0x03,RP0
	BSF   0x8C,RCIE
			;
			;   TXIF = 0;	// Clear receive interrupt
	BCF   0x03,RP0
	BCF   0x0C,TXIF
			;   TXIE = 1; 	// Enable receive interrupts
	BSF   0x03,RP0
	BSF   0x8C,TXIE
			;
			;
			;	// Analog to Digital Setup
			;    cur_analog = 0;
	BCF   0x03,RP0
	CLRF  cur_analog
			;
			;//	ADCON1 = 0b.1000.0010;	// RE0, 1, 2 : digital RA0,1,2,3,5 : analog
			;
			;	ADCON1 = 0b.1000.0000;	// RE0, 1, 2 : digital RA0,1,2,3,5 : analog
	MOVLW .128
	BSF   0x03,RP0
	MOVWF ADCON1
			;
			;
			;	ADCS1 = 1;				// Fosc/32 clocl
	BCF   0x03,RP0
	BSF   0x1F,ADCS1
			;	ADCS0 = 0;
	BCF   0x1F,ADCS0
			;	ADCON0 &= 0b.1100.0111;
	MOVLW .199
	ANDWF ADCON0,1
			;	ADON = 1;					// turn on converter
	BSF   0x1F,ADON
			;
			;    ADIF =0;
	BCF   0x0C,ADIF
			;    ADIE =1;
	BSF   0x03,RP0
	BSF   0x8C,ADIE
			;
			;	GO = 1;
	BCF   0x03,RP0
	BSF   0x1F,GO
			;	
			;    GIE = 1;				// interrupts allowed 
	BSF   0x0B,GIE
			;	PEIE = 1;				// enable periphial interrupts
	BSF   0x0B,PEIE
			;
			;encoder_0_count = 0;
	CLRF  encoder_0_count
			;encoder_0_speed = 0;
	CLRF  encoder_0_speed
			;
			;
			;	encoder_low[0] = 0;
	CLRF  encoder_low
			;	encoder_high[0] = 0;
	CLRF  encoder_high
			;	encoder_low[1] = 0;
	CLRF  encoder_low+1
			;	encoder_high[1] = 0;
	CLRF  encoder_high+1
			;	encoder_low[2] = 0;
	CLRF  encoder_low+2
			;	encoder_high[2] = 0;
	CLRF  encoder_high+2
			;	encoder_low[3] = 0;
	CLRF  encoder_low+3
			;	encoder_high[3] = 0;
	CLRF  encoder_high+3
			;
			;last_dir = 0;
	CLRF  last_dir
			;run_count = 0;
	CLRF  run_count
			;}
	RETURN
			;/* end of startup */
			;
			;/**************************
			;** End of Initialization **
			;**************************/
			;
			;
			;
			;/****************************************
			;**	Serial command interface functions **
			;****************************************/
			;
			;
			;
			;/* deal with digital out command */
			;/*void digital_out_command ( void )
			;{
			;	unsigned char n = get_hex_nibble(); // get output number
			;
			;	if (n > 5) return;	// range check
			;
			;	unsigned shift = 1 << n; // create bit mask
			;
			;	unsigned char v = get_hex_nibble(); // get value (on or off)
			;
			;	if( v == 0)
			;	{
			;		shift = 255 - shift; // and mask
			;		PORTD &=  shift;
			;	}
			;
			;	if (v == 1)
			;		PORTD |= shift;   // or mask
			;}*/
			;/* end of digital_out_command */
			;
			;/* return the valur of a digital input */
			;/*bit get_digital_value(unsigned char n)
			;{
			;	if (n == 0) return(digital_in_0); else
			;	if (n == 1) return(digital_in_1); else
			;	if (n == 2) return(digital_in_2); else
			;	if (n == 3) return(digital_in_3); else
			;	if (n == 4) return(digital_in_4);
			;
			;	return(0);
			;}*/
			;/* end of get_digital_value */
			;
			;
			;/***********************************************
			;**	End of serial command interface functions **
			;***********************************************/
			;
			;/* Read data from sonar sensor */
			;// The parmeter is the input /output pair number
			;// for example passing '2' will use input 2 and output 2
			;//
			;/*void get_sonar_command( void )
			;{
			;	unsigned char n = get_hex_nibble(); 
			;
			;	unsigned char mask = 1 << n;
			;
			;    PORTD |= mask;   // turn output on
			;
			;	delay(0x8);
			;
			;	PORTD &= ~mask;   // turn output off
			;
			;	TMR1H = 0;
			;
			;	while(!get_digital_value(n) && TMR1H < 0x80);
			;
			;	TMR1H = 0;
			;	TMR1L = 0;
			;
			;	// Read the pulse width
			;	while(get_digital_value(n) && TMR1H < 0x80);
			;
			;	unsigned char l = TMR1L;			// Save low order, it will change during transmittion
			;
			;	send_hex(TMR1H);
			;	send_hex(l);
			;}*/
			;/* End of read sonar */
			;
			;
			;
			;
			;
			;/* main function */
			;void main ( void )
			;{
main
			;	startup();
	CALL  startup
			;
			;	setup_serial();
	CALL  setup_serial
			;
			;	while (1);	// infinte loop
m046	GOTO  m046

	ORG 0x0000
	DATA 018AH
	DATA 0000H
	DATA 0000H
	ORG 0x2007
	DATA 3FF2H
	END


; *** KEY INFO ***

; 0x0004 P0  559 word(s) 27 % : ISR
; 0x0233 P0   16 word(s)  0 % : setup_serial
; 0x0243 P0  109 word(s)  5 % : startup
; 0x02B0 P0    3 word(s)  0 % : main

; RAM usage: 89 bytes (5 local), 247 bytes free
; Maximum call level: 1 (+1 for interrupt)
;  Codepage 0 has  691 word(s) :  33 %
;  Codepage 1 has    0 word(s) :   0 %
;  Codepage 2 has    0 word(s) :   0 %
;  Codepage 3 has    0 word(s) :   0 %
; Total of 691 code words (8 %)
