92 lines
2.0 KiB
C++
92 lines
2.0 KiB
C++
#include <riscv/Bus.hpp>
|
|
#include <span>
|
|
|
|
#include "riscv/Types.hpp"
|
|
|
|
namespace riscv {
|
|
|
|
namespace {
|
|
|
|
template <bool Rom>
|
|
struct BasicMemoryDevice : public Bus::Device {
|
|
BasicMemoryDevice(usize size) : memorySize(size) {
|
|
memory = new u8[size];
|
|
LUCORE_CHECK(memory, "Could not allocate buffer for memory device.");
|
|
}
|
|
|
|
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)];
|
|
}
|
|
|
|
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:
|
|
/// helper used for implementing stuff
|
|
template <class T>
|
|
constexpr usize OffsetToIndex(AddressT offset) {
|
|
return (offset % memorySize) / sizeof(T);
|
|
}
|
|
|
|
// remember what we were attached to via "signal"
|
|
Bus* attachedBus {};
|
|
AddressT baseAddress {};
|
|
|
|
u8* memory {};
|
|
usize memorySize {};
|
|
};
|
|
|
|
using RamDevice = BasicMemoryDevice<false>;
|
|
using RomDevice = BasicMemoryDevice<true>;
|
|
|
|
} // namespace
|
|
|
|
// Bus::Device* NewRam()
|
|
|
|
} // namespace riscv
|