c++/rgb-assembler/rgb-assembler.cpp
author František Kučera <franta-hg@frantovo.cz>
Sun, 24 Dec 2017 00:12:58 +0100
changeset 27 835bd4559e5c
parent 26 47ee91579133
child 28 2b2f8a17d63a
permissions -rw-r--r--
parametric INCREMENT and DECREMENT
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
franta-hg@19
     8
#include "types.h"
franta-hg@20
     9
#include "memory.h"
franta-hg@20
    10
#include "Command.h"
franta-hg@20
    11
#include "commands/Goto.h"
franta-hg@25
    12
#include "commands/GotoCompare.h"
franta-hg@22
    13
#include "commands/Sleep.h"
franta-hg@23
    14
#include "commands/End.h"
franta-hg@24
    15
#include "commands/Color.h"
franta-hg@26
    16
#include "commands/IncrementDecrement.h"
franta-hg@19
    17
franta-hg@0
    18
using namespace std;
franta-hg@0
    19
franta-hg@12
    20
// TODO: strong typedefs http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html ?
franta-hg@12
    21
franta-hg@13
    22
/**
franta-hg@13
    23
 * Skip to the given address.
franta-hg@13
    24
 * parameter: address_t
franta-hg@13
    25
 */
franta-hg@5
    26
const command_t CMD_GOTO = 0x70;
franta-hg@13
    27
franta-hg@13
    28
/**
franta-hg@15
    29
 * Compare values on two addresses and go to one of given three addresses.
franta-hg@15
    30
 * parameter: address_t a
franta-hg@15
    31
 * parameter: address_t b
franta-hg@15
    32
 * parameter: address_t GOTO target when a == b
franta-hg@15
    33
 * parameter: address_t GOTO target when a > b
franta-hg@15
    34
 * parameter: address_t GOTO target when a < b
franta-hg@15
    35
 */
franta-hg@15
    36
const command_t CMD_GOTO_COMPARE = 0x80;
franta-hg@15
    37
franta-hg@15
    38
/**
franta-hg@13
    39
 * Wait given time in ms.
franta-hg@13
    40
 * parameter: sleep_t
franta-hg@13
    41
 */
franta-hg@5
    42
const command_t CMD_SLEEP = 0xFF;
franta-hg@13
    43
franta-hg@13
    44
/**
franta-hg@13
    45
 * Set RGB LED color.
franta-hg@13
    46
 * parameter: led_t LED number
franta-hg@13
    47
 * parameter: color_t red
franta-hg@13
    48
 * parameter: color_t green
franta-hg@13
    49
 * parameter: color_t blue
franta-hg@13
    50
 */
franta-hg@10
    51
const command_t CMD_COLOR = 0xAA;
franta-hg@13
    52
franta-hg@13
    53
/**
franta-hg@13
    54
 * Stop program.
franta-hg@13
    55
 */
franta-hg@5
    56
const command_t CMD_END = 0xED;
franta-hg@13
    57
franta-hg@13
    58
/**
franta-hg@14
    59
 * Increase value at given address
franta-hg@14
    60
 * parameter: address_t
franta-hg@14
    61
 */
franta-hg@14
    62
const command_t CMD_INCREMENT = 0x11;
franta-hg@14
    63
franta-hg@14
    64
/**
franta-hg@14
    65
 * Decrease value at given address
franta-hg@14
    66
 * parameter: address_t
franta-hg@14
    67
 */
franta-hg@14
    68
const command_t CMD_DECREMENT = 0x12;
franta-hg@14
    69
franta-hg@14
    70
/**
franta-hg@13
    71
 * Placeholder for unsupported command.
franta-hg@13
    72
 * Just for testing.
franta-hg@13
    73
 */
franta-hg@13
    74
const command_t CMD_INVALID = 0x1;
franta-hg@0
    75
franta-hg@15
    76
// TODO: more commands, better numbers
franta-hg@15
    77
franta-hg@0
    78
int main(int argc, char* argv[]) {
franta-hg@0
    79
franta-hg@0
    80
	setlocale(LC_ALL, "");
franta-hg@0
    81
franta-hg@17
    82
	octet_t * memory = (octet_t*) malloc(MEMORY_SIZE);
franta-hg@0
    83
franta-hg@16
    84
	// Sample program / data:
franta-hg@16
    85
	// TODO: load bytes from file, stdin, serial port, network…
franta-hg@2
    86
	{
franta-hg@2
    87
		address_t a = 0;
franta-hg@9
    88
		write<command_t>(memory, a, CMD_SLEEP);
franta-hg@9
    89
		write<sleep_t>(memory, a, 255);
franta-hg@9
    90
		write<command_t>(memory, a, CMD_SLEEP);
franta-hg@9
    91
		write<sleep_t>(memory, a, 10);
franta-hg@9
    92
		write<command_t>(memory, a, CMD_SLEEP);
franta-hg@9
    93
		write<sleep_t>(memory, a, 255);
franta-hg@9
    94
		write<command_t>(memory, a, CMD_GOTO);
franta-hg@15
    95
		write<address_t>(memory, a, a + sizeof (address_t) + 2 * sizeof (command_t));
franta-hg@11
    96
		write<command_t>(memory, a, CMD_INVALID);
franta-hg@11
    97
		write<command_t>(memory, a, CMD_INVALID);
franta-hg@9
    98
		write<command_t>(memory, a, CMD_SLEEP);
franta-hg@9
    99
		write<sleep_t>(memory, a, 255);
franta-hg@10
   100
		write<command_t>(memory, a, CMD_COLOR);
franta-hg@13
   101
		write<led_t>(memory, a, 23);
franta-hg@11
   102
		write<color_t>(memory, a, 0);
franta-hg@11
   103
		write<color_t>(memory, a, 200);
franta-hg@11
   104
		write<color_t>(memory, a, 255);
franta-hg@14
   105
		write<command_t>(memory, a, CMD_INCREMENT);
franta-hg@14
   106
		write<address_t>(memory, a, 0);
franta-hg@14
   107
		write<command_t>(memory, a, CMD_DECREMENT);
franta-hg@14
   108
		write<address_t>(memory, a, 0);
franta-hg@15
   109
		write<command_t>(memory, a, CMD_GOTO_COMPARE);
franta-hg@15
   110
		write<address_t>(memory, a, 0);
franta-hg@15
   111
		write<address_t>(memory, a, 0 + sizeof (command_t) + sizeof (sleep_t));
franta-hg@15
   112
		write<address_t>(memory, a, a - 3 * sizeof (address_t) - 2 * sizeof (command_t));
franta-hg@15
   113
		write<address_t>(memory, a, 0);
franta-hg@15
   114
		write<address_t>(memory, a, a + sizeof (address_t));
franta-hg@9
   115
		write<command_t>(memory, a, CMD_END);
franta-hg@2
   116
	}
franta-hg@0
   117
franta-hg@21
   118
	unordered_map<command_t, shared_ptr < Command>> commands = {
franta-hg@21
   119
		{CMD_GOTO, make_shared<commands::Goto>()},
franta-hg@25
   120
		{CMD_GOTO_COMPARE, make_shared<commands::GotoCompare>()},
franta-hg@22
   121
		{CMD_SLEEP, make_shared<commands::Sleep>()},
franta-hg@23
   122
		{CMD_END, make_shared<commands::End>()},
franta-hg@24
   123
		{CMD_COLOR, make_shared<commands::Color>()},
franta-hg@27
   124
		{CMD_INCREMENT, make_shared < commands::IncrementDecrement>(true, 1)},
franta-hg@27
   125
		{CMD_DECREMENT, make_shared < commands::IncrementDecrement>(false, 1)},
franta-hg@21
   126
	};
franta-hg@27
   127
franta-hg@21
   128
franta-hg@2
   129
	for (address_t i = 0; i < MEMORY_SIZE;) {
franta-hg@11
   130
		wprintf(L"command %*d = ", 4, i);
franta-hg@26
   131
		command_t commandCode = read<command_t>(memory, i);
franta-hg@26
   132
		wprintf(L"%02X  ", commandCode);
franta-hg@0
   133
franta-hg@26
   134
		shared_ptr<Command> command = commands[commandCode];
franta-hg@21
   135
franta-hg@26
   136
		if (command) {
franta-hg@26
   137
			command->process(memory, i);
franta-hg@21
   138
		} else {
franta-hg@26
   139
			wprintf(L"invalid command\n");
franta-hg@21
   140
		}
franta-hg@0
   141
	}
franta-hg@0
   142
franta-hg@7
   143
	free(memory);
franta-hg@7
   144
	memory = nullptr;
franta-hg@0
   145
	wprintf(L"all done\n");
franta-hg@0
   146
	return 0;
franta-hg@0
   147
}