gmod-lcpu/native/projects/riscv/src/MemoryDevice.cpp

92 lines
2.0 KiB
C++
Raw Normal View History

2023-07-16 01:58:32 -04:00
#include <riscv/Bus.hpp>
#include <span>
#include "riscv/Types.hpp"
2023-07-16 01:58:32 -04:00
namespace riscv {
namespace {
template <bool Rom>
2023-07-16 01:58:32 -04:00
struct BasicMemoryDevice : public Bus::Device {
BasicMemoryDevice(usize size) : memorySize(size) {
2023-07-16 01:58:32 -04:00
memory = new u8[size];
LUCORE_CHECK(memory, "Could not allocate buffer for memory device.");
2023-07-16 01:58:32 -04:00
}
virtual ~BasicMemoryDevice() {
if(memory)
delete[] memory;
}
// Implementation of Device interface
void Attached(Bus* bus, AddressT base) override {
attachedBus = bus;
baseAddress = base;
}
AddressT BaseAddress() const override {
return baseAddress;
}
u8 PeekByte(AddressT offset) override {
return memory[offset % memorySize];
}
u16 PeekShort(AddressT offset) override {
return std::bit_cast<u16*>(memory)[OffsetToIndex<u16>(offset)];
}
u32 PeekWord(AddressT offset) override {
return std::bit_cast<u32*>(memory)[OffsetToIndex<u32>(offset)];
2023-07-16 01:58:32 -04:00
}
void PokeByte(AddressT offset, u8 value) override {
if constexpr(!Rom) {
memory[offset % memorySize] = value;
} else {
// TODO: trap here
}
}
void PokeShort(AddressT offset, u16 value) override {
if constexpr(!Rom) {
std::bit_cast<u16*>(memory)[OffsetToIndex<u16>(offset)] = value;
} else {
// TODO: trap here
}
}
void PokeWord(AddressT offset, u32 value) override {
if constexpr(!Rom) {
std::bit_cast<u32*>(memory)[OffsetToIndex<u32>(offset)] = value;
} else {
// TODO: trap here
}
}
private:
2023-07-16 01:58:32 -04:00
/// helper used for implementing stuff
template <class T>
2023-07-16 01:58:32 -04:00
constexpr usize OffsetToIndex(AddressT offset) {
return (offset % memorySize) / sizeof(T);
}
// remember what we were attached to via "signal"
Bus* attachedBus {};
AddressT baseAddress {};
2023-07-16 01:58:32 -04:00
u8* memory {};
usize memorySize {};
2023-07-16 01:58:32 -04:00
};
using RamDevice = BasicMemoryDevice<false>;
using RomDevice = BasicMemoryDevice<true>;
} // namespace
2023-07-16 01:58:32 -04:00
// Bus::Device* NewRam()
2023-07-16 01:58:32 -04:00
} // namespace riscv