mirror of
https://github.com/hch12907/orbum.git
synced 2024-05-20 13:07:53 -04:00
More speedups...
This commit is contained in:
parent
c7e37542a2
commit
ba73a24a8a
|
@ -1,5 +1,8 @@
|
||||||
# CMake 3.8.2 is needed for C++17 support.
|
# CMake 3.8.2 is needed for C++17 support.
|
||||||
cmake_minimum_required(VERSION 3.8.2)
|
# CMake 3.9 is needed for LTO support.
|
||||||
|
cmake_minimum_required(VERSION 3.9)
|
||||||
|
cmake_policy(SET CMP0069 NEW) # Link time optimization support
|
||||||
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Pre-project options #
|
# Pre-project options #
|
||||||
|
@ -13,20 +16,29 @@ project(orbum CXX)
|
||||||
###########
|
###########
|
||||||
# Options #
|
# Options #
|
||||||
###########
|
###########
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out")
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out")
|
|
||||||
set(BUILD_SHARED_LIBS on)
|
set(BUILD_SHARED_LIBS on)
|
||||||
|
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE on)
|
||||||
|
|
||||||
|
include(CheckIPOSupported)
|
||||||
|
check_ipo_supported(RESULT ipo_result)
|
||||||
|
if(ipo_result)
|
||||||
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION on)
|
||||||
|
endif()
|
||||||
|
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -pthread")
|
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -pthread")
|
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out")
|
||||||
|
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out")
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||||
|
|
||||||
|
|
||||||
################
|
################
|
||||||
# Dependencies #
|
# Dependencies #
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.8.2)
|
cmake_minimum_required(VERSION 3.9)
|
||||||
|
cmake_policy(SET CMP0069 NEW) # Link time optimization support
|
||||||
|
|
||||||
project(liborbum CXX)
|
project(liborbum CXX)
|
||||||
|
|
||||||
|
@ -10,16 +11,11 @@ set(COMMON_SRC_FILES
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Bus/ByteBus.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Bus/ByteBus.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Bus/ByteBusMappable.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Bus/ByteBusMappable.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FifoQueue/DmaFifoQueue.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FifoQueue/DmaFifoQueue.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FifoQueue/FifoQueue.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FifoQueue/FifoQueue.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FifoQueue/FifoQueue.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FpuFlags.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/FpuFlags.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ArrayByteMemory.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ArrayByteMemory.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ArrayByteMemory.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ArrayHwordMemory.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ArrayHwordMemory.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ArrayHwordMemory.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ByteMemory.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ByteMemory.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/ByteMemory.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/HwordMemory.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/HwordMemory.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Memory/HwordMemory.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/BranchDelaySlot.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/BranchDelaySlot.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/MipsCoprocessor.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/MipsCoprocessor.hpp"
|
||||||
|
@ -28,27 +24,16 @@ set(COMMON_SRC_FILES
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/MipsInstructionInfo.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/MipsInstructionInfo.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/MmuAccess.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Mips/MmuAccess.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Primitive.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Primitive.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/ByteRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/ByteRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/ByteRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/DwordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/DwordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/DwordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/HwordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/HwordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/HwordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/MapperHwordWordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/MapperHwordWordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/MapperHwordWordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/QwordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/QwordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/QwordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedByteRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedByteRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedByteRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedDwordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedDwordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedDwordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedHwordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedHwordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedHwordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedQwordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedQwordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedQwordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedWordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedWordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/SizedWordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/WordRegister.cpp"
|
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/WordRegister.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/WordRegister.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/PcRegisters.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/Register/PcRegisters.hpp"
|
||||||
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/ScopeLock.hpp"
|
"${CMAKE_SOURCE_DIR}/liborbum/src/Common/Types/ScopeLock.hpp"
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
#include "Common/Types/FifoQueue/FifoQueue.hpp"
|
|
||||||
|
|
||||||
void FifoQueue::read(ubyte* buffer, const size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
buffer[i] = read_ubyte();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FifoQueue::write(const ubyte* buffer, const size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
write_ubyte(buffer[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte FifoQueue::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FifoQueue::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword FifoQueue::byte_bus_read_uhword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
uhword value;
|
|
||||||
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_HWORD);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FifoQueue::byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
|
||||||
{
|
|
||||||
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
uword FifoQueue::byte_bus_read_uword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
uword value;
|
|
||||||
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_WORD);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FifoQueue::byte_bus_write_uword(const BusContext context, const usize offset, const uword value)
|
|
||||||
{
|
|
||||||
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_WORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
udword FifoQueue::byte_bus_read_udword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
udword value;
|
|
||||||
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_DWORD);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FifoQueue::byte_bus_write_udword(const BusContext context, const usize offset, const udword value)
|
|
||||||
{
|
|
||||||
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_DWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
uqword FifoQueue::byte_bus_read_uqword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
uqword value;
|
|
||||||
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_QWORD);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FifoQueue::byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value)
|
|
||||||
{
|
|
||||||
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_QWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FifoQueue::is_empty() const
|
|
||||||
{
|
|
||||||
return !has_read_available(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FifoQueue::is_full() const
|
|
||||||
{
|
|
||||||
return !has_write_available(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
usize FifoQueue::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(1);
|
|
||||||
}
|
|
|
@ -22,11 +22,19 @@ public:
|
||||||
|
|
||||||
/// Reads bytes to the buffer given.
|
/// Reads bytes to the buffer given.
|
||||||
/// This is a wrapper around the read_ubyte function, and should not be treated as a separate interface (not made virtual).
|
/// This is a wrapper around the read_ubyte function, and should not be treated as a separate interface (not made virtual).
|
||||||
void read(ubyte * buffer, const size_t length);
|
void read(ubyte * buffer, const size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
buffer[i] = read_ubyte();
|
||||||
|
}
|
||||||
|
|
||||||
/// Writes bytes from the buffer given.
|
/// Writes bytes from the buffer given.
|
||||||
/// This is a wrapper around the write_ubyte function, and should not be treated as a separate interface (not made virtual).
|
/// This is a wrapper around the write_ubyte function, and should not be treated as a separate interface (not made virtual).
|
||||||
void write(const ubyte * buffer, const size_t length);
|
void write(const ubyte * buffer, const size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
write_ubyte(buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if the queue has at least n_bytes available for reading.
|
/// Checks if the queue has at least n_bytes available for reading.
|
||||||
virtual bool has_read_available(const size_t n_bytes) const = 0;
|
virtual bool has_read_available(const size_t n_bytes) const = 0;
|
||||||
|
@ -35,23 +43,80 @@ public:
|
||||||
virtual bool has_write_available(const size_t n_bytes) const = 0;
|
virtual bool has_write_available(const size_t n_bytes) const = 0;
|
||||||
|
|
||||||
/// Check if queue is full/empty (wrappers around above functions).
|
/// Check if queue is full/empty (wrappers around above functions).
|
||||||
bool is_empty() const;
|
bool is_empty() const
|
||||||
bool is_full() const;
|
{
|
||||||
|
return !has_read_available(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_full() const
|
||||||
|
{
|
||||||
|
return !has_write_available(1);
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
/// For the FifoQueue object, the map size is always one byte.
|
/// For the FifoQueue object, the map size is always one byte.
|
||||||
/// The offset is not used in reading or writing to the queue.
|
/// The offset is not used in reading or writing to the queue.
|
||||||
/// For a larger mapping, map the queue multiple times.
|
/// For a larger mapping, map the queue multiple times.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
{
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
return static_cast<usize>(1);
|
||||||
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override;
|
}
|
||||||
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override;
|
|
||||||
uword byte_bus_read_uword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override;
|
|
||||||
udword byte_bus_read_udword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override;
|
|
||||||
uqword byte_bus_read_uqword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_ubyte();
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
write_ubyte(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
uhword value;
|
||||||
|
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_HWORD);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override
|
||||||
|
{
|
||||||
|
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_HWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
uword byte_bus_read_uword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
uword value;
|
||||||
|
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_WORD);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override
|
||||||
|
{
|
||||||
|
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_WORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
udword byte_bus_read_udword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
udword value;
|
||||||
|
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_DWORD);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override
|
||||||
|
{
|
||||||
|
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_DWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
uqword byte_bus_read_uqword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
uqword value;
|
||||||
|
read(reinterpret_cast<ubyte*>(&value), NUMBER_BYTES_IN_QWORD);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value) override
|
||||||
|
{
|
||||||
|
write(reinterpret_cast<const ubyte*>(&value), NUMBER_BYTES_IN_QWORD);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "Common/Types/Memory/ArrayByteMemory.hpp"
|
|
||||||
|
|
||||||
ArrayByteMemory::ArrayByteMemory(const size_t size, const ubyte initial_value, const bool read_only) :
|
|
||||||
size(size),
|
|
||||||
memory(size, initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::initialise()
|
|
||||||
{
|
|
||||||
std::vector<ubyte>(size, initial_value).swap(memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::read_from_file(const std::string & path, const size_t file_length)
|
|
||||||
{
|
|
||||||
std::ifstream file(path, std::ios_base::binary);
|
|
||||||
if (!file)
|
|
||||||
throw std::runtime_error("Unable to read file");
|
|
||||||
file.read(reinterpret_cast<char*>(&memory[0]), file_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::write_to_file(const std::string & path)
|
|
||||||
{
|
|
||||||
std::ofstream file(path, std::ios_base::binary);
|
|
||||||
if (!file)
|
|
||||||
throw std::runtime_error("Unable to write file");
|
|
||||||
file.write(reinterpret_cast<char*>(&memory[0]), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte ArrayByteMemory::read_ubyte(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<ubyte*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::write_ubyte(const size_t offset, const ubyte value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<ubyte*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword ArrayByteMemory::read_uhword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<uhword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::write_uhword(const size_t offset, const uhword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<uhword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uword ArrayByteMemory::read_uword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<uword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::write_uword(const size_t offset, const uword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<uword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
udword ArrayByteMemory::read_udword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<udword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::write_udword(const size_t offset, const udword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<udword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uqword ArrayByteMemory::read_uqword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<uqword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayByteMemory::write_uqword(const size_t offset, const uqword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<uqword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
usize ArrayByteMemory::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ubyte>& ArrayByteMemory::get_memory()
|
|
||||||
{
|
|
||||||
return memory;
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "Common/Types/Memory/ByteMemory.hpp"
|
#include "Common/Types/Memory/ByteMemory.hpp"
|
||||||
|
|
||||||
|
@ -9,37 +10,158 @@
|
||||||
class ArrayByteMemory : public ByteMemory
|
class ArrayByteMemory : public ByteMemory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArrayByteMemory(const size_t size, const ubyte initial_value = 0, const bool read_only = false);
|
ArrayByteMemory(const size_t size, const ubyte initial_value = 0, const bool read_only = false) :
|
||||||
|
size(size),
|
||||||
|
memory(size, initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise memory.
|
/// Initialise memory.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
std::vector<ubyte>(size, initial_value).swap(memory);
|
||||||
|
}
|
||||||
|
|
||||||
/// Read in a raw file to the memory (byte copy).
|
/// Read in a raw file to the memory (byte copy).
|
||||||
/// For Core use only! Do not use within the controller logic.
|
/// For Core use only! Do not use within the controller logic.
|
||||||
void read_from_file(const std::string & path, const size_t file_length);
|
void read_from_file(const std::string & path, const size_t file_length)
|
||||||
|
{
|
||||||
|
std::ifstream file(path, std::ios_base::binary);
|
||||||
|
if (!file)
|
||||||
|
throw std::runtime_error("Unable to read file");
|
||||||
|
file.read(reinterpret_cast<char*>(&memory[0]), file_length);
|
||||||
|
}
|
||||||
|
|
||||||
/// Dumps the memory contents to a file.
|
/// Dumps the memory contents to a file.
|
||||||
/// For Core use only! Do not use within the controller logic.
|
/// For Core use only! Do not use within the controller logic.
|
||||||
void write_to_file(const std::string & path);
|
void write_to_file(const std::string & path)
|
||||||
|
{
|
||||||
|
std::ofstream file(path, std::ios_base::binary);
|
||||||
|
if (!file)
|
||||||
|
throw std::runtime_error("Unable to write file");
|
||||||
|
file.write(reinterpret_cast<char*>(&memory[0]), size);
|
||||||
|
}
|
||||||
|
|
||||||
/// Read or write a value of a given type, to the specified byte index (offset).
|
/// Read or write a value of a given type, to the specified byte index (offset).
|
||||||
ubyte read_ubyte(const size_t offset) override;
|
ubyte read_ubyte(const size_t offset) override
|
||||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
{
|
||||||
uhword read_uhword(const size_t offset) override;
|
#if defined(BUILD_DEBUG)
|
||||||
void write_uhword(const size_t offset, const uhword value) override;
|
if (offset >= size)
|
||||||
uword read_uword(const size_t offset) override;
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
void write_uword(const size_t offset, const uword value) override;
|
#endif
|
||||||
udword read_udword(const size_t offset) override;
|
|
||||||
void write_udword(const size_t offset, const udword value) override;
|
return *reinterpret_cast<ubyte*>(&memory[offset]);
|
||||||
uqword read_uqword(const size_t offset) override;
|
}
|
||||||
void write_uqword(const size_t offset, const uqword value) override;
|
|
||||||
|
void write_ubyte(const size_t offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<ubyte*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword read_uhword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<uhword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const size_t offset, const uhword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<uhword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uword read_uword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<uword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uword(const size_t offset, const uword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<uword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
udword read_udword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<udword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_udword(const size_t offset, const udword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<udword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uqword read_uqword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<uqword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uqword(const size_t offset, const uqword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayByteMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<uqword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
|
{
|
||||||
|
return static_cast<usize>(size);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a reference to the memory storage.
|
/// Get a reference to the memory storage.
|
||||||
/// Used for the emulator: sometimes we need to peek and poke directly.
|
/// Used for the emulator: sometimes we need to peek and poke directly.
|
||||||
std::vector<ubyte> & get_memory();
|
std::vector<ubyte> & get_memory()
|
||||||
|
{
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Total size of the byte memory.
|
/// Total size of the byte memory.
|
||||||
|
@ -55,4 +177,3 @@ private:
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "Common/Types/Memory/ArrayHwordMemory.hpp"
|
|
||||||
|
|
||||||
ArrayHwordMemory::ArrayHwordMemory(const size_t size, const uhword initial_value, const bool read_only) :
|
|
||||||
size(size),
|
|
||||||
memory(size, initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::initialise()
|
|
||||||
{
|
|
||||||
std::vector<uhword>(size, initial_value).swap(memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword ArrayHwordMemory::read_uhword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<uhword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::write_uhword(const size_t offset, const uhword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<uhword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uword ArrayHwordMemory::read_uword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<uword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::write_uword(const size_t offset, const uword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<uword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
udword ArrayHwordMemory::read_udword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<udword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::write_udword(const size_t offset, const udword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<udword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uqword ArrayHwordMemory::read_uqword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return *reinterpret_cast<uqword*>(&memory[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::write_uqword(const size_t offset, const uqword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= size)
|
|
||||||
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
*reinterpret_cast<uqword*>(&memory[offset]) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uhword>& ArrayHwordMemory::get_memory()
|
|
||||||
{
|
|
||||||
return memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::read_from_file(const std::string & path, const size_t file_length)
|
|
||||||
{
|
|
||||||
std::ifstream file(path, std::ios_base::binary);
|
|
||||||
if (!file)
|
|
||||||
throw std::runtime_error("Unable to read file");
|
|
||||||
file.read(reinterpret_cast<char*>(&memory[0]), file_length * NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayHwordMemory::write_to_file(const std::string & path)
|
|
||||||
{
|
|
||||||
std::ofstream file(path, std::ios_base::binary);
|
|
||||||
if (!file)
|
|
||||||
throw std::runtime_error("Unable to write file");
|
|
||||||
file.write(reinterpret_cast<char*>(&memory[0]), size * NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "Common/Types/Memory/HwordMemory.hpp"
|
#include "Common/Types/Memory/HwordMemory.hpp"
|
||||||
|
|
||||||
|
@ -9,32 +10,131 @@
|
||||||
class ArrayHwordMemory : public HwordMemory
|
class ArrayHwordMemory : public HwordMemory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArrayHwordMemory(const size_t size, const uhword initial_value = 0, const bool read_only = false);
|
ArrayHwordMemory(const size_t size, const uhword initial_value = 0, const bool read_only = false) :
|
||||||
|
size(size),
|
||||||
|
memory(size, initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise memory.
|
/// Initialise memory.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
std::vector<uhword>(size, initial_value).swap(memory);
|
||||||
|
}
|
||||||
|
|
||||||
/// Read in a raw file to the memory (hword copy).
|
/// Read in a raw file to the memory (hword copy).
|
||||||
/// For Core use only! Do not use within the controller logic.
|
/// For Core use only! Do not use within the controller logic.
|
||||||
void read_from_file(const std::string & path, const size_t file_length);
|
void read_from_file(const std::string & path, const size_t file_length)
|
||||||
|
{
|
||||||
|
std::ifstream file(path, std::ios_base::binary);
|
||||||
|
if (!file)
|
||||||
|
throw std::runtime_error("Unable to read file");
|
||||||
|
file.read(reinterpret_cast<char*>(&memory[0]), file_length * NUMBER_BYTES_IN_HWORD);
|
||||||
|
}
|
||||||
|
|
||||||
/// Dumps the memory contents to a file.
|
/// Dumps the memory contents to a file.
|
||||||
/// For Core use only! Do not use within the controller logic.
|
/// For Core use only! Do not use within the controller logic.
|
||||||
void write_to_file(const std::string & path);
|
void write_to_file(const std::string & path)
|
||||||
|
{
|
||||||
|
std::ofstream file(path, std::ios_base::binary);
|
||||||
|
if (!file)
|
||||||
|
throw std::runtime_error("Unable to write file");
|
||||||
|
file.write(reinterpret_cast<char*>(&memory[0]), size * NUMBER_BYTES_IN_HWORD);
|
||||||
|
}
|
||||||
|
|
||||||
/// Read or write a value of a given type, to the specified hword index (offset).
|
/// Read or write a value of a given type, to the specified hword index (offset).
|
||||||
uhword read_uhword(const size_t offset) override;
|
uhword read_uhword(const size_t offset) override
|
||||||
void write_uhword(const size_t offset, const uhword value) override;
|
{
|
||||||
uword read_uword(const size_t offset) override;
|
#if defined(BUILD_DEBUG)
|
||||||
void write_uword(const size_t offset, const uword value) override;
|
if (offset >= size)
|
||||||
udword read_udword(const size_t offset) override;
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
void write_udword(const size_t offset, const udword value) override;
|
#endif
|
||||||
uqword read_uqword(const size_t offset) override;
|
|
||||||
void write_uqword(const size_t offset, const uqword value) override;
|
return *reinterpret_cast<uhword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const size_t offset, const uhword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<uhword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uword read_uword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<uword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uword(const size_t offset, const uword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<uword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
udword read_udword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<udword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_udword(const size_t offset, const udword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<udword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uqword read_uqword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return *reinterpret_cast<uqword*>(&memory[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uqword(const size_t offset, const uqword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= size)
|
||||||
|
throw std::runtime_error("Tried to access ArrayHwordMemory with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
*reinterpret_cast<uqword*>(&memory[offset]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a reference to the memory storage.
|
/// Get a reference to the memory storage.
|
||||||
/// Used for the emulator: sometimes we need to peek and poke directly.
|
/// Used for the emulator: sometimes we need to peek and poke directly.
|
||||||
std::vector<uhword> & get_memory();
|
std::vector<uhword> & get_memory()
|
||||||
|
{
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Total size of the hword memory.
|
/// Total size of the hword memory.
|
||||||
|
@ -50,4 +150,3 @@ private:
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
#include "Common/Types/Memory/ByteMemory.hpp"
|
|
||||||
|
|
||||||
void ByteMemory::read(const size_t offset, ubyte * buffer, const size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
buffer[i] = read_ubyte(offset + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteMemory::write(const size_t offset, const ubyte * buffer, const size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
write_ubyte(offset + i, buffer[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte ByteMemory::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteMemory::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword ByteMemory::byte_bus_read_uhword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uhword(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteMemory::byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
|
||||||
{
|
|
||||||
write_uhword(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uword ByteMemory::byte_bus_read_uword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uword(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteMemory::byte_bus_write_uword(const BusContext context, const usize offset, const uword value)
|
|
||||||
{
|
|
||||||
write_uword(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
udword ByteMemory::byte_bus_read_udword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_udword(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteMemory::byte_bus_write_udword(const BusContext context, const usize offset, const udword value)
|
|
||||||
{
|
|
||||||
write_udword(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uqword ByteMemory::byte_bus_read_uqword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uqword(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteMemory::byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value)
|
|
||||||
{
|
|
||||||
write_uqword(offset, value);
|
|
||||||
}
|
|
|
@ -27,22 +27,68 @@ public:
|
||||||
|
|
||||||
/// Reads bytes to the buffer given.
|
/// Reads bytes to the buffer given.
|
||||||
/// This is a wrapper around the read_ubyte function, and should not be treated as a separate interface (not made virtual).
|
/// This is a wrapper around the read_ubyte function, and should not be treated as a separate interface (not made virtual).
|
||||||
void read(const size_t offset, ubyte * buffer, const size_t length);
|
void read(const size_t offset, ubyte * buffer, const size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
buffer[i] = read_ubyte(offset + i);
|
||||||
|
}
|
||||||
|
|
||||||
/// Writes bytes from the buffer given.
|
/// Writes bytes from the buffer given.
|
||||||
/// This is a wrapper around the write_ubyte function, and should not be treated as a separate interface (not made virtual).
|
/// This is a wrapper around the write_ubyte function, and should not be treated as a separate interface (not made virtual).
|
||||||
void write(const size_t offset, const ubyte * buffer, const size_t length);
|
void write(const size_t offset, const ubyte * buffer, const size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
write_ubyte(offset + i, buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset)
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
{
|
||||||
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override;
|
return read_ubyte(offset);
|
||||||
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override;
|
}
|
||||||
uword byte_bus_read_uword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override;
|
|
||||||
udword byte_bus_read_udword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override;
|
|
||||||
uqword byte_bus_read_uqword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
||||||
|
{
|
||||||
|
write_ubyte(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword byte_bus_read_uhword(const BusContext context, const usize offset)
|
||||||
|
{
|
||||||
|
return read_uhword(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
||||||
|
{
|
||||||
|
write_uhword(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uword byte_bus_read_uword(const BusContext context, const usize offset)
|
||||||
|
{
|
||||||
|
return read_uword(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value)
|
||||||
|
{
|
||||||
|
write_uword(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
udword byte_bus_read_udword(const BusContext context, const usize offset)
|
||||||
|
{
|
||||||
|
return read_udword(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value)
|
||||||
|
{
|
||||||
|
write_udword(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uqword byte_bus_read_uqword(const BusContext context, const usize offset)
|
||||||
|
{
|
||||||
|
return read_uqword(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value)
|
||||||
|
{
|
||||||
|
write_uqword(offset, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#include "Common/Types/Memory/HwordMemory.hpp"
|
|
||||||
|
|
||||||
void HwordMemory::read(const size_t offset, uhword * buffer, const size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
buffer[i] = read_uhword(offset + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwordMemory::write(const size_t offset, const uhword * buffer, const size_t length)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < length; i++)
|
|
||||||
write_uhword(offset + i, buffer[i]);
|
|
||||||
}
|
|
|
@ -23,10 +23,17 @@ public:
|
||||||
|
|
||||||
/// Reads hwords to the buffer given.
|
/// Reads hwords to the buffer given.
|
||||||
/// This is a wrapper around the read_uhword function, and should not be treated as a separate interface (not made virtual).
|
/// This is a wrapper around the read_uhword function, and should not be treated as a separate interface (not made virtual).
|
||||||
void read(const size_t offset, uhword * buffer, const size_t length);
|
void read(const size_t offset, uhword * buffer, const size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
buffer[i] = read_uhword(offset + i);
|
||||||
|
}
|
||||||
|
|
||||||
/// Writes hwords from the buffer given.
|
/// Writes hwords from the buffer given.
|
||||||
/// This is a wrapper around the write_uhword function, and should not be treated as a separate interface (not made virtual).
|
/// This is a wrapper around the write_uhword function, and should not be treated as a separate interface (not made virtual).
|
||||||
void write(const size_t offset, const uhword * buffer, const size_t length);
|
void write(const size_t offset, const uhword * buffer, const size_t length)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < length; i++)
|
||||||
|
write_uhword(offset + i, buffer[i]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/Types/Primitive.hpp"
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Register/WordRegister.hpp"
|
#include "Common/Types/Register/PcRegisters.hpp"
|
||||||
|
|
||||||
/// Contains functionallity for the branch delay slot featured in MIPS CPU's.
|
/// Contains functionallity for the branch delay slot featured in MIPS CPU's.
|
||||||
/// A branch delay occurs when a jump/branch instruction is hit,
|
/// A branch delay occurs when a jump/branch instruction is hit,
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
/// configured branch slots have been run, and then the jump/branch occurs.
|
/// configured branch slots have been run, and then the jump/branch occurs.
|
||||||
/// A default slot size of 1 is used by the EE and IOP cores.
|
/// A default slot size of 1 is used by the EE and IOP cores.
|
||||||
/// slot + 1 is used internally as this is the real amount of instruction cycles.
|
/// slot + 1 is used internally as this is the real amount of instruction cycles.
|
||||||
template<int slots = 1>
|
template<size_t slots = 1>
|
||||||
class BranchDelaySlot
|
class BranchDelaySlot
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -75,6 +75,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int current_slot;
|
size_t current_slot;
|
||||||
uptr branch_pc;
|
uptr branch_pc;
|
||||||
};
|
};
|
|
@ -1,31 +0,0 @@
|
||||||
#include "Common/Types/Register/ByteRegister.hpp"
|
|
||||||
|
|
||||||
ubyte ByteRegister::extract_field(const Bitfield field)
|
|
||||||
{
|
|
||||||
return field.extract_from(read_ubyte());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteRegister::insert_field(const Bitfield field, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(field.insert_into(read_ubyte(), value));
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte ByteRegister::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteRegister::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ByteRegister::offset(const sbyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(read_ubyte() + value);
|
|
||||||
}
|
|
||||||
|
|
||||||
usize ByteRegister::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(1);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||||
#include "Common/Types/Bitfield.hpp"
|
#include "Common/Types/Bitfield.hpp"
|
||||||
|
|
||||||
|
@ -17,14 +18,35 @@ public:
|
||||||
virtual void write_ubyte(const ubyte value) = 0;
|
virtual void write_ubyte(const ubyte value) = 0;
|
||||||
|
|
||||||
/// Bitfield extraction/insertion.
|
/// Bitfield extraction/insertion.
|
||||||
ubyte extract_field(const Bitfield field);
|
ubyte extract_field(const Bitfield field)
|
||||||
void insert_field(const Bitfield field, const ubyte value);
|
{
|
||||||
|
return field.extract_from(read_ubyte());
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_field(const Bitfield field, const ubyte value)
|
||||||
|
{
|
||||||
|
write_ubyte(field.insert_into(read_ubyte(), value));
|
||||||
|
}
|
||||||
|
|
||||||
/// Offsets the register by the specified (signed) value.
|
/// Offsets the register by the specified (signed) value.
|
||||||
void offset(const sbyte value);
|
void offset(const sbyte value)
|
||||||
|
{
|
||||||
|
write_ubyte(read_ubyte() + value);
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
{
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
return static_cast<usize>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_ubyte();
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
write_ubyte(value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
#include "Common/Types/Register/DwordRegister.hpp"
|
|
||||||
|
|
||||||
udword DwordRegister::extract_field(const Bitfield field)
|
|
||||||
{
|
|
||||||
return field.extract_from(read_udword());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwordRegister::insert_field(const Bitfield field, const udword value)
|
|
||||||
{
|
|
||||||
write_udword(field.insert_into(read_udword(), value));
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte DwordRegister::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwordRegister::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword DwordRegister::byte_bus_read_uhword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uhword(offset / NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwordRegister::byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
|
||||||
{
|
|
||||||
write_uhword(offset / NUMBER_BYTES_IN_HWORD, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uword DwordRegister::byte_bus_read_uword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uword(offset / NUMBER_BYTES_IN_WORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwordRegister::byte_bus_write_uword(const BusContext context, const usize offset, const uword value)
|
|
||||||
{
|
|
||||||
write_uword(offset / NUMBER_BYTES_IN_WORD, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
udword DwordRegister::byte_bus_read_udword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_udword();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwordRegister::byte_bus_write_udword(const BusContext context, const usize offset, const udword value)
|
|
||||||
{
|
|
||||||
write_udword(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DwordRegister::offset(const sdword value)
|
|
||||||
{
|
|
||||||
write_udword(read_udword() + value);
|
|
||||||
}
|
|
||||||
|
|
||||||
usize DwordRegister::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(NUMBER_BYTES_IN_DWORD);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||||
#include "Common/Types/Bitfield.hpp"
|
#include "Common/Types/Bitfield.hpp"
|
||||||
|
|
||||||
|
@ -23,20 +24,65 @@ public:
|
||||||
virtual void write_udword(const udword value) = 0;
|
virtual void write_udword(const udword value) = 0;
|
||||||
|
|
||||||
/// Bitfield extraction/insertion.
|
/// Bitfield extraction/insertion.
|
||||||
udword extract_field(const Bitfield field);
|
udword extract_field(const Bitfield field)
|
||||||
void insert_field(const Bitfield field, const udword value);
|
{
|
||||||
|
return field.extract_from(read_udword());
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_field(const Bitfield field, const udword value)
|
||||||
|
{
|
||||||
|
write_udword(field.insert_into(read_udword(), value));
|
||||||
|
}
|
||||||
|
|
||||||
/// Offsets the register by the specified (signed) value.
|
/// Offsets the register by the specified (signed) value.
|
||||||
void offset(const sdword value);
|
void offset(const sdword value)
|
||||||
|
{
|
||||||
|
write_udword(read_udword() + value);
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
{
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
return static_cast<usize>(NUMBER_BYTES_IN_DWORD);
|
||||||
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override;
|
}
|
||||||
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override;
|
|
||||||
uword byte_bus_read_uword(const BusContext context, const usize offset) override;
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override
|
||||||
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override;
|
{
|
||||||
udword byte_bus_read_udword(const BusContext context, const usize offset) override;
|
return read_ubyte(offset);
|
||||||
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override;
|
}
|
||||||
};
|
|
||||||
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
write_ubyte(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uhword(offset / NUMBER_BYTES_IN_HWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override
|
||||||
|
{
|
||||||
|
write_uhword(offset / NUMBER_BYTES_IN_HWORD, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uword byte_bus_read_uword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uword(offset / NUMBER_BYTES_IN_WORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override
|
||||||
|
{
|
||||||
|
write_uword(offset / NUMBER_BYTES_IN_WORD, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
udword byte_bus_read_udword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_udword();
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override
|
||||||
|
{
|
||||||
|
write_udword(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
#include "Common/Types/Register/HwordRegister.hpp"
|
|
||||||
|
|
||||||
uhword HwordRegister::extract_field(const Bitfield field)
|
|
||||||
{
|
|
||||||
return field.extract_from(read_uhword());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwordRegister::insert_field(const Bitfield field, const uhword value)
|
|
||||||
{
|
|
||||||
write_uhword(field.insert_into(read_uhword(), value));
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte HwordRegister::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwordRegister::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword HwordRegister::byte_bus_read_uhword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uhword();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwordRegister::byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
|
||||||
{
|
|
||||||
write_uhword(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HwordRegister::offset(const shword value)
|
|
||||||
{
|
|
||||||
write_uhword(read_uhword() + value);
|
|
||||||
}
|
|
||||||
|
|
||||||
usize HwordRegister::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||||
#include "Common/Types/Bitfield.hpp"
|
#include "Common/Types/Bitfield.hpp"
|
||||||
|
|
||||||
|
@ -19,16 +20,45 @@ public:
|
||||||
virtual void write_uhword(const uhword value) = 0;
|
virtual void write_uhword(const uhword value) = 0;
|
||||||
|
|
||||||
/// Bitfield extraction/insertion.
|
/// Bitfield extraction/insertion.
|
||||||
uhword extract_field(const Bitfield field);
|
uhword extract_field(const Bitfield field)
|
||||||
void insert_field(const Bitfield field, const uhword value);
|
{
|
||||||
|
return field.extract_from(read_uhword());
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_field(const Bitfield field, const uhword value)
|
||||||
|
{
|
||||||
|
write_uhword(field.insert_into(read_uhword(), value));
|
||||||
|
}
|
||||||
|
|
||||||
/// Offsets the register by the specified (signed) value.
|
/// Offsets the register by the specified (signed) value.
|
||||||
void offset(const shword value);
|
void offset(const shword value)
|
||||||
|
{
|
||||||
|
write_uhword(read_uhword() + value);
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
{
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
return static_cast<usize>(NUMBER_BYTES_IN_HWORD);
|
||||||
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override;
|
}
|
||||||
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override;
|
|
||||||
};
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_ubyte(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
write_ubyte(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uhword();
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override
|
||||||
|
{
|
||||||
|
write_uhword(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
#include "Common/Types/Register/MapperHwordWordRegister.hpp"
|
|
||||||
#include "Common/Types/Register/HwordRegister.hpp"
|
|
||||||
|
|
||||||
void MapperHwordWordRegister::initialise()
|
|
||||||
{
|
|
||||||
hword_register->initialise();
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte MapperHwordWordRegister::read_ubyte(const size_t offset)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapperHwordWordRegister::write_ubyte(const size_t offset, const ubyte value)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword MapperHwordWordRegister::read_uhword(const size_t offset)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapperHwordWordRegister::write_uhword(const size_t offset, const uhword value)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
uword MapperHwordWordRegister::read_uword()
|
|
||||||
{
|
|
||||||
return static_cast<uword>(hword_register->read_uhword());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapperHwordWordRegister::write_uword(const uword value)
|
|
||||||
{
|
|
||||||
hword_register->write_uhword(static_cast<uhword>(value));
|
|
||||||
}
|
|
|
@ -1,22 +1,50 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/Types/Register/WordRegister.hpp"
|
#include <stdexcept>
|
||||||
|
|
||||||
class HwordRegister;
|
#include "Common/Types/Primitive.hpp"
|
||||||
|
#include "Common/Types/Register/WordRegister.hpp"
|
||||||
|
#include "Common/Types/Register/HwordRegister.hpp"
|
||||||
|
|
||||||
/// Maps a hword register to word register by zero-filling or truncating.
|
/// Maps a hword register to word register by zero-filling or truncating.
|
||||||
class MapperHwordWordRegister : public WordRegister
|
class MapperHwordWordRegister : public WordRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Initialise register (initialise underlying register).
|
/// Initialise register (initialise underlying register).
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
hword_register->initialise();
|
||||||
|
}
|
||||||
|
|
||||||
ubyte read_ubyte(const size_t offset) override;
|
ubyte read_ubyte(const size_t offset) override
|
||||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
{
|
||||||
uhword read_uhword(const size_t offset) override;
|
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
||||||
void write_uhword(const size_t offset, const uhword value) override;
|
}
|
||||||
uword read_uword() override;
|
|
||||||
void write_uword(const uword value) override;
|
void write_ubyte(const size_t offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword read_uhword(const size_t offset) override
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const size_t offset, const uhword value) override
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
uword read_uword() override
|
||||||
|
{
|
||||||
|
return static_cast<uword>(hword_register->read_uhword());
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uword(const uword value) override
|
||||||
|
{
|
||||||
|
hword_register->write_uhword(static_cast<uhword>(value));
|
||||||
|
}
|
||||||
|
|
||||||
/// Reference to mapped hword register.
|
/// Reference to mapped hword register.
|
||||||
HwordRegister * hword_register;
|
HwordRegister * hword_register;
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#include "Common/Types/Register/QwordRegister.hpp"
|
|
||||||
|
|
||||||
ubyte QwordRegister::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QwordRegister::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword QwordRegister::byte_bus_read_uhword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uhword(offset / NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QwordRegister::byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
|
||||||
{
|
|
||||||
write_uhword(offset / NUMBER_BYTES_IN_HWORD, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uword QwordRegister::byte_bus_read_uword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uword(offset / NUMBER_BYTES_IN_WORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QwordRegister::byte_bus_write_uword(const BusContext context, const usize offset, const uword value)
|
|
||||||
{
|
|
||||||
write_uword(offset / NUMBER_BYTES_IN_WORD, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
udword QwordRegister::byte_bus_read_udword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_udword(offset / NUMBER_BYTES_IN_DWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QwordRegister::byte_bus_write_udword(const BusContext context, const usize offset, const udword value)
|
|
||||||
{
|
|
||||||
write_udword(offset / NUMBER_BYTES_IN_DWORD, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uqword QwordRegister::byte_bus_read_uqword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uqword();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QwordRegister::byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value)
|
|
||||||
{
|
|
||||||
write_uqword(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 QwordRegister::read_float(const size_t offset)
|
|
||||||
{
|
|
||||||
return static_cast<f32>(read_uword(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QwordRegister::write_float(const size_t offset, const f32 value)
|
|
||||||
{
|
|
||||||
write_uword(offset, static_cast<uword>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
usize QwordRegister::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(NUMBER_BYTES_IN_QWORD);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||||
|
|
||||||
/// Qword register.
|
/// Qword register.
|
||||||
|
@ -24,19 +25,73 @@ public:
|
||||||
virtual void write_uqword(const uqword value) = 0;
|
virtual void write_uqword(const uqword value) = 0;
|
||||||
|
|
||||||
/// Read/write floats - wrappers around read/write uword.
|
/// Read/write floats - wrappers around read/write uword.
|
||||||
f32 read_float(const size_t offset);
|
f32 read_float(const size_t offset)
|
||||||
void write_float(const size_t offset, const f32 value);
|
{
|
||||||
|
return static_cast<f32>(read_uword(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_float(const size_t offset, const f32 value)
|
||||||
|
{
|
||||||
|
write_uword(offset, static_cast<uword>(value));
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
{
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
return static_cast<usize>(NUMBER_BYTES_IN_QWORD);
|
||||||
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override;
|
}
|
||||||
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override;
|
|
||||||
uword byte_bus_read_uword(const BusContext context, const usize offset) override;
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override
|
||||||
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override;
|
{
|
||||||
udword byte_bus_read_udword(const BusContext context, const usize offset) override;
|
return read_ubyte(offset);
|
||||||
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override;
|
}
|
||||||
uqword byte_bus_read_uqword(const BusContext context, const usize offset) override;
|
|
||||||
void byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value) override;
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override
|
||||||
};
|
{
|
||||||
|
write_ubyte(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uhword(offset / NUMBER_BYTES_IN_HWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override
|
||||||
|
{
|
||||||
|
write_uhword(offset / NUMBER_BYTES_IN_HWORD, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uword byte_bus_read_uword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uword(offset / NUMBER_BYTES_IN_WORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override
|
||||||
|
{
|
||||||
|
write_uword(offset / NUMBER_BYTES_IN_WORD, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
udword byte_bus_read_udword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_udword(offset / NUMBER_BYTES_IN_DWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_udword(const BusContext context, const usize offset, const udword value) override
|
||||||
|
{
|
||||||
|
write_udword(offset / NUMBER_BYTES_IN_DWORD, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uqword byte_bus_read_uqword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uqword();
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uqword(const BusContext context, const usize offset, const uqword value) override
|
||||||
|
{
|
||||||
|
write_uqword(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#include "Common/Types/Register/SizedByteRegister.hpp"
|
|
||||||
|
|
||||||
SizedByteRegister::SizedByteRegister(const ubyte initial_value, const bool read_only) :
|
|
||||||
b(initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedByteRegister::initialise()
|
|
||||||
{
|
|
||||||
b = initial_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte SizedByteRegister::read_ubyte()
|
|
||||||
{
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedByteRegister::write_ubyte(const ubyte value)
|
|
||||||
{
|
|
||||||
if (!read_only)
|
|
||||||
b = value;
|
|
||||||
}
|
|
|
@ -6,14 +6,30 @@
|
||||||
class SizedByteRegister : public ByteRegister
|
class SizedByteRegister : public ByteRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SizedByteRegister(const ubyte initial_value = 0, const bool read_only = false);
|
SizedByteRegister(const ubyte initial_value = 0, const bool read_only = false) :
|
||||||
|
b(initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise register.
|
/// Initialise register.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
b = initial_value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Read/write functions to access the register.
|
/// Read/write functions to access the register.
|
||||||
ubyte read_ubyte() override;
|
ubyte read_ubyte() override
|
||||||
void write_ubyte(const ubyte value) override;
|
{
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_ubyte(const ubyte value) override
|
||||||
|
{
|
||||||
|
if (!read_only)
|
||||||
|
b = value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Primitive (sized) storage for register.
|
/// Primitive (sized) storage for register.
|
||||||
|
@ -28,4 +44,4 @@ private:
|
||||||
/// Read-only flag.
|
/// Read-only flag.
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
#include "Common/Types/Register/SizedDwordRegister.hpp"
|
|
||||||
|
|
||||||
SizedDwordRegister::SizedDwordRegister(const udword initial_value, const bool read_only) :
|
|
||||||
d(initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedDwordRegister::initialise()
|
|
||||||
{
|
|
||||||
d = initial_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte SizedDwordRegister::read_ubyte(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_DWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return b[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedDwordRegister::write_ubyte(const size_t offset, const ubyte value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_DWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
b[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword SizedDwordRegister::read_uhword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_HWORDS_IN_DWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return h[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedDwordRegister::write_uhword(const size_t offset, const uhword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_HWORDS_IN_DWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
h[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uword SizedDwordRegister::read_uword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_WORDS_IN_DWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return w[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedDwordRegister::write_uword(const size_t offset, const uword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_WORDS_IN_DWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
w[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
udword SizedDwordRegister::read_udword()
|
|
||||||
{
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedDwordRegister::write_udword(const udword value)
|
|
||||||
{
|
|
||||||
if (!read_only)
|
|
||||||
d = value;
|
|
||||||
}
|
|
|
@ -1,25 +1,101 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Register/DwordRegister.hpp"
|
#include "Common/Types/Register/DwordRegister.hpp"
|
||||||
|
|
||||||
/// Sized Dword register.
|
/// Sized Dword register.
|
||||||
class SizedDwordRegister : public DwordRegister
|
class SizedDwordRegister : public DwordRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SizedDwordRegister(const udword initial_value = 0, const bool read_only = false);
|
SizedDwordRegister(const udword initial_value = 0, const bool read_only = false) :
|
||||||
|
d(initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise register.
|
/// Initialise register.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
d = initial_value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Read/write functions to access the register.
|
/// Read/write functions to access the register.
|
||||||
ubyte read_ubyte(const size_t offset) override;
|
ubyte read_ubyte(const size_t offset) override
|
||||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
{
|
||||||
uhword read_uhword(const size_t offset) override;
|
#if defined(BUILD_DEBUG)
|
||||||
void write_uhword(const size_t offset, const uhword value) override;
|
if (offset >= NUMBER_BYTES_IN_DWORD)
|
||||||
uword read_uword(const size_t offset) override;
|
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
||||||
void write_uword(const size_t offset, const uword value) override;
|
#endif
|
||||||
udword read_udword() override;
|
|
||||||
void write_udword(const udword value) override;
|
return b[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_ubyte(const size_t offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_BYTES_IN_DWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
b[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword read_uhword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_HWORDS_IN_DWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return h[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const size_t offset, const uhword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_HWORDS_IN_DWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
h[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uword read_uword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_WORDS_IN_DWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return w[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uword(const size_t offset, const uword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_WORDS_IN_DWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedDwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
w[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
udword read_udword() override
|
||||||
|
{
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_udword(const udword value) override
|
||||||
|
{
|
||||||
|
if (!read_only)
|
||||||
|
d = value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Primitive (sized) storage for register.
|
/// Primitive (sized) storage for register.
|
||||||
|
@ -37,4 +113,5 @@ private:
|
||||||
/// Read-only flag.
|
/// Read-only flag.
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include "Common/Types/Register/SizedHwordRegister.hpp"
|
|
||||||
|
|
||||||
SizedHwordRegister::SizedHwordRegister(const uhword initial_value, const bool read_only) :
|
|
||||||
h(initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedHwordRegister::initialise()
|
|
||||||
{
|
|
||||||
h = initial_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte SizedHwordRegister::read_ubyte(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_HWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedHwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return b[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedHwordRegister::write_ubyte(const size_t offset, const ubyte value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_HWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedHwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
b[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword SizedHwordRegister::read_uhword()
|
|
||||||
{
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedHwordRegister::write_uhword(const uhword value)
|
|
||||||
{
|
|
||||||
if (!read_only)
|
|
||||||
h = value;
|
|
||||||
}
|
|
|
@ -1,21 +1,59 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Register/HwordRegister.hpp"
|
#include "Common/Types/Register/HwordRegister.hpp"
|
||||||
|
|
||||||
/// Sized Hword register.
|
/// Sized Hword register.
|
||||||
class SizedHwordRegister : public HwordRegister
|
class SizedHwordRegister : public HwordRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SizedHwordRegister(const uhword initial_value = 0, const bool read_only = false);
|
SizedHwordRegister(const uhword initial_value = 0, const bool read_only = false) :
|
||||||
|
h(initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise register.
|
/// Initialise register.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
h = initial_value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Read/write functions to access the register.
|
/// Read/write functions to access the register.
|
||||||
ubyte read_ubyte(const size_t offset) override;
|
ubyte read_ubyte(const size_t offset) override
|
||||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
{
|
||||||
uhword read_uhword() override;
|
#if defined(BUILD_DEBUG)
|
||||||
void write_uhword(const uhword value) override;
|
if (offset >= NUMBER_BYTES_IN_HWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedHwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return b[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_ubyte(const size_t offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_BYTES_IN_HWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedHwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
b[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword read_uhword() override
|
||||||
|
{
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const uhword value) override
|
||||||
|
{
|
||||||
|
if (!read_only)
|
||||||
|
h = value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Primitive (sized) storage for register.
|
/// Primitive (sized) storage for register.
|
||||||
|
@ -31,4 +69,4 @@ private:
|
||||||
/// Read-only flag.
|
/// Read-only flag.
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
#include "Common/Types/Register/SizedQwordRegister.hpp"
|
|
||||||
|
|
||||||
SizedQwordRegister::SizedQwordRegister(const uqword initial_value, const bool read_only) :
|
|
||||||
q(initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedQwordRegister::initialise()
|
|
||||||
{
|
|
||||||
q = initial_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte SizedQwordRegister::read_ubyte(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return b[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedQwordRegister::write_ubyte(const size_t offset, const ubyte value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
b[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword SizedQwordRegister::read_uhword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_HWORDS_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return h[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedQwordRegister::write_uhword(const size_t offset, const uhword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_HWORDS_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
h[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uword SizedQwordRegister::read_uword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_WORDS_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return w[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedQwordRegister::write_uword(const size_t offset, const uword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_WORDS_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
w[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
udword SizedQwordRegister::read_udword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_WORDS_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return d[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedQwordRegister::write_udword(const size_t offset, const udword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_WORDS_IN_QWORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
d[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uqword SizedQwordRegister::read_uqword()
|
|
||||||
{
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedQwordRegister::write_uqword(const uqword value)
|
|
||||||
{
|
|
||||||
if (!read_only)
|
|
||||||
q = value;
|
|
||||||
}
|
|
|
@ -1,27 +1,122 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Register/QwordRegister.hpp"
|
#include "Common/Types/Register/QwordRegister.hpp"
|
||||||
|
|
||||||
/// Sized Qword register.
|
/// Sized Qword register.
|
||||||
class SizedQwordRegister : public QwordRegister
|
class SizedQwordRegister : public QwordRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SizedQwordRegister(const uqword initial_value = 0, const bool read_only = false);
|
SizedQwordRegister(const uqword initial_value = 0, const bool read_only = false) :
|
||||||
|
q(initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise register.
|
/// Initialise register.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
q = initial_value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Read/write functions to access the register.
|
/// Read/write functions to access the register.
|
||||||
ubyte read_ubyte(const size_t offset) override;
|
ubyte read_ubyte(const size_t offset) override
|
||||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
{
|
||||||
uhword read_uhword(const size_t offset) override;
|
#if defined(BUILD_DEBUG)
|
||||||
void write_uhword(const size_t offset, const uhword value) override;
|
if (offset >= NUMBER_BYTES_IN_QWORD)
|
||||||
uword read_uword(const size_t offset) override;
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
void write_uword(const size_t offset, const uword value) override;
|
#endif
|
||||||
udword read_udword(const size_t offset) override;
|
|
||||||
void write_udword(const size_t offset, const udword value) override;
|
return b[offset];
|
||||||
uqword read_uqword() override;
|
}
|
||||||
void write_uqword(const uqword value) override;
|
|
||||||
|
void write_ubyte(const size_t offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_BYTES_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
b[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword read_uhword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_HWORDS_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return h[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const size_t offset, const uhword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_HWORDS_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
h[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uword read_uword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_WORDS_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return w[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uword(const size_t offset, const uword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_WORDS_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
w[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
udword read_udword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_WORDS_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return d[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_udword(const size_t offset, const udword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_WORDS_IN_QWORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedQwordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
d[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uqword read_uqword() override
|
||||||
|
{
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uqword(const uqword value) override
|
||||||
|
{
|
||||||
|
if (!read_only)
|
||||||
|
q = value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Primitive (sized) storage for register.
|
/// Primitive (sized) storage for register.
|
||||||
|
@ -40,4 +135,5 @@ private:
|
||||||
/// Read-only flag.
|
/// Read-only flag.
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#include "Common/Types/Register/SizedWordRegister.hpp"
|
|
||||||
|
|
||||||
SizedWordRegister::SizedWordRegister(const uword initial_value, const bool read_only) :
|
|
||||||
w(initial_value),
|
|
||||||
initial_value(initial_value),
|
|
||||||
read_only(read_only)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedWordRegister::initialise()
|
|
||||||
{
|
|
||||||
w = initial_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte SizedWordRegister::read_ubyte(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_WORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return b[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedWordRegister::write_ubyte(const size_t offset, const ubyte value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_BYTES_IN_WORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
b[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword SizedWordRegister::read_uhword(const size_t offset)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_HWORDS_IN_WORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return h[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedWordRegister::write_uhword(const size_t offset, const uhword value)
|
|
||||||
{
|
|
||||||
#if defined(BUILD_DEBUG)
|
|
||||||
if (offset >= NUMBER_HWORDS_IN_WORD)
|
|
||||||
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read_only)
|
|
||||||
h[offset] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uword SizedWordRegister::read_uword()
|
|
||||||
{
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SizedWordRegister::write_uword(const uword value)
|
|
||||||
{
|
|
||||||
if (!read_only)
|
|
||||||
w = value;
|
|
||||||
}
|
|
|
@ -1,23 +1,80 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Register/WordRegister.hpp"
|
#include "Common/Types/Register/WordRegister.hpp"
|
||||||
|
|
||||||
/// Sized Word register.
|
/// Sized Word register.
|
||||||
class SizedWordRegister : public WordRegister
|
class SizedWordRegister : public WordRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SizedWordRegister(const uword initial_value = 0, const bool read_only = false);
|
SizedWordRegister(const uword initial_value = 0, const bool read_only = false) :
|
||||||
|
w(initial_value),
|
||||||
|
initial_value(initial_value),
|
||||||
|
read_only(read_only)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise register.
|
/// Initialise register.
|
||||||
void initialise() override;
|
void initialise() override
|
||||||
|
{
|
||||||
|
w = initial_value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Read/write functions to access the register.
|
/// Read/write functions to access the register.
|
||||||
ubyte read_ubyte(const size_t offset) override;
|
ubyte read_ubyte(const size_t offset) override
|
||||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
{
|
||||||
uhword read_uhword(const size_t offset) override;
|
#if defined(BUILD_DEBUG)
|
||||||
void write_uhword(const size_t offset, const uhword value) override;
|
if (offset >= NUMBER_BYTES_IN_WORD)
|
||||||
uword read_uword() override;
|
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
||||||
void write_uword(const uword value) override;
|
#endif
|
||||||
|
|
||||||
|
return b[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_ubyte(const size_t offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_BYTES_IN_WORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
b[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword read_uhword(const size_t offset) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_HWORDS_IN_WORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return h[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uhword(const size_t offset, const uhword value) override
|
||||||
|
{
|
||||||
|
#if defined(BUILD_DEBUG)
|
||||||
|
if (offset >= NUMBER_HWORDS_IN_WORD)
|
||||||
|
throw std::runtime_error("Tried to access SizedWordRegister with an invalid offset.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!read_only)
|
||||||
|
h[offset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uword read_uword() override
|
||||||
|
{
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uword(const uword value) override
|
||||||
|
{
|
||||||
|
if (!read_only)
|
||||||
|
w = value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Primitive (sized) storage for register.
|
/// Primitive (sized) storage for register.
|
||||||
|
@ -34,4 +91,4 @@ private:
|
||||||
/// Read-only flag.
|
/// Read-only flag.
|
||||||
/// Writes are silently discarded if turned on.
|
/// Writes are silently discarded if turned on.
|
||||||
bool read_only;
|
bool read_only;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
#include "Common/Types/Register/WordRegister.hpp"
|
|
||||||
|
|
||||||
uword WordRegister::extract_field(const Bitfield field)
|
|
||||||
{
|
|
||||||
return field.extract_from(read_uword());
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordRegister::insert_field(const Bitfield field, const uword value)
|
|
||||||
{
|
|
||||||
write_uword(field.insert_into(read_uword(), value));
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte WordRegister::byte_bus_read_ubyte(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_ubyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordRegister::byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value)
|
|
||||||
{
|
|
||||||
write_ubyte(offset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uhword WordRegister::byte_bus_read_uhword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uhword(offset / NUMBER_BYTES_IN_HWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordRegister::byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value)
|
|
||||||
{
|
|
||||||
write_uhword(offset / NUMBER_BYTES_IN_HWORD, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
uword WordRegister::byte_bus_read_uword(const BusContext context, const usize offset)
|
|
||||||
{
|
|
||||||
return read_uword();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordRegister::byte_bus_write_uword(const BusContext context, const usize offset, const uword value)
|
|
||||||
{
|
|
||||||
write_uword(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordRegister::offset(const sword value)
|
|
||||||
{
|
|
||||||
write_uword(read_uword() + value);
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 WordRegister::read_float()
|
|
||||||
{
|
|
||||||
return static_cast<f32>(read_uword());
|
|
||||||
}
|
|
||||||
|
|
||||||
void WordRegister::write_float(const f32 value)
|
|
||||||
{
|
|
||||||
write_uword(static_cast<uword>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
usize WordRegister::byte_bus_map_size() const
|
|
||||||
{
|
|
||||||
return static_cast<usize>(NUMBER_BYTES_IN_WORD);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Common/Types/Primitive.hpp"
|
||||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||||
#include "Common/Types/Bitfield.hpp"
|
#include "Common/Types/Bitfield.hpp"
|
||||||
|
|
||||||
|
@ -21,22 +22,66 @@ public:
|
||||||
virtual void write_uword(const uword value) = 0;
|
virtual void write_uword(const uword value) = 0;
|
||||||
|
|
||||||
/// Read/write floats - wrappers around read/write uword.
|
/// Read/write floats - wrappers around read/write uword.
|
||||||
f32 read_float();
|
f32 read_float()
|
||||||
void write_float(const f32 value);
|
{
|
||||||
|
return static_cast<f32>(read_uword());
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_float(const f32 value)
|
||||||
|
{
|
||||||
|
write_uword(static_cast<uword>(value));
|
||||||
|
}
|
||||||
|
|
||||||
/// Bitfield extraction/insertion.
|
/// Bitfield extraction/insertion.
|
||||||
uword extract_field(const Bitfield field);
|
uword extract_field(const Bitfield field)
|
||||||
void insert_field(const Bitfield field, const uword value);
|
{
|
||||||
|
return field.extract_from(read_uword());
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_field(const Bitfield field, const uword value)
|
||||||
|
{
|
||||||
|
write_uword(field.insert_into(read_uword(), value));
|
||||||
|
}
|
||||||
|
|
||||||
/// Offsets the register by the specified (signed) value.
|
/// Offsets the register by the specified (signed) value.
|
||||||
void offset(const sword value);
|
void offset(const sword value)
|
||||||
|
{
|
||||||
|
write_uword(read_uword() + value);
|
||||||
|
}
|
||||||
|
|
||||||
/// ByteBusMappable overrides.
|
/// ByteBusMappable overrides.
|
||||||
usize byte_bus_map_size() const override;
|
usize byte_bus_map_size() const override
|
||||||
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override;
|
{
|
||||||
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override;
|
return static_cast<usize>(NUMBER_BYTES_IN_WORD);
|
||||||
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override;
|
}
|
||||||
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override;
|
|
||||||
uword byte_bus_read_uword(const BusContext context, const usize offset) override;
|
ubyte byte_bus_read_ubyte(const BusContext context, const usize offset) override
|
||||||
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override;
|
{
|
||||||
};
|
return read_ubyte(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_ubyte(const BusContext context, const usize offset, const ubyte value) override
|
||||||
|
{
|
||||||
|
write_ubyte(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhword byte_bus_read_uhword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uhword(offset / NUMBER_BYTES_IN_HWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uhword(const BusContext context, const usize offset, const uhword value) override
|
||||||
|
{
|
||||||
|
write_uhword(offset / NUMBER_BYTES_IN_HWORD, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uword byte_bus_read_uword(const BusContext context, const usize offset) override
|
||||||
|
{
|
||||||
|
return read_uword();
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_bus_write_uword(const BusContext context, const usize offset, const uword value) override
|
||||||
|
{
|
||||||
|
write_uword(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -452,15 +452,20 @@ std::optional<uptr> CEeCore::translate_address(const uptr virtual_address, const
|
||||||
return translate_address_fallback(virtual_address, rw_access);
|
return translate_address_fallback(virtual_address, rw_access);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::optional<uptr> result;
|
||||||
switch (id_access)
|
switch (id_access)
|
||||||
{
|
{
|
||||||
case INSTRUCTION:
|
case INSTRUCTION:
|
||||||
return translation_cache_inst.lookup(virtual_address, rw_access, fallback_fn);
|
result = translation_cache_inst.lookup(virtual_address, rw_access, fallback_fn);
|
||||||
|
break;
|
||||||
case DATA:
|
case DATA:
|
||||||
return translation_cache_data.lookup(virtual_address, rw_access, fallback_fn);
|
result = translation_cache_data.lookup(virtual_address, rw_access, fallback_fn);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unrecognised id_access");
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Unrecognised id_access");
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uptr> CEeCore::translate_address_fallback(const uptr virtual_address, const MmuRwAccess rw_access)
|
std::optional<uptr> CEeCore::translate_address_fallback(const uptr virtual_address, const MmuRwAccess rw_access)
|
||||||
|
|
|
@ -111,16 +111,6 @@ Core::~Core()
|
||||||
BOOST_LOG(get_logger()) << "Core shutting down";
|
BOOST_LOG(get_logger()) << "Core shutting down";
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoreOptions & Core::get_options() const
|
|
||||||
{
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
RResources & Core::get_resources() const
|
|
||||||
{
|
|
||||||
return *resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::run()
|
void Core::run()
|
||||||
{
|
{
|
||||||
#if defined(BUILD_DEBUG)
|
#if defined(BUILD_DEBUG)
|
||||||
|
@ -176,22 +166,6 @@ void Core::run()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::enqueue_controller_event(const ControllerType::Type c_type, const ControllerEvent & event)
|
|
||||||
{
|
|
||||||
EventEntry qe{ c_type, event };
|
|
||||||
controller_event_queue.push(qe);
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskExecutor & Core::get_task_executor() const
|
|
||||||
{
|
|
||||||
return *task_executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::log::sources::logger_mt & Core::get_logger()
|
|
||||||
{
|
|
||||||
return logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::dump_all_memory() const
|
void Core::dump_all_memory() const
|
||||||
{
|
{
|
||||||
boost::filesystem::create_directory(options.dumps_dir_path);
|
boost::filesystem::create_directory(options.dumps_dir_path);
|
||||||
|
|
|
@ -56,24 +56,39 @@ public:
|
||||||
~Core();
|
~Core();
|
||||||
|
|
||||||
/// Returns a reference to the logging functionality.
|
/// Returns a reference to the logging functionality.
|
||||||
static boost::log::sources::logger_mt & get_logger();
|
static boost::log::sources::logger_mt & get_logger()
|
||||||
|
{
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the runtime core options.
|
/// Returns the runtime core options.
|
||||||
const CoreOptions & get_options() const;
|
const CoreOptions & get_options() const
|
||||||
|
{
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the task executor.
|
||||||
|
TaskExecutor & get_task_executor() const
|
||||||
|
{
|
||||||
|
return *task_executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the PS2 resources.
|
||||||
|
RResources & get_resources() const
|
||||||
|
{
|
||||||
|
return *resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enqueues a controller event that is dispatched on the next synchronised run.
|
||||||
|
void enqueue_controller_event(const ControllerType::Type c_type, const ControllerEvent & event)
|
||||||
|
{
|
||||||
|
controller_event_queue.push({ c_type, event });
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs the core and updates the state.
|
/// Runs the core and updates the state.
|
||||||
/// This is the main loop function.
|
/// This is the main loop function.
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
/// Returns the task executor.
|
|
||||||
TaskExecutor & get_task_executor() const;
|
|
||||||
|
|
||||||
/// Returns a reference to the PS2 resources.
|
|
||||||
RResources & get_resources() const;
|
|
||||||
|
|
||||||
/// Enqueues a controller event that is dispatched on the next synchronised run.
|
|
||||||
void enqueue_controller_event(const ControllerType::Type c_type, const ControllerEvent & event);
|
|
||||||
|
|
||||||
/// Dumps all memory objects to the ./dumps folder.
|
/// Dumps all memory objects to the ./dumps folder.
|
||||||
void dump_all_memory() const;
|
void dump_all_memory() const;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.8.2)
|
cmake_minimum_required(VERSION 3.9)
|
||||||
|
cmake_policy(SET CMP0069 NEW) # Link time optimization support
|
||||||
|
|
||||||
project(orbumfront CXX)
|
project(orbumfront CXX)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.8.2)
|
cmake_minimum_required(VERSION 3.9)
|
||||||
|
cmake_policy(SET CMP0069 NEW) # Link time optimization support
|
||||||
|
|
||||||
project(utilities CXX)
|
project(utilities CXX)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ template<int Size, typename KeyTy, typename ValueTy>
|
||||||
class ArrayLfuCache
|
class ArrayLfuCache
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using CacheEntry = std::tuple<KeyTy, ValueTy, int>;
|
using CacheEntry = std::tuple<KeyTy, ValueTy, size_t>;
|
||||||
using CacheContainer = std::array<CacheEntry, Size>;
|
using CacheContainer = std::array<CacheEntry, Size>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -24,7 +24,7 @@ public:
|
||||||
/// Returns the value associated with the key and increments the access count.
|
/// Returns the value associated with the key and increments the access count.
|
||||||
std::optional<const ValueTy> get(const KeyTy key)
|
std::optional<const ValueTy> get(const KeyTy key)
|
||||||
{
|
{
|
||||||
auto entry_it = std::find_if(cache.begin(), cache.begin() + current_cache_size, [&key](const CacheEntry & e) {
|
auto entry_it = std::find_if(cache.begin(), cache.begin() + current_cache_size, [key](const CacheEntry & e) {
|
||||||
return std::get<0>(e) == key;
|
return std::get<0>(e) == key;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int current_cache_size;
|
size_t current_cache_size;
|
||||||
CacheContainer cache;
|
CacheContainer cache;
|
||||||
|
|
||||||
/// Finds the entry with the lowest access count to evict, and returns its position.
|
/// Finds the entry with the lowest access count to evict, and returns its position.
|
||||||
|
@ -83,7 +83,7 @@ template<int Size, typename KeyTy, typename ValueTy>
|
||||||
class ArrayLruCache
|
class ArrayLruCache
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using CacheEntry = std::tuple<KeyTy, ValueTy, int>;
|
using CacheEntry = std::tuple<KeyTy, ValueTy, size_t>;
|
||||||
using CacheContainer = std::array<CacheEntry, Size>;
|
using CacheContainer = std::array<CacheEntry, Size>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -97,7 +97,7 @@ public:
|
||||||
/// Returns the value associated with the key and sets the access timestamp.
|
/// Returns the value associated with the key and sets the access timestamp.
|
||||||
std::optional<const ValueTy> get(const KeyTy key)
|
std::optional<const ValueTy> get(const KeyTy key)
|
||||||
{
|
{
|
||||||
auto entry_it = std::find_if(cache.begin(), cache.begin() + current_cache_size, [&key](const CacheEntry & e) {
|
auto entry_it = std::find_if(cache.begin(), cache.begin() + current_cache_size, [key](const CacheEntry & e) {
|
||||||
return std::get<0>(e) == key;
|
return std::get<0>(e) == key;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int total_cache_access;
|
size_t total_cache_access;
|
||||||
int current_cache_size;
|
size_t current_cache_size;
|
||||||
CacheContainer cache;
|
CacheContainer cache;
|
||||||
|
|
||||||
/// Finds the entry with the lowest timestamp to evict, and returns its position.
|
/// Finds the entry with the lowest timestamp to evict, and returns its position.
|
||||||
|
|
Loading…
Reference in a new issue