#include #include #include "riscv/Types.hpp" namespace riscv { namespace { template 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(memory)[OffsetToIndex(offset)]; } u32 PeekWord(AddressT offset) override { return std::bit_cast(memory)[OffsetToIndex(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(memory)[OffsetToIndex(offset)] = value; } else { // TODO: trap here } } void PokeWord(AddressT offset, u32 value) override { if constexpr(!Rom) { std::bit_cast(memory)[OffsetToIndex(offset)] = value; } else { // TODO: trap here } } private: /// helper used for implementing stuff template 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; using RomDevice = BasicMemoryDevice; } // namespace // Bus::Device* NewRam() } // namespace riscv