c++/rgb-assembler/rgb-assembler.cpp
author František Kučera <franta-hg@frantovo.cz>
Sat, 23 Dec 2017 23:24:51 +0100
changeset 20 b9ceffdcaf14
parent 19 17785b69430d
child 21 ae4a9092e1a8
permissions -rw-r--r--
move memory functions to a header file + introduce Command classes
     1 #include <cstdlib>
     2 #include <iostream>
     3 #include <wchar.h>
     4 #include <locale.h>
     5 #include <cstring>
     6 #include <unordered_map>
     7 #include <chrono>
     8 #include <thread>
     9 
    10 #include "types.h"
    11 #include "memory.h"
    12 #include "Command.h"
    13 #include "commands/Goto.h"
    14 
    15 using namespace std;
    16 
    17 // TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ?
    18 
    19 /**
    20  * Skip to the given address.
    21  * parameter: address_t
    22  */
    23 const command_t CMD_GOTO = 0x70;
    24 
    25 /**
    26  * Compare values on two addresses and go to one of given three addresses.
    27  * parameter: address_t a
    28  * parameter: address_t b
    29  * parameter: address_t GOTO target when a == b
    30  * parameter: address_t GOTO target when a > b
    31  * parameter: address_t GOTO target when a < b
    32  */
    33 const command_t CMD_GOTO_COMPARE = 0x80;
    34 
    35 /**
    36  * Wait given time in ms.
    37  * parameter: sleep_t
    38  */
    39 const command_t CMD_SLEEP = 0xFF;
    40 
    41 /**
    42  * Set RGB LED color.
    43  * parameter: led_t LED number
    44  * parameter: color_t red
    45  * parameter: color_t green
    46  * parameter: color_t blue
    47  */
    48 const command_t CMD_COLOR = 0xAA;
    49 
    50 /**
    51  * Stop program.
    52  */
    53 const command_t CMD_END = 0xED;
    54 
    55 /**
    56  * Increase value at given address
    57  * parameter: address_t
    58  */
    59 const command_t CMD_INCREMENT = 0x11;
    60 
    61 /**
    62  * Decrease value at given address
    63  * parameter: address_t
    64  */
    65 const command_t CMD_DECREMENT = 0x12;
    66 
    67 /**
    68  * Placeholder for unsupported command.
    69  * Just for testing.
    70  */
    71 const command_t CMD_INVALID = 0x1;
    72 
    73 // TODO: more commands, better numbers
    74 
    75 int main(int argc, char* argv[]) {
    76 
    77 	setlocale(LC_ALL, "");
    78 
    79 	octet_t * memory = (octet_t*) malloc(MEMORY_SIZE);
    80 
    81 	// Sample program / data:
    82 	// TODO: load bytes from file, stdin, serial port, network…
    83 	{
    84 		address_t a = 0;
    85 		write<command_t>(memory, a, CMD_SLEEP);
    86 		write<sleep_t>(memory, a, 255);
    87 		write<command_t>(memory, a, CMD_SLEEP);
    88 		write<sleep_t>(memory, a, 10);
    89 		write<command_t>(memory, a, CMD_SLEEP);
    90 		write<sleep_t>(memory, a, 255);
    91 		write<command_t>(memory, a, CMD_GOTO);
    92 		write<address_t>(memory, a, a + sizeof (address_t) + 2 * sizeof (command_t));
    93 		write<command_t>(memory, a, CMD_INVALID);
    94 		write<command_t>(memory, a, CMD_INVALID);
    95 		write<command_t>(memory, a, CMD_SLEEP);
    96 		write<sleep_t>(memory, a, 255);
    97 		write<command_t>(memory, a, CMD_COLOR);
    98 		write<led_t>(memory, a, 23);
    99 		write<color_t>(memory, a, 0);
   100 		write<color_t>(memory, a, 200);
   101 		write<color_t>(memory, a, 255);
   102 		write<command_t>(memory, a, CMD_INCREMENT);
   103 		write<address_t>(memory, a, 0);
   104 		write<command_t>(memory, a, CMD_DECREMENT);
   105 		write<address_t>(memory, a, 0);
   106 		write<command_t>(memory, a, CMD_GOTO_COMPARE);
   107 		write<address_t>(memory, a, 0);
   108 		write<address_t>(memory, a, 0 + sizeof (command_t) + sizeof (sleep_t));
   109 		write<address_t>(memory, a, a - 3 * sizeof (address_t) - 2 * sizeof (command_t));
   110 		write<address_t>(memory, a, 0);
   111 		write<address_t>(memory, a, a + sizeof (address_t));
   112 		write<command_t>(memory, a, CMD_END);
   113 	}
   114 
   115 	for (address_t i = 0; i < MEMORY_SIZE;) {
   116 		wprintf(L"command %*d = ", 4, i);
   117 		command_t command = read<command_t>(memory, i);
   118 		wprintf(L"%02X  ", command);
   119 
   120 		switch (command) {
   121 			case CMD_GOTO:
   122 			{
   123 				i = read<address_t>(memory, i);
   124 				wprintf(L"GOTO %*d\n", 5, i);
   125 				break;
   126 			}
   127 			case CMD_SLEEP:
   128 			{
   129 				sleep_t delay = read<sleep_t>(memory, i);
   130 				wprintf(L"SLEEP %*d ms\n", 4, delay);
   131 				this_thread::sleep_for(chrono::milliseconds(delay));
   132 				break;
   133 			}
   134 			case CMD_COLOR:
   135 			{
   136 				led_t led = read<led_t>(memory, i);
   137 				color_t r = read<color_t>(memory, i);
   138 				color_t g = read<color_t>(memory, i);
   139 				color_t b = read<color_t>(memory, i);
   140 				wprintf(L"COLOR  %02X %02X %02X → %d\n", r, g, b, led);
   141 				break;
   142 			}
   143 			case CMD_INCREMENT:
   144 			case CMD_DECREMENT:
   145 			{
   146 				address_t address = read<address_t>(memory, i);
   147 				address_t address_r = address;
   148 				address_t address_w = address_r;
   149 				octet_t value = read<octet_t>(memory, address_r);
   150 				value = command == CMD_INCREMENT ? value + 1 : value - 1;
   151 				write<octet_t>(memory, address_w, value);
   152 				wprintf(L"%sCREMENT %*d → %02X\n", (command == CMD_INCREMENT ? "IN" : "DE"), 5, address, value);
   153 				break;
   154 			}
   155 			case CMD_GOTO_COMPARE:
   156 			{
   157 				address_t aa = read<address_t>(memory, i);
   158 				address_t ab = read<address_t>(memory, i);
   159 				address_t eq = read<address_t>(memory, i);
   160 				address_t gt = read<address_t>(memory, i);
   161 				address_t lt = read<address_t>(memory, i);
   162 
   163 				octet_t a = read<octet_t>(memory, aa);
   164 				octet_t b = read<octet_t>(memory, ab);
   165 
   166 				if (a == b) i = eq;
   167 				else if (a > b) i = gt;
   168 				else i = lt;
   169 
   170 				wprintf(L"GOTO COMPARE  a = %02X, b = %02X, eq = %d, gt = %d, lt = %d → %d\n", a, b, eq, gt, lt, i);
   171 				break;
   172 			}
   173 			case CMD_END:
   174 			{
   175 				wprintf(L"END\n");
   176 				i = MEMORY_SIZE;
   177 				break;
   178 			}
   179 			default:
   180 			{
   181 				wprintf(L"invalid command\n");
   182 			}
   183 		}
   184 
   185 	}
   186 
   187 	free(memory);
   188 	memory = nullptr;
   189 	wprintf(L"all done\n");
   190 	return 0;
   191 }
   192