c++/rgb-assembler/Memory.h
author František Kučera <franta-hg@frantovo.cz>
Mon, 25 Dec 2017 01:34:06 +0100
changeset 34 d7eed4d972de
parent 33 ff150572e8c0
child 35 84356a15828b
permissions -rw-r--r--
parametric memory size
     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 #pragma once
    20 
    21 #include "types.h"
    22 
    23 class Memory {
    24 private:
    25 
    26 	template<typename T> T logMemoryError(const address_t &index) {
    27 		wprintf(L"memory error: index = %d, sizeof(T) = %d, MEMORY_SIZE = %d\n", index, sizeof (T), memorySize);
    28 		// TODO: return error value or throw exception
    29 		return T();
    30 	}
    31 
    32 	octet_t * memory;
    33 	address_t memorySize;
    34 	address_t index;
    35 
    36 public:
    37 
    38 	Memory(const address_t memorySize) {
    39 		this->memory = (octet_t*) malloc(memorySize);
    40 		this->memorySize = memorySize;
    41 		this->index = 0;
    42 	}
    43 
    44 	virtual ~Memory() {
    45 		free(memory);
    46 		memory = nullptr;
    47 	}
    48 
    49 	/**
    50 	 * Reads data on current position in memory and increments the index (position).
    51 	 * @return value found at current position
    52 	 */
    53 	template<typename T> T read() {
    54 		// TODO: map higher memory to static hardcoded areas or peripherals
    55 		if (index + sizeof (T) <= memorySize) {
    56 			T * value = reinterpret_cast<T*> (memory + index);
    57 			index += sizeof (T);
    58 			return *value;
    59 		} else {
    60 			return logMemoryError<T>(index);
    61 		}
    62 	}
    63 
    64 	/**
    65 	 * Reads data on given position in memory (without affecting the current position).
    66 	 * @return value found at given position
    67 	 */
    68 	template<typename T> T read(const address_t &address) {
    69 		// TODO: map higher memory to static hardcoded areas or peripherals
    70 		if (address + sizeof (T) <= memorySize) {
    71 			return *(reinterpret_cast<T*> (memory + address));
    72 		} else {
    73 			return logMemoryError<T>(address);
    74 		}
    75 	}
    76 
    77 	/**
    78 	 * Writes data to current position in memory and increments the index (position).
    79 	 * @param value value to be written at current position
    80 	 */
    81 	template<typename T> T write(const T value) {
    82 		if (index + sizeof (T) <= memorySize) {
    83 			T * m = reinterpret_cast<T*> (memory + index);
    84 			*m = value;
    85 			index += sizeof (value);
    86 		} else {
    87 			return logMemoryError<T>(index);
    88 		}
    89 	}
    90 
    91 	/**
    92 	 * Writes data to given position in memory (without affecting the current position).
    93 	 * @param value value to be written at given position
    94 	 */
    95 	template<typename T> T write(const address_t &address, const T value) {
    96 		if (address + sizeof (T) <= memorySize) {
    97 			T * m = reinterpret_cast<T*> (memory + address);
    98 			*m = value;
    99 		} else {
   100 			return logMemoryError<T>(address);
   101 		}
   102 	}
   103 
   104 	/**
   105 	 * Set current addres to given position.
   106 	 * @param index
   107 	 */
   108 	void setAddress(address_t &index) {
   109 		this->index = index;
   110 	}
   111 
   112 	/**
   113 	 * @return Current position in the memory.
   114 	 */
   115 	address_t getAddress() {
   116 		return index;
   117 	}
   118 
   119 	/**
   120 	 * @return whether the current position is inside the memory boundaries = still processing.
   121 	 */
   122 	bool isNotOver() {
   123 		return index < memorySize;
   124 	}
   125 
   126 	/**
   127 	 * Set current position to the start of the memory = position 0.
   128 	 */
   129 	void setAddressToBeginning() {
   130 		index = 0;
   131 	}
   132 
   133 	/**
   134 	 * Set current position behind the end of the memory = stop processing.
   135 	 */
   136 	void setAddressToEnd() {
   137 		index = memorySize;
   138 	}
   139 };