c++/rgb-assembler/rgb-assembler.cpp
author František Kučera <franta-hg@frantovo.cz>
Fri, 22 Dec 2017 16:10:56 +0100
changeset 12 1ecfa42ca0d2
parent 11 1d1cc6552542
child 13 2a4b8b3abe14
permissions -rw-r--r--
local variables inside switch
     1 #include <cstdlib>
     2 #include <iostream>
     3 #include <wchar.h>
     4 #include <locale.h>
     5 #include <cstring>
     6 
     7 #include <chrono>
     8 #include <thread>
     9 
    10 using namespace std;
    11 
    12 typedef uint16_t address_t;
    13 typedef uint8_t command_t;
    14 typedef uint8_t sleep_t;
    15 typedef uint8_t color_t;
    16 
    17 // TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ?
    18 
    19 const address_t MEMORY_SIZE = 1024;
    20 
    21 const command_t CMD_GOTO = 0x70;
    22 const command_t CMD_SLEEP = 0xFF;
    23 const command_t CMD_COLOR = 0xAA;
    24 const command_t CMD_END = 0xED;
    25 const command_t CMD_INVALID = 0x1; // placeholder for unsupported command
    26 
    27 /**
    28  * Reads data on given position in memory and increments the index (position).
    29  */
    30 template<typename T> T read(command_t * memory, address_t &index) {
    31 	// TODO: for addresses: map higher memory to static hardcoded areas or peripherals
    32 	// TODO: sizeof (command_t) != 1 ?
    33 	T * value = reinterpret_cast<T*> (memory + index);
    34 	index += sizeof (*value) / sizeof (command_t);
    35 	return *value;
    36 }
    37 
    38 /**
    39  * Writes data to given position in memory and increments the index (position).
    40  */
    41 template<typename T> void write(command_t * memory, address_t &index, const T value) {
    42 	// TODO: sizeof (command_t) != 1 ?
    43 	// T * m = (T*) (memory + index);
    44 	T * m = reinterpret_cast<T*> (memory + index);
    45 	*m = value;
    46 	index += sizeof (value) / sizeof (command_t);
    47 }
    48 
    49 int main(int argc, char* argv[]) {
    50 
    51 	setlocale(LC_ALL, "");
    52 
    53 	command_t * memory = (command_t*) malloc(MEMORY_SIZE);
    54 
    55 	{
    56 		address_t a = 0;
    57 		write<command_t>(memory, a, CMD_SLEEP);
    58 		write<sleep_t>(memory, a, 255);
    59 		write<command_t>(memory, a, CMD_SLEEP);
    60 		write<sleep_t>(memory, a, 10);
    61 		write<command_t>(memory, a, CMD_SLEEP);
    62 		write<sleep_t>(memory, a, 255);
    63 		write<command_t>(memory, a, CMD_GOTO);
    64 		write<address_t>(memory, a, a + 4);
    65 		write<command_t>(memory, a, CMD_INVALID);
    66 		write<command_t>(memory, a, CMD_INVALID);
    67 		write<command_t>(memory, a, CMD_SLEEP);
    68 		write<sleep_t>(memory, a, 255);
    69 		write<command_t>(memory, a, CMD_COLOR);
    70 		write<color_t>(memory, a, 0);
    71 		write<color_t>(memory, a, 200);
    72 		write<color_t>(memory, a, 255);
    73 		write<command_t>(memory, a, CMD_END);
    74 	}
    75 
    76 	for (address_t i = 0; i < MEMORY_SIZE;) {
    77 		wprintf(L"command %*d = ", 4, i);
    78 		command_t ch = read<command_t>(memory, i);
    79 		wprintf(L"%02X  ", ch);
    80 
    81 		switch (ch) {
    82 			case CMD_GOTO:
    83 			{
    84 				i = read<address_t>(memory, i);
    85 				wprintf(L"GOTO %*d\n", 5, i);
    86 				break;
    87 			}
    88 			case CMD_SLEEP:
    89 			{
    90 				sleep_t delay = read<sleep_t>(memory, i);
    91 				wprintf(L"SLEEP %*d ms\n", 4, delay);
    92 				this_thread::sleep_for(chrono::milliseconds(delay));
    93 				break;
    94 			}
    95 			case CMD_COLOR:
    96 			{
    97 				color_t r = read<color_t>(memory, i);
    98 				color_t g = read<color_t>(memory, i);
    99 				color_t b = read<color_t>(memory, i);
   100 				wprintf(L"COLOR  %02X %02X %02X\n", r, g, b);
   101 				break;
   102 			}
   103 			case CMD_END:
   104 			{
   105 				wprintf(L"END\n");
   106 				i = MEMORY_SIZE;
   107 				break;
   108 			}
   109 			default:
   110 			{
   111 				wprintf(L"invalid command\n");
   112 			}
   113 		}
   114 
   115 	}
   116 
   117 	free(memory);
   118 	memory = nullptr;
   119 	wprintf(L"all done\n");
   120 	return 0;
   121 }
   122