Fully generalize access to vram
This commit is contained in:
parent
98a543b86c
commit
03bdb5091e
2 changed files with 22 additions and 13 deletions
27
src/vm.cpp
27
src/vm.cpp
|
@ -13,7 +13,11 @@ inline int32_t sign_extend(int32_t value, int bits) {
|
|||
}
|
||||
|
||||
VM::VM(const std::vector<uint8_t>& memory, const std::string& file_path)
|
||||
: ram(memory), pc(PROGRAM_ADDR), file_path(file_path) {}
|
||||
: ram(memory), pc(PROGRAM_ADDR), file_path(file_path) {
|
||||
devices = std::vector<Device*>(2, 0);
|
||||
devices[0] = &ram;
|
||||
devices[1] = &uart;
|
||||
}
|
||||
|
||||
void VM::setreg(int regnum, uint32_t value) {
|
||||
if (regnum == 0) {
|
||||
|
@ -70,22 +74,23 @@ void UART::write_mem(uint8_t* src, size_t addr, size_t size) {
|
|||
}
|
||||
|
||||
void VM::read_mem(uint8_t* dst, size_t addr, size_t size) {
|
||||
if (addr >= PROGRAM_ADDR) {
|
||||
ram.read_mem(dst, addr, size);
|
||||
for (Device* dev : devices) {
|
||||
if (addr >= dev->base() && addr + size <= dev->base() + dev->size()) {
|
||||
dev->read_mem(dst, addr, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Memory access out of bounds");
|
||||
}
|
||||
|
||||
void VM::write_mem(uint8_t* src, size_t addr, size_t size) {
|
||||
if (addr >= PROGRAM_ADDR) {
|
||||
ram.write_mem(src, addr, size);
|
||||
}
|
||||
|
||||
if (is_mmap(addr, size)) {
|
||||
if (addr >= UART_ADDR && addr < UART_ADDR + 8) {
|
||||
uart.write_mem(src, addr, size);
|
||||
for (Device* dev : devices) {
|
||||
if (addr >= dev->base() && addr + size <= dev->base() + dev->size()) {
|
||||
dev->write_mem(src, addr, size);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error("Memory access out of bounds");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> VM::read_memory(size_t start, size_t size) {
|
||||
|
|
|
@ -24,13 +24,16 @@ class Device {
|
|||
virtual void write_mem(uint8_t *src, size_t addr, size_t size);
|
||||
virtual void read_mem(uint8_t *dst, size_t addr, size_t size);
|
||||
|
||||
uint32_t base() { return base_addr; }
|
||||
uint32_t size() { return mem_size; }
|
||||
|
||||
private:
|
||||
uint32_t base_addr = 0;
|
||||
uint32_t mem_size = 0;
|
||||
std::vector<uint8_t> mem;
|
||||
};
|
||||
|
||||
class UART : public Device {
|
||||
class UART final : public Device {
|
||||
public:
|
||||
UART() : Device(UART_ADDR, 8) {}
|
||||
|
||||
|
@ -48,7 +51,7 @@ class UART : public Device {
|
|||
enum LSRBits { LSR_TRANSMITTER_EMPTY = 0x20 };
|
||||
};
|
||||
|
||||
class RAM : public Device {
|
||||
class RAM final : public Device {
|
||||
public:
|
||||
RAM(const std::vector<uint8_t> &memory) : Device(PROGRAM_ADDR, memory) {}
|
||||
};
|
||||
|
@ -81,4 +84,5 @@ class VM {
|
|||
std::string file_path;
|
||||
|
||||
UART uart;
|
||||
std::vector<Device *> devices;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue