c++/rgb-assembler/rgb-assembler.cpp
author František Kučera <franta-hg@frantovo.cz>
Sun, 24 Dec 2017 00:47:34 +0100
changeset 30 f049c3d3244d
parent 29 10d6964e7b4a
child 31 b997cbf9e30b
permissions -rw-r--r--
comments, formatting
     1 /**
     2  * RGB assembler
     3  * Copyright © 2017 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, either version 3 of the License, or
     8  * (at your option) any later version.
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 
    19 #include <cstdlib>
    20 #include <iostream>
    21 #include <wchar.h>
    22 #include <locale.h>
    23 #include <cstring>
    24 #include <unordered_map>
    25 
    26 #include "types.h"
    27 #include "memory.h"
    28 #include "Command.h"
    29 #include "commands.h"
    30 #include "commands/Goto.h"
    31 #include "commands/GotoCompare.h"
    32 #include "commands/Sleep.h"
    33 #include "commands/End.h"
    34 #include "commands/Color.h"
    35 #include "commands/IncrementDecrement.h"
    36 
    37 using namespace std;
    38 
    39 int main(int argc, char* argv[]) {
    40 
    41 	setlocale(LC_ALL, "");
    42 
    43 	// TODO: wrap in a class with read(), write() and setAddress() methods
    44 	octet_t * memory = (octet_t*) malloc(MEMORY_SIZE);
    45 
    46 	// Sample program / data:
    47 	// TODO: load bytes from file, stdin, serial port, network…
    48 	{
    49 		address_t a = 0;
    50 		write<command_t>(memory, a, CMD_SLEEP);
    51 		write<sleep_t>(memory, a, 255);
    52 		write<command_t>(memory, a, CMD_SLEEP);
    53 		write<sleep_t>(memory, a, 10);
    54 		write<command_t>(memory, a, CMD_SLEEP);
    55 		write<sleep_t>(memory, a, 255);
    56 		write<command_t>(memory, a, CMD_GOTO);
    57 		write<address_t>(memory, a, a + sizeof (address_t) + 2 * sizeof (command_t));
    58 		write<command_t>(memory, a, CMD_INVALID);
    59 		write<command_t>(memory, a, CMD_INVALID);
    60 		write<command_t>(memory, a, CMD_SLEEP);
    61 		write<sleep_t>(memory, a, 255);
    62 		write<command_t>(memory, a, CMD_COLOR);
    63 		write<led_t>(memory, a, 23);
    64 		write<color_t>(memory, a, 0);
    65 		write<color_t>(memory, a, 200);
    66 		write<color_t>(memory, a, 255);
    67 		write<command_t>(memory, a, CMD_INCREMENT);
    68 		write<address_t>(memory, a, 0);
    69 		write<command_t>(memory, a, CMD_DECREMENT);
    70 		write<address_t>(memory, a, 0);
    71 		write<command_t>(memory, a, CMD_GOTO_COMPARE);
    72 		write<address_t>(memory, a, 0);
    73 		write<address_t>(memory, a, 0 + sizeof (command_t) + sizeof (sleep_t));
    74 		write<address_t>(memory, a, a - 3 * sizeof (address_t) - 2 * sizeof (command_t));
    75 		write<address_t>(memory, a, 0);
    76 		write<address_t>(memory, a, a + sizeof (address_t));
    77 		write<command_t>(memory, a, CMD_END);
    78 	}
    79 
    80 	// Supported commands
    81 	// TODO: dynamic reconfiguration
    82 	unordered_map<command_t, shared_ptr < Command>> commands = {
    83 		{CMD_GOTO, make_shared<commands::Goto>()},
    84 		{CMD_GOTO_COMPARE, make_shared<commands::GotoCompare>()},
    85 		{CMD_SLEEP, make_shared<commands::Sleep>()},
    86 		{CMD_END, make_shared<commands::End>()},
    87 		{CMD_COLOR, make_shared<commands::Color>()},
    88 		{CMD_INCREMENT, make_shared <commands::IncrementDecrement>(true, 1)},
    89 		{CMD_DECREMENT, make_shared <commands::IncrementDecrement>(false, 1)},
    90 	};
    91 
    92 
    93 	// Main loop / interpreter:
    94 	for (address_t i = 0; i < MEMORY_SIZE;) {
    95 		wprintf(L"command %*d = ", 4, i);
    96 		command_t commandCode = read<command_t>(memory, i);
    97 		wprintf(L"%02X  ", commandCode);
    98 
    99 		shared_ptr<Command> command = commands[commandCode];
   100 
   101 		if (command) {
   102 			command->process(memory, i);
   103 		} else {
   104 			wprintf(L"invalid command\n");
   105 		}
   106 	}
   107 
   108 	free(memory);
   109 	memory = nullptr;
   110 	wprintf(L"all done\n");
   111 	return 0;
   112 }