Просмотр исходного кода

UserspaceEmulator: Add 8/16 bit memory read/write operations

Andreas Kling 5 лет назад
Родитель
Сommit
6f27770cea

+ 24 - 0
DevTools/UserspaceEmulator/Emulator.cpp

@@ -49,12 +49,36 @@ public:
         free(m_data);
     }
 
+    virtual u8 read8(u32 offset) override
+    {
+        ASSERT(offset < size());
+        return *reinterpret_cast<const u8*>(m_data + offset);
+    }
+
+    virtual u16 read16(u32 offset) override
+    {
+        ASSERT(offset + 1 < size());
+        return *reinterpret_cast<const u16*>(m_data + offset);
+    }
+
     virtual u32 read32(u32 offset) override
     {
         ASSERT(offset + 3 < size());
         return *reinterpret_cast<const u32*>(m_data + offset);
     }
 
+    virtual void write8(u32 offset, u8 value) override
+    {
+        ASSERT(offset < size());
+        *reinterpret_cast<u8*>(m_data + offset) = value;
+    }
+
+    virtual void write16(u32 offset, u16 value) override
+    {
+        ASSERT(offset + 1 < size());
+        *reinterpret_cast<u16*>(m_data + offset) = value;
+    }
+
     virtual void write32(u32 offset, u32 value) override
     {
         ASSERT(offset + 3 < size());

+ 30 - 0
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);

+ 5 - 0
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:

+ 40 - 0
DevTools/UserspaceEmulator/SoftMMU.cpp

@@ -44,6 +44,26 @@ void SoftMMU::add_region(NonnullOwnPtr<Region> 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);

+ 10 - 0
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);