wrap memory in a class
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 25 Dec 2017 00:24:07 +0100
changeset 31b997cbf9e30b
parent 30 f049c3d3244d
child 32 78c4d6b53499
wrap memory in a class
c++/rgb-assembler/Command.h
c++/rgb-assembler/commands/Color.h
c++/rgb-assembler/commands/End.h
c++/rgb-assembler/commands/Goto.h
c++/rgb-assembler/commands/GotoCompare.h
c++/rgb-assembler/commands/IncrementDecrement.h
c++/rgb-assembler/commands/Sleep.h
c++/rgb-assembler/memory.h
c++/rgb-assembler/rgb-assembler.cpp
     1.1 --- a/c++/rgb-assembler/Command.h	Sun Dec 24 00:47:34 2017 +0100
     1.2 +++ b/c++/rgb-assembler/Command.h	Mon Dec 25 00:24:07 2017 +0100
     1.3 @@ -24,11 +24,8 @@
     1.4  class Command {
     1.5  public:
     1.6  	/**
     1.7 -	 * Process command at given address, read parameters if any. And shift address to new one (after last parameter)
     1.8 +	 * Process command at given address, read parameters if any.
     1.9  	 * @param memory
    1.10 -	 * @param index address of the command in the memory
    1.11  	 */
    1.12 -	virtual void process(octet_t * memory, address_t &index) = 0;
    1.13 -private:
    1.14 -
    1.15 +	virtual void process(Memory &memory) = 0;
    1.16  };
     2.1 --- a/c++/rgb-assembler/commands/Color.h	Sun Dec 24 00:47:34 2017 +0100
     2.2 +++ b/c++/rgb-assembler/commands/Color.h	Mon Dec 25 00:24:07 2017 +0100
     2.3 @@ -27,15 +27,13 @@
     2.4  class Color : public Command {
     2.5  public:
     2.6  
     2.7 -	void process(octet_t* memory, address_t& index) override {
     2.8 -		led_t led = read<led_t>(memory, index);
     2.9 -		color_t r = read<color_t>(memory, index);
    2.10 -		color_t g = read<color_t>(memory, index);
    2.11 -		color_t b = read<color_t>(memory, index);
    2.12 +	void process(Memory &memory) override {
    2.13 +		led_t led = memory.read<led_t>();
    2.14 +		color_t r = memory.read<color_t>();
    2.15 +		color_t g = memory.read<color_t>();
    2.16 +		color_t b = memory.read<color_t>();
    2.17  		wprintf(L"COLOR  %02X %02X %02X → %d\n", r, g, b, led);
    2.18  	}
    2.19 -private:
    2.20 -
    2.21  };
    2.22  
    2.23  }
     3.1 --- a/c++/rgb-assembler/commands/End.h	Sun Dec 24 00:47:34 2017 +0100
     3.2 +++ b/c++/rgb-assembler/commands/End.h	Mon Dec 25 00:24:07 2017 +0100
     3.3 @@ -32,12 +32,10 @@
     3.4  class End : public Command {
     3.5  public:
     3.6  
     3.7 -	void process(octet_t* memory, address_t& index) override {
     3.8 +	void process(Memory &memory) override {
     3.9  		wprintf(L"END\n");
    3.10 -		index = MEMORY_SIZE;
    3.11 +		memory.finish();
    3.12  	}
    3.13 -private:
    3.14 -
    3.15  };
    3.16  
    3.17  }
     4.1 --- a/c++/rgb-assembler/commands/Goto.h	Sun Dec 24 00:47:34 2017 +0100
     4.2 +++ b/c++/rgb-assembler/commands/Goto.h	Mon Dec 25 00:24:07 2017 +0100
     4.3 @@ -27,12 +27,11 @@
     4.4  class Goto : public Command {
     4.5  public:
     4.6  
     4.7 -	void process(octet_t* memory, address_t& index) override {
     4.8 -		index = read<address_t>(memory, index);
     4.9 +	void process(Memory &memory) override {
    4.10 +		address_t index = memory.read<address_t>();
    4.11 +		memory.setIndex(index);
    4.12  		wprintf(L"GOTO %*d\n", 5, index);
    4.13  	}
    4.14 -private:
    4.15 -
    4.16  };
    4.17  
    4.18  }
     5.1 --- a/c++/rgb-assembler/commands/GotoCompare.h	Sun Dec 24 00:47:34 2017 +0100
     5.2 +++ b/c++/rgb-assembler/commands/GotoCompare.h	Mon Dec 25 00:24:07 2017 +0100
     5.3 @@ -27,24 +27,31 @@
     5.4  class GotoCompare : public Command {
     5.5  public:
     5.6  
     5.7 -	void process(octet_t* memory, address_t& index) override {
     5.8 -		address_t aa = read<address_t>(memory, index);
     5.9 -		address_t ab = read<address_t>(memory, index);
    5.10 -		address_t eq = read<address_t>(memory, index);
    5.11 -		address_t gt = read<address_t>(memory, index);
    5.12 -		address_t lt = read<address_t>(memory, index);
    5.13 +	void process(Memory &memory) override {
    5.14 +		address_t aa = memory.read<address_t>();
    5.15 +		address_t ab = memory.read<address_t>();
    5.16 +		address_t eq = memory.read<address_t>();
    5.17 +		address_t gt = memory.read<address_t>();
    5.18 +		address_t lt = memory.read<address_t>();
    5.19  
    5.20 -		octet_t a = read<octet_t>(memory, aa);
    5.21 -		octet_t b = read<octet_t>(memory, ab);
    5.22 +		address_t originalAddress = memory.getIndex();
    5.23 +		// TODO: add to Memory methods read(address_t) and write(address_t, T)
    5.24 +		memory.setIndex(aa);
    5.25 +		octet_t a = memory.read<octet_t>();
    5.26 +		memory.setIndex(ab);
    5.27 +		octet_t b = memory.read<octet_t>();
    5.28 +		memory.setIndex(originalAddress);
    5.29 +
    5.30 +		address_t index;
    5.31  
    5.32  		if (a == b) index = eq;
    5.33  		else if (a > b) index = gt;
    5.34  		else index = lt;
    5.35  
    5.36 +		memory.setIndex(index);
    5.37 +
    5.38  		wprintf(L"GOTO COMPARE  a = %02X, b = %02X, eq = %d, gt = %d, lt = %d → %d\n", a, b, eq, gt, lt, index);
    5.39  	}
    5.40 -private:
    5.41 -
    5.42  };
    5.43  
    5.44  }
     6.1 --- a/c++/rgb-assembler/commands/IncrementDecrement.h	Sun Dec 24 00:47:34 2017 +0100
     6.2 +++ b/c++/rgb-assembler/commands/IncrementDecrement.h	Mon Dec 25 00:24:07 2017 +0100
     6.3 @@ -37,13 +37,16 @@
     6.4  		this->change = change;
     6.5  	}
     6.6  
     6.7 -	void process(octet_t* memory, address_t& index) override {
     6.8 -		address_t address = read<address_t>(memory, index);
     6.9 -		address_t address_r = address;
    6.10 -		address_t address_w = address_r;
    6.11 -		octet_t value = read<octet_t>(memory, address_r);
    6.12 +	void process(Memory &memory) override {
    6.13 +		address_t address = memory.read<address_t>();
    6.14 +		address_t originalAddress = memory.getIndex();
    6.15 +		// TODO: add to Memory methods read(address_t) and write(address_t, T)
    6.16 +		memory.setIndex(address);
    6.17 +		octet_t value = memory.read<octet_t>();
    6.18  		value = increment ? value + change : value - change;
    6.19 -		write<octet_t>(memory, address_w, value);
    6.20 +		memory.setIndex(address);
    6.21 +		memory.write<octet_t>(value);
    6.22 +		memory.setIndex(originalAddress);
    6.23  		wprintf(L"%sCREMENT %*d → %02X\n", (increment ? "IN" : "DE"), 5, address, value);
    6.24  	}
    6.25  private:
     7.1 --- a/c++/rgb-assembler/commands/Sleep.h	Sun Dec 24 00:47:34 2017 +0100
     7.2 +++ b/c++/rgb-assembler/commands/Sleep.h	Mon Dec 25 00:24:07 2017 +0100
     7.3 @@ -31,13 +31,11 @@
     7.4  class Sleep : public Command {
     7.5  public:
     7.6  
     7.7 -	void process(octet_t* memory, address_t& index) override {
     7.8 -		sleep_t delay = read<sleep_t>(memory, index);
     7.9 +	void process(Memory &memory) override {
    7.10 +		sleep_t delay = memory.read<sleep_t>();
    7.11  		wprintf(L"SLEEP %*d ms\n", 4, delay);
    7.12  		this_thread::sleep_for(chrono::milliseconds(delay));
    7.13  	}
    7.14 -private:
    7.15 -
    7.16  };
    7.17  
    7.18  }
     8.1 --- a/c++/rgb-assembler/memory.h	Sun Dec 24 00:47:34 2017 +0100
     8.2 +++ b/c++/rgb-assembler/memory.h	Mon Dec 25 00:24:07 2017 +0100
     8.3 @@ -22,42 +22,85 @@
     8.4  
     8.5  const address_t MEMORY_SIZE = 1024;
     8.6  
     8.7 -template<typename T> T logMemoryError(const address_t &index) {
     8.8 -	wprintf(L"memory error: index = %d, sizeof(T) = %d, MEMORY_SIZE = %d\n", index, sizeof (T), MEMORY_SIZE);
     8.9 -	// TODO: return error value or throw exception
    8.10 -	return T();
    8.11 -}
    8.12 +class Memory {
    8.13 +private:
    8.14  
    8.15 -/**
    8.16 - * Reads data on given position in memory and increments the index (position).
    8.17 - * 
    8.18 - * @param memory array of bytes / octets
    8.19 - * @param index offset in same units as memory type
    8.20 - * @return value found at given position
    8.21 - */
    8.22 -template<typename T> T read(octet_t * memory, address_t &index) {
    8.23 -	// TODO: map higher memory to static hardcoded areas or peripherals
    8.24 -	if (index + sizeof (T) <= MEMORY_SIZE) {
    8.25 -		T * value = reinterpret_cast<T*> (memory + index);
    8.26 -		index += sizeof (T);
    8.27 -		return *value;
    8.28 -	} else {
    8.29 -		return logMemoryError<T>(index);
    8.30 +	template<typename T> T logMemoryError(const address_t &index) {
    8.31 +		wprintf(L"memory error: index = %d, sizeof(T) = %d, MEMORY_SIZE = %d\n", index, sizeof (T), MEMORY_SIZE);
    8.32 +		// TODO: return error value or throw exception
    8.33 +		return T();
    8.34  	}
    8.35 -}
    8.36 +	octet_t * memory;
    8.37 +	address_t index;
    8.38  
    8.39 -/**
    8.40 - * Writes data to given position in memory and increments the index (position).
    8.41 - * @param memory array of bytes / octets
    8.42 - * @param index offset in same units as memory type
    8.43 - * @param value value to be written at given position
    8.44 - */
    8.45 -template<typename T> T write(octet_t * memory, address_t &index, const T value) {
    8.46 -	if (index + sizeof (T) <= MEMORY_SIZE) {
    8.47 -		T * m = reinterpret_cast<T*> (memory + index);
    8.48 -		*m = value;
    8.49 -		index += sizeof (value);
    8.50 -	} else {
    8.51 -		return logMemoryError<T>(index);
    8.52 +public:
    8.53 +
    8.54 +	Memory() {
    8.55 +		memory = (octet_t*) malloc(MEMORY_SIZE);
    8.56 +		index = 0;
    8.57  	}
    8.58 -}
    8.59 +
    8.60 +	virtual ~Memory() {
    8.61 +		free(memory);
    8.62 +		memory = nullptr;
    8.63 +	}
    8.64 +
    8.65 +	/**
    8.66 +	 * Reads data on given position in memory and increments the index (position).
    8.67 +	 * @return value found at current position
    8.68 +	 */
    8.69 +	template<typename T> T read() {
    8.70 +		// TODO: map higher memory to static hardcoded areas or peripherals
    8.71 +		if (index + sizeof (T) <= MEMORY_SIZE) {
    8.72 +			T * value = reinterpret_cast<T*> (memory + index);
    8.73 +			index += sizeof (T);
    8.74 +			return *value;
    8.75 +		} else {
    8.76 +			return logMemoryError<T>(index);
    8.77 +		}
    8.78 +	}
    8.79 +
    8.80 +	/**
    8.81 +	 * Writes data to current position in memory and increments the index (position).
    8.82 +	 * @param value value to be written at given position
    8.83 +	 */
    8.84 +	template<typename T> T write(const T value) {
    8.85 +		if (index + sizeof (T) <= MEMORY_SIZE) {
    8.86 +			T * m = reinterpret_cast<T*> (memory + index);
    8.87 +			*m = value;
    8.88 +			index += sizeof (value);
    8.89 +		} else {
    8.90 +			return logMemoryError<T>(index);
    8.91 +		}
    8.92 +	}
    8.93 +
    8.94 +	void setIndex(address_t &index) {
    8.95 +		this->index = index;
    8.96 +	}
    8.97 +
    8.98 +	address_t getIndex() {
    8.99 +		return index;
   8.100 +	}
   8.101 +
   8.102 +	/**
   8.103 +	 * FIXME: rename
   8.104 +	 * @return 
   8.105 +	 */
   8.106 +	bool isInside() {
   8.107 +		return index < MEMORY_SIZE;
   8.108 +	}
   8.109 +	
   8.110 +	/**
   8.111 +	 * FIXME: rename, refactor
   8.112 +	 */
   8.113 +	void start() {
   8.114 +		index = 0;
   8.115 +	}
   8.116 +
   8.117 +	/**
   8.118 +	 * FIXME: rename, refactor
   8.119 +	 */
   8.120 +	void finish() {
   8.121 +		index = MEMORY_SIZE;
   8.122 +	}
   8.123 +};
     9.1 --- a/c++/rgb-assembler/rgb-assembler.cpp	Sun Dec 24 00:47:34 2017 +0100
     9.2 +++ b/c++/rgb-assembler/rgb-assembler.cpp	Mon Dec 25 00:24:07 2017 +0100
     9.3 @@ -40,41 +40,40 @@
     9.4  
     9.5  	setlocale(LC_ALL, "");
     9.6  
     9.7 -	// TODO: wrap in a class with read(), write() and setAddress() methods
     9.8 -	octet_t * memory = (octet_t*) malloc(MEMORY_SIZE);
     9.9 -
    9.10 +	Memory memory;
    9.11 +	
    9.12  	// Sample program / data:
    9.13  	// TODO: load bytes from file, stdin, serial port, network…
    9.14  	{
    9.15 -		address_t a = 0;
    9.16 -		write<command_t>(memory, a, CMD_SLEEP);
    9.17 -		write<sleep_t>(memory, a, 255);
    9.18 -		write<command_t>(memory, a, CMD_SLEEP);
    9.19 -		write<sleep_t>(memory, a, 10);
    9.20 -		write<command_t>(memory, a, CMD_SLEEP);
    9.21 -		write<sleep_t>(memory, a, 255);
    9.22 -		write<command_t>(memory, a, CMD_GOTO);
    9.23 -		write<address_t>(memory, a, a + sizeof (address_t) + 2 * sizeof (command_t));
    9.24 -		write<command_t>(memory, a, CMD_INVALID);
    9.25 -		write<command_t>(memory, a, CMD_INVALID);
    9.26 -		write<command_t>(memory, a, CMD_SLEEP);
    9.27 -		write<sleep_t>(memory, a, 255);
    9.28 -		write<command_t>(memory, a, CMD_COLOR);
    9.29 -		write<led_t>(memory, a, 23);
    9.30 -		write<color_t>(memory, a, 0);
    9.31 -		write<color_t>(memory, a, 200);
    9.32 -		write<color_t>(memory, a, 255);
    9.33 -		write<command_t>(memory, a, CMD_INCREMENT);
    9.34 -		write<address_t>(memory, a, 0);
    9.35 -		write<command_t>(memory, a, CMD_DECREMENT);
    9.36 -		write<address_t>(memory, a, 0);
    9.37 -		write<command_t>(memory, a, CMD_GOTO_COMPARE);
    9.38 -		write<address_t>(memory, a, 0);
    9.39 -		write<address_t>(memory, a, 0 + sizeof (command_t) + sizeof (sleep_t));
    9.40 -		write<address_t>(memory, a, a - 3 * sizeof (address_t) - 2 * sizeof (command_t));
    9.41 -		write<address_t>(memory, a, 0);
    9.42 -		write<address_t>(memory, a, a + sizeof (address_t));
    9.43 -		write<command_t>(memory, a, CMD_END);
    9.44 +		memory.write<command_t>(CMD_SLEEP);
    9.45 +		memory.write<sleep_t>(255);
    9.46 +		memory.write<command_t>(CMD_SLEEP);
    9.47 +		memory.write<sleep_t>(10);
    9.48 +		memory.write<command_t>(CMD_SLEEP);
    9.49 +		memory.write<sleep_t>(255);
    9.50 +		memory.write<command_t>(CMD_GOTO);
    9.51 +		memory.write<address_t>(memory.getIndex() + sizeof (address_t) + 2 * sizeof (command_t));
    9.52 +		memory.write<command_t>(CMD_INVALID);
    9.53 +		memory.write<command_t>(CMD_INVALID);
    9.54 +		memory.write<command_t>(CMD_SLEEP);
    9.55 +		memory.write<sleep_t>(255);
    9.56 +		memory.write<command_t>(CMD_COLOR);
    9.57 +		memory.write<led_t>(23);
    9.58 +		memory.write<color_t>(0);
    9.59 +		memory.write<color_t>(200);
    9.60 +		memory.write<color_t>(255);
    9.61 +		memory.write<command_t>(CMD_INCREMENT);
    9.62 +		memory.write<address_t>(0);
    9.63 +		memory.write<command_t>(CMD_DECREMENT);
    9.64 +		memory.write<address_t>(0);
    9.65 +		memory.write<command_t>(CMD_GOTO_COMPARE);
    9.66 +		memory.write<address_t>(0);
    9.67 +		memory.write<address_t>(0 + sizeof (command_t) + sizeof (sleep_t));
    9.68 +		memory.write<address_t>(memory.getIndex() - 3 * sizeof (address_t) - 2 * sizeof (command_t));
    9.69 +		memory.write<address_t>(0);
    9.70 +		memory.write<address_t>(memory.getIndex() + sizeof (address_t));
    9.71 +		memory.write<command_t>(CMD_END);
    9.72 +		memory.start();
    9.73  	}
    9.74  
    9.75  	// Supported commands
    9.76 @@ -91,22 +90,20 @@
    9.77  
    9.78  
    9.79  	// Main loop / interpreter:
    9.80 -	for (address_t i = 0; i < MEMORY_SIZE;) {
    9.81 -		wprintf(L"command %*d = ", 4, i);
    9.82 -		command_t commandCode = read<command_t>(memory, i);
    9.83 +	while (memory.isInside()) {
    9.84 +		wprintf(L"command %*d = ", 4, memory.getIndex());
    9.85 +		command_t commandCode = memory.read<command_t>();
    9.86  		wprintf(L"%02X  ", commandCode);
    9.87  
    9.88  		shared_ptr<Command> command = commands[commandCode];
    9.89  
    9.90  		if (command) {
    9.91 -			command->process(memory, i);
    9.92 +			command->process(memory);
    9.93  		} else {
    9.94  			wprintf(L"invalid command\n");
    9.95  		}
    9.96  	}
    9.97  
    9.98 -	free(memory);
    9.99 -	memory = nullptr;
   9.100  	wprintf(L"all done\n");
   9.101  	return 0;
   9.102  }