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; };
|
||||
|
||||
(@r16 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, ($modrm:ident, $modrm16:tt, $modrm8:tt)) => {
|
||||
@@ -248,12 +257,39 @@ impl i8088 {
|
||||
0x3e => nop[seg=ds, prefix] / 2,
|
||||
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,
|
||||
|
||||
@@ -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 reg: &'a Cell<u16>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user