diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index 9370518a65..a0a197a4c3 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -28,14 +28,54 @@ #include "SoftCPU.h" #include #include -#include #include +#include namespace UserspaceEmulator { +static constexpr u32 stack_location = 0x10000000; +static constexpr size_t stack_size = 64 * KB; + +class SimpleRegion final : public SoftMMU::Region { +public: + SimpleRegion(u32 base, u32 size) + : Region(base, size) + { + m_data = (u8*)malloc(size); + } + + ~SimpleRegion() + { + free(m_data); + } + + virtual u32 read32(u32 offset) override + { + ASSERT(offset + 3 < size()); + return *reinterpret_cast(m_data + offset); + } + + virtual void write32(u32 offset, u32 value) override + { + ASSERT(offset + 3 < size()); + *reinterpret_cast(m_data + offset) = value; + } + +private: + u8* m_data { nullptr }; +}; + Emulator::Emulator() : m_cpu(*this) { + setup_stack(); +} + +void Emulator::setup_stack() +{ + auto stack_region = make(stack_location, stack_size); + m_mmu.add_region(move(stack_region)); + m_cpu.set_esp(stack_location + stack_size); } int Emulator::exec(X86::SimpleInstructionStream& stream, u32 base) @@ -59,8 +99,8 @@ int Emulator::exec(X86::SimpleInstructionStream& stream, u32 base) u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) { - (void) arg2; - (void) arg3; + (void)arg2; + (void)arg3; printf("Syscall: %s (%x)\n", Syscall::to_string((Syscall::Function)function), function); switch (function) { diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 567a3cfc22..228808ecf8 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -51,6 +51,34 @@ void SoftCPU::dump() const printf("o=%u s=%u z=%u a=%u p=%u c=%u\n", m_of, m_sf, m_zf, m_af, m_pf, m_cf); } +u32 SoftCPU::read_memory32(X86::LogicalAddress address) +{ + ASSERT(address.selector() == 0x20); + auto value = m_emulator.mmu().read32(address.offset()); + printf("\033[36;1mread_memory32: @%08x -> %08x\033[0m\n", address.offset(), value); + return value; +} + +void SoftCPU::write_memory32(X86::LogicalAddress address, u32 value) +{ + ASSERT(address.selector() == 0x20); + printf("\033[35;1mwrite_memory32: @%08x <- %08x\033[0m\n", address.offset(), value); + m_emulator.mmu().write32(address.offset(), value); +} + +void SoftCPU::push32(u32 value) +{ + m_esp -= sizeof(value); + write_memory32({ get_ss(), get_esp() }, value); +} + +u32 SoftCPU::pop32() +{ + auto value = read_memory32({ get_ss(), get_esp() }); + m_esp += sizeof(value); + return value; +} + void SoftCPU::AAA(const X86::Instruction&) { TODO(); } void SoftCPU::AAD(const X86::Instruction&) { TODO(); } void SoftCPU::AAM(const X86::Instruction&) { TODO(); } @@ -346,7 +374,12 @@ void SoftCPU::POP_RM16(const X86::Instruction&) { TODO(); } void SoftCPU::POP_RM32(const X86::Instruction&) { TODO(); } void SoftCPU::POP_SS(const X86::Instruction&) { TODO(); } void SoftCPU::POP_reg16(const X86::Instruction&) { TODO(); } -void SoftCPU::POP_reg32(const X86::Instruction&) { TODO(); } + +void SoftCPU::POP_reg32(const X86::Instruction& insn) +{ + *m_reg32_table[insn.register_index()] = pop32(); +} + void SoftCPU::PUSHA(const X86::Instruction&) { TODO(); } void SoftCPU::PUSHAD(const X86::Instruction&) { TODO(); } void SoftCPU::PUSHF(const X86::Instruction&) { TODO(); } @@ -364,7 +397,12 @@ void SoftCPU::PUSH_imm16(const X86::Instruction&) { TODO(); } void SoftCPU::PUSH_imm32(const X86::Instruction&) { TODO(); } void SoftCPU::PUSH_imm8(const X86::Instruction&) { TODO(); } void SoftCPU::PUSH_reg16(const X86::Instruction&) { TODO(); } -void SoftCPU::PUSH_reg32(const X86::Instruction&) { TODO(); } + +void SoftCPU::PUSH_reg32(const X86::Instruction& insn) +{ + push32(*m_reg32_table[insn.register_index()]); +} + void SoftCPU::RCL_RM16_1(const X86::Instruction&) { TODO(); } void SoftCPU::RCL_RM16_CL(const X86::Instruction&) { TODO(); } void SoftCPU::RCL_RM16_imm8(const X86::Instruction&) { TODO(); } diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h index 30174bd3de..24ab02c693 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.h +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -26,6 +26,7 @@ #pragma once +#include #include namespace UserspaceEmulator { @@ -37,6 +38,21 @@ public: explicit SoftCPU(Emulator&); void dump() const; + void push32(u32); + u32 pop32(); + + u32 get_esp() const { return m_esp; } + void set_esp(u32 value) { m_esp = value; } + + u16 get_cs() const { return 0x18; } + u16 get_ds() const { return 0x20; } + u16 get_es() const { return 0x20; } + u16 get_ss() const { return 0x20; } + + u32 read_memory32(X86::LogicalAddress); + void write_memory32(X86::LogicalAddress, u32); + +private: virtual void AAA(const X86::Instruction&) override; virtual void AAD(const X86::Instruction&) override; virtual void AAM(const X86::Instruction&) override;