From c372a96b7c8483fe8d0d3a781d4d09282d9389af Mon Sep 17 00:00:00 2001 From: Jared Burce Date: Fri, 12 Mar 2021 04:02:27 -0800 Subject: [PATCH] emu: all MOV opcodes (no modrm base/index/displacement modes yet) --- src/emu/i8088.rs | 42 +++++++++++++++++++++++++++++++++++++++--- src/emu/operands.rs | 17 +++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/emu/i8088.rs b/src/emu/i8088.rs index e0c506a..d533972 100644 --- a/src/emu/i8088.rs +++ b/src/emu/i8088.rs @@ -122,6 +122,15 @@ macro_rules! step { } } }; + (@modrm8 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, + ($modrm_val:ident, $modrm16:tt, { $($val:literal => $($args:ident = $argrhs:tt),*),*$(,)? } )) => { { + let modrm_val = $modrm_val & !0x38; + match modrm_val { + $( $val => step!(@push $cookie, ($($args = $argrhs)* ) ) ),*, + _ => unimplemented!("modrm: {:02X}({:02X})\ncpu: {:#X?}", $modrm_val, modrm_val, $cpu) + } + } }; + (@prefix $cookie:tt, $cpu:expr, $bus:expr, ($segment:ident, $prefix_loop:lifetime), $modrm:tt) => { continue $prefix_loop; }; (@r16 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm:ident, $modrm16:tt, $modrm8:tt)) => { @@ -246,14 +255,41 @@ impl i8088 { 0x2e => nop[seg=cs, prefix] / 2, 0x36 => nop[seg=ss, prefix] / 2, 0x3e => nop[seg=ds, prefix] / 2, - 0x60 => show[cpu] / 0, // Fake opcode for debugging + 0x60 => show[cpu] / 0, // Fake opcode for debugging 0x61 => peek[seg=ds, addr] / 0, // Fake opcode for debugging + 0x88 _ => mov[modrm8, r8] / "2/13+", + 0x89 _ => mov[modrm16, r16] / "2/13+", + 0x8A _ => mov[r8, modrm8] / "2/12+", 0x8B _ => mov[r16, modrm16] / "2/12+", - 0x8C: { 0x08 => mov[modrm16, reg=cs] / "2/13+", }, - 0x8E: { 0x18 => mov[reg=ds, modrm16] / "2/12+", }, + 0x8C: { 0x00 => mov[modrm16, reg=es] / "2/13+", + 0x08 => mov[modrm16, reg=cs] / "2/13+", + 0x10 => mov[modrm16, reg=ss] / "2/13+", + 0x18 => mov[modrm16, reg=ds] / "2/13+", }, + 0x8E: { 0x00 => mov[reg=es, modrm16] / "2/12+", + 0x08 => mov[reg=cs, modrm16] / "2/12+", + 0x10 => mov[reg=ss, modrm16] / "2/12+", + 0x18 => mov[reg=ds, modrm16] / "2/12+", }, 0x90 => nop[] / 3, + 0xA0 => mov[reglo=a, addr] / 14, + 0xA1 => mov[reg=a, addr] / 14, + 0xA2 => mov[addr, reglo=a] / 14, + 0xA3 => mov[addr, reg=a] / 14, + 0xB0 => mov[reglo=a, d8] / 4, + 0xB1 => mov[reglo=c, d8] / 4, + 0xB2 => mov[reglo=d, d8] / 4, + 0xB3 => mov[reglo=b, d8] / 4, 0xB4 => mov[reghi=a, d8] / 4, + 0xB5 => mov[reghi=c, d8] / 4, + 0xB6 => mov[reghi=d, d8] / 4, + 0xB7 => mov[reghi=b, d8] / 4, + 0xB8 => mov[reg=a, d16] / 4, + 0xB9 => mov[reg=c, d16] / 4, 0xBA => mov[reg=d, d16] / 4, + 0xBB => mov[reg=b, d16] / 4, + 0xBC => mov[reg=sp, d16] / 4, + 0xBD => mov[reg=bp, d16] / 4, + 0xBE => mov[reg=si, d16] / 4, + 0xBF => mov[reg=di, d16] / 4, 0xC3 => ret[reg=ip, regval=ss, reg=sp, mem] / 20, 0xCD => int[cpu, bus, d8] / 71, 0xE8 => call[reg=ip, regval=ss, reg=sp, mem, rel16] / 23, diff --git a/src/emu/operands.rs b/src/emu/operands.rs index 0f7bfb4..85fe90d 100644 --- a/src/emu/operands.rs +++ b/src/emu/operands.rs @@ -56,6 +56,23 @@ impl RValue for Addr<'_> { } } +impl LValue for Addr<'_> { + fn write(&mut self, val: u16) { + let buf = val.to_le_bytes(); + self.bus.write(self.addr, buf[0]); + self.bus.write(self.addr + 1, buf[1]); + } +} + +impl RValue for Addr<'_> { + fn read(&self) -> u16 { + let mut buf = [0u8; 2]; + buf[0] = self.bus.read(self.addr); + buf[1] = self.bus.read(self.addr + 1); + u16::from_le_bytes(buf) + } +} + pub struct Reg<'a> { pub reg: &'a Cell }