'****************************************************************
'*  Name    : Neo_PIC_xelType15.bas                              *
'*  Author  : Original Idea From :Michel Jasmin					*
'*  Notice  : NO Copyright (c) 2014 Michel Jasmin  ;)           *
'*          : No Rights Reserved                                *
'*			: Major rewrite by: David Purola (N8NTA)			*
'*			: Please incorporate this header if reusing			*
'*  Date    : 2015-06-14                                        *
'*  Version : 3.0                                               *
'*  Notes   : Demo how to use WS2812B (NeoPixels) on            *
'*          :a PIC16F1825 @40 MHz.								*
'****************************************************************
'	Rewritten for PIC16F1825 @ 40 mhz (10 mHZ. resonator  w/4 x PLL).(06/07/2015)
'	Made operational w/6 message storage and enough memory for 240 pixels of
'storage in RAM. This equates to a full 4 meter string of NeoPixels.
'Program was re-written to break-up memory into 80 byte pages as this is
'a limitation of this 16F1825 processor. (06/10/2015)
'
'	Careful attention was payed to the use of BYTE elements and not WORD
'elements for added speed. Direct_NeoPixelASM40 was also Rewritten to be called
'by this program to generate the actual bit stream.(06/16/2015)
'
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'			OH WELL IT'S TIME FOR SOME DOCUMENTATION I SUPPOSE:
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'	Well the jist of this code is to make something similar to a project I saw
'using a duino for the controller. This guy made a hat with a scrolling display
'using some of the Adafruit NeoPixel strips. Well me not being an expert at the
'C language unless I'm at work, I decided to try my hand designing a similar
'project with the exception of using a PIC for the controller. I could not find
'a low pin count device with at least 2K of ram so, I ended up using an 18F26K22.
'	When I originally saw the project on the pic forum that someone used an 12F683
'I reproduced the project. I was somewhat disapointed that the software encoding
'for the bit stream was not dynamic in nature. That meant that if you wanted to
'change a message you would have to hardcode that into program memory and re-compile.
'	That got me inspired, so I decided to use an 12F1840 running @ 32Mhz. and develope
'am assembly routine to dynamicly encode the bit stream from a buffered message
'on demand. Well I was successful in getting the encoder asm. code to work
'as well as the duino code available on the web. Now I needed to add some frills
'but the small 8 pin processor was running a bit low on resources so, here I am
'with an 18F26K22 processor with a BUTT LOAD of extra pins and enough ram as the
'code stands today to support 24 6x7 characters. I only need 3 pins, 1 for the
'NeoPixels, and 2 for the communications. I opted to use the internal oscillator
'to eliminate the external xtal for parts count. The communication port is
'connected to an JY-MCU Blue Tooth Module HC-03 for data entry and retrieval.
'	That way I can program new messages with anything that has a blue tooth
'connection like a smart phone or tablet or PC. I have been working non stop
'on this project for the last 2 days and it's time for a data dump before I forget.
'	The software is working flawlessly at this point and all looks good on the
'scope as that is all I have to hook up to it at the moment. I have a reel of
'NeoPixels on the way but won't be here till Tuesday 12/09. So on with the
'documentation...... 

'	Well here I am again, This time trying to get the same bang for the buck with
'a smaller PIC. This time I decided to use an 16F1825 because of the lower pin
'count but with the most ram for its size. Well I did it and only sacraficed 4
'of the stored messages. I also decreased the size of them a few bytes or so.

'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'						SERIAL COMMAND SUMMARY
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'
'-	UPTO 3 DIGITS FOLLOWED BY (Ctrl B) CR = 3 DIGIT NUMBER REPRESENTING BACKGROUND
'BLUE INTENSITY 0-255 THEN (Ctrl B) FOLLOWED BY CARRAGE RETURN. (FORGROUND/BACKGROUND
'SELECTION DEFAULTS TO FORGROUNG AFTER ENTRY)

'-	UPTO 3 DIGITS FOLLOWED BY (Ctrl G) CR = 3 DIGIT NUMBER REPRESENTING BACKGROUND
'GREEN INTENSITY 0-255 THEN (Ctrl G) FOLLOWED BY CARRAGE RETURN. (FORGROUND/BACKGROUND
'SELECTION DEFAULTS TO FORGROUNG AFTER ENTRY)

'-	UPTO 3 DIGITS FOLLOWED BY (Ctrl R) CR = 3 DIGIT NUMBER REPRESENTING BACKGROUND
'RED INTENSITY 0-255 THEN (Ctrl R) FOLLOWED BY CARRAGE RETURN. (FORGROUND/BACKGROUND
'SELECTION DEFAULTS TO FORGROUNG AFTER ENTRY)

'-	(Ctrl A) TOGGLES A/D ENTRY OF COLORS GREEN, BLUE, and RED BY READING POT VALUES
'FROM AN0,AN1,AN2 RESPECTIVLY.

'-	UPTO 4 DIGITS FOLLOWED BY (Ctrl D) CR = 4 DIGIT NUMBER REPRESENTING SCROLLING
'DELAY IN Milliseconds WITH A MAXIMUM OF 1000 (1 SECOND) AND A MINIMUM OF 1. THIS
'VALUE IS STORED ONCE FOR EACH MODE OF OPERATION AND RECALLED DEPENDING ON MODE.

'-	(Ctrl E) PRECEEDING ANY OF THE ABOVE COMMANDS SETS THE BACKGROUND COLORS (PIXELS
'ILLUMINATED). IF THIS COMMAND IS LEFT OUT OF COLOR SELECTION PROCESS, DEFAULT IS FORGROUND.

'-	(Ctrl F) PRECEEDING ANY OF THE ABOVE COMMANDS SETS THE FORGROUND COLORS (PIXELS
'ILLUMINATED). IF THIS COMMAND IS LEFT OUT OF COLOR SELECTION PROCESS, DEFAULT IS FORGROUND.

'-	(Ctrl T) IS THE START OF TEXT STRING COMMAND.

'-	(Ctrl X) IS THE END OF TEXT STRING COMMAND.
'THE USAGE WOULD LOOK LIKE: (Ctrl T) THEN A STRING OF UPTO 39 CHARACTERS or NUMBERS
'FOLLOWED BY (Ctrl X) THEN CARRAGE RETURN

'-	(Ctrl Z) CR = READBACK OF CURRENTLY DISPLAYED TEXT MESSAGE.

'-	1 DIGIT (Ctrl W) CR = WRITING CURRENTLY DISPLAYED TEXT STRING TO MEMORY LOCATION
'PRESEEDING THE (Ctrl W) COMMAND. LOCATIONS ARE 0 THRU 5 DECIMAL. (COLORS ARE ALSO STORED)

'-	1 DIGIT (Ctrl S) CR = RETRIEVING TEXT STRING FROM THE MEMORY LOCATION PRESEEDING
'THE (Ctrl S) COMMAND. LOCATIONS ARE 0 THRU 5 DECIMAL. (COLORS ARE ALSO RETRIEVED)

'-	(Ctrl Q) CR = RECALL OF CURRENT FORGROUND GREEN, BLUE, RED INTENSITY VALUES ON ONE LINE
'FOLLOWED BY BACKGROUND GREEN, BLUE, RED INTENSITY VALUES ON ONE LINE.
'
'-	(Ctrl L) CR = TOGGLE LOOPING OF ALL STORED MESSDAGES 0-5.
'
'-	(Ctrl O) CR = TOGGLE ALL COLOR TEST and OPERATION MODEs FOR ENTIRE STRIP.
'DEFAULT POWER-ON MODE IS 0.
'
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'						AND NOW ON WITH THE CODE......
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

DEFINE OSC 20	'ACTUAL FREQUENCY IS 40 Mhz. THIS DEFINE ONLY USED BY PAUSEUS COMMAND
DEFINE NO_CLRWDT 1
DEFINE LOADER_USED 1	    
DEFINE WRITE_INT 1

DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 4
DEFINE DEBUG_BAUD 19200
DEFINE DEBUG_MODE 0	'0 = TRUE 1 = INVERTED

INCLUDE "C:\PBP\INCLUDES\DT_INTS-14.bas"      	' Interrupt Control routines	
INCLUDE "C:\PBP\INCLUDES\ReEnterPBP-14.bas"     ' Interrupt Control routines	

#CONFIG
;----- CONFIG1 Options --------------------------------------------------
    __config _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON

;----- CONFIG2 Options --------------------------------------------------
    __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG

' ********************************************************************
'				Declare Port Variables
' ********************************************************************
ANALOG_0	VAR	PORTA.0	'1-GREEN COLOR ADJUSTMENT POT (DEVELOPMENT ONLY)
ANALOG_1	VAR	PORTA.1	'1-BLUE COLOR ADJUSTMENT POT (DEVELOPMENT ONLY)
ANALOG_2	VAR	PORTC.2	'1-RED COLOR ADJUSTMENT POT (DEVELOPMENT ONLY)
RST			VAR	PORTA.3	'1-RESET/MCLR
PA4			VAR	PORTA.4	'0-OSCOUT
PA5			VAR	PORTA.5	'1-OSCIN

NEOPIN	    VAR	LATC.0	'0-OUTPUT TO NEO_PIXEL STRIP                      `	
TESTPIN		VAR	LATC.1	'0-OUTPUT TO TEST CODE WITH (DEVELOPMENT ONLY)
TESTPIN1	VAR	LATC.2	'0-OUTPUT TO TEST CODE WITH (DEVELOPMENT ONLY)
TESTPIN2	VAR	LATC.3	'0-OUTPUT TO TEST CODE WITH (DEVELOPMENT ONLY)
COMOUT		VAR	PORTC.4	'0-OUTPUT COMMUNICATIONS PORT PIN RS-232 (BLUE TOOTH)
COMIN		VAR	PORTC.5	'1-INPUT COMMUNICATIONS PORT PIN RS-232 (BLUE TOOTH)

' ********************************************************************
'------------ DEFINE CONSTANTS -------------------------
' ********************************************************************
BAUD		CON	260		'TX/RX BAUD RATE (40000000/4/38400) - 1 HIGH BAUD/16 BIT
INSIZE		CON	15		'INPUT ARRAY SIZE FOR COMMUNICATIONS
OUTSIZE		CON	15		'OUTPUT ARRAY SIZE FOR COMMUNICATIONS
RXTIMEOUT	CON	1000	'TIMEOUT FOR DATA COMMUNICATIONS (BUFFER CLEAR, 10s. BETWEEN CHARACTERS)
ONESIXTH	CON	OUTSIZE / 6	'BUFFER EMPTY POINT
FIVESIXTH	CON	ONESIXTH * 5	'BUFFER FULL POINT

'||||||||||||||||| THIS YEILDS ~6, 6 x 7 CHARACTERS |||||||||||||||||||||||||||||
FULLSTRING	CON	240	'TOTAL NUMBER OF PIXELS IN ATTACHED STRING (4 METER REEL UNCUT)
MATRIXNUM	CON	238	'TOTAL NUMBER OF PIXELS IN CONFIGURED MATRIX (5.66 CHARACTERS)
COL_P_CHR	CON	6	'COLLUMS PER CHARACTER (1 BLANK BETWEEN ADJACENT CHARACTERS)
ROW_P_CHR	CON	7	'ROWS PER CHARACTER
PIX_P_ROW	CON	MATRIXNUM / ROW_P_CHR		'PIXELS PER HORIZONTAL ROW
COLORMAX 	CON 63	'MAXIMUM INTENSITY LEVEL (TO REDUCE POWER ON BATTERIES)
'|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

COLORSIZE	CON	6		'TOTAL NUMBER OF COLOR STORAGE CELLS
BUFSIZE		CON	32		'MAXUMUM INPUT MESSAGE LENGTH
MAXMESS		CON	6		'TOTAL NUMBER OF STORED MESSAGES
TOTALTEXT	CON	MAXMESS * BUFSIZE
TOTALCOLR	CON	MAXMESS * COLORSIZE
MAXMODES	CON	4		'MAXIMUM NUMBER OF MODES
MODEBYTES	CON	MAXMODES * 2

E_TEXT		CON	0		'STARTING LOCATION FOR TEXT MESSAGE STORAGE
E_COLORS	CON	E_TEXT + TOTALTEXT	'STARTING LOCATION FOR MESSAGE COLOR STORAGE
E_CONFIG	CON	E_COLORS + TOTALCOLR	'STARTING LOCATION FOR MESSAGE CONFIG STORAGE
E_DELAY		CON E_CONFIG + 1	'STARTING LOCATION OF SCROLLING DELAY VARIABLE
INTRO		CON	E_DELAY + MODEBYTES		'STARTING LOCATION FOR SPLASH SCREEN TEXT

EEPROM E_CONFIG,[0]
EEPROM INTRO,["Neo_PIC_xelType15",0]

' ********************************************************************
'------------------- ALIASES ----------------------
' ********************************************************************
ON_			CON	1
OFF_		CON	0
UP			CON	1
DOWN		CON	0

' ********************************************************************
'*********************** USART # 1 *********************************
' ********************************************************************
TX_BYTES   VAR BYTE(OUTSIZE + 1)   'DATA TO HSEROUT TRANSMITIONS
TX_INPUT   VAR BYTE 	'TRANSMIT CHARACTER POINTER (INTERRUPT)
TX_OUTPUT  VAR BYTE 	'TRANSMIT CHARACTER POINTER (MAINCODE)
TX_DAVAIL  VAR BYTE 	'TRANSMITTER DATA AVAILABLE

RX_BYTES   VAR BYTE(INSIZE + 1)	'DATA FROM HSERIN TRANSMITIONS
RX_OUTPUT  VAR BYTE  	'RECEIVED CHARACTER POINTER (INTERRUPT)
RX_INPUT   VAR BYTE     'RECEIVED CHARACTER POINTER (MAINCODE)
RX_DAVAIL  VAR BYTE     'RECEIVER DATA AVAILABLE
JUNKRX     VAR BYTE     'SCRATCH VARIABLE FOR RECEIVER
RXTIMER    VAR WORD     'RECEIVED MESSAGE TIMER

' ********************************************************************
'------------ Variable Bits -------------------------
' ********************************************************************
BITSWORD	VAR	WORD	'BITS FOR STORAGE
TX_EMPTY	VAR BITSWORD.0	'TRANSMIT BUFFER EMPTY FLAG
RX_BUFFULL	VAR BITSWORD.1  'RECEIVER BUFFER FULL FLAG
RX_MESSAGE	VAR BITSWORD.2	'MESSAGE RECEIVED FLAG
COWS_HOME	VAR BITSWORD.3	'LOOP FLAG
TX2PAR		VAR	BITSWORD.4	'PARITY ENABLE FLAG
PARITYTYPE	VAR BITSWORD.5	'PARITY TYPE (1=ODD/0=EVEN)
CLEARINPT	VAR BITSWORD.6	'INPUT FLAG
TXTENAB		VAR BITSWORD.7	'INPUT BUFFER ENABLE FLAG
FOR_BAK		VAR BITSWORD.8	'FORGROUND/BACKGROUND COLOR DESTINATION FLAG
LZB			VAR BITSWORD.9	'LEADING ZERO BLANKING FLAG
ADENABLE	VAR BITSWORD.10	'A/D ENABLE FLAG
DIR			VAR BITSWORD.11	'PIXEL TEST DIRECTION FLAG
FIRSTPASS   VAR BITSWORD.12	'1 TIME LOAD FLAG

CONFIG		VAR	BYTE	'BITS FOR STORAGE
ROTATEMESS	VAR CONFIG.4	'ROTATE MESSAGE FLAG

' ********************************************************************
'------------ Variables -------------------------
' ********************************************************************
LOOPCNTR	VAR	WORD	'LOOP TIMER WORD DELAY ROUTINE
SCRATCH1	VAR	WORD
ININDEX		VAR	BYTE	'INPUT BUFFER POINTER
INBUF		VAR	BYTE(BUFSIZE)'INPUT CHARACTER BUFFER
INCHAR		VAR	BYTE	'WORKING INPUT CHARACTER
JUNK	    VAR	BYTE	'SCRATCH VARIABLE
JUNK1	    VAR	BYTE	'SCRATCH VARIABLE
DIGITS		VAR	BYTE	'DIGITS TO SEND SERIALLY
TARGETEMP	VAR	WORD	'SERIAL NUMERIC ACCUMULATOR
VOLTS		VAR	WORD[3]	'A/D RESULT ARRAY
CHANNEL		VAR	BYTE	'A/D CHANNEL BEING SELECTED

NeoGreen1    VAR BYTE[80]BANK3	'Green intensity array	\
NeoBlue1     VAR BYTE[80]BANK4	'Blue intensity array	 FIRST 80 NEOPIXELS
NeoRed1      VAR BYTE[80]BANK5	'Red intensity array	/
NeoGreen2    VAR BYTE[80]BANK6	'Green intensity array	\
NeoBlue2     VAR BYTE[80]BANK7	'Blue intensity array     SECOND 80 NEOPIXELS
NeoRed2      VAR BYTE[80]BANK8	'Red intensity array	/
NeoGreen3    VAR BYTE[80]BANK9	'Green intensity array	\
NeoBlue3     VAR BYTE[80]BANK10	'Blue intensity array	  THIRD 80 NERPIXELS
NeoRed3      VAR BYTE[80]BANK11	'Red intensity array	/

SCRATCH	    VAR	BYTE BANK0	'SCRATCH VARIABLE
POINTER		VAR	WORD BANK0	'POINTER USED FOR PIXEL BUFFER
POINT		VAR	BYTE BANK0	'POINTER USED FOR PIXEL BUFFER
NeoPixel    VAR BYTE BANK0	'Looping variable
NeoPixValue VAR BYTE BANK0	'Value to be bit-banged
NEO_NUM     VAR BYTE BANK0	'TOTAL Number of pixels
FOR_GREEN	VAR	BYTE		'FORGROUND GREEN INTENSITY
FOR_BLUE	VAR	BYTE		'FORGROUND BLUE INTENSITY
FOR_RED		VAR	BYTE		'FORGROUND RED INTENSITY
BAK_GREEN	VAR	BYTE		'BACKGROUND GREEN INTENSITY
BAK_BLUE	VAR	BYTE		'BACKGROUND BLUE INTENSITY
BAK_RED		VAR	BYTE		'BACKGROUND RED INTENSITY
IN_GREEN	VAR	BYTE		'ARRAY INPUT GREEN INTENSITY
IN_BLUE		VAR	BYTE		'ARRAY INPUT BLUE INTENSITY
IN_RED		VAR	BYTE		'ARRAY INPUT RED INTENSITY
GAMMAIN		VAR	BYTE		'INTENSITY VALUE TO BE LOOKED UP FROM GAMMA CORRECTION TABLE
GAMMAOUT	VAR	BYTE		'INTENSITY VALUE FROM GAMMA CORRECTION TABLE

ROW_DAT		VAR	BYTE[7]		'CHARACTER PIXEL ARRAY FOR 5 X 7 DOT MATRIX
CHARACTER	VAR	BYTE		'ASCII CHARACTER REPRESENTATION
CHARCNTR	VAR	BYTE		'CHARACTER TABLE POINTER
DOT			VAR	BYTE		'HORIZONTAL PIXEL POINTER
ROW			VAR	BYTE		'CHARACTER ROW POINTER

INTENSITY	VAR	BYTE		'NEOPIXEL INTENSITY LEVEL
COLOR		VAR	BYTE		'COLOR CYCLING POINTER
NEW_Green	VAR	BYTE	'NEW colors to be added to highest element in array
NEW_Blue	VAR	BYTE
NEW_Red		VAR	BYTE
OLDGreen	VAR	BYTE	'recovered from location 0 of array before rotating
OLDBlue		VAR	BYTE
OLDRed		VAR	BYTE
TESTMODE	VAR BYTE	'test mode selector value
OLDTESTMODE	VAR BYTE	'test mode selector value HISTORY
DELAYTIME	VAR	WORD	'delay variable to be used for delay routine
MESSNUM		VAR BYTE	'MESSAGE NUMBER value
VALUE		VAR	WORD

' ********************************************************************
'				SYSTEM INITIALIZATION
' ********************************************************************
clear
PORTA = %00000000
PORTC = %00010000
LATA = %00000000
LATC = %00010000
TRISA = %00101111	'INITIALIZE PORT DIRECTIONS
TRISC = %00100000	'INITIALIZE PORT DIRECTIONS
OSCCON = %11110000	'SET SYSTEM CLOCK,PLL ENABLED,16 MHZ.,FOSC 2:0	(EXTERNAL 10 Mhz. OSC.)
INTCON = %00000000 'CLEAR GIE,PEIE,TMR0IE,INTE,RBIE,TMR0IF,INTF,RBIF
PIE1 = %00000000    'CLEAR ALL INTERRUPT ENABLE BITS
PIR1 = %00000000    'CLEAR ALL INTERRUPT FLAGS
PIE2 = %00000000    'CLEAR ALL INTERRUPT ENABLE BITS
PIR2 = %00000000    'CLEAR ALL INTERRUPT FLAGS
APFCON0 = %00000000	'ALL DEFAULT
APFCON1 = %00000000	'ALL DEFAULT
ANSELA = %00000111	'AN0:AN2 ANALOG
WPUA = %00000000	'WEEK PULLUP'S OFF
INLVLA = %00000000	'TTL TRIGGER
ANSELC = %00000000	'RC0:RC5 DIGITAL I/O
WPUC = %00000000	'WEEK PULLUP'S OFF
INLVLC = %00000000	'TTL TRIGGER
IOCAP = %00000000	'INTERRUPT ON CHANGE DISABLED
IOCAN = %00000000	'INTERRUPT ON CHANGE DISABLED
ADCON0 = %00000001  'GO/DONE,ADON
ADCON1 = %11100000  'RIGHT JUSTIFIED,FOSC/64,VSS,VDD
SRCON0 = %00000000
SRCON1 = %00000000
CM1CON0 = %00000000	'CLEAR/DISABLE COMPARATOR
CM1CON1 = %00000000	'CLEAR/DISABLE COMPARATOR
CM2CON0 = %00000000	'CLEAR/DISABLE COMPARATOR
CM2CON1 = %00000000	'CLEAR/DISABLE COMPARATOR
CMOUT = %00000000	'DISABLE OUTPUT REGISTER
DACCON0 = %00000000	'CLEAR/DISABLE D/A
DACCON1 = %00000000	'CLEAR/DISABLE D/A
FVRCON = %00000000	'DISABLE FIXED VOLTAGE REFERENCE
MDCON = %00000000	'DISABLE DATA MODULATOR
MDSRC = %10000000	'DISABLE DATA MODULATOR
MDCARH = %10000000	'DISABLE DATA MODULATOR
MDCARL = %10000000	'DISABLE DATA MODULATOR
OPTION_REG = %10000000 'CLEAR PULL-UPS,INTEDG,TMR0CS=OSC/4,TMR0SE=LEADING,PS=NOT,PS=1:2
T1CON = %00000000	'POSTSCALER 1/1,STOP,PRESCALER 1/1
T1GCON = %00000000	'NO GATE CONTROL
T2CON = %00000000	'POSTSCALER 1/1,STOP,PRESCALER 1/1
T4CON = %00000000	'POSTSCALER 1/1,STOP,PRESCALER 1/1
T6CON = %00000000	'POSTSCALER 1/1,STOP,PRESCALER 1/1
CCP1CON = %00000000	'PLACE CCP1 INTO DISABLE MODE
CCP2CON = %00000000	'PLACE CCP2 INTO DISABLE MODE
CCP3CON = %00000000	'PLACE CCP3 INTO DISABLE MODE
CCP4CON = %00000000	'PLACE CCP1 INTO DISABLE MODE
CCPTMRS = %00000000	'PLACE ALL CCP'S W/DEFAULT TIMERS
PSTR1CON = %00000000	'DISABLE ANY STEERING LOGIC
PSTR2CON = %00000000	'DISABLE ANY STEERING LOGIC
TMR2 = 0			'CLEAR TMR2 MODULE REGISTER
TMR4 = 0			'CLEAR TMR2 MODULE REGISTER
TMR6 = 0			'CLEAR TMR2 MODULE REGISTER
PR2 = $FF			'SET PERIOD
PR4 = $FF			'SET PERIOD
PR6 = $FF			'SET PERIOD
CCPR1L = $00		'CLEAR LOWER 8 BITS
CCPR1H = $00		'CLEAR UPPER 2 BITS
CCPR2L = $00		'CLEAR LOWER 8 BITS
CCPR2H = $00		'CLEAR UPPER 2 BITS
CCPR3L = $00		'CLEAR LOWER 8 BITS
CCPR3H = $00		'CLEAR UPPER 2 BITS
CCPR4L = $00		'CLEAR LOWER 8 BITS
CCPR4H = $00		'CLEAR UPPER 2 BITS
SSP1CON1 = %00000000	'DISABLE I2C or SPI COMM
RCSTA = %10010000   'ENABLE RECEIVER,CONTINUOUS
TXSTA = %00100100   'ENABLE TRANSMIT,HIGH BAUD
BAUDCON = %00001000	'ENABLE 16 BIT BAUDRATE GENERATOR
SCRATCH1 = BAUD
SPBRGL = SCRATCH1.LOWBYTE		'SET LOW BYTE OF BAUD GENERATOR
SPBRGH = SCRATCH1.HIGHBYTE		'SET HIGH BYTE OF BAUD GENERATOR

'*********************************************************************

	NEOPIN = 0

INCLUDE "C:\PBP\INCLUDES\direct_NeoPixelASM40.bas"

'*********************************************************************
asm
INT_LIST  macro    ; IntSource,       Label,  Type, ResetFlag?
    INT_Handler     TX_INT,     _UARTTX,	PBP,  no
    INT_Handler     RX_INT,     _UARTRX,	PBP,  no
	endm
	INT_CREATE               ; Creates the High Priority interrupt processor
ENDASM

@	INT_ENABLE  RX_INT     ; Enable RX UART Interrupts

	GOTO Main
	
'*********************************************************************
UARTRX:		'INTERRUPT SERVICE ROUTINE FOR UART RECEIVER
'*********************************************************************
	IF RCSTA.1 = ON_ THEN	'IF OVERRUN BIT SET THEN
		RCSTA.4 = OFF_	'CLEAR CREN
		RCSTA.4 = ON_	'SET CREN
		RX_DAVAIL = 0   'TELL MAIN NO DATA IS AVAILABLE        
		RX_OUTPUT = 0	'RESET POINTER FOR MINIMUM ROLLOVER
		RX_INPUT = RX_OUTPUT
		RXTIMER = 0		'CLEAR CHARACTER RECEIVED TIMER
	ENDIF
	WHILE PIR1.5 = ON_	'UNLOAD ANY RECEIVED CHARACTERS
		IF (RX_OUTPUT + 1) <> RX_INPUT THEN
			RX_BYTES(RX_OUTPUT) = RCREG	'GET THE CHARACTER
			SELECT CASE RX_BYTES(RX_OUTPUT)
				CASE $0D,$0A	'CR or LF
					RX_MESSAGE = 1  'TELL MAIN DATA BUFFER HAS MESSAGE AVAILABLE
				CASE IS < $01		'NULL CONTROL CHARACTER
					GOTO DONERX
				CASE IS > $7E		'CONTROL CHARACTERS
					GOTO DONERX
				CASE ELSE
					RX_OUTPUT = RX_OUTPUT + 1	'INCREMENT BUFFER POINTER
					RX_OUTPUT = RX_OUTPUT & INSIZE
					RX_BUFFULL = OFF_  'CLEAR DATA BUFFER FULL
					RX_DAVAIL = RX_DAVAIL + 1   'TELL MAIN DATA IS AVAILABLE
			END SELECT
		ELSE
			RX_BUFFULL = ON_  'TELL MAIN DATA BUFFER IS FULL
			JUNKRX = RCREG
		ENDIF
DONERX:
	RXTIMER = 0		'CLEAR CHARACTER RECEIVED TIMER
	WEND
@	INT_RETURN

'*********************************************************************
UARTTX:		'INTERRUPT SERVICE ROUTINE FOR UART TRANSMITTER
'*********************************************************************
	IF TX_INPUT <> TX_OUTPUT THEN   'DATA TO BE SENT
		TXREG = TX_BYTES(TX_INPUT)
		TX_INPUT = TX_INPUT + 1
		TX_INPUT = TX_INPUT & OUTSIZE
		TX_EMPTY = ON_  'TELL MAIN DATA TO BE SENT
		TX_DAVAIL = TX_DAVAIL - 1
	ELSE
		TX_EMPTY = 0'TELL MAIN ALL DATA IS SENT
		TX_DAVAIL = 0
@		INT_DISABLE  TX_INT     ; Disable TX UART Interrupts
	ENDIF
@	INT_RETURN

'------------------------- SUBROUTINES -------------------------------
'*********************************************************************
CLRREC:     'CLEAR THE SERIAL PORT BUFFER
'*********************************************************************
    RX_OUTPUT = 0       'RESET POINTER FOR MINIMUM ROLLOVER
    RX_INPUT = RX_OUTPUT
    RX_DAVAIL = 0
	RX_BUFFULL = 0  'CLEAR DATA BUFFER FULL
	RX_MESSAGE = 0  'TELL MAIN DATA BUFFER HAS MESSAGE
	TARGETEMP = 0
    RETURN

'*********************************************************************
DELAYSTAT:	'SEND SCROLL DELAY STATUS & CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = "D"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "E"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "L"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "A"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "Y"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	GOSUB EQUALS
	VALUE = DELAYTIME
	GOSUB BUILDSTRINGLZB:	'BUILD ASCII STRING FROM NUMBER VARIABLE W/LZB
	GOTO CRLF		'CARRIAGE RETURN & LINE FEED
		
'*********************************************************************
MODESTAT:	'SEND MODE STATUS & CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = "M"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "O"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "D"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "E"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	GOSUB EQUALS
	VALUE = TESTMODE
	GOSUB BUILDSTRINGLZB:	'BUILD ASCII STRING FROM NUMBER VARIABLE W/LZB
	GOTO CRLF		'CARRIAGE RETURN & LINE FEED
		
'*********************************************************************
ADSTATE:	'SEND A/D STATUS & CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = "A"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "D"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "-"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "O"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	IF ADENABLE = 1 THEN	'IF COLOR'S ARE FROM ANALOG POTS
		TX_BYTES(TX_OUTPUT) = "N"
		GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	ELSE
		TX_BYTES(TX_OUTPUT) = "F"
		GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
		TX_BYTES(TX_OUTPUT) = "F"
		gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	ENDIF
	GOTO CRLF		'CARRIAGE RETURN & LINE FEED
		
'*********************************************************************
FORGROUND:		'SEND FORGROUND & CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = " "
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "F"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "O"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "R"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "G"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	GOTO CRLF		'CARRIAGE RETURN & LINE FEED
	
'*********************************************************************
BACKGROUND:		'SEND BACKGROUND & CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = " "
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "B"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "A"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "C"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "K"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	GOTO CRLF		'CARRIAGE RETURN & LINE FEED
	
'*********************************************************************
ACK:		'SEND ACKNOWLAGEMENT & CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = "O"
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = "K"
	GOSUB SNDCHAR		'INCREMENT BUFFER POINTERS
	
'*********************************************************************
CRLF:		'CARRIAGE RETURN & LINE FEED
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = 10
	gosub SNDCHAR		'INCREMENT BUFFER POINTERS
	TX_BYTES(TX_OUTPUT) = 13
	GOTO SNDCHAR		'INCREMENT BUFFER POINTERS & RETURN
	
'*********************************************************************
COMMA:			'SEND COMMA TO TERMINAL DISPLAY
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = ","
	goTO SNDCHAR		'INCREMENT BUFFER POINTERS

'*********************************************************************
EQUALS:			'SEND EQUALS SIGN TO TERMINAL DISPLAY
'*********************************************************************
	TX_BYTES(TX_OUTPUT) = "="

'*********************************************************************
SNDCHAR:		'INCREMENT BUFFER POINTERS
'*********************************************************************
    TX_OUTPUT = TX_OUTPUT + 1
    TX_OUTPUT = TX_OUTPUT & OUTSIZE
	TX_DAVAIL = TX_DAVAIL + 1
@	INT_ENABLE  TX_INT     ; Enable TX UART Interrupts
	IF  TX_DAVAIL > FIVESIXTH THEN		'> 5/6 TH
		WHILE TX_DAVAIL > ONESIXTH		'1/6 TH
		WEND
	ENDIF
	RETURN
	
' ********************************************************************
BUILDSTRINGLZB:	'BUILD ASCII STRING FROM NUMBER VARIABLE W/LZB
' ********************************************************************
	LZB = 1		'SET LEADING ZERO BLANKING BIT
	DIGITS = 5	'SET FOR ALL 5 DIGITS DISPLAYED
' ********************************************************************
BUILDSTRING:	'BUILD ASCII STRING FROM NUMBER VARIABLE
' ********************************************************************
	JUNK = DIGITS - 1	'BASE 0
	WHILE JUNK < 255	'CHECK EACH POSITION
		IF VALUE DIG JUNK <> 0 OR LZB = 0 THEN	'IF INFO FOUND NOW or PREVIOUSLY
			TX_BYTES(TX_OUTPUT) = $30 + VALUE DIG JUNK	'PRINT IT...
			gosub SNDCHAR		'INCREMENT BUFFER POINTERS
			LZB = 0		'CLEAR LEADING ZERO BLANKING FLAG
		ENDIF
		JUNK = JUNK - 1	'NEXT DIGIT
		IF JUNK = 0 THEN LZB = 0	'ALWAYS DISPLAY LAST DIGIT TO RIGHT, EVEN IF ZERO
	WEND
	RETURN

'*********************************************************************
CHKSERIAL:
'*********************************************************************
	WHILE RX_DAVAIL <> 0
		INCHAR = RX_BYTES(RX_INPUT)
		RX_INPUT = (RX_INPUT + 1) & INSIZE
		RX_DAVAIL = RX_DAVAIL - 1
		SELECT CASE INCHAR
'*********************************************************************
			CASE $01	'CTRL (A) SET ALL COLORS BY USE OF A/D
				ADENABLE = ~ADENABLE
				GOSUB ADSTATE:	'SEND A/D STATUS & CARRIAGE RETURN & LINE FEED
'				GOSUB ACK
				
'*********************************************************************
			CASE $04	'CTRL (D) SET SCROLLING DELAY FOR TEXT
				DELAYTIME = ((TARGETEMP MIN 1000) MAX 1)	'1 SECOND MAXIMUM
				WRITE E_DELAY + (TESTMODE * 2) + 0,DELAYTIME.LOWBYTE
				WRITE E_DELAY + (TESTMODE * 2) + 1,DELAYTIME.HIGHBYTE
				GOSUB DELAYSTAT
				
'*********************************************************************
			CASE $02	'CTRL (B) SET BLUE INTENSITY
				GAMMAIN = TARGETEMP MIN 255		'FORGROUND BLUE INTENSITY
				TX_BYTES(TX_OUTPUT) = "B"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = GAMMAIN
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				GOSUB GAMMACORR:		' Gamma correction table, 256 values
				IF TXTENAB = OFF_ THEN	'IF NOT IN TEXT ENTRY MODE
					IF FOR_BAK = ON_ THEN	'COLOR IS FOR FORGROUND
						FOR_BLUE = GAMMAOUT				'FORGROUND BLUE INTENSITY
						GOSUB FORGROUND:		'SEND FORGROUND & CARRIAGE RETURN & LINE FEED
					ELSE	'COLOR IS FOR BACKGROUND
						BAK_BLUE = GAMMAOUT				'BACKGROUND BLUE INTENSITY
						GOSUB BACKGROUND:		'SEND BACKGROUND & CARRIAGE RETURN & LINE FEED
					ENDIF
				ENDIF
'				FOR_BAK = ON_	'DEFAULT COLOR IS FOR FORGROUND
				GOSUB ACK
											
'*********************************************************************
			CASE $07	'CTRL (G) SET GREEN INTENSITY
				GAMMAIN = TARGETEMP MIN 255		'FORGROUND BLUE INTENSITY
				TX_BYTES(TX_OUTPUT) = "G"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = GAMMAIN
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				GOSUB GAMMACORR:		' Gamma correction table, 256 values
				IF TXTENAB = OFF_ THEN  'IF NOT IN TEXT ENTRY MODE
					IF FOR_BAK = ON_ THEN	'COLOR IS FOR FORGROUND
						FOR_GREEN = GAMMAOUT		'FORGROUND GREEN INTENSITY
						GOSUB FORGROUND:		'SEND FORGROUND & CARRIAGE RETURN & LINE FEED
					ELSE	'COLOR IS FOR BACKGROUND
						BAK_GREEN = GAMMAOUT		'BACKGROUND GREEN INTENSITY
						GOSUB BACKGROUND:		'SEND BACKGROUND & CARRIAGE RETURN & LINE FEED
					ENDIF
				ENDIF
'				FOR_BAK = ON_	'DEFAULT COLOR IS FOR FORGROUND
				GOSUB ACK
											
'*********************************************************************
			CASE $12	'CTRL (R) SET RED INTENSITY
				GAMMAIN = TARGETEMP MIN 255		'FORGROUND BLUE INTENSITY
				TX_BYTES(TX_OUTPUT) = "R"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = GAMMAIN
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				GOSUB GAMMACORR:		' Gamma correction table, 256 values
				IF TXTENAB = OFF_ THEN	'IF NOT IN TEXT ENTRY MODE
					IF FOR_BAK = ON_ THEN	'COLOR IS FOR FORGROUND
						FOR_RED = GAMMAOUT			'FORGROUND RED INTENSITY
						GOSUB FORGROUND:		'SEND FORGROUND & CARRIAGE RETURN & LINE FEED
					ELSE	'COLOR IS FOR BACKGROUND
						BAK_RED = GAMMAOUT			'BACKGROUND RED INTENSITY
						GOSUB BACKGROUND:		'SEND BACKGROUND & CARRIAGE RETURN & LINE FEED
					ENDIF
				ENDIF
'				FOR_BAK = ON_	'DEFAULT COLOR IS FOR FORGROUND
				GOSUB ACK
											
'*********************************************************************
			CASE $05	'CTRL (E) SET BACKROUND COLOR DESTINATION
				IF TXTENAB = OFF_ THEN	'IF NOT IN TEXT ENTRY MODE
					FOR_BAK = OFF_	'COLOR IS FOR BACKGROUND
				ENDIF
				GOSUB BACKGROUND:		'SEND BACKGROUND & CARRIAGE RETURN & LINE FEED
'				GOSUB ACK
											
'*********************************************************************
			CASE $0C	'CTRL (L) TOGGLE LOOP MESSAGES
				ROTATEMESS = ~ROTATEMESS
				TX_BYTES(TX_OUTPUT) = "L"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = ROTATEMESS
				GOSUB BUILDSTRINGLZB:	'BUILD ASCII STRING FROM NUMBER VARIABLE W/LZB
				GOTO CRLF		'CARRIAGE RETURN & LINE FEED
'				GOSUB ACK
											
'*********************************************************************
			CASE $06	'CTRL (F) SET FORGROUND COLOR DESTINATION
				IF TXTENAB = OFF_ THEN	'IF NOT IN TEXT ENTRY MODE
					FOR_BAK = ON_	'COLOR IS FOR FORGROUND
				ENDIF
				GOSUB FORGROUND:		'SEND FORGROUND & CARRIAGE RETURN & LINE FEED
'				GOSUB ACK

'*********************************************************************
			CASE $0F	'CTRL (O) TOGGLE TEST MODE
				TESTMODE = (TESTMODE + 1)
				IF TESTMODE > (MAXMODES - 1) THEN TESTMODE = 0
				GOSUB MODESTAT:	'SEND MODE STATUS & CARRIAGE RETURN & LINE FEED
				GOSUB ACK
				
'*********************************************************************
			CASE $13	'CTRL (S) RECALL STORED MESSAGE BUFFER and COLOR VALUES FROM EEPROM
				MESSNUM = TARGETEMP MIN (MAXMESS - 1)
				GOSUB READMEM:	'UPDATE CURRENT TEXT and COLORS FROM MEMORY
				GOSUB SENDBUFF:	'REPORT/DUMP MESSAGE IN BUFFER
'				GOSUB ACK

'*********************************************************************
			CASE $17	'CTRL (W) WRITE MESSAGE BUFFER and COLOR VALUES TO EEPROM
				MESSNUM = TARGETEMP MIN (MAXMESS - 1)
				SCRATCH = (MESSNUM * BUFSIZE)	'CALCULATE THE ADDRESS
				CHARCNTR = 0
				WHILE CHARCNTR < (BUFSIZE - 1)	'LIMIT TO BUFFER SIZE - 1
					WRITE E_TEXT + SCRATCH + CHARCNTR,INBUF(CHARCNTR)	'STORE VARIABLE TEXT
					CHARCNTR = CHARCNTR + 1
				WEND
				WRITE E_TEXT + SCRATCH + CHARCNTR,$18	'SET LAST CHARACTER FOR END OF MESSAGE
				SCRATCH = (MESSNUM * COLORSIZE)	'CALCULATE THE ADDRESS
				WRITE E_COLORS + (SCRATCH + 0),FOR_GREEN	'SAVE THE COLORS
				WRITE E_COLORS + (SCRATCH + 1),FOR_BLUE
				WRITE E_COLORS + (SCRATCH + 2),FOR_RED
				WRITE E_COLORS + (SCRATCH + 3),BAK_GREEN
				WRITE E_COLORS + (SCRATCH + 4),BAK_BLUE
				WRITE E_COLORS + (SCRATCH + 5),BAK_RED
				GOSUB ACK

'*********************************************************************
			CASE $11	'CTRL (Q) SEND VARIABLE STATUS
				TX_BYTES(TX_OUTPUT) = "G"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = FOR_GREEN
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				TX_BYTES(TX_OUTPUT) = "B"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = FOR_BLUE
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				TX_BYTES(TX_OUTPUT) = "R"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = FOR_RED
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB FORGROUND:		'SEND FORGROUND & CARRIAGE RETURN & LINE FEED
				TX_BYTES(TX_OUTPUT) = "G"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = BAK_GREEN
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				TX_BYTES(TX_OUTPUT) = "B"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = BAK_BLUE
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB COMMA
				TX_BYTES(TX_OUTPUT) = "R"
				gosub SNDCHAR		'INCREMENT BUFFER POINTERS
				GOSUB EQUALS
				VALUE = BAK_RED
				GOSUB BUILDSTRINGLZB	'BUILD ASCII STRING FROM NUMBER VARIABLE
				GOSUB BACKGROUND:		'SEND BACKGROUND & CARRIAGE RETURN & LINE FEED
				GOSUB ACK
				
'*********************************************************************
			CASE $14	'CTRL (T) START OF TEXT
				IF TXTENAB = OFF_ THEN	'IF NOT IN TEXT ENTRY MODE
					TXTENAB = ON_ 	'SET FLAG FOR IT
					ININDEX = 0		'ZERO BUFFER POINTER
				ENDIF
											
'*********************************************************************
			CASE $18	'CTRL (X) END OF TEXT
				IF TXTENAB = ON_ THEN	'IF IN TEXT ENTRY MODE
'					INBUF(ININDEX) = "."'ADD NEW CHARACTER TO BUFFER
'					ININDEX = (ININDEX + 1) MIN (BUFSIZE - 1)
					INBUF(ININDEX) = INCHAR	'ADD END OF FUFFER CHARACTER
					ININDEX = (ININDEX + 1) MIN (BUFSIZE - 1)
				ENDIF
				TXTENAB = OFF_	'DISABLE IT WHEN DONE
				GOSUB ACK
			
'*********************************************************************
			CASE $1A	'CTRL Z	(REPORT/DUMP MESSAGE IN BUFFER)
				GOSUB SENDBUFF:	'REPORT/DUMP MESSAGE IN BUFFER
'				GOSUB ACK
												
'*********************************************************************
			CASE $30,$31,$32,$33,$34,$35,$36,$37,$38,$39	'0,1,2,3,4,5,6,7,8,9
				IF TXTENAB = ON_ THEN	'IF IN TEXT ENTRY MODE
					INBUF(ININDEX) = INCHAR	'ADD NEW CHARACTER TO BUFFER
					ININDEX = (ININDEX + 1) MIN (BUFSIZE - 1)
				ELSE
					TARGETEMP = TARGETEMP * 10	'NUMERIC KEY JUST RELEASED SO ADD TO VALUE
					TARGETEMP = TARGETEMP + (INCHAR - $30)
        		ENDIF
        		
'*********************************************************************
			CASE IS > $7E	'MUST NOT BE AN ASCII CHARACTER
				'YOU ARE OUT OF LUCK... START ALL OVER AGAIN....			

'*********************************************************************
			CASE IS > $1F	'MUST BE AN ASCII CHARACTER
				IF TXTENAB = ON_ THEN	'IF IN TEXT ENTRY MODE
					INBUF(ININDEX) = INCHAR	'ADD NEW CHARACTER TO BUFFER
					ININDEX = (ININDEX + 1) MIN (BUFSIZE - 1)
				ENDIF
				
'*********************************************************************
			CASE ELSE
				'YOU ARE OUT OF LUCK... START ALL OVER AGAIN....			
				
'*********************************************************************

		END SELECT
	WEND
	GOSUB CLRREC	'CLEANUP RECEIVER BUFFER POINTERS....
	RETURN	

' ********************************************************************	
SENDBUFF:	'REPORT/DUMP MESSAGE IN BUFFER
' ********************************************************************	
	IF TXTENAB = OFF_ THEN	'IF NOT IN TEXT ENTRY MODE
		ININDEX = 0
		WHILE INBUF(ININDEX) <> $18 AND ININDEX < BUFSIZE
			TX_BYTES(TX_OUTPUT) = INBUF(ININDEX)
			gosub SNDCHAR		'INCREMENT BUFFER POINTERS
			ININDEX = ININDEX + 1
		WEND
		GOSUB CRLF:		'CARRIAGE RETURN & LINE FEED
	ENDIF
	RETURN
	
' ********************************************************************	
READMEM:	'UPDATE CURRENT TEXT and COLORS FROM MEMORY
' ********************************************************************	
	SCRATCH = (MESSNUM * BUFSIZE)	'CALCULATE ADDRESS
	CHARCNTR = 0
	WHILE CHARCNTR < BUFSIZE	'LIMIT TO BUFFER SIZE
		READ E_TEXT + SCRATCH + CHARCNTR,INBUF(CHARCNTR)	'RESTORE VARIABLE TEXT
		CHARCNTR = CHARCNTR + 1
	WEND
	SCRATCH = (MESSNUM * COLORSIZE)	'CALCULATE ADDRESS
	READ E_COLORS + (SCRATCH + 0),FOR_GREEN	'RESTORE THE COLORS (FORGROUND)
	READ E_COLORS + (SCRATCH + 1),FOR_BLUE
	READ E_COLORS + (SCRATCH + 2),FOR_RED
	READ E_COLORS + (SCRATCH + 3),BAK_GREEN	'RESTORE THE COLORS (BACKGROUND)
	READ E_COLORS + (SCRATCH + 4),BAK_BLUE
	READ E_COLORS + (SCRATCH + 5),BAK_RED
	RETURN
	
'*********************************************************************
READAD:	'READ SYSTEM A/D VOLTAGES (AVERAGE 8 READINGS)
'*********************************************************************
	CHANNEL = 2
NXTCHAN:
	ADCON0 = $01 | (CHANNEL << 2)		' Set A/D to Channel X, On
	PAUSEUS 80		'(normally 40 due to 2 x frequency)
	VOLTS(CHANNEL) = 0     'CLEAR A/D READINGS
	ADCON0.1 = ON_		' START CONVERSION
	JUNK = 7		'TAKE 8 READINGS
NXTAD:
	IF ADCON0.1 = ON_ THEN NXTAD	'WAIT FOR A/D TO FINISH	
	VOLTS(CHANNEL) = VOLTS(CHANNEL) + (((ADRESH & $3) << 8) + ADRESL)	'BUILD SENSOR WORD (RIGHT JUSTIFIED)
	JUNK = JUNK - 1
	IF JUNK.7 = 0 THEN NXTAD
	VOLTS(CHANNEL) = VOLTS(CHANNEL) >> 5	'DIVIDE BY 32 TO GENERATE 0-255
	GAMMAIN = VOLTS(JUNK)
	GOSUB GAMMACORR		' Gamma correction table, 256 values
	VOLTS(JUNK) = GAMMAOUT
	CHANNEL = CHANNEL - 1
	IF CHANNEL.7 = 0 THEN NXTCHAN:
	RETURN

'*********************************************************************
PAUSDELAY: 		'PAUSE BASED ON DELAY VARIABLE CHECK COM PORT DURING PAUSE PERIOD
'*********************************************************************
	LOOPCNTR = (DELAYTIME MAX 1) - 1	'PIXEL SCROLLING DELAY
NXT1MS:		PAUSEUS 2000	'(normally 1000 due to 2 x frequency)
	LOOPCNTR = LOOPCNTR - 1
	IF RX_MESSAGE = 1 THEN GOSUB CHKSERIAL	'CHECK FOR MESSAGE AVAILABLE
	IF LOOPCNTR // 10 = 0 THEN RXTIMER = RXTIMER + 1	'INCREMENT RECEIVE TIMEOUT TIMER
	IF RX_DAVAIL <> 0 AND RXTIMER > RXTIMEOUT THEN	'IF RANDOM CHARACTERS
		GOSUB CLRREC		'THEN FLUSH
	ENDIF					
	IF LOOPCNTR.15 = 0 THEN NXT1MS
	RETURN
	
' ********************************************************************	
CHARTABLR:		'CHARACTER LOOK-UP TABLE FOR ROWS (LSB=RIGHT) (ROW0 = TOP)
' ********************************************************************
'             76543210-BIT VALUE POSITIONS
'ROW_DAT(0) = 000XXXXX \
'ROW_DAT(1) = 000XXXXX  \
'ROW_DAT(2) = 000XXXXX   \
'ROW_DAT(3) = 000XXXXX    \ 5 X 7 CHARACTER REPRESENTED BY X's
'ROW_DAT(4) = 000XXXXX   /
'ROW_DAT(5) = 000XXXXX  /
'ROW_DAT(6) = 000XXXXX /
	IF CHARACTER > 31 THEN	'ONLY DECODE ASCII PRINTABLE CHARACTER's
						 ' " ","!",""","#","$","%","&","'","(",")","*","+",",",
   '"-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?",
   '"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R",
   '"S","T","U","V","W","X","Y","Z","[","\","]","^","_","`","a","b","c","d","e",
   '"f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x",
   '"y","z","{","|","}","~"]	
ROW0:
	LOOKUP CHARACTER - 32,[$00,$04,$0A,$0A,$04,$18,$0C,$0C,$04,$04,$00,$00,$00,_
	$00,$00,$00,$0E,$04,$0E,$1F,$02,$1F,$06,$1F,$0E,$0E,$00,$00,$02,$00,$08,$0E,_
	$0E,$0E,$1E,$0E,$1C,$1F,$1F,$0E,$11,$0E,$07,$11,$10,$11,$11,$0E,$1E,$0E,$1E,_
	$0F,$1F,$11,$11,$11,$11,$11,$1F,$1C,$00,$07,$04,$00,$08,$00,$10,$00,$01,$00,_
	$06,$00,$10,$04,$01,$10,$0C,$00,$00,$00,$00,$00,$00,$00,$08,$00,$00,$00,$00,_
	$00,$00,$04,$04,$04,$00],ROW_DAT(0)
ROW1:
	LOOKUP CHARACTER - 32,[$00,$04,$0A,$0A,$0F,$19,$12,$04,$08,$02,$04,$04,$00,_
	$00,$00,$01,$11,$0C,$11,$02,$06,$10,$08,$01,$11,$11,$0C,$0C,$04,$00,$04,$11,_
	$11,$11,$11,$11,$12,$10,$10,$11,$11,$04,$02,$12,$10,$1B,$11,$11,$11,$11,$11,_
	$10,$04,$11,$11,$11,$11,$11,$01,$10,$10,$01,$0A,$00,$04,$00,$10,$00,$01,$00,_
	$09,$0F,$10,$00,$00,$10,$04,$00,$00,$00,$00,$00,$00,$00,$08,$00,$00,$00,$00,_
	$00,$00,$08,$04,$02,$00],ROW_DAT(1)
ROW2:
	LOOKUP CHARACTER - 32,[$00,$04,$0A,$1F,$14,$02,$14,$08,$10,$01,$15,$04,$00,_
	$00,$00,$02,$13,$04,$01,$04,$0A,$1E,$10,$02,$11,$11,$0C,$0C,$08,$1F,$02,$01,_
	$01,$11,$11,$10,$11,$10,$10,$10,$11,$04,$02,$14,$10,$15,$19,$11,$11,$11,$11,_
	$10,$04,$11,$11,$11,$0A,$11,$02,$10,$08,$01,$11,$00,$02,$0E,$16,$0E,$0D,$0E,_
	$08,$11,$16,$0C,$03,$12,$04,$1A,$16,$0E,$1E,$0D,$16,$0E,$1C,$11,$11,$11,$11,_
	$11,$1F,$08,$04,$02,$05],ROW_DAT(2)
ROW3:
	LOOKUP CHARACTER - 32,[$00,$04,$00,$0A,$0E,$04,$08,$00,$10,$01,$0E,$1F,$00,_
	$1F,$00,$04,$15,$04,$02,$02,$12,$01,$1E,$04,$0E,$0F,$00,$00,$10,$00,$01,$02,_
	$0D,$11,$1E,$10,$11,$1E,$1E,$17,$1F,$04,$02,$18,$10,$15,$15,$11,$1E,$11,$1E,_
	$0E,$04,$11,$11,$15,$04,$0A,$04,$10,$04,$01,$00,$00,$00,$01,$19,$10,$13,$11,_
	$1C,$11,$19,$04,$01,$14,$04,$15,$19,$11,$11,$13,$19,$10,$08,$11,$11,$11,$0A,_
	$11,$02,$10,$04,$01,$0A],ROW_DAT(3)
ROW4:
	LOOKUP CHARACTER - 32,[$00,$00,$00,$1F,$05,$08,$15,$00,$10,$01,$15,$04,$0C,_
	$00,$00,$08,$19,$04,$04,$01,$1F,$01,$11,$08,$11,$01,$0C,$0C,$08,$1F,$02,$04,_
	$15,$1F,$11,$10,$11,$10,$10,$11,$11,$04,$02,$14,$10,$11,$13,$11,$10,$15,$14,_
	$01,$04,$11,$11,$15,$0A,$04,$08,$10,$02,$01,$00,$00,$00,$0F,$11,$10,$11,$1F,_
	$08,$0F,$11,$04,$01,$18,$04,$15,$11,$11,$1E,$0F,$10,$0E,$08,$11,$11,$15,$04,_
	$0F,$04,$08,$04,$02,$00],ROW_DAT(4)
ROW5:
	LOOKUP CHARACTER - 32,[$00,$00,$00,$0A,$1E,$13,$12,$00,$08,$02,$04,$04,$04,_
	$00,$0C,$10,$11,$04,$08,$11,$02,$11,$11,$08,$11,$01,$0C,$04,$04,$00,$04,$00,_
	$15,$11,$11,$11,$12,$10,$10,$11,$11,$04,$12,$12,$10,$11,$11,$11,$10,$12,$12,_
	$01,$04,$11,$0A,$15,$11,$04,$10,$10,$01,$01,$00,$00,$00,$11,$11,$11,$11,$10,_
	$08,$01,$11,$04,$09,$14,$04,$11,$11,$11,$10,$01,$10,$01,$09,$13,$0A,$15,$0A,_
	$01,$08,$08,$04,$02,$00],ROW_DAT(5)
ROW6:
	LOOKUP CHARACTER - 32,[$00,$04,$00,$0A,$04,$03,$0D,$00,$04,$04,$00,$00,$08,_
	$00,$0C,$00,$0E,$0E,$1F,$0E,$02,$0E,$0E,$08,$0E,$0E,$00,$08,$02,$00,$08,$04,_
	$0E,$11,$1E,$0E,$1C,$1F,$10,$0F,$11,$0E,$0C,$11,$1F,$11,$11,$0E,$10,$0D,$11,_
	$1E,$04,$0E,$04,$0A,$11,$04,$1F,$1C,$00,$07,$00,$1F,$00,$0F,$1E,$0E,$0F,$0E,_
	$08,$0E,$11,$0E,$06,$12,$0E,$11,$11,$0E,$10,$01,$10,$1E,$06,$0D,$04,$0A,$11,_
	$0E,$1F,$04,$04,$04,$00],ROW_DAT(6)
	ENDIF
	RETURN

' ********************************************************************	
GAMMACORR:		' Gamma correction table, 256 values
' ********************************************************************	
	LOOKUP GAMMAIN,[_
	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,_
	$01,$01,$01,$01,$01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,_
	$02,$03,$03,$03,$03,$03,$03,$03,$04,$04,$04,$04,$04,$05,$05,$05,_
	$05,$06,$06,$06,$06,$07,$07,$07,$07,$08,$08,$08,$09,$09,$09,$0A,_
	$0A,$0A,$0B,$0B,$0B,$0C,$0C,$0D,$0D,$0D,$0E,$0E,$0F,$0F,$10,$10,_
	$11,$11,$12,$12,$13,$13,$14,$14,$15,$15,$16,$16,$17,$18,$18,$19,_
	$19,$1A,$1B,$1B,$1C,$1D,$1D,$1E,$1F,$20,$20,$21,$22,$23,$23,$24,_
	$25,$26,$27,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F,$30,$31,$32,$32,_
	$33,$34,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F,$40,$42,$43,$44,_
	$45,$46,$48,$49,$4A,$4B,$4D,$4E,$4F,$51,$52,$53,$55,$56,$57,$59,_
	$5A,$5C,$5D,$5F,$60,$62,$63,$65,$66,$68,$69,$6B,$6D,$6E,$70,$72,_
	$73,$75,$77,$78,$7A,$7C,$7E,$7F,$81,$83,$85,$87,$89,$8A,$8C,$8E,_
	$90,$92,$94,$96,$98,$9A,$9C,$9E,$A0,$A2,$A4,$A7,$A9,$AB,$AD,$AF,_
	$B1,$B4,$B6,$B8,$BA,$BD,$BF,$C1,$C4,$C6,$C8,$CB,$CD,$D0,$D2,$D5,_
	$D7,$DA,$DC,$DF,$E1,$E4,$E7,$E9,$EC,$EF,$F1,$F4,$F7,$F9,$FC,$FF_
	],GAMMAOUT
	GAMMAOUT = GAMMAIN	'BYPASS THIS ROUTINE FOR NOW....
	RETURN
	
' ********************************************************************	
NeoPixelRotate:	'ROTATE ALL PIXELS FROM RIGHT TO LEFT (HIGHEST tO LOWEST)
'				'PROGRESSIVE CONNECTION (1 SINGLE STRING)
' ********************************************************************	
	POINTER = NEO_NUM - 1	'THIS SCHEME USED TO ELIMINATE USING "< or >" COMPARE STATEMENTS
	OLDGreen = NeoGreen1[0]	'remember location 0 if needed for looping
	OLDBlue = NeoBlue1[0]
	OLDRed = NeoRed1[0]
NXTPIXEL:
	NeoPixel = ((NEO_NUM - 1) - POINTER)
	SELECT CASE NEOPIXEL
		CASE IS < 79
			POINT = NEOPIXEL
			NeoGreen1[POINT] = NeoGreen1[POINT + 1]
			NeoBlue1[POINT] = NeoBlue1[POINT + 1]
			NeoRed1[POINT] = NeoRed1[POINT + 1]
		CASE 79
			POINT = NEOPIXEL
			NeoGreen1[POINT] = NeoGreen2[0]
			NeoBlue1[POINT] = NeoBlue2[0]
			NeoRed1[POINT] = NeoRed2[0]
		CASE IS < 159
			POINT = NEOPIXEL - 80
			NeoGreen2[POINT] = NeoGreen2[POINT + 1]
			NeoBlue2[POINT] = NeoBlue2[POINT + 1]
			NeoRed2[POINT] = NeoRed2[POINT + 1]
		CASE 159
			POINT = NEOPIXEL - 80
			NeoGreen2[POINT] = NeoGreen3[0]
			NeoBlue2[POINT] = NeoBlue3[0]
			NeoRed2[POINT] = NeoRed3[0]
		CASE IS < 239
			POINT = NEOPIXEL - 160
			NeoGreen3[POINT] = NeoGreen3[POINT + 1]
			NeoBlue3[POINT] = NeoBlue3[POINT + 1]
			NeoRed3[POINT] = NeoRed3[POINT + 1]
		CASE 239
			POINT = NEOPIXEL - 160
			NeoGreen3[POINT] = 0
			NeoBlue3[POINT] = 0
			NeoRed3[POINT] = 0
	END SELECT
	POINTER = POINTER - 1	'next pixel in the string
	IF POINTER.15 = 0 THEN NXTPIXEL
	'WHEN DONE,THE LAST PIXEL IN EACH HORIZONTAL ROW (FAR RIGHT) WILL
	' HAVE INCORRECT DATA SO, WE WILL TAKE CARE OF THAT UPDATING IN THE MAIN ROUTINE.
    RETURN

' ********************************************************************	
CLR_ARRAY:	'SET PIXELS COLOR ARRAY TO BLACK (OFF)
' ********************************************************************
	POINTER = FULLSTRING - 1
    IN_Green = OFF_
    IN_Blue = OFF_
    IN_Red = OFF_
NXTCLR:
	GOSUB LOADARRAY
	POINTER = POINTER - 1
	IF POINTER.15 = 0 THEN NXTCLR
	RETURN

'*********************************************************************
LOADARRAY:	'LOAD ARRAY ELEMENTS BASED ON POINTER VALUE
'*********************************************************************
	SELECT CASE POINTER
		CASE IS < 80
			POINT = POINTER
		    NeoGreen1[POINT] = IN_Green	'add NEW color to ms pixel
		    NeoBlue1[POINT] = IN_Blue
		    NeoRed1[POINT] = IN_Red
		CASE IS < 160
			POINT = POINTER - 80
		    NeoGreen2[POINT] = IN_Green	'add NEW color to ms pixel
		    NeoBlue2[POINT] = IN_Blue
		    NeoRed2[POINT] = IN_Red
		CASE IS < 240
			POINT = POINTER - 160
		    NeoGreen3[POINT] = IN_Green	'add NEW color to ms pixel
		    NeoBlue3[POINT] = IN_Blue
		    NeoRed3[POINT] = IN_Red
	END SELECT
	RETURN
	
'*********************************************************************

'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXX Main program XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Main:
	CHARACTER = 255
	SCRATCH = 0
	GOSUB CRLF		'CARRIAGE RETURN & LINE FEED
	WHILE (CHARACTER <> 0) AND (SCRATCH < 255)	'DISPLAY INTRO SPLASH SCREEN
		READ (INTRO + SCRATCH),CHARACTER
		TX_BYTES(TX_OUTPUT) = CHARACTER
		gosub SNDCHAR		'INCREMENT BUFFER POINTERS
		SCRATCH = SCRATCH + 1
	WEND
	GOSUB CRLF		'CARRIAGE RETURN & LINE FEED

	FOR_BAK = ON_	'DEFAULT TO FORGROUND COLOR
	GOSUB CLR_ARRAY:	'SET PIXELS COLOR ARRAY TO BACKGROUNG (OFF)
	NEO_NUM = FULLSTRING	'TOTAL NUMBER OF PIXELS IN ATTACHED STRING

	gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
	'DO IT AGAIN INCASE OF NOISE.....
	gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING

	MESSNUM = 0	'DEFAULT MESSAGE and COLORS TO BE DISPLAYED IS IN MESSAGE -0-
	GOSUB READMEM:	'UPDATE CURRENT TEXT and COLORS FROM MEMORY

	CHARCNTR = 0	'INITIAL CHARACTER IN BUFFER
	NEO_NUM = MATRIXNUM		'SET FOR TEXT MODE (DEFAULT)
	
	TESTMODE = 0	'DEFAULT MODE
	OLDTESTMODE = 255	'INITIALIZE

	REPEAT		'UNTIL COWS COME HOME.....

		IF OLDTESTMODE <> TESTMODE THEN	 'CHECK THAT MODE HAS NOT CHANGED
			OLDTESTMODE = TESTMODE
			SELECT CASE TESTMODE	'initialization for mode change
				CASE 0		'TEXT ONLY MODE
					NEO_NUM = MATRIXNUM		'SET FOR TEXT MODE (DEFAULT)
					CHARCNTR = 0	'INITIAL CHARACTER IN BUFFER
				CASE 1		'RAINBOW MODE
					NEO_NUM = FULLSTRING'	CON	240	'TOTAL NUMBER OF PIXELS IN ATTACHED STRING
					DIR = 1
					INTENSITY = COLORMAX / 2
					COLOR = 0
				CASE 2		'SHIFTING COLOR PIXEL MODE
					NEO_NUM = FULLSTRING'	CON	240	'TOTAL NUMBER OF PIXELS IN ATTACHED STRING
					INTENSITY = COLORMAX / 2
		            FIRSTPASS = 1
				CASE 3		'VERTICAL LINE SHIFTING MODE (RAINBOW)
					NEO_NUM = MATRIXNUM		'SET FOR TEXT MODE (DEFAULT)
			END SELECT
			GOSUB CLR_ARRAY:	'SET PIXELS COLOR ARRAY TO BLACK (OFF)
			gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
		ENDIF

		READ E_DELAY + (TESTMODE * 2) + 0,DELAYTIME.LOWBYTE	'recall delay used in this mode
		READ E_DELAY + (TESTMODE * 2) + 1,DELAYTIME.HIGHBYTE
	
		SELECT CASE TESTMODE	'now.... what mode to be in?
			CASE 0		'SCROLLING TEXT MODE
				IF ADENABLE = 1 THEN	'IF COLOR'S ARE FROM ANALOG POTS
					GOSUB READAD	'READ SYSTEM A/D VOLTAGES (AVERAGE 8 READINGS)
					DEBUG "G=",DEC3 VOLTS(0),",B=",DEC3 VOLTS(1),",R=",DEC3 VOLTS(2),10,13
					IF FOR_BAK = OFF_ THEN	'COLOR IS FOR BACKGROUND
					    BAK_GREEN = VOLTS(0)	'BACKGROUND GREEN INTENSITY
					    BAK_BLUE = VOLTS(1)		'BACKGROUND BLUE INTENSITY
					    BAK_RED = VOLTS(2)		'BACKGROUND RED INTENSITY
					ELSE
					    FOR_GREEN = VOLTS(0)	'FORGROUND GREEN INTENSITY
					    FOR_BLUE = VOLTS(1)		'FORGROUND BLUE INTENSITY
					    FOR_RED = VOLTS(2)		'FORGROUND RED INTENSITY
					ENDIF
				ENDIF			
		
				CHARACTER = INBUF(CHARCNTR)	'READ BUFFERED CHARACTER STRING
				IF CHARACTER <> $18 AND CHARCNTR < BUFSIZE THEN	'CHECK FOR END OF STRING
					GOSUB CHARTABLR:		'CHARACTER LOOK-UP TABLE FOR ROWS (LSB=RIGHT) (ROW0 = TOP)
					DOT = COL_P_CHR - 1		'COLLUM POSITION, START WITH 1 BLANK COLLUM TO LEFT OF 5 X 7
NXTDOT:				GOSUB NeoPixelRotate:	'ROTATE ALL PIXEL COLLUMS FROM RIGHT TO LEFT, IN PREP FOR NEW DATA
					JUNK1 = ROW_P_CHR - 1	'CYCLE THRU TILL ALL 7 ROWS READ
NXTROW:				ROW = (ROW_P_CHR - 1) - JUNK1	'CYCLE THRU TILL ALL 7 ROWS READ
					POINTER = ((PIX_P_ROW * (ROW + 1)) - 1)	'CALCULATE PIXEL ARRAY POSITION
					'HERE WE NEED TO UPDATE THE LAST PIXEL (FAR RIGHT) IN EACH HORIZONTAL ROW
					JUNK = ROW_DAT(ROW)	'TRANSFER ROW DATA FROM TABLE
					IF JUNK.0(DOT) = 1 THEN	'CHECK PIXEL FOR ILLUMINATION
					    IN_Green = FOR_GREEN	'FORGROUND GREEN INTENSITY
					    IN_Blue = FOR_BLUE		'FORGROUND BLUE INTENSITY
					    IN_Red = FOR_RED		'FORGROUND RED INTENSITY
			        ELSE
					    IN_Green = BAK_GREEN	'BACKGROUND GREEN INTENSITY
					    IN_Blue = BAK_BLUE		'BACKGROUND BLUE INTENSITY
					    IN_Red = BAK_RED		'BACKGROUND RED INTENSITY
		        	ENDIF
    				GOSUB LOADARRAY
					JUNK1 = JUNK1 - 1	'INCREMENT ROW COUNTER (VERTICAL)
					IF JUNK1.7 = 0 THEN NXTROW
					gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
					GOSUB PAUSDELAY
					DOT = DOT - 1	'DECREMENT COLLUM POINTER
					IF DOT.7 = 0 THEN NXTDOT		'CYCLE THRU TILL ALL 6 COLLUMS READ
					CHARCNTR = CHARCNTR + 1	'NEXT CHARACTER IN BUFFER
				ELSE
					IF ROTATEMESS = 1 THEN	'IF REQUESTED TO LOOP MESSAGES THEN SELECT NEXT
						MESSNUM = (MESSNUM + 1)
						IF MESSNUM > MAXMESS - 1 THEN
							MESSNUM = 1
						ENDIF
						GOSUB READMEM:	'UPDATE CURRENT TEXT and COLORS FROM MEMORY
					ENDIF
					CHARCNTR = 0	'END OF STRING FOUND, START ALL OVER
				ENDIF
				
			CASE 1,3		'TEST PATTERN FOR ALL COLORS (THIS SAME CODE FOR MODES 1,3)
				IF DIR = UP THEN	'CHECK DIRECTION
					INTENSITY = INTENSITY + 1	
					IF INTENSITY = COLORMAX THEN
						DIR = DOWN
						COLOR = COLOR + 1
					ENDIF
				ELSE	'MUST BE DOWN
					INTENSITY = INTENSITY - 1	
					IF INTENSITY = 0 THEN
						DIR = UP
						COLOR = COLOR + 1
					ENDIF
				ENDIF
				IF COLOR > 5 THEN COLOR = 0
				SELECT CASE COLOR
					CASE 0	'GREEN-UP/RED-DOWN			
				        NEW_Green = INTENSITY  'POSITIVE
					    NEW_Blue = 0
				    	NEW_Red = ~INTENSITY & COLORMAX
				
					CASE 1	'GREEN-DOWN/BLUE-UP			
				        NEW_Green = INTENSITY  'NEGATIVE
					    NEW_Blue = ~INTENSITY & COLORMAX
				    	NEW_Red = 0
					
					CASE 2	'BLUE-DOWn/RED-UP			
				        NEW_Green = 0
					    NEW_Blue = ~INTENSITY & COLORMAX
				    	NEW_Red = INTENSITY    'POSITIVE
					
					CASE 3	'GREEN-UP/RED-DOWN			
				        NEW_Green = ~INTENSITY & COLORMAX
					    NEW_Blue = 0
				    	NEW_Red = INTENSITY		'NEGATIVE
				
					CASE 4	'GREEN-DOWN/BLUE-UP			
				        NEW_Green = ~INTENSITY & COLORMAX
					    NEW_Blue = INTENSITY		'POSITIVE
				    	NEW_Red = 0
					
					CASE 5	'BLUE-DOWN/RED-UP			
				        NEW_Green = 0
					    NEW_Blue = INTENSITY		'NEGATIVE
				    	NEW_Red = ~INTENSITY & COLORMAX
				END SELECT	
				SELECT CASE TESTMODE	'CODE SPECIFIC TO MODES 1,3
					CASE 1			'RAINBOW SHIFT (ALL COLORS)
						GOSUB NeoPixelRotate:	'ROTATE ALL PIXEL COLLUMS FROM RIGHT TO LEFT, IN PREP FOR NEW DATA
						POINTER = (NEO_NUM - 1)
					    IN_Green = NEW_Green	'add NEW color to ms pixel
					    IN_Blue = NEW_Blue
					    IN_Red = NEW_Red
	    				GOSUB LOADARRAY
						gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
						GOSUB PAUSDELAY
					CASE 3				'VERTICAL LINE SHIFT (RAINBOW COLORS)
						JUNK1 = ROW_P_CHR - 1	'CYCLE THRU TILL ALL 7 ROWS READ
NXTTSTROW:				ROW = (ROW_P_CHR - 1) - JUNK1	'CYCLE THRU TILL ALL 7 ROWS READ
						'HERE WE NEED TO UPDATE THE FIRST PIXEL (FAR LEFT) IN EACH HORIZONTAL ROW W/0
						POINTER = PIX_P_ROW * ROW	'CALCULATE PIXEL ARRAY POSITION TO CLEAR
					    IN_Green = OFF_
					    IN_Blue = OFF_
					    IN_Red = OFF_
	    				GOSUB LOADARRAY
						POINTER = ((PIX_P_ROW * (ROW + 1)) - 1)	'CALCULATE PIXEL ARRAY POSITION
						'HERE WE NEED TO UPDATE THE LAST PIXEL (FAR RIGHT) IN EACH HORIZONTAL ROW
					    IN_Green = NEW_Green	'add NEW color to ms pixel
					    IN_Blue = NEW_Blue
					    IN_Red = NEW_Red
	    				GOSUB LOADARRAY
						JUNK1 = JUNK1 - 1	'INCREMENT ROW COUNTER (VERTICAL)
						IF JUNK1.7 = 0 THEN NXTTSTROW
						gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
						GOSUB PAUSDELAY
						DOT = PIX_P_ROW - 1
NXTCOL:					GOSUB NeoPixelRotate:	'ROTATE ALL PIXEL COLLUMS FROM RIGHT TO LEFT, IN PREP FOR NEW DATA
						gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
						GOSUB PAUSDELAY
						DOT = DOT - 1
    					IF DOT.7 = 0 THEN NXTCOL
				END SELECT

			CASE 2			'MULTI COLOR PIXELS SHIFTING                           
                IF FIRSTPASS = 1 THEN   'PRE-LOAD PIXEL ARRAY
                    FIRSTPASS = 0
                    POINTER = NEO_NUM - 1
NXTPXL:             IF POINTER // 6 = 0 THEN		'ORANGE
                        NEW_Green = INTENSITY / 2
                        NEW_Blue = 0
                        NEW_Red = INTENSITY / 2
                    ELSEIF POINTER // 6 = 1 THEN	'GREEN
                        NEW_Green = INTENSITY
                        NEW_Blue = 0
                        NEW_Red = 0
                    ELSEIF POINTER // 6 = 2 THEN	'CYAN
                        NEW_Green = INTENSITY / 2
                        NEW_Blue = INTENSITY / 2
                        NEW_Red = 0
                    ELSEIF POINTER // 6 = 3 THEN	'BLUE
                        NEW_Green = 0
                        NEW_Blue = INTENSITY
                        NEW_Red = 0
                    ELSEIF POINTER // 6 = 4 THEN	'MANGENTA	
                        NEW_Green = 0
                        NEW_Blue = INTENSITY / 2
                        NEW_Red = INTENSITY / 2
                    ELSEIF POINTER // 6 = 5 THEN	'RED
                        NEW_Green = 0
                        NEW_Blue = 0
                        NEW_Red = INTENSITY
                    ENDIF

				    IN_Green = NEW_Green	'add NEW color to ms pixel
				    IN_Blue = NEW_Blue
				    IN_Red = NEW_Red
    				GOSUB LOADARRAY
                	POINTER = POINTER - 1
                	IF POINTER.15 = 0 THEN NXTPXL
				ENDIF
				GOSUB NeoPixelRotate:	'ROTATE ALL PIXEL COLLUMS FROM RIGHT TO LEFT, IN PREP FOR NEW DATA
				POINTER = (NEO_NUM -1)
			    IN_Green = OLDGreen	'add NEW color to ms pixel
			    IN_Blue = OLDBlue
			    IN_Red = OLDRed
   				GOSUB LOADARRAY
				gosub NEOPIXELASM40	'PUSH NEW PIXEL DATA TO NEOPIXEL STRING
				GOSUB PAUSDELAY
				
		END SELECT
	UNTIL COWS_HOME		'I DON'T THINK THEY ARE HOME YET?

END
STOP
	
