From d4aa2c749c80ea61c247411a917b536f448cc90c Mon Sep 17 00:00:00 2001 From: Tim Gopaul Date: Sun, 19 Feb 2023 23:12:15 -0700 Subject: [PATCH] Add the commands gameSaveMemory and gameLoadMemory The main loop will now have three input modes CommandMode DataMode - to direct Hex-file format input to the shadow memory gameDataMode - to direct Hex-file format input to game memory --- CommandLine.h | 40 +++++++- PinBallMemoryPort20230205.ino | 176 ++++++++++++++-------------------- 2 files changed, 111 insertions(+), 105 deletions(-) diff --git a/CommandLine.h b/CommandLine.h index 3f4e97e..a92c7dc 100644 --- a/CommandLine.h +++ b/CommandLine.h @@ -109,8 +109,10 @@ void dumpRange(unsigned int addrStart, unsigned int addrCount); void gameDumpRange(unsigned int addrStart, unsigned int addrCount); void dumpBuffRange(unsigned int addrStart, unsigned int addrCount); void saveMemory(unsigned int addrStart, unsigned int addrCount); +void gameSaveMemory(unsigned int addrStart, unsigned int addrCount); void testMemory(unsigned int addrStart, unsigned int addrCount); void loadMemory(); +void gameLoadMemory(); int helpText(); void testMemory(unsigned int addrStart, unsigned int addrCount, int testLoops); @@ -153,6 +155,8 @@ const char *testMemoryCommandToken = "testmemory"; // destructive test const char *gameReadCommandToken = "gameread"; // read address ignore const char *gameWriteCommandToken = "gamewrite"; // write address byte const char *gameDumpCommandToken = "gameDump"; // Dumps game memory from starting address with byte count +const char *gameSaveMemoryCommandToken = "gamesave"; // creates Intel Hex output from ram range. +const char *gameLoadMemoryCommandToken = "gameload"; // takes an Intel Hex formatted line and writes it to RAM const char *BusyFaultCountToken = "busyfaultcount"; // displays the accumulative count of the busy interrupts const char *ShadowFaultCountToken = "shadowfaultcount"; // displays the accumulative count of the busy interrupts @@ -346,6 +350,21 @@ int loadMemoryCommand() { return 0; } +// ***** gameSaveMemoryCommand ***** +int gameSaveMemoryCommand() { + unsigned int addrStart = readNumber(); + unsigned int addrCount = readNumber(); + + gameSaveMemory(addrStart, addrCount); + return 0; +} + +// ***** gameLoadMemoryCommand ***** +int gameLoadMemoryCommand() { + gameLoadMemory(); + return 0; +} + // ***** Help Text ***** int helpCommand() { helpText(); @@ -401,7 +420,7 @@ int testMemoryCommand(){ DoMyHexLine */ bool -DoMyHexLine(char * HexLine) { +DoMyHexLine(char * HexLine, int writeMode) { // char * endOfFile = ":00000001FF"; //For Intel Hex file transfer a the final line must match.. to switch to command inputMode @@ -451,7 +470,16 @@ DoMyHexLine(char * HexLine) { int address = addrStart; HLBIndex =4; //Data starts at index 4 in HexLineBytes for(unsigned int i = 0; i < hexCount; i++){ - writeAddress( address++, HexLineBytes[HLBIndex++]); + switch(writeMode){ + case DataMode: + writeAddress( address++, HexLineBytes[HLBIndex++]); + break; + case gameDataMode: + gameWriteAddress( address++, HexLineBytes[HLBIndex++]); + break; + default: + break; + } } } @@ -531,7 +559,13 @@ DoMyCommand(char * commandLine) { else if (strcasecmp(ptrToCommandName, loadMemoryCommandToken) == 0) { //Modify here result = loadMemoryCommand(); } - + else if (strcasecmp(ptrToCommandName, gameSaveMemoryCommandToken) == 0) { //Modify here + result = saveMemoryCommand(); + Serial.println(); + } + else if (strcasecmp(ptrToCommandName, gameLoadMemoryCommandToken) == 0) { //Modify here + result = loadMemoryCommand(); + } else if (strcasecmp(ptrToCommandName, helpCommandToken) == 0) { //Modify here result = helpText(); } diff --git a/PinBallMemoryPort20230205.ino b/PinBallMemoryPort20230205.ino index 5b4f01e..7d75a79 100644 --- a/PinBallMemoryPort20230205.ino +++ b/PinBallMemoryPort20230205.ino @@ -1,7 +1,7 @@ // Protospace is running code version PinBallMemoryPort20230201 // The next version of code starts dated 2023 02 05 // -// 2023-02-18 Tim Gopaul, trouble getting PCINT30 working. changed to interruptPin = PIN_PD2 which gives digitalPinToInterrupt(interruptPin) as 0 +// 2023-02-18 Tim Gopaul, trouble getting PCINT30 working. changed to interrup Pin = PIN_PD2 which gives digitalPinToInterrupt(interruptPin) as 0 // 2023-02-14 Tim Gopaul, attach an interrupt low edge to pin 20 PD6 PCINT30 // connect interrupt to _BusyRight to indicate the Pinball live memory was issued a wait.. which likey corrupted game ram // What to do. ..maybe save high score to portal then restart the pinball machine or issue a warning to the LCD screen @@ -55,14 +55,17 @@ /* email address in distributed copies, and let me know about any bugs */ //#define _DEBUG_ -#define MAXHEXLINE 16 //for Hex record length -const int ramSize = 2048; -#define CommandMode 1 //inputMode will flip between command and data entry -#define DataMode 2 // 2023-01-09 Tim Gopaul -int inputMode = 1; -#include "CommandLine.h" + +#define MAXHEXLINE 16 // for Hex record length +const int ramSize = 2048; // don't change this without also defining address bits PORTC has limited bits available + +#define CommandMode 1 // inputMode will flip between command and data entry, commands defined in CommandLine.h file +#define DataMode 2 // 2023-01-09 Tim Gopaul.. in DataMode the UART stream is read as an Intel HEX file +#define gameDataMode 3 // 2023-01-09 Tim Gopaul.. in DataMode the UART stream is read as an Intel HEX file + +int inputMode = CommandMode; // on startup the input is waiting for commands // PORTB alternates between input and output for use by data read and write. #define DDRB_Output DDRB = B11111111 // all 1's is output for Atmega1284 PortB to write to IDC-7132 RAM @@ -119,52 +122,55 @@ void ramBufferInit(){ } } + // ****** helpText ***** int helpText(){ - Serial.println(">**********************************"); - Serial.println(">* *"); + Serial.println(">****************************************"); + Serial.println(">* *"); Serial.printf(">* Compile Date: %s\n", __DATE__ ); Serial.printf(">* Compile Time: %s\n", __TIME__ ); - Serial.println(">* *"); - Serial.println(">* Untility program to read RAM *"); - Serial.println(">* Tim Gopaul for Protospace *"); - Serial.println(">* *"); - Serial.println(">* Enter numbers as baseTen,or *"); - Serial.println(">* Enter as 0xNN for hex format *"); - Serial.println(">* *"); - Serial.println(">* add integer integer *"); - Serial.println(">* sub integer integer *"); - Serial.println(">* read address *"); - Serial.println(">* write address databyte *"); - Serial.println(">* dump start count *"); - Serial.println(">* dumpBuffer start count *"); - Serial.println(">* fill start count databyte *"); - Serial.println(">* fillRandom start count *"); - Serial.println(">* save startAddress count *"); - Serial.println(">* load Intelhex record line *"); - Serial.println(">* testMemory start count *"); - Serial.println(">* *"); - Serial.println(">* game commands work directly *"); - Serial.println(">* Game RAM. *"); - Serial.println(">* Use only when pinball off *"); - Serial.println(">* *"); - Serial.println(">* gameRead address *"); - Serial.println(">* gameWrite address databyte *"); - Serial.println(">* gameDump start count *"); - Serial.println(">* *"); + Serial.println(">* *"); + Serial.println(">* Untility program to read RAM *"); + Serial.println(">* Tim Gopaul for Protospace *"); + Serial.println(">* *"); + Serial.println(">* Enter numbers as baseTen,or *"); + Serial.println(">* Enter as 0xNN for hex format *"); + Serial.println(">* *"); + Serial.println(">* add integer integer *"); + Serial.println(">* sub integer integer *"); + Serial.println(">* read address *"); + Serial.println(">* write address databyte *"); + Serial.println(">* dump start count *"); + Serial.println(">* dumpBuffer start count *"); + Serial.println(">* fill start count databyte *"); + Serial.println(">* fillRandom start count *"); + Serial.println(">* save startAddress count *"); + Serial.println(">* load Intelhex record line *"); + Serial.println(">* testMemory start count *"); + Serial.println(">* *"); + Serial.println(">* game commands work directly *"); + Serial.println(">* Game RAM. *"); + Serial.println(">* Use only when pinball off *"); + Serial.println(">* *"); + Serial.println(">* gameRead address *"); + Serial.println(">* gameWrite address databyte *"); + Serial.println(">* gameDump start count *"); + Serial.println(">* *"); - Serial.println(">* *"); - Serial.println(">* Enter numbers as decimal or *"); - Serial.println(">* 0xNN 0X55 for HEX *"); - Serial.println(">* *"); - Serial.println(">* BusyFaultCount will give the *"); - Serial.println(">* count of Busy Interruptes *"); - Serial.println(">* *"); - Serial.println(">* ShadowFaultCount gives the *"); - Serial.println(">* count of Shadow Busy *"); - Serial.println(">* Interruptes *"); - Serial.println(">* *"); - Serial.println(">**********************************"); + Serial.println(">* *"); + Serial.println(">* Enter numbers as decimal or *"); + Serial.println(">* 0xNN 0X55 for HEX *"); + Serial.println(">* *"); + Serial.println(">* BusyFaultCount will give the *"); + Serial.println(">* count of Busy Interruptes *"); + Serial.println(">* PIN_PD2 IRQ 0 *"); + Serial.println(">* *"); + Serial.println(">* ShadowFaultCount gives the *"); + Serial.println(">* count of Shadow Busy Interruptes *"); + Serial.println(">* PIN_PD3 IRQ 1 *"); + Serial.println(">* *"); + Serial.println(">* *"); + Serial.println(">****************************************"); Serial.println(); return(0); } @@ -173,6 +179,7 @@ unsigned int smaller( unsigned int a, unsigned int b){ return (b < a) ? b : a; } +#include "CommandLine.h" // ****** writeAddress ***** void writeAddress(unsigned int address, byte dataByte){ @@ -371,66 +378,16 @@ void gameRefreshBuffer(unsigned int addrStart, unsigned int addrCount){ } -} // void refreshBuffer(unsigned int addrStart, unsigned int addrCount){ - - -// ***** dumpBuffRange ***** -void gameDumpBuffRange(unsigned int addrStart, unsigned int addrCount){ - - gameRefreshBuffer(addrStart, addrCount); // The buffer has read the memory now dump to the screen - - unsigned int addrEnd = smaller((addrStart + addrCount), ramSize); //bounds check on gameRamBuffer index - - Serial.printf("> Dump Buffer: 0x%04X: To Address Data: 0x%04X: \n", addrStart, addrEnd -1); - if ((addrStart % 16) != 0) Serial.printf("\n0x%04X: ", addrStart); - for (unsigned int address = addrStart; address < addrEnd; address++) { - - if ((address % 16) == 0) Serial.printf("\n0x%04X: ", address); - Serial.printf("0x%02X ", gameRamBuffer[address]); - - #ifdef _DEBUG_ - Serial.printf("Reading Address: 0x%04X: Data: 0x%02X\n", address, gameRamBuffer[address]); - #endif - } - Serial.println(); - Serial.println(); - -//Dump the buffer displaying contents as ASCII if printable - - Serial.printf("> Dump Buffer ASCII: 0x%04X: To Address Data: 0x%04X: \n", addrStart, addrEnd -1); - Serial.println(); - - //creat column headings from low address nibble - Serial.print(" "); //print some leading space - for (unsigned int i = 0; i <= 0x0f;i++) - Serial.printf( "%1X ",i); - - if ((addrStart % 16) != 0) Serial.printf("\n0x%04X: ", addrStart); - for (unsigned int address = addrStart; address < addrEnd ; address++) { - - if ((address % 16) == 0) Serial.printf("\n0x%04X: ", address); - if (isPrintable(gameRamBuffer[address])) - Serial.printf("%c ", (char)gameRamBuffer[address]); - else - Serial.printf("%c ", ' '); - } - - Serial.println(); - Serial.println(); - - //call the saveMemory function to see if it displays the buffer properly - gameSaveMemory(addrStart, addrCount); - -} //void gameDumpBuffRange(unsigned int addrStart, unsigned int addrCount) - +} // void game refreshBuffer(unsigned int addrStart, unsigned int addrCount){ +// 2023-02-19 Tim Gopaul remove the GameDumpBuffer that accesses the live RAM // ***** gameSaveMemory ***** void gameSaveMemory(unsigned int addrStart, unsigned int addrCount){ gameRefreshBuffer(addrStart, addrCount); //This will copy the physical IDC7132 RAM to the Atmel gameRamBuffer[2048] - // Only refresh the buffer with the range of bytes needed to avoid contention. + // Only refresh the buffer with the range of bytes needed (to avoid contention.) // copy the RAM memory to a buffer array before processing output // Global array is used gameRamBuffer[2048] @@ -743,6 +700,18 @@ void loadMemory(){ // .. add CTRL-C and esc as ways to terminate the input } +// ***** gameLoadMemory ***** +void gameLoadMemory(){ + Serial.printf("> Waiting for Intel Hex input records or end of file record :00000001FF\n"); + inputMode = gameDataMode; + // This flips to DataMode so that main loop will dispatch input to build Intel Hex input line + // once in DataMode the main loop will add characters to a buffer line until enter is pressed Linefeed. + // in DataMode each line is interpretted as an Intel Hex record.. type 01 and type 00 supported + // to leave DataMode the input must receive the Intel Hex end of file record. + // :00000001FF + // .. add CTRL-C and esc as ways to terminate the input +} + // ***** compareBuffer ***** void compareBuffer( unsigned int addrStart, unsigned int addrCount){ @@ -861,7 +830,10 @@ bool received = getCommandLineFromSerialPort(CommandLine); //global Command DoMyCommand(CommandLine); break; case DataMode: - DoMyHexLine(CommandLine); + DoMyHexLine(CommandLine, DataMode); + break; + case gameDataMode: + DoMyHexLine(CommandLine, gameDataMode); break; default: break;