mirror of
https://github.com/hch12907/orbum.git
synced 2024-05-10 00:34:06 -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_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 #
|
||||
|
@ -13,20 +16,29 @@ project(orbum CXX)
|
|||
###########
|
||||
# Options #
|
||||
###########
|
||||
|
||||
|
||||
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(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")
|
||||
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")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
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 #
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -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/ByteBusMappable.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/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/ArrayHwordMemory.cpp"
|
||||
"${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/HwordMemory.cpp"
|
||||
"${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/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/MmuAccess.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/DwordRegister.cpp"
|
||||
"${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/MapperHwordWordRegister.cpp"
|
||||
"${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/SizedByteRegister.cpp"
|
||||
"${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/SizedHwordRegister.cpp"
|
||||
"${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/SizedWordRegister.cpp"
|
||||
"${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/PcRegisters.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.
|
||||
/// 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.
|
||||
/// 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.
|
||||
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;
|
||||
|
||||
/// Check if queue is full/empty (wrappers around above functions).
|
||||
bool is_empty() const;
|
||||
bool is_full() const;
|
||||
bool is_empty() const
|
||||
{
|
||||
return !has_read_available(1);
|
||||
}
|
||||
|
||||
bool is_full() const
|
||||
{
|
||||
return !has_write_available(1);
|
||||
}
|
||||
|
||||
/// ByteBusMappable overrides.
|
||||
/// For the FifoQueue object, the map size is always one byte.
|
||||
/// The offset is not used in reading or writing to the queue.
|
||||
/// For a larger mapping, map the queue multiple times.
|
||||
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;
|
||||
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;
|
||||
};
|
||||
usize byte_bus_map_size() const 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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
#include "Common/Types/Memory/ByteMemory.hpp"
|
||||
|
||||
|
@ -9,37 +10,158 @@
|
|||
class ArrayByteMemory : public ByteMemory
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
std::vector<ubyte>(size, initial_value).swap(memory);
|
||||
}
|
||||
|
||||
/// Read in a raw file to the memory (byte copy).
|
||||
/// 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.
|
||||
/// 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).
|
||||
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;
|
||||
void write_uhword(const size_t offset, const uhword value) override;
|
||||
uword read_uword(const size_t offset) override;
|
||||
void write_uword(const size_t offset, const uword value) override;
|
||||
udword read_udword(const size_t offset) override;
|
||||
void write_udword(const size_t offset, const udword value) override;
|
||||
uqword read_uqword(const size_t offset) override;
|
||||
void write_uqword(const size_t offset, const uqword value) override;
|
||||
ubyte read_ubyte(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<ubyte*>(&memory[offset]);
|
||||
}
|
||||
|
||||
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.
|
||||
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.
|
||||
/// 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:
|
||||
/// Total size of the byte memory.
|
||||
|
@ -55,4 +177,3 @@ private:
|
|||
/// Writes are silently discarded if turned on.
|
||||
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
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
#include "Common/Types/Memory/HwordMemory.hpp"
|
||||
|
||||
|
@ -9,32 +10,131 @@
|
|||
class ArrayHwordMemory : public HwordMemory
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
std::vector<uhword>(size, initial_value).swap(memory);
|
||||
}
|
||||
|
||||
/// Read in a raw file to the memory (hword copy).
|
||||
/// 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.
|
||||
/// 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).
|
||||
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;
|
||||
void write_uword(const size_t offset, const uword value) override;
|
||||
udword read_udword(const size_t offset) override;
|
||||
void write_udword(const size_t offset, const udword value) override;
|
||||
uqword read_uqword(const size_t offset) override;
|
||||
void write_uqword(const size_t offset, const uqword value) override;
|
||||
uhword read_uhword(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<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.
|
||||
/// 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:
|
||||
/// Total size of the hword memory.
|
||||
|
@ -50,4 +150,3 @@ private:
|
|||
/// Writes are silently discarded if turned on.
|
||||
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.
|
||||
/// 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.
|
||||
/// 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.
|
||||
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;
|
||||
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)
|
||||
{
|
||||
return read_ubyte(offset);
|
||||
}
|
||||
|
||||
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.
|
||||
/// 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.
|
||||
/// 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
|
||||
|
||||
#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.
|
||||
/// 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.
|
||||
/// 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.
|
||||
template<int slots = 1>
|
||||
template<size_t slots = 1>
|
||||
class BranchDelaySlot
|
||||
{
|
||||
public:
|
||||
|
@ -75,6 +75,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
int current_slot;
|
||||
size_t current_slot;
|
||||
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 "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||
#include "Common/Types/Bitfield.hpp"
|
||||
|
||||
|
@ -17,14 +18,35 @@ public:
|
|||
virtual void write_ubyte(const ubyte value) = 0;
|
||||
|
||||
/// Bitfield extraction/insertion.
|
||||
ubyte extract_field(const Bitfield field);
|
||||
void insert_field(const Bitfield field, const ubyte value);
|
||||
ubyte extract_field(const Bitfield field)
|
||||
{
|
||||
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.
|
||||
void offset(const sbyte value);
|
||||
void offset(const sbyte value)
|
||||
{
|
||||
write_ubyte(read_ubyte() + value);
|
||||
}
|
||||
|
||||
/// ByteBusMappable overrides.
|
||||
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;
|
||||
usize byte_bus_map_size() const 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 "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||
#include "Common/Types/Bitfield.hpp"
|
||||
|
||||
|
@ -23,20 +24,65 @@ public:
|
|||
virtual void write_udword(const udword value) = 0;
|
||||
|
||||
/// Bitfield extraction/insertion.
|
||||
udword extract_field(const Bitfield field);
|
||||
void insert_field(const Bitfield field, const udword value);
|
||||
udword extract_field(const Bitfield field)
|
||||
{
|
||||
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.
|
||||
void offset(const sdword value);
|
||||
|
||||
void offset(const sdword value)
|
||||
{
|
||||
write_udword(read_udword() + value);
|
||||
}
|
||||
|
||||
/// ByteBusMappable overrides.
|
||||
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;
|
||||
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;
|
||||
};
|
||||
usize byte_bus_map_size() const override
|
||||
{
|
||||
return static_cast<usize>(NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
|
||||
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(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 "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||
#include "Common/Types/Bitfield.hpp"
|
||||
|
||||
|
@ -19,16 +20,45 @@ public:
|
|||
virtual void write_uhword(const uhword value) = 0;
|
||||
|
||||
/// Bitfield extraction/insertion.
|
||||
uhword extract_field(const Bitfield field);
|
||||
void insert_field(const Bitfield field, const uhword value);
|
||||
uhword extract_field(const Bitfield field)
|
||||
{
|
||||
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.
|
||||
void offset(const shword value);
|
||||
void offset(const shword value)
|
||||
{
|
||||
write_uhword(read_uhword() + value);
|
||||
}
|
||||
|
||||
/// ByteBusMappable overrides.
|
||||
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;
|
||||
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;
|
||||
};
|
||||
usize byte_bus_map_size() const override
|
||||
{
|
||||
return static_cast<usize>(NUMBER_BYTES_IN_HWORD);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#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.
|
||||
class MapperHwordWordRegister : public WordRegister
|
||||
{
|
||||
public:
|
||||
/// Initialise register (initialise underlying register).
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
hword_register->initialise();
|
||||
}
|
||||
|
||||
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;
|
||||
void write_uhword(const size_t offset, const uhword value) override;
|
||||
uword read_uword() override;
|
||||
void write_uword(const uword value) override;
|
||||
ubyte read_ubyte(const size_t offset) override
|
||||
{
|
||||
throw std::runtime_error("Only Word R/W wrapper calls to HwordRegister are allowed.");
|
||||
}
|
||||
|
||||
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.
|
||||
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 "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||
|
||||
/// Qword register.
|
||||
|
@ -24,19 +25,73 @@ public:
|
|||
virtual void write_uqword(const uqword value) = 0;
|
||||
|
||||
/// Read/write floats - wrappers around read/write uword.
|
||||
f32 read_float(const size_t offset);
|
||||
void write_float(const size_t offset, const f32 value);
|
||||
f32 read_float(const size_t offset)
|
||||
{
|
||||
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.
|
||||
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;
|
||||
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;
|
||||
};
|
||||
usize byte_bus_map_size() const override
|
||||
{
|
||||
return static_cast<usize>(NUMBER_BYTES_IN_QWORD);
|
||||
}
|
||||
|
||||
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(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
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
b = initial_value;
|
||||
}
|
||||
|
||||
/// Read/write functions to access the register.
|
||||
ubyte read_ubyte() override;
|
||||
void write_ubyte(const ubyte value) override;
|
||||
ubyte read_ubyte() override
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
void write_ubyte(const ubyte value) override
|
||||
{
|
||||
if (!read_only)
|
||||
b = value;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Primitive (sized) storage for register.
|
||||
|
@ -28,4 +44,4 @@ private:
|
|||
/// Read-only flag.
|
||||
/// Writes are silently discarded if turned on.
|
||||
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
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Register/DwordRegister.hpp"
|
||||
|
||||
/// Sized Dword register.
|
||||
class SizedDwordRegister : public DwordRegister
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
d = initial_value;
|
||||
}
|
||||
|
||||
/// Read/write functions to access the register.
|
||||
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;
|
||||
void write_uhword(const size_t offset, const uhword value) override;
|
||||
uword read_uword(const size_t offset) override;
|
||||
void write_uword(const size_t offset, const uword value) override;
|
||||
udword read_udword() override;
|
||||
void write_udword(const udword value) override;
|
||||
ubyte read_ubyte(const size_t offset) override
|
||||
{
|
||||
#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 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:
|
||||
/// Primitive (sized) storage for register.
|
||||
|
@ -37,4 +113,5 @@ private:
|
|||
/// Read-only flag.
|
||||
/// Writes are silently discarded if turned on.
|
||||
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
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Register/HwordRegister.hpp"
|
||||
|
||||
/// Sized Hword register.
|
||||
class SizedHwordRegister : public HwordRegister
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
h = initial_value;
|
||||
}
|
||||
|
||||
/// Read/write functions to access the register.
|
||||
ubyte read_ubyte(const size_t offset) override;
|
||||
void write_ubyte(const size_t offset, const ubyte value) override;
|
||||
uhword read_uhword() override;
|
||||
void write_uhword(const uhword value) override;
|
||||
ubyte read_ubyte(const size_t offset) override
|
||||
{
|
||||
#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 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:
|
||||
/// Primitive (sized) storage for register.
|
||||
|
@ -31,4 +69,4 @@ private:
|
|||
/// Read-only flag.
|
||||
/// Writes are silently discarded if turned on.
|
||||
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
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Register/QwordRegister.hpp"
|
||||
|
||||
/// Sized Qword register.
|
||||
class SizedQwordRegister : public QwordRegister
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
q = initial_value;
|
||||
}
|
||||
|
||||
/// Read/write functions to access the register.
|
||||
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;
|
||||
void write_uhword(const size_t offset, const uhword value) override;
|
||||
uword read_uword(const size_t offset) override;
|
||||
void write_uword(const size_t offset, const uword value) override;
|
||||
udword read_udword(const size_t offset) override;
|
||||
void write_udword(const size_t offset, const udword value) override;
|
||||
uqword read_uqword() override;
|
||||
void write_uqword(const uqword value) override;
|
||||
ubyte read_ubyte(const size_t offset) override
|
||||
{
|
||||
#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 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:
|
||||
/// Primitive (sized) storage for register.
|
||||
|
@ -40,4 +135,5 @@ private:
|
|||
/// Read-only flag.
|
||||
/// Writes are silently discarded if turned on.
|
||||
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
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Register/WordRegister.hpp"
|
||||
|
||||
/// Sized Word register.
|
||||
class SizedWordRegister : public WordRegister
|
||||
{
|
||||
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.
|
||||
void initialise() override;
|
||||
void initialise() override
|
||||
{
|
||||
w = initial_value;
|
||||
}
|
||||
|
||||
/// Read/write functions to access the register.
|
||||
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;
|
||||
void write_uhword(const size_t offset, const uhword value) override;
|
||||
uword read_uword() override;
|
||||
void write_uword(const uword value) override;
|
||||
ubyte read_ubyte(const size_t offset) override
|
||||
{
|
||||
#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 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:
|
||||
/// Primitive (sized) storage for register.
|
||||
|
@ -34,4 +91,4 @@ private:
|
|||
/// Read-only flag.
|
||||
/// Writes are silently discarded if turned on.
|
||||
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 "Common/Types/Primitive.hpp"
|
||||
#include "Common/Types/Bus/ByteBusMappable.hpp"
|
||||
#include "Common/Types/Bitfield.hpp"
|
||||
|
||||
|
@ -21,22 +22,66 @@ public:
|
|||
virtual void write_uword(const uword value) = 0;
|
||||
|
||||
/// Read/write floats - wrappers around read/write uword.
|
||||
f32 read_float();
|
||||
void write_float(const f32 value);
|
||||
f32 read_float()
|
||||
{
|
||||
return static_cast<f32>(read_uword());
|
||||
}
|
||||
|
||||
void write_float(const f32 value)
|
||||
{
|
||||
write_uword(static_cast<uword>(value));
|
||||
}
|
||||
|
||||
/// Bitfield extraction/insertion.
|
||||
uword extract_field(const Bitfield field);
|
||||
void insert_field(const Bitfield field, const uword value);
|
||||
uword extract_field(const Bitfield field)
|
||||
{
|
||||
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.
|
||||
void offset(const sword value);
|
||||
void offset(const sword value)
|
||||
{
|
||||
write_uword(read_uword() + value);
|
||||
}
|
||||
|
||||
/// ByteBusMappable overrides.
|
||||
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;
|
||||
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;
|
||||
};
|
||||
usize byte_bus_map_size() const override
|
||||
{
|
||||
return static_cast<usize>(NUMBER_BYTES_IN_WORD);
|
||||
}
|
||||
|
||||
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(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);
|
||||
};
|
||||
|
||||
std::optional<uptr> result;
|
||||
switch (id_access)
|
||||
{
|
||||
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:
|
||||
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)
|
||||
|
|
|
@ -111,16 +111,6 @@ Core::~Core()
|
|||
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()
|
||||
{
|
||||
#if defined(BUILD_DEBUG)
|
||||
|
@ -176,22 +166,6 @@ void Core::run()
|
|||
#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
|
||||
{
|
||||
boost::filesystem::create_directory(options.dumps_dir_path);
|
||||
|
|
|
@ -56,24 +56,39 @@ public:
|
|||
~Core();
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
/// This is the main loop function.
|
||||
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.
|
||||
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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ template<int Size, typename KeyTy, typename ValueTy>
|
|||
class ArrayLfuCache
|
||||
{
|
||||
private:
|
||||
using CacheEntry = std::tuple<KeyTy, ValueTy, int>;
|
||||
using CacheEntry = std::tuple<KeyTy, ValueTy, size_t>;
|
||||
using CacheContainer = std::array<CacheEntry, Size>;
|
||||
|
||||
public:
|
||||
|
@ -24,7 +24,7 @@ public:
|
|||
/// Returns the value associated with the key and increments the access count.
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
int current_cache_size;
|
||||
size_t current_cache_size;
|
||||
CacheContainer cache;
|
||||
|
||||
/// 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
|
||||
{
|
||||
private:
|
||||
using CacheEntry = std::tuple<KeyTy, ValueTy, int>;
|
||||
using CacheEntry = std::tuple<KeyTy, ValueTy, size_t>;
|
||||
using CacheContainer = std::array<CacheEntry, Size>;
|
||||
|
||||
public:
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
/// Returns the value associated with the key and sets the access timestamp.
|
||||
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;
|
||||
});
|
||||
|
||||
|
@ -126,8 +126,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
int total_cache_access;
|
||||
int current_cache_size;
|
||||
size_t total_cache_access;
|
||||
size_t current_cache_size;
|
||||
CacheContainer cache;
|
||||
|
||||
/// Finds the entry with the lowest timestamp to evict, and returns its position.
|
||||
|
|
Loading…
Reference in a new issue