From 22d2b612b89ebbc7adfd9cab73e45214b4e3a487 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 28 Oct 2022 21:12:01 +0200 Subject: [PATCH] botching Teakra some... not a big success --- src/teakra/src/CMakeLists.txt | 1 + src/teakra/src/interpreter.h | 48 +++++++++++++++++++++++++---- src/teakra/src/memory_interface.cpp | 16 +++++++--- src/teakra/src/operand.h | 2 +- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/teakra/src/CMakeLists.txt b/src/teakra/src/CMakeLists.txt index b96c500b..2ba05b40 100644 --- a/src/teakra/src/CMakeLists.txt +++ b/src/teakra/src/CMakeLists.txt @@ -19,6 +19,7 @@ add_library(teakra timer.cpp timer.h icu.h + InstrDecode.h interpreter.h matcher.h memory_interface.cpp diff --git a/src/teakra/src/interpreter.h b/src/teakra/src/interpreter.h index 98241a32..22ca5653 100644 --- a/src/teakra/src/interpreter.h +++ b/src/teakra/src/interpreter.h @@ -16,6 +16,9 @@ namespace Teakra { +class Interpreter; +extern void (*InstrTable[65536])(Interpreter& cpu, u16 instr); + class UnimplementedException : public std::runtime_error { public: UnimplementedException() : std::runtime_error("unimplemented") {} @@ -60,6 +63,34 @@ public: UNREACHABLE(); } + u16 OpcodeFetch() + { + u16 opcode = mem.ProgramRead((regs.pc++) | (regs.prpage << 18)); + return opcode; + } + + void HandleLoops() + { + if (regs.rep) { + if (regs.repc == 0) { + regs.rep = false; + } else { + --regs.repc; + --regs.pc; + } + } + + if (regs.lp && regs.bkrep_stack[regs.bcn - 1].end + 1 == regs.pc) { + if (regs.bkrep_stack[regs.bcn - 1].lc == 0) { + --regs.bcn; + regs.lp = regs.bcn != 0; + } else { + --regs.bkrep_stack[regs.bcn - 1].lc; + regs.pc = regs.bkrep_stack[regs.bcn - 1].start; + } + } + } + void Run(u64 cycles) { idle = false; for (u64 i = 0; i < cycles; ++i) { @@ -84,8 +115,8 @@ public: regs.ipv = 1; } - u16 opcode = mem.ProgramRead((regs.pc++) | (regs.prpage << 18)); - auto& decoder = decoders[opcode]; + u16 opcode = OpcodeFetch(); + /*auto& decoder = decoders[opcode]; u16 expand_value = 0; if (decoder.NeedExpansion()) { expand_value = mem.ProgramRead((regs.pc++) | (regs.prpage << 18)); @@ -110,7 +141,8 @@ public: } } - decoder.call(*this, opcode, expand_value); + decoder.call(*this, opcode, expand_value);*/ + InstrTable[opcode](*this, opcode); // I am not sure if a single-instruction loop is interruptable and how it is handled, // so just disable interrupt for it for now. @@ -1185,14 +1217,16 @@ public: // retd is supposed to kick in after 2 cycles for (int i = 0; i < 2; i++) { - u16 opcode = mem.ProgramRead((regs.pc++) | (regs.prpage << 18)); + /*u16 opcode = mem.ProgramRead((regs.pc++) | (regs.prpage << 18)); auto& decoder = decoders[opcode]; u16 expand_value = 0; if (decoder.NeedExpansion()) { expand_value = mem.ProgramRead((regs.pc++) | (regs.prpage << 18)); } - decoder.call(*this, opcode, expand_value); + decoder.call(*this, opcode, expand_value);*/ + u16 opcode = OpcodeFetch(); + InstrTable[opcode](*this, opcode); } PopPC(); @@ -3642,7 +3676,9 @@ private: return map.at(in); } - const std::vector> decoders = GetDecoderTable(); + //const std::vector> decoders = GetDecoderTable(); }; } // namespace Teakra + +#include "InstrDecode.h" diff --git a/src/teakra/src/memory_interface.cpp b/src/teakra/src/memory_interface.cpp index ef30b95a..b771a9d1 100644 --- a/src/teakra/src/memory_interface.cpp +++ b/src/teakra/src/memory_interface.cpp @@ -2,6 +2,8 @@ #include "mmio.h" #include "shared_memory.h" +#include "../../DSi.h" + namespace Teakra { MemoryInterface::MemoryInterface(SharedMemory& shared_memory, MemoryInterfaceUnit& memory_interface_unit) @@ -11,11 +13,17 @@ void MemoryInterface::SetMMIO(MMIORegion& mmio) { this->mmio = &mmio; } -u16 MemoryInterface::ProgramRead(u32 address) const { - return shared_memory.ReadWord(address); +u16 MemoryInterface::ProgramRead(u32 address) const +{ + //return shared_memory.ReadWord(address); + u8* ptr = DSi::NWRAMMap_B[2][(address >> 14) & 0x7]; + return ptr ? *(u16*)&ptr[(address << 1) & 0x7FFF] : 0; } -void MemoryInterface::ProgramWrite(u32 address, u16 value) { - shared_memory.WriteWord(address, value); +void MemoryInterface::ProgramWrite(u32 address, u16 value) +{ + //shared_memory.WriteWord(address, value); + u8* ptr = DSi::NWRAMMap_B[2][(address >> 14) & 0x7]; + if (ptr) *(u16*)&ptr[(address << 1) & 0x7FFF] = value; } u16 MemoryInterface::DataRead(u16 address, bool bypass_mmio) { if (memory_interface_unit.InMMIO(address) && !bypass_mmio) { diff --git a/src/teakra/src/operand.h b/src/teakra/src/operand.h index 67900bd6..bd761aae 100644 --- a/src/teakra/src/operand.h +++ b/src/teakra/src/operand.h @@ -9,7 +9,7 @@ struct Operand { static_assert(bits > 0 && bits <= 16); static constexpr unsigned Bits = bits; -protected: +public: u16 storage{}; template