浏览代码

UserspaceEmulator: Implement the LODSB/LODSW/LODSD instructions

Look how nice they look with the new loop instruction helpers. :^)
Andreas Kling 5 年之前
父节点
当前提交
41bbedc41d
共有 1 个文件被更改,包括 26 次插入3 次删除
  1. 26 3
      DevTools/UserspaceEmulator/SoftCPU.cpp

+ 26 - 3
DevTools/UserspaceEmulator/SoftCPU.cpp

@@ -1369,9 +1369,32 @@ void SoftCPU::LGS_reg32_mem32(const X86::Instruction&) { TODO(); }
 void SoftCPU::LIDT(const X86::Instruction&) { TODO(); }
 void SoftCPU::LIDT(const X86::Instruction&) { TODO(); }
 void SoftCPU::LLDT_RM16(const X86::Instruction&) { TODO(); }
 void SoftCPU::LLDT_RM16(const X86::Instruction&) { TODO(); }
 void SoftCPU::LMSW_RM16(const X86::Instruction&) { TODO(); }
 void SoftCPU::LMSW_RM16(const X86::Instruction&) { TODO(); }
-void SoftCPU::LODSB(const X86::Instruction&) { TODO(); }
-void SoftCPU::LODSD(const X86::Instruction&) { TODO(); }
-void SoftCPU::LODSW(const X86::Instruction&) { TODO(); }
+
+template<typename T>
+ALWAYS_INLINE static void do_lods(SoftCPU& cpu, const X86::Instruction& insn)
+{
+    auto src_segment = cpu.segment(insn.segment_prefix().value_or(X86::SegmentRegister::DS));
+    cpu.do_once_or_repeat<true>(insn, [&] {
+        auto src = cpu.read_memory<T>({ src_segment, cpu.source_index(insn.a32()) });
+        cpu.gpr<T>(X86::RegisterAL) = src;
+        cpu.step_source_index(insn.a32(), sizeof(T));
+    });
+}
+
+void SoftCPU::LODSB(const X86::Instruction& insn)
+{
+    do_lods<u8>(*this, insn);
+}
+
+void SoftCPU::LODSD(const X86::Instruction& insn)
+{
+    do_lods<u32>(*this, insn);
+}
+
+void SoftCPU::LODSW(const X86::Instruction& insn)
+{
+    do_lods<u16>(*this, insn);
+}
 
 
 void SoftCPU::LOOPNZ_imm8(const X86::Instruction& insn)
 void SoftCPU::LOOPNZ_imm8(const X86::Instruction& insn)
 {
 {