emu: all MOV opcodes (no modrm base/index/displacement modes yet)
This commit is contained in:
@@ -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; };
|
(@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)) => {
|
(@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,
|
0x2e => nop[seg=cs, prefix] / 2,
|
||||||
0x36 => nop[seg=ss, prefix] / 2,
|
0x36 => nop[seg=ss, prefix] / 2,
|
||||||
0x3e => nop[seg=ds, 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
|
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+",
|
0x8B _ => mov[r16, modrm16] / "2/12+",
|
||||||
0x8C: { 0x08 => mov[modrm16, reg=cs] / "2/13+", },
|
0x8C: { 0x00 => mov[modrm16, reg=es] / "2/13+",
|
||||||
0x8E: { 0x18 => mov[reg=ds, modrm16] / "2/12+", },
|
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,
|
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,
|
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,
|
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,
|
0xC3 => ret[reg=ip, regval=ss, reg=sp, mem] / 20,
|
||||||
0xCD => int[cpu, bus, d8] / 71,
|
0xCD => int[cpu, bus, d8] / 71,
|
||||||
0xE8 => call[reg=ip, regval=ss, reg=sp, mem, rel16] / 23,
|
0xE8 => call[reg=ip, regval=ss, reg=sp, mem, rel16] / 23,
|
||||||
|
|||||||
@@ -56,6 +56,23 @@ impl RValue<u8> for Addr<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LValue<u16> 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<u16> 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 struct Reg<'a> {
|
||||||
pub reg: &'a Cell<u16>
|
pub reg: &'a Cell<u16>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user