franta-hg@0: #include franta-hg@0: #include franta-hg@0: #include franta-hg@0: #include franta-hg@0: #include franta-hg@20: #include franta-hg@6: #include franta-hg@6: #include franta-hg@6: franta-hg@19: #include "types.h" franta-hg@20: #include "memory.h" franta-hg@20: #include "Command.h" franta-hg@20: #include "commands/Goto.h" franta-hg@19: franta-hg@0: using namespace std; franta-hg@0: franta-hg@12: // TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ? franta-hg@12: franta-hg@13: /** franta-hg@13: * Skip to the given address. franta-hg@13: * parameter: address_t franta-hg@13: */ franta-hg@5: const command_t CMD_GOTO = 0x70; franta-hg@13: franta-hg@13: /** franta-hg@15: * Compare values on two addresses and go to one of given three addresses. franta-hg@15: * parameter: address_t a franta-hg@15: * parameter: address_t b franta-hg@15: * parameter: address_t GOTO target when a == b franta-hg@15: * parameter: address_t GOTO target when a > b franta-hg@15: * parameter: address_t GOTO target when a < b franta-hg@15: */ franta-hg@15: const command_t CMD_GOTO_COMPARE = 0x80; franta-hg@15: franta-hg@15: /** franta-hg@13: * Wait given time in ms. franta-hg@13: * parameter: sleep_t franta-hg@13: */ franta-hg@5: const command_t CMD_SLEEP = 0xFF; franta-hg@13: franta-hg@13: /** franta-hg@13: * Set RGB LED color. franta-hg@13: * parameter: led_t LED number franta-hg@13: * parameter: color_t red franta-hg@13: * parameter: color_t green franta-hg@13: * parameter: color_t blue franta-hg@13: */ franta-hg@10: const command_t CMD_COLOR = 0xAA; franta-hg@13: franta-hg@13: /** franta-hg@13: * Stop program. franta-hg@13: */ franta-hg@5: const command_t CMD_END = 0xED; franta-hg@13: franta-hg@13: /** franta-hg@14: * Increase value at given address franta-hg@14: * parameter: address_t franta-hg@14: */ franta-hg@14: const command_t CMD_INCREMENT = 0x11; franta-hg@14: franta-hg@14: /** franta-hg@14: * Decrease value at given address franta-hg@14: * parameter: address_t franta-hg@14: */ franta-hg@14: const command_t CMD_DECREMENT = 0x12; franta-hg@14: franta-hg@14: /** franta-hg@13: * Placeholder for unsupported command. franta-hg@13: * Just for testing. franta-hg@13: */ franta-hg@13: const command_t CMD_INVALID = 0x1; franta-hg@0: franta-hg@15: // TODO: more commands, better numbers franta-hg@15: franta-hg@0: int main(int argc, char* argv[]) { franta-hg@0: franta-hg@0: setlocale(LC_ALL, ""); franta-hg@0: franta-hg@17: octet_t * memory = (octet_t*) malloc(MEMORY_SIZE); franta-hg@0: franta-hg@16: // Sample program / data: franta-hg@16: // TODO: load bytes from file, stdin, serial port, network… franta-hg@2: { franta-hg@2: address_t a = 0; franta-hg@9: write(memory, a, CMD_SLEEP); franta-hg@9: write(memory, a, 255); franta-hg@9: write(memory, a, CMD_SLEEP); franta-hg@9: write(memory, a, 10); franta-hg@9: write(memory, a, CMD_SLEEP); franta-hg@9: write(memory, a, 255); franta-hg@9: write(memory, a, CMD_GOTO); franta-hg@15: write(memory, a, a + sizeof (address_t) + 2 * sizeof (command_t)); franta-hg@11: write(memory, a, CMD_INVALID); franta-hg@11: write(memory, a, CMD_INVALID); franta-hg@9: write(memory, a, CMD_SLEEP); franta-hg@9: write(memory, a, 255); franta-hg@10: write(memory, a, CMD_COLOR); franta-hg@13: write(memory, a, 23); franta-hg@11: write(memory, a, 0); franta-hg@11: write(memory, a, 200); franta-hg@11: write(memory, a, 255); franta-hg@14: write(memory, a, CMD_INCREMENT); franta-hg@14: write(memory, a, 0); franta-hg@14: write(memory, a, CMD_DECREMENT); franta-hg@14: write(memory, a, 0); franta-hg@15: write(memory, a, CMD_GOTO_COMPARE); franta-hg@15: write(memory, a, 0); franta-hg@15: write(memory, a, 0 + sizeof (command_t) + sizeof (sleep_t)); franta-hg@15: write(memory, a, a - 3 * sizeof (address_t) - 2 * sizeof (command_t)); franta-hg@15: write(memory, a, 0); franta-hg@15: write(memory, a, a + sizeof (address_t)); franta-hg@9: write(memory, a, CMD_END); franta-hg@2: } franta-hg@0: franta-hg@21: unordered_map> commands = { franta-hg@21: {CMD_GOTO, make_shared()}, franta-hg@21: }; franta-hg@21: franta-hg@2: for (address_t i = 0; i < MEMORY_SIZE;) { franta-hg@11: wprintf(L"command %*d = ", 4, i); franta-hg@16: command_t command = read(memory, i); franta-hg@16: wprintf(L"%02X ", command); franta-hg@0: franta-hg@21: shared_ptr cx = commands[command]; franta-hg@21: franta-hg@21: if (cx) { franta-hg@21: cx->process(memory, i); franta-hg@21: continue; franta-hg@21: } else { franta-hg@21: // TODO: wprintf(L"invalid command\n"); franta-hg@21: } franta-hg@21: franta-hg@16: switch (command) { franta-hg@0: case CMD_SLEEP: franta-hg@12: { franta-hg@12: sleep_t delay = read(memory, i); franta-hg@11: wprintf(L"SLEEP %*d ms\n", 4, delay); franta-hg@11: this_thread::sleep_for(chrono::milliseconds(delay)); franta-hg@0: break; franta-hg@12: } franta-hg@10: case CMD_COLOR: franta-hg@12: { franta-hg@13: led_t led = read(memory, i); franta-hg@12: color_t r = read(memory, i); franta-hg@12: color_t g = read(memory, i); franta-hg@12: color_t b = read(memory, i); franta-hg@13: wprintf(L"COLOR %02X %02X %02X → %d\n", r, g, b, led); franta-hg@10: break; franta-hg@12: } franta-hg@14: case CMD_INCREMENT: franta-hg@14: case CMD_DECREMENT: franta-hg@14: { franta-hg@14: address_t address = read(memory, i); franta-hg@14: address_t address_r = address; franta-hg@14: address_t address_w = address_r; franta-hg@17: octet_t value = read(memory, address_r); franta-hg@16: value = command == CMD_INCREMENT ? value + 1 : value - 1; franta-hg@17: write(memory, address_w, value); franta-hg@16: wprintf(L"%sCREMENT %*d → %02X\n", (command == CMD_INCREMENT ? "IN" : "DE"), 5, address, value); franta-hg@14: break; franta-hg@14: } franta-hg@15: case CMD_GOTO_COMPARE: franta-hg@15: { franta-hg@15: address_t aa = read(memory, i); franta-hg@15: address_t ab = read(memory, i); franta-hg@15: address_t eq = read(memory, i); franta-hg@15: address_t gt = read(memory, i); franta-hg@15: address_t lt = read(memory, i); franta-hg@15: franta-hg@17: octet_t a = read(memory, aa); franta-hg@17: octet_t b = read(memory, ab); franta-hg@15: franta-hg@16: if (a == b) i = eq; franta-hg@16: else if (a > b) i = gt; franta-hg@16: else i = lt; franta-hg@16: franta-hg@15: wprintf(L"GOTO COMPARE a = %02X, b = %02X, eq = %d, gt = %d, lt = %d → %d\n", a, b, eq, gt, lt, i); franta-hg@15: break; franta-hg@15: } franta-hg@0: case CMD_END: franta-hg@12: { franta-hg@11: wprintf(L"END\n"); franta-hg@2: i = MEMORY_SIZE; franta-hg@0: break; franta-hg@12: } franta-hg@11: default: franta-hg@12: { franta-hg@11: wprintf(L"invalid command\n"); franta-hg@12: } franta-hg@0: } franta-hg@0: franta-hg@0: } franta-hg@0: franta-hg@7: free(memory); franta-hg@7: memory = nullptr; franta-hg@0: wprintf(L"all done\n"); franta-hg@0: return 0; franta-hg@0: } franta-hg@0: