14 // TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ?
16 const address_t MEMORY_SIZE = 1024;
19 * Skip to the given address.
20 * parameter: address_t
22 const command_t CMD_GOTO = 0x70;
25 * Compare values on two addresses and go to one of given three addresses.
26 * parameter: address_t a
27 * parameter: address_t b
28 * parameter: address_t GOTO target when a == b
29 * parameter: address_t GOTO target when a > b
30 * parameter: address_t GOTO target when a < b
32 const command_t CMD_GOTO_COMPARE = 0x80;
35 * Wait given time in ms.
38 const command_t CMD_SLEEP = 0xFF;
42 * parameter: led_t LED number
43 * parameter: color_t red
44 * parameter: color_t green
45 * parameter: color_t blue
47 const command_t CMD_COLOR = 0xAA;
52 const command_t CMD_END = 0xED;
55 * Increase value at given address
56 * parameter: address_t
58 const command_t CMD_INCREMENT = 0x11;
61 * Decrease value at given address
62 * parameter: address_t
64 const command_t CMD_DECREMENT = 0x12;
67 * Placeholder for unsupported command.
70 const command_t CMD_INVALID = 0x1;
72 // TODO: more commands, better numbers
74 template<typename T> T logMemoryError(const address_t &index) {
75 wprintf(L"memory error: index = %d, sizeof(T) = %d, MEMORY_SIZE = %d\n", index, sizeof (T), MEMORY_SIZE);
76 // TODO: return error value or throw exception
81 * Reads data on given position in memory and increments the index (position).
83 * @param memory array of bytes / octets
84 * @param index offset in same units as memory type
85 * @return value found at given position
87 template<typename T> T read(octet_t * memory, address_t &index) {
88 // TODO: map higher memory to static hardcoded areas or peripherals
89 if (index + sizeof (T) <= MEMORY_SIZE) {
90 T * value = reinterpret_cast<T*> (memory + index);
94 return logMemoryError<T>(index);
99 * Writes data to given position in memory and increments the index (position).
100 * @param memory array of bytes / octets
101 * @param index offset in same units as memory type
102 * @param value value to be written at given position
104 template<typename T> T write(octet_t * memory, address_t &index, const T value) {
105 if (index + sizeof (T) <= MEMORY_SIZE) {
106 T * m = reinterpret_cast<T*> (memory + index);
108 index += sizeof (value);
110 return logMemoryError<T>(index);
114 int main(int argc, char* argv[]) {
116 setlocale(LC_ALL, "");
118 octet_t * memory = (octet_t*) malloc(MEMORY_SIZE);
120 // Sample program / data:
121 // TODO: load bytes from file, stdin, serial port, network…
124 write<command_t>(memory, a, CMD_SLEEP);
125 write<sleep_t>(memory, a, 255);
126 write<command_t>(memory, a, CMD_SLEEP);
127 write<sleep_t>(memory, a, 10);
128 write<command_t>(memory, a, CMD_SLEEP);
129 write<sleep_t>(memory, a, 255);
130 write<command_t>(memory, a, CMD_GOTO);
131 write<address_t>(memory, a, a + sizeof (address_t) + 2 * sizeof (command_t));
132 write<command_t>(memory, a, CMD_INVALID);
133 write<command_t>(memory, a, CMD_INVALID);
134 write<command_t>(memory, a, CMD_SLEEP);
135 write<sleep_t>(memory, a, 255);
136 write<command_t>(memory, a, CMD_COLOR);
137 write<led_t>(memory, a, 23);
138 write<color_t>(memory, a, 0);
139 write<color_t>(memory, a, 200);
140 write<color_t>(memory, a, 255);
141 write<command_t>(memory, a, CMD_INCREMENT);
142 write<address_t>(memory, a, 0);
143 write<command_t>(memory, a, CMD_DECREMENT);
144 write<address_t>(memory, a, 0);
145 write<command_t>(memory, a, CMD_GOTO_COMPARE);
146 write<address_t>(memory, a, 0);
147 write<address_t>(memory, a, 0 + sizeof (command_t) + sizeof (sleep_t));
148 write<address_t>(memory, a, a - 3 * sizeof (address_t) - 2 * sizeof (command_t));
149 write<address_t>(memory, a, 0);
150 write<address_t>(memory, a, a + sizeof (address_t));
151 write<command_t>(memory, a, CMD_END);
154 for (address_t i = 0; i < MEMORY_SIZE;) {
155 wprintf(L"command %*d = ", 4, i);
156 command_t command = read<command_t>(memory, i);
157 wprintf(L"%02X ", command);
162 i = read<address_t>(memory, i);
163 wprintf(L"GOTO %*d\n", 5, i);
168 sleep_t delay = read<sleep_t>(memory, i);
169 wprintf(L"SLEEP %*d ms\n", 4, delay);
170 this_thread::sleep_for(chrono::milliseconds(delay));
175 led_t led = read<led_t>(memory, i);
176 color_t r = read<color_t>(memory, i);
177 color_t g = read<color_t>(memory, i);
178 color_t b = read<color_t>(memory, i);
179 wprintf(L"COLOR %02X %02X %02X → %d\n", r, g, b, led);
185 address_t address = read<address_t>(memory, i);
186 address_t address_r = address;
187 address_t address_w = address_r;
188 octet_t value = read<octet_t>(memory, address_r);
189 value = command == CMD_INCREMENT ? value + 1 : value - 1;
190 write<octet_t>(memory, address_w, value);
191 wprintf(L"%sCREMENT %*d → %02X\n", (command == CMD_INCREMENT ? "IN" : "DE"), 5, address, value);
194 case CMD_GOTO_COMPARE:
196 address_t aa = read<address_t>(memory, i);
197 address_t ab = read<address_t>(memory, i);
198 address_t eq = read<address_t>(memory, i);
199 address_t gt = read<address_t>(memory, i);
200 address_t lt = read<address_t>(memory, i);
202 octet_t a = read<octet_t>(memory, aa);
203 octet_t b = read<octet_t>(memory, ab);
206 else if (a > b) i = gt;
209 wprintf(L"GOTO COMPARE a = %02X, b = %02X, eq = %d, gt = %d, lt = %d → %d\n", a, b, eq, gt, lt, i);
220 wprintf(L"invalid command\n");
228 wprintf(L"all done\n");