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