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)
|
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) {
|
void VM::setreg(int regnum, uint32_t value) {
|
||||||
if (regnum == 0) {
|
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) {
|
void VM::read_mem(uint8_t* dst, size_t addr, size_t size) {
|
||||||
if (addr >= PROGRAM_ADDR) {
|
for (Device* dev : devices) {
|
||||||
ram.read_mem(dst, addr, size);
|
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) {
|
void VM::write_mem(uint8_t* src, size_t addr, size_t size) {
|
||||||
if (addr >= PROGRAM_ADDR) {
|
for (Device* dev : devices) {
|
||||||
ram.write_mem(src, addr, size);
|
if (addr >= dev->base() && addr + size <= dev->base() + dev->size()) {
|
||||||
}
|
dev->write_mem(src, addr, size);
|
||||||
|
return;
|
||||||
if (is_mmap(addr, size)) {
|
|
||||||
if (addr >= UART_ADDR && addr < UART_ADDR + 8) {
|
|
||||||
uart.write_mem(src, addr, size);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
throw std::runtime_error("Memory access out of bounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> VM::read_memory(size_t start, size_t size) {
|
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 write_mem(uint8_t *src, size_t addr, size_t size);
|
||||||
virtual void read_mem(uint8_t *dst, 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:
|
private:
|
||||||
uint32_t base_addr = 0;
|
uint32_t base_addr = 0;
|
||||||
uint32_t mem_size = 0;
|
uint32_t mem_size = 0;
|
||||||
std::vector<uint8_t> mem;
|
std::vector<uint8_t> mem;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UART : public Device {
|
class UART final : public Device {
|
||||||
public:
|
public:
|
||||||
UART() : Device(UART_ADDR, 8) {}
|
UART() : Device(UART_ADDR, 8) {}
|
||||||
|
|
||||||
|
@ -48,7 +51,7 @@ class UART : public Device {
|
||||||
enum LSRBits { LSR_TRANSMITTER_EMPTY = 0x20 };
|
enum LSRBits { LSR_TRANSMITTER_EMPTY = 0x20 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class RAM : public Device {
|
class RAM final : public Device {
|
||||||
public:
|
public:
|
||||||
RAM(const std::vector<uint8_t> &memory) : Device(PROGRAM_ADDR, memory) {}
|
RAM(const std::vector<uint8_t> &memory) : Device(PROGRAM_ADDR, memory) {}
|
||||||
};
|
};
|
||||||
|
@ -81,4 +84,5 @@ class VM {
|
||||||
std::string file_path;
|
std::string file_path;
|
||||||
|
|
||||||
UART uart;
|
UART uart;
|
||||||
|
std::vector<Device *> devices;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue