diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-11-14 21:10:40 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-11-14 21:10:40 -0600 |
| commit | 6fb3849e73b797d4610a2b782127f927dec0c9c9 (patch) | |
| tree | 9d17de8907d860b795761e0644f17d0fd33106de /tb/mem.impl.hpp | |
| parent | cad870295dfb741d5c24c25016c5bba878bc37e5 (diff) | |
Implement VGA simulation
Diffstat (limited to 'tb/mem.impl.hpp')
| -rw-r--r-- | tb/mem.impl.hpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/tb/mem.impl.hpp b/tb/mem.impl.hpp new file mode 100644 index 0000000..f7bb424 --- /dev/null +++ b/tb/mem.impl.hpp @@ -0,0 +1,81 @@ +#ifndef TALLER_MEM_IMPL_HPP +#define TALLER_MEM_IMPL_HPP + +#include <cassert> +#include <cstdint> +#include <memory> + +namespace taller::avalon +{ + template<typename Cell> + mem<Cell>::mem(std::uint32_t base, std::uint32_t size) + : slave(base, size, sizeof(Cell)), + block(std::make_unique<Cell[]>(size >> word_bits())) + {} + + template<typename Cell> + template<typename F> + void mem<Cell>::load(F loader, std::size_t offset) + { + auto base = base_address(); + auto bits = word_bits(); + std::size_t size = address_span(); + std::size_t addr = base_address() + offset; + + while(addr >= base && addr < base + size) + { + std::size_t read = loader(&block[(addr - base) >> bits], (base + size - addr) >> bits); + if(read == 0) + { + break; + } + + addr += read << bits; + } + } + + template<typename Cell> + bool mem<Cell>::read(std::uint32_t addr, std::uint32_t &data) + { + data = block[addr]; + return ready(); + } + + template<typename Cell> + bool mem<Cell>::write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) + { + std::uint32_t bytes = 0; + + if(byte_enable & 0b1000) + { + bytes |= 0xff << 24; + } + + if(byte_enable & 0b0100) + { + bytes |= 0xff << 16; + } + + if(byte_enable & 0b0010) + { + bytes |= 0xff << 8; + } + + if(byte_enable & 0b0001) + { + bytes |= 0xff; + } + + block[addr] = (data & bytes) | (block[addr] & ~bytes); + return ready(); + } + + template<typename Cell> + bool mem<Cell>::ready() noexcept + { + count = count > 0 ? count - 1 : 2; + return count == 0; + } +} + +#endif |
