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