c++/rgb-assembler/rgb-assembler.cpp
author František Kučera <franta-hg@frantovo.cz>
Fri, 22 Dec 2017 17:15:15 +0100
changeset 14 2ab3d7282249
parent 13 2a4b8b3abe14
child 15 4b4fb847d01a
permissions -rw-r--r--
INCREMENT, DECREMENT
     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 byte_t;
    14 typedef uint8_t command_t;
    15 typedef uint8_t sleep_t;
    16 typedef uint8_t color_t;
    17 typedef uint8_t led_t;
    18 
    19 // TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ?
    20 
    21 const address_t MEMORY_SIZE = 1024;
    22 
    23 /**
    24  * Skip to the given address.
    25  * parameter: address_t
    26  */
    27 const command_t CMD_GOTO = 0x70;
    28 
    29 /**
    30  * Wait given time in ms.
    31  * parameter: sleep_t
    32  */
    33 const command_t CMD_SLEEP = 0xFF;
    34 
    35 /**
    36  * Set RGB LED color.
    37  * parameter: led_t LED number
    38  * parameter: color_t red
    39  * parameter: color_t green
    40  * parameter: color_t blue
    41  */
    42 const command_t CMD_COLOR = 0xAA;
    43 
    44 /**
    45  * Stop program.
    46  */
    47 const command_t CMD_END = 0xED;
    48 
    49 /**
    50  * Increase value at given address
    51  * parameter: address_t
    52  */
    53 const command_t CMD_INCREMENT = 0x11;
    54 
    55 /**
    56  * Decrease value at given address
    57  * parameter: address_t
    58  */
    59 const command_t CMD_DECREMENT = 0x12;
    60 
    61 /**
    62  * Placeholder for unsupported command.
    63  * Just for testing.
    64  */
    65 const command_t CMD_INVALID = 0x1;
    66 
    67 /**
    68  * Reads data on given position in memory and increments the index (position).
    69  */
    70 template<typename T> T read(byte_t * memory, address_t &index) {
    71 	// TODO: for addresses: map higher memory to static hardcoded areas or peripherals
    72 	// TODO: sizeof (byte_t) != 1 ?
    73 	T * value = reinterpret_cast<T*> (memory + index);
    74 	index += sizeof (*value) / sizeof (byte_t);
    75 	return *value;
    76 }
    77 
    78 /**
    79  * Writes data to given position in memory and increments the index (position).
    80  */
    81 template<typename T> void write(byte_t * memory, address_t &index, const T value) {
    82 	// TODO: sizeof (byte_t) != 1 ?
    83 	// T * m = (T*) (memory + index);
    84 	T * m = reinterpret_cast<T*> (memory + index);
    85 	*m = value;
    86 	index += sizeof (value) / sizeof (byte_t);
    87 }
    88 
    89 int main(int argc, char* argv[]) {
    90 
    91 	setlocale(LC_ALL, "");
    92 
    93 	byte_t * memory = (byte_t*) malloc(MEMORY_SIZE);
    94 
    95 	{
    96 		address_t a = 0;
    97 		write<command_t>(memory, a, CMD_SLEEP);
    98 		write<sleep_t>(memory, a, 255);
    99 		write<command_t>(memory, a, CMD_SLEEP);
   100 		write<sleep_t>(memory, a, 10);
   101 		write<command_t>(memory, a, CMD_SLEEP);
   102 		write<sleep_t>(memory, a, 255);
   103 		write<command_t>(memory, a, CMD_GOTO);
   104 		write<address_t>(memory, a, a + 4);
   105 		write<command_t>(memory, a, CMD_INVALID);
   106 		write<command_t>(memory, a, CMD_INVALID);
   107 		write<command_t>(memory, a, CMD_SLEEP);
   108 		write<sleep_t>(memory, a, 255);
   109 		write<command_t>(memory, a, CMD_COLOR);
   110 		write<led_t>(memory, a, 23);
   111 		write<color_t>(memory, a, 0);
   112 		write<color_t>(memory, a, 200);
   113 		write<color_t>(memory, a, 255);
   114 		write<command_t>(memory, a, CMD_INCREMENT);
   115 		write<address_t>(memory, a, 0);
   116 		write<command_t>(memory, a, CMD_DECREMENT);
   117 		write<address_t>(memory, a, 0);
   118 		write<command_t>(memory, a, CMD_END);
   119 	}
   120 
   121 	for (address_t i = 0; i < MEMORY_SIZE;) {
   122 		wprintf(L"command %*d = ", 4, i);
   123 		command_t ch = read<command_t>(memory, i);
   124 		wprintf(L"%02X  ", ch);
   125 
   126 		switch (ch) {
   127 			case CMD_GOTO:
   128 			{
   129 				i = read<address_t>(memory, i);
   130 				wprintf(L"GOTO %*d\n", 5, i);
   131 				break;
   132 			}
   133 			case CMD_SLEEP:
   134 			{
   135 				sleep_t delay = read<sleep_t>(memory, i);
   136 				wprintf(L"SLEEP %*d ms\n", 4, delay);
   137 				this_thread::sleep_for(chrono::milliseconds(delay));
   138 				break;
   139 			}
   140 			case CMD_COLOR:
   141 			{
   142 				led_t led = read<led_t>(memory, i);
   143 				color_t r = read<color_t>(memory, i);
   144 				color_t g = read<color_t>(memory, i);
   145 				color_t b = read<color_t>(memory, i);
   146 				wprintf(L"COLOR  %02X %02X %02X → %d\n", r, g, b, led);
   147 				break;
   148 			}
   149 			case CMD_INCREMENT:
   150 			case CMD_DECREMENT:
   151 			{
   152 				address_t address = read<address_t>(memory, i);
   153 				address_t address_r = address;
   154 				address_t address_w = address_r;
   155 				byte_t value = read<byte_t>(memory, address_r);
   156 				value = ch == CMD_INCREMENT ? value + 1 : value - 1;
   157 				write<byte_t>(memory, address_w, value);
   158 				wprintf(L"%sCREMENT %*d → %02X\n", (ch == CMD_INCREMENT ? "IN" : "DE"), 5, address, value);
   159 				break;
   160 			}
   161 			case CMD_END:
   162 			{
   163 				wprintf(L"END\n");
   164 				i = MEMORY_SIZE;
   165 				break;
   166 			}
   167 			default:
   168 			{
   169 				wprintf(L"invalid command\n");
   170 			}
   171 		}
   172 
   173 	}
   174 
   175 	free(memory);
   176 	memory = nullptr;
   177 	wprintf(L"all done\n");
   178 	return 0;
   179 }
   180