14 #include <gdk/gdkkeysyms.h> 23 #include <sys/signal.h> 25 #include <sys/types.h> 33 #include <unordered_map> 94 unsigned char dataA[8] = {0};
101 unsigned char dataB[8] = {0};
108 unsigned int misc = 0xFFFFFFFF;
114 enum class BoardInstruction : unsigned char {
147 inline unsigned char operator|(BoardInstruction l,
unsigned char r) {
148 return static_cast<unsigned char>(l) | r;
174 unsigned int address;
224 const uint32_t s_address,
225 int*
const increment,
226 const int currentAddressI,
227 unsigned char (*memdata)[52]);
232 inline void sendChar(
unsigned char);
238 inline const int getChar(
unsigned char*);
254 const unsigned char*
const);
258 unsigned char*
const,
270 const char*
const pathToS,
271 const char*
const pathToKMD) {
276 execlp(pathToBin,
"aasm",
"-lk", pathToKMD, pathToS, (
char*)0);
297 sendChar(static_cast<unsigned char>(BoardInstruction::START));
308 sendChar(static_cast<unsigned char>(BoardInstruction::CONTINUE));
316 sendChar(static_cast<unsigned char>(BoardInstruction::STOP));
323 sendChar(static_cast<unsigned char>(BoardInstruction::RESET));
332 unsigned int wordA = 0, wordB = 0;
347 if (((wordA >> i) & 1) != 0) {
362 int temp = (~wordA) & wordB;
385 switch (board_state) {
386 case ClientState::RUNNING_SWI:
388 case ClientState::RUNNING:
390 case ClientState::STEPPING:
392 case ClientState::MEMFAULT:
394 case ClientState::BUSY:
396 case ClientState::FINISHED:
398 case ClientState::BREAKPOINT:
401 return ClientState::NORMAL;
415 std::array<std::string, 16> ret;
418 for (
long unsigned int i = 0; i < ret.size(); i++) {
430 unsigned char string[256];
431 unsigned char length = 1;
433 std::string output(
"");
436 sendChar(static_cast<unsigned char>(BoardInstruction::FR_READ));
444 string[length] =
'\0';
445 output.append((
char*)
string);
459 unsigned int key_pressed = val;
460 unsigned char res = 0;
463 switch (key_pressed) {
465 case GDK_KEY_KP_Enter:
468 case GDK_KEY_BackSpace:
487 key_pressed = key_pressed - GDK_KEY_KP_0 +
'0';
492 case GDK_KEY_KP_Subtract:
495 case GDK_KEY_KP_Multiply:
498 case GDK_KEY_KP_Divide:
501 case GDK_KEY_KP_Decimal:
509 if (((key_pressed >=
' ') && (key_pressed <= 0x7F)) ||
510 (key_pressed ==
'\n') || (key_pressed ==
'\b') || (key_pressed ==
'\t') ||
511 (key_pressed ==
'\a')) {
512 sendChar(static_cast<unsigned char>(
513 BoardInstruction::FR_WRITE));
531 const uint32_t s_address) {
532 constexpr
int count = 13;
537 unsigned char* p = (
unsigned char*)&s_address;
539 currentAddressS[0] &= -4;
542 unsigned char memdata[bytecount];
543 sendChar(static_cast<unsigned char>(BoardInstruction::GET_MEM));
549 bool firstFlag =
false;
552 if (source.
pStart != NULL) {
554 while ((src != NULL) && ((src->
address < s_address) || not src->
hasData)) {
564 while ((src != NULL) && not src->
hasData) {
572 std::array<Jimulator::MemoryValues, 13> readValues;
576 for (
long unsigned int i = 0; i < readValues.size(); i++) {
578 unsigned int currentAddressI =
580 readValues[i].address = currentAddressI;
581 readValues[i].hex = std::string(
"00000000");
582 readValues[i].disassembly = std::string(
"...");
585 if (src != NULL && currentAddressI == src->
address) {
586 readValues[i].disassembly =
587 std::regex_replace(std::string(src->
text), std::regex(
";.*$"),
"");
589 currentAddressI, &memdata);
591 firstFlag =
moveSrc(firstFlag, &src);
597 auto iter = bps.find(readValues[i].address);
598 if (iter != bps.end()) {
599 readValues[i].breakpoint =
true;
622 for (; (((v >> i) & 1) == 0); i++)
692 unsigned int* wordB) {
693 sendChar(static_cast<unsigned char>(BoardInstruction::BP_GET));
694 return not((
getNBytes((
int*)wordA, 4) != 4) ||
706 if ((*src)->next != NULL) {
707 (*src) = (*src)->next;
716 }
while (((*src) != NULL) && not(*src)->hasData);
735 const uint32_t s_address,
736 int*
const increment,
737 const int currentAddressI,
738 unsigned char (*memdata)[52]) {
739 std::string hex =
"";
742 if ((*src)->dataSize[i] > 0) {
743 char spaces[5] = {0};
748 &((*memdata)[currentAddressI - s_address + *increment]));
751 for (; j < (*src)->dataSize[i]; j++) {
762 *increment = *increment + (*src)->dataSize[i];
780 sendChar(static_cast<unsigned char>(BoardInstruction::BP_READ));
805 const unsigned char*
const s2) {
821 unsigned char* source,
822 unsigned char* dest) {
835 sendChar(static_cast<unsigned char>(BoardInstruction::BP_SET));
849 sendChar(static_cast<unsigned char>(BoardInstruction::BP_WRITE));
864 struct pollfd pollfd;
866 pollfd.events = POLLOUT;
870 std::cout <<
"Client system not responding!\n";
875 std::cout <<
"Pipe write error!\n";
897 unsigned char buffer[n];
900 for (
auto& c : buffer) {
918 struct pollfd pollfd;
921 pollfd.events = POLLIN;
936 if (reply_count == 0) {
941 if (reply_count < 0) {
945 reply_total += reply_count;
946 length -= reply_count;
958 inline const int getChar(
unsigned char* data) {
980 for (
int i = 0; i < numberOfReceivedBytes; i++) {
984 return numberOfReceivedBytes;
992 unsigned char clientStatus = 0;
997 sendChar(static_cast<unsigned char>(BoardInstruction::WOT_U_DO));
999 if (
getChar(&clientStatus) != 1 ||
1002 std::cout <<
"board not responding\n";
1003 return ClientState::BROKEN;
1009 return static_cast<ClientState
>(clientStatus);
1019 unsigned char data[64];
1021 sendChar(static_cast<unsigned char>(BoardInstruction::GET_REG));
1026 std::array<unsigned char, 64> ret;
1027 std::copy(std::begin(data), std::end(data), std::begin(ret));
1042 unsigned char*
const v,
1043 const bool prepend0x) {
1044 std::stringstream ss;
1051 ss << std::setfill(
'0') << std::setw(2) << std::uppercase << std::hex
1095 if (temp >= 0x100) {
1110 unsigned int addr) {
1111 if (src == NULL || src ==
nullptr) {
1115 unsigned int diff = src->
address - addr;
1130 return 4 - (addr % 4);
1144 std::unordered_map<u_int32_t, bool> breakpointAddresses;
1145 unsigned int wordA, wordB;
1152 if (((wordA >> i) & 1) != 0) {
1157 breakpointAddresses.insert({addr,
true});
1165 return breakpointAddresses;
1180 while (old != NULL) {
1181 if (old->
text != NULL) {
1197 if ((character >=
'0') && (character <=
'9')) {
1198 return character -
'0';
1199 }
else if ((character >=
'A') && (character <=
'F')) {
1200 return character -
'A' + 10;
1201 }
else if ((character >=
'a') && (character <=
'f')) {
1202 return character -
'a' + 10;
1217 unsigned int*
const n) {
1218 while ((*c ==
' ') || (*c ==
'\t')) {
1222 int j = 0, value = 0;
1225 value = (value << 4) | digit;
1240 for (k = 1; k < j; k = k << 1) {
1279 unsigned char*
const value,
1296 int byteTotal, textLength;
1303 if (system(
"pidof -x jimulator > /dev/null")) {
1304 std::cout <<
"Jimulator is not running!\n";
1309 FILE* komodoSource = fopen(pathToKMD,
"r");
1310 if (komodoSource == NULL) {
1311 std::cout <<
"Source could not be opened!\n";
1315 bool hasOldAddress =
false;
1318 while (not feof(komodoSource)) {
1319 unsigned int address = 0;
1321 char c = getc(komodoSource);
1325 hasOldAddress =
false;
1341 c = getc(komodoSource);
1349 if (dSize[j] == 0) {
1353 byteTotal = byteTotal + dSize[j];
1356 oldAddress = address + byteTotal;
1357 hasOldAddress =
true;
1360 else if (hasOldAddress) {
1361 address = oldAddress;
1367 while ((c !=
';') && (c !=
'\n') && not feof(komodoSource)) {
1368 c = getc(komodoSource);
1373 c = getc(komodoSource);
1375 c = getc(komodoSource);
1381 while ((c !=
'\n') && not feof(komodoSource) &&
1383 buffer[textLength++] = c;
1384 c = getc(komodoSource);
1387 buffer[textLength++] =
'\0';
1389 currentLine->
address = address;
1393 currentLine->
dataSize[j] = dSize[j];
1396 if ((currentLine->
dataSize[j] > 0) &&
1398 unsigned char addr[4], data[4];
1400 for (
int i = 0; i < 4; i++) {
1404 for (
int i = 0; i < currentLine->
dataSize[j]; i++) {
1413 byteTotal = byteTotal + currentLine->
dataSize[j];
1414 currentLine->
hasData = (byteTotal != 0);
1425 byteTotal = byteTotal - currentLine->
dataSize[j];
1427 dSize[j] = currentLine->
dataSize[j];
1433 std::cout <<
"OVERFLOW " << dSize[0] <<
" " << dSize[1] <<
" " 1434 << dSize[2] <<
" " << dSize[3] <<
" " << byteTotal
1439 currentLine->
text = g_new(
char, textLength);
1440 for (
int j = 0; j < textLength; j++) {
1441 currentLine->
text[j] = buffer[j];
1447 while ((temp1 != NULL) && (address >= temp1->
address)) {
1449 temp1 = temp1->
next;
1452 currentLine->
next = temp1;
1453 currentLine->
prev = temp2;
1455 if (temp1 != NULL) {
1456 temp1->
prev = currentLine;
1458 source.
pEnd = currentLine;
1461 if (temp2 != NULL) {
1462 temp2->
next = currentLine;
1464 source.
pStart = currentLine;
1471 while ((c !=
'\n') && not feof(komodoSource)) {
1472 c = getc(komodoSource);
1476 fclose(komodoSource);
const std::string integerArrayToHexString(int, unsigned char *const, const bool=false)
Converts an array of integers into a formatted hexadecimal string.
unsigned int address
The address of the source line.
Describes an entire file of a .kmd sourceFile.
void sendCharArray(int, unsigned char *)
Sends an array of characters to Jimulator.
unsigned char operator|(BoardInstruction l, unsigned char r)
Performing an or between a BoardInstruction and an unsigned char.
constexpr void copyStringLiterals(int, unsigned char *, unsigned char *)
Copy one string literal into another string literal.
constexpr int IN_POLL_TIMEOUT
The maximum amount of time to wait after sending input to the pipes.
bool hasData
A flag that indicates that the line stores internal data or not.
char * text
Text, as read from the source file.
SourceFileLine * pEnd
The last line in a source file.
void resetJimulator()
Reset the emulators running.
const int getCharArray(int, unsigned char *)
reads an array of characters from Jimulator.
unsigned char addressB[ADDRESS_BUS_WIDTH]
A secondary address for a breakpoint.
const std::string generateMemoryHex(SourceFileLine **src, const uint32_t s_address, int *const increment, const int currentAddressI, unsigned char(*memdata)[52])
Get the hex values from the memory data.
const bool getBreakpointStatus(unsigned int *, unsigned int *)
Gets the status of breakpoints from within Jimulator.
unsigned char dataA[8]
Data associated with the breakpoint.
constexpr const unsigned int boardTranslateMemsize(const int size)
Converts a provided memory size into a Jimulator legal memory size.
void compileJimulator(std::string pathToBin, const char *const pathToS, const char *const pathToKMD)
Runs pathToS through the associated compiler binary, and outputs a .kmd file at pathToKMD.
constexpr int SOURCE_FIELD_COUNT
The number of fields that can be used in a source file.
unsigned int misc
Miscellaneous information associated with the breakpoint.
unsigned char addressA[ADDRESS_BUS_WIDTH]
The address of the breakpoint.
const bool setBreakpoint(const uint32_t address)
Sets a breakpoint.
int writeToJimulator
Stores the file descriptor used for writing to Jimulator.
constexpr int SOURCE_BYTE_COUNT
The maximum number of bytes that can be read from a source file.
constexpr int OUT_POLL_TIMEOUT
The maximum amount of time to wait waiting for output from the pipes.
Describes a single line of a .kmd file.
void setBreakpointStatus(unsigned int, unsigned int)
Overwrites some breakpoint information into Jimulator.
constexpr const int rotateRight1Byte(const int val)
Rotates an integers bits to the right by 1 byte.
unsigned char dataB[8]
Data associated with the secondary breakpoint.
constexpr const char getLeastSignificantByte(const int)
Get the least significant byte out of an integer - if little endian, get the most signficant byte...
constexpr int SOURCE_TEXT_LENGTH
The maximum length of a line in a source file.
constexpr int ADDRESS_BUS_WIDTH
The width of Jimulators internal address bus.
void sendChar(unsigned char)
Sends a singular character to Jimulator.
constexpr const int disassembleSourceFile(SourceFileLine *, unsigned int)
Calculates the difference between the current address to display and the next address that needs to b...
void pauseJimulator()
Pauses the emulator running.
SourceFileLine * pStart
The first line in a source file.
const int getNBytes(int *, int)
Reads n bytes of data from Jimulator.
const std::unordered_map< u_int32_t, bool > getAllBreakpoints()
Reads all of the breakpoints from Jimulator into a map that can be indexed by address. The address is the key, with a boolean as the value to form a pair. However the boolean is redundant - since the address is the key, if you lookup an address in the map and it is present, you know that a breakpoint was found there.
constexpr const int checkHexCharacter(const char character)
Check if the passed character represents a legal hex digit.
int dataValue[4]
Stores the data values.
constexpr const int numericStringSubtraction(const unsigned char *const, const unsigned char *const)
Takes two string literals of equal length which represent string forms of integers - for example...
constexpr const bool moveSrc(bool firstFlag, SourceFileLine **src)
Steps any given source line to the next valid source line.
sourceFile source
The source file that is currently loaded into Jimulator.
void startJimulator(const int steps)
Commences running the emulator.
constexpr const int rotateLeft1Byte(const int val)
Rotates an integers bits to the left by 1 byte.
const bool sendTerminalInputToJimulator(const unsigned int val)
Sends terminal information to Jimulator.
void setBreakpointDefinition(unsigned int, BreakpointInfo *)
Writes a new breakpoint into the breakpoint list.
constexpr int MAX_NUMBER_OF_BREAKPOINTS
The maximum number of breakpoints within the application.
const std::array< unsigned char, 64 > readRegistersIntoArray()
Gets serialized bit data from the board that represents 16 register values - 15 general purpose regis...
const bool loadJimulator(const char *const pathToKMD)
Clears the existing source object and loads the file at pathToKMD into Jimulator. ...
int readFromJimulator
Stores the file descriptor used for reading from Jimulator.
const int getChar(unsigned char *)
Reads a singular character from Jimulator.
void flushSourceFile()
removes all of the old references to the previous file.
constexpr const int getNextFreeBreakpoint(const int)
Gets the index of the next free breakpoint from Jimulators internal breakpoint list.
The header file associated with the jimulatorInterface.c file - specifies functions which can be acce...
SourceFileLine * next
The next line of the overall source file.
SourceFileLine * prev
The previous line of the overall source file.
const ClientState getBoardStatus()
Gets a code that indicates the internal state of Jimulator.
void continueJimulator()
Continues running Jimulator.
constexpr void numericStringAndIntAddition(unsigned char *const, int)
Takes a string representation of an integer - for example, the string {'5' '7' '2'} representing the ...
const bool readSourceFile(const char *const)
Reads the source of the file pointer to by pathToKMD.
std::array< Jimulator::MemoryValues, 13 > getJimulatorMemoryValues(const uint32_t s_address_int)
Get the memory values from Jimulator, starting to s_address.
constexpr const int readNumberFromFile(FILE *const f, char *const c, unsigned int *const n)
Reads a n from a string of text in the .kmd file.
int compilerCommunication[2]
The pipe that handles communication between the compiler process and KoMo2.
const bool getBreakpointDefinition(unsigned int, BreakpointInfo *)
Reads a breakpoint definition for use by the breakpoints callbacks.
void boardSetMemory(unsigned char *const address, unsigned char *const value, const int size)
Sets a memory value of a given address to a new value. This code is LEGACY. It used to run with a che...
Contains the information read from Jimulator about a given breakpoint.
const ClientState checkBoardState()
Check the state of the board - logs what it is doing.
constexpr const int numericStringToInt(int, const unsigned char *const)
Takes a string literals which represent a string form of an integer - for example, the number 5 represented as the string {'5'}, or the number 327 represented as the string {'3', '2', '7'} - and returns the value represented as an int. For example: Input string {'8', '1', '8'} will result in the output 818.
const std::string getJimulatorTerminalMessages()
Reads for messages from Jimulator, to display in the terminal output.
void sendNBytes(int, int)
Writes n bytes of data to Jimulator.
const std::array< std::string, 16 > getJimulatorRegisterValues()
Queries a register in Jimulator to get it's current value.
int dataSize[4]
Stores the size of the data fields.