// S100 Bus Interface for the Raspberry Pi S100 board (John Monahan S100Computers.com)
//	
//	V0.1			4/4/2022 	Start of display port address working
//	V.1.1			5/1/2022	Start Display RAM	
//	V1.12			5/10/2022	Added console input source.
//	V1.13			6/6/2022	Added monitor commands
//	V1.31			6/24/2022	Added interrupts



// Notes:-
// You can use the printf() function to display feedback text messages in the Eclipse Console window.
// However if they are too rapid/long the S100 system seems to get out of sync.
// They are however very useful for debugging.
//
#include <stdio.h>
// #include <chrono>
// #include <thread>
#include <wiringPi.h>
#include <ctype.h>


//#define FALSE 0
//#define TRUE 1

#define LOW 0
#define HIGH 1
#define ESC  0x1b
#define CR   0x0d
#define LF   0x0a
#define BS   0x08
#define BELL 0x07
#define SP   0x20
#define DEL  0x7f

#define TEST1 FALSE								// Set TRUE to increase from 0 to FFFFF the S100 Bus address lines (Can be monitored with SMB)
#define TEST2 FALSE								// Set TRUE to continuously 0123456789 the S100 Bus console out port (01H)
#define TEST3 FALSE								// Read a keyboard character and print it on screen



										// These three tests are used only initially to check/debug the hardware
#define SerialBoardPresent TRUE							// If serial board for speech synthesis is present
#define IOBYTE  0xEF								// S100 Bus IOBYTE Port on V3 SMB Board
#define CON_OUT_PORT 1								// Port 1 on Propeller driven Console I/O Board
#define CON_IN_PORT 1								// Port 1 on Propeller driven Console I/O Board
#define CON_STATUS_PORT 0							// Port 0 on Propeller driven Console I/O Board
#define BCTL 0xA0								// Serial board speaker CTL port (Zilog SCC Chip)
#define BDTA 0xA2								// Speaker data port
#define RESET_PORT 0xdd								// Port to reset things back to the Z80 bus master

#define DATA_A0	2								// GPIO2 Raspberry Pi Zero Pin 3
#define DATA_A1	3								// GPIO3 Raspberry Pi Zero Pin 5
#define DATA_A2	4								// GPIO4 Raspberry Pi Zero Pin 7
#define DATA_A3 5								// GPIO5 Raspberry Pi Zero Pin 29
#define DATA_A4 6								// GPIO6 Raspberry Pi Zero Pin 31
#define DATA_A5 7								// GPIO7 Raspberry Pi Zero Pin 26
#define DATA_A6 8								// GPIO8 Raspberry Pi Zero Pin 24
#define DATA_A7 9								// GPIO9 Raspberry Pi Zero Pin 21

#define DATA_A8	2								// GPIO2 Raspberry Pi Zero Pin 3
#define DATA_A9	3								// GPIO3 Raspberry Pi Zero Pin 5
#define DATA_A10 4								// GPIO4 Raspberry Pi Zero Pin 7
#define DATA_A11 5								// GPIO5 Raspberry Pi Zero Pin 29
#define DATA_A12 6								// GPIO6 Raspberry Pi Zero Pin 31
#define DATA_A13 7								// GPIO7 Raspberry Pi Zero Pin 26
#define DATA_A14 8								// GPIO8 Raspberry Pi Zero Pin 24
#define DATA_A15 9								// GPIO9 Raspberry Pi Zero Pin 21

#define DATA_A16 2								// GPIO2 Raspberry Pi Zero Pin 3
#define DATA_A17 3								// GPIO3 Raspberry Pi Zero Pin 5
#define DATA_A18 4								// GPIO4 Raspberry Pi Zero Pin 7
#define DATA_A19 5								// GPIO5 Raspberry Pi Zero Pin 29
#define DATA_A20 6								// GPIO6 Raspberry Pi Zero Pin 31
#define DATA_A21 7								// GPIO7 Raspberry Pi Zero Pin 26
#define DATA_A22 8								// GPIO8 Raspberry Pi Zero Pin 24
#define DATA_A23 9								// GPIO9 Raspberry Pi Zero Pin 21

#define DATA_IO0 16								// GPIO16 Raspberry Pi Zero Pin 36
#define DATA_IO1 17								// GPIO17 Raspberry Pi Zero Pin 11
#define DATA_IO2 18								// GPIO18 Raspberry Pi Zero Pin 12
#define DATA_IO3 19								// GPIO19 Raspberry Pi Zero Pin 35
#define DATA_IO4 20								// GPIO20 Raspberry Pi Zero Pin 38
#define DATA_IO5 21								// GPIO21 Raspberry Pi Zero Pin 4
#define DATA_IO6 22								// GPIO22 Raspberry Pi Zero Pin 15
#define DATA_IO7 23								// GPIO23 Raspberry Pi Zero Pin 16

#define DATA_II0 16								// GPIO16 Raspberry Pi Zero Pin 36
#define DATA_II1 17								// GPIO17 Raspberry Pi Zero Pin 11
#define DATA_II2 18								// GPIO18 Raspberry Pi Zero Pin 12
#define DATA_II3 19								// GPIO19 Raspberry Pi Zero Pin 35
#define DATA_II4 20								// GPIO20 Raspberry Pi Zero Pin 38
#define DATA_II5 21								// GPIO21 Raspberry Pi Zero Pin 4
#define DATA_II6 22								// GPIO22 Raspberry Pi Zero Pin 15
#define DATA_II7 23								// GPIO23 Raspberry Pi Zero Pin 16

#define ADD_LOW 25								// GPIO25 Raspberry Pi Zero Pin 22
#define ADD_HIGH 24								// GPIO24 Raspberry Pi Zero Pin 18
#define ADD_EXT 12								// GPIO12 Raspberry Pi Zero Pin 32
#define STATUS 10								// GPIO10 Raspberry Pi Zero Pin 19
#define CTL 0									// GPIO0 Raspberry Pi Zero Pin 27
#define WRITE_DATA 1								// GPIO1 Raspberry Pi Zero Pin 28
#define READ_DATA  13								// GPIO13 Raspberry Pi Zero Pin 33

#define MWRT 2									// GPIO2 Raspberry Pi Zero Pin 3
#define sHLTA 3									// GPIO3 Raspberry Pi Zero Pin 5
#define sINTA 4									// GPIO4 Raspberry Pi Zero Pin 7
#define sWO 5									// GPIO5 Raspberry Pi Zero Pin 29
#define sM1 6									// GPIO6 Raspberry Pi Zero Pin 31
#define sOUT 7									// GPIO7 Raspberry Pi Zero Pin 26
#define sINP 8									// GPIO8 Raspberry Pi Zero Pin 24
#define sMEMR 9									// GPIO8 Raspberry Pi Zero Pin 21

#define pSYNC 2									// GPIO2 Raspberry Pi Zero Pin 3
#define pWR 3									// GPIO3 Raspberry Pi Zero Pin 5
#define pSTVAL 4								// GPIO4 Raspberry Pi Zero Pin 7
#define pDBIN 5									// GPIO5 Raspberry Pi Zero Pin 29
#define sXTRQ 6									// GPIO6 Raspberry Pi Zero Pin 31
#define CLEAR_INT 7								// GPIO7 Raspberry Pi Zero Pin 26
#define S100_INT 15								// GPI15 Raspberry Pi Zero Pin 10
#define INPUT_INT 26								// GPI26 Raspberry Pi Zero Pin 37



#define ACTIVE 11								// GPIO11 Raspberry Pi Zero Pin 32
#define RESET 27								// GPIO27 Raspberry Pi Zero Pin 36
#define CONSOLE_FLAG 14								// GPIO14 Determines if Console input is S100 bus or Raspberry)

int Interrupt_Flag;
int Interrupts_Active;								// If True Interrupts will be detected and flagged
int AbortFlag;
char buffer[1024];
char char_buffer[200];

void EndBusCycle();
char ReadRAM(int);
void WriteRAM(int,int);							
void S100_pSYNC();
void PrintString();
void PutChar(char);
void PutCRLF();
char GetChar();
void QueryPort();
int GetHexValue();								// Return a int HEX value from keyboard
char ReadPort(int);
void WritePort (int, int);							
void Show_RAM_Map();
void GetHex2Values(int*, int*);
void GetHex3Values(int*, int*, int*);
void DisplayRAM();
void DisplayRAM_ASCII();
void Echo();
void S100Signals();
void halt();
void FillRAM();
void MoveRAM();
void SubstituteRAM();

int ConsoleStatusIn();
int ConsoleStatusOut();
int ConsoleDataIn();
void ConsoleDataOut(int);
int SpeakString(char*);
int SpeakOut(char);
int Send_Z80Reset();
void DisplayRAM_ASCII();
void VerifyRAM();
void ShortDelay(int);

void IntSignalOn();
void IntSignalOff();
int CheckForInterrupts();							// If the was an interrupt , if so process it
void ClearInterrupts();
int ReadIntVector();
void Send_sINTA();
void PrintBits(int);
void PrintIntNummber(int);


int main(int argc, char **argv)
{
	wiringPiSetupGpio();
	
	pinMode(DATA_A0, OUTPUT);						//Data Out
	pinMode(DATA_A1, OUTPUT);
	pinMode(DATA_A2, OUTPUT);
	pinMode(DATA_A3, OUTPUT);
	pinMode(DATA_A4, OUTPUT);
	pinMode(DATA_A5, OUTPUT);
	pinMode(DATA_A6, OUTPUT);
	pinMode(DATA_A7, OUTPUT);

	pinMode(DATA_IO0, INPUT);						//Data Out or In  (Default INPUT)
	pinMode(DATA_IO1, INPUT);
	pinMode(DATA_IO2, INPUT);
	pinMode(DATA_IO3, INPUT);
	pinMode(DATA_IO4, INPUT);
	pinMode(DATA_IO5, INPUT);
	pinMode(DATA_IO6, INPUT);
	pinMode(DATA_IO7, INPUT);


	pinMode(ADD_LOW, OUTPUT);						//Latches
	pinMode(ADD_HIGH, OUTPUT);				
	pinMode(ADD_EXT, OUTPUT);				
	pinMode(STATUS, OUTPUT);				
	pinMode(CTL, OUTPUT);				

	pinMode(WRITE_DATA, OUTPUT);				
	pinMode(READ_DATA, OUTPUT);				
	pinMode(INPUT_INT, OUTPUT);				

	pinMode(ACTIVE, INPUT);							//BOARD ACTIVE
	pinMode(RESET, INPUT);							//RESET*
	pinMode(CONSOLE_FLAG, INPUT);						//Determines if Console input is S100 bus or Raspberry)

													//Inactivate all signals
	digitalWrite(ADD_LOW, LOW);						//low Address
	digitalWrite(ADD_HIGH, LOW);						//High Address
	digitalWrite(ADD_EXT, LOW);						//Extended Address
	digitalWrite(STATUS, LOW);						//Status Lines
	digitalWrite(CTL, LOW);							//Control lines
	digitalWrite(WRITE_DATA, LOW);						// WRITE DATA STROBE
	digitalWrite(READ_DATA, LOW);						// READ DATA LATCH

	digitalWrite(INPUT_INT, HIGH);						// S100 Ints

	AbortFlag = 0;


	while(TRUE)								// <-- This is the start of the main Pi software loop.
	{
	int i,Interrupt_k;
	int zzz = 000000;
	char RAM_data,c;
	int value = 0;

	while(TRUE)								// <-- This is the start of the main Pi software loop.
		{
		while(digitalRead(ACTIVE) == TRUE)				//Wait for board to be activated
			{
			printf("Waiting for Pi Zero Board to be active. %d\n",i++);
			if(digitalRead(CONSOLE_FLAG) == TRUE)
				printf("Console = S100\n");
			else	printf("Console = Raspberry\n");
			delay (2000);
			}
		
		EndBusCycle();							// Clear the S100 Bus Status & CTL Lines
		ClearInterrupts();						// And any interrupt

		while(TEST1)                                                    // <--- DIGNOSTIC TEST 
			{
			printf("The S100 bus address lines should increase from 0H to FFFFFH\n");
			for(zzz=0; zzz < 0xFFFFF; zzz++)
				{
				RAM_data = ReadRAM(zzz);				//Set S100 RAM starting address to 0H
				EndBusCycle();						// Also Clear the S100 Bus Status Line
				printf("RAM %6x = %02x \n",(int)zzz, (int)RAM_data);
				}
			printf("\nEnd of RAM test\n");					
			EndBusCycle();  	
			getchar();	
			}


		while(TEST2)
			{
			if(ConsoleStatusIn())
				{
				c = ConsoleDataIn();
				printf("\nConsole I/0 Board c= %04x",c);
				}
			delay(10);
			}


		while(TEST3)							// <--- DIGNOSTIC TEST 3
			{
			printf("The S100 Propeller Console I/0 Board should display 01234556789 continously,\n");
			value = 0x30;
			while(TRUE)
				{
				if(ConsoleStatusOut())
					ConsoleDataOut(value++);
				if(value > 0x39)
					value = 0x30;
				}
			}
		

MenuSignon:	if(digitalRead(CONSOLE_FLAG) == TRUE)
			PrintString("\r\nRaspberry Pi Zero S100 bus menu (V1.31) Console input = S100 bus.\n");
		else 	PrintString("\r\nRaspberry Pi Zero 2W S100 bus menu (V1.31) Console input = Raspberry Pi.\n");

		PrintString ("\r\nA=Memmap      D=Disp RAM     E=Echo       F=Fill RAM    G=S100 Bus\r\n");
		PrintString (    "I Ints On/Off K=Menu         M=Move RAM   Q=Port I/O    T=Type RAM\r\n");
		PrintString (    "S=Subs RAM    V=Verify RAM   W=Speech     Z=To Z80      ESC to abort \r\n");
		PrintString ("\r\n>");

		AbortFlag = FALSE;

		while(TRUE)
			{
			if(Interrupts_Active)
				{	
				Interrupt_k = CheckForInterrupts();					// Was there an interrupt

				if(Interrupt_k)
					{			
					PrintIntNummber(Interrupt_k);
					PrintBits(Interrupt_k);
					ClearInterrupts();						
					printf("\nInterrupt Cleared\n");					
					}
				}

			if(ConsoleStatusIn())
				{
				c = ConsoleDataIn();							// Get menu option
				if(ConsoleStatusOut())
					ConsoleDataOut(c);

				c = toupper(c);
				switch(c)
					{
					case CR:
					case LF:
						break;

					case 'A':
						PrintString("\r\nS100 Bus Memory Map.\r\n");
						printf("\nS100 Bus Memory Map. (Do not move the mouse during this command).\r\n");
						Show_RAM_Map();						// Display Memory map
						PrintString ("\r\n\r\n>");
						break;

					case 'D':
						printf("\nDisplay RAM.\r\n");
						DisplayRAM();						// Print HEX values in RAM
						PrintString ("\r\n\r\n>");
						break;

					case 'E':
						printf("\nEcho (keyboard test).\r\n");
						Echo();							// Echo Console characters
						PrintString ("\r\n\r\n>");
						break;
					
					case 'F':
						printf("\nFill RAM with a byte.\r\n");
						FillRAM();
						PrintString ("\r\n\r\n>");
						break;

					case 'G':
						printf("\nS100 Bus Signals.\r\n");
						S100Signals();						// Move RAM area
						PrintString ("\r\n\r\n>");
						break;

					case 'I':
						if(Interrupts_Active == 0)
							{
							IntSignalOn();						// Detect Interrupts
							PrintString("\r\nS100 Bus Interrupts Detection ON.");
							printf("\nDetect S100 Bus Interrupts On.\r\n");
							}
						else 
							{
							IntSignalOff();						// No Detect Interrupts
							PrintString("\r\nS100 Bus Interrupts Ignored.");
							printf("\nDetect S100 Bus Interrupts Off.\r\n");
							}
						PrintString ("\r\n\r\n>");	
						break;

					case 'K':
						goto MenuSignon;
					
					case 'M':
						printf("\nMove RAM.\r\n");
						MoveRAM();						// Move RAM area
						PrintString ("\r\n\r\n>");
						break;

					case 'Q':
						printf("\nQuery an I/O Port.\r\n");
						QueryPort();						// Input or Output to a port
						PrintString ("\r\n\r\n>");
						break;

					case 'S':
						PrintString("\r\nSubstitute RAM.\r\n ");
						printf("\nSubstitute RAM.\r\n ");
						SubstituteRAM();					// Change RAM bytes one at a time
						PrintString ("\r\n\r\n>");
						break;

					case 'T':
						printf("\nDisplay ASCII in RAM.\r\n ");
						DisplayRAM_ASCII();					// Print ASCII values in RAM
						PrintString ("\r\n\r\n>");
						break;

					case 'V':
						printf("\nVerify two RAM areas are the same.\r\n ");
						VerifyRAM();						// Verify areas of RAM are the same.
						PrintString ("\r\n\r\n>");
						break;

					case 'W':
						printf("\nTest output to Speech Synthesizer.\r\n ");
						SpeakString("This is a test of the Raspberry S 100 Board.$");		// Send test string to speech synthesizer (Note the required '$')
						PrintString("\r\nSpoke:- This is a test of the Raspberry S100 Board.\r\n\n");
						PrintString ("\r\n\r\n>");
						break;
					
					case 'Z':
						PrintString("\r\nRaspberry returning control back to S100 bus master. \r\n>");
						Send_Z80Reset();						
						PrintString ("\r\n\r\n>");
						break;

					default:
						sprintf(buffer,"  '%c' <--- Menu option is not done yet.\r\n\n",c);
						PrintString(buffer);
						PutChar(BELL);
						PrintString ("\r\n\r\n>");
						goto MenuSignon;
					}
				}
			delay(100);
			}
		}
	}
}													// End of main loop
		
/////////////////////////////////////////  SUPPORT ROUTINES ////////////////////////////////////////////////////////////////

void S100Signals()
{
char c;
int repeat,zzz;
int port,value;
int address;

	while(TRUE)
		{
menu2:		PutCRLF();
		PrintString(">>>>>>> S100 Bus Signal Testing Menu <<<<<<<\r\n\n");
		PrintString("A	Turn Off all S100 bus Signals\r\n");
		PrintString("B	Pulse sOUT    (S100 bus High, Pin 45) \r\n");
		PrintString("C	Pulse sMEMR   (S100 bus High, Pin 47) \r\n");
		PrintString("D	Pulse MEMW    (S100 bus High, Pin 68) \r\n");
		PrintString("E	Pulse sINTA   (S100 bus High, Pin 96) \r\n");
		PrintString("F	Pulse pDBIN   (S100 bus High, Pin 78) \r\n");
		PrintString("G	Pulse pWR*    (S100 bus Low,  Pin 77) \r\n");
		PrintString("H	Cycle the Address lines (0-FFFFFH)\r\n");
		PrintString("I	Write to a Port \r\n");
		PrintString("J	Read From a Port \r\n");
		PrintString("K	Write To RAM location    \r\n");
		PrintString("L	Read From RAM location   \r\n");
		PrintString("M	Test Interrupt (S100 V1)\r\n");
		PrintString("ESC to return to the main menu\r\n\n");
		if(AbortFlag)
			{
			PrintString("\r\nCommand Aborted\b\r\n\r\n");
			AbortFlag = FALSE;
			}
		PutChar('>');
		c = toupper(GetChar());
		if(c == ESC)
			return;
		PutChar(c);


		switch(c)
			{
			case 'A':
				PrintString("\r\nAll S100 Bus lines are now turned off.\r\n>");
				EndBusCycle();
				PutCRLF();
				PutCRLF();
				break;

			case 'B':
				printf("Pulse sOUT, Pin 45.\n");
				PrintString("\r\nPulse sOUT, Pin 45.    Enter # of times to pulse (0-FFFFH+CR): ");
				repeat = GetHexValue();
				if(AbortFlag)
					return;

				PrintString("\r\nPulse sOUT test running.\r\n\n");

				while(repeat--)
					{
					digitalWrite(MWRT, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(sHLTA, LOW);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(sINTA, LOW);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(sWO, LOW);			// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sM1, LOW);			// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(sOUT, HIGH);	//HIGH	// GPIO7 Raspberry Pi Zero Pin 26
					digitalWrite(sINP, LOW);		// GPIO8 Raspberry Pi Zero Pin 24
					digitalWrite(sMEMR, LOW);		// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(sOUT, LOW);	//LOW	// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(READ_DATA,HIGH);		// GPIO13 Raspberry Pi Zero Pin 33

					digitalWrite(pSYNC, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(pWR, HIGH);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pSTVAL, HIGH);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(pDBIN, LOW);		// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sXTRQ, HIGH);		// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(CLEAR_INT, HIGH);		// GPIO7 Raspberry Pi Zero Pin 26
	
					digitalWrite(CTL, HIGH);		// GPIO0 Raspberry Pi Zero Pin 27
					digitalWrite(CTL, LOW);			// GPIO0 Raspberry Pi Zero Pin 27	

					EndBusCycle();  
					}
				PrintString("\r\nPulse sOUT test complete.\r\n\n");
				goto menu2;

			case 'C':
				printf("Pulse sMEMR, Pin 47.\n");
				PrintString("\r\nPulse sMEMR, Pin 47.    Enter # of times to pulse (0-FFFFH+CR): ");
				repeat = GetHexValue();
				if(AbortFlag)
					return;
				PrintString("\r\nPulse sMEMR test running.\r\n\n");

				while(repeat--)
					{
					digitalWrite(MWRT, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(sHLTA, LOW);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(sINTA, LOW);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(sWO, LOW);			// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sM1, LOW);			// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(sOUT, LOW);		// GPIO7 Raspberry Pi Zero Pin 26
					digitalWrite(sINP, LOW);		// GPIO8 Raspberry Pi Zero Pin 24
					digitalWrite(sMEMR, HIGH);	//HIGH	// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(sMEMR, LOW);	//LOW	// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(READ_DATA,HIGH);		// GPIO13 Raspberry Pi Zero Pin 33

					digitalWrite(pSYNC, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(pWR, HIGH);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pSTVAL, HIGH);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(pDBIN, LOW);		// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(pDBIN, LOW);		// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sXTRQ, HIGH);		// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(CLEAR_INT, HIGH);		// GPIO7 Raspberry Pi Zero Pin 26
	
					digitalWrite(CTL, HIGH);		// GPIO0 Raspberry Pi Zero Pin 27
					digitalWrite(CTL, LOW);			// GPIO0 Raspberry Pi Zero Pin 27	

					EndBusCycle();  
					}
				PrintString("\r\nPulse sMEMR test complete.\r\n\n");
				goto menu2;

			case 'D':
				printf("Pulse MWRT, Pin 68.\n");
				PrintString("\r\nPulse MWRT, pin 68.    Enter # of times to pulse (0-FFFFH+CR): ");
				repeat = GetHexValue();
				if(AbortFlag)
					return;
				PrintString("\r\nPulse MWRT test running.\r\n\n");
				
				while(repeat--)
					{
					digitalWrite(MWRT, HIGH);	//HIGH	// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(sHLTA, LOW);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(sINTA, LOW);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(sWO, LOW);			// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sM1, LOW);			// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(sOUT, LOW);		// GPIO7 Raspberry Pi Zero Pin 26
					digitalWrite(sINP, LOW);		// GPIO8 Raspberry Pi Zero Pin 24
					digitalWrite(sMEMR, HIGH);		// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(MWRT, LOW);	//LOW	// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(READ_DATA,HIGH);		// GPIO13 Raspberry Pi Zero Pin 33

					digitalWrite(pSYNC, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(pWR, HIGH);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pSTVAL, HIGH);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(pDBIN, LOW);		// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sXTRQ, HIGH);		// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(CLEAR_INT, HIGH);		// GPIO7 Raspberry Pi Zero Pin 26
	
					digitalWrite(CTL, HIGH);		// GPIO0 Raspberry Pi Zero Pin 27
					digitalWrite(CTL, LOW);			// GPIO0 Raspberry Pi Zero Pin 27	

					EndBusCycle();  
					}
				PrintString("\r\nPulse MWRT test complete.\r\n\n");
				goto menu2;

			case 'E':
				printf("Pulse sINP, Pin 46.\n");
				PrintString("\r\nPulse sINP, pin 46.       Enter # of times to pulse (0-FFFFH+CR): ");
				
				while(TRUE)
				repeat = GetHexValue();
				if(AbortFlag)
					return;
				PrintString("\r\nPulse sINP test running.\r\n\n");
				
				while(repeat--)
					{
					digitalWrite(MWRT, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(sHLTA, LOW);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(sINTA, LOW);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(sWO, LOW);			// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sM1, LOW);			// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(sOUT, LOW);		// GPIO7 Raspberry Pi Zero Pin 26
					digitalWrite(sINP, HIGH);	//HIGH	// GPIO8 Raspberry Pi Zero Pin 24
					digitalWrite(sMEMR, HIGH);		// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(sINP, LOW);	//LOW	// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(READ_DATA,HIGH);		// GPIO13 Raspberry Pi Zero Pin 33

					digitalWrite(pSYNC, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(pWR, HIGH);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pSTVAL, HIGH);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(pDBIN, LOW);		// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sXTRQ, HIGH);		// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(CLEAR_INT, HIGH);		// GPIO7 Raspberry Pi Zero Pin 26
	
					digitalWrite(CTL, HIGH);		// GPIO0 Raspberry Pi Zero Pin 27
					digitalWrite(CTL, LOW);			// GPIO0 Raspberry Pi Zero Pin 27	

					EndBusCycle();  
					}
				PrintString("\r\nPulse sINP test complete.\r\n\n");
				goto menu2;

			case 'F':
				printf("Pulse pDBIN, Pin 78.\n");
				PrintString("\r\nPulse pDBIN, pin 78.    Enter # of times to pulse (0-FFFFH+CR): ");
				
				repeat = GetHexValue();
				if(AbortFlag)
					return;
				PrintString("\r\nPulse pDBIN test running.\r\n\n");

				while(repeat--)
					{
					digitalWrite(MWRT, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(sHLTA, LOW);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(sINTA, LOW);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(sWO, LOW);			// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sM1, LOW);			// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(sOUT, LOW);		// GPIO7 Raspberry Pi Zero Pin 26
					digitalWrite(sINP, LOW);		// GPIO8 Raspberry Pi Zero Pin 24
					digitalWrite(sMEMR, HIGH);		// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(READ_DATA,HIGH);		// GPIO13 Raspberry Pi Zero Pin 33

					digitalWrite(pSYNC, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(pWR, LOW);			   // GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pSTVAL, HIGH);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(pDBIN, HIGH);	//HIGH	// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(pDBIN, HIGH);	//HIGH	// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sXTRQ, HIGH);		// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(CLEAR_INT, HIGH);		// GPIO7 Raspberry Pi Zero Pin 26
	
					digitalWrite(CTL, HIGH);		// GPIO0 Raspberry Pi Zero Pin 27
					digitalWrite(CTL, LOW);			// GPIO0 Raspberry Pi Zero Pin 27	

					EndBusCycle();  
					}
				PrintString("\r\nPulse pDBIN test complete.\r\n\n");
				goto menu2;


			case 'G':
				printf("Pulse pWR*, Pin 77.\n");
				PrintString("\r\nPulse pWR*, pin 77.    Enter # of times to pulse (0-FFFFH+CR): ");
				
				repeat = GetHexValue();
				if(AbortFlag)
					return;
				PrintString("\r\nPulse pWR* test running.\r\n\n");
				
				while(repeat--)
					{
					digitalWrite(MWRT, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(sHLTA, LOW);		// GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(sINTA, LOW);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(sWO, LOW);			// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sM1, LOW);			// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(sOUT, LOW);		// GPIO7 Raspberry Pi Zero Pin 26
					digitalWrite(sINP, LOW);		// GPIO8 Raspberry Pi Zero Pin 24
					digitalWrite(sMEMR, HIGH);		// GPIO9 Raspberry Pi Zero Pin 21
	
					digitalWrite(STATUS, HIGH);		// GPIO10 Raspberry Pi Zero Pin 19 (latch status lines)
					digitalWrite(STATUS, LOW);		// GPIO10 Raspberry Pi Zero Pin 19

					digitalWrite(READ_DATA,HIGH);		// GPIO13 Raspberry Pi Zero Pin 33

					digitalWrite(pSYNC, LOW);		// GPIO2 Raspberry Pi Zero Pin 3
					digitalWrite(pWR, LOW);		//LOW   // GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pWR, LOW);		//LOW   // GPIO3 Raspberry Pi Zero Pin 5					
					digitalWrite(pSTVAL, HIGH);		// GPIO4 Raspberry Pi Zero Pin 7					
					digitalWrite(pDBIN, LOW);		// GPIO5 Raspberry Pi Zero Pin 29					
					digitalWrite(sXTRQ, HIGH);		// GPIO6 Raspberry Pi Zero Pin 31			
					digitalWrite(CLEAR_INT, HIGH);		// GPIO7 Raspberry Pi Zero Pin 26
	
					digitalWrite(CTL, HIGH);		// GPIO0 Raspberry Pi Zero Pin 27
					digitalWrite(CTL, LOW);			// GPIO0 Raspberry Pi Zero Pin 27	

					EndBusCycle();  
					}
				PrintString("\r\nPulse pWR*T test complete.\r\n\n");
				goto menu2;


			case 'H':
				printf("Address lines test.\n");
				PrintString("Cycle the Address lines (0-FFFFFH)    Enter ESC to stop test.");
				PrintString("\r\nAddress line test running.....");

				for(zzz=0; zzz < 0xFFFFF; zzz++)
					{
					if(ConsoleStatusIn() == 1)
						{
						if(GetChar() == ESC)
							{
							PrintString("\r\nAddress line test complete.\r\n\n");
							goto menu2;
							}
						}
					c = ReadRAM(zzz);					//Set S100 RAM starting address 
					EndBusCycle();						// Also Clear the S100 Bus Status Line
					}
				PrintString("\r\nAddress lines test complete.\r\n\n");
				goto menu2;

			
			case 'I':
				printf("Test Output to a port.\n");
				PrintString("\r\nEnter Port, Value, # of times to test (XXH,XXH,XXXXXH +CR) ");
				GetHex3Values(&port, &value, &repeat);
				if(AbortFlag)
					return;
				PrintString("\r\nTest Output to a port running.....");
	
				while(repeat--)
					WritePort((int)port,(int)value);
				PrintString("\r\nOutput to a port test complete.\r\n\n");
				goto menu2;

			case 'J':
				printf("Test Input from a port.\n");
				PrintString("\r\nEnter Port, # of times (XXH,XXXXXH +CR) ");
				GetHex2Values(&port,&repeat);
				if(AbortFlag)
					return;
				PrintString("\r\nTest Input from a port running.....");
	
				while(repeat--)
					c = ReadPort((int)port);
				PrintString("\r\nRead from port test complete.\r\n\n");
				goto menu2;

			case 'K':
				printf("Write to a RAM location.\n");
				PrintString("\r\nEnter Address, Value, # of times to test (XXXXXH,XXH,XXXXXH +CR) ");
				GetHex3Values(&address, &value, &repeat);
				if(AbortFlag)
					return;
				PrintString("\r\nWrite to a RAM location test running.....");

				while(repeat--)
					WriteRAM(address,(int)value);
				PrintString("\r\nWrite to RAM test complete.\r\n\n");
				goto menu2;

			case 'L':
				printf("Read from a RAM location.\n");
				PrintString("\r\nEnter RAM Address,for the RAM read, # of times to test (XXXXXH,XXH +CR) ");
				GetHex2Values(&address,&repeat);
				if(AbortFlag)
					return;
				PrintString("\r\nRead from a RAM location test running.....");

				while(repeat--)
					c = ReadRAM(address);
				PrintString("\r\nWrite to RAM test complete.\r\n\n");
				goto menu2;

			case CR:
			case LF:
				PutChar(BELL);
				break;

			default:
				PrintString("\r\nInvalid menu Option.\r\n");
				goto menu2;
			}
		return;
		}
	return;
}

void Echo()
{
	char c;

	PrintString("\r\nWill S100 display keyboard characters (ESC to abort).\r\n");
	while(TRUE)
		{
		c = GetChar();
		if (c == ESC)
			{
			AbortFlag = TRUE;
			PutCRLF();
			return;
			}
		if(isascii(c))
			PutChar(c);
		else PutChar(BELL);
		}
}


/////////////////////////////////// SUBSTITUTE RAM ///////////////////////////
void SubstituteRAM()
{
	int p;
	int c,k = 0;
	char char_buffer[200];

	PrintString("\r\nEnter RAM Location.(XXXXXH+CR) ");
	p = GetHexValue();
	if(AbortFlag)
		return;
	sprintf(char_buffer, "\r\n%05x  ",p);
	PrintString(char_buffer);

	while(TRUE)
		{
		c = ReadRAM(p);
		if(AbortFlag)
			return;
		sprintf(char_buffer, "%02xH-",c);
		PrintString(char_buffer);
		c = GetHexValue();
		if(AbortFlag)
			{
			AbortFlag = FALSE;								// Use ESC just to end the substitution process
			PutCRLF();
			PutCRLF();
			return;
			}
		if((c == CR) || (c == LF))
			{
			PutCRLF();
			PutCRLF();
			return;
			}
		WriteRAM(p++,c);
		PutChar(' ');
		if(k++ == 0x08)
			{
			sprintf(char_buffer, "\r\n%05x  ",p);
			PrintString(char_buffer);
			k = 0;
			}
		}
	return;
}


/////////////////////////////////// MOVE RAM ///////////////////////////

void MoveRAM()
{
	int start;
	int finish;
	int new;
	int p,q,temp;
	char c;

	PrintString("\rMove RAM.(XXXXXH,XXXXXH,XXXXXH+CR) ");
	GetHex3Values(&start, &finish, &new);
	if(AbortFlag)
		return;
	if(finish < start)										// Adjust so the order so first < second
		{
		temp = start;
		start = finish;
		finish = temp;
		}
	PutCRLF();
	printf("\n");
	q = new;

	for(p = start; p <= finish; p++)
		{
		if(ConsoleStatusIn() == 1)
			{
			if(GetChar() == ESC)
				{
				AbortFlag = TRUE;
				return;
				}
			}
		c = ReadRAM(p);										// Add in fill byte
		WriteRAM(q++,c);
		printf("\rAt:%04x",p);
		}
	PrintString("\r\nMove Complete.");
	printf("\nMove Complete.");
	return;
}

/////////////////////////////////// VERIFY RAM ///////////////////////////

void VerifyRAM()
{
int start;
int finish;
int loc2;
int p,q,temp;
char c,k;
int error_flag = 0;

	PrintString("\rVerify RAM bytes. (XXXXXH,XXXXXH,XXXXXH+CR) ");
	GetHex3Values(&start, &finish, &loc2);
	if(AbortFlag)
		return;
	if(finish < start)										// Adjust so the order so first < second
		{
		temp = start;
		start = finish;
		finish = temp;
		}
	PutCRLF();
	q = loc2;

	for(p = start; p <= finish; p++,q++)
		{
		if(ConsoleStatusIn() == 1)
			{
			if(GetChar() == ESC)
				{
				AbortFlag = TRUE;
				return;
				}
			}
		c = ReadRAM(p);										// Add in fill byte
		k = ReadRAM(q);
		if (c != k)
			{
			if(error_flag++ == 6)
				{
				PrintString("\r\nMultiple mismatches. Will stop checking\r\n");
				PutCRLF();
				return;
				}
			sprintf(char_buffer,"\r\nMismatch at %xH (%02x) and %xH (%02x)\r\n",p,c,q,k);
			PrintString(char_buffer);
			PrintString("\r\nVerify Failed.");
			printf("\nVerify failed.");
			return;
			}
		printf("\rAt:%04x",p);
		}
	if(!error_flag)
		{
		PrintString("\r\nNo mismatches were detected.\r\n");
		PrintString("\r\nVerify Complete.");
		printf("\nVerify Complete.");
		return;
		}
}


/////////////////////////////////// FILL RAM ///////////////////////////

void FillRAM()
{
	int start;
	int finish;
	int fill_byte;
	int p,temp;


	PrintString("\rFill RAM. (XXXXXH,XXXXXH,XXH+CR) ");
	GetHex3Values(&start, &finish, &fill_byte);

//	printf("RAM %6x, %6x, %6x\n",(int)start, (int)finish, (int) fill_byte);

	if(AbortFlag)
		return;
	PutCRLF();
	if(finish < start)								// Adjust so the order so first < second
		{
		temp = start;
		start = finish;
		finish = temp;
		}

	for(p = start; p <= finish; p++)
		{
		if(ConsoleStatusIn() == 1)
			{
			if(GetChar() == ESC)
				{
				AbortFlag = TRUE;
				return;
				}
			}
		WriteRAM(p,(int)fill_byte);						// Add in fill byte
		printf("\rAt:%04x",p);
		}
	PrintString("\r\nFill RAM Complete.");
	printf("\nFill Complete.");
	return;
}



/////////////////////////////////// DISPLAY RAM ///////////////////////////

void DisplayRAM()
{
	int start;
	int finish;
	int p,temp;
	int r;
	int i;

	PrintString("\rDisplay RAM. (XXXXXH,XXXXXH+CR) ");
	GetHex2Values(&start, &finish);

	if(AbortFlag)
		return;
	PutCRLF();
	if(finish < start)										// Adjust so the order so first < second
		{
		temp = start;
		start = finish;
		finish = temp;
		}

	sprintf(char_buffer, "\r\n%05x  ",start);
	PrintString(char_buffer);

	for(p = start, i=0; p <= finish; p++,i++)
		{
		if(ConsoleStatusIn() == 1)
			{
			if(GetChar() == ESC)
				{
				AbortFlag = TRUE;
				return;
				}
			}
		r = ReadRAM(p);										// Get HEX value
		r &= 0xff;
		if(i == 0x10)
			{
			sprintf(char_buffer, "\r\n%05x  ",p);
			PrintString(char_buffer);
			i = 0;
			}
		sprintf(char_buffer, "%02x ",r);
		PrintString(char_buffer);
		}
	PutCRLF();
	PutCRLF();
	return;
}


void DisplayRAM_ASCII()
{
int start;
int finish;
int p,temp;
int r;
int i;

	PrintString("\rDisplay RAM ASCII (XXXXXH,XXXXXH+CR) ");
	GetHex2Values(&start, &finish);
	if(AbortFlag)
		return;
	PutCRLF();
	if(finish < start)										// Adjust so the order so first < second
		{
		temp = start;
		start = finish;
		finish = temp;
		}

	sprintf(char_buffer, "\r\n%05x  ",start);
	PrintString(char_buffer);

	for(p = start, i=0; p <= finish; p++,i++)
		{
		if(ConsoleStatusIn() == 1)
			{
			if(GetChar() == ESC)
				{
				AbortFlag = TRUE;
				return;
				}
			}
		r =	ReadRAM(p);										// Get HEX value
		r &= 0xff;
		if(r < ' ')											// Only printable characters
			r = '.';
		if(r > 0x7E)
			r= '.';
		if(i == 0x20)
			{
			sprintf(char_buffer, "\r\n%05x  ",p);
			PrintString(char_buffer);
			i = 0;
			}
		sprintf(char_buffer, "%c",(char)r);
		PrintString(char_buffer);
		}
	PutCRLF();
	PutCRLF();
	return;
}




void Show_RAM_Map()
{
	unsigned int k;
	char c1,c2,c3;

	for(k = 0; k < 0xffffff; k += 0x2000)
		{
		switch (k)
			{
			case 0:
				sprintf(buffer, "\r\n000000 ");
				PrintString(buffer);
				break;
			case 0x0080000:
				sprintf(buffer, "\r\n080000 ");
				PrintString(buffer);
				break;
			case 0x0100000:
			case 0x0180000:
			case 0x0200000:
			case 0x0280000:
			case 0x0300000:
			case 0x0380000:
			case 0x0400000:
			case 0x0480000:
			case 0x0500000:
			case 0x0580000:
			case 0x0600000:
			case 0x0680000:
			case 0x0700000:
			case 0x0780000:
			case 0x0800000:
			case 0x0880000:
			case 0x0900000:
			case 0x0980000:
			case 0x0a00000:
			case 0x0a80000:
			case 0x0b00000:
			case 0x0b80000:
			case 0x0c00000:
			case 0x0c80000:
			case 0x0d00000:
			case 0x0d80000:
			case 0x0e00000:
			case 0x0e80000:
			case 0x0f00000:
			case 0x0f80000:
				sprintf(buffer, "\r\n%4x ",(unsigned int)k);
				PrintString(buffer);
				break;
			}
//		delay(80);
		c1 = ReadRAM(k);									//Read RAM
//		delay(50);
		c2 = !c1;										//Complement it
		WriteRAM(k,c2);
//		delay(80);
		c3 = ReadRAM(k);									//Read RAM again
		if(c3 == c2)										//Must be RAM
			{
//			delay(50);
			WriteRAM(k,c1);									//Put back original data
			PutChar('R');
			}
		else if (c1 != 0xff)
			PutChar('p');									//Must be PROM
		else
			PutChar('.');									//Must be empty

		if(ConsoleStatusIn() == 1)
			{
			if(GetChar() == ESC)
				{
				AbortFlag = TRUE;
				return;
				}
			}
		}
	PutCRLF();
	PutCRLF();
}



void QueryPort()
{
char c;
int port, out_value;
char in_value;

	c = toupper(GetChar());

	switch(c)
		{
		case 'I':
			PrintString("I\r\nQuery In Port ");
			port = GetHexValue();
			if(AbortFlag)
				return;
			in_value = ReadPort(port);
			sprintf(char_buffer," = %02xH \n\n",in_value);		// Print hex values
			PrintString(char_buffer);
			return;

		case 'O':
			PrintString("O\r\nQuery Out Port (XXH,XXH) ");
			GetHex2Values( &port,&out_value);
			if(AbortFlag)
				return;
			WritePort((int)port,(int)out_value);
			PutCRLF();
			return;

		case ESC:
		default:
			AbortFlag = TRUE;
			return;
			break;
		}
}

int Send_Z80Reset()
{
int	in_value;

	in_value = ReadPort(RESET_PORT);
	return in_value;
}


char ReadRAM (int location)							// Set S100 bus address lines A0-A23 to a value (24 bits wide)
{										// Remember location is a int
int i; 
int k=0;

	for(i=0; i < 24; i++)
		{
		k = ((location >> i) & 1);
		if(i==0)
			{		
			if(k)
				digitalWrite(DATA_A0, HIGH);
			else digitalWrite(DATA_A0,LOW);
			}
		else if(i==1)
			{		
			if(k)
				digitalWrite(DATA_A1, HIGH);
			else digitalWrite(DATA_A1,LOW);
			}
		else if(i==2)
			{		
			if(k)
				digitalWrite(DATA_A2, HIGH);
			else digitalWrite(DATA_A2,LOW);
			}
		else if(i==3)
			{		
			if(k)
				digitalWrite(DATA_A3, HIGH);
			else digitalWrite(DATA_A3,LOW);
			}
		else if(i==4)
			{		
			if(k)
				digitalWrite(DATA_A4, HIGH);
			else digitalWrite(DATA_A4,LOW);
			}
		else if(i==5)
			{		
			if(k)
				digitalWrite(DATA_A5, HIGH);
			else digitalWrite(DATA_A5,LOW);
			}
		else if(i==6)
			{		
			if(k)
				digitalWrite(DATA_A6, HIGH);
			else digitalWrite(DATA_A6,LOW);
			}
		else if(i==7)
			{		
			if(k)
				digitalWrite(DATA_A7, HIGH);
			else digitalWrite(DATA_A7,LOW);
			digitalWrite(ADD_LOW, HIGH);				//Latch low address lines
			digitalWrite(ADD_LOW, LOW);	
			}

			

		else if(i==8)
			{		
			if(k)
				digitalWrite(DATA_A8, HIGH);
			else digitalWrite(DATA_A8,LOW);
			}
		else if(i==9)
			{		
			if(k)
				digitalWrite(DATA_A9, HIGH);
			else digitalWrite(DATA_A9,LOW);
			}
		else if(i==10)
			{		
			if(k)
				digitalWrite(DATA_A10, HIGH);
			else digitalWrite(DATA_A10,LOW);
			}
		else if(i==11)
			{		
			if(k)
				digitalWrite(DATA_A11, HIGH);
			else digitalWrite(DATA_A11,LOW);
			}
		else if(i==12)
			{		
			if(k)
				digitalWrite(DATA_A12, HIGH);
			else digitalWrite(DATA_A12,LOW);
			}
		else if(i==13)
			{		
			if(k)
				digitalWrite(DATA_A13, HIGH);
			else digitalWrite(DATA_A13,LOW);
			}
		else if(i==14)
			{		
			if(k)
				digitalWrite(DATA_A14, HIGH);
			else digitalWrite(DATA_A14,LOW);
			}
		else if(i==15)
			{		
			if(k)
				digitalWrite(DATA_A15, HIGH);
			else digitalWrite(DATA_A15,LOW);
			digitalWrite(ADD_HIGH, HIGH);				//Latch high address lines
			digitalWrite(ADD_HIGH, LOW);	
			}

		else if(i==16)
			{		
			if(k)
				digitalWrite(DATA_A16, HIGH);
			else digitalWrite(DATA_A16,LOW);
			}
		else if(i==17)
			{		
			if(k)
				digitalWrite(DATA_A17, HIGH);
			else digitalWrite(DATA_A17,LOW);
			}
		else if(i==18)
			{		
			if(k)
				digitalWrite(DATA_A18, HIGH);
			else digitalWrite(DATA_A18,LOW);
			}
		else if(i==19)
			{		
			if(k)
				digitalWrite(DATA_A19, HIGH);
			else digitalWrite(DATA_A19,LOW);
			}
		else if(i==20)
			{		
			if(k)
				digitalWrite(DATA_A20, HIGH);
			else digitalWrite(DATA_A20,LOW);
			}
		else if(i==21)
			{		
			if(k)
				digitalWrite(DATA_A21, HIGH);
			else digitalWrite(DATA_A21,LOW);
			}
		else if(i==22)
			{		
			if(k)
				digitalWrite(DATA_A22, HIGH);
			else digitalWrite(DATA_A22,LOW);
			}
		else if(i==23)
			{		
			if(k)
			     digitalWrite(DATA_A23, HIGH);
			else digitalWrite(DATA_A23,LOW);
			digitalWrite(ADD_EXT, HIGH);				//Latch extended address lines
			digitalWrite(ADD_EXT, LOW);	
			}
		}
	S100_pSYNC();

	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, LOW);							// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, LOW);						// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, HIGH);			//HIGH			// GPIO9 Raspberry Pi Zero Pin 21
	digitalWrite(sMEMR, HIGH);			//HIGH			// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(READ_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);							// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, HIGH);			//HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(pDBIN, HIGH);			//HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	


	for(i=0; i < 8; i++)							// bits to READ already set
		{
		if (i==0)
			{
			if(digitalRead(DATA_II0))				// GPIO16 Raspberry Pi Zero Pin 36
				k = 1;
			else k = 0;
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(digitalRead(DATA_II1))
				k |= 0b00000010;
			}
		else if (i==2)
			{
			if(digitalRead(DATA_II2))				// GPIO18 Raspberry Pi Zero Pin 12
				k |= 0b00000100;
			}
		else if (i==3)
			{
			if(digitalRead(DATA_II3))				// GPIO19 Raspberry Pi Zero Pin 35
				k |= 0b00001000;
			}
		else if (i==4)
			{
			if(digitalRead(DATA_II4))				// GPIO20 Raspberry Pi Zero Pin 38
				k |= 0b00010000;
			}
		else if (i==5)
			{
			if(digitalRead(DATA_II5))				// GPIO21 Raspberry Pi Zero Pin 4
				k |= 0b00100000;
			}
		else if (i==6)
			{
			if(digitalRead(DATA_II6))				// GPIO22 Raspberry Pi Zero Pin 15
				k |= 0b01000000;
			}
		else if (i==7)
			{
			if(digitalRead(DATA_II7))				// GPIO23 Raspberry Pi Zero Pin 16
				k |= 0b10000000;
			}
		}
	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	
//	printf("\nReadRAM()");	
//	delay(1);
	return (char)k;
}										



void WriteRAM (int location, int value)					// Set S100 bus address lines A0-A23 to a value (24 bits wide)
{										// Remember location is a long
int i; 
int k=0;

	for(i=0; i < 24; i++)
		{
		k = ((location >> i) & 1);
		if(i==0)
			{		
			if(k)
				digitalWrite(DATA_A0, HIGH);
			else digitalWrite(DATA_A0,LOW);
			}
		else if(i==1)
			{		
			if(k)
				digitalWrite(DATA_A1, HIGH);
			else digitalWrite(DATA_A1,LOW);
			}
		else if(i==2)
			{		
			if(k)
				digitalWrite(DATA_A2, HIGH);
			else digitalWrite(DATA_A2,LOW);
			}
		else if(i==3)
			{		
			if(k)
				digitalWrite(DATA_A3, HIGH);
			else digitalWrite(DATA_A3,LOW);
			}
		else if(i==4)
			{		
			if(k)
				digitalWrite(DATA_A4, HIGH);
			else digitalWrite(DATA_A4,LOW);
			}
		else if(i==5)
			{		
			if(k)
				digitalWrite(DATA_A5, HIGH);
			else digitalWrite(DATA_A5,LOW);
			}
		else if(i==6)
			{		
			if(k)
				digitalWrite(DATA_A6, HIGH);
			else digitalWrite(DATA_A6,LOW);
			}
		else if(i==7)
			{		
			if(k)
				digitalWrite(DATA_A7, HIGH);
			else digitalWrite(DATA_A7,LOW);
			digitalWrite(ADD_LOW, HIGH);				//Latch low address lines
			digitalWrite(ADD_LOW, LOW);	
			}

			

		else if(i==8)
			{		
			if(k)
				digitalWrite(DATA_A8, HIGH);
			else digitalWrite(DATA_A8,LOW);
			}
		else if(i==9)
			{		
			if(k)
				digitalWrite(DATA_A9, HIGH);
			else digitalWrite(DATA_A9,LOW);
			}
		else if(i==10)
			{		
			if(k)
				digitalWrite(DATA_A10, HIGH);
			else digitalWrite(DATA_A10,LOW);
			}
		else if(i==11)
			{		
			if(k)
				digitalWrite(DATA_A11, HIGH);
			else digitalWrite(DATA_A11,LOW);
			}
		else if(i==12)
			{		
			if(k)
				digitalWrite(DATA_A12, HIGH);
			else digitalWrite(DATA_A12,LOW);
			}
		else if(i==13)
			{		
			if(k)
				digitalWrite(DATA_A13, HIGH);
			else digitalWrite(DATA_A13,LOW);
			}
		else if(i==14)
			{		
			if(k)
				digitalWrite(DATA_A14, HIGH);
			else digitalWrite(DATA_A14,LOW);
			}
		else if(i==15)
			{		
			if(k)
				digitalWrite(DATA_A15, HIGH);
			else digitalWrite(DATA_A15,LOW);
			digitalWrite(ADD_HIGH, HIGH);				//Latch high address lines
			digitalWrite(ADD_HIGH, LOW);	
			}

		else if(i==16)
			{		
			if(k)
				digitalWrite(DATA_A16, HIGH);
			else digitalWrite(DATA_A16,LOW);
			}
		else if(i==17)
			{		
			if(k)
				digitalWrite(DATA_A17, HIGH);
			else digitalWrite(DATA_A17,LOW);
			}
		else if(i==18)
			{		
			if(k)
				digitalWrite(DATA_A18, HIGH);
			else digitalWrite(DATA_A18,LOW);
			}
		else if(i==19)
			{		
			if(k)
				digitalWrite(DATA_A19, HIGH);
			else digitalWrite(DATA_A19,LOW);
			}
		else if(i==20)
			{		
			if(k)
				digitalWrite(DATA_A20, HIGH);
			else digitalWrite(DATA_A20,LOW);
			}
		else if(i==21)
			{		
			if(k)
				digitalWrite(DATA_A21, HIGH);
			else digitalWrite(DATA_A21,LOW);
			}
		else if(i==22)
			{		
			if(k)
				digitalWrite(DATA_A22, HIGH);
			else digitalWrite(DATA_A22,LOW);
			}
		else if(i==23)
			{		
			if(k)
			     digitalWrite(DATA_A23, HIGH);
			else digitalWrite(DATA_A23,LOW);
			digitalWrite(ADD_EXT, HIGH);				//Latch extended address lines
			digitalWrite(ADD_EXT, LOW);	
			}
		}

	pinMode(DATA_IO0, OUTPUT);						//Data Out (Default was INPUT)
	pinMode(DATA_IO1, OUTPUT);
	pinMode(DATA_IO2, OUTPUT);
	pinMode(DATA_IO3, OUTPUT);
	pinMode(DATA_IO4, OUTPUT);
	pinMode(DATA_IO5, OUTPUT);
	pinMode(DATA_IO6, OUTPUT);
	pinMode(DATA_IO7, OUTPUT);

		
	for(i=0; i < 8; i++)							// Setup data
		{
		k = ((value >> i) & 1);
		if (i==0)
			{
			if(k)
			digitalWrite(DATA_II0,HIGH);
			else digitalWrite(DATA_II0,LOW);
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(k)
				digitalWrite(DATA_II1,HIGH);
			else digitalWrite(DATA_II1,LOW);
			}
		else if (i==2)
			{
			if(k)
				digitalWrite(DATA_II2,HIGH);
			else digitalWrite(DATA_II2,LOW);
			}
		else if (i==3)
			{
			if(k)
				digitalWrite(DATA_II3,HIGH);
			else digitalWrite(DATA_II3,LOW);
			}
		else if (i==4)
			{
			if(k)
				digitalWrite(DATA_II4,HIGH);
			else digitalWrite(DATA_II4,LOW);
			}
		else if (i==5)
			{
			if(k)
				digitalWrite(DATA_II5,HIGH);
			else digitalWrite(DATA_II5,LOW);
			}
		else if (i==6)
			{
			if(k)
				digitalWrite(DATA_II6,HIGH);
			else digitalWrite(DATA_II6,LOW);
			}
		else if (i==7)
			{
			if(k)
				digitalWrite(DATA_II7,HIGH);
			else digitalWrite(DATA_II7,LOW);
			}
		}
	

	S100_pSYNC();

	digitalWrite(MWRT, HIGH);			//HIGH			// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(MWRT, HIGH);			//HIGH			// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, HIGH);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, LOW);						// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(WRITE_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, LOW);				//LOW			// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pWR, LOW);				//LOW			// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	

	digitalWrite(WRITE_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	

	pinMode(DATA_IO0, INPUT);						//Data Out or In  (Default INPUT)
	pinMode(DATA_IO1, INPUT);
	pinMode(DATA_IO2, INPUT);
	pinMode(DATA_IO3, INPUT);
	pinMode(DATA_IO4, INPUT);
	pinMode(DATA_IO5, INPUT);
	pinMode(DATA_IO6, INPUT);
	pinMode(DATA_IO7, INPUT);

//	printf("Write RAM %6x = %02x \n",(int)location, (int)value);
//	delay(1);
	return;	
}



char ReadPort (int location)							// Set S100 bus address lines A0-A15 to a value (24 bits wide)
{										// Remember location is a int
	int i; 
	int k=0;

	for(i=0; i < 16; i++)
		{
		k = ((location >> i) & 1);
		if(i==0)
			{		
			if(k)
				digitalWrite(DATA_A0, HIGH);
			else digitalWrite(DATA_A0,LOW);
			}
		else if(i==1)
			{		
			if(k)
				digitalWrite(DATA_A1, HIGH);
			else digitalWrite(DATA_A1,LOW);
			}
		else if(i==2)
			{		
			if(k)
				digitalWrite(DATA_A2, HIGH);
			else digitalWrite(DATA_A2,LOW);
			}
		else if(i==3)
			{		
			if(k)
				digitalWrite(DATA_A3, HIGH);
			else digitalWrite(DATA_A3,LOW);
			}
		else if(i==4)
			{		
			if(k)
				digitalWrite(DATA_A4, HIGH);
			else digitalWrite(DATA_A4,LOW);
			}
		else if(i==5)
			{		
			if(k)
				digitalWrite(DATA_A5, HIGH);
			else digitalWrite(DATA_A5,LOW);
			}
		else if(i==6)
			{		
			if(k)
				digitalWrite(DATA_A6, HIGH);
			else digitalWrite(DATA_A6,LOW);
			}
		else if(i==7)
			{		
			if(k)
				digitalWrite(DATA_A7, HIGH);
			else digitalWrite(DATA_A7,LOW);
			digitalWrite(ADD_LOW, HIGH);				//Latch low address lines
			digitalWrite(ADD_LOW, LOW);	
			}

			

		else if(i==8)
			{		
			if(k)
				digitalWrite(DATA_A8, HIGH);
			else digitalWrite(DATA_A8,LOW);
			}
		else if(i==9)
			{		
			if(k)
				digitalWrite(DATA_A9, HIGH);
			else digitalWrite(DATA_A9,LOW);
			}
		else if(i==10)
			{		
			if(k)
				digitalWrite(DATA_A10, HIGH);
			else digitalWrite(DATA_A10,LOW);
			}
		else if(i==11)
			{		
			if(k)
				digitalWrite(DATA_A11, HIGH);
			else digitalWrite(DATA_A11,LOW);
			}
		else if(i==12)
			{		
			if(k)
				digitalWrite(DATA_A12, HIGH);
			else digitalWrite(DATA_A12,LOW);
			}
		else if(i==13)
			{		
			if(k)
				digitalWrite(DATA_A13, HIGH);
			else digitalWrite(DATA_A13,LOW);
			}
		else if(i==14)
			{		
			if(k)
				digitalWrite(DATA_A14, HIGH);
			else digitalWrite(DATA_A14,LOW);
			}
		else if(i==15)
			{		
			if(k)
				digitalWrite(DATA_A15, HIGH);
			else digitalWrite(DATA_A15,LOW);
			digitalWrite(ADD_HIGH, HIGH);				//Latch high address lines
			digitalWrite(ADD_HIGH, LOW);	
			}
		}
	S100_pSYNC();
	digitalWrite(READ_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, LOW);							// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, HIGH);		//// HIGH			// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, HIGH);		///// HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	


	for(i=0; i < 8; i++)							// First set direction of Edison bits to READ
		{
		if (i==0)
			{
			if(digitalRead(DATA_II0))				// GPIO16 Raspberry Pi Zero Pin 36
				k = 1;
			else k = 0;
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(digitalRead(DATA_II1))
				k |= 0b00000010;
			}
		else if (i==2)
			{
			if(digitalRead(DATA_II2))				// GPIO18 Raspberry Pi Zero Pin 12
				k |= 0b00000100;
			}
		else if (i==3)
			{
			if(digitalRead(DATA_II3))				// GPIO19 Raspberry Pi Zero Pin 35
				k |= 0b00001000;
			}
		else if (i==4)
			{
			if(digitalRead(DATA_II4))				// GPIO20 Raspberry Pi Zero Pin 38
				k |= 0b00010000;
			}
		else if (i==5)
			{
			if(digitalRead(DATA_II5))				// GPIO21 Raspberry Pi Zero Pin 4
				k |= 0b00100000;
			}
		else if (i==6)
			{
			if(digitalRead(DATA_II6))				// GPIO22 Raspberry Pi Zero Pin 15
				k |= 0b01000000;
			}
		else if (i==7)
			{
			if(digitalRead(DATA_II7))				// GPIO23 Raspberry Pi Zero Pin 16
				k |= 0b10000000;
			}
		}
	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	
//	printf("\nReadPort()");							// not sure why this is required
	return k;								
}	


int ConsoleStatusIn()								// Special fast read Console Status port
{										// Assumes Propeller Consol I/O status port is at 00H
	int i; 
	delay(2);

	digitalWrite(DATA_A0,LOW);
	digitalWrite(DATA_A1,LOW);
	digitalWrite(DATA_A2,LOW);
	digitalWrite(DATA_A3,LOW);
	digitalWrite(DATA_A4,LOW);
	digitalWrite(DATA_A5,LOW);
	digitalWrite(DATA_A6,LOW);
	digitalWrite(DATA_A7,LOW);

	digitalWrite(ADD_LOW, HIGH);						//Latch low address lines
	digitalWrite(ADD_LOW, LOW);	

	digitalWrite(DATA_A8,LOW);
	digitalWrite(DATA_A9,LOW);
	digitalWrite(DATA_A10,LOW);
	digitalWrite(DATA_A11,LOW);
	digitalWrite(DATA_A12,LOW);
	digitalWrite(DATA_A13,LOW);
	digitalWrite(DATA_A14,LOW);
	digitalWrite(DATA_A15,LOW);

	digitalWrite(ADD_HIGH, HIGH);						//Latch high address lines
	digitalWrite(ADD_HIGH, LOW);	
		
	S100_pSYNC();
	
	digitalWrite(READ_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, LOW);							// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, HIGH);		//// HIGH			// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, HIGH);		///// HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	


	i = digitalRead(DATA_II1);						// get bit 1;

	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	
//	printf("\nConsoleStatusIn()");						// not sure why this is required
	return i;								// without it sometimes an incorrect status is sent!
}										


int ConsoleStatusOut()								// Special fast read console status out port
{										// Assumes Propeller Consol I/O status port is at 00H
	int i; 

	digitalWrite(DATA_A0,LOW);
	digitalWrite(DATA_A1,LOW);
	digitalWrite(DATA_A2,LOW);
	digitalWrite(DATA_A3,LOW);
	digitalWrite(DATA_A4,LOW);
	digitalWrite(DATA_A5,LOW);
	digitalWrite(DATA_A6,LOW);
	digitalWrite(DATA_A7,LOW);

	digitalWrite(ADD_LOW, HIGH);						//Latch low address lines
	digitalWrite(ADD_LOW, LOW);	

	digitalWrite(DATA_A8,LOW);
	digitalWrite(DATA_A9,LOW);
	digitalWrite(DATA_A10,LOW);
	digitalWrite(DATA_A11,LOW);
	digitalWrite(DATA_A12,LOW);
	digitalWrite(DATA_A13,LOW);
	digitalWrite(DATA_A14,LOW);
	digitalWrite(DATA_A15,LOW);

	digitalWrite(ADD_HIGH, HIGH);						//Latch high address lines
	digitalWrite(ADD_HIGH, LOW);	
		
	S100_pSYNC();
	
	digitalWrite(READ_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, LOW);							// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, HIGH);		//// HIGH			// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, HIGH);		///// HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	


	i = digitalRead(DATA_II2);						// get bit 1;

	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	
//	printf("\nConsoleStatusIn()");						// not sure why this is required
	return i;								// without it sometimes an incorrect status is sent!
}										


int ConsoleDataIn()								// Special fast read console data read port
{										// Assumes Propeller Consol I/O status port is at 00H
	int i; 
	int k=0;


	digitalWrite(DATA_A0,HIGH);						//S100 bus port 01H
	digitalWrite(DATA_A1,LOW);
	digitalWrite(DATA_A2,LOW);
	digitalWrite(DATA_A3,LOW);
	digitalWrite(DATA_A4,LOW);
	digitalWrite(DATA_A5,LOW);
	digitalWrite(DATA_A6,LOW);
	digitalWrite(DATA_A7,LOW);

	digitalWrite(ADD_LOW, HIGH);						//Latch low address lines
	digitalWrite(ADD_LOW, LOW);	

	digitalWrite(DATA_A8,LOW);
	digitalWrite(DATA_A9,LOW);
	digitalWrite(DATA_A10,LOW);
	digitalWrite(DATA_A11,LOW);
	digitalWrite(DATA_A12,LOW);
	digitalWrite(DATA_A13,LOW);
	digitalWrite(DATA_A14,LOW);
	digitalWrite(DATA_A15,LOW);

	digitalWrite(ADD_HIGH, HIGH);						//Latch high address lines
	digitalWrite(ADD_HIGH, LOW);	
		
	S100_pSYNC();
	
	digitalWrite(READ_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, LOW);							// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, HIGH);		//// HIGH			// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, HIGH);		///// HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	


	for(i=0; i < 8; i++)							// default direction of Pi data bits is to READ
		{
		if (i==0)
			{
			if(digitalRead(DATA_II0))				// GPIO16 Raspberry Pi Zero Pin 36
				k = 1;
			else k = 0;
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(digitalRead(DATA_II1))
				k |= 0b00000010;
			}
		else if (i==2)
			{
			if(digitalRead(DATA_II2))				// GPIO18 Raspberry Pi Zero Pin 12
				k |= 0b00000100;
			}
		else if (i==3)
			{
			if(digitalRead(DATA_II3))				// GPIO19 Raspberry Pi Zero Pin 35
				k |= 0b00001000;
			}
		else if (i==4)
			{
			if(digitalRead(DATA_II4))				// GPIO20 Raspberry Pi Zero Pin 38
				k |= 0b00010000;
			}
		else if (i==5)
			{
			if(digitalRead(DATA_II5))				// GPIO21 Raspberry Pi Zero Pin 4
				k |= 0b00100000;
			}
		else if (i==6)
			{
			if(digitalRead(DATA_II6))				// GPIO22 Raspberry Pi Zero Pin 15
				k |= 0b01000000;
			}
		else if (i==7)
			{
			if(digitalRead(DATA_II7))				// GPIO23 Raspberry Pi Zero Pin 16
				k |= 0b10000000;
			}
		}
	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	
//	printf("\nConsoleDataIn()");						// not sure why this is required
//	delay(1);
	return k;								// without it sometimes an incorrect status is sent!
}										



void WritePort (int location, int value)					// Set S100 bus address lines A0-A15 to a value (24 bits wide)
{										// Remember location is a int
	int i; 
	int k=0;

	for(i=0; i < 16; i++)
		{
		k = ((location >> i) & 1);
		if(i==0)
			{		
			if(k)
				digitalWrite(DATA_A0, HIGH);
			else digitalWrite(DATA_A0,LOW);
			}
		else if(i==1)
			{		
			if(k)
				digitalWrite(DATA_A1, HIGH);
			else digitalWrite(DATA_A1,LOW);
			}
		else if(i==2)
			{		
			if(k)
				digitalWrite(DATA_A2, HIGH);
			else digitalWrite(DATA_A2,LOW);
			}
		else if(i==3)
			{		
			if(k)
				digitalWrite(DATA_A3, HIGH);
			else digitalWrite(DATA_A3,LOW);
			}
		else if(i==4)
			{		
			if(k)
				digitalWrite(DATA_A4, HIGH);
			else digitalWrite(DATA_A4,LOW);
			}
		else if(i==5)
			{		
			if(k)
				digitalWrite(DATA_A5, HIGH);
			else digitalWrite(DATA_A5,LOW);
			}
		else if(i==6)
			{		
			if(k)
				digitalWrite(DATA_A6, HIGH);
			else digitalWrite(DATA_A6,LOW);
			}
		else if(i==7)
			{		
			if(k)
				digitalWrite(DATA_A7, HIGH);
			else digitalWrite(DATA_A7,LOW);
			digitalWrite(ADD_LOW, HIGH);				//Latch low address lines
			digitalWrite(ADD_LOW, LOW);	
			}

			

		else if(i==8)
			{		
			if(k)
				digitalWrite(DATA_A8, HIGH);
			else digitalWrite(DATA_A8,LOW);
			}
		else if(i==9)
			{		
			if(k)
				digitalWrite(DATA_A9, HIGH);
			else digitalWrite(DATA_A9,LOW);
			}
		else if(i==10)
			{		
			if(k)
				digitalWrite(DATA_A10, HIGH);
			else digitalWrite(DATA_A10,LOW);
			}
		else if(i==11)
			{		
			if(k)
				digitalWrite(DATA_A11, HIGH);
			else digitalWrite(DATA_A11,LOW);
			}
		else if(i==12)
			{		
			if(k)
				digitalWrite(DATA_A12, HIGH);
			else digitalWrite(DATA_A12,LOW);
			}
		else if(i==13)
			{		
			if(k)
				digitalWrite(DATA_A13, HIGH);
			else digitalWrite(DATA_A13,LOW);
			}
		else if(i==14)
			{		
			if(k)
				digitalWrite(DATA_A14, HIGH);
			else digitalWrite(DATA_A14,LOW);
			}
		else if(i==15)
			{		
			if(k)
				digitalWrite(DATA_A15, HIGH);
			else digitalWrite(DATA_A15,LOW);
			digitalWrite(ADD_HIGH, HIGH);				//Latch high address lines
			digitalWrite(ADD_HIGH, LOW);	
			}
		}

	pinMode(DATA_IO0, OUTPUT);						//Data Out (Default INPUT)
	pinMode(DATA_IO1, OUTPUT);
	pinMode(DATA_IO2, OUTPUT);
	pinMode(DATA_IO3, OUTPUT);
	pinMode(DATA_IO4, OUTPUT);
	pinMode(DATA_IO5, OUTPUT);
	pinMode(DATA_IO6, OUTPUT);
	pinMode(DATA_IO7, OUTPUT);

	for(i=0; i < 8; i++)							// Setup data
		{
		k = ((value >> i) & 1);
		if (i==0)
			{
			if(k)
			digitalWrite(DATA_II0,HIGH);
			else digitalWrite(DATA_II0,LOW);
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(k)
				digitalWrite(DATA_II1,HIGH);
			else digitalWrite(DATA_II1,LOW);
			}
		else if (i==2)
			{
			if(k)
				digitalWrite(DATA_II2,HIGH);
			else digitalWrite(DATA_II2,LOW);
			}
		else if (i==3)
			{
			if(k)
				digitalWrite(DATA_II3,HIGH);
			else digitalWrite(DATA_II3,LOW);
			}
		else if (i==4)
			{
			if(k)
				digitalWrite(DATA_II4,HIGH);
			else digitalWrite(DATA_II4,LOW);
			}
		else if (i==5)
			{
			if(k)
				digitalWrite(DATA_II5,HIGH);
			else digitalWrite(DATA_II5,LOW);
			}
		else if (i==6)
			{
			if(k)
				digitalWrite(DATA_II6,HIGH);
			else digitalWrite(DATA_II6,LOW);
			}
		else if (i==7)
			{
			if(k)
				digitalWrite(DATA_II7,HIGH);
			else digitalWrite(DATA_II7,LOW);
			}
		}

	S100_pSYNC();
	
	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, HIGH);		///// HIGH			// GPIO5 Raspberry Pi Zero Pin 29 (Note output is invered by U23C)					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, HIGH);		//// HIGH			// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, LOW);						// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(WRITE_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, LOW);			///// LOW			// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);		///// HIGH			// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	

	digitalWrite(WRITE_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	

	pinMode(DATA_IO0, INPUT);						//Data Out or In  (Default INPUT)
	pinMode(DATA_IO1, INPUT);
	pinMode(DATA_IO2, INPUT);
	pinMode(DATA_IO3, INPUT);
	pinMode(DATA_IO4, INPUT);
	pinMode(DATA_IO5, INPUT);
	pinMode(DATA_IO6, INPUT);
	pinMode(DATA_IO7, INPUT);

//	printf("\nWritePort()");						// not sure why this is required
	return;									
}										


void ConsoleDataOut (int value)							// Special fast write to Propeller Console IO board at port 01H
{										
	int i; 
	int k=0;

	digitalWrite(DATA_A0,HIGH);
	digitalWrite(DATA_A1,LOW);
	digitalWrite(DATA_A2,LOW);
	digitalWrite(DATA_A3,LOW);
	digitalWrite(DATA_A4,LOW);
	digitalWrite(DATA_A5,LOW);
	digitalWrite(DATA_A6,LOW);
	digitalWrite(DATA_A7,LOW);

	digitalWrite(ADD_LOW, HIGH);						//Latch low address lines
	digitalWrite(ADD_LOW, LOW);	

	digitalWrite(DATA_A8,LOW);
	digitalWrite(DATA_A9,LOW);
	digitalWrite(DATA_A10,LOW);
	digitalWrite(DATA_A11,LOW);
	digitalWrite(DATA_A12,LOW);
	digitalWrite(DATA_A13,LOW);
	digitalWrite(DATA_A14,LOW);
	digitalWrite(DATA_A15,LOW);

	digitalWrite(ADD_HIGH, HIGH);						//Latch high address lines
	digitalWrite(ADD_HIGH, LOW);	
		

	pinMode(DATA_IO0, OUTPUT);						//Data Out (Default is INPUT)
	pinMode(DATA_IO1, OUTPUT);
	pinMode(DATA_IO2, OUTPUT);
	pinMode(DATA_IO3, OUTPUT);
	pinMode(DATA_IO4, OUTPUT);
	pinMode(DATA_IO5, OUTPUT);
	pinMode(DATA_IO6, OUTPUT);
	pinMode(DATA_IO7, OUTPUT);

	for(i=0; i < 8; i++)							// Setup data
		{
		k = ((value >> i) & 1);
		if (i==0)
			{
			if(k)
			digitalWrite(DATA_II0,HIGH);
			else digitalWrite(DATA_II0,LOW);
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(k)
				digitalWrite(DATA_II1,HIGH);
			else digitalWrite(DATA_II1,LOW);
			}
		else if (i==2)
			{
			if(k)
				digitalWrite(DATA_II2,HIGH);
			else digitalWrite(DATA_II2,LOW);
			}
		else if (i==3)
			{
			if(k)
				digitalWrite(DATA_II3,HIGH);
			else digitalWrite(DATA_II3,LOW);
			}
		else if (i==4)
			{
			if(k)
				digitalWrite(DATA_II4,HIGH);
			else digitalWrite(DATA_II4,LOW);
			}
		else if (i==5)
			{
			if(k)
				digitalWrite(DATA_II5,HIGH);
			else digitalWrite(DATA_II5,LOW);
			}
		else if (i==6)
			{
			if(k)
				digitalWrite(DATA_II6,HIGH);
			else digitalWrite(DATA_II6,LOW);
			}
		else if (i==7)
			{
			if(k)
				digitalWrite(DATA_II7,HIGH);
			else digitalWrite(DATA_II7,LOW);
			}
		}

	S100_pSYNC();
	
	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, HIGH);		/// HIGH			// GPIO5 Raspberry Pi Zero Pin 29 (Note output is inverted by U23C)					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, HIGH);		//// HIGH			// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, LOW);						// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(WRITE_DATA,HIGH);						// GPIO13 Raspberry Pi Zero Pin 33

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, LOW);			///// LOW			// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);		///// HIGH QUICKLY			// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	

	digitalWrite(WRITE_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle();  	

	pinMode(DATA_IO0, INPUT);						//Data Out or In  (Default INPUT)
	pinMode(DATA_IO1, INPUT);
	pinMode(DATA_IO2, INPUT);
	pinMode(DATA_IO3, INPUT);
	pinMode(DATA_IO4, INPUT);
	pinMode(DATA_IO5, INPUT);
	pinMode(DATA_IO6, INPUT);
	pinMode(DATA_IO7, INPUT);

//	printf("\nConsoleDataOut()");						// not sure why this is required
	return;									
}										


///////////////////////////////////////////// INTERRUPTS ///////////////////////////////////////////////////////////////


void IntSignalOn()
{
	Interrupts_Active = TRUE;
}


void IntSignalOff()
{
	Interrupts_Active = FALSE;
}


int CheckForInterrupts()							// If there was an interrupt process it
{
int k = 0;
	if(!digitalRead(S100_INT))						// GPIO15 Raspberry Pi Zero Pin 10
		{
		Send_sINTA();
		k = ReadIntVector();
		}
	return k;								// Return 0 if no interrupt								
}


void ClearInterrupts()								// Clear any pending interrupt
{
	EndBusCycle();  	
	digitalWrite(CLEAR_INT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	
}


void Send_sINTA()
{
	EndBusCycle();  	
	digitalWrite(sINTA, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(STATUS, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(STATUS, LOW);						// GPIO0 Raspberry Pi Zero Pin 27
}


void PrintIntNummber(int IntNumber)
{
int i;

	for(i=0; i < 8; i++)							// default direction of Pi data bits is to READ
		{
		if (i==0)
			{
			if(IntNumber == 0x7F)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(IntNumber == 0xBF)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==2)
			{
			if(IntNumber == 0xDF)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==3)
			{
			if(IntNumber == 0xEF)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==4)
			{
			if(IntNumber == 0xF7)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==5)
			{
			if(IntNumber == 0xFB)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==6)
			{
			if(IntNumber == 0xFD)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		if (i==7)
			{
			if(IntNumber == 0xFE)				
				PutChar(0x30);
			else PutChar(0x31);
			}
		}
	PutChar(0x0D);
	PutChar(0x0A);
	PutChar(0x3E);								// '>'
}

int ReadIntVector()
{
int i,k;

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, HIGH);		///// HIGH			// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27	

	digitalWrite(INPUT_INT, LOW);		///// LOW for U33		// GPIO14 Raspberry Pi Zero Pin 8

	for(i=0; i < 8; i++)							// default direction of Pi data bits is to READ
		{
		if (i==0)
			{
			if(digitalRead(DATA_II0))				// GPIO16 Raspberry Pi Zero Pin 36
				k = 1;
			else k = 0;
			}
		else if (i==1)
			{							// GPIO17 Raspberry Pi Zero Pin 11
			if(digitalRead(DATA_II1))
				k |= 0b00000010;
			}
		else if (i==2)
			{
			if(digitalRead(DATA_II2))				// GPIO18 Raspberry Pi Zero Pin 12
				k |= 0b00000100;
			}
		else if (i==3)
			{
			if(digitalRead(DATA_II3))				// GPIO19 Raspberry Pi Zero Pin 35
				k |= 0b00001000;
			}
		else if (i==4)
			{
			if(digitalRead(DATA_II4))				// GPIO20 Raspberry Pi Zero Pin 38
				k |= 0b00010000;
			}
		else if (i==5)
			{
			if(digitalRead(DATA_II5))				// GPIO21 Raspberry Pi Zero Pin 4
				k |= 0b00100000;
			}
		else if (i==6)
			{
			if(digitalRead(DATA_II6))				// GPIO22 Raspberry Pi Zero Pin 15
				k |= 0b01000000;
			}
		else if (i==7)
			{
			if(digitalRead(DATA_II7))				// GPIO23 Raspberry Pi Zero Pin 16
				k |= 0b10000000;
			}
		}
	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	EndBusCycle(); 
	return k;
}



int SpeakString(char* SpeechString)
{
	char p;

	while((p = *SpeechString++) != '$')
		{
		if((p < SP ) || (p == DEL) || (p == '\n') || (p == '\r'))	// Send speech if CR as well
			break;
		if(!SpeakOut(p))
			return 0;
		}
	if(!SpeakOut(CR))
		return 0;
	return 1;
}



int SpeakOut(char character)
{
	int c;
	int retry_count = 100;

	if(ReadPort(BCTL) == 0xff)
		{
		PrintString("Speech Synthesizer not detected.\r\n");
		PutChar(BELL);
		return 0;
		}
	while(retry_count--)
		{
		c = ReadPort(BCTL);
		if((c &= 0x04))
			{
			WritePort(BDTA, character);
			return 1;
			}
		}
	PrintString("Speech Synthesizer timed out.\r\n");
	PutChar(BELL);
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void EndBusCycle()										// Clear all S100 Bus signals
{
	digitalWrite(READ_DATA, LOW);						// GPIO13 Raspberry Pi Zero Pin 33
	digitalWrite(WRITE_DATA, LOW);						// GPIO1 Raspberry Pi Zero Pin 28

	digitalWrite(MWRT, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(sHLTA, LOW);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(sINTA, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(sWO, LOW);							// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sM1, LOW);							// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(sOUT, LOW);						// GPIO7 Raspberry Pi Zero Pin 26
	digitalWrite(sINP, LOW);						// GPIO8 Raspberry Pi Zero Pin 24
	digitalWrite(sMEMR, LOW);						// GPIO9 Raspberry Pi Zero Pin 21
	
	digitalWrite(STATUS, HIGH);						// GPIO10 Raspberry Pi Zero Pin 19
	digitalWrite(STATUS, LOW);						// GPIO10 Raspberry Pi Zero Pin 19

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27
	delay(1);
}



void S100_pSYNC()								// Pulse pSYNC high & (pSTVAL Low)
{
	digitalWrite(pSYNC, HIGH);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, LOW);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27

	digitalWrite(pSYNC, LOW);						// GPIO2 Raspberry Pi Zero Pin 3
	digitalWrite(pWR, HIGH);						// GPIO3 Raspberry Pi Zero Pin 5					
	digitalWrite(pSTVAL, HIGH);						// GPIO4 Raspberry Pi Zero Pin 7					
	digitalWrite(pDBIN, LOW);						// GPIO5 Raspberry Pi Zero Pin 29					
	digitalWrite(sXTRQ, HIGH);						// GPIO6 Raspberry Pi Zero Pin 31			
	digitalWrite(CLEAR_INT, HIGH);						// GPIO7 Raspberry Pi Zero Pin 26
	
	digitalWrite(CTL, HIGH);						// GPIO0 Raspberry Pi Zero Pin 27
	digitalWrite(CTL, LOW);							// GPIO0 Raspberry Pi Zero Pin 27
}



//////////////////////////////////////// LOW LEVEL SUPPORT ROUTINRS ////////////////////////////////////////////////////////////


void GetHex3Values(int* first, int* second, int* third)
{
	*first = 0;
	*second = 0;
	*third = 0;

	*first = GetHexValue();
	if(AbortFlag)
		return;
	*second = GetHexValue();
	if(AbortFlag)
		return;
	*third = GetHexValue();
	return;
}


void GetHex2Values(int* first, int* second)
{
	*first = 0;
	*second = 0;

//	printf("\nAt GetHexValue().............................");

	*first = GetHexValue();
	if(AbortFlag)
		return;
	*second = GetHexValue();
	return;
}


int GetHexValue()								// Return a int HEX value from keyboard
{
	int i = 0;
	char c;
	int hex_value;
	
	AbortFlag = FALSE;

	while(TRUE)
		{
		c = GetChar();
		c = toupper(c);

		switch(c)
			{
			case ESC:
				AbortFlag = TRUE;
				return(0);
			case ' ':
			case ',':
			case '\n':
			case '\r':
				if(c == ',')
					PutChar(c);
				char_buffer[i++] = 0;
				sscanf(char_buffer,"%x",&hex_value);
				return(hex_value);
				break;
			case ':':
			case ';':
			case '<':
			case '=':
			case '>':
			case '?':
			case '@':
				PutChar(BELL);
				continue;
			default:
				if((c < '0') || (c > 'F' ))
					{
					PutChar(BELL);
					continue;
					}
				char_buffer[i++] = c;
				PutChar(c);
			}
		}
}

void PrintBits(int val)
{
	for(unsigned int mask = 0x80; mask; mask >>= 1)
		printf("%d", !!(mask & val));
}


void PrintString(char* TextString)						// Print a string on the console
{
	while(*TextString)
		{
		char p;
		p = *TextString++;
		PutChar(p);
		}
}

void PutCRLF()									// Send CR + LF to Console
{
	PutChar(CR);
	PutChar(LF);
}


void PutChar(char c)								// Print a character on the Console
{
	if(digitalRead(CONSOLE_FLAG) == TRUE)					// TRUE if S100 bus keyboard input
		{
		while(!ConsoleStatusOut())					// Wait until status returns 0
		delay(10);
		ConsoleDataOut(c);
		delay(10);
		}
	else printf("%x",c);
}

char GetChar()
{	
	char c;
	int i;

	if(digitalRead(CONSOLE_FLAG) == TRUE)					// TRUE if S100 bus keyboard input
		{
		while (TRUE)							// Wait until something is there.
			{
			i = ConsoleStatusIn();
			delay(10);
			if(i == 1)
				{
				c = ConsoleDataIn();
				return (c);
				}
			}	
		}
	else	c = getchar();							//Data from USB keyboard
	return(c);
}


void halt()
{	
	while(TRUE);
}
