franta-hg@29: /**
franta-hg@29: * RGB assembler
franta-hg@29: * Copyright © 2017 František Kučera (frantovo.cz)
franta-hg@29: *
franta-hg@29: * This program is free software: you can redistribute it and/or modify
franta-hg@29: * it under the terms of the GNU General Public License as published by
franta-hg@29: * the Free Software Foundation, either version 3 of the License, or
franta-hg@29: * (at your option) any later version.
franta-hg@29: *
franta-hg@29: * This program is distributed in the hope that it will be useful,
franta-hg@29: * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@29: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@29: * GNU General Public License for more details.
franta-hg@29: *
franta-hg@29: * You should have received a copy of the GNU General Public License
franta-hg@29: * along with this program. If not, see .
franta-hg@29: */
franta-hg@29:
franta-hg@20: #pragma once
franta-hg@20:
franta-hg@20: #include "types.h"
franta-hg@20:
franta-hg@31: class Memory {
franta-hg@31: private:
franta-hg@20:
franta-hg@31: template T logMemoryError(const address_t &index) {
franta-hg@34: wprintf(L"memory error: index = %d, sizeof(T) = %d, MEMORY_SIZE = %d\n", index, sizeof (T), memorySize);
franta-hg@31: // TODO: return error value or throw exception
franta-hg@31: return T();
franta-hg@20: }
franta-hg@34:
franta-hg@31: octet_t * memory;
franta-hg@34: address_t memorySize;
franta-hg@31: address_t index;
franta-hg@20:
franta-hg@31: public:
franta-hg@31:
franta-hg@34: Memory(const address_t memorySize) {
franta-hg@34: this->memory = (octet_t*) malloc(memorySize);
franta-hg@34: this->memorySize = memorySize;
franta-hg@34: this->index = 0;
franta-hg@20: }
franta-hg@31:
franta-hg@31: virtual ~Memory() {
franta-hg@31: free(memory);
franta-hg@31: }
franta-hg@31:
franta-hg@31: /**
franta-hg@33: * Reads data on current position in memory and increments the index (position).
franta-hg@31: * @return value found at current position
franta-hg@31: */
franta-hg@31: template T read() {
franta-hg@31: // TODO: map higher memory to static hardcoded areas or peripherals
franta-hg@34: if (index + sizeof (T) <= memorySize) {
franta-hg@31: T * value = reinterpret_cast (memory + index);
franta-hg@31: index += sizeof (T);
franta-hg@31: return *value;
franta-hg@31: } else {
franta-hg@31: return logMemoryError(index);
franta-hg@31: }
franta-hg@31: }
franta-hg@31:
franta-hg@31: /**
franta-hg@33: * Reads data on given position in memory (without affecting the current position).
franta-hg@33: * @return value found at given position
franta-hg@33: */
franta-hg@33: template T read(const address_t &address) {
franta-hg@33: // TODO: map higher memory to static hardcoded areas or peripherals
franta-hg@34: if (address + sizeof (T) <= memorySize) {
franta-hg@33: return *(reinterpret_cast (memory + address));
franta-hg@33: } else {
franta-hg@33: return logMemoryError(address);
franta-hg@33: }
franta-hg@33: }
franta-hg@33:
franta-hg@33: /**
franta-hg@31: * Writes data to current position in memory and increments the index (position).
franta-hg@33: * @param value value to be written at current position
franta-hg@31: */
franta-hg@36: template void write(const T value) {
franta-hg@34: if (index + sizeof (T) <= memorySize) {
franta-hg@31: T * m = reinterpret_cast (memory + index);
franta-hg@31: *m = value;
franta-hg@31: index += sizeof (value);
franta-hg@31: } else {
franta-hg@36: logMemoryError(index);
franta-hg@31: }
franta-hg@31: }
franta-hg@31:
franta-hg@33: /**
franta-hg@33: * Writes data to given position in memory (without affecting the current position).
franta-hg@33: * @param value value to be written at given position
franta-hg@33: */
franta-hg@36: template void write(const address_t &address, const T value) {
franta-hg@34: if (address + sizeof (T) <= memorySize) {
franta-hg@33: T * m = reinterpret_cast (memory + address);
franta-hg@33: *m = value;
franta-hg@33: } else {
franta-hg@36: logMemoryError(address);
franta-hg@33: }
franta-hg@33: }
franta-hg@33:
franta-hg@33: /**
franta-hg@33: * Set current addres to given position.
franta-hg@33: * @param index
franta-hg@33: */
franta-hg@33: void setAddress(address_t &index) {
franta-hg@31: this->index = index;
franta-hg@31: }
franta-hg@31:
franta-hg@33: /**
franta-hg@33: * @return Current position in the memory.
franta-hg@33: */
franta-hg@33: address_t getAddress() {
franta-hg@31: return index;
franta-hg@31: }
franta-hg@31:
franta-hg@31: /**
franta-hg@33: * @return whether the current position is inside the memory boundaries = still processing.
franta-hg@31: */
franta-hg@33: bool isNotOver() {
franta-hg@34: return index < memorySize;
franta-hg@31: }
franta-hg@33:
franta-hg@31: /**
franta-hg@33: * Set current position to the start of the memory = position 0.
franta-hg@31: */
franta-hg@33: void setAddressToBeginning() {
franta-hg@31: index = 0;
franta-hg@31: }
franta-hg@31:
franta-hg@31: /**
franta-hg@33: * Set current position behind the end of the memory = stop processing.
franta-hg@31: */
franta-hg@33: void setAddressToEnd() {
franta-hg@34: index = memorySize;
franta-hg@31: }
franta-hg@31: };