What the heck ? Compile errors in stdlib.h ?

So I opened a project that I had started a while ago and if I run a Verify/Compile immediately after opening my project it compiles successfully. I can even upload the code to my Arduino and it runs as expected.

BUT if I make a single edit - even changing something and then back to what it originally was - I suddenly get compile errors referencing the system stdlib.h file. And I have NOT messed around with any of the default system files like stdlib.h

How is this possible? My Arduino IDE was out of date when I reopened the project and I updated the main app and several libraries and board files. Open source is great, but this isn't the first time that some library update blew up previously fine code. It's a real PITA trying to juggle library versions sometimes.

Anyway - this seems like something basic, but I cannot put my finger on it. Some Googling suggested to ensure that the very first include reference was to Arduino.h in my ino project file, and that is what I have. I cannot understand how errors could possible occur in stdlib.h ???

HELP LOL

Obviously, there is some kind of cached compiled code from earlier work that allows it to run fine UNTIL I make an edit and it must flush that cache and recompile from scratch..

Here are my errors:

In file included from C:\Documents\Arduino\Sketches\XYscope-master\examples\CRT_SCOPE\XYscope.cpp:1:0:

C:\Users\me\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12\cores\arduino/wiring_constants.h:96:9: error: 'uint8_t' does not name a type

typedef uint8_t byte ;

^

c:\users\me\appdata\local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\stdlib.h:67:5: error: expected unqualified-id before 'int'

int _EXFUN(abs,(int));

^

c:\users\me\appdata\local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\stdlib.h:67:5: error: expected ')' before 'int'

c:\users\me\appdata\local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\stdlib.h:67:5: error: expected ')' before 'int'

exit status 1

Which Arduino board are you using and which board is selected in the IDE ?

Try holding down the shift key and clicking the Verify button in the IDE to do a clean recompile of teh code

This is for an Arduino Due. If I don't change anything when I open the ino project, it compiles correctly and I can upload the program to the Due board. No errors until I edit the code in some way. I can edit comments without issue, but changing any code - even putting it back the same way it was - causes the errors.

Holding down shift and doing a clean compile still has the same errors.

Example - after clean compile I get the errors. Close Arduino IDE but do not save. Reopen same file and if I do not edit any code, everything is fine...

Sketch uses 78796 bytes (15%) of program storage space. Maximum is 524288 bytes.

Atmel SMART device 0x285e0a60 found

Erase flash

done in 0.041 seconds

 

Write 81256 bytes to flash (318 pages)

 

[                              ] 0% (0/318 pages)

[==                            ] 9% (31/318 pages)

[=====                         ] 19% (62/318 pages)

[========                      ] 29% (93/318 pages)

[===========                   ] 38% (124/318 pages)

[==============                ] 48% (155/318 pages)

[=================             ] 58% (186/318 pages)

[====================          ] 68% (217/318 pages)

[=======================       ] 77% (248/318 pages)

[==========================    ] 87% (279/318 pages)

[============================= ] 97% (310/318 pages)

[==============================] 100% (318/318 pages)

done in 15.640 seconds

 

Verify 81256 bytes of flash

 

[                              ] 0% (0/318 pages)

[==                            ] 9% (31/318 pages)

[=====                         ] 19% (62/318 pages)

[========                      ] 29% (93/318 pages)

[===========                   ] 38% (124/318 pages)

[==============                ] 48% (155/318 pages)

[=================             ] 58% (186/318 pages)

[====================          ] 68% (217/318 pages)

[=======================       ] 77% (248/318 pages)

[==========================    ] 87% (279/318 pages)

[============================= ] 97% (310/318 pages)

[==============================] 100% (318/318 pages)

Verify successful

done in 14.534 seconds

Set boot flash true

CPU reset.

What happens if you save the sketch with a different name ? Does it compile ? If so, what happens if you then edit it. Does it still compile ?

I saved a copy of the project and IDE created a new folder with the copied project as expected.

Same exact results - compiles fine until I edit the line.

HOWEVER - I just noticed that not any edit causes the issue. I have been focused on inverting a digital output by modifying

digitalWrite(crtBlankingPin, HIGH);

to

digitalWrite(crtBlankingPin, LOW);

Both HIGH and LOW are defined in wiring_constants.h and I am not editing that file.

If I change HIGH to LOW and then back again so the code is the same way it was when I opened the project, I get the errors. It seems like I can do some other editing such as copying other lines that don't reference the HIGH and LOW aliases.

Can you post your sketch? Or a representative example that shows the behaviour?

Which version of the IDE are you using?

I believe that I am working with the current version 2.3.10. I was doing some testing and now I see the compiler is complaining about pinMode no declared. I have a suspicion that I have some bad library references combined with some cache issues. I did some Googling and apparently it's not possible (or easy) to flush the cache and rebuild from scratch? I tried the Shift-Compile option and everything always works fine the first time through. If I try to edit anything related to the wiring libraries, I get into trouble. Other edits seem to work fine.

My project is based on a Nuts & Volts magazine project here: GitHub - Ed-EE-Eng/XYscope: Library for using Arduino DUE to drive an oscilloscope as ab XYZ graphics device. · GitHub

Here is a 7zip file of my project - CRT_SCOPE_TEST.7z

I am attempting to invert some pin settings in the XYscope.cpp file from

digitalWrite(crtBlankingPin, HIGH);

to

digitalWrite(crtBlankingPin, LOW);

Seems straightforward enough and I never recall having any issues the last time I worked on this project. But after updating the IDE and numerous libraries this morning I haven't been able to edit these lines.

FWIW - I downloaded the original source code from Github and renamed my existing project folder and replaced it with the freshly download version in a new folder. I had to copy some code and .h files from the /src folder to the project folder so it could locate the references correctly, but after that EVERYTHING IS ACTING THE EXACT SAME. First time compile works fine. Edit a digitalWrite() line and everything falls apart.

If I find out that for some reason updates to wiring.h or stdlib.h definitions or calls have changed over the last few years to the point they now fail, that would be extremely stupid. How do you manage software if you cannot rely on basic system library calls ??? Or at least not provide any provision for old code to continue to run ??? Because that's what this is starting to feel like.

You're really going to have to show us a representative sketch that demonstrates the error. There are plenty of folks out here with that particular SAM core who could try compiling something to see if the error occurs.

Pick your poison - I provided links to the project above in post #8

After opening, try to compile - it will work fine.

Then go to the XYscope.cpp file and edit line 2170 from

digitalWrite(crtBlankingPin, HIGH);

to

digitalWrite(crtBlankingPin, LOW);

See if you can compile after that simple edit.

Note that if you choose the Github source, you will need to copy the files in the /src folder to the /examples/CRT_SCOPE folder for the references to work.

NOT links; post the actual code in code blocks, ideally also the verbose compiler and upload logs as well. Most of the experienced folks here already have a good idea of what is happening, but we need your code to confirm it. Make sure you auto-format first.

I have seen that type of error many times, some this year even.

I was thinking more along the lines of usual "minimal reproducible example" being provided. Hence, I'll pass and wish you good luck figuring it out.

That is suspicious. Most examples work without any fussing around.

Please attach your 7z file here; I'm having problems getting it from onedrive.

It should be a matter of drag-and-drop.

Unacceptable response.

OK - I think links are easier but if it helps, here you go...

INO

#define CompileDate DATE
#define CompileTime TIME
char CompileDateStamp[] = CompileDate;//This is how we get a compile date and time stamp into the program
char CompileTimeStamp[] = CompileTime;

char startMsg[] = "CRT_SCOPE (Ver_1.60) ";	//Program Revision Text

/*
CRT_SCOPE.ino  E.Andrews  Brookfield, WI USA

This program is an EXAMPLE program to demonstrate and test the
Arduino Graphics Interface (AGI) hardware.  This hardware provides
an interface between an Arduino DUE processor and an Oscillocope that
permits XY drawing and display of graphics objects onto the scope CRT.

Hardwareand software details can be are found in the EXTRA folder.
This project is urther described in the February 2018 and March 2018
editions of of the electronics magazine "Nuts & Volts"

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see http://www.gnu.org/licenses/.

Note: This program was written and tested using Arduino IDE, Version 1.8.2
Modifications may be required if using other platforms or versions of the IDE.
Also, you must select Arduino DUE as the target processor for correct and valid compilation.

20170311 Ver  0.00	E.Andrews	Development begins
20170826 Ver  1.00	E.Andrews	All key functions working, General Clean up
20171122 Ver  1.58 E.Andrews	Cleanup and tuning; Reset master revision level to 1.58
20180103 Ver  1.59 E.Andrews   Added clarifying comments throughout code base
20180103 Ver  1.60 E.Andrews   Adapt to Lib-structure, enhance comments, & test to ensure
that package can be compiled within ARDUINO-IDE Ver 1.8.2 as a library

This mainline requires the use of XYscope library, the set of drivers
that manage and drive the Arduino Graphics Interface (AGI) hardware.

XYscope libraries were first created by E. Andrews (March-September 2017) to enable
an Ardino DUE to drive a X-Y CRT such as an Oscilloscope or XYZ Monitor.

This program requires the following three (3) XYscope library routines to function properly
XYscope.h			Include file
XYscope.cpp			All grapahics control and plotting routines
VectorFontROM.h		FONT file used by XYscope to display variable sized vector-stroke characters.
All defined characters can be displayed using XYscope option 'S' and 's'.

*/

#include <Arduino.h>	//Provided as part of the Arduino IDE

#include <DueTimer.h>	//Timer library for DUE; download this library from the Arduino.org site
//Timer library is also available from author at https://github.com/ivanseidel/DueTimer

//UNCOMMENT ONE OF THE FOLLOWING TWO INCLUDE STATEMENTS TO SET THE PATH TO THESE THE LIBRARY PROGRAMS

#include <XYscope.h>	//UNCOMMENT THIS LINE for PUBLIC XYscope Drivers & Graphics Functions for Arduino Graphics Engine (AGI)
//Use this INCLUDE if you store XYscope library routines inside of ...\Library\XYscope folder

//#include "XYscope.h"	//UNCOMMENT THIS LINE for PRIVATE XYscope Drivers & Graphics Functions for Arduino Graphics Engine (AGI)
//Use this INCLUDE if you keep XYscope library routines in same directory as mainline.ino Directory

//Download this library from GitHub

XYscope XYscope;

// 	+---------Begin Critical Interrupt Service Routines ------------+
//	|  These routines MUST be declared as shown at the top of the	|
//	|      user's main line code for all XYscope Projects!			|
// 	+---------------------------------------------------------------+
//	|																|
//	V																V

void DACC_Handler(void) {
//	DACC_Handler Interrupt Service Routine. This routine
//	provides a 'wrapper' to link the AVR DAC INTERRUPT
//	to the 'XYscope-class' ISR routine.
XYscope.dacHandler();	//Link the AVR DAC ISR/IRQ to the XYscope.
//It is called whenever the DMA controller
//'DAC_ready_for_More_data' event occurs
}

void paintCrt_ISR(void) {
//	paintCrtISR  Interrupt Service Routine. This routine
//	provides a 'wrapper' to link the Timer3.AttachedInterrupt()
//	function to the 'XYscope-class' ISR routine.
XYscope.initiateDacDma();	//Start the DMA transfer to paint the CRT screen
}

//	V																V
//	|																|
// 	+---------- END Critical Interrupt Service Routines ------------+

//	Define/initialize critical global constants and variables

double dacClkRateHz, dacClkRateKHz;

int EndOfSetup_Ptr;
double TimeForRefresh;

char shiftVal = 0;
uint32_t dispTimer = 0;
int MovingX = 2048, MovingY = 2048;

int enabSecondHand;	//Flag to turn "Radar Scope clock Second-hand" demo feature on/off
//0=Disable second-hand animation, <>0=ENABLE second-hand animation

float angle = 0;

#include <malloc.h>	//Required for RAM usage monitoring routines

// The following lines are used for RAM monitoring routines
extern char _end;
extern "C" char *sbrk(int i);
char *ramstart = (char *) 0x20070000;
char *ramend = (char *) 0x20088000;

void setup() {
// Mainline program SETUP routine.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170708 Ver 0.0	E.Andrews	First cut
//						(Updated throughout development cycle without version change)

//Set Serial Monitor must be setup to agree with this initializtion.
//  [X] Autoscroll
//  "No Line Ending"
//  "115200 baud"
Serial.begin(115200);

//Send startup messages out to Serial monitor port...
Serial.println("");
Serial.print(startMsg);
Serial.print(" (");
Serial.print(CompileDateStamp);
Serial.print(" ");
Serial.print(CompileTimeStamp);
Serial.println(")");

double DmaFreq=800000;		//800000 (Hz) is the default startup value for the DMA frequency.
							//You can try various alternate values to find an optimal
							//value that works best for your scope, setup, & application.
							//Use program menu option "c" & "C" to vary the frequency while
							//watching your scope display; Using "c" & "C" options will allow you
							//to see how frequency changes effect the display quality in real-time.

XYscope.begin(DmaFreq);

//Timer3 is used as the CRT refresh timer.  This timer is setup inside of XYscope.begin( ).
//However, paintCRT_ISR must be "attached" to timer 3.  To be properly link to the
//refresh-screen XYscope interupt service routine, it must be linked in the Arduino 
//setup() code as follows:

Timer3.attachInterrupt(paintCrt_ISR);

//Here is just some stuff to paint onto CRT at startup
//v----------BEGIN SETUP SPLASH SCREEN ---------------v
ArduinoSplash();				//Paint an Arduino logo
int xC = 1800, yC = 2800;		//Set values of XY center coordinates for start of text
int textSize = 400;				//Set Text Size (in pixels)
bool const UndrLined = true;	//Turn underline ON
int textBright = 150;
XYscope.printSetup(xC - 150, yC + 50 + 700, textSize, textBright);
XYscope.print((char *)"AGI", UndrLined);
xC = 100;
yC = 2900;
textSize = 250;
XYscope.printSetup(xC + 50, yC + 50 + textSize, textSize, textBright);
XYscope.setFontSpacing(XYscope.prop);			//Select Proportional Spacing
if (XYscope.getFontSpacing() != XYscope.mono)	//Adjust coordinate in currently active spacing mode is 'prop'
	XYscope.printSetup(xC + 50 + 500, yC + 50 + textSize, textSize,
			textBright);
XYscope.print((char *)"Arduino Graphics Interface", false);	//(false=No underline)
XYscope.setFontSpacing(XYscope.mono);

XYscope.autoSetRefreshTime();
XYscope.plotRectangle(0, 0, 4095, 4095);

XYscope.printSetup(350, 275, 175, 100);
XYscope.print(startMsg);XYscope.print((char *)" LibRev:");XYscope.print(XYscope.getLibRev(),2);

//Now put the compile date & time onto the screen
//The time and data stamp come from #define statements at the top of the program...
XYscope.printSetup(1100, 100, 150, 100);
XYscope.print((char *)"(");
XYscope.print(CompileDateStamp);
XYscope.print((char *)"  ");
XYscope.print(CompileTimeStamp);
XYscope.print((char *)")");

//^----------BEGIN SETUP SPLASH SCREEN ---------------^

//Send option menu out to PC via Serial.print
Serial.println();
Print_CRT_Scope_Menu();
PrintStatsToConsole();

}

void loop() {	
// Begin CRT_SCOPE Mainline code!
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170708 Ver 0.0	E.Andrews	First cut
//						(Updated throughout development cycle without version change)
//

//Here is the start of the DEMO CONTROL panel, run via Serial.print link to PC...
int x0, y0, x1, y1;
int xCtr;
int yCtr;
int radius;
int xRadius;
int yRadius;
// This is main operator input decoder loop
if (Serial.available()) {

	char d = Serial.read();
	Serial.println();
	Serial.println(d);

	switch (d) {	//Decode operator input received via the serial monitor link-up

		case 'h': {	//Print main HELP menu to console
			Print_CRT_Scope_Menu();	//Show Help Menu
			break;
		}

		case '?': {	//Print current memory usage stats to console
			Print_CRT_Scope_Menu();	//Show Help Menu
			PrintStatsToConsole();	//Print current STATS to console
			break;

		}

		case '0': {		//Test rouine for XYscope.print (number) routines.
						//Print samaple Numbers WITHOUT Underline
						//This is just a bunch of random nums sent to screen
						//using various number formats...
						//Note: this shows that only about 7 digits of resolution
						//are truely available for floating point numbers 
						
			short ChInt = 100;	//Brightness of text for this test
			float TstNum = random(-160000000, 160000000);	//Create a random number
			TstNum = TstNum / 10000;	//make it a bit smaller
			Serial.print((char *)"Trying to print: ");	//Send Message to Serial Monitor
			Serial.print(TstNum, 9);
			Serial.println((char *)"  ");
			//These two routines do essentially the same thing...
			XYscope.plotClear();	//clear screen and intialize a fresh plot
			XYscope.plotStart();	//clear screen and intialize a fresh plot
			
			int CharSize = random(200, 325);
			int xPos = 20, yPos = 4095 - CharSize - 50;
			
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			
			XYscope.print(int(TstNum));						//Print Integer
			
			yPos = yPos - CharSize - 50;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum);			//Print Float to default (2) places

			yPos = yPos - CharSize - 50;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 3);//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 4);	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 5);	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 6);	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 7);	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 8);	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 9);//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 10);	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 11);	//Print Floating point to specified number of places

			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();	//Send memory usage report out to Serial Monitor

			break;
		}
		case '1': {		//Test rouine for XYscope.print (number) routines.
						//Print formatted Numbers WITH Underline
						//This is just a bunch of random numbers sent to screen
						//using various number formats with every other row underlined
						
			const int ChInt = 100;	//Brightness of text for this test
			float TstNum = random(-160000000, 160000000);
			TstNum = TstNum / 10000;
			Serial.print((char *)"Trying to print: ");
			Serial.print(TstNum, 9);
			Serial.println("  ");

			XYscope.plotClear();
			XYscope.plotStart();
			int CharSize = random(200, 325);
			int xPos = 20, yPos = 4095 - CharSize - 50;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(int(TstNum), bool(true));	//Print Integer

			yPos = yPos - CharSize - 50;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum);					//Print float to default (2) places

			yPos = yPos - CharSize - 50;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 3, bool(true));	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 4);				//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 5, bool(true));	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 6);				//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 7, bool(true));	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 8);				//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 9, bool(true));	//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 10);				//Print Floating point to specified number of places

			yPos = yPos - CharSize;
			XYscope.printSetup(xPos, yPos, CharSize, ChInt);
			XYscope.print(TstNum, 11, bool(true));	//Print Floating point to specified number of places

			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();

			break;
		}

		case '2': {	//Draw Circle inside of Box Pattern for CENTERING
			drawCenteringPattern();	//Use this pattern for scope and gain adjustments
			PrintStatsToConsole();
			break;
		}

		case '3': {	//Random graphics figures
			XYscope.plotClear();
			XYscope.plotStart();
			for (int i = 1; i < 5; i++) {

				x0 = int(random(0, 4096));
				y0 = int(random(0, 4096));
				x1 = int(random(0, 4096));
				y1 = int(random(0, 4096));

				XYscope.plotRectangle(x0, y0, x1, y1);

				xCtr = int(random(0, 4096));
				yCtr = int(random(0, 4096));
				radius = int(random(0, 2048));
				XYscope.plotCircle(xCtr, yCtr, radius);

				xCtr = (random(0, 4096));
				yCtr = (random(0, 4096));
				xRadius = int(random(0, 2048));
				yRadius = int(random(0, 2048));
				XYscope.plotEllipse(xCtr, yCtr, xRadius, yRadius);

			}

			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}
		case '4': {	//Simulated graphical chart plot
			SimGraph_0();
			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}

		case '5': {	// Plot Random Eliptical figures
			XYscope.plotClear();
			XYscope.plotStart();
			XYscope.plotErr = 1;

			while (XYscope.plotErr > 0) {
				xCtr = int(random(0, 4096));
				yCtr = int(random(0, 4096));
				xRadius = int(random(0, 2048));
				yRadius = int(random(0, 2048));
				XYscope.plotEllipse(xCtr, yCtr, xRadius, yRadius);
				//TODO XYscope.plotEll(xCtr,yCtr,xRadius,yRadius);
				XYscope.autoSetRefreshTime();
			}
			PrintStatsToConsole();	//Send mem usage report to console
			break;
		}
		case '6': {	//Plot one single fixed size Ellipse
			XYscope.plotClear();
			XYscope.plotStart();
			xCtr = 2048;
			yCtr = 2048;
			xRadius = 500;
			yRadius = 1000;
			XYscope.plotEllipse(xCtr, yCtr, xRadius, yRadius);
			XYscope.autoSetRefreshTime();

			PrintStatsToConsole();	//Send mem usage report to console
			break;
		}
		case '7': {		//Scope sine wave pattern.  This one is good for op-amp adjustment
			XYscope.plotClear();
			XYscope.plotStart();
			XYscope.plotPoint(0, 4095);
			xCtr = 2047;
			yCtr = 2047;
			xRadius = 2047;
			yRadius = 2047;

			float numTestPoints = XYscope.getGraphicsIntensity();
			float testAngle = 0;
			int patternCount = 0;
			float angleStep = 2 * 3.141526 / numTestPoints;
			testAngle = testAngle - angleStep;
			for (patternCount = 0; patternCount < numTestPoints;
					patternCount++) {
				testAngle = testAngle + angleStep;
				XYscope.plotPoint(int(xCtr + xRadius * sin(testAngle)),
						int(yCtr + yRadius * cos(testAngle)));
			}
			XYscope.plotPoint(4095, 4095);
			XYscope.plotEnd();
			XYscope.autoSetRefreshTime();

			PrintStatsToConsole();	//Send mem usage report to console

			break;

		}
		case '8': {	//plotARC test function - Draw series of Circle arc segments from 0 to 7
					//This shows how the segment variable can be used.  Note that Multiple segments can be 
					//plotted in one call as the 'segment' variable is 'bit' based.

			int aSeg = 1;
			for (int segment = 0; segment < 8; segment++) {
				XYscope.plotClear();
				XYscope.plotStart();
				xCtr = 2047;
				yCtr = 2047;
				xRadius = 2047;
				yRadius = 2047;

				int tempIntensity = XYscope.getGraphicsIntensity();
				XYscope.setGraphicsIntensity(10);//Reset density to high value so we can draw a dotted ellipse
				XYscope.plotCircle(xCtr, yCtr, xRadius);	//draw dotted circle
				XYscope.setGraphicsIntensity(tempIntensity);//Return density to normal value


				XYscope.plotLine(0, 4095, 4095, 0);		//Draw 135 Deg Line, TopLeft to BotRright
				XYscope.plotLine(4095, 4095, 0, 0);		//Draw 45 Deg Line, TopRight to BotLeft
				XYscope.plotLine(0, 2047, 4095, 2047);	//Center Horizontal Cross Hair
				XYscope.plotLine(2047, 0, 2047, 4095);	//Center Vertical Cross Hair

				XYscope.plotCircle(xCtr, yCtr, xRadius, aSeg);

				XYscope.printSetup(50, 2200, 300, 100);	//Set char height, x-location, y-location, Brightness%
				//Print segment report onto screen
				XYscope.print((char *)"Seg:");

				XYscope.print(segment);
				//Send status report to console to show which segment was generated...
				Serial.print(" Plotted ArcCircle pattern... Segment: ");
				Serial.print(segment);
				Serial.print(", Code: ");
				Serial.println(aSeg);

				//PAUSE (Stop and wait for any keypress...)
				WaitForAnyKey(" DONE ");
				aSeg = aSeg * 2;	//Shift left one position

			}
			PrintStatsToConsole();	//Send mem usage status report to console
			break;

		}
		case '9': {	//plotArcEllipse test function - Draw series of Ellilpse arc segments from segment code 0 to 7
					//This shows how the segment variable can be used.  Note that Multiple segments can be 
					//plotted in one call as the as the 'segments' varabile is 'bit' based.
			int aSeg = 1;
			for (int segment = 0; segment < 8; segment++) {
				XYscope.plotClear();
				XYscope.plotStart();
				xCtr = 2047;
				yCtr = 2047;
				xRadius = 1200;
				yRadius = 1800;

				int tempIntensity = XYscope.getGraphicsIntensity();
				XYscope.setGraphicsIntensity(10);//Reset intensity low to draw a dotted ellipse
				XYscope.plotEllipse(xCtr, yCtr, xRadius, yRadius, 255);	//draw dotted ellipse

				XYscope.setGraphicsIntensity(tempIntensity);//Return density to normal value

				XYscope.plotLine(0, 4095, 4095, 0);		//Draw 135 Deg Line, TopLeft to BotRright
				XYscope.plotLine(4095, 4095, 0, 0);		//Draw 45 Deg Line, TopRight to BotLeft
				XYscope.plotLine(0, 2047, 4095, 2047);	//Center Horizontal Cross Hair
				XYscope.plotEllipse(xCtr, yCtr, xRadius, yRadius, aSeg);//Draw just desired segment

				XYscope.printSetup(50, 2200, 300, 100);
				XYscope.print((char *)"Seg:");
				XYscope.print(segment);

				Serial.print(" Plotted ArcEllipse pattern... Segment: ");
				Serial.print(segment);
				Serial.print(", Code: ");
				Serial.println(aSeg);
				//PAUSE (Stop and wait for any keypress...)
				WaitForAnyKey(" DONE ");
				aSeg = aSeg * 2;	//Shift left one position
			}
			PrintStatsToConsole();	//Send mem usage status report to console
			break;
		}

		case '-': {	//Decrease Graphics Intensity Value
			if (XYscope.getGraphicsIntensity() - 10 > 0)
				//Decrement current Graphics Intensity by 10
				XYscope.setGraphicsIntensity(
						XYscope.getGraphicsIntensity() - 10);
			break;
		}

		case '+': {	//Increase Graphics Intensity Value
			if (XYscope.getGraphicsIntensity() + 10 < 255)
				//Increment current Graphics Intensity by 10
				XYscope.setGraphicsIntensity(XYscope.getGraphicsIntensity() + 10);
			break;
		}

		case '*': {	//Toggles sweep second hand animation ON and OFF

			if (enabSecondHand == 0) {
				enabSecondHand = 1;
				Serial.println("   Seconds Hand ENABLED");
			} else {
				enabSecondHand = 0;
				Serial.println("   Seconds Hand DISABLED");
			}
			break;
		}
		case 'F': {	//Increase FRONT PORCH timing by one count
			//Detailed timing adjustment...you shouldn't normally need to change this value
			//Increment Front-Porch Blanking
			XYscope.frontPorchBlankCount++;
			Serial.print("    DMA Clock Freq: ");
			Serial.print(XYscope.DmaClkFreq_Hz / 1000);
			Serial.print(" Khz");
			Serial.print(" (Period: ");
			Serial.print(XYscope.DmaClkPeriod_us);
			Serial.println(" us)");
			Serial.print("   INCR FRONT PORCH: New Blank Count = ");
			Serial.println(XYscope.frontPorchBlankCount);
			break;
		}
		case 'f': {	//Decrease FRONT PORCH timing by one count
			//Detailed timing adjustment...you shouldn't normally need to change this value
			//Decrement Front-Porch Blanking
			XYscope.frontPorchBlankCount--;
			Serial.print("    DMA Clock Freq: ");
			Serial.print(XYscope.DmaClkFreq_Hz / 1000);
			Serial.print(" Khz");
			Serial.print(" (Period: ");
			Serial.print(XYscope.DmaClkPeriod_us);
			Serial.println(" us)");
			Serial.print("   DECR FRONT PORCH: New Blank Count = ");
			Serial.println(XYscope.frontPorchBlankCount);
			break;
		}

		case 'B': {//Increase BACK PORCH timing by one count
			//Detailed timing adjustment...you shouldn't normally need to change this value
			//Increment Back-Porch Blanking
			XYscope.backPorchBlankCount++;
			Serial.print("    DMA Clock Freq: ");
			Serial.print(XYscope.DmaClkFreq_Hz / 1000);
			Serial.print(" Khz");
			Serial.print(" (Period: ");
			Serial.print(XYscope.DmaClkPeriod_us);
			Serial.println(" us)");
			Serial.print("   INCR BACK PORCH: New Blank Count = ");
			Serial.println(XYscope.backPorchBlankCount);
			break;
		}
		case 'b': {	//Decrease BACK PORCH timing by one count
			//Detailed timing adjustment...you shouldn't normally need to change this value
			//Decrement Back Front-Porch Blanking
			XYscope.backPorchBlankCount--;
			Serial.print("    DMA Clock Freq: ");
			Serial.print(XYscope.DmaClkFreq_Hz / 1000);
			Serial.print(" Khz");
			Serial.print(" (Period: ");
			Serial.print(XYscope.DmaClkPeriod_us);
			Serial.println(" us)");
			Serial.print("   DECR BACK PORCH: New Blank Count = ");
			Serial.println(XYscope.backPorchBlankCount);
			break;
		}
		case 'c': {	//Change Clock Frequency...
			//DECREASE DMA Clock Frequency in 50khz steps (Limit min value to 500 Khz)
			// Try different values to see how well your scope and setup perform.
			// Look for artifacts and defects in the graphics display, particularly when
			// graphics objects are spaced far apart.
			uint32_t New_XfrRateHz = XYscope.DmaClkFreq_Hz - 50000;	//Decr in 50Khz steps
			if (New_XfrRateHz < 500000)
				New_XfrRateHz = 500000;
			XYscope.setDmaClockRate(New_XfrRateHz);
			XYscope.autoSetRefreshTime();
			Serial.print("   DECR DMA CLK: New Freq = ");
			Serial.print(XYscope.DmaClkFreq_Hz);
			Serial.println(" (Hz)");

			break;
		}
		case 'C': {	//Change Clock Frequency...
			//INCREASE DMA Clock Frequency in 50 kHz steps (Limit max value to 1.2 Mhz)
			// Try different values to see how well your scope and setup perform.
			// Look for artifacts and defects in the graphics display, particularly when
			// graphics objects are spaced far apart.

			uint32_t New_XfrRateHz = XYscope.DmaClkFreq_Hz + 50000;	//Incr in 50Khz steps
			if (New_XfrRateHz > 120000000)
				New_XfrRateHz = 1800000;
			XYscope.setDmaClockRate(New_XfrRateHz);
			XYscope.autoSetRefreshTime();
			Serial.print("   INCR DMA CLK: New Freq = ");
			Serial.print(XYscope.DmaClkFreq_Hz);
			Serial.println(" (Hz)");

			break;
		}

		case 'd':	//Draw pattern to measure DAC raise and fall times
			//For use in testing and setting detailed timing adjustments...
			//Draw corner to corner dot pattern to Screen for worst case DAC evaluation
			PeakToPeakTest_D();
			PrintStatsToConsole();
			break;

		case 'D':
			//Draw Coordinate System Plot
			SimCoordinateSys();
			PrintStatsToConsole();
			break;

		case 'H':
			//Draw HORIZONTAL Sq Wave Pattern to Screen
			//For use in testing and setting detailed timing adjustments...
			PeakToPeakTest_H();
			PrintStatsToConsole();

			break;
		case 'V':
			//Draw VERTICAL Sq Wave Pattern to Screen
			//For use in testing and setting detailed timing adjustments...
			PeakToPeakTest_V();
			PrintStatsToConsole();
			break;

		case 'i': {
			//Decrease TEXT Intensity Value
			if (XYscope.getTextIntensity() - 10 > 0)
				XYscope.setTextIntensity(XYscope.getTextIntensity() - 10);
			break;
		}
		case 'w': {
			//Example of How To Wakeup from a screen saver blank event
			//To wakeup the screen, just call the setScreenSaverSecs routine with the Current Setting...
			// 1) Read the Current Setting
			long curScreenSaverSetting = XYscope.getScreenSaveSecs();
			// 2) Call routine with Current Setting
			XYscope.setScreenSaveSecs(curScreenSaverSetting);//This sequence wakes up screen and resets the time to sleep? counterresets save timer
			break;
		}
		case 'I': {
			//Increase TEXT Intensity Value
			if (XYscope.getTextIntensity() + 10 < 255)
				XYscope.setTextIntensity(XYscope.getTextIntensity() + 10);
			break;
		}
		case 'l': {	//Animation example...
			//Animation that Plots Arduino LOGO at various sizes
			int Lx = 100, Ly = 2000, Lht = 1000;
			XYscope.plotStart();
			bool const Underlined = true;
			XYscope.printSetup(2047 - int(float(4000 / 16) * 1.5), 1200, 400,
					100);
			XYscope.print((char *)"AGI", Underlined);
			short Tx = 150, Ty = 900;
			if (XYscope.getFontSpacing() != XYscope.mono)
				Tx = 775;
			XYscope.printSetup(Tx, Ty, 230, 100);
			XYscope.print((char *)"A", Underlined);
			XYscope.print((char *)"rduino ");		//(No-underline)
			XYscope.print((char *)"G", Underlined);
			XYscope.print((char *)"raphics ");		//(No-underline)
			XYscope.print((char *)"I", Underlined);
			XYscope.print((char *)"nterface");		//(No-underline)
			XYscope.printSetup(1100, 100, 175, 100);
			XYscope.print(startMsg);				//(No-underline)
			XYscope.plotRectangle(0, 0, 4095, 4095);

			XYscope.printSetup(20, 100, 175, 100);
			int StartOfLogo = XYscope.XYlistEnd;//Grab the current pointer value

			for (Lht = 30; Lht < 2025; Lht = Lht + 50) {
				XYscope.XYlistEnd = StartOfLogo;//Here's how to do ANIMATION at the endof XYlist...
												//Keep the pointer fixed to keep rewriting
												//the same part of the array
				XYscope.plotErr = 1;
				Lx = 2047 - int(float(Lht / 16) * 14);
				Ly = 2000;
				XYscope.plotArduinoLogo(Lx, Ly, Lht);
				delay(40);	//Just a slight delay to slow redraws down a bit


			}

			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}
		case 'm': {
			//Toggle Font Space mode back and forth between Mono and Proportional
			if (XYscope.getFontSpacing() == XYscope.mono)
				XYscope.setFontSpacing(XYscope.prop);
			else
				XYscope.setFontSpacing(XYscope.mono);
			break;
		}

		case 's': {
			//Display sample text, Test #1
			XYscope.plotClear();
			XYscope.plotStart();
			XYscope.plotErr = 1;
			int cX = 50, cY = 4050, charHt = 500;
			const int charPerLine = 12;
			uint8_t startChar = ' ' - charPerLine;
			for (int Row = 1; Row < 9; Row++) {
				startChar = startChar + charPerLine;
				cY = 4050 - Row * 500;
				cX = 0;
				for (uint8_t tstChar = startChar;
						tstChar < startChar + charPerLine; tstChar++) {
					XYscope.plotChar(tstChar, cX, cY, charHt);
				}
			}
			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}
		case 'S': {
			//Display sample text, Test #2
			XYscope.plotClear();
			XYscope.plotStart();
			XYscope.plotErr = 1;
			int cX = 50, cY = 4050, charHt = 500;
			const int charPerLine = 12;
			uint8_t startChar = '0' - charPerLine;
			for (int Row = 1; Row < 9; Row++) {
				startChar = startChar + charPerLine;
				cY = 4050 - Row * 500;
				cX = 0;
				for (uint8_t tstChar = startChar;
						tstChar < startChar + charPerLine; tstChar++) {
					XYscope.plotChar(tstChar, cX, cY, charHt);
				}
			}
			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}
		case 't': {
			//Show Analog Clock Hands simulation 1
			SimClock_1();
			EndOfSetup_Ptr = XYscope.XYlistEnd;
			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}
		case 'T': {
			//Show Analog Clock Hands simulation 2
			SimClock_0();
			EndOfSetup_Ptr = XYscope.XYlistEnd;
			XYscope.autoSetRefreshTime();
			PrintStatsToConsole();
			break;
		}
		case 'p':
			//Show Pong Demo (Animated; Type any key to end demo)
			PongDemo();
			break;

		default: {
			//Undefined input character detected; just print HELP screen to user
			Serial.println("^-- invalid/unknown command character entered ");
			XYscope.plotStart();		//Clear Screen and plot message...
			XYscope.setFontSpacing(XYscope.prop);	//Set Proportional Spacing
			XYscope.printSetup(100, 2047, 230, 100);
			XYscope.print((char *)"Unknown Option Entered...Try Again");
			XYscope.plotEnd();
			XYscope.autoSetRefreshTime();
			delay(3000);	//Wait 3 seconds
			//drawCenteringPattern();
			setup();		//Reset All and draw startup image
			PrintStatsToConsole();
			break;
		}

	}	//End of operator input decoder

}

else {

	float delta_Ang = (2 * PI) / (60);

	if ((enabSecondHand == 1) && (millis() > TimeForRefresh)) {
		//This is an early version of a moving second hand demo...Redundant to menu option 't' (Clock simulation)
		TimeForRefresh = millis() + 1000;
		angle = (angle + delta_Ang);
		if (angle >= 2 * PI)
			angle = delta_Ang;
		MovingX = 2047 * sin(angle) + 2047;
		if (MovingX > 4095)
			MovingX = 4095;
		if (MovingX < 0)
			MovingX = 0;
		MovingY = 2047 * cos(angle) + 2047;
		if (MovingY > 4095)
			MovingX = 4095;
		if (MovingY < 0)
			MovingX = 0;
		XYscope.setGraphicsIntensity(XYscope.getGraphicsIntensity());
		XYscope.XYlistEnd = EndOfSetup_Ptr - 1;
		XYscope.plotLine(2047, 2047, MovingX, MovingY);
		XYscope.plotEnd();
		XYscope.autoSetRefreshTime();
	}
}

}

//=======================================================
//	PONG Demo
//=======================================================
void PongDemo() {
// PONG style game display to demo how to do animation.
// This demo just moves a 'ball' around the screen bouncing off of walls.
// Touch any key to terminate the demo and select another program
// option.  The program could easily sample some analog ports and
// use that data to 'move the paddles' and in turn actually code
// a working 'PONG-Style' game.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170708 Ver 0.0	E.Andrews	First cut
//						(Updated slightly throughout development cycle without version change)
//
float ballX = 2048, ballY = 2048;//define and initialize ball at center of screenBall Center Point
int ballR = 75;					//Define Ball Radius
float ballDX = .5, ballDY = .31;	//Define initial Ball Velocities

int Lwall = 0, Rwall = 4095;		//Define Left & right Wall	X-Coord

int Twall = 4095, Bwall = 0;		//Top & Bottom wall Y-Coord

int ballCount = 5, ballMax = 1;	//Define number of times to draw ball

// Clear screen and draw court
XYscope.plotStart();
XYscope.plotLine(Lwall, Twall, Rwall, Twall);	//Top line
XYscope.plotLine(Rwall, Twall, Rwall, Bwall);	//Right line
XYscope.plotLine(Rwall, Bwall, Lwall, Bwall);	//Bottom line
XYscope.plotLine(Lwall, Bwall, Lwall, Twall);	//Left line
//Draw "net" as a dashed line down the center of the screen
const int dashLength = 200;
for (int dash = dashLength / 2; dash < Twall - dashLength / 2;
		dash = dash + dashLength) {
	XYscope.plotLine(Rwall / 2, dash, Rwall / 2, dash + dashLength / 2);//Center line
}

//Draw a simulated score...Note, scores do not change in DEMO code!
XYscope.printSetup(700, 3000, 800);
XYscope.print((char *)"18");
XYscope.printSetup(2700, 3000, 800);
XYscope.print((char *)"09");

//Draw simulated paddles...Paddles remain stationary in DEMO code!
XYscope.plotRectangle(200, 1200, 300, 1700);	//Left Paddle
XYscope.plotRectangle(3800, 1600, 3900, 2100);	//Right Paddle

//Remember the current XYlistEnd value so we can return to it every time we
//want to move and rewrite the ball
int ixEmptyCourt = XYscope.XYlistEnd;

Serial.println("**** press a key to stop PONG DEMO ****");
int wait = true;
ballCount = 0;

while (wait)	//In this loop, we just move the ball around the court!
{
	if (Serial.available()) {//Check for key press...any key = Leave the DEMO
		int d=0;
		while (d>=0) {
			d=Serial.read();	//clean out the buffer (Retrieved data is NOT USED)
		} 						//...flush buffer, keep reading until buffer is empty.  Note, Serial.read will return as -1 when no data is available

		wait = false;
		Serial.println(F("_KP_"));
		delay(100);
	}
	//Draw Ball
	XYscope.plotCircle(ballX, ballY, ballR);
	ballCount = ballCount + 1;

	//Plot the ball multiple times before moving it to make it brighter
	if (ballCount > ballMax) {
		XYscope.XYlistEnd = ixEmptyCourt;
		ballCount = 0;
	}

	//Move Ball...
	ballX = ballX + ballDX;
	ballY = ballY + ballDY;
	//Define Ball to Wall collision limits based on size of ball
	int TopLimit = Twall - ballR;
	int BotLimit = Bwall + ballR;
	int RightLimit = Rwall - ballR;
	int LeftLimit = Lwall + ballR;

	//---Check for Top-Bottom collisions with walls...
	if (ballY >= TopLimit) {	//Top Wall Impact
		ballY = +TopLimit - (abs(ballDY) - abs(ballY - TopLimit));
		ballDY = -ballDY;
	}
	if (ballY <= BotLimit) {	//Bottom wall Impact
		ballY = BotLimit + (abs(ballDY) - abs(ballY - BotLimit));
		ballDY = -ballDY;
	}
	//Check Left-Right collisions with walls...
	if (ballX >= RightLimit) {	//Right Wall Impact
		ballX = RightLimit - (abs(ballDX) - abs(ballX - RightLimit));
		ballDX = -ballDX;
	}
	if (ballX <= LeftLimit) {	//Left Wall Impact
		ballX = LeftLimit + (abs(ballDX) - abs(ballX - LeftLimit));
		ballDX = -ballDX;
	}
	//---Check for & react to ball collisions with Paddles.....
	//	Need to add scoring & reporting, ball reaction, ball sounds, etc...
	//  You Add this Part!!!

}

}
//=========== END PONG DEMO =============================

//=======================================================
//	SPLASH SCREEN DEMO
//=======================================================
void ArduinoSplash() {
// Locate and plot the Arduino-Logo to screen.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20171008 Ver 0.0	E.Andrews	First cut
//

int Lx = 1150, Ly = 2000, Lht = 1000;
XYscope.plotStart();
XYscope.plotArduinoLogo(Lx, Ly, Lht);

}
//=========== END SPLASH =================================

void drawCenteringPattern(void) {
// Plots a circle and square that can be used for scope centering and gain adjust
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170708 Ver 0.0	E.Andrews	First cut
//

XYscope.plotStart();
int X_Center = 2047;
int Y_Center = 2400;
int Circ_Radius = 800;
X_Center = 2048;
Y_Center = 2048;

XYscope.plotCircle(X_Center, Y_Center, Circ_Radius);		//try a circle
Circ_Radius = 2045;
XYscope.plotCircle(X_Center, Y_Center, Circ_Radius);		//try a circle

XYscope.plotPoint(X_Center, Y_Center);	// Put a DOT at the center of the circ.
XYscope.plotLine(4095, 4095, 0, 4095);	//TOP Border
XYscope.plotLine(0, 4095, 4095, 0);		//TopLt to BotRt Diag
XYscope.plotLine(4095, 0, 0, 0);		//BOTTOM Border
XYscope.plotLine(0, 0, 4095, 4095);		//TopRt to BotLt Diag

XYscope.plotLine(4095, 0, 4095, 4095);	//RIGHT Border
XYscope.plotLine(0, 0, 0, 4095);		//LEFT Border

EndOfSetup_Ptr = XYscope.XYlistEnd;		//Remember end of buffer ptr in case second hand is enabled

XYscope.plotEnd();						//end with plot to 0,0
XYscope.autoSetRefreshTime();
ShowMemory();
PrintStatsToConsole();

}

//================ START OF SIMULATED CLOCK ROUTINES ========================//
//DEFINE Global (Gbl) Variables used to draw the clock features

float Gbl_X_Center, Gbl_Y_Center, Gbl_Center_Radius, Gbl_MinHubCenterRadius;
float Gbl_Hour_HandLength,Gbl_Hour_EndRadius, Gbl_Hour_End_X_Center, Gbl_Hour_End_Y_Center;
float Gbl_Min_HandLength, Gbl_Min_EndRadius, Gbl_Min_End_X_Center, Gbl_Min_End_Y_Center;
float Gbl_Sec_HandLength, Gbl_Sec_End_X, Gbl_Sec_End_Y;
int Gbl_HR_ListPtr, Gbl_MIN_ListPtr, Gbl_SEC_ListPtr;

void SimClock_0(void) {
//  This routine does a one time paint of a fixed clock image.
//	You can use  the '*' key (at the main menu) to active a moving second-hand.
//
//	Note: This is just a fixed image of a clock face and was my first
//	attempt to see how AGI would look as a CRT-Clock driver.  SimClock_1 came
//	later and is a more fully animated version with moving hour, minute, & second hands.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170708 Ver 0.0	E.Andrews	First cut
//						(Updated throughout project without version change)

XYscope.plotClear();
XYscope.plotStart();
int xCtr = 2047;
int yCtr = 2047;
int xRadius = 1900;
int yRadius = 1900;
Serial.print(" Generating Clock Face test pattern...");
//Serial.print(" ==> Ellipse (ix,x,y,xRadius,yRadius) = (");Serial.print(ix); Serial.print(",");Serial.print(xCtr); Serial.print(",");Serial.print(yCtr); Serial.print(",");Serial.print(xRadius); Serial.print(",");Serial.print(yRadius);Serial.println(")");
//WaitForAnyKey(" ");
float numTestPoints = 12;
float testAngle = 0;
int patternCount = 0;
float angleStep = 2 * 3.141526 / numTestPoints;
testAngle = testAngle - angleStep;
const int charHt = 500;
int HoursIntensity = 0;
int OldTextIntensity = XYscope.getTextIntensity();
XYscope.setGraphicsIntensity(100);
for (patternCount = 0; patternCount < numTestPoints; patternCount++) {
	HoursIntensity = HoursIntensity + 20;//For test purposes, change intensity of every hour value. Start at 20%
	if (HoursIntensity > 255)
		HoursIntensity = 255;

	testAngle = testAngle + angleStep;
	int xP, yP;
	xP = int(xCtr + xRadius * sin(testAngle));
	yP = int(yCtr + yRadius * cos(testAngle));
	//XYscope.plotPoint(xP,yP);
	//XYscope.plotPoint(xP,yP);
	//XYscope.plotPoint(xP,yP);
	//XYscope.plotPoint(xP,yP);
	XYscope.plotCircle(xP, yP, 40);	//Plot small circles at HOUR marks
	// Now Plot Hour numbers 1-12.  Change in text-plot-radius
	// and offsets were needed to get the numbers in the right place...
	int xDelta = -350;
	int yDelta = -350;
	int xOffset = -charHt / 2;
	int yOffset = -charHt / 2;
	xP = int(xCtr + xOffset + (xRadius + xDelta) * sin(testAngle));
	yP = int(yCtr + yOffset + (yRadius + yDelta) * cos(testAngle));
	//Plot HOURS text
	if (patternCount > 0 && patternCount < 7)
		XYscope.printSetup(xP + 150, yP, charHt, HoursIntensity);
	else
		XYscope.printSetup(xP, yP, charHt, HoursIntensity);
	if (patternCount == 0) {
		XYscope.printSetup(xP, yP, charHt, 250);
		XYscope.print((char *)"12");
	} else
		XYscope.print(patternCount);
}
//Restore prior Text Intensity
XYscope.setTextIntensity(OldTextIntensity);
//Draw some sample hour hands...
XYscope.plotCircle(xCtr, yCtr, 150);	//Center Circle
//Hour Hand
XYscope.plotLine(xCtr, yCtr + 150, xCtr + xRadius - 500, yCtr);
XYscope.plotLine(xCtr, yCtr - 150, xCtr + xRadius - 500, yCtr);
//Minute Hand
XYscope.plotLine(xCtr + 150, yCtr, xCtr, yCtr + yRadius);
XYscope.plotLine(xCtr - 150, yCtr, xCtr, yCtr + yRadius);

//Draw short dashed lines for each of the SECOND marks
numTestPoints = 60;
angleStep = 2 * 3.141526 / numTestPoints;
for (patternCount = 0; patternCount < numTestPoints; patternCount++) {
	testAngle = testAngle + angleStep;
	int xP1, yP1, xP2, yP2;
	xP1 = int(xCtr + (xRadius + 50) * sin(testAngle));
	yP1 = int(yCtr + (yRadius + 50) * cos(testAngle));
	xP2 = int(xCtr + (xRadius - 50) * sin(testAngle));
	yP2 = int(yCtr + (yRadius - 50) * cos(testAngle));
	//Skip plotting the SECONDS-MARK at each of the HOUR marks
	if ((patternCount + 1) % 5 != 0)
		XYscope.plotLine(xP1, yP1, xP2, yP2);
}
int logoHt = 1000;
int logoX = 2047 - logoHt * .85;
int logoY = 2047 - logoHt;

XYscope.plotArduinoLogo(logoX, logoY, logoHt);

XYscope.plotPoint(4095, 4095);
Serial.print(" DONE.\n  Num of Points Plotted: ");
Serial.print(numTestPoints);
Serial.print("  XYlistEnd=");
Serial.println(XYscope.XYlistEnd);
XYscope.plotEnd();
//ix=XYscope.plotEllipse(ix,xCtr,yCtr,xRadius,yRadius);
EndOfSetup_Ptr = XYscope.XYlistEnd - 1;
XYscope.autoSetRefreshTime();

}

void SimClock_1(void) {
//  This routine shows the basics of a CRT clock application
//	This shows how DrawClockHourHand(Hr), DrawClockMinuteHand(Min),
//	and DrawClockSecondHand(Sec) routines can be written and used.
//	Take note of how the XYscope.XYlistEnd is managed to animate and
//	redraw the hands. Also, note that ClockHandsSetup(...) is a routine
//	that is used to define the location and size parameters for hands.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20171106 Ver 0.0	E.Andrews	First cut
//						(Minor updates throughout development without version change)

XYscope.plotClear();
XYscope.plotStart();
int xCtr = 2047;
int yCtr = 2047;
int CenterRadius=200;
int Min_HubCenterRadius = 100;
int ClockRadius=1900;
int HR_armRadius=ClockRadius-500;
int MN_armRadius=ClockRadius;
int SEC_armRadius=ClockRadius+120;
int xRadius = 1900;
int yRadius = 1900;
//Initialize ClockHands global variables

ClockHandsSetup(xCtr,yCtr,CenterRadius,Min_HubCenterRadius, HR_armRadius,MN_armRadius,SEC_armRadius);

//	Here is where we draw the fixed, CLOCK FACE parts...
Serial.print(" Run: CRT-Clock-Sim Routines...");
float numTestPoints = 12;	//We want to have 12 text Hour Markers
float testAngle = 0;
int patternCount = 0;
float angleStep = 2 * 3.141526 / numTestPoints;
testAngle = testAngle - angleStep;
const int charHt = 500;
int HoursIntensity = 0;
int OldTextIntensity = XYscope.getTextIntensity();
XYscope.setGraphicsIntensity(100);
for (patternCount = 0; patternCount < numTestPoints; patternCount++) {
	HoursIntensity = HoursIntensity + 20;	//Just for fun and test purposes, change
											//intensity of every hour value. Start at
											//20% and step brightness for each HOUR.
											//A real CRT clock will probably want to
											// have one intensity for all hour markers.
	HoursIntensity=150;	//Comment this line out if you want to plot each hour at different level
	if (HoursIntensity > 255)  HoursIntensity = 255;
	testAngle = testAngle + angleStep;
	int xP, yP;
	xP = int(xCtr + xRadius * sin(testAngle));
	yP = int(yCtr + yRadius * cos(testAngle));

	XYscope.plotCircle(xP, yP, 40);	//Plot small circles at HOUR marks
	// Now Plot Hour numbers 1-12.  Change in text-plot-radius
	// and offsets were needed to get the numbers in the right place...
	int xDelta = -350;
	int yDelta = -350;
	int xOffset = -charHt / 2;
	int yOffset = -charHt / 2;
	xP = int(xCtr + xOffset + (xRadius + xDelta) * sin(testAngle));
	yP = int(yCtr + yOffset + (yRadius + yDelta) * cos(testAngle));

	//Plot HOURS text
	if (patternCount > 0 && patternCount < 7)
		XYscope.printSetup(xP + 150, yP, charHt, HoursIntensity);
	else
		XYscope.printSetup(xP, yP, charHt, HoursIntensity);
	if (patternCount == 0) {
		XYscope.printSetup(xP, yP, charHt, HoursIntensity);
		XYscope.print((char *)"12");
	} else
		XYscope.print(patternCount);
}
//Restore prior Text Intensity
XYscope.setTextIntensity(OldTextIntensity);

//Draw short dashed lines for each of the SECOND marks
numTestPoints = 60;
angleStep = 2 * 3.141526 / numTestPoints;
for (patternCount = 0; patternCount < numTestPoints; patternCount++) {
	testAngle = testAngle + angleStep;
	int xP1, yP1, xP2, yP2;
	xP1 = int(xCtr + (xRadius + 50) * sin(testAngle));
	yP1 = int(yCtr + (yRadius + 50) * cos(testAngle));
	xP2 = int(xCtr + (xRadius - 50) * sin(testAngle));
	yP2 = int(yCtr + (yRadius - 50) * cos(testAngle));

	//Note: Here we skip plotting the SECONDS-MARK at each of the HOUR marks
	if ((patternCount + 1) % 5 != 0)
		XYscope.plotLine(xP1, yP1, xP2, yP2);
}

//Uncomment the following four (4) lines if you want add the Arduino-logo on the screen...
//int logoHt = 1000;
//int logoX = 2047 - logoHt * .85;
//int logoY = 2047 - logoHt;
//XYscope.plotArduinoLogo(logoX, logoY, logoHt);

//Draw the center hubs of the HOURS and MINITE hands...
XYscope.plotCircle(xCtr, yCtr, CenterRadius-5);			//Hour Hand Center Circle ('-5' just makes it look nicer!)
XYscope.plotCircle(xCtr, yCtr, Min_HubCenterRadius-5);	//Minute Hand Center Circle
XYscope.plotCircle(xCtr, yCtr, 10);						//Second-Hand Center Circle
//Post message on how to stop demo...
XYscope.printSetup(10,10,200,100);
XYscope.setFontSpacing(XYscope.prop);
XYscope.print((char*)"(Key Press=Stop)");

//###################### Draw Hour Hand (in a Test mode) #########################
Gbl_HR_ListPtr = XYscope.XYlistEnd;
for (float TestHour=0; TestHour<13; TestHour=TestHour+.1){
	if (Serial.available()) TestHour=13; //Terminate early if key pressed
	XYscope.XYlistEnd=Gbl_HR_ListPtr;
	DrawClockHourHand(TestHour);
	delay(10);
}
XYscope.XYlistEnd=Gbl_HR_ListPtr;
float TestHour=3.00;
DrawClockHourHand(TestHour);	// Position & paint final location of Hour Hand at 3:30

//###################### Draw Minute Hand (in a Test mode) #########################
Gbl_MIN_ListPtr = XYscope.XYlistEnd;
float TestMin;
TestHour=3.00;
for (TestMin=0; TestMin<60; TestMin=TestMin+.1){
	if (Serial.available()) TestMin=60; //Terminate early if key pressed
	XYscope.XYlistEnd=Gbl_HR_ListPtr;
	DrawClockHourHand(TestHour+TestMin/60);
	//XYscope.XYlistEnd=Gbl_MIN_ListPtr;
	Gbl_MIN_ListPtr=XYscope.XYlistEnd;
	DrawClockMinHand(TestMin);
	delay(10);
}
TestHour=2.00;
TestMin=23;

XYscope.XYlistEnd=Gbl_HR_ListPtr;
DrawClockHourHand(TestHour+TestMin/60);
DrawClockMinHand(TestMin);	// Position & paint final location of Minute Hand at :27 past the hour

//###################### Draw Second Hand (in a Test mode) #########################
Gbl_SEC_ListPtr = XYscope.XYlistEnd;
//Second Hand
float TestSec;
for (TestSec=0; TestSec<60; TestSec++){
	if (Serial.available()) TestSec=60; //Terminate early if key pressed
	XYscope.XYlistEnd = Gbl_SEC_ListPtr;
	DrawClockSecHand(TestSec);
	delay(10);
}

TestMin++;
XYscope.XYlistEnd=Gbl_HR_ListPtr;
DrawClockHourHand(TestHour+TestMin/60);
DrawClockMinHand(TestMin);
Gbl_SEC_ListPtr =XYscope.XYlistEnd;
DrawClockSecHand(TestSec);
delay(1000);	//Slight pause before demo continues

for (int TestLoop=0;TestLoop<2;TestLoop++){

	for (TestSec=0; TestSec<60; TestSec++){
		if (Serial.available()){	//Terminate early if key pressed
			TestSec=60;
			TestLoop=5000;
		}

		if (Serial.available()) TestSec=60; //Terminate early if key pressed
		XYscope.XYlistEnd = Gbl_SEC_ListPtr;
		DrawClockSecHand(TestSec);

		//Draw Digital Readout of Time as well...
		XYscope.printSetup(1200,2300,450,100);
		XYscope.print(int(TestHour));
		if (TestMin<10)XYscope.print((char *) ":0"); else XYscope.print((char *) ":");
		XYscope.print(int(TestMin));
		if (TestSec<10)XYscope.print((char *) ":0"); else XYscope.print((char *) ":");
		XYscope.print(int(TestSec));
		delay(1000);
	}
	TestSec=0;
	TestMin++;
	if(TestMin>59){
		TestMin=0;
		TestHour++;
		if (TestHour>12) TestHour=1;
	}
	XYscope.XYlistEnd=Gbl_HR_ListPtr;
	DrawClockHourHand(TestHour+TestMin/60);
	DrawClockMinHand(TestMin);
	Gbl_SEC_ListPtr =XYscope.XYlistEnd;
	DrawClockSecHand(TestSec);
	//Draw Digital Readout of Time as Well
	XYscope.printSetup(1200,2300,450,100);
	XYscope.print(int(TestHour));
	if (TestMin<10)XYscope.print((char *) ":0"); else XYscope.print((char *) ":");
	XYscope.print(int(TestMin));
	if (TestSec<10)XYscope.print((char *) ":0"); else XYscope.print((char *) ":");
	XYscope.print(int(TestSec));

}


//Redraw Second Hand...
DrawClockSecHand(0);	//Position & paint final location of Second Hand at 53 second position

if (Serial.available()){	//If stopped by Oper Key Press, dump the serial Buffer
	int d=0;
	while (d>=0) {			//clean out the buffer (Retrieved data is NOT USED)
		d=Serial.read();	//...flush buffer, keep reading until buffer is empty.
	} 						// (Serial.read returns -1 when no data is available)
}

XYscope.plotPoint(4095, 4095);
XYscope.plotEnd();
XYscope.autoSetRefreshTime();

Serial.print(" DONE with CLOCK SIM.\n  Num of Points Plotted: ");
Serial.print(numTestPoints);
Serial.print("  XYlistEnd=");
Serial.println(XYscope.XYlistEnd);
Serial.println(" (Press a key to continue)");
XYscope.plotEnd();
EndOfSetup_Ptr = XYscope.XYlistEnd - 1;
XYscope.autoSetRefreshTime();
//flush serial buffer
if (Serial.available()){
	char d = Serial.read();
	Serial.println();
}

}

void ClockHandsSetup(int X_Center, int Y_Center, int Center_Radius,int MinCenterRadius, int Hour_Length, int Min_Length, int Sec_Length){
//	Routine to set global variables used to drive the clock hands display
//
//	Calling parameters (All coordinates, radius, and length parameters are in "pixels")
//		X_Center, Y-Center - These are the coordinates of the center of the clock
//		Center_Radius - Defines the radius of the center of the Hour hand
//		MinCenterRadius - Defines the radius for center of the Minute hand
//		Hour_Length, Min_Length - Defines the length of the Hour/Minute hands
//
//	Returns:
//		NOTHING
//
//	20171106 Ver 0.0	E.Andrews	First cut

Gbl_X_Center=X_Center;
Gbl_Y_Center=Y_Center;
Gbl_Center_Radius=Center_Radius;
Gbl_MinHubCenterRadius=MinCenterRadius;
Gbl_Hour_HandLength=Hour_Length;
Gbl_Min_HandLength=Min_Length;
Gbl_Sec_HandLength=Sec_Length;

}
void DrawClockMinHand(float CurrentMinutes){
//	CLOCK routine that plots a minute-hand
//
//	Passed Parameters:
//		float Minutes	This is the current minutes value, 0<= Minutes <= 59
//						If this value is out of range, 0 will be the minutes value used
//
//	This routine uses the following global parameters:
//		float Gbl_X_Center, Gbl_Y_Center	- This is the XY center of the clock face.
//		float Gbl_Center_Radius			- Radius of the central clock face 'circle'
//		float Gbl_Min_HandLength			- This is the length of the clock arm
//		int XYscope.ListEnd					- Standard XY_List array pointer
//
//	Returns: NOTHING
//
//	20171106 Ver 0.0	E.Andrews	First cut
//
int X0, Y0, X1, Y1;
float mins;
double TwoPi=atan(1)*8;

//Figure out the Theta, the ANGLE (in radians) of the hand based on the passed parameter.FYI: 0=12 o'clock, Pi=6 o'clock, etc...
mins=CurrentMinutes;
if (mins<0 or mins>59) mins=0;			//Bound the incoming value
double theta = TwoPi * mins/60.;		//This is the angle of the Minute hand
//theta = const_2pi / 60. * seconds;	//This is the angle of the Second Hand
//theta = const_2pi / 12. * hours;		//This is the angle of the Hour Hand

//Calculate the Coordinates for the center point of the END of the hand
//Gbl_Hour_End_X_Center = Gbl_X_Center + Gbl_Hour_HandLength * sin(theta);	//=+(Xc0)+Hand_Len*SIN(Theta)
//Gbl_Hour_End_Y_Center = Gbl_Y_Center + Gbl_Hour_HandLength * cos(theta);	//=+(Yc0)+Hand_Len*COS(Theta)
Gbl_Min_End_X_Center = Gbl_X_Center + Gbl_Min_HandLength * sin(theta);	//=+(Xc0)+Hand_Len*SIN(Theta)
Gbl_Min_End_Y_Center = Gbl_Y_Center + Gbl_Min_HandLength * cos(theta);	//=+(Yc0)+Hand_Len*COS(Theta)



//Calculate the Coordinates for LINE#1 of arm and draw this line	(min and hour hand only)
X0= int(Gbl_X_Center - Gbl_MinHubCenterRadius*cos(theta));					//+=Xc0-Radius_1*COS(Theta)
Y0= int(Gbl_Y_Center + Gbl_MinHubCenterRadius*sin(theta));					//=+Yc0-Radius_1*SIN(Theta)
X1=	int(Gbl_Min_End_X_Center);			//=+(Xc1_)-Radius_2*COS(Theta)
Y1=	int(Gbl_Min_End_Y_Center);			//=Yc1_+Radius_2*SIN(Theta)
XYscope.plotLine(X0,Y0,X1,Y1);

//Calculate the Coordinates for LINE#2 of arm and draw this line	(min and hour hand only)
X0= int(Gbl_X_Center + Gbl_MinHubCenterRadius*cos(theta));					//=+Xc0+Radius_1*COS(Theta)
Y0= int(Gbl_Y_Center - Gbl_MinHubCenterRadius*sin(theta));					//=+Yc0-Radius_1*SIN(Theta)
X1=	int(Gbl_Min_End_X_Center);			//=+Xc1_+Radius_2*COS(Theta)
Y1=	int(Gbl_Min_End_Y_Center);			//=+Yc1_-Radius_2*SIN(Theta)
XYscope.plotLine(X1,Y1,X0,Y0);	//Reverse order of vector for best plot quality

}
void DrawClockHourHand(float CurrentHour){
//	CLOCK routine that plots the Hour-hand
//
//	Passed Parameters:
//		float Hours		This is the current Hours value, 0<= Hour <= 12
//						If this value is out of range, 12 will be the Hours value used
//						Note: An Hours value such as 3.5 will put hour hand at 3:30 position.
//
//	This routine uses the following global parameters:
//		float Gbl_X_Center, Gbl_Y_Center	- This is the XY center of the clock face.
//		float Gbl_Center_Radius			- Radius of the central clock face 'circle'
//		float Gbl_Hour_HandLength			- This is the length of the clock arm
//		float Gbl_Hour_EndRadius			- Radius of the circle plotted at the 'end' of the clock arm
//		int XYscope.ListEnd					- Standard XY_List array pointer
//
//	Returns: NOTING
//
//	20171106 Ver 0.0	E.Andrews	First cut
//
int X0, Y0, X1, Y1;
float Hours;
double TwoPi=atan(1)*8;

//Figure out the Theta, the ANGLE (in radians) of the hand based on the passed parameter.FYI: 0=12 o'clock, Pi=6 o'clock, etc...
Hours=CurrentHour;
if (Hours<0 or Hours>12) Hours=12;			//Bound the incoming value
//double theta = TwoPi * mins/60.;			//This is the angle of the Minute hand
//double theta = TwoPi * seconds / 60.;		//This is the angle of the Second Hand
double theta = TwoPi * Hours/ 12.;			//This is the angle of the Hour Hand

//Calculate the Coordinates for the center point of the END of the hand
Gbl_Hour_End_X_Center = Gbl_X_Center + Gbl_Hour_HandLength * sin(theta);	//=+(Xc0)+Hand_Len*SIN(Theta)
Gbl_Hour_End_Y_Center = Gbl_Y_Center + Gbl_Hour_HandLength * cos(theta);	//=+(Yc0)+Hand_Len*COS(Theta)
//Gbl_Min_End_X_Center = Gbl_X_Center + Gbl_Min_HandLength * sin(theta);	//=+(Xc0)+Hand_Len*SIN(Theta)
//Gbl_Min_End_Y_Center = Gbl_Y_Center + Gbl_Min_HandLength * cos(theta);	//=+(Yc0)+Hand_Len*COS(Theta)



//Calculate the Coordinates for LINE#1 of arm and draw this line	(min and hour hand only)
X0= int(Gbl_X_Center - Gbl_Center_Radius*cos(theta));					//+=Xc0-Radius_1*COS(Theta)
Y0= int(Gbl_Y_Center + Gbl_Center_Radius*sin(theta));					//=+Yc0-Radius_1*SIN(Theta)
X1=	int(Gbl_Hour_End_X_Center);			//=+(Xc1_)-Radius_2*COS(Theta)
Y1=	int(Gbl_Hour_End_Y_Center);			//=Yc1_+Radius_2*SIN(Theta)
XYscope.plotLine(X0,Y0,X1,Y1);


//Calculate the Coordinates for LINE#2 of arm and draw this line	(min and hour hand only)
X0= int(Gbl_X_Center + Gbl_Center_Radius*cos(theta));					//=+Xc0+Radius_1*COS(Theta)
Y0= int(Gbl_Y_Center - Gbl_Center_Radius*sin(theta));					//=+Yc0-Radius_1*SIN(Theta)
X1=	int(Gbl_Hour_End_X_Center);			//=+Xc1_+Radius_2*COS(Theta)
Y1=	int(Gbl_Hour_End_Y_Center);			//=+Yc1_-Radius_2*SIN(Theta)
XYscope.plotLine(X1,Y1,X0,Y0);	//Reverse order of vector for best plot quality

}
void DrawClockSecHand (int Secs){
//	Clock Routine that plots the SECONDS-hand
//
//	Passed Parameters:
//		int Secs		This is the current Secs value, 0<= Secs <= 59
//						If this value is out of range, 0 will be used
//
//	This routine uses the following global parameters:
//		float Gbl_X_Center, Gbl_Y_Center	- This is the XY center of the clock face.
//		float Gbl_Center_Radius			- Radius of the central clock face 'circle'
//		float Gbl_Secs_HandLength			- This is the length of the clock arm
//		int XYscope.ListEnd					- Standard XY_List array pointer
//
//	Returns: NOTING
//
//	20171106 Ver 0.0	E.Andrews	First cut
//
double TwoPi=atan(1)8;
float angle= (TwoPiSecs) / (60);

int X_end=Gbl_X_Center+Gbl_Sec_HandLength*sin(angle);
int Y_end=Gbl_Y_Center+Gbl_Sec_HandLength*cos(angle);
//Plot a simple vector (line) as the second hand
XYscope.plotLine(Gbl_X_Center, Gbl_Y_Center, X_end, Y_end);

}
//================ END SIMULATED CLOCK ROUTINES ========================//

void SimCoordinateSys(void) {
//	Routine to plot a sample graphic to show the AGI (X,Y) Coordinate system
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170811 Ver 0.0	E.Andrews	First cut
//
int xC, yC;
const boolean UndrLined = true;

XYscope.plotClear();
XYscope.plotStart();
XYscope.setGraphicsIntensity(10);
XYscope.plotRectangle(0, 0, 4095, 4095);

XYscope.setGraphicsIntensity(150);
int textSize = 250, textBright = 150;

xC = 0;
yC = 0;
PlotCrossHair(xC, yC);
XYscope.printSetup(xC + 100, yC + 40, textSize, textBright);
XYscope.print((char *)"(");
XYscope.print(xC);
XYscope.print((char *)",");
XYscope.print(yC);
XYscope.print((char *)")");

xC = 0;
yC = 4095;
PlotCrossHair(xC, yC);
XYscope.printSetup(xC + 100, yC - 50 - textSize, textSize, textBright);
XYscope.print((char *)"(");
XYscope.print(xC);
XYscope.print((char *)",");
XYscope.print(yC);
XYscope.print((char *)")");

xC = 4095;
yC = 4095;
PlotCrossHair(xC, yC);
XYscope.printSetup(xC - 50 - (11 * (textSize * .65)), yC - 50 - textSize,
		textSize, textBright);
XYscope.print((char *)"(");
XYscope.print(xC);
XYscope.print((char *)",");
XYscope.print(yC);
XYscope.print((char *)")");

xC = 4095;
yC = 0;
PlotCrossHair(xC, yC);
XYscope.printSetup(xC - 50 - (8 * (textSize * .65)), yC + 50, textSize,
		textBright);
XYscope.print((char *)"(");
XYscope.print(xC);
XYscope.print((char *)",");
XYscope.print(yC);
XYscope.print((char *)")");

xC = 2047;
yC = 2047;
PlotCrossHair(xC, yC);
XYscope.printSetup(xC + 50, yC - 50 - textSize, textSize, textBright);
XYscope.print((char *)" (");
XYscope.print(xC);
XYscope.print((char *)",");
XYscope.print(yC);
XYscope.print((char *)")");

xC = 1023;
yC = 1023;
PlotCrossHair(xC, yC);
XYscope.printSetup(xC + 50, yC - 50 - textSize, textSize, textBright);
XYscope.print((char *)" (");
XYscope.print(xC);
XYscope.print((char *)",");
XYscope.print(yC);
XYscope.print((char *)")");

xC = 1650;
yC = 2047;

textSize = 400;
textBright = 150;
XYscope.printSetup(xC + 50, yC + 50 + 700, textSize, textBright);
XYscope.print((char *)"AGI", UndrLined);
xC = 100;
yC = 2047;
textSize = 350;
XYscope.printSetup(xC + 50, yC + 50 + textSize, textSize, textBright);
if (XYscope.getFontSpacing() != XYscope.mono)
	XYscope.printSetup(xC + 50 + 500, yC + 50 + textSize, textSize,
			textBright);
XYscope.print((char *)"Coordinate System", UndrLined);

//PlotCrossHair(2047,2047);

XYscope.plotEnd();
XYscope.autoSetRefreshTime();
ShowMemory();
PrintStatsToConsole();

}

void PlotCrossHair(int Xcoord, int Ycoord) {
//	Routine to draw a cross hair symbol to screen.  Size is fixed by const definitions.
//            |
//          - * -
//            |
//	Calling parameters (All coordinate parameters are in "pixels")
//		X_Coord, Ycoord - Defines the XY-Center of the symbol
//
//	Returns:
//		NOTHING
//
//	20171022 Ver 0.0	E.Andrews	First cut

const int LineLeng = 100;
const int LineSpace = 50;
const int DotRepeatCnt = 10;
int x0, y0, x1, y1;
//Xcoord=Xcoord && 4095;	//Make sure coordinates are ON-SCREEN
//Ycoord=Ycoord && 4095;	//Make sure coordinates are ON-SCREEN

//Plot the target Point...Make it Bright by plotting multiple times
for (int i = 0; i < DotRepeatCnt; i++) {
	XYscope.plotPoint(Xcoord, Ycoord);
}

//Plot Left Horizontal Cross-hair line
x0 = Xcoord - LineSpace;
x1 = Xcoord - (LineSpace + LineLeng);
if (x1 < 0)
	x1 = 0;
y0 = Ycoord;
y1 = Ycoord;
if (x0 >= 0 && x1 <= 4095)
	XYscope.plotLine(x0, y0, x1, y1);

//Plot Right Horizontal Cross-hair line
x0 = Xcoord + LineSpace;
x1 = Xcoord + (LineSpace + LineLeng);
if (x1 > 4095)
	x1 = 4095;
if (x0 >= 0 && x1 <= 4095)
	XYscope.plotLine(x0, y0, x1, y1);

//Plot Top Vertical Cross-hair line
x0 = Xcoord;
x1 = Xcoord;
if (x1 < 0)
	x1 = 0;
y0 = Ycoord + LineSpace;
y1 = Ycoord + (LineSpace + LineLeng);
if (y1 > 4095)
	y1 = 4095;
if (y0 >= 0 && y1 <= 4095)
	XYscope.plotLine(x0, y0, x1, y1);

//Plot Bottom Vertical Cross-hair line
y0 = Ycoord - LineSpace;
y1 = Ycoord - (LineSpace + LineLeng);
if (y1 < 0)
	y1 = 0;
if (y0 >= 0 && y1 >= 0)
	XYscope.plotLine(x0, y0, x1, y1);

}

void SimGraph_0(void) {
//	Routine to plot a sample graphic chart display
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170811 Ver 0.0	E.Andrews	First cut
//
Serial.print("ERASING Data Table...");
XYscope.plotClear();
XYscope.plotStart();
XYscope.plotRectangle(500, 500, 4000, 3500);

for (int yLine = 1000; yLine < 3501; yLine = yLine + 500) {
	XYscope.printSetup(20, yLine - 100, 200);
	XYscope.print(yLine / 100);
	XYscope.plotLine(450, yLine, 4000, yLine);
}

for (int xLine = 1000; xLine < 4001; xLine = xLine + 500) {
	XYscope.printSetup(xLine - 700, 200, 200);
	XYscope.print(float(xLine) / 1000., 1);
	XYscope.plotLine(xLine, 450, xLine, 3500);
}
int yPoint = 2000;
for (int xPoint = 500; xPoint < 4001; xPoint = xPoint + 2) {
	yPoint = 2000 + 1200 * sin(float(xPoint) / 500.);
	XYscope.plotPoint(xPoint, yPoint);
}
XYscope.printSetup(100, 3800, 250);
XYscope.print((char *)"      Flux-Capacitance");
XYscope.printSetup(100, 3600, 250);
XYscope.print((char *)"       Vs Giga-Watts");
XYscope.plotEnd();
XYscope.autoSetRefreshTime();
ShowMemory();
PrintStatsToConsole();

}

void PeakToPeakTest_V() {
//	Routine to plot a Vertical edge-to-edge Freq Response Test pattern
//	   +--+  +--+  +--+  +--+
//     |  |  |  |  |  |  |  |
//   ..+  +--+  +--+  +--+  +...
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170811 Ver 0.0	E.Andrews	First cut
//
XYscope.plotStart();
//Dashed Line, Top and Bottom
for (int i = 0; i < 4095; i = i + 256) {
XYscope.plotLine(i, 4095, i + 127, 4095);//Dashed line at Top of Screen
XYscope.plotLine(i + 128, 0, i + 255, 0);//Dashed Line at Bottom of Screen
}
Serial.println(" DONE PeakToPeak_Vert Sq Wave ");
}
void PeakToPeakTest_H() {
//	Routine to plot Horizontal edge-to-edge Freq Response Test pattern
//	:
//  +----+
//       |
//	+----+
//	|
//  +----+
//       |
//	+----+
//	:
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170811 Ver 0.0	E.Andrews	First cut
//
XYscope.plotStart();
//Dashed Line, Left & Right
for (int i = 0; i < 4095; i = i + 256) {
XYscope.plotLine(0, i, 0, i + 127);	//Dashed line at Left Side of Screen
XYscope.plotLine(4095, i + 128, 4095, i + 255);	//Dashed Line at Right Side of Screen
}
Serial.println(" DONE PeakToPeak_Horiz Sq Wave ");
}

void PeakToPeakTest_D() {
//	Routine to plot just dots in the corners of the screen.
//	This pattern was used to vary and optimize the blanking timing
//	parameters.	
//	
//    *            *
//
//	
//	
//
//    *            *
//	
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170811 Ver 0.0	E.Andrews	First cut
//

XYscope.plotStart();
//Dots in lower left hand corner and upper right hand corner of display screen
//Used to measure frequency response of the DACs

XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotPoint(0, 0);
XYscope.plotPoint(4095, 4095);
XYscope.plotEnd();

Serial.println(" DONE PeakToPeak Corner_to_Corner Test ");

}
void PrintStatsToConsole(void) {
//	Routine to send memory usage status reports out to the
//	serial monitor port.  Use this to observe how various graphics
//	objects consume the graphics list RAM memory.  Routine also
//	also displays current clock speeds in use so as you change
//	them and observe performance differences, you can zero in on
//	what works best for your scope.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170811 Ver 0.0	E.Andrews	First cut
//
Serial.print("\n STATS..............\n MaxBuffSize: ");
Serial.print(XYscope.MaxBuffSize);
Serial.print("  Total Array Used: ");
Serial.print((XYscope.XYlistEnd - 1));
Serial.print(" (");
Serial.print((XYscope.XYlistEnd * 100) / XYscope.MaxBuffSize);
Serial.println(" %)");
Serial.print("     DMA Clock Freq: ");
Serial.print(XYscope.DmaClkFreq_Hz / 1000);
Serial.print(" Khz");
Serial.print(" (Period: ");
Serial.print(XYscope.DmaClkPeriod_us);
Serial.println(" us)");
Serial.print("   Point Clock Freq: ");
Serial.print(XYscope.DmaClkFreq_Hz / 2000);
Serial.print(" Khz");
Serial.print(" (Period: ");
Serial.print(XYscope.DmaClkPeriod_us * 2);
Serial.println(" us)");
Serial.print("       Refresh Freq: ");
Serial.print(float(1000000) / float(XYscope.ActiveRefreshPeriod_us),1);
Serial.print(" Hz (Period: ");
Serial.print(XYscope.ActiveRefreshPeriod_us/1000);
Serial.print(" ms)\n");
Serial.print("Graphics Int: ");
Serial.print(XYscope.getGraphicsIntensity(), DEC);
Serial.print(" %   Text Int: ");
Serial.print(XYscope.getTextIntensity(), DEC);
Serial.println(" %");
Serial.print("Font Spcng Mode = ");
if (XYscope.getFontSpacing() == 0)
Serial.print("PROP");
else
Serial.print("MONO");
Serial.print(", Second_Hand_Enab = ");
if (enabSecondHand)
Serial.print("YES,");
else
Serial.print("NO,");
Serial.print(" Scrn_Sav_Secs: ");
Serial.print(XYscope.getScreenSaveSecs());
Serial.println();
}
void Print_CRT_Scope_Menu() {
//	Routine to send a menu of all available options to
//	the serial monitor port.  This routine is continuously
//	updated as options are added or changed in XYscope.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170725 Ver 0.0	E.Andrews	First cut
//						(changes made continuously without version num updates)
//

Serial.print("========= ");
Serial.print(startMsg);
Serial.println(" =========");
Serial.println("  h     Show this HELP Screen");
Serial.println("  ?     Show current plotting STATS");
Serial.println("---- Hardware setup and diagnostics -----");
Serial.println("  7     Signal Scope Pattern for Gain & Center Adj.");
Serial.println("  C/c   Incr(C)/Decr(c) DMA Clock Freq by 50 Khz");
Serial.println("  F/f   Front-Porch blank count [Incr=F/Decr=f]");
Serial.println("  B/b   Back-Porch blank count [Incr=B/Decr=b]");
Serial.println("  2     Display Centering Pattern");
Serial.println("  V/H   Peak-to-Peak Vertical/Horiz Sq-Wv Test Pattern");
Serial.println("  d     Peak-to-Peak Dots_in_the_Corners Test Pattern");

Serial.println("---- Test plots for TEXT routines");
Serial.println("  m     Toggle Font mode Monospace<->Propotional");
Serial.println("  I/i   TEXT intensity [Incr=I)/Decr=i]");
Serial.println("  0/1   0=Print Random Nums, 1=Nums w/Underlines");
Serial.println("  s/S   plotChar Test, s=Test 1, S=Test 2");
Serial.println("  w     Wakeup from Screen-save timeout");

Serial.println("---- Test plots for GRAPHICS routines ----");
Serial.println("  +/-   GRAPHICS Intensity [Incr=+/Decr=-]");
Serial.println("  3     Display Random Rectangles, Circles, & Ellipses");
Serial.println("  4     Simulated Graph Plot");
Serial.println("  5     Display Random Ellipse");
Serial.println("  6     Display a fixed Ellipse");
Serial.println("  8     Demo Circle arc segments from 0 to 7");
Serial.println("  9     Demo Ellipse arc segments from 0 to 7");

Serial.println("---- Simulated Application Screens ----");
Serial.println("  l     Plot an animated Arduino Logo");
Serial.println("  D     Show AGI Coordinate System Plot");
Serial.println("  t     TIME - A Simulated Clock Display (Random Time)");
Serial.println("  *     Toggle 'SimClock' second-hand On-Off");
Serial.println("  p     Pong Simulation");

Serial.println("==========================================");

}

//=======================================================
// DIAGNOSTIC ROUTINES
//=======================================================
void WaitForAnyKey(String msg) {
// Routine outputs 'msg' to serial monitor port using Serial.print then halts execution and
// waits for Opr to hit any key.  Then it will return so execution can continue.
// Used as a diagnostic tool to provide a 'halt execution and wait' function for
// debugging use
//
//	Passed Parameters	
//		msg - 	This string is output to the Serial Monitor port, then
//				execution halts until the operator touches any key.
//
//	Returns: NOTHING
//
//	20170708 Ver 0.0	E.Andrews	First cut
//

boolean wait;
Serial.print(msg);
Serial.println(F(" <-WAITING! (...Hit any Key to CONTINUE...)"));
wait = true;
while (wait) {
	if (Serial.available()) {
		int d=0;
		while (d>=0) {
			d=Serial.read();	//clean out the buffer (Retrieved data is NOT USED)
		}						//...keep reading until buffer is empty; note, Serial.read will return as -1 when no data is available
		wait = false;
		Serial.println(F("_KP_"));
		delay(100);
	}

}

}
void ShowMemory() {
// Routine outputs an estimate of the total RAM in active use to the serial monitor port.
// Used during development to observe RAM consumption.
//
//	Passed Parameters	NONE
//
//	Returns: NOTHING
//
//	20170725 Ver 0.0	E.Andrews	First cut
//

char *heapend = sbrk(0);
register char * stack_ptr asm ("sp");
struct mallinfo mi = mallinfo();
printf("\n DUE Dynamic ram used: %d\n", mi.uordblks);
printf("  DUE Program static ram used %d\n", &_end - ramstart);
printf("  DUE Stack ram used %d\n\n", ramend - stack_ptr);
printf("     ... My guess at free mem: %d\n",
		stack_ptr - heapend + mi.fordblks);

}

XYscope.cpp

#include "XYscope.h"

#include <DueTimer.h>

uint8_t TimerBlinkState = 0;

//#include "XYscopeVectorFont.cpp"

XYscope::XYscope() {
//Initialize variables used in these routines

XYlistEnd = 0;
pinMode(crtBlankingPin, OUTPUT);

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Vector Graphics Package
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//

float XYscope::getLibRev(void){
//	Routine to get XYscope Library Revision Level using Semantic scheme (Major_Rev.Minor_Rev.Patch_Rev0
//		Note: PatchRev is NOT USED; library revision is returned as a single floating point value.
//
//	Calling parameters: NONE
//
//	Returns:
//		LibRevision as a FLOATING POINT variable. WHOLE portion = MAJOR REV, FRACTIONAL portion = MINOR REV.
//
//	20171012 Ver 0.0	E.Andrews	First cut --- Initialize Lib Rev to ver 0.0

// Here's where we define Major and Minor Rev Levels; Reset these values whenver a lib rev is completed.
_libMajorRev=1.;			//Bump MAJOR value wherever incompatible API changes are made
_libMinorRev=.0;			//Bump MINOR value whenever functionality is added (in a backwards compatible fashion occurs)
_libPatchRev=0;			//NOT USED (LibPatchRev not used in this application)
_libRev = _libMajorRev + _libMinorRev +.005;	//Bias up by .005 to improve float to text conversion
return _libRev;		//Combine and return the composite value.

}

void XYscope::setGraphicsIntensity(short GraphBright) {
//	Routine to set graphics "intensity" (aka: brightness) for all graphics operations
//
//	Calling parameters:
//
//	GraphBright	This variable sets brightness of the graphics figure (in percent)
//				While valid range is 0-255, Useful values are 25-200%.
//
//				Note 1: Brighter (larger) value will plot brighter as more "dots per inch"
//				will be plotted.  This will "consume" more space in XY_list array.
//
//				Note 2: Depending upon size & focus of CRT, gaps between contiguous points of a line,
//				circle, ellipse, etc. may be become visible for values less than 50%.
//
//				At startup, GraphBright is initialized to 100.
//	Returns:
//				Nothing.
//
//	20170811 Ver 0.0	E.Andrews	First cut

long InputMin, InputMax, OutputMin, OutputMax;
//Use linear mapping functions for brightness conversion
//using two breakpoints...One for 0-100%, and the other for 100-255%;

const int BreakPoint = 100;

if (GraphBright <= 255 && GraphBright >= 0) {
	if (GraphBright >= BreakPoint) {//Use this mapping function parameters for Inputs from 100-255%

		InputMin = 100;		//Define output when input=100%
		OutputMin = 10;

		InputMax = 255;		//Define output when input=255%
		OutputMax = 1;
	} else {//Use this mapping function parameters for Inputs from 0 to 100%

		InputMin = 25;		//Define output when input=25%
		OutputMin = 40;

		InputMax = 100;		//Define output when input=100%
		OutputMax = 10;
	}
	//Save updated GraphBright to class variable
	_graphBrightness = GraphBright;
	//Calculate new graphDensity based on 'GraphBright' value
	_graphDensity = (GraphBright - InputMin) * (OutputMax - OutputMin)
			/ (InputMax - InputMin) + OutputMin;

}//If user passes us a NEGATIVE or OVER_RANGE value, just go to the graphics density setting

}

short XYscope::getGraphicsIntensity() {
//	Routine to set graphics "intensity" (aka: brightness) for all graphics operations
//
//	Calling parameters: NONE
//
//	Returns:
//	GraphBright	This variable represents the current brightness of the graphics figure (in percent)
//				While valid range is 0-255, Useful values are 25-200%.
//
//				At startup, GraphBright is initialized to 100.
//
//	20170811 Ver 0.0	E.Andrews	First cut

return _graphBrightness;

}

void XYscope::setTextIntensity(short TextBright) {
//	Routine to set graphics "intensity" (aka: brightness) for all graphics operations
//
//	Calling parameters:
//
//	GraphBright	This variable sets brightness of the text (in percent)
//				While valid range is 0-255, Useful values are 25-200%.
//
//				Note 1: Brighter (larger) value will plot brighter as more "dots per inch"
//				will be plotted.  This will "consume" more space in XY_list array.
//
//				Note 2: Depending upon size & focus of CRT, gaps between contiguous points of
//				character may be become visible for values less than 50%.
//
//				At startup, TextBright is initialized to 100.
//	Returns:
//				Nothing.
//
//	20170811 Ver 0.0	E.Andrews	First cut

long InputMin, InputMax, OutputMin, OutputMax;
//Use linear mapping functions for brightness conversion
//using two breakpoints...One for 0-100%, and the other for 100-255%;

const int BreakPoint = 100;

if (TextBright < 255 && TextBright >= 0) {//Only update brightness if passed parameter is IN RANGE
	if (TextBright >= BreakPoint) {	//Use this mapping function parameters for Inputs from 100-255%

		InputMin = 100;		//Define output when input=100%
		OutputMin = 10;

		InputMax = 255;		//Define output when input=255%
		OutputMax = 1;
	} else {//Use this mapping function parameters for Inputs from 0 to 100%

		InputMin = 25;		//Define output when input=25%
		OutputMin = 40;

		InputMax = 100;		//Define output when input=100%
		OutputMax = 10;
	}
	//Save updated TextBright to class variable
	_textBrightness = TextBright;
	//Calculate new density based on 'GraphBright' value
	_textDensity = (TextBright - InputMin) * (OutputMax - OutputMin)
			/ (InputMax - InputMin) + OutputMin;
}

}

short XYscope::getTextIntensity() {
//	Routine to set graphics "intensity" (aka: brightness) for all graphics operations
//
//	Calling parameters: NONE
//
//	Returns:
//	TextBright	This variable represents the current brightness of the graphics figure (in percent)
//				While valid range is 0-255, Useful values are 25-200%.
//
//				At startup, GraphBright is initialized to 100.
//
//	20170811 Ver 0.0	E.Andrews	First cut

return _textBrightness;

}

void XYscope::plotClear(void) {
//	This CLEARS OUT the current plot buffer
//
//	Returns: NOTHING (Sets global variable, XYlistEnd = 0)
//
//	20170705 Ver 2.0	E.Andrews	Simplified call by eliminating all passed parameters

//	Just reset the array pointers and display goes blank
XYlistEnd = 0;
//Now initialize the first entry into the XYlist array using the plotStart() function
plotStart();
plotEnd();
//AutoSetRefreshTime();
return;

}

void XYscope::plotEnd() {
//	Routine Repeats the contents of the last entry just pass the end-of-buffer pointer.
//	This compensates for END OF LIST blanking uncertainty & ensures the very last point in the buffer
//	will be unblanked and seen on the.	Call this routine anytime you think the display list is complete.
//
//	Calling parameters: NONE
//	Returns: NOTHING
//
//	20170705 Ver 0.1	E.Andrews	First cut of simplified routine (no passed parameters)

if (XYlistEnd > 0) {

	XY_List[XYlistEnd].X = XY_List[XYlistEnd - 1].X;
	XY_List[XYlistEnd].Y = XY_List[XYlistEnd - 1].X;
} else {
	XY_List[XYlistEnd].X = X_flag;
	XY_List[XYlistEnd].Y = Y_flag;
}

//AutoSetRefreshTime();
return;

}

void XYscope::plotStart() {
//	Routine Loads the following three(X,Y) points into the start of the XYlist() buffer.
//		(0,0), (4095,0),(0,0) - This creates a full-scale pulse on the X-channel, occuring during BLANKING period,
//		that is used by the AGE hardware to properly synchronize the point clock to the DMA clock.
//	Calling parameters: NONE
//
//	Returns: NOTHING
//
//	Global Variables: Resets pointers and Loads points into XY_List, updates XYlistEnd pointer
//
//	20170320 Ver 0.0	E.Andrews	First cut
//  20170526 ver 0.1	E.Andrews	Fine tune number of start up pixels..
//	20170617 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//
//
plotErr = 0;

XYlistEnd = 0;
//  We need to load a full scale pulse into the XYlist array for sync-up pouposes
XY_List[XYlistEnd].X = 0 | X_flag;				//Load X Value
XY_List[XYlistEnd].Y = 0 | Y_flag;
XYlistEnd++;	//Load Y value and increment pointer

//Write the SYNC PULSE into the front of the buffer...

XY_List[XYlistEnd].X = 0xfff | X_flag;//Load full scale value into X to create a pulse
XY_List[XYlistEnd].Y = 0 | Y_flag;
XYlistEnd++;	//Load Y value

XY_List[XYlistEnd].X = 0xfff | X_flag;//Load full scale value into X to create a pulse
XY_List[XYlistEnd].Y = 0 | Y_flag;
XYlistEnd++;	//Load Y value and increment pointer

XY_List[XYlistEnd].X = 0 | X_flag;				//Load X Value
XY_List[XYlistEnd].Y = 0 | Y_flag;
XYlistEnd++;	//Load Y value and increment pointer

//  Now add  a few more dummy points to give us time to come out of blanking...

XY_List[XYlistEnd].X = 0 | X_flag;			    //Load X Value
XY_List[XYlistEnd].Y = 0 | Y_flag;
XYlistEnd++;	//Load Y value
//AutoSetRefreshTime();
return;

}

void XYscope::plotPoint(int x0, int y0) {
//	Routine for POINT plotting
//	Calling parameters:
//
//		x0, y0	Coordinate of point to be plotted.
//				Valid Range:  0<= x0 <= 4095, 0<= y0 <= 4095
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170320 Ver 0.0	E.Andrews	First cut
//	20170427 Ver 0.1	E.Andrews	Add plotErr & near end-of-buffer limit logic and check
//	20170627 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//
if (_screenOnTime_ms != 0)
_crtOffTOD_ms = millis() + _screenOnTime_ms;//Update ScreenOff time of day (ms)
if (XYlistEnd > MaxBuffSize - 3) {
plotErr = 0;//Set plotErr and skip writing point into buffer if we are about to hit the end-of-buffer.
} else {

	XY_List[XYlistEnd].X = (x0 & 0xfff) | X_flag;//Load X Value into EVEN array term
	XY_List[XYlistEnd].Y = (y0 & 0xfff) | Y_flag;//Load Y value into ODD array term

	XYlistEnd++;							//Increment List Pointer  value 

}
return;

}

void XYscope::plotLine(int x0, int y0, int x1, int y1) {
//	BRESSHAM Algorithm for LINE drawing
//		Algorithm implementation/starting code base from: http://members.chello.at/~easyfilter/bresenham.html
//	Calling parameters:
//
//		x0, y0	Coordinate of starting point
//		x1, y1	Coordinate of ending point
//
//		  		Density is a COMMON variable that the using sets with setDensity() routine.
//				Higher values of Density increases the distance between ajacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//				Valid numbers are 0 to 100.  Note: depending upon size & focus of CRT, values more ~50 shows
//				cause lines of circles and vectors to begin to appear as dotted lines.
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170321 Ver 0.1	E.Andrews	First cut
//	20170617 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//
plotErr = 0;
int lastPointX, lastPointY;
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2, e2;
int SkipCount = 0;
for (;;) {
if (SkipCount <= 0)	//|| (x0 == x1 && y0 == y1) )	//should we skip actualling putting point to the screen?
{
plotPoint(x0, y0);
lastPointX = x0;		//Save and hold the last point plotted
lastPointY = y0;
SkipCount = _graphDensity;
} else {
SkipCount--;//The point is to be skipped so we don't need to actually send the point to the screen buffer
//Just decrement Skip Point Counter till it gets to Zero, then plot the point
}

	if (x0 == x1 && y0 == y1) {
		//Force a plot at the endpoint to 'finish the line' if the end point was not previously plotted
		if (lastPointX != x1 && lastPointY != y1)
			plotPoint(x1, y1);
		break;
	}
	e2 = err;
	if (e2 > -dx) {
		err -= dy;
		x0 += sx;
	}
	if (e2 < dy) {
		err += dx;
		y0 += sy;
	}
}

return;

}

void XYscope::plotRectangle(int x0, int y0, int x1, int y1) {
//	Plots a RECTANGLE LINE drawing
//	
//	Calling parameters:
//
//		x0, y0	Coordinate of starting point
//		x1, y1	Coordinate of ending point
//
//		  		Density is a COMMON variable that the using sets with setDensity() routine.
//				Higher values of Density increases the distance between ajacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//				Valid numbers are 0 to 100.  Note: depending upon size & focus of CRT, values more ~50 shows
//				cause lines of circles and vectors to begin to appear as dotted lines.
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170424 Ver 0.0	E.Andrews	First cut
//	20170617 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//

plotErr = 0;
plotLine(x0, y0, x1, y0);	//Top horizontal line
plotLine(x1, y0, x1, y1);	//Right verticle line
plotLine(x1, y1, x0, y1);	//Bottom horizontal line
plotLine(x0, y1, x0, y0);	//Left verticle line

return;

}

void XYscope::plotCircle(int xc, int yc, int r) {
//	Routine for CIRCLE plotting.  Basic algorithm implementation/starting code base from:
//	https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//
//	Calling parameters:
//		ix		Array pointer into aaAudio.dacBuffer16() where X & Y point will be put.
//
//		xc, yc	Coordinate of point center of circle to be plotted.
//				Valid Range:  0<= xc <= 4095, 0<= yc <= 4095
//
//		r		Radius of circle
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Caller should take care so that center - radius values do not exceed 4095.
//				Negative or coordinate values >4095 will be masked to 12 bits and will
//				fold-over the edges of the valid plot area (x,y) = (0 to 4095, 0 to 4095).
//
//				NOTE: Routine will set plotErr >0 & skip plotting if passed parameter errors are detected.
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170322 Ver 0.0	E.Andrews	First cut
//	20170427 Ver 1.0	E.Andrews	Rework to improve shape
//	20170617 Ver 2.0	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//	20170619 Ver 2.1	E.Andrews	Make this routine run in four passes to improve plot quality at high DMA clock speeds
//

//plotCircle(xc, yc, r,255);
int arcSegment = 255;

plotErr = 0;
int SkipCount = 0;
uint8_t pass = 0;

//==========Check to be sure that the figure is fully on-screen
if ((xc + r > 4095) || (xc - r < 0))
	plotErr = 1;
if ((yc + r > 4095) || (yc - r < 0))
	plotErr = 1;
//==========Skip drawing if figure is faulted
if (plotErr == 0) {

	int x, y, delta, error;
	for (uint8_t loopCnt = 0; loopCnt < 4; loopCnt++) {	//Although this is 4X slower, it orders the points in a way that will improve plot quality

		x = 0;
		y = r;	//radius
		delta = 2 - 2 * r;
		error = 0;
		int xHalfWayLimit = int(float(r) * .707106);//xHalfWayLimit = xr * sin(45Deg)
		int yHalfWayLimit = int(float(r) * .707106);//yHalfWayLimit = xr * cos(45Deg)

		while (y >= 0) {
			if (SkipCount == 0 || y <= 0) {	//Actually plot a point whenever (SkipCount=0) OR (we're at the last point to be plotted)
				int xp, yp;
				switch (loopCnt) {

				case 0: {
					xp = xc - x;
					yp = yc + y;	//Segment 0, 1
					//Serial.print("S01 (");Serial.print(xp);Serial.print(",");Serial.print(yp);Serial.println(")");						
					//plotPoint(xc - x, yc + y);		//Segment 0, 1
					if (arcSegment & arc0 && x >= xHalfWayLimit)
						plotPoint(xp, yp);		//Segment 0
					if (arcSegment & arc1 && x < xHalfWayLimit)
						plotPoint(xp, yp);		//Segment 1

					break;

				}
				case 1: {
					xp = xc + x;
					yp = yc + y;	//Segment 2, 3
					//Serial.print("S23 (");Serial.print(xp);Serial.print(",");Serial.print(yp);Serial.println(")");					
					//plotPoint(xc + x, yc + y);		//Segment 2, 3
					if (arcSegment & arc2 && x < xHalfWayLimit)
						plotPoint(xp, yp);		//Segment 2
					if (arcSegment & arc3 && y <= yHalfWayLimit)
						plotPoint(xp, yp);		//Segment 3
					break;
				}
				case 2: {
					xp = xc + x;
					yp = yc - y;
					//plotPoint(xc + x, yc - y);		//Segment 4, 5
					if (arcSegment & arc4 && x < xHalfWayLimit)
						plotPoint(xp, yp);		//Segment 4
					if (arcSegment & arc5 && y <= yHalfWayLimit)
						plotPoint(xp, yp);		//Segment 5
					break;
				}
				case 3: {
					xp = xc - x;
					yp = yc - y;
					//plotPoint(xc - x, yc - y);		//Segment 6. 7
					if (arcSegment & arc6 && x < xHalfWayLimit)
						plotPoint(xp, yp);		//Segment 6
					if (arcSegment & arc7 && y <= yHalfWayLimit)
						plotPoint(xp, yp);		//Segment 7
					break;
				}

				}
				//if (arcSegment & arc0 && x >= xHalfWayLimit) plotPoint(xc - x, yc + y);	//Segment 0
				//if (arcSegment & arc1 && x < xHalfWayLimit) plotPoint(xc - x, yc + y);	//Segment 1
				//if (arcSegment & arc2 && x < xHalfWayLimit) plotPoint(xc + x, yc + y);	//Segment 2
				//if (arcSegment & arc3 && y <= yHalfWayLimit ) plotPoint(xc + x, yc + y);	//Segment 3
				//if (arcSegment & arc4 && y < yHalfWayLimit) plotPoint(xc + x, yc - y);		//Segment 4
				//if (arcSegment & arc5 && x <= xHalfWayLimit) plotPoint(xc + x, yc - y);		//Segment 5
				//if (arcSegment & arc6 && x <= xHalfWayLimit) plotPoint(xc - x, yc - y);		//Segment 6
				//if (arcSegment & arc7 && x > xHalfWayLimit) plotPoint(xc - x, yc - y);		//Segment 7
				SkipCount = _graphDensity;
			} else
				SkipCount--;

			error = 2 * (delta + y) - 1;

			if ((delta < 0) && (error <= 0)) {
				++x;
				delta += 2 * x + 1;
				continue;
			}

			error = 2 * (delta - x) - 1;

			if (delta > 0 && error > 0) {
				--y;
				delta += 1 - 2 * y;
				continue;
			}
			++x;
			delta += 2 * (x - y);
			--y;
		}
	}
}
return;

}
/*

void XYscope::plotCircle(int xc, int yc, int r){
//	Routine for CIRCLE plotting.  Basic algorithm implementation/starting code base from:
//	https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//
//	Calling parameters:
//
//		xc, yc	Coordinate of point center of circle to be plotted.
//				Valid Range:  0<= xc <= 4095, 0<= yc <= 4095
//
//		r		Radius of circle
//
//		arcSegment	8-bit code corresponding to the arc segments that are to be drawn.
//					Bit = 1 means Draw arc segment, Bit = 0 means do NOT draw arc segment (Skip it!)
//

1  |	 2
\	  |   /
0  \  |  /  3
-------+-------
7  /  |  \   4
/   |   
6  |  5

//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Caller should take care so that center - radius values do not exceed 4095.
//				Negative or coordinate values >4095 will be masked to 12 bits and will
//				fold-over the edges of the valid plot area (x,y) = (0 to 4095, 0 to 4095).
//
//				NOTE: Routine will set plotErr >0 & skip plotting if passed parameter errors are detected.
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170322 Ver 0.0	E.Andrews	First cut
//	20170427 Ver 1.0	E.Andrews	Rework to improve shape
//	20170617 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//	20170714 Ver 0.3	E.Andrews	Overlay function when user wants a full circle
//
plotCircle(xc, yc, r,255);
}

*/

void XYscope::plotCircle(int xc, int yc, int r, uint8_t arcSegment) {
//	Routine for CIRCLE plotting.  Basic algorithm implementation/starting code base from:
//	https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//
//	Calling parameters:
//
//		xc, yc	Coordinate of point center of circle to be plotted.
//				Valid Range:  0<= xc <= 4095, 0<= yc <= 4095
//
//		r		Radius of circle
//
//		arcSegment	8-bit code corresponding to the arc segments that are to be drawn.
//					Bit = 1 means Draw arc segment, Bit = 0 means do NOT draw arc segment (Skip it!)
//
/*
1  |	 2
\	  |   /
0  \  |  /  3
-------+-------
7  /  |  \   4
/   |   
6  |  5
*/
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Caller should take care so that center - radius values do not exceed 4095.
//				Negative or coordinate values >4095 will be masked to 12 bits and will
//				fold-over the edges of the valid plot area (x,y) = (0 to 4095, 0 to 4095).
//
//				NOTE: Routine will set plotErr >0 & skip plotting if passed parameter errors are detected.
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170322 Ver 0.0	E.Andrews	First cut
//	20170427 Ver 1.0	E.Andrews	Rework to improve shape
//	20170617 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//	20170907 Ver 2.0 	E.Andrews	Abandon Bresenham algorithm for slower floating point approach
//									because new approach plots adjacent points and does not take advantage
//									of figure symetry.This Allows AGI to run at a higher DMA_CLK freq.
//
const float pi = atan(1) * 4;
const float arcAng0 = 0;
const float arcAng1 = pi * .25;		// .25 * pi
const float arcAng2 = pi * .5;		// .50 * pi
const float arcAng3 = pi * .75;		// .75 * pi
const float arcAng4 = pi;			//1.00 * pi
const float arcAng5 = pi * 1.25;	//1.25 * pi
const float arcAng6 = pi * 1.50;	//1.50 * pi
const float arcAng7 = pi * 1.75;	//1.75 * pi
const float FullCircle = 2 * pi;	//2.00 * pi
float circumf;
short xr, yr;
xr = yr = r;

//calculate circle circumference
circumf = FullCircle * r;

//Figure out how many points we will actually be plotting
//based on the current graphicsIntensity (_graphicsDensity) setting
float numOfPoints = circumf / _graphDensity;
//Calc the deltaAng between points
float deltaAng = FullCircle / (numOfPoints);

float angle;
short X, Y;

for (angle = 0; angle < FullCircle; angle = angle + deltaAng) {
	X = int(xc - cos(angle) * xr);
	Y = int(yc + sin(angle) * yr);

	//Only plot those segments that are enabled by passed "arcSegment" variable
	if (arcSegment & arc0 && angle <= arcAng1)
		plotPoint(X, Y);					//Segment 0
	if (arcSegment & arc1 && angle > arcAng1 && angle <= arcAng2)
		plotPoint(X, Y);	//Segment 1
	if (arcSegment & arc2 && angle > arcAng2 && angle <= arcAng3)
		plotPoint(X, Y);	//Segment 2
	if (arcSegment & arc3 && angle > arcAng3 && angle <= arcAng4)
		plotPoint(X, Y);	//Segment 3
	if (arcSegment & arc4 && angle > arcAng4 && angle <= arcAng5)
		plotPoint(X, Y);	//Segment 4
	if (arcSegment & arc5 && angle > arcAng5 && angle <= arcAng6)
		plotPoint(X, Y);	//Segment 5
	if (arcSegment & arc6 && angle > arcAng6 && angle <= arcAng7)
		plotPoint(X, Y);	//Segment 6
	if (arcSegment & arc7 && angle > arcAng7)
		plotPoint(X, Y);						//Segment 7
}

return;

}

void XYscope::plotCircleBres(int xc, int yc, int r, uint8_t arcSegment) {
/*
//	Routine for CIRCLE plotting.  Basic algorithm implementation/starting code base from:
//	https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//
//	Calling parameters:
//
//		xc, yc	Coordinate of point center of circle to be plotted.
//				Valid Range:  0<= xc <= 4095, 0<= yc <= 4095
//
//		r		Radius of circle
//
//		arcSegment	8-bit code corresponding to the arc segments that are to be drawn.
//					Bit = 1 means Draw arc segment, Bit = 0 means do NOT draw arc segment (Skip it!)
//
//
//					   1  |	 2
//					  \	  |   /
//					0  \  |  /  3
//				   -------+-------
//					7  /  |  \   4
//					  /   |   
//					   6  |  5
//
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Caller should take care so that center - radius values do not exceed 4095.
//				Negative or coordinate values >4095 will be masked to 12 bits and will
//				fold-over the edges of the valid plot area (x,y) = (0 to 4095, 0 to 4095).
//
//				NOTE: Routine will set plotErr >0 & skip plotting if passed parameter errors are detected.
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	20170322 Ver 0.0	E.Andrews	First cut
//	20170427 Ver 1.0	E.Andrews	Rework to improve shape
//	20170617 Ver 0.2	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//
*/
plotErr = 0;
int SkipCount = 0;
//==========Check to be sure that the figure is fully on-screen
if ((xc + r > 4095) || (xc - r < 0))
plotErr = 1;
if ((yc + r > 4095) || (yc - r < 0))
plotErr = 1;
//==========Skip drawing if figure is faulted
if (plotErr == 0) {

	int x = 0;
	int y = r;	//radius
	int delta = 2 - 2 * r;
	int error = 0;

	int xHalfWayLimit = int(float(r) * .707106);//xHalfWayLimit = xr * sin(45Deg)
	int yHalfWayLimit = int(float(r) * .707106);//yHalfWayLimit = xr * cos(45Deg)
	while (y >= 0) {
		//if (SkipCount<=0 || y <= 0){
		if (SkipCount <= 0 || y <= 0) {
			if (arcSegment & arc0 && x >= xHalfWayLimit)
				plotPoint(xc - x, yc + y);		//Segment 0
			if (arcSegment & arc1 && x < xHalfWayLimit)
				plotPoint(xc - x, yc + y);		//Segment 1
			if (arcSegment & arc2 && x < xHalfWayLimit)
				plotPoint(xc + x, yc + y);		//Segment 2 
			if (arcSegment & arc3 && y <= yHalfWayLimit)
				plotPoint(xc + x, yc + y);	//Segment 3
			if (arcSegment & arc4 && y < yHalfWayLimit)
				plotPoint(xc + x, yc - y);		//Segment 4
			if (arcSegment & arc5 && x <= xHalfWayLimit)
				plotPoint(xc + x, yc - y);		//Segment 5
			if (arcSegment & arc6 && x <= xHalfWayLimit)
				plotPoint(xc - x, yc - y);		//Segment 6
			if (arcSegment & arc7 && x > xHalfWayLimit)
				plotPoint(xc - x, yc - y);		//Segment 7

			SkipCount = _graphDensity;
		} else
			SkipCount--;

		error = 2 * (delta + y) - 1;
		if ((delta < 0) && (error <= 0)) {
			++x;
			delta += 2 * x + 1;
			continue;
		}
		error = 2 * (delta - x) - 1;

		if (delta > 0 && error > 0) {
			--y;
			delta += 1 - 2 * y;
			continue;
		}
		++x;
		delta += 2 * (x - y);
		--y;
	}
}
return;

}

void XYscope::plotEllipse(int xc, int yc, int xr, int yr) {
//	Routine for horizontal ELLIPSE plotting.
//		Algorithm implementation/starting code base from:
//			https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//			Also see: http://members.chello.at/~easyfilter/bresenham.html
//	Calling parameters:
//		xc, yc	Coordinate of point center of ellipse to be plotted.
//				Valid Range:  0<= x0 <= 4095, 0<= y0 <= 4095
//
//		xr, yr	X-Radius of ellipse, Y-radius of ellipse
//				Valid Range:  0<= xr <= 4095, 0<= yr <= 4095	//
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Negative coordinates or coordinate values >4095 will be masked to 12 bits and will
//				be folded-over the edges of the valid plot area which is (x,y) = (0 to 4095, 0 to 4095).	
//
//				NOTE: Routine will set plotErr to non-zero value and skip plotting if error in passed parameters are detected.
//
//	20170424	Ver 0.0	E.Andrews	First cut, irratic operation
//	20170427	Ver 1.0	E.Andrews	This version uses some DOUBLE variables to correct ocasional mishapen ellipses!)
//	20170617 	Ver 1.1	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer

//Adjust passed coordinates to algorithm needs 

plotEllipse(xc, yc, xr, yr, 255);//Call standard plotEllipse function with all segments=ON (255)
return;

}

void XYscope::plotEllipseBres(int xc, int yc, int xr, int yr,
uint8_t arcSegment)
//TODO REMOVE routine
{
//	Routine for horizontal ELLIPSE plotting.
//		Breseham Algorithm implementation/starting code base from:
//			https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//			Also see: http://members.chello.at/~easyfilter/bresenham.html
//	Calling parameters:
//		xc, yc	Coordinate of point center of ellipse to be plotted.
//				Valid Range:  0<= x0 <= 4095, 0<= y0 <= 4095
//
//		xr, yr	X-Radius of ellipse, Y-radius of ellipse
//				Valid Range:  0<= xr <= 4095, 0<= yr <= 4095
//
//		arcSegment	8-bit code corresponding to the arc segments that are to be drawn.
//					Bit = 1 means Draw arc segment, Bit = 0 means do NOT draw arc segment (Skip it!)
//					Any combination from 1 to 8 segments may be spec'd.
/*
1  |	 2
\	  |   /
0  \  |  /  3
-------+-------
7  /  |  \   4
/   |   
6  |  5
*/
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Negative coordinates or coordinate values >4095 will be masked to 12 bits and will
//				be folded-over the edges of the valid plot area which is (x,y) = (0 to 4095, 0 to 4095).
//
//				NOTE: Routine will set plotErr to non-zero value and skip plotting if error in passed parameters are detected.
//
//	20170424	Ver 0.0	E.Andrews	First cut, Works but had erratic operation
//	20170427	Ver 1.0	E.Andrews	This version uses some DOUBLE variables to correct occasional mis-shaoed ellipses!
//	20170617 	Ver 1.1	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
plotErr = 0;		//Initialize plotErr to FALSE (No errors)...
//Check to see if passed coordinates fully fit into the display range
int x0 = xc - xr;//x0,y0 = lower left hand corner of a rectangle bounding the totality of the Ellipse
int y0 = yc - yr;
int x1 = xc + xr;//x1,y1 = upper right hand corner of a rectangle bounding the totality of the Ellipse
int y1 = yc + yr;
short px, py;
//==========Check to be sure that the figure is fully on-screen; Set PlotErr flag if NO
if ((x0 > 4095) || (x0 < 0) || (x1 > 4095) || (x1 < 0))
plotErr = 1;
if ((y0 > 4095) || (y0 < 0) || (y1 > 4095) || (y1 < 0))
plotErr = 1;

//==========Skip drawing if passed parameters are faulted
if (plotErr == 0) {
	int SkipCount = 0;	//Initialize the point-skip counter...
	double width = 1 * xr;
	int height = 1 * yr;
	//  The following variables must be DOUBLE or ellipse shape can
	//	be plotted badly deformed due to value over-flows
	//  Note: On Arduino DUE, sizeof(double)=8 bytes
	double a2 = width * width;
	double b2 = height * height;
	double fa2 = 4 * a2, fb2 = 4 * b2;
	double x, y, sigma;
	//Calculate segment 'HalfWayLimits'
	int xHalfWayLimit = xr * .707106;	//xHalfWayLimit = xr * sin(45Deg)
	int yHalfWayLimit = yr * .707106;	//yHalfWayLimit = xr * cos(45Deg)
	/* first half */
	for (x = 0, y = height, sigma = 2 * b2 + a2 * (1 - 2 * height);
			b2 * x <= a2 * y; x++) {
		if (SkipCount <= 0) {//Only plot the point if the arcsegment flag bit=1, otherwise, skip the point

			if (arcSegment & arc0 && x > xHalfWayLimit) {
				//plotPoint(xc - x, yc + y);		//Segment 0
				px = xc - x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("0, 0, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc1 && x <= xHalfWayLimit) {
				//plotPoint(xc - x, yc + y);		//Segment 1
				px = xc - x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("0, 1, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc2 && x < xHalfWayLimit) {
				//plotPoint(xc + x, yc + y);		//Segment 2
				px = xc + x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("0, 2, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc3 && y <= yHalfWayLimit) {
				//plotPoint(xc + x, yc + y);		//Segment 3					px=xc+x; py=yc+y;
				px = xc + x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("0, 3, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc4 && y < yHalfWayLimit) {
				//plotPoint(xc + x, yc - y);		//Segment 4
				px = xc + x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("0, 4, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc5 && x <= xHalfWayLimit) {
				//plotPoint(xc + x, yc - y);		//Segment 5
				px = xc + x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("0, 5, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc6 && x < xHalfWayLimit) {
				//plotPoint(xc - x, yc - y);		//Segment 6
				px = xc - x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("0, 6, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc7 && x >= xHalfWayLimit) {
				//plotPoint(xc - x, yc - y);		//Segment 7
				px = xc - x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("0, 7, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			SkipCount = _graphDensity;
			;
		} else
			SkipCount--;
		if (sigma >= 0) {
			sigma += fa2 * (1 - y);
			y--;
		}
		sigma += b2 * ((4 * x) + 6);
	}

	/* second half */
	//SkipCount=0;
	//int X, Y;
	for (x = width, y = 0, sigma = 2 * a2 + b2 * (1 - 2 * width);
			a2 * y <= b2 * x; y++) {
		if (SkipCount <= 0) {

			if (arcSegment & arc0 && x > xHalfWayLimit) {
				//plotPoint(xc - x, yc + y);		//Segment 0
				px = xc - x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("1, 0, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc1 && x <= xHalfWayLimit) {
				//plotPoint(xc - x, yc + y);		//Segment 1
				px = xc - x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("1, 1, ");Serial.print(px); Serial.print(", "); Serial.println(py);
			}

			if (arcSegment & arc2 && x < xHalfWayLimit) {
				//plotPoint(xc + x, yc + y);		//Segment 2
				px = xc + x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("1, 2, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc3 && y <= yHalfWayLimit) {
				//plotPoint(xc + x, yc + y);		//Segment 3
				px = xc + x;
				py = yc + y;
				plotPoint(px, py);
				//Serial.print ("1, 3, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc4 && y < yHalfWayLimit) {
				//plotPoint(xc + x, yc - y);		//Segment 4
				px = xc + x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("1, 4, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc5 && x <= xHalfWayLimit) {
				//plotPoint(xc + x, yc - y);		//Segment 5
				px = xc + x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("1, 5, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc6 && x < xHalfWayLimit) {
				//plotPoint(xc - x, yc - y);		//Segment 6
				px = xc - x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("1, 6, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			if (arcSegment & arc7 && x >= xHalfWayLimit) {
				//plotPoint(xc - x, yc - y);		//Segment 7
				px = xc - x;
				py = yc - y;
				plotPoint(px, py);
				//Serial.print ("1, 7, ");Serial.print(px);Serial.print(", ");	Serial.println(py);
			}

			SkipCount = _graphDensity;
			;
		} else
			SkipCount--;

		if (sigma >= 0) {
			sigma += fb2 * (1 - x);
			x--;
		}
		sigma += a2 * ((4 * y) + 6);
	}
}
return;

}

void XYscope::plotEllipse(int xc, int yc, int xr, int yr, uint8_t arcSegment) {
//	Routine for non-rotated ELLIPSE plotting.
//		Algorithm implementation uses standard geometry (not speed optized)
//
//	Calling parameters:
//		xc, yc	Coordinate of point center of ellipse to be plotted.
//				Valid Range:  0<= x0 <= 4095, 0<= y0 <= 4095
//
//		xr, yr	X-Radius of ellipse, Y-radius of ellipse
//				Valid Range:  0<= xr <= 4095, 0<= yr <= 4095
//
//		arcSegment	8-bit code corresponding to the arc segments that are to be drawn.
//					Bit = 1 means Draw arc segment, Bit = 0 means do NOT draw arc segment (Skip it!)
//					Any combination from 1 to 8 segments may be spec'd.
/*
1  |	 2
\	  |   /
0  \  |  /  3
-------+-------
7  /  |  \   4
/   |   
6  |  5
*/
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Negative coordinates or coordinate values >4095 will be masked to 12 bits and will
//				be folded-over the edges of the valid plot area which is (x,y) = (0 to 4095, 0 to 4095).
//
//				NOTE: Routine will set plotErr to non-zero value and skip plotting if error in passed parameters are detected.
//
//	20170424	Ver 0.0	E.Andrews	First cut, Works but had erratic operation
//	20170427	Ver 1.0	E.Andrews	This version uses some DOUBLE variables to correct occasional mis-shaoed ellipses!
//	20170617 	Ver 1.1	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer
//	20170907	Ver 2.0 E.Andrews	Abandon Bresenham algorithm for slower floating point approach
//									because new approach plots adjacent points and does not take advantage
//									of figure symetry.This Allows AGI to run at a higher DMA_CLK freq.
const float pi = atan(1) * 4;
const float arcAng0 = 0;
const float arcAng1 = pi * .25;		// .25 * pi
const float arcAng2 = pi * .5;		// .50 * pi
const float arcAng3 = pi * .75;		// .75 * pi
const float arcAng4 = pi;			//1.00 * pi
const float arcAng5 = pi * 1.25;	//1.25 * pi
const float arcAng6 = pi * 1.50;	//1.50 * pi
const float arcAng7 = pi * 1.75;	//1.75 * pi
const float FullCircle = 2 * pi;	//2.00 * pi
float circumf;
//calculate ellipse circumference

circumf = FullCircle * sqrt((pow(xr, 2) + pow(yr, 2)) / 2.);
//Figure out how many points we will actually be plotting
//based on the current graphicsIntensity (_graphicsDensity) setting
float numOfPoints = circumf / _graphDensity;
//Calc the deltaAng between points
float deltaAng = FullCircle / (numOfPoints);

float angle;
short X, Y;

for (angle = 0; angle < FullCircle; angle = angle + deltaAng) {
	X = int(xc - cos(angle) * xr);
	Y = int(yc + sin(angle) * yr);

	//Only plot those segments that are enabled by passed "arcSegment" variable
	if (arcSegment & arc0 && angle <= arcAng1)
		plotPoint(X, Y);					//Segment 0
	if (arcSegment & arc1 && angle > arcAng1 && angle <= arcAng2)
		plotPoint(X, Y);	//Segment 1
	if (arcSegment & arc2 && angle > arcAng2 && angle <= arcAng3)
		plotPoint(X, Y);	//Segment 2
	if (arcSegment & arc3 && angle > arcAng3 && angle <= arcAng4)
		plotPoint(X, Y);	//Segment 3
	if (arcSegment & arc4 && angle > arcAng4 && angle <= arcAng5)
		plotPoint(X, Y);	//Segment 4
	if (arcSegment & arc5 && angle > arcAng5 && angle <= arcAng6)
		plotPoint(X, Y);	//Segment 5
	if (arcSegment & arc6 && angle > arcAng6 && angle <= arcAng7)
		plotPoint(X, Y);	//Segment 6
	if (arcSegment & arc7 && angle > arcAng7)
		plotPoint(X, Y);						//Segment 7
}

}
/*

void XYscope::plotEllipse_BAK(int xc, int yc, int xr, int yr,uint8_t arcSegment=255)
//TODO Rework this routine
{
//	Routine for horizontal ELLIPSE plotting.
//		Algorithm implementation/starting code base from:
//			https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm
//			Also see: http://members.chello.at/~easyfilter/bresenham.html
//	Calling parameters:
//		xc, yc	Coordinate of point center of ellipse to be plotted.
//				Valid Range:  0<= x0 <= 4095, 0<= y0 <= 4095
//
//		xr, yr	X-Radius of ellipse, Y-radius of ellipse
//				Valid Range:  0<= xr <= 4095, 0<= yr <= 4095
//	
//		arcSegment	8-bit code corresponding to the arc segments that are to be drawn.
//					Bit = 1 means Draw arc segment, Bit = 0 means do NOT draw arc segment (Skip it!)
//					Any combination from 1 to 8 segments may be spec'd.

//   \ 1 | 2 /
//    \  |  /
//   0 \ | / 3
//  -----+-------
//   7  /|\  4
//     / | 
//    /6 | 5
//
//
//	Returns: NOTHING
//
//	Global Variables: Loads points int XY_List, updates XYlistEnd pointer
//
//	CAUTIONS:	Caller should take care so that center + radius values do not exceed 4095.
//				Negative coordinates or coordinate values >4095 will be masked to 12 bits and will
//				be folded-over the edges of the valid plot area which is (x,y) = (0 to 4095, 0 to 4095).	
//
//				NOTE: Routine will set plotErr to non-zero value and skip plotting if error in passed parameters are detected.
//
//	20170424	Ver 0.0	E.Andrews	First cut, Works but had erratic operation
//	20170427	Ver 1.0	E.Andrews	This version uses some DOUBLE variables to correct occasional mis-shaoed ellipses!
//	20170617 	Ver 1.1	E.Andrews	Simplify Routine Call by eliminating need to pass the index pointer

plotErr=0;		//Initialize plotErr to FALSE (No errors)...
//Check to see if passed coordinates fully fit into the display range
int x0 = xc - xr;	//x0,y0 = lower left hand corner of a rectangle bounding the totality of the Ellipse
int y0 = yc - yr;
int x1 = xc + xr;	//x1,y1 = upper right hand corner of a rectangle bounding the totality of the Ellipse
int y1 = yc + yr;
//==========Check to be sure that the figure is fully on-screen; Set PlotErr flag if NO
if ((x0>4095 )||(x0<0)||(x1>4095 )||(x1<0)) plotErr=1;
if ((y0>4095 )||(y0<0)||(y1>4095 )||(y1<0)) plotErr=1;

//==========Skip drawing if passed parameters are faulted
if (plotErr==0){
int SkipCount = 0;	//Initialize the point-skip counter...
double width=1xr;
int height=1yr;		
//  The following variables must be DOUBLE or ellipse shape can
//	be plotted badly deformed due to value over-flows
//  Note: On Arduino DUE, sizeof(double)=8 bytes
double a2 = width * width;			
double b2 = height * height;
double fa2 = 4 * a2, fb2 = 4 * b2;
double x, y, sigma;
//Calculate segment 'HalfWayLimits'
int xHalfWayLimit=xr*.707106;	//xHalfWayLimit = xr * sin(45Deg)
int yHalfWayLimit=yr*.707106;	//yHalfWayLimit = xr * cos(45Deg)
first half
for (x = 0, y = height, sigma = 2b2+a2(1-2height); b2x <= a2*y; x++)
{
if(SkipCount<=0){	//Only plot the point if the arcsegment flag bit=1, otherwise, skip the point

if (arcSegment & arc0 && x >  xHalfWayLimit) plotPoint(xc - x, yc + y);		//Segment 0

if (arcSegment & arc1 && x <= xHalfWayLimit) plotPoint(xc - x, yc + y);		//Segment 1

if (arcSegment & arc2 && x < xHalfWayLimit)  plotPoint(xc + x, yc + y);		//Segment 2

if (arcSegment & arc3 && y <= yHalfWayLimit) plotPoint(xc + x, yc + y);		//Segment 3

if (arcSegment & arc4 && y <  yHalfWayLimit) plotPoint(xc + x, yc - y);		//Segment 4

if (arcSegment & arc5 && x <= xHalfWayLimit) plotPoint(xc + x, yc - y);		//Segment 5

if (arcSegment & arc6 && x <  xHalfWayLimit) plotPoint(xc - x, yc - y);		//Segment 6

if (arcSegment & arc7 && x >= xHalfWayLimit) plotPoint(xc - x, yc - y);		//Segment 7

SkipCount=_graphDensity;;
} else SkipCount--;
if (sigma >= 0)
{
sigma += fa2 * (1 - y);
y--;
}
sigma += b2 * ((4 * x) + 6);
}

second half
//SkipCount=0;
for (x = width, y = 0, sigma = 2a2+b2(1-2width); a2y <= b2*x; y++)
{
if(SkipCount<=0){

if (arcSegment & arc0 && x >  xHalfWayLimit) plotPoint(xc - x, yc + y);		//Segment 0

if (arcSegment & arc1 && x <= xHalfWayLimit) plotPoint(xc - x, yc + y);		//Segment 1

if (arcSegment & arc2 && x < xHalfWayLimit)  plotPoint(xc + x, yc + y);		//Segment 2

if (arcSegment & arc3 && y <= yHalfWayLimit) plotPoint(xc + x, yc + y);		//Segment 3

if (arcSegment & arc4 && y <  yHalfWayLimit) plotPoint(xc + x, yc - y);		//Segment 4

if (arcSegment & arc5 && x <= xHalfWayLimit) plotPoint(xc + x, yc - y);		//Segment 5

if (arcSegment & arc6 && x <  xHalfWayLimit) plotPoint(xc - x, yc - y);		//Segment 6

if (arcSegment & arc7 && x >= xHalfWayLimit) plotPoint(xc - x, yc - y);		//Segment 7

SkipCount=_graphDensity;;
} else SkipCount--;

if (sigma >= 0)
{
sigma += fb2 * (1 - x);
x--;
}
sigma += a2 * ((4 * y) + 6);
}
}	
return;
}

*/

void XYscope::plotArduinoLogo(int& charX, int& charY, int& charHt) {
//	Plots the horizontal, figure-8 Arduino LOGO to the screen,  Displays "ARDUINO DUE"
//	text below the figure-8 logo.
//
//	Calling parameters:
//
//		x0, y0	Coordinate of lower left hand corner of logo and as passed by REFERENCE and will be updated by
//				this routine; they will be incremented (and returned) pointing to the next character position to the right.
//				(x0,y0) values will	wrap to right most character position in the next (lower) row when end-of-line is reached.
//
//		CharHt	Logo_height in pixels, Range: 16<=CharHt<=4095
//				Note: Logo_width is 1.6 X Logo_height!
//
//-----COMMON VARIABLES----- (Not passed during procedure call)
//		 Density is a COMMON variable that is changed by calling the setDensity() routine.
//				Higher values of Density increases the distance between ajacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//				Valid numbers are 0 to 100.  Note: depending upon size & focus of CRT, values more ~50 shows
//				cause lines of circles and vectors to begin to appear as dotted lines.
//
//	Returns: charX & charY are updated.
//
//	201703719 Ver 0.0	E.Andrews	First cut
//

plotErr = 0;
//Make CharScale Factor
float Char_ScaleFactor = float(charHt) / 16;

//Plot the two logo characters, 13 spaces apart

int Tx = charX + 13, Ty = charY;
plotChar(128, charX, charY, charHt);

//Move charX to the right by 13*CharHt places...
charX = Tx + 13 * Char_ScaleFactor;	//Fixed, non-proportional Font...

charY = Ty;
plotChar(129, charX, charY, charHt);
Ty = Ty - charHt / 16;
Tx = Tx + charHt / 8;//Starting location for "Ardu.." text for PROPORTIONAL FONT
if (getFontSpacing() != mono)
	Tx = Tx + ((charHt / 8) * .75);	//Starting location for "Ardu.." text for PROPORTIONAL FONT
printSetup(Tx, Ty, charHt / 5);
print((char *)"ARDUINO DUE");

return;

}

const short prop = 0, monoTight = 8, mono = 10, monoNorm = 10, monoWide = 12;//Define FontSpacing  Constants

void XYscope::setFontSpacing(short spacingMode) {
//Set Font Proportional or mono spaced mode...
//
//	Calling parameters:
//
//		spacingMode  Valid range 0-15.  Normal values are: prop=0, monoTight=8, mono=10, monoNorm=10, monoWide=12;
//					representing Proportional Spacing, tight Mono Spacing, Normal Mono Spacing, Wide Mono Spacing
//
//-----COMMON VARIABLES-----
//		fontSpacing
//
//	Returns: Nothing.
//
//	20170906 Ver 0.0	E.Andrews	First cut
//
if (spacingMode >= 0 && spacingMode < 16)
_fontSpacing = spacingMode;
//TODO Serial.print ("SpacingMode=");Serial.print(spacingMode); Serial.print(", _fontSpacing=");Serial.println(_fontSpacing);
return;
}

short XYscope::getFontSpacing() {
//Retrieve current font spacing value.
//
//	Calling parameters:  NONE
//
//-----COMMON VARIABLES-----
//		fontSpacing
//
//	Returns: Current fontSpacing Value.  Normal values are: prop=0, monoTight=8, mono=10, monoNorm=10, monoWide=12;
//			 representing Proportional Spacing, tight Mono Spacing, Normal Mono Spacing, Wide Mono Spacing
//
//	20170906 Ver 0.0	E.Andrews	First cut
//

return _fontSpacing;

}
void XYscope::plotChar(char c, int& charX, int& charY, int& charHt) {
//	Writes a single CHARACTER to screen

//	Calling parameters:
//
//		c		Ascii Charactor to be plotted, Range: 0<= digit <= 255
//				Note: Invalid or undefined characters will be plotted as "~"
//		
//		x0, y0	Coordinate of lower left hand cornder of character cell and as passed by REFERENCE and will be updated by
//				this routine; they will be incremented (and returned) pointing to the next character position to the right.
//				(x0,y0) values will	wrap to right most character position in the next (lower) row when end-of-line is reached.
//
//		CharHt	Character height in pixels, Range: 16<=CharHt<=4095
//
//-----COMMON VARIABLES----- (Not passed during procedure call)
//		 _textDensity is a COMMON variable that sets the plot brightness during plotChar operaitons.
//				Higher values of Density increases the distance between ajacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//
//	Returns: x0 & y0 are updated.
//
//	20170609 Ver 0.0	E.Andrews	First cut
//	20170714 Ver 1.0	E.Andrews	Simplified calling sequence
//	20170714 Ver 1.1	E.Andrews	Updated to use _textDensity value durin plotChar operations
//	20170905 Ver 2.0	E.Andrews	Added Proportional Font spacing into ROM & Ascii2Font arrays
//
boolean printDump = false; //Diagnostics flag used during code development (set to false to prevent debug message output)
plotErr = 0;

//Make CharScale Factor
float Char_ScaleFactor = float(charHt) / 16;

int EndOfPlot = 0;

int PlotCount = 10;

//Get pointer into the fontROM
int charRomIndex = int((Ascii2Font[int(c)] & 0x1ff)) - 1;//limit return to low order 9 bits
//Get Width of character (if it is present)
int charWidth;
charWidth = _fontSpacing;
//TODO Serial.print(" plotChar -");
if (_fontSpacing == 0) {
	charWidth = int((Ascii2Font[int(c)]) >> 9);	//extract char width from b10-b13 (if available)

	charWidth = charWidth & 0x0f;				//mask value to 0-15 range.
	//TODO Serial.print(c); Serial.print(", width = ");Serial.print(charWidth);
}

//TODO Serial.print(", Final_width = ");Serial.println(charWidth);

//For Character Plotting, temporarily set  _density value to _textDensity
short tempDensity = _graphDensity;
_graphDensity = _textDensity;

while (EndOfPlot == 0) {
	PlotCount--;
	charRomIndex++;
	//Initialize Retrieve OpCode
	uint8_t OC = 0, EOC = 0, P1a = 0, P1b = 0, P2a = 0, P2b = 0, P3 = 0;
	EOC=EOC;
	//Unpack OPCODE, EndOfChar Flag, P1,P2,P3
	OC = DigitFont[charRomIndex].Opcode;	//Retrieve OPCODE from FontROM
	if ((OC & 0x80) != 0)
		EndOfPlot++;//Test to see if End_of_Charaacter (EOC) is set; end processing if so
	OC = OC & 0x0f;						//Strip down to just lower 4 bits
	P1b = DigitFont[charRomIndex].P1;//Retrieve P1 from FontROM and unpack 
	P1a = P1b >> 4;
	P1b = P1b & 0x0f;
	P2b = DigitFont[charRomIndex].P2;//Retrieve P2 from FontROM and unpack 
	P2a = P2b >> 4;
	P2b = P2b & 0x0f;
	P3 = DigitFont[charRomIndex].P3;			//Retrieve P3 from FontROM

	//Process each graphics element code
	uint8_t const NOP = 0x0, PNT = 0x1, LIN = 0x2, REC = 0x3, CIR = 0x4,
			ELP = 0x5;//NOP = No Operaton, PNT = plot a single POINT, LIN = Plot a LINE
	//REC = Plot a Rectangle, CIR = Plot a Circle or a partial circular segment 
	//ELP = Plot an Ellipse or a partial ellipical segment.
	//translate to plotting location and scale ROM data by CharHeight value
	int x0 = P1a * Char_ScaleFactor + charX;//Start X for lines, points, rectangles...Center point for Circles & Ellipses												
	int y0 = P1b * Char_ScaleFactor + charY;//Start Y for lines, points, rectangles...Center point for Circles & Ellipses
	int x1 = P2a * Char_ScaleFactor + charX;//End X for lines and Rectangles												
	int y1 = P2b * Char_ScaleFactor + charY;//End Y for Lines and Rectangles
	int xCP = x0;					//X Center Point for Circle & Ellipse
	int yCP = y0;					//Y Center Point for Circle & Ellipse
	int r1 = P2a * Char_ScaleFactor;//Radius for Circle, RadiusX for Ellipse
	int r2 = P2b * Char_ScaleFactor;				//RadiusY for Ellipse
	uint8_t SegmentFlag = P3;		//Segment flag for Circles and Ellipse

	if (printDump) {
		//lookup char in ROM and start processing

		Serial.println("|----------plotChar Data Dump -------------|");
		Serial.print("charIndex = ");
		Serial.print(charRomIndex);
		Serial.print("  (charX,charY)= ");
		Serial.print(charX);
		Serial.print(",");
		Serial.print(charY);
		Serial.print("   Char_ScaleFactor = ");
		Serial.println(Char_ScaleFactor, 2);
		Serial.print("  OpCode,P1,P2,P3 = ");
		Serial.print(OC, HEX);
		Serial.print(", ");
		Serial.print(DigitFont[charRomIndex].P1, HEX);
		Serial.print(", ");
		Serial.print(DigitFont[charRomIndex].P2, HEX);
		Serial.print(", ");
		Serial.print(DigitFont[charRomIndex].P3, HEX);
		Serial.print("   .... P1a,P1b,P2a,P2b,P3 = ");
		Serial.print(P1a);
		Serial.print(", ");
		Serial.print(P1b);
		Serial.print(", ");
		Serial.print(P2a);
		Serial.print(", ");
		Serial.print(P2b);
		Serial.print(", ");
		Serial.print(P3, HEX);
		Serial.println();
		Serial.print("   (x0,y0) = ");
		Serial.print(x0);
		Serial.print(",");
		Serial.print(y0);
		Serial.print("   (x1,y1) = ");
		Serial.print(x1);
		Serial.print(",");
		Serial.print(y1);
		Serial.print("   (xCP,yCP) = ");
		Serial.print(xCP);
		Serial.print(",");
		Serial.print(yCP);
		Serial.print("   (r1,r2) = ");
		Serial.print(r1);
		Serial.print(",");
		Serial.print(r2);
		Serial.print("   SegmentFlag = ");
		Serial.print(SegmentFlag, HEX);

	}


	switch (OC) {
	case NOP:	//Do nothing
		if (printDump)
			Serial.print("    OpCode= NOP");
		break;
	case PNT:	//Plot a point 		P1=(x0,y0), P2 Not Used, P3 Not Used
		if (printDump)
			Serial.print("    OpCode= PNT");
		plotPoint(x0, y0);
		break;
	case LIN:	//plot a line		P1=(x0,y0), P2=(x1,y1), P3 Not Used
		if (printDump)
			Serial.print("    OpCode= LIN");
		plotLine(x0, y0, x1, y1);
		break;
	case REC:	//plot a rectangle	P1=(x0,y0), P2=(x1,y1), P3 Not Used
		if (printDump)
			Serial.print("    OpCode= REC");
		plotRectangle(x0, y0, x1, y1);
		break;
	case CIR://plot a circle		P1=(xCenterPoint,yCenterPoint), P2=(radiusX,not used), P3=Segment Flags (0-7)
		if (printDump)
			Serial.print("    OpCode= CIR");
		plotCircle(xCP, yCP, r1, SegmentFlag);
		break;
	case ELP://plot an ellipse	P1=(xCenterPoint,yCenterPoint), P2=(radiusX,radiusY), P3=Segment Flags (0-7)
		if (printDump)
			Serial.print("    OpCode= ELP");
		plotEllipse(xCP, yCP, r1, r2, SegmentFlag);
		break;
	default:	//Do Nothing
		break;
	}

	if ((OC & 0x80) != 0)
		EndOfPlot++;	//Does this instruction have the EndOfChar flag set?
	if (PlotCount == 10)
		EndOfPlot++;//Backup check to prevent more than MaxCount of graphic primatives to be processed (prevents run-ons...)
	//if (EndOfPlot!=0) Serial.println (" <<-END OF CHARACTER"); else Serial.println("");

}
//Done with Character Plotting, reset  _graphDensity value to teh temp value...
_graphDensity = tempDensity;

//Move charX to the right by one character size...
charX = charX + charWidth * Char_ScaleFactor;//Move to the right one place...
if (charX + charHt > 4095) {//Perform NEW LINE function if we will spill over...
	charX = 0;
	charY = charY - 15 * Char_ScaleFactor;
}

return;

}

void XYscope::plotCharUL(char c, int& charX, int& charY, int& charHt) {
//	Writes a single CHARACTER to screen with UNDERLINE
//
//	Calling Paramerters:
//
//		c		Ascii Charactor to be plotted, Range: 0<= digit <= 255
//				Note: Invalid or undefined characters will be plotted as "~"
//				Character will be printed with UNDERLINE beneath it!
//
//		x0, y0	Coordinate of lower left hand corner of character cell and as passed by REFERENCE and will be updated by
//				this routine; they will be incremented (and returned) pointing to the next character position to the right.
//				(x0,y0) values will	wrap to right most character position in the next (lower) row when end-of-line is reached.
//
//		CharHt	Character height in pixels, Range: 16<=CharHt<=4095
//
//-----COMMON VARIABLES----- (Not passed during procedure call)
//		 TextIntensity is a COMMON variable that is changed by calling the setTextIntensity() routine.
//				Higher values of Density increases the distance between adjacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//				Valid numbers are 0 to 100.  Note: depending upon size & focus of CRT, values more ~50 shows
//				cause lines of circles and vectors to begin to appear as dotted lines.
//
//	Returns: x0 & y0 are updated.
//
//	20170718 Ver 0.0	E.Andrews	First cut
//	20170905 Ver 2.0	E.Andrews	Reordered things so Proportional Font spacing will work for UL characcters
//
int charX_Temp = charX;	//Remember the original passed Coordinates
int charY_Temp = charY;
int c_Temp = c;
c = '_';
plotChar(c, charX_Temp, charY_Temp, charHt);	//Now print the UNDERLINE

plotChar(c_Temp, charX, charY, charHt);			//Print the base character

return;

}

void XYscope::printSetup(short textX, short textY) {
//	Sets X and Y location for subsequent calls to XYscope.print(...)
//
//	Calling parameters:
//	
//		x0, y0	Coordinate of lower left hand corner of character cell.  Range: 0 to 4095.
//
//-----COMMON VARIABLES----- (Not passed during procedure call)
//		 Density is a COMMON variable that is changed by calling the setDensity() routine.
//				Higher values of Density increases the distance between ajacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//				Valid numbers are 0 to 100.  Note: depending upon size & focus of CRT, values more ~50 shows
//				cause lines of circles and vectors to begin to appear as dotted lines.
//	Returns:  NOTHING
//
//	201703610 Ver 0.0	E.Andrews	First cut
//
charX = textX;
charY = textY;
}

void XYscope::printSetup(short textX, short textY, short textSize = -1) {
//	Sets X and Y location for subsequent calls to XYscope.print(...)
//
//	Calling parameters:
//	
//		x0, y0	Coordinate of lower left hand corner of character cell.  Range: 0 to 4095.
//
//		textSize	Character height in pixels, Range: 16<=CharHt<=4095
//
//-----COMMON VARIABLES----- (Not passed during procedure call)
//		 Density is a COMMON variable that is changed by calling the setDensity() routine.
//				Higher values of Density increases the distance between ajacent plotted points of graphics figures.
//				Smaller values of Density reduces the distand between adjacent plotted points of graphics figures.
//				Valid numbers are 0 to 100.  Note: depending upon size & focus of CRT, values more ~50 shows
//				cause lines of circles and vectors to begin to appear as dotted lines.
//	Returns:  NOTHING
//
//	201703610 Ver 0.0	E.Andrews	First cut
//
charX = textX;
charY = textY;
if (textSize > 0)
charSize = textSize;
}

void XYscope::printSetup(short textX, short textY, short textSize = -1,
short textBright = -1) {
//	Sets X and Y location for subsequint calls to XYscope.print(...)
//
//	Calling parameters:
//	
//		x0, y0	Coordinate of lower left hand cornder of character cell.  Range: 0 to 4095.
//
//		textSize	Character height in pixels, Range: 16<=CharHt<=4095
//
//		textBright	Sets text brightness (%). Range: 1 to approx 255, Larger=BRIGHTER.
//				Values less than 25% will be less bright and or lower text quality.
//
//-----OTHER NOTES
//	Use int GetTextIntensity() to read current text setting.
//	SetTextIntensity(value) is an alternate way to set text brightness value
//	Returns:  NOTHING
//
//	201703610 Ver 0.0	E.Andrews	First cut
//
charX = textX;
charY = textY;
if (textSize > 0)
charSize = textSize;
if (textBright > 0)
setTextIntensity(textBright);
}

void XYscope::print(char* text) {
print(text, bool(false));
return;
}
void XYscope::print(char* text, bool UL_Flag = false) {
//	Print text sring to screen at current x-y locations.
//
//	Calling parameters:
//	
//		text	String of text to be printed to screen
//
//		UL_Flag	Boolean, true=UNDERLINE text, False=NO-UNDERLINE
//
//  Other Notes
//		Use PrintSetup(...) to set XY locations, textSize, and textBrightness
//
//	Returns:  NOTHING
//
//	201703610 Ver 0.0	E.Andrews	First cut
//	
int textPtr = 0;
while (text[textPtr] != 0) {
if (UL_Flag)
plotCharUL(text[textPtr], charX, charY, charSize);
else
plotChar(text[textPtr], charX, charY, charSize);
textPtr++;
}

}
void XYscope::printUnderline(int nPlaces) {
//	Print underline character to screen at current x-y locations.
//
//	Calling parameters:
//
//		nPlaces	Integer, value=Number of Underline places to write
//
//  Other Notes
//		Use PrintSetup(...) to set XY locations, textSize, and textBrightness
//
//	Returns:  NOTHING
//
//	201703610 Ver 0.0	E.Andrews	First cut
//	201703718 Ver 1.0	E.Andrews	Update to work with UNDERLINE flag
//
for (int n=nPlaces; n > 0; n--)
;
{
plotChar('_', charX, charY, charSize);
}
return;
}
void XYscope::print(int number) {
//	Print integer number to screen at current x-y locations.
//
//	Calling parameters:
//
//		number	Integer, value to be printed to screen
//
//	Returns:  NOTHING
//
//  Other Notes
//		Use PrintSetup(...) to set XY locations, textSize, and textBrightness
//
//	201703610 Ver 0.0	E.Andrews	First cut
//	201703718 Ver 1.0	E.Andrews	Update to work with UNDERLINE flag
//

print(number, bool(false));
return;

}
void XYscope::print(int number, bool UL_Flag = false) {
//	Print integer number to screen at current x-y locations.
//
//	Calling parameters:
//	
//		number	Integer, value to be printed to screen
//
//		UL_Flag	Boolean, true=UNDERLINE text, False=NO-UNDERLINE
//
//	Returns:  NOTHING
//
//  Other Notes
//		Use PrintSetup(...) to set XY locations, textSize, and textBrightness
//
//	201703610 Ver 0.0	E.Andrews	First cut
//	201703718 Ver 1.0	E.Andrews	Add UNDERLINE capability
//

char charsToPrint[30] = { 0 };
int digitCount = 0;

if (number < 0) {
	//Serial.print("-");
	if (UL_Flag)
		plotCharUL('-', charX, charY, charSize);
	else
		plotChar('-', charX, charY, charSize);
	number = abs(number);		//Convert NEG number to POSITIVE
}
//Disect value, extract individual digits into array and count digits extracted
if (number == 0) {
	charsToPrint[0] = '0';
	digitCount = 0;
} else {
	while (number > 0 && digitCount < 30) {
		//Serial.print("  Extracted["); Serial.print(digitCount); Serial.print("]:"); Serial.print(number%10);
		//Extract least significant digit and store it into array as an ASCII character
		charsToPrint[digitCount] = '0' + number % 10;
		number = number / 10;
		digitCount++;
	}
	digitCount--;
}

//Serial.println();

//Now print stored Ascii digits in proper order!
for (int i = digitCount; i >= 0; i--) {
	//Serial.print( i);Serial.print(":");Serial.print(charsToPrint[i]);Serial.print("   ");
	//Print each char digit to the screen!
	if (UL_Flag)
		plotCharUL(charsToPrint[i], charX, charY, charSize);
	else
		plotChar(charsToPrint[i], charX, charY, charSize);

}
//Serial.println();

}

void XYscope::print(float number) {
//	Print floating point number to screen at current x-y locations.
//
//	Calling parameters:
//	
//		number	Floating point value to be printed to screen, defaults to show two digits to the right of the DP displayed.
//
//	Returns:  NOTHING
//
//  Other Notes
//		Use PrintSetup(...) to set XY location, textSize, and textBrightness
//
//	201703610 Ver 0.0	E.Andrews	First cut
//

print(float(number), 2, bool(false));//Default: 2 places to the right of the DP.

}

void XYscope::print(float number, int placesToPrint = 2) {
//	Print floating point number to screen at current x-y locations.
//
//	Calling parameters:
//	
//		number			Float, value to be printed to screen, defaults to show two digits to the right of the DP displayed.
//
//		placesToPrint	Integer, value defines number ot digits to the right of the dec point that should be plotted.
//
//	Returns:  NOTHING
//
//  Other Notes
//		Use PrintSetup(...) to set XY location, textSize, and textBrightness
//
//	201703610 Ver 0.0	E.Andrews	First cut
//

print(float(number), placesToPrint, bool(false));

}

void XYscope::print(float number, int placesToPrint = 2, bool UL_Flag = false) {
//	Print floating point number to screen at current x-y locations.
//
//	Calling parameters:
//
//		number			Float, value to be printed to screen, defaults to show two digits to the right of the DP displayed.
//
//		placesToPrint	Integer, value defines number ot digits to the right of the dec point that should be plotted.
//
//		UL_Flag=false	Boolean, TRUE=underline digits, FALSE= do not underline digits
//
//	Returns:  NOTHING
//
//  Other Notes
//		Use PrintSetup(...) to set XY locations, textSize, and textBrightness
//
//	201703610 Ver 0.0	E.Andrews	First cut
//

//check and bound placesToPrint to a reasonable number
if (placesToPrint < 0 || placesToPrint > 10)
	placesToPrint = 2;	//Reset placesToPrint to reasonable number if it's out of bounds!

if (number < 0) {
	//Serial.print("-");
	//Plot a NEGATIVE sign for negative numbers
	if (UL_Flag)
		plotCharUL('-', charX, charY, charSize);
	else
		plotChar('-', charX, charY, charSize);
}

number = abs(number);
int digitCount = 0;

// Figure out how many digits we will be printing for the Integer Portion of the number...
//intNumber=int(number);	//Capture an integer version of the floating point number

//Serial.println("  Figuring out how many digits to print...");
while ((number / (pow(10, digitCount))) > 9.9999999999) {
	//Serial.print(digitCount);Serial.print("=");Serial.print(pow(10,digitCount)); Serial.print( " : "); Serial.print((number/pow(10,digitCount))); Serial.print("_");
	digitCount++;
}
//Serial.print("  Here's the num of digits I think I must print for the Integer part: ");Serial.println(digitCount);
//Now print just the integer part of the number...

while (digitCount >= 0) {
	number = abs(number);	//disect and print it as a positive number...
	int digitToPrint = number / pow(10, digitCount);
	char charToPrint = '0' + digitToPrint;
	//plotChar(charToPrint,charX,charY,charSize);;	//Convert each digit to a single ASCII character and print it!
	if (UL_Flag)
		plotCharUL(charToPrint, charX, charY, charSize);
	else
		plotChar(charToPrint, charX, charY, charSize);//Convert digit to a single ASCII character and print it!
	//Serial.print(digitToPrint); Serial.print("_");
	//Serial.print("[");
	//Serial.print(charToPrint);Serial.Print("]  ");

	number = number - digitToPrint * pow(10, digitCount);
	digitCount--;
}
// Insert DP character Here!!
//plotCircle(charX-int ix, int xc, int yc, int r)
//plotPoint();
if (UL_Flag)
	plotCharUL('.', charX, charY, charSize);
else
	plotChar('.', charX, charY, charSize);
number = number * pow(10, placesToPrint);
digitCount = placesToPrint - 1;

while (digitCount >= 0) {
	number = abs(number);	//disect and print it as a positive number...
	int digitToPrint = int(number / pow(10, digitCount));
	//int digitToPrint=digitToPrintNoRound;
	//int digitToPrintRoundUp = int((number+.5) / pow(10, digitCount));
	//if (digitCount==0) digitToPrint = digitToPrintRoundUp;
	char charToPrint = '0' + digitToPrint;
	if (UL_Flag) plotCharUL(charToPrint, charX, charY, charSize);
	else plotChar(charToPrint, charX, charY, charSize);//Convert digit to a single ASCII character and print it!
	//Serial.print(digitToPrint); Serial.print("_");
	//Serial.print("[");
	//Serial.print(charToPrint);Serial.Print("]  ");
	
	//Now shift by power of 10
	number = number - digitToPrint * pow(10, digitCount);
	digitCount--;
}
//Serial.println();

}

void XYscope::setDmaClockRate(uint32_t New_XfrRate_hz) {
//	Routine to setup Timer Counter 0 which is used to clock DMA transformers.
//	(This is just a CALLER FREINDLIER version of txSetup)
//
//	Begin automatically calls this routine.  User only needs to call this
//	this routine if he/she wants to change clock rate during runtime.
//
//	Calling parameters:
//	
//	New_XfrRateHZ	This is the intended DMA Transfer Rate in Hertz.
//				Note that Point_Clk_Freq = XfrRateHz/2.
//
//	CAUTIONS:	Usual XfrRateHz values should be in 300,000 to 800,000 range.
//
//				Lower values make the screen refresh take longer and therefore
//				reduces the total number of points that can be displayed before
//				CRT flicker becomes visually apparant.
//
//				Higher values demand more of the XY display/oscilloscope
//				hardware but do allow more points to be plotted before refresh
//				flicker is a apparent.
//
//	Returns:	Nothing.
//	Other Notes:
//		This routine calculates and set the front and back porch of the blanking signals
//		based on the clock rate specified when it is called.
//
//	20170405 Ver 0.0	E.Andrews	First cut
//
//This routine sets up TimerCounter0
//TC0 is used to drive DAC0 & dAC1

tcSetup(New_XfrRate_hz);
DmaClkPeriod_us = (float(1 / float(New_XfrRate_hz)) * 1000000.);
//Calculate new value and Update the 'FRONT-PORCH' blankCount
//serial.print("\n   DmaClkPeriod_us=");Serial.print(DmaClkPeriod_us);Serial.print("  blankCount=").Serial.println(blankCount);
frontPorchBlankCount = int(DmaClkPeriod_us * 186.23 - 52.1 + .5);
backPorchBlankCount = int(DmaClkPeriod_us * 79. - 36 + .5);
Serial.print("\n   DmaClkPeriod_us=");
Serial.print(DmaClkPeriod_us);
Serial.print("  frontPorchBlankCount=");
Serial.print(frontPorchBlankCount);
Serial.print(", backPorchBlankCount=");
Serial.println(backPorchBlankCount);

}

void XYscope::tcSetup(uint32_t New_XfrRateHz) {
//	Routine to setup Timer Counter 0.  TC0 is used to clock DMA transformers.
//
//	User does NOT usually directly call this routine; XYscope.Begin automatically
//	does Counter timer setup.
//
//	Calling parameters:
//	
//	XfrRateHZ	User specifies the desired intended DMA Transfer Rate in Hertz.
//				Note that Point_Clk_Freq = XfrRateHz/2.
//
//				Typically, XfrRateHz should be in the 300,000-800,000 range.
//				User may need to experiment with this value to see what works best
//				for the'scope'being used as a display screen.
//
//				Smaller values make the screen refresh take longer and therefore
//				reduces the total number of points that can be displayed before
//				CRT flicker becomes visually apparant.
//
//				Larger values demand more of the XY display/oscilloscope
//				hardware but do allow more points to be plotted before refresh
//				flicker is a apparent.
//
//	Returns:	Nothing.
//
//	20170405 Ver 0.0	E.Andrews	First cut
//

if (New_XfrRateHz > 0)	//DO NOTHING if XfrRateHz is zero or less.
		{
	uint32_t tcTicks = FreqToTimerTicks(New_XfrRateHz);	//Convert "Hz value" to "Clock Ticks"
	// Send TC0 Clock signal to external pin so AGS hardware can se it to sync things up
	int ulPin = 2; // just an example:   it's 2  for the Timer0 TIOAO
	PIO_Configure(g_APinDescription[ulPin].pPort,
			g_APinDescription[ulPin].ulPinType,
			g_APinDescription[ulPin].ulPin,
			g_APinDescription[ulPin].ulPinConfiguration);

	// Enable TC0  
	pmc_enable_periph_clk (TC_INTERFACE_ID);

	//Set Mode and Frequency of TC0
	Tc * tc = TC0;
	TcChannel * t = &tc->TC_CHANNEL[0];
	t->TC_CCR = TC_CCR_CLKDIS;
	t->TC_IDR = 0xFFFFFFFF;
	t->TC_SR;
	t->TC_RC = tcTicks;    		// Sets PERIOD of timer in "tcTicks" units
	t->TC_RA = (tcTicks - tcTicks / 2);	// Use this value to alter clock signal symmetry...(tcTicks/2 = 50%)

	//TC_CMR = Timer Counter Channel Mode Register, a four byte register used to set WAVEFORM MODE
	//	Note: Since the DUE MCK = 84 MHz, the following master clock source settings are available
	// 		TC-CMR_TCCLOCKS_TIMER_CLOCK1 sets the clock source to be =  MCK/2  (48.0   MHz)
	// 		TC-CMR_TCCLOCKS_TIMER_CLOCK2 sets the clock source to be =  MCK/8  (10.5   MHz)
	// 		TC-CMR_TCCLOCKS_TIMER_CLOCK3 sets the clock source to be =  MCK/32 ( 2.652 MHz)
	// 		TC-CMR_TCCLOCKS_TIMER_CLOCK3 sets the clock source to be =  MCK/128( 0.65625 MHz or 656.25 KHz)
	t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_WAVE
			| TC_CMR_WAVSEL_UP_RC;
	t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR
			| TC_CMR_ACPC_SET;
	t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;

	//Setup is done; Remember the setting for later recall as needed
	DmaClkFreq_Hz = New_XfrRateHz;
}

}

void XYscope::dacSetup(void) {
//	Routine to setup DAC and Interrupt Controller for DMA transformers.
//
//	User calls this once during SETUP.
//
//	Calling parameters:
//	
//	None
//
//	Returns:	Nothing.
//		ix		Returns updated pointer into array where next graphics point will go.
//
//	20170407 Ver 0.0	E.Andrews	First cut
//

//----------------------------------------------------    
//  DAC SETUP
//----------------------------------------------------
pmc_enable_periph_clk (DACC_INTERFACE_ID); 	// start clocking DAC

dacc_reset (DACC);		//This returns DAC hardware to power-up conditions

dacc_set_transfer_mode(DACC, 0);//for this variable, 0=HALFWORD_MODE (16 bits integers) or 1=FULLWORD_MODE (32 bit integers)
dacc_set_power_save(DACC, 0, 0);	//Setup of DAC Power_Save option
// Set DACC Analog Current Register - Use typical recommended values of 0x01 for IBCTLDACCORE and 0x02 for IBCTLCH0/IBCTLCH1
// This may sets the slew rate of DACC register & IBCTLDACCH0/IBCTLDACCH1:
dacc_set_analog_control(DACC,
		DACC_ACR_IBCTLCH0(0x02) | DACC_ACR_IBCTLCH1(0x02)
				| DACC_ACR_IBCTLDACCORE(0x01));
dacc_set_trigger(DACC, 1);

dacc_enable_channel(DACC, 0);	//Enable DAC0
dacc_enable_channel(DACC, 1);	//Enable DAC1

// DACC_MR bit definitions
//
//	|	31	|	30	|	29	|	28	|	27	|	26	|	25	|	24	|
//	+-------+-------+-------+-------+-------+-------+-------+-------+	STARTUP TIME: Time till initial startup conversion 
//	|		|		|<-------------- STARTUP TIME ----------------->|	0=0 periods of DACC CLOCK, 63=4032 periods of DACC CLOCK 
//	+-------+-------+-------+-------+-------+-------+-------+-------+	Typical value = 3 to 8. (See table on pg 1366 of HW Data Sheet for more details)
//
//	|	23	|	22	|	21	|	20	|	19	|	18	|	17	|	16	|
//	+-------+-------+-------+-------+-------+-------+-------+-------+	MAXS: Startup after wake up; 0=Normal (No Sleep), 1=Fast Wake up Sleep Mode
//	|		|		| MAXS	|  TAG	|		|		|<--USER  SEL-->|	TAG: 0=DIS (Tag Selection Mode Disabled, using USER_SEL value to chan conversion
//	+-------+-------+-------+-------+-------+-------+-------+-------+	USER_SEL: 0=Chan 0 Selected, 1=Chan 1 Selected (Only meaningful when TAG=1)
//
//	|	15	|	14	|	13	|	12	|	11	|	10	|	 9	|	 8	|
//	+-------+-------+-------+-------+-------+-------+-------+-------+	DAC AUTO REFRESH PERIOD
//	|<----------------------   REFRESH   -------------------------->| 	0: No DAC Refresh, >0: DAC Refresh Period = 1024 * REFRESH_VALUE/DACC_CLOCK
//	+-------+-------+-------+-------+-------+-------+-------+-------+
//
//	|	7	|	6	|	5	|	4	|	3	|	2	|	 1	|	 0	|
//	+-------+-------+-------+-------+-------+-------+-------+-------+	FAST WKUP: 0=Sleep Mode defined by SLEEP bit, 1=Fast Wak up Sleep Mode (Vref ON Between Conversions but DAC core is OFF)
//	|		|FSTWKUP| SLEEP	|WRD MOD|<----- TRIG SEL ------>| TRGEN	|	SLEEP: 0=Normal (No Sleep), 1=Sleep Mode (Sleeps between conversions)
//	+-------+-------+-------+-------+-------+-------+-------+-------+	WORD/HALF-WORD MODE: 0=Half Word Mode (16 Bit), 1=Full Word Mode (32 Bit)
//																		TRIG SEL: 0=Ext, 1=TC0_CH0, 2=TC0_CH1, 3=TC0_CH2,4=PWM Event_0,5=PWM Event_1,6=RESRVD,7=RESERVD
//																		TRGEN (Trig Enable): 0=Disabled, DACC in Free Run Mode, 1=Ext Trig mode.
//
//

//	DACC_MR REGISTER SETTINGS...
//		STARTUP TIME
DACC->DACC_MR |= 8 << 24;		//8=512 DACC clock periods of startup time.
//		MAXS Mode bit
DACC->DACC_MR |= 0 << 16;		//No Bits Set, MAXS=0 meaning NO SLEEP
//		TAG MODE Bit
DACC->DACC_MR |= 1 << 20;//TAG=1 (Bits 12,13 of incomming data selects DAC0/DAC1 destination )
//		DAC REFRESH 
DACC->DACC_MR |= 0 << 8;//No Bits Set.  REFRESH=0, meaning NO AUTO REFRESH DESIRED
//		FSTWKUP, SLEEP,WRD MODE, TRIG SEL, TRig ENABLE
DACC->DACC_MR |= 0;	//No Bits Set.  HALF_WORD MODE, EXT-TRIG, TRIG DISABLED

//----------------------------------------------------    
//  Interrupt Controller SETUP
//----------------------------------------------------

NVIC_DisableIRQ (DACC_IRQn);//Disable DACC IRQ in the Nested Vectored Interrupt Controller (NVIC)
NVIC_ClearPendingIRQ(DACC_IRQn);//Clear any pending DACC IRQ in the Nested Vectored Interrupt Controller (NVIC)
NVIC_EnableIRQ(DACC_IRQn);//Now, ENABLE DACC IRQ in the Nested Vectored Interrupt Controller (NVIC)

}

void XYscope::dacHandler(void) {
//	Routine to handls END OF TRANSFER dma interrupt.
//	This ISR is called when the DMA transfer to the CRT screen is finished.
//	The Primary task of the routine is to set crtBlaningPin output pin to HIGH
//	so that the screen is turned off.
//
//	User does NOT directly call this routine.
//
//	Calling parameters:
//				None.
//
//	Returns:	Nothing.
//
//
//	20170405 Ver 0.0	E.Andrews	First cut.
//	20170405 Ver 0.1	E.Andrews	Reworked to play nicely with timer driven refresh inteerupt
//	20170526 Ver 0.2	E.Andrews	Cleaned up comments and throw out unused code fragments
//

//Retrive DACC interupt status
uint32_t status = dacc_get_interrupt_status(DACC);

if ((status & DACC_ISR_ENDTX) == DACC_ISR_ENDTX) {//Verify we have a true ENDTX interrupt event.
	//digitalWrite(crtBlankingPin,HIGH);	//turnoff crt beam

	//digitalWrite(crtBlankingPin,LOW);	//Keep Beam On a little while longer...
	//digitalWrite(crtBlankingPin,LOW);	//Keep Beam On a little while longer...
	//digitalWrite(crtBlankingPin,LOW);	//Keep Beam On a little while longer...
	//digitalWrite(crtBlankingPin,HIGH);	//turnoff crt beam
	///digitalWrite(crtBlankingPin,LOW);	//turnoff crt beam}
	///digitalWrite(crtBlankingPin,HIGH);	//turnoff crt beam}
	///digitalWrite(crtBlankingPin,LOW);	//turnoff crt beam}
	///digitalWrite(crtBlankingPin,LOW);	//turnoff crt beam}

	dacc_disable_interrupt(DACC, DACC_IER_ENDTX);//disable interrupt.  ENDTX = Interrupt at End_of_Transmit_Buffer event														//Skip this code and do nothing if not a ENDTX event
	//ENDTX = End of Transmit Buffer.  ENDTX is set when DACC_TCR = 0.
	//This statis check is insurance to be sure it is safe to start updating DMA registers
	//This interlocks with ENDTX status bit so that we only change and update the DMA registers inbetween active DMA transfers.
	// //digitalWrite(crtBlankingPin,HIGH);	//Reset External Sync Signal
	//Update CURRENT REGISTER SET to get it ready for next DMA Operation
	// //DACC->DACC_TPR = (uint32_t)XYlist;		//(DACC_TPR) = Transmit (source data) Pointer Register
	//Set this register to the starting address of the XYList[] array)
	// //DACC->DACC_TCR = XYlistEnd;				//(DACC_TCR)= Transmit Counter Register. Loading this value initiates the start of a transfer
	//The TCR should be set to number of integers we want to happen for each DMA transfer.
	//In this case, XYlistEnd is always pointing at the last element of array XYlist[].	
	//So...Set this TCR register = XYlistEnd counter value

	//NVIC_DisableIRQ(DACC_IRQn);			//Disable DACC IRQ in the Nested Vectored Interrupt Controller (NVIC)
	//NVIC_ClearPendingIRQ(DACC_IRQn);	//Clear any pending DACC IRQ in the Nested Vectored Interrupt Controller (NVIC)
	//NVIC_EnableIRQ(DACC_IRQn);			//Now, ENABLE DACC IRQ in the Nested Vectored Interrupt Controller (NVIC)
	//dacc_enable_interrupt(DACC, DACC_IER_ENDTX);	//Enable DAC interrupt.
	//dacc_enable_interrupt(DACC, DACC_IER_TXBUFE);	//Enable DAC interrupt. DACC_IER_TXBUFE = Interrupt at End_of_Transmit_Buffer_EMPTY event

}

for (int i = backPorchBlankCount; i > 0; i--) {
	__asm__ __volatile__("nop");
	//loop to generate a short (~60ns per count), programmable delays
}
digitalWrite(crtBlankingPin, HIGH);	//BLANK display...Last point has been plotted...

}

//void initiateDacDma(short& ArrayPtr,int NumOfPoints){

void XYscope::initiateDacDma(void) {
//
//	This routine will initiate a DMA transfer of the current XYlist of points to DAC0 (X) & DAC1 (Y)
//	causing the points to "paint" onto the CRT screen.  It is called from the DacHandler ISR routine.
//
//	Timer3 is used to trigger this routine every 'refreshPeriodMs'.  Usually refreshPeriodMs is a constant
//	(defined in XYscope.h) that is normally set to a value in the 16 to 32 range of values.  The XY points
//	will be repainted and with the help of POV (persistance of vision) appear continuously to the observer.
//	If refreshPeriodms is set too long, the screen image will flicker or be noticably blinking.
//
//	Calling parameters: NONE
//
//	Returns:	NOTHING
//
//	20170418 Ver 0.0	E.Andrews	First cut.
//	20170724 Ver 0.1	E.Andrews	Reworked to automatically adjust FRONT PORCH blanking signal
//									based on active DMA clock rate.

DACC->DACC_TPR = (uint32_t) XY_List;//(DACC_TPR) = Transmit (source data) Pointer Register
//DACC->DACC_TNPR = (uint32_t)XY_List;	//(DACC_TNPR) Transmit NEXT Pointer register. <--May not be needed...
//Set this register to the starting address of the XY_List[] array)

DACC->DACC_TCR = XYlistEnd * 2;	//(DACC_TCR)= Transmit Count Register (TCR=How many Short-Integers to transfer).
								//Set TCR register = XYlistEnd counter value
DACC->DACC_TNCR = 0;//(DACC_TNCR)= Transmit NEXT Counter Register is NOT USED; set to zero!. <--May not be needed...
//DACC->DACC_TNCR = XYlistEnd*2;		//(DACC_TNCR)= Transmit NEXT Counter Register. <--May not be needed...
//The TCR should be set to number of integers we want to happen for each DMA transfer.
//In this case, XYlistEnd is always pointing at the last element of array XY_List[].	

//This is how we START a transfer! (This will acttually start the DMA transfer
DACC->DACC_PTCR = DACC_PTCR_TXTEN;//(DACC_PTCR) = Receiver Transfer Enable Register  

//Now that DMA transfer is underway, we must UNBLANK the Z-Axis by setting the Blanking Pin LOW.

//The following repeated digitalWrites are used as fixed delays to properly time the
//state change of the crtBlanking signal which is used by the hardware interface &
//to properly unblank the output once actual data is starting to appear at DAC1/DAC2

digitalWrite(crtBlankingPin, HIGH);	//Stay blanked...

for (int i = frontPorchBlankCount; i > 0; i--) {
	__asm__ __volatile__("nop");
	//loop to generate a short (~60ns per count), programmable delays
}

if (millis() > _crtOffTOD_ms && _screenOnTime_ms != 0) {
	digitalWrite(crtBlankingPin, HIGH);	//Keep BLANKED if ScreenSave Time Not yet Exceeded
} else
	digitalWrite(crtBlankingPin, LOW);	//Unblank and resume display

dacc_enable_interrupt(DACC, DACC_IER_ENDTX); //Enable interrupt when dac runs out of data...

}

void paintCrt_isrsss() {	//TODO REMOVE THIS ROUTINE!
//	paintCrtISR Interrupt Service Routine
//
//	This routine will initiate a DMA transfer of the current XYlist of points to DAC0 (X) & DAC1 (Y)
//	causing the points to "paint" onto the CRT screen.
//
//	Timer3 is used to trigger this routine every 'refreshPeriodMs'.  Usually refreshPeriodMs is a constant
//	(defined in XYscope.h) that is normally set to a value in the 16 to 32 range of values.  The XY points
//	will be repainted and with the help of POV (persistance of vision) appear continuously to the observer.
//	If refreshPeriodms is set too long, the screen image will flicker or be noticably blinking.
//
//	Calling parameters:
//				None.
//
//	Returns:	Nothing.
//
//
//	20170418 Ver 0.0	E.Andrews	First cut.
//

//digitalWrite(crtBlankingPin,HIGH);	//Go into blanking...

// *** END TEST SIGNAL **********	TODO You can DELETE this block when scope testing is no longer needed
const uint8_t Led13 = 13;//	*	Attach scope probe to pin 13 to monitor entry and exit into this routine
digitalWrite(Led13, HIGH);	//	*   Entering ISR, Set LED13=HIGH
// *** END TEST SIGNAL **********

//initiateDacDma();	//Start the DMA transfer to paint the CRT screen

// *** END TEST SIGNAL **********	TODO You can DELETE this block when scope testing is no longer needed
digitalWrite(Led13, LOW);	//	*	Leaving ISR, Set LED13=LOW
// *** END TEST SIGNAL **********

}

void XYscope::disableDac(void) {
dacc_disable_interrupt(DACC, DACC_IER_ENDTX);
}

void XYscope::setScreenSaveSecs(long ScreenOnTime_sec) {
//	Routine to set/change the screen-save period.
//
//	Calling parameters:
//
//	ScreenOnTime_sec	The time that the display will remain active after the last plotPoint call.
//						This screen timer begins after the LAST plotPoint command is executed;
//						Display will blank when timer expires.
//
//						ScreenOnTime_Sec = 0 means that the screen saver function is OFF.
//
//	Returns:	Nothing.
//
//	20170705 Ver 0.0	E.Andrews	First cut
//
_screenOnTime_ms = ScreenOnTime_sec * 1000;
if (_screenOnTime_ms != 0)
_crtOffTOD_ms = millis() + _screenOnTime_ms;
}
long XYscope::getScreenSaveSecs(void) {
//	Routine to get the screen-save period.
//
//	Calling parameters:
//
//	ScreenOnTime_sec	The time that the display will remain active when there is no plotPoint activity.
//						This screen timer begins after the LAST plotPoint command is executed.
//						ScreenOnTime_Sec = 0 means that the screen saver function is OFF
//						and the screen continuously on.
//
//	Returns:	ScreenOnTime_sec
//
//	20170705 Ver 0.0	E.Andrews	First cut
//
return _screenOnTime_ms / 1000;
}

void XYscope::setRefreshPeriodUs(uint32_t refresh_us) {
//	Routine to set/change the refresh timer.  User can call any time to change the refresh period.
//
//	Calling parameters:
//
//	refresh_us	Refresh period in microseconds (us). Value is nominally 15000 < refresh_us < 33000.
//
//	CAUTIONS:
//	1) 	For short persistance phosphors, refresh_us may need to <25000 (25 ms)
//	   	to prevent display flicker.
//	2)	If refresh time is set too short, the whole display list may not be visualized.
//
//	Returns:	Nothing.
//
//	20170705 Ver 0.0	E.Andrews	First cut
//
ActiveRefreshPeriod_us = refresh_us;//Store the value as the ActiveRefreshPeriod
Timer3.start(refresh_us);			//Set the refresh timer
}
long XYscope::getRefreshPeriodUs(void) {
//	Routine to Get the refresh timer.  User can call any time to change the refresh period.
//
//	Calling parameters:
//
//	refresh_us	Refresh period in microseconds (us). Value is nominally 15000 < refresh_us < 33000.
//
//	CAUTIONS:
//	1) 	For short persistance phoshors, refresh_us may need to <25000 (25 ms)
//	   	to prevent display flicker.
//	2)	If refresh time is set too short, the whole display list may not be visualized.
//
//	Returns:	Currently active refresh period (in microseconds)
//
//	20170705 Ver 0.0	E.Andrews	First cut
//

return ActiveRefreshPeriod_us;

}

void XYscope::autoSetRefreshTime(void) {
//	This routine automatically adjusts the crt refresh period.  Time will be
//	set based to CrtMinRefresh_ms OR TimeReqdToPlotAllPoints_us, whichever
//  is larger. User should call this function.
//
//	Call this routine AFTER every major write the XYlist to be sure all points are
//	visualized.
//
//	Calling parameters: NONE
//
//	Returns:	NOTHING.
//  Other Notes:  Use GetRefreshPeriodUs() routine to retrieve the active value.
//
//	201707017 Ver 0.0	E.Andrews	First cut
//

uint32_t crtRefreshTime_us, TimeReqdToPlotAllPoints_us;

// Calculate the display time needed based on number of points in XYlist
// Add a "20 Point Buffer" into the calculation to ensure float to integer round off errors
// do not result in over-run conditions.
TimeReqdToPlotAllPoints_us = int(DmaClkPeriod_us * 2 * (XYlistEnd + 20));

//  Compare calculated TimeReqd.. to MinRefresh value as as spec'd in header file.
//  Pick which ever time is slowest....
if (TimeReqdToPlotAllPoints_us > CrtMinRefresh_ms * 1000) {
	crtRefreshTime_us = TimeReqdToPlotAllPoints_us;	//Set Refresh time = to miniumn defined refreshtime or that required to get all the points to the screen...
} else {
	crtRefreshTime_us = CrtMinRefresh_ms * 1000;//Min Refresh Time in microseconds...
}

//	Now see if we need to actually change the refresh timer...
//  Only Update REFRESH timer period (microseconds) when new time <> currently active timer
if (ActiveRefreshPeriod_us != crtRefreshTime_us) {
	Timer3.start(crtRefreshTime_us);			//Upadate Timer Period
	ActiveRefreshPeriod_us = crtRefreshTime_us;	//Store new value "ActiveRefreshPeriod_us"
}

}

//
/ Private Functions /
//

uint32_t XYscope::FreqToTimerTicks(uint32_t freqHz) {
return VARIANT_MCK / 2UL / freqHz;//Converts frequency(Hz) into Timer Count values for TC programming
}

void XYscope::begin(uint32_t dmaFreqHz) {
//	Routine to initialize DAC, CounterTimer, & DMA Controller.
//
//	User Calls ONCE inside application setup() procedure.
//
//	Calling parameters:
//	
//	dmaFreqHZ	This is the intended DMA Transfer Rate in Hertz.
//				If value is omitted, startup frequency will set to XYscope.h default
//				Note that Point_Clk_Freq = XfrRateHz/2.
//
//	CAUTIONS:	Usual XfrRateHz values should be in 300,000 to 800,000 range.
//
//				Lower values make the screen refresh take longer and therefore
//				reduces the total number of points that can be displayed before
//				CRT flicker becomes visually apparant.
//
//				Higher values demand more of the XY display/oscilloscope
//				hardware but do allow more points to be plotted before refresh
//				flicker is a apparent.
//
//	Returns:	Nothing.
//
//	20170405 Ver 0.0	E.Andrews	First cut
//	20170828 Ver 1.0	E.Andrews	Remove diag "print" statements and code/comment clean up
//

float temp = getLibRev();	//Call revision routine to properly set the (global variables in case someone uses them)
temp=temp;

// Initialize the pin mode for BLANKING PIN and set default start up value=HIGH
pinMode(crtBlankingPin, OUTPUT);
digitalWrite(crtBlankingPin, HIGH);	//At the start, set CRT output to BLANKED

//Reset global PlotErr flag.  This flag is set inside the POINT PLOT routine
//whenever we run out of room in the XY_List array (ie: XYlistEnd > MaxBuffSize).
plotErr = 0;

//Initialize ScreenSaver time to default minute
setScreenSaveSecs(screenOnTimeDefaultSec);

// Initialize global GRAPHICS and TEXT intensity variables (NO PASSED VALUE=Set to 100%)
setGraphicsIntensity();	//Set default Graphics intensity
setTextIntensity();		//Set default Text intensity;

// Initalize to normal Mono Spaced Characters
setFontSpacing(mono);

//Perform DMA Timer Counter setup
setDmaClockRate(dmaFreqHz);

tcSetup(dmaFreqHz);	//DO NOT DELETE - This 'redundant' call is needed to get the TC started!

// Perform Refresh Timer (Timer #3) Setup
Timer3.start(CrtMinRefresh_ms * 1000);

// Perform DAC setup
dacSetup();

//Initialize XY_list array
plotStart();

//Set refresh timer
autoSetRefreshTime();

//Serial.print ("\n  -> BEGIN: Graphics/Text Intensity Default Set: ");Serial.print (GetGraphicsIntensity());Serial.print ("% / ");Serial.print (GetTextIntensity());;Serial.print ("%");

//Serial.print ("\n  -> BEGIN: Calling dacSetup()");

//Serial.print("...Returned");

//Serial.print("\n  -> BEGIN: Calling tcSetup (");Serial.print(dmaFreqHz);Serial.print(")");

}

XYscope.h

#ifndef XYs		//Include-Guard to prevent multiple includes...
#define XYs

#if (ARDUINO >=100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

//Make sure we are compiling for an Arduino DUE processor
#if not(SAM3X8E)
#error WRONG PROCESSOR SELECTED - XYscope Library is only usable with Arduino DUE Processor
#endif

//void paintCrt2_ISR();						//This is the Refresh CRT ISR declaration

//void XY_TimerTestISR();						//TODO this is a test routine...Delete ASAP
//void initiateDacDma(void);					//Fires off a DacDMA transfer
//void initiateDacDma(short *ArrayPtr,int NumPoints,int blankCount,int crtBlankingPin); //Another version of the InitialDacDMA routine

class XYscope{
public:
// Constructor
XYscope();

//Methods

//Setup and Control Routines
float getLibRev(void);								//Retrieves the revision level of the active library
void begin(uint32_t dmaFreqHz=800000);				//Initializes and enables DAC, DAC Counter Timer, DMA controller, Refresh Counter Timer
void initiateDacDma(void);							//NOT A USER ROUTINE: Fires off a DacDMA transfer
void dacHandler(void);								//NOT A USER ROUTINE: This is link to DAC_TRANSFER_COMPLETED interrupt

void setScreenSaveSecs(long ScreenOnTime_sec);	//Set the screen saver time. Set to Zero to disable screen saver.
long screenOnTimeDefaultSec=600;				//Define power-up default setting.

long getScreenSaveSecs(void);					//Retrieve current screen saver time. Zero=screen saver disabled.

void setDmaClockRate(uint32_t New_XfrRateHz);	//Allows user to change output Clk rate during run-time

void setRefreshPeriodUs(uint32_t refresh_us);	//Can be used to manually change the refresh period (us) during run-time.

void autoSetRefreshTime();						//Automatically sets the best refresh time based on the number points being plotted
long getRefreshPeriodUs(void);					//Retrieves the currently active refresh period (us).

//Buffer Management Routines
void plotStart();				//Reset current buffer pointer to zero, effectively erasing the existing XY_List array
void plotClear();				//Reset current buffer pointer to zero, effectively erasing the existing XY_List array and turning the display OFF
void plotEnd();					//Makes sure last points in XYlist are actually actually visualized

//Graphics Plotting Routines

void setGraphicsIntensity(short GraphBright=100);	//Set (Get) brightness of Lines, Circles, Ellipse, Rectangles (in percent)
short getGraphicsIntensity();							//Nominal setting is 100. Usable range is 50-200.

short getGraphDensity();								//OBSOLETE-DO NOT USE. Function returns dot-to-dot spacing value in use (driven by intensity setting)

void setTextIntensity(short TextBright=100);		//Set (Get) brightness of Text (in percent)
short getTextIntensity();								//Nominal setting is 100. Usable range is 50-200.
short getTextDensity();								//OBSOLETE-DO NOT USE. Function returns dot-to-dot spacing value in use (driven by intensity setting)

void plotPoint(int x0, int y0);											// Plots a POINT
void plotLine(int x0, int y0, int x1, int y1);							// Plots Lines (aka: a Vector)
void plotRectangle(int x0, int y0, int x1, int y1);						// Plots a rectangle	
void plotCircle(int xc, int yc, int r);									// Plots a circle centered at (xc,yc) of radius "r"	
void plotCircle(int xc, int yc, int r, uint8_t arcSegment);				// Plots a circle centered at (xc,yc) of radius "r" BUT just specified arcSegment(s) of the circle.
void plotCircleBres(int xc, int yc, int r, uint8_t arcSegment);			// Bresenham Algorthm:Plots a circle centered at (xc,yc) of radius "r" BUT just specified arcSegment(s) of the circle.
void plotEllipse(int xc, int yc, int xr, int yr);						// Plots an ellipse
void plotEllipse(int xc, int yc, int xr, int yr,uint8_t arcSegment);	// Plots an ellipical arc BUT just specified arcSegment(s)of the ellipse.
void plotEllipseBres(int xc, int yc, int xr, int yr,uint8_t arcSegment=255);	//Bresenham Algorthm:Plots an ellipse (does Not use Bressham!)

void plotChar(char c, int& x0, int& y0, int& charHt);					//Plot a single Character
void plotCharUL(char c, int& x0, int& y0, int& charHt);					//Plot a single character WITH UNDERLINE

void plotArduinoLogo(int& charX, int& charY, int& charHt);				//Plot the Arduino LOGO to screen

const short prop=0, monoTight=8, mono=10, monoNorm=10, monoWide=12;	//Define FontSpacing  Constants
void setFontSpacing(short spacingMode=0);	//Set Font Proportional or mono spaced mode...
short getFontSpacing();						//retrieve current font spacing

void printSetup(short textX, short textY);									//Set X-Y location for start of text
void printSetup(short textX, short textY, short textSize);					//Set X-Y location for start of text, set textSixe (pixels)
void printSetup(short textX, short textY, short textSize, short textDensity);	//Set X-Y location for start of text, set textSixe (pixels), textDensity(Brightness)

void printUnderline(int nPlaces);			//Print UNDERLINE character(s)
void print(char* text);						//Print text string (starting at current X-Y location, size, & density, no underline)
void print(char* text, bool UL_flag);		//Print text string (starting at current X-Y location, size, & density, with/without UNDERLINE)
void print(int number);						//Print integer to screen (starting at current X-Y location, size, & density, no underline)
void print(int number,bool UL_Flag);		//Print integer to screen (starting at current X-Y location, size, & density, with/without UNDERLINE)
void print(float number);					//Print floating point number to screen (starting at current X-Y location, size, & density), nPlaces to right of DP
void print(float number,int placesToPrint);	//Print floating point number to screen (starting at current X-Y location, size, & density), nPlaces to right of DP, without UNDERLINE
void print(float number,int placesToPrint,bool UL_Flag);	//Print floating point number to screen (starta at current X-Y location, size, & density), nPlaces to right of DP, with/without UNDERLINE



void disableDac(void); 					//NOT A USER ROUTINE - Turns dac Off...May not need this

//========================================
//Global Variables & Constants
//========================================


static const uint8_t crtBlankingPin=3;		//CRT_Blanking pin (1=CRT_OFF, 0=CRT_ON)
uint16_t frontPorchBlankCount=100;			//Calculated and set by setDmaClockRate(int dmaClkFreq); Used to define the duration before CRT unblanks & displays starts at START of DMA transfer
uint16_t backPorchBlankCount=100;			//Calculated and set by setDmaClockRate(int dmaClkFreq); Used to define the duration before CRT blanking starts and display ENDS after the completion of a DMA transfer
uint32_t DmaClkFreq_Hz;						//Currently Active DMA Clock FREQUENCY (Hz)
float DmaClkPeriod_us;						//Currently Active DMA Clock PERIOD (us)

uint32_t ActiveRefreshPeriod_us;			//Currently Active REFRESH Clock PERIOD (us)

int MaxBuffSize=15000;						//This sets the size of the XY point plotting buffer.
											// NOTE: Each XY point pair consumes 4 bytes of RAM. This means that a buffer size of 15000
											// actually uses 15K X 4 = 60K bytes of RAM.  To leave room for other variables, MaxBufferSize should
											// NEVER exceed MaxArraySize (about 20000).  Also note that a lots of XY points can require longer refresh times
											// which will lead to display flicker!

static const uint32_t MaxArraySize=17000;	//This sets the max Array size reserved for XY list.  MaxBufferSize must always be <= MaxArraySize!

int XYlistEnd;								//This value points to the last element loaded into XYlist[] array
											//and is automatically maintained by Driver Routine "plotPoint"
											//By using the plotPoint routine, new points are automatically added at the END of the current list.
											//If you want to add point pairs directly into XYlist yourself, you must watch & maintain this value
											//and you must FOLLOW THESE RULES!
											//  1. Always use plotStart routine to setup a new list.  This places the needed snychronization pattern into the
											//     very start of a new list.  The hardware interface needs this pattern to run properly.
											//	2. When adding data into the XY_List array, you MUST include the X & Y flag values
											//     that are set into the high order bits of the X and Y integers. Look inside of plotPoint for details!
											//	3. XYlistEnd must stay BELOW MaxBufferSize or else you'll clobber other variables!
											//  4. XYlistEnd must be updated every time a point is added to the lsit.
											//	5. XYlistEnd always points the the NEXT AVAILABLE LOCATION in the XYList[] array.
											//	6. If the total number of points in the list gets too big, they may not all be displayed!
											//     If this happens, either reduce the the number of points in the list, or increase the refresh period.
											//	   You increase the the regresh period by changing the value of crtRefreshMs found else where in this file.						//


// Define Structure of XY Point List.  This is the actual data array that holds the points to be plotted to the CRT.
//  Use plotPoint or the other graphic draw routines to add points into this array.
//  Use plotStart to initialize and/or start over with a new list

struct pointList{
	short X;	//X-coordinate value of a point. Valid range: 0-4095 (See also the "rules" in XYlistEnd comment above!)
	short Y;	//Y-coordinate value of a point. Valid range: 0-4095 (See also the "rules" in XYlistEnd comment above!)
};
pointList XY_List[MaxArraySize];	//This reserves & defines the RAM allocated for the XY_List.  Actual value of usable space is set by variable MaxBuffSize

//Define Test Justification Flags
static const uint8_t LtJustify=0;	//Left Justified Text	(default)
static const uint8_t RtJustify=1;	//Right Justified Text
static const uint8_t CtrJustify=2;	//Center justified Text

//Define partial-circle/partial-ellipse "Arc-Codes"
static const uint8_t arc0=1;
static const uint8_t arc1=2;
static const uint8_t arc2=4;
static const uint8_t arc3=8;
static const uint8_t arc4=16;
static const uint8_t arc5=32;
static const uint8_t arc6=64;
static const uint8_t arc7=128;


	
uint8_t plotErr;						//plotPoint routine sets this variable when ever we attempt to plot too many points



static const long CrtMinRefresh_ms=20;	//This variable sets the target refresh rate for the display
										//  Note: 20ms = 50Hz CRT refresh rate
										//  Note: Although not recommended, you can set value=0 for fastest possible refresh.
												

static const uint16_t X_flag=0x0000;	//These are routing codes used by the DMA hardware to route each integer the right DAC
static const uint16_t Y_flag=0x1000;

// Define & initialize global text X-Y coordinates and text size variables
int charX=0,charY=4095, charSize=50;



#include "VectorFontROM.h"		//Include Font ROM file

private:
//Methods
//void paintCrt_isr();			//This routine Calls for a SCREEN REFRESH every crtRefreshMs milliseconds...this routine to refresh CRT as needed
void dacSetup (void);				//Called within begin(). Initializes and enables dac peripherals.
void tcSetup (uint32_t XfrRateHz);	//Called within begin().  Used to initialize Timer Counter TC0 (Drive DAC_DMA channel) at target transfer rate
uint32_t FreqToTimerTicks(uint32_t freqHz);	//Used within tcSetup to set DMA_Clock Rate

//Private Variables

//int _density=5;		//This is the global "active_density" value
int _graphDensity;		//value calculated by/set by call to SetGraphicsIntensity(int brightness)
int _graphBrightness;	//value that is set by call to SetGraphicsIntensity(int graphbrightness)

int _textDensity;		//value calculated by/set by call to SetTextIntensity(int brightness)
int _textBrightness;	//value that is set by call to SetGraphicsIntensity(int graphbrightness)

unsigned long _crtOffTOD_ms;	//Screen save time in ms; Zero means screen saver disabled.
unsigned long _screenOnTime_ms;	//TOD (ms) when Screen should next be blanked;

//Define Font Spacing variable
short _fontSpacing=8;
uint8_t	_fontJustifyFlag;	//Global varialbe to define justification
uint8_t	_fontJustifyEnab;	//0=disable justification (default to LEFT); !0=enable justification as set by _fontJustifyFlag


//Define XYscope Library Version using Semantic scheme (Major_Rev, Minor_Rev, Patch_Rev)
float _libMajorRev=0;	//Valid range: 0-99
float _libMinorRev=0;	//Valid range: .00-.99
short _libPatchRev=0;		//Valid range: 0-99
float _libRev=0.0;

};
#endif // XYscope

VectorFontROM.h

/*

VectorFontROM.h



Created on: Jul 13, 2017

 Author: EdAndrews



 This is a vector stroke font data file for use with the XYscope library. The FontROM

 data structure (below) to specify graphics elements, coordinates, and graphic feature parameters.

 Each character is defined using graphics primatives within a 16x16 XY coordinate

 character cell. Graphics "Opcode" primatives define NOP, POINT, LINE, CIRCLE, ELLIPSE, & RECTANGLE

 features that are used to "plot the character" into the XY point list.  Coordinate &

 Radius values are held as 4-bit (0-15) values, double packed two to a byte.



 Lines & Rectangles (Opcodes LIN & REC) are defined by corner end points.

   Variable [P1]: Defines the feature start point (x0,y0)

   Variable [P2]: Defines the feature end point (x1,y1)

   Variable [P3]: Not used



 Circles & Arcs (Opcode CIR) are defined by a center coordinate, feature radius, & segment flag.

   Variable [P1]: Defines the circlular feature center point (x),y0)

   Variable [P2]: Defines the circle radius (radius).

   Variable [P3]: Defines the 'segment' flag bits.

      By setting bits within the segment flag to 1, whole or partial circlular features can be plotted.

      When segment  bits are set to 1 (value=255), a full circle is drawn.



 Ellipses (Opcode ELP) are defined by a center coordinate, feature radius, & segment flag.

   Variable [P1]: Defines the ellipse feature center point (x0,y0),

   Variable [P2]: Defines the ellipse X & Y radius values (x_radius,y_radius).

   Variable [P3]: Defines the 'segment' flag bits.

      By setting bits within the segment flag to 1, whole or partial ellipical features can be plotted.

      When segment  bits are set to 1 (value=255), a full ellipse is drawn.



 A cross reference array, (Ascii2font[]) is used as a pointer to the Starting primative

 to each character.



 Since the graphical definition of a given  character varies based on the graphics complexity required

 to draw the symbol, the MSB of the Opcode is used as an End-Of-Character (EOC) flag bit. When EOC is set,

 the character plotting routine that is scanning and executing the graphics primatives stops when it sees

 the EOC bit set.

*/

#ifndef VECTORFONTROM_H_
#define VECTORFONTROM_H_

//Define Stroke_Font EOC  (End_Of_Character) flag.
//This flag tells plotChar when the end of a character in the FontROM has been reached (time to plotting data for the current character)
uint8_t const EOC = 0x80;			//End of Character Flag (hi-order bit=1)

//Define Stroke_Font OpCodes (with EOC flag NOT SET); These codes are used within the FontROM data structure and which is the core of the plotChar routine
uint8_t const NOP = 0x0, PNT = 0x1, LIN = 0x2, REC = 0x3, CIR = 0x4, ELP = 0x5;	//NOP = No Operation, PNT = plot a single POINT, LIN = Plot a LINE
//REC = Plot a Rectangle, CIR = Plot a fully closed Cirecle or just some circular segment(s)
//ELP = Plot a fully closed Ellipse or just some ellipical segment(s).

//Define Stroke_Font OpCodes with EOC flag SET (Opcodes OR EOC_Flag)
uint8_t const NOP_E = NOP | EOC, PNT_E = PNT | EOC, LIN_E = LIN | EOC, REC_E =
REC | EOC, CIR_E = CIR | EOC, ELP_E = ELP | EOC;

//This is the structure definition for the FontROM lookup table
struct FontROM {
uint8_t Opcode;	//D7 = EOC Flag, D0-4 = Stroke Font Code (ie: NOP,Point,Line,Circle,Elipse,Rectangle, etc)
uint8_t P1;		//D4-7= x0, D0-3= y0
uint8_t P2;	//For LINE & RECT: D4-7= x1, D0-3= y1   For CIR & ELP: D4-7= radius_X, for ELP: D0-3= radius_Y
uint8_t P3;		//for CIR & ELP (not used for others); D0-7 = Segment Flags.
// When a SegmentFlag is set to 1, plot the segment; when set to 0, do not plot (skip) the segment
};

FontROM DigitFont[280] PROGMEM= {

{	NOP_E,0x0,0x0,0x00},    // ASCII: 32   SP   (Space)

{	LIN ,0x2E,0x28,0x00},    // ASCII: 33   !   (Exclamation mark)
{	CIR_E,0x25,0x11,0xFF},    // ASCII: 33   !   (Exclamation mark)

{	LIN ,0x2D,0x2B,0x00}, // ASCII: 34   "   (Quotation mark (&quot; in HTML))
{	LIN_E,0x4D,0x4B,0x00}, // ASCII: 34   "   (Quotation mark (&quot; in HTML))

{	LIN ,0x3D,0x26,0x3E},    // ASCII: 35   #   (Cross hatch (number sign))
{	LIN ,0x5D,0x46,0x7C},    // ASCII: 35   #   (Cross hatch (number sign))
{	LIN ,0x1B,0x6B,0x00},    // ASCII: 35   #   (Cross hatch (number sign))
{	LIN_E,0x18,0x68,0x00},    // ASCII: 35   #   (Cross hatch (number sign))

{	CIR ,0x3B,0x22,0xC7},    // ASCII: 36   $   (Dollar sign)
{	CIR ,0x37,0x22,0x7C},    // ASCII: 36   $   (Dollar sign)
{	LIN_E,0x3E,0x34,0x00},    // ASCII: 36   $   (Dollar sign)

{	LIN ,0x6E,0x14,0xFC},    // ASCII: 37   %   (Percent sign)
{	CIR ,0x2C,0x11,0xFF},    // ASCII: 37   %   (Percent sign)
{	CIR_E,0x55,0x11,0xFF},    // ASCII: 37   %   (Percent sign)

{	CIR ,0x3C,0x11,0x4F},    // ASCII: 38   &   (Ampersand)
{	CIR ,0x37,0x22,0xE1},    // ASCII: 38   &   (Ampersand)
{	LIN ,0x65,0x2B,0x00},    // ASCII: 38   &   (Ampersand)
{	LIN ,0x4B,0x18,0x00},    // ASCII: 38   &   (Ampersand)
{	LIN_E,0x56,0x67,0x00},    // ASCII: 38   &   (Ampersand)

{	LIN_E,0x2D,0x2B,0x80}, // ASCII: 39   `   (Closing single quote (apostrophe))

{	ELP_E,0x39,0x25,0xC3},    // ASCII: 40   (   (Opening parentheses)

{	ELP_E,0x19,0x25,0x3C},    // ASCII: 41   )   (Closing parentheses)

{	LIN ,0x19,0x79,0x00},    // ASCII: 42   *   (Asterisk (star, multiply))
{	LIN ,0x27,0x6B,0x00},    // ASCII: 42   *   (Asterisk (star, multiply))
{	LIN ,0x46,0x4C,0x00},    // ASCII: 42   *   (Asterisk (star, multiply))
{	LIN_E,0x2B,0x67,0x00},    // ASCII: 42   *   (Asterisk (star, multiply))

{	LIN ,0x19,0x79,0x00},    // ASCII: 43   +   (Plus)
{	LIN_E,0x46,0x4C,0x00},    // ASCII: 43   +   (Plus)

{	CIR ,0x25,0x11,0xFF},    // ASCII: 44   ,   (Comma)
{	ELP_E,0x25,0x13,0x30},    // ASCII: 44   ,   (Comma)

{	LIN_E,0x19,0x79,0x00},    // ASCII: 45   -   (Hyphen, dash, minus)

{	CIR_E,0x35,0x11,0xFF},    // ASCII: 46   .   (Period)

{	LIN_E,0x6E,0x14,0x00}, // ASCII: 47   /   (Slant (forward slash, divide))

{	ELP ,0x49,0x35,0xFF},    // ASCII: 48   0   (Zero)
{	LIN_E,0x14,0x7E,0x00},    // ASCII: 48   0   (Zero)

{	LIN ,0x2C,0x4E,0x00},    // ASCII: 49   1   (One)
{	LIN ,0x4E,0x44,0x00},    // ASCII: 49   1   (One)
{	LIN_E,0x24,0x64,0x00},    // ASCII: 49   1   (One)

{	ELP ,0x3C,0x22,0x03},    // ASCII: 50   2   (Two)
{	ELP ,0x4C,0x22,0x1C},    // ASCII: 50   2   (Two)
{	LIN ,0x3E,0x4E,0x00},    // ASCII: 50   2   (Two)
{	LIN ,0x6B,0x15,0x00},    // ASCII: 50   2   (Two)
{	ELP ,0x34,0x22,0x01},    // ASCII: 50   2   (Two)
{	LIN_E,0x14,0x64,0x00},    // ASCII: 50   2   (Two)

{	ELP ,0x3C,0x22,0x3E},    // ASCII: 51   3   (Three)
{	ELP_E,0x37,0x33,0x7C},    // ASCII: 51   3   (Three)

{	LIN ,0x54,0x5E,0x00},    // ASCII: 52   4   (Four)
{	LIN ,0x5E,0x18,0x00},    // ASCII: 52   4   (Four)
{	LIN_E,0x18,0x68,0x00},    // ASCII: 52   4   (Four)

{	ELP ,0x47,0x33,0xFC},    // ASCII: 53   5   (Five)
{	LIN ,0x4A,0x2A,0x00},    // ASCII: 53   5   (Five)
{	LIN ,0x2A,0x3E,0x00},    // ASCII: 53   5   (Five)
{	LIN_E,0x3E,0x7E,0x00},    // ASCII: 53   5   (Five)

{	ELP ,0x47,0x33,0xFF},    // ASCII: 54   6   (Six)
{	LIN_E,0x29,0x5E,0x00},    // ASCII: 54   6   (Six)

{	LIN ,0x24,0x7E,0x00},    // ASCII: 55   7   (Seven)
{	LIN_E,0x7E,0x1E,0x00},    // ASCII: 55   7   (Seven)

{	ELP ,0x47,0x33,0xFF},    // ASCII: 56   8   (Eight)
{	ELP_E,0x4C,0x22,0xFF},    // ASCII: 56   8   (Eight)

{	ELP ,0x4B,0x33,0xFF},    // ASCII: 57   9   (Nine)
{	LIN_E,0x7A,0x44,0x00},    // ASCII: 57   9   (Nine)

{	CIR ,0x3B,0x11,0xFF},    // ASCII: 58   :   (Colon)
{	CIR_E,0x37,0x11,0xFF},    // ASCII: 58   :   (Colon)

{	CIR ,0x3B,0x11,0xFF},    // ASCII: 59   ;   (Semicolon)
{	CIR ,0x37,0x11,0xFF},    // ASCII: 59   ;   (Semicolon)
{	LIN_E,0x46,0x34,0x01},    // ASCII: 59   ;   (Semicolon)

{	LIN ,0x19,0x4C,0x00}, // ASCII: 60   <   (Less than sign (&lt; in HTML))
{	LIN_E,0x19,0x46,0x00}, // ASCII: 60   <   (Less than sign (&lt; in HTML))

{	LIN ,0x1A,0x5A,0x00},    // ASCII: 61   =   (Equals sign)
{	LIN_E,0x17,0x57,0x00},    // ASCII: 61   =   (Equals sign)

{	LIN ,0x1C,0x49,0x00}, // ASCII: 62   >   (Greater than sign (&gt; in HTML))
{	LIN_E,0x16,0x49,0x00}, // ASCII: 62   >   (Greater than sign (&gt; in HTML))

{	CIR ,0x3C,0x22,0x3F},    // ASCII: 63   ?   (Question mark)
{	LIN ,0x3A,0x38,0x00},    // ASCII: 63   ?   (Question mark)
{	CIR_E,0x35,0x11,0xFF},    // ASCII: 63   ?   (Question mark)

{	ELP ,0x49,0x35,0xCF},    // ASCII: 64   @   (At-sign)
{	LIN ,0x44,0x74,0x00},    // ASCII: 64   @   (At-sign)
{	ELP ,0x4A,0x12,0xC7},    // ASCII: 64   @   (At-sign)
{	LIN ,0x5B,0x58,0x00},    // ASCII: 64   @   (At-sign)
{	ELP_E,0x59,0x21,0x70},    // ASCII: 64   @   (At-sign)

{	LIN ,0x14,0x4E,0x00},    // ASCII: 65   A   (Uppercase A)
{	LIN ,0x4E,0x74,0x00},    // ASCII: 65   A   (Uppercase A)
{	LIN_E,0x38,0x58,0x00},    // ASCII: 65   A   (Uppercase A)

{	LIN ,0x34,0x14,0x00},    // ASCII: 66   B   (Uppercase B)
{	LIN ,0x14,0x1E,0x00},    // ASCII: 66   B   (Uppercase B)
{	LIN ,0x1A,0x3A,0x00},    // ASCII: 66   B   (Uppercase B)
{	LIN ,0x1E,0x3E,0x00},    // ASCII: 66   B   (Uppercase B)
{	CIR ,0x3C,0x22,0x3C},    // ASCII: 66   B   (Uppercase B)
{	CIR_E,0x37,0x33,0x3C},    // ASCII: 66   B   (Uppercase B)

{	ELP_E,0x49,0x35,0xE7},    // ASCII: 67   C   (Uppercase C)

{	LIN ,0x34,0x14,0xFF},    // ASCII: 68   D   (Uppercase D)
{	LIN ,0x14,0x1E,0x00},    // ASCII: 68   D   (Uppercase D)
{	LIN ,0x1E,0x3E,0x00},    // ASCII: 68   D   (Uppercase D)
{	ELP_E,0x39,0x35,0x3C},    // ASCII: 68   D   (Uppercase D)

{	LIN ,0x6E,0x1E,0x00},    // ASCII: 69   E   (Uppercase E)
{	LIN ,0x1E,0x14,0x00},    // ASCII: 69   E   (Uppercase E)
{	LIN ,0x19,0x49,0x00},    // ASCII: 69   E   (Uppercase E)
{	LIN_E,0x14,0x64,0x00},    // ASCII: 69   E   (Uppercase E)

{	LIN ,0x6E,0x1E,0x00},    // ASCII: 70   F   (Uppercase F)
{	LIN ,0x1E,0x14,0x00},    // ASCII: 70   F   (Uppercase F)
{	LIN_E,0x19,0x49,0x00},    // ASCII: 70   F   (Uppercase F)

{	LIN ,0x58,0x68,0x00},    // ASCII: 71   G   (Uppercase G)
{	LIN ,0x68,0x64,0x00},    // ASCII: 71   G   (Uppercase G)
{	ELP_E,0x49,0x35,0xE7},    // ASCII: 71   G   (Uppercase G)

{	LIN ,0x1E,0x14,0x00},    // ASCII: 72   H   (Uppercase H)
{	LIN ,0x6E,0x64,0x00},    // ASCII: 72   H   (Uppercase H)
{	LIN_E,0x19,0x69,0x00},    // ASCII: 72   H   (Uppercase H)

{	LIN ,0x3E,0x34,0x00},    // ASCII: 73   I   (Uppercase I)
{	LIN ,0x1E,0x5E,0x00},    // ASCII: 73   I   (Uppercase I)
{	LIN_E,0x14,0x54,0x00},    // ASCII: 73   I   (Uppercase I)

{	CIR ,0x36,0x22,0xF0},    // ASCII: 74   J   (Uppercase J)
{	LIN ,0x56,0x5E,0x00},    // ASCII: 74   J   (Uppercase J)
{	LIN_E,0x3E,0x6E,0x00},    // ASCII: 74   J   (Uppercase J)

{	LIN ,0x14,0x1E,0x00},    // ASCII: 75   K   (Uppercase K)
{	LIN ,0x64,0x19,0x00},    // ASCII: 75   K   (Uppercase K)
{	LIN_E,0x6E,0x19,0x00},    // ASCII: 75   K   (Uppercase K)

{	LIN ,0x64,0x14,0x00},    // ASCII: 76   L   (Uppercase L)
{	LIN_E,0x14,0x1E,0x00},    // ASCII: 76   L   (Uppercase L)

{	LIN ,0x14,0x1E,0x00},    // ASCII: 77   M   (Uppercase M)
{	LIN ,0x74,0x7E,0x00},    // ASCII: 77   M   (Uppercase M)
{	LIN ,0x1E,0x47,0x00},    // ASCII: 77   M   (Uppercase M)
{	LIN_E,0x47,0x7E,0x00},    // ASCII: 77   M   (Uppercase M)

{	LIN ,0x14,0x1E,0x00},    // ASCII: 78   N   (Uppercase N)
{	LIN ,0x6E,0x64,0x00},    // ASCII: 78   N   (Uppercase N)
{	LIN_E,0x1E,0x64,0x00},    // ASCII: 78   N   (Uppercase N)

{	ELP_E,0x49,0x35,0xFF},    // ASCII: 79   O   (Uppercase O)

{	LIN ,0x14,0x1E,0x00},    // ASCII: 80   P   (Uppercase P)
{	LIN ,0x19,0x49,0x00},    // ASCII: 80   P   (Uppercase P)
{	LIN ,0x1E,0x4E,0x00},    // ASCII: 80   P   (Uppercase P)
{	LIN ,0x6C,0x6A,0x3C},    // ASCII: 80   P   (Uppercase P)
{	CIR ,0x4C,0x22,0xC},    // ASCII: 80   P   (Uppercase P)
{	CIR_E,0x4B,0x22,0x30},    // ASCII: 80   P   (Uppercase P)

{	ELP ,0x49,0x35,0xFF},    // ASCII: 81   Q   (Uppercase Q)
{	LIN_E,0x56,0x74,0x00},    // ASCII: 81   Q   (Uppercase Q)

{	LIN ,0x14,0x1E,0x00},    // ASCII: 82   R   (Uppercase R)
{	LIN ,0x19,0x49,0x00},    // ASCII: 82   R   (Uppercase R)
{	LIN ,0x1E,0x4E,0x00},    // ASCII: 82   R   (Uppercase R)
{	LIN ,0x6C,0x6A,0x3C},    // ASCII: 82   R   (Uppercase R)
{	CIR ,0x4C,0x22,0xC},    // ASCII: 82   R   (Uppercase R)
{	CIR ,0x4B,0x22,0x30},    // ASCII: 82   R   (Uppercase R)
{	LIN_E,0x49,0x64,0x00},    // ASCII: 82   R   (Uppercase R)

{	CIR ,0x4C,0x22,0xC7},    // ASCII: 83   S   (Uppercase S)
{	CIR_E,0x47,0x33,0x7C},    // ASCII: 83   S   (Uppercase S)

{	LIN ,0x44,0x4E,0x00},    // ASCII: 84   T   (Uppercase T)
{	LIN ,0x1E,0x4E,0x00},    // ASCII: 84   T   (Uppercase T)
{	LIN_E,0x7E,0x4E,0x00},    // ASCII: 84   T   (Uppercase T)

{	CIR ,0x47,0x33,0xF0},    // ASCII: 85   U   (Uppercase U)
{	LIN ,0x1E,0x17,0x00},    // ASCII: 85   U   (Uppercase U)
{	LIN_E,0x7E,0x77,0x00},    // ASCII: 85   U   (Uppercase U)

{	LIN ,0x1E,0x44,0x00},    // ASCII: 86   V   (Uppercase V)
{	LIN_E,0x44,0x7E,0x00},    // ASCII: 86   V   (Uppercase V)

{	LIN ,0x1E,0x34,0x00},    // ASCII: 87   W   (Uppercase W)
{	LIN ,0x34,0x5A,0x00},    // ASCII: 87   W   (Uppercase W)
{	LIN ,0x5A,0x74,0x00},    // ASCII: 87   W   (Uppercase W)
{	LIN_E,0x74,0x9E,0x00},    // ASCII: 87   W   (Uppercase W)

{	LIN ,0x1E,0x74,0x00},    // ASCII: 88   X   (Uppercase X)
{	LIN_E,0x14,0x7E,0x00},    // ASCII: 88   X   (Uppercase X)

{	LIN ,0x1E,0x49,0x00},    // ASCII: 89   Y   (Uppercase Y)
{	LIN ,0x7E,0x49,0x00},    // ASCII: 89   Y   (Uppercase Y)
{	LIN_E,0x44,0x49,0x00},    // ASCII: 89   Y   (Uppercase Y)

{	LIN ,0x1E,0x7E,0x00},    // ASCII: 90   Z   (Uppercase Z)
{	LIN ,0x7E,0x14,0x00},    // ASCII: 90   Z   (Uppercase Z)
{	LIN_E,0x14,0x74,0x00},    // ASCII: 90   Z   (Uppercase Z)

{	LIN ,0x1E,0x14,0x00},    // ASCII: 91   [   (Opening square bracket)
{	LIN ,0x1E,0x3e,0x00},    // ASCII: 91   [   (Opening square bracket)
{	LIN_E,0x14,0x34,0x00},    // ASCII: 91   [   (Opening square bracket)

{	LIN_E,0x1E,0x64,0x00},    // ASCII: 92   \   (Reverse slant (Backslash))

{	LIN ,0x3E,0x34,0x00},    // ASCII: 93   ]   (Closing square bracket)
{	LIN ,0x1E,0x3E,0x00},    // ASCII: 93   ]   (Closing square bracket)
{	LIN_E,0x14,0x34,0x00},    // ASCII: 93   ]   (Closing square bracket)

{	LIN ,0x19,0x3D,0x00},    // ASCII: 94   ^   (Caret (Circumflex))
{	LIN_E,0x3D,0x59,0x00},    // ASCII: 94   ^   (Caret (Circumflex))

{	LIN_E,0x2,0x72,0x00},    // ASCII: 95   _   (Underscore)

{	LIN_E,0x2D,0x4B,0x00},    // ASCII: 96   `   (Opening single quote)

{	ELP ,0x37,0x23,0xFF},    // ASCII: 97   a   (Lowercase a)
{	LIN_E,0x57,0x54,0x00},    // ASCII: 97   a   (Lowercase a)

{	ELP ,0x37,0x23,0xFF},    // ASCII: 98   b   (Lowercase b)
{	LIN_E,0x1E,0x14,0x00},    // ASCII: 98   b   (Lowercase b)

{	ELP_E,0x37,0x23,0xE7},    // ASCII: 99   c   (Lowercase c)

{	ELP ,0x37,0x23,0xFF},    // ASCII: 100   d   (Lowercase d)
{	LIN_E,0x5E,0x54,0x00},    // ASCII: 100   d   (Lowercase d)

{	ELP ,0x37,0x23,0xEF},    // ASCII: 101   e   (Lowercase e)
{	LIN_E,0x17,0x57,0x00},    // ASCII: 101   e   (Lowercase e)

{	CIR ,0x4C,0x22,0x07},    // ASCII: 102   f   (Lowercase f)
{	LIN ,0x19,0x49,0x00},    // ASCII: 102   f   (Lowercase f)
{	LIN_E,0x24,0x2c,0x00},    // ASCII: 102   f   (Lowercase f)

{	ELP ,0x37,0x23,0xFF},    // ASCII: 103   g   (Lowercase g)
{	LIN ,0x56,0x52,0x00},    // ASCII: 103   g   (Lowercase g)
{	CIR_E,0x32,0x22,0x70},    // ASCII: 103   g   (Lowercase g)

{	LIN ,0x1E,0x14,0x00},    // ASCII: 104   h   (Lowercase h)
{	ELP ,0x38,0x22,0xF},    // ASCII: 104   h   (Lowercase h)
{	LIN_E,0x58,0x54,0x00},    // ASCII: 104   h   (Lowercase h)

{	CIR ,0x2C,0x11,0xFF},    // ASCII: 105   i   (Lowercase i)
{	LIN_E,0x24,0x29,0x00},    // ASCII: 105   i   (Lowercase i)

{	CIR ,0x3C,0x11,0xFF},    // ASCII: 106   j   (Lowercase j)
{	LIN ,0x39,0x33,0x00},    // ASCII: 106   j   (Lowercase j)
{	CIR_E,0x13,0x22,0x30},    // ASCII: 106   j   (Lowercase j)

{	LIN ,0x1E,0x14,0x00},    // ASCII: 107   k   (Lowercase k)
{	LIN ,0x17,0x5A,0x00},    // ASCII: 107   k   (Lowercase k)
{	LIN_E,0x54,0x38,0x00},    // ASCII: 107   k   (Lowercase k)

{	LIN ,0x1E,0x15,0x00},    // ASCII: 108   l   (Lowercase l)
{	LIN_E,0x24,0x15,0x00},    // ASCII: 108   l   (Lowercase l)

{	LIN ,0x0A,0x4,0x00},    // ASCII: 109   m   (Lowercase m)
{	LIN ,0x44,0x48,0x00},    // ASCII: 109   m   (Lowercase m)
{	LIN ,0x84,0x88,0x00},    // ASCII: 109   m   (Lowercase m)
{	CIR ,0x28,0x22,0xF},    // ASCII: 109   m   (Lowercase m)
{	CIR_E,0x68,0x22,0xF},    // ASCII: 109   m   (Lowercase m)

{	LIN ,0x1A,0x14,0x00},    // ASCII: 110   n   (Lowercase n)
{	LIN ,0x54,0x58,0x00},    // ASCII: 110   n   (Lowercase n)
{	CIR_E,0x38,0x22,0xF},    // ASCII: 110   n   (Lowercase n)

{	ELP_E,0x37,0x23,0xFF},    // ASCII: 111   o   (Lowercase o)

{	ELP ,0x37,0x23,0xFF},    // ASCII: 112   p   (Lowercase p)
{	LIN_E,0x18,0x10,0x00},    // ASCII: 112   p   (Lowercase p)

{	ELP ,0x37,0x23,0xFF},    // ASCII: 113   q   (Lowercase q)
{	LIN_E,0x58,0x50,0x00},    // ASCII: 113   q   (Lowercase q)

{	ELP ,0x37,0x23,0x07},    // ASCII: 114   r   (Lowercase r)
{	LIN_E,0x1A,0x14,0x00},    // ASCII: 114   r   (Lowercase r)

{	ELP ,0x39,0x21,0xC7},    // ASCII: 115   s   (Lowercase s)
{	CIR_E,0x36,0x22,0x7C},    // ASCII: 115   s   (Lowercase s)

{	LIN ,0x3E,0x35,0xE3},    // ASCII: 116   t   (Lowercase t)
{	LIN ,0x1B,0x5B,0x3E},    // ASCII: 116   t   (Lowercase t)
{	CIR_E,0x45,0x11,0xC0},    // ASCII: 116   t   (Lowercase t)

{	LIN ,0x1A,0x16,0x00},    // ASCII: 117   u   (Lowercase u)
{	LIN ,0x5A,0x54,0x00},    // ASCII: 117   u   (Lowercase u)
{	CIR_E,0x36,0x22,0xF0},    // ASCII: 117   u   (Lowercase u)

{	LIN ,0x1A,0x34,0xF},    // ASCII: 118   v   (Lowercase v)
{	LIN_E,0x5A,0x34,0x00},    // ASCII: 118   v   (Lowercase v)

{	LIN ,0x1A,0x34,0x00},    // ASCII: 119   w   (Lowercase w)
{	LIN ,0x5A,0x34,0x00},    // ASCII: 119   w   (Lowercase w)
{	LIN ,0x5A,0x74,0x00},    // ASCII: 119   w   (Lowercase w)
{	LIN_E,0x9A,0x74,0x00},    // ASCII: 119   w   (Lowercase w)

{	LIN ,0x1A,0x54,0x00},    // ASCII: 120   x   (Lowercase x)
{	LIN_E,0x14,0x5A,0x00},    // ASCII: 120   x   (Lowercase x)

{	LIN ,0x1A,0x34,0x00},    // ASCII: 121   y   (Lowercase y)
{	LIN_E,0x5A,0x21,0x00},    // ASCII: 121   y   (Lowercase y)

{	LIN ,0x1A,0x4A,0x00},    // ASCII: 122   z   (Lowercase z)
{	LIN ,0x4A,0x14,0x00},    // ASCII: 122   z   (Lowercase z)
{	LIN_E,0x14,0x44,0x00},    // ASCII: 122   z   (Lowercase z)

{	CIR ,0x3D,0x11,0x03},    // ASCII: 123   {   (Opening curly brace)
{	LIN ,0x2D,0x2A,0x30},    // ASCII: 123   {   (Opening curly brace)
{	CIR ,0x1A,0x11,0x30},    // ASCII: 123   {   (Opening curly brace)
{	CIR ,0x18,0x11,0xC},    // ASCII: 123   {   (Opening curly brace)
{	LIN ,0x28,0x25,0x00},    // ASCII: 123   {   (Opening curly brace)
{	CIR_E,0x35,0x11,0xC0},    // ASCII: 123   {   (Opening curly brace)

{	LIN_E,0x2E,0x24,0x00},    // ASCII: 124   |   (Vertical line)

{	CIR ,0x1D,0x11,0xC},    // ASCII: 125   }   (Closing curly brace)
{	LIN ,0x2D,0x2A,0x00},    // ASCII: 125   }   (Closing curly brace)
{	CIR ,0x3A,0x11,0xC0},    // ASCII: 125   }   (Closing curly brace)
{	CIR ,0x38,0x11,0x03},    // ASCII: 125   }   (Closing curly brace)
{	LIN ,0x28,0x25,0x00},    // ASCII: 125   }   (Closing curly brace)
{	CIR_E,0x15,0x11,0x30},    // ASCII: 125   }   (Closing curly brace)

{	CIR ,0x2B,0x11,0xF},    // ASCII: 126   ~   (Tilde (approximate))
{	CIR_E,0x4B,0x11,0xF0},    // ASCII: 126   ~   (Tilde (approximate))

{	REC ,0x0E,0x74,0x00}, // ASCII: 127   DEL   (Delete (rubout), cross-hatch box)
{	LIN ,0x1D,0x65,0x00}, // ASCII: 127   DEL   (Delete (rubout), cross-hatch box)
{	LIN_E,0x15,0x6D,0x00}, // ASCII: 127   DEL   (Delete (rubout), cross-hatch box)

{	CIR ,0x69,0x55,0xE7},    //
{	LIN ,0x9D,0xD9,0x00},    //
{	LIN ,0xD9,0x95,0x00},    //
{	LIN_E,0x39,0x99,0x00},    //

{	CIR ,0x79,0x55,0x7E},    //
{	LIN ,0x4D,0x9,0x00},    //
{	LIN ,0x9,0x45,0x00},    //
{	LIN ,0x49,0xA9,0x00},    //
{	LIN_E,0x7C,0x76,0x00},    //

};

uint16_t Ascii2Font[260] PROGMEM= {	//bits 0-8 = Pointer into VectorFontROM, bits 9-15 = Prop Character Width
Ascii2Font[0] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[1] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[2] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[3] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[4] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[5] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[6] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[7] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[8] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[9] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[10] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[11] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[12] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[13] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[14] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[15] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[16] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[17] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[18] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[19] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[20] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[21] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[22] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[23] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[24] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[25] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[26] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[27] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[28] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[29] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[30] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[31] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[32] = 4608,// ASCII: 32   SP   (Space)
Ascii2Font[33] = 2561,// ASCII: 33   !   (Exclamation mark)
Ascii2Font[34] = 3075,// ASCII: 34   "   (Quotation mark (" in HTML))
Ascii2Font[35] = 4101,// ASCII: 35   #   (Cross hatch (number sign))
Ascii2Font[36] = 3593,// ASCII: 36   $   (Dollar sign)
Ascii2Font[37] = 4108,// ASCII: 37   %   (Percent sign)
Ascii2Font[38] = 4111,// ASCII: 38   &   (Ampersand)
Ascii2Font[39] = 2580,// ASCII: 39     (Closing single quote (apostrophe)) 	Ascii2Font[40] = 2581,// ASCII: 40   (   (Opening parentheses) 	Ascii2Font[41] = 2582,// ASCII: 41   )   (Closing parentheses) 	Ascii2Font[42] = 4631,// ASCII: 42   *   (Asterisk (star, multiply)) 	Ascii2Font[43] = 4635,// ASCII: 43   +   (Plus) 	Ascii2Font[44] = 2589,// ASCII: 44   ,   (Comma) 	Ascii2Font[45] = 4639,// ASCII: 45   -   (Hyphen, dash, minus) 	Ascii2Font[46] = 4640,// ASCII: 46   .   (Period) 	Ascii2Font[47] = 4129,// ASCII: 47   /   (Slant (forward slash, divide)) 	Ascii2Font[48] = 4642,// ASCII: 48   0   (Zero) 	Ascii2Font[49] = 4644,// ASCII: 49   1   (One) 	Ascii2Font[50] = 4647,// ASCII: 50   2   (Two) 	Ascii2Font[51] = 4653,// ASCII: 51   3   (Three) 	Ascii2Font[52] = 4655,// ASCII: 52   4   (Four) 	Ascii2Font[53] = 4658,// ASCII: 53   5   (Five) 	Ascii2Font[54] = 4662,// ASCII: 54   6   (Six) 	Ascii2Font[55] = 4664,// ASCII: 55   7   (Seven) 	Ascii2Font[56] = 4666,// ASCII: 56   8   (Eight) 	Ascii2Font[57] = 4668,// ASCII: 57   9   (Nine) 	Ascii2Font[58] = 3646,// ASCII: 58   :   (Colon) 	Ascii2Font[59] = 3648,// ASCII: 59   ;   (Semicolon) 	Ascii2Font[60] = 3651,// ASCII: 60   <   (Less than sign (&lt; in HTML)) 	Ascii2Font[61] = 3653,// ASCII: 61   =   (Equals sign) 	Ascii2Font[62] = 3143,// ASCII: 62   >   (Greater than sign (&gt; in HTML)) 	Ascii2Font[63] = 3657,// ASCII: 63   ?   (Question mark) 	Ascii2Font[64] = 4684,// ASCII: 64   @   (At-sign) 	Ascii2Font[65] = 4689,// ASCII: 65   A   (Uppercase A) 	Ascii2Font[66] = 4180,// ASCII: 66   B   (Uppercase B) 	Ascii2Font[67] = 4186,// ASCII: 67   C   (Uppercase C) 	Ascii2Font[68] = 4187,// ASCII: 68   D   (Uppercase D) 	Ascii2Font[69] = 4191,// ASCII: 69   E   (Uppercase E) 	Ascii2Font[70] = 4195,// ASCII: 70   F   (Uppercase F) 	Ascii2Font[71] = 4198,// ASCII: 71   G   (Uppercase G) 	Ascii2Font[72] = 4201,// ASCII: 72   H   (Uppercase H) 	Ascii2Font[73] = 3692,// ASCII: 73   I   (Uppercase I) 	Ascii2Font[74] = 4207,// ASCII: 74   J   (Uppercase J) 	Ascii2Font[75] = 4210,// ASCII: 75   K   (Uppercase K) 	Ascii2Font[76] = 4213,// ASCII: 76   L   (Uppercase L) 	Ascii2Font[77] = 4727,// ASCII: 77   M   (Uppercase M) 	Ascii2Font[78] = 4219,// ASCII: 78   N   (Uppercase N) 	Ascii2Font[79] = 4734,// ASCII: 79   O   (Uppercase O) 	Ascii2Font[80] = 4223,// ASCII: 80   P   (Uppercase P) 	Ascii2Font[81] = 4741,// ASCII: 81   Q   (Uppercase Q) 	Ascii2Font[82] = 4231,// ASCII: 82   R   (Uppercase R) 	Ascii2Font[83] = 4238,// ASCII: 83   S   (Uppercase S) 	Ascii2Font[84] = 4752,// ASCII: 84   T   (Uppercase T) 	Ascii2Font[85] = 4755,// ASCII: 85   U   (Uppercase U) 	Ascii2Font[86] = 4758,// ASCII: 86   V   (Uppercase V) 	Ascii2Font[87] = 5784,// ASCII: 87   W   (Uppercase W) 	Ascii2Font[88] = 4764,// ASCII: 88   X   (Uppercase X) 	Ascii2Font[89] = 4766,// ASCII: 89   Y   (Uppercase Y) 	Ascii2Font[90] = 4769,// ASCII: 90   Z   (Uppercase Z) 	Ascii2Font[91] = 2724,// ASCII: 91   [   (Opening square bracket) 	Ascii2Font[92] = 4263,// ASCII: 92   \   (Reverse slant (Backslash)) 	Ascii2Font[93] = 2728,// ASCII: 93   ]   (Closing square bracket) 	Ascii2Font[94] = 3755,// ASCII: 94   ^   (Caret (Circumflex)) 	Ascii2Font[95] = 4269,// ASCII: 95   _   (Underscore) 	Ascii2Font[96] = 3246,// ASCII: 96     (Opening single quote)
Ascii2Font[97] = 3759,// ASCII: 97   a   (Lowercase a)
Ascii2Font[98] = 3761,// ASCII: 98   b   (Lowercase b)
Ascii2Font[99] = 3251,// ASCII: 99   c   (Lowercase c)
Ascii2Font[100] = 3764,// ASCII: 100   d   (Lowercase d)
Ascii2Font[101] = 3766,// ASCII: 101   e   (Lowercase e)
Ascii2Font[102] = 3256,// ASCII: 102   f   (Lowercase f)
Ascii2Font[103] = 3771,// ASCII: 103   g   (Lowercase g)
Ascii2Font[104] = 3774,// ASCII: 104   h   (Lowercase h)
Ascii2Font[105] = 2753,// ASCII: 105   i   (Lowercase i)
Ascii2Font[106] = 2755,// ASCII: 106   j   (Lowercase j)
Ascii2Font[107] = 3782,// ASCII: 107   k   (Lowercase k)
Ascii2Font[108] = 2249,// ASCII: 108   l   (Lowercase l)
Ascii2Font[109] = 5323,// ASCII: 109   m   (Lowercase m)
Ascii2Font[110] = 3792,// ASCII: 110   n   (Lowercase n)
Ascii2Font[111] = 3795,// ASCII: 111   o   (Lowercase o)
Ascii2Font[112] = 3796,// ASCII: 112   p   (Lowercase p)
Ascii2Font[113] = 3798,// ASCII: 113   q   (Lowercase q)
Ascii2Font[114] = 3800,// ASCII: 114   r   (Lowercase r)
Ascii2Font[115] = 3802,// ASCII: 115   s   (Lowercase s)
Ascii2Font[116] = 3804,// ASCII: 116   t   (Lowercase t)
Ascii2Font[117] = 3807,// ASCII: 117   u   (Lowercase u)
Ascii2Font[118] = 3810,// ASCII: 118   v   (Lowercase v)
Ascii2Font[119] = 5860,// ASCII: 119   w   (Lowercase w)
Ascii2Font[120] = 3816,// ASCII: 120   x   (Lowercase x)
Ascii2Font[121] = 3818,// ASCII: 121   y   (Lowercase y)
Ascii2Font[122] = 3308,// ASCII: 122   z   (Lowercase z)
Ascii2Font[123] = 2799,// ASCII: 123   {   (Opening curly brace)
Ascii2Font[124] = 2293,// ASCII: 124   |   (Vertical line)
Ascii2Font[125] = 2806,// ASCII: 125   }   (Closing curly brace)
Ascii2Font[126] = 3836,// ASCII: 126   ~   (Tilde (approximate))
Ascii2Font[127] = 4350,// ASCII: 127   DEL   (Delete (rubout), cross-hatch box)
Ascii2Font[128] = 6913,//
Ascii2Font[129] = 7429,//
Ascii2Font[130] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[131] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[132] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[133] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[134] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[135] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[136] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[137] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[138] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[139] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[140] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[141] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[142] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[143] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[144] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[145] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[146] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[147] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[148] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[149] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[150] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[151] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[152] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[153] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[154] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[155] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[156] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[157] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[158] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[159] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[160] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[161] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[162] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[163] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[164] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[165] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[166] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[167] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[168] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[169] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[170] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[171] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[172] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[173] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[174] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[175] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[176] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[177] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[178] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[179] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[180] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[181] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[182] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[183] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[184] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[185] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[186] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[187] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[188] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[189] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[190] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[191] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[192] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[193] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[194] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[195] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[196] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[197] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[198] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[199] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[200] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[201] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[202] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[203] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[204] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[205] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[206] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[207] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[208] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[209] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[210] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[211] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[212] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[213] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[214] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[215] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[216] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[217] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[218] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[219] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[220] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[221] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[222] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[223] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[224] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[225] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[226] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[227] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[228] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[229] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[230] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[231] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[232] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[233] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[234] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[235] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[236] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[237] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[238] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[239] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[240] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[241] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[242] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[243] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[244] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[245] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[246] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[247] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[248] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[249] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[250] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[251] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[252] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[253] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[254] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol
Ascii2Font[255] = 4860,//No symbol defined in FontROM. As a diagnostic helper, show a TILDE symbol

};

#endif /* VECTORFONTROM_H_ */