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