From 6f27770cea41238f4d500d716c123546330ea7c3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 10 Jul 2020 17:17:06 +0200 Subject: [PATCH] UserspaceEmulator: Add 8/16 bit memory read/write operations --- DevTools/UserspaceEmulator/Emulator.cpp | 24 +++++++++++++++ DevTools/UserspaceEmulator/SoftCPU.cpp | 30 +++++++++++++++++++ DevTools/UserspaceEmulator/SoftCPU.h | 5 ++++ DevTools/UserspaceEmulator/SoftMMU.cpp | 40 +++++++++++++++++++++++++ DevTools/UserspaceEmulator/SoftMMU.h | 10 +++++++ 5 files changed, 109 insertions(+) diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index a0a197a4c3..f8dc12f254 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -49,12 +49,36 @@ public: free(m_data); } + virtual u8 read8(u32 offset) override + { + ASSERT(offset < size()); + return *reinterpret_cast(m_data + offset); + } + + virtual u16 read16(u32 offset) override + { + ASSERT(offset + 1 < size()); + return *reinterpret_cast(m_data + offset); + } + virtual u32 read32(u32 offset) override { ASSERT(offset + 3 < size()); return *reinterpret_cast(m_data + offset); } + virtual void write8(u32 offset, u8 value) override + { + ASSERT(offset < size()); + *reinterpret_cast(m_data + offset) = value; + } + + virtual void write16(u32 offset, u16 value) override + { + ASSERT(offset + 1 < size()); + *reinterpret_cast(m_data + offset) = value; + } + virtual void write32(u32 offset, u32 value) override { ASSERT(offset + 3 < size()); diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 2fd5d946fa..9f5b1b03b9 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -78,6 +78,22 @@ void SoftCPU::dump() const printf("o=%u s=%u z=%u a=%u p=%u c=%u\n", of(), sf(), zf(), af(), pf(), cf()); } +u8 SoftCPU::read_memory8(X86::LogicalAddress address) +{ + ASSERT(address.selector() == 0x20); + auto value = m_emulator.mmu().read8(address.offset()); + printf("\033[36;1mread_memory8: @%08x -> %02x\033[0m\n", address.offset(), value); + return value; +} + +u16 SoftCPU::read_memory16(X86::LogicalAddress address) +{ + ASSERT(address.selector() == 0x20); + auto value = m_emulator.mmu().read16(address.offset()); + printf("\033[36;1mread_memory16: @%08x -> %04x\033[0m\n", address.offset(), value); + return value; +} + u32 SoftCPU::read_memory32(X86::LogicalAddress address) { ASSERT(address.selector() == 0x20); @@ -86,6 +102,20 @@ u32 SoftCPU::read_memory32(X86::LogicalAddress address) return value; } +void SoftCPU::write_memory8(X86::LogicalAddress address, u8 value) +{ + ASSERT(address.selector() == 0x20); + printf("\033[35;1mwrite_memory8: @%08x <- %02x\033[0m\n", address.offset(), value); + m_emulator.mmu().write8(address.offset(), value); +} + +void SoftCPU::write_memory16(X86::LogicalAddress address, u16 value) +{ + ASSERT(address.selector() == 0x20); + printf("\033[35;1mwrite_memory16: @%08x <- %04x\033[0m\n", address.offset(), value); + m_emulator.mmu().write16(address.offset(), value); +} + void SoftCPU::write_memory32(X86::LogicalAddress address, u32 value) { ASSERT(address.selector() == 0x20); diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h index e41e397977..c3379873db 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.h +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -117,7 +117,12 @@ public: u16 es() const { return m_segment[(int)X86::SegmentRegister::ES]; } u16 ss() const { return m_segment[(int)X86::SegmentRegister::SS]; } + u8 read_memory8(X86::LogicalAddress); + u16 read_memory16(X86::LogicalAddress); u32 read_memory32(X86::LogicalAddress); + + void write_memory8(X86::LogicalAddress, u8); + void write_memory16(X86::LogicalAddress, u16); void write_memory32(X86::LogicalAddress, u32); private: diff --git a/DevTools/UserspaceEmulator/SoftMMU.cpp b/DevTools/UserspaceEmulator/SoftMMU.cpp index 0545894ac8..1de7fcde35 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.cpp +++ b/DevTools/UserspaceEmulator/SoftMMU.cpp @@ -44,6 +44,26 @@ void SoftMMU::add_region(NonnullOwnPtr region) m_regions.append(move(region)); } +u8 SoftMMU::read8(u32 address) +{ + auto* region = find_region(address); + if (!region) { + TODO(); + } + + return region->read8(address - region->base()); +} + +u16 SoftMMU::read16(u32 address) +{ + auto* region = find_region(address); + if (!region) { + TODO(); + } + + return region->read16(address - region->base()); +} + u32 SoftMMU::read32(u32 address) { auto* region = find_region(address); @@ -54,6 +74,26 @@ u32 SoftMMU::read32(u32 address) return region->read32(address - region->base()); } +void SoftMMU::write8(u32 address, u8 value) +{ + auto* region = find_region(address); + if (!region) { + TODO(); + } + + region->write8(address - region->base(), value); +} + +void SoftMMU::write16(u32 address, u16 value) +{ + auto* region = find_region(address); + if (!region) { + TODO(); + } + + region->write16(address - region->base(), value); +} + void SoftMMU::write32(u32 address, u32 value) { auto* region = find_region(address); diff --git a/DevTools/UserspaceEmulator/SoftMMU.h b/DevTools/UserspaceEmulator/SoftMMU.h index b1a7e38821..fd12534a45 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.h +++ b/DevTools/UserspaceEmulator/SoftMMU.h @@ -43,7 +43,12 @@ public: bool contains(u32 address) const { return address >= base() && address < end(); } + virtual void write8(u32 offset, u8 value) = 0; + virtual void write16(u32 offset, u16 value) = 0; virtual void write32(u32 offset, u32 value) = 0; + + virtual u8 read8(u32 offset) = 0; + virtual u16 read16(u32 offset) = 0; virtual u32 read32(u32 offset) = 0; protected: @@ -58,7 +63,12 @@ public: u32 m_size { 0 }; }; + u8 read8(u32 address); + u16 read16(u32 address); u32 read32(u32 address); + + void write8(u32 address, u8 value); + void write16(u32 address, u16 value); void write32(u32 address, u32 value); Region* find_region(u32 address);