diff --git a/src/emu/i8088.rs b/src/emu/i8088.rs index b878781..23cb00d 100644 --- a/src/emu/i8088.rs +++ b/src/emu/i8088.rs @@ -1,6 +1,5 @@ use std::cell::Cell; use std::fmt::{Debug, Formatter}; -use std::marker::PhantomData; use super::byteorder::{ByteOrder, LittleEndian}; @@ -63,34 +62,45 @@ pub enum RepPrefix { macro_rules! step { // Base case: all args processed and ready to call op - (@code ( $($done:tt)* ), + (@code $(form=($($tyargs:tt),*),)? ( $($done:tt)* ), $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, ()) => { - ops::$name($($done),*); + ops::$name$(::<$($tyargs),*>)?($($done),*); }; // Inductive case: decode next arg to be placed in list - (@code ( $($done:tt)* ), + (@code $(form=$form:tt,)? ( $($done:tt)* ), $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, ($next:ident $(= $nextrhs:tt)? $($rest:ident $(= $restrhs:tt)?)*)) => { step!(@$next$(= $nextrhs)? // "cookie" tt to be passed thru to @arg so we have all the args for the recursive step - ( ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ($($rest $(= $restrhs)?)*) ), + ( $(form=$form,)? ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ($($rest $(= $restrhs)?)*) ), $cpu, $bus, $prefix, $modrm) }; // accept an argument from a decoder and recur to look for next arg - (@arg ( ($($done:tt)*), $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, - $name:ident, $cycles:literal, $rest:tt ) + (@arg ( $(form=$form:tt,)? ($($done:tt)*), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + $rest:tt ) $(, $arg:expr)?) => { - step!(@code ($($done)* $($arg)?), $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest) + step!(@code $(form=$form,)? ($($done)* $($arg)?), $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest) }; // decoder deferring to sub-decoders, push them onto the decoder stack to process next - (@push ( $done:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, ( $($rest:tt)* ) ), - ( $($args:tt)* )) => { - step!(@code $done, $cpu, $bus, $prefix, $modrm, $name, $cycles, ( $($args)* $($rest)* )) + (@push ( $(form=$form:tt,)? ($($done:tt)*), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, ( $($rest:tt)* ) ), + ( $($args:tt)* )) => { + step!(@code $(form=$form,)? ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ( $($args)* $($rest)* )) }; + + // Set the type arguments for operations that cannot infer width + (@form ( $done:tt, + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + $rest:tt ), + form=$form:tt) => { + step!(@code form=$form, $done, $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest) + }; + // Argument Decoders (@addr $cookie:tt, $cpu:expr, $bus:expr, @@ -192,6 +202,14 @@ macro_rules! step { step!(@arg $cookie, &mut $cpu.flags) }; + (@form=unary_byte $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { + step!(@form $cookie, form=(u8, _)); + }; + + (@form=unary_word $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { + step!(@form $cookie, form=(u16, _)); + }; + (@mem $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { step!(@arg $cookie, &mut $bus.ram) }; @@ -327,14 +345,6 @@ macro_rules! step { step!(@arg $cookie, $segment.unwrap()) } }; - (@width=byte $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@arg $cookie, PhantomData::); - }; - - (@width=word $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@arg $cookie, PhantomData::); - }; - // Group Decoder (@group $cpu:expr, $bus:expr, $prefix:tt, ($modrm_val:ident, $modrm:tt, $modrm16:tt, $modrm8:tt), @@ -416,22 +426,22 @@ impl i8088 { 0x3C => cmp[flags, reglo=a, d8] / "3/24+", 0x3D => cmp[flags, reg=a, d16] / "3/24+", 0x3E => nop[seg=ds, prefix] / 2, - 0x40 => inc[width=word, flags, reg=a] / 3, - 0x41 => inc[width=word, flags, reg=c] / 3, - 0x42 => inc[width=word, flags, reg=d] / 3, - 0x43 => inc[width=word, flags, reg=b] / 3, - 0x44 => inc[width=word, flags, reg=sp] / 3, - 0x45 => inc[width=word, flags, reg=bp] / 3, - 0x46 => inc[width=word, flags, reg=si] / 3, - 0x47 => inc[width=word, flags, reg=di] / 3, - 0x48 => dec[width=word, flags, reg=a] / 3, - 0x49 => dec[width=word, flags, reg=c] / 3, - 0x4A => dec[width=word, flags, reg=d] / 3, - 0x4B => dec[width=word, flags, reg=b] / 3, - 0x4C => dec[width=word, flags, reg=sp] / 3, - 0x4D => dec[width=word, flags, reg=bp] / 3, - 0x4E => dec[width=word, flags, reg=si] / 3, - 0x4F => dec[width=word, flags, reg=di] / 3, + 0x40 => inc[flags, reg=a] / 3, + 0x41 => inc[flags, reg=c] / 3, + 0x42 => inc[flags, reg=d] / 3, + 0x43 => inc[flags, reg=b] / 3, + 0x44 => inc[flags, reg=sp] / 3, + 0x45 => inc[flags, reg=bp] / 3, + 0x46 => inc[flags, reg=si] / 3, + 0x47 => inc[flags, reg=di] / 3, + 0x48 => dec[flags, reg=a] / 3, + 0x49 => dec[flags, reg=c] / 3, + 0x4A => dec[flags, reg=d] / 3, + 0x4B => dec[flags, reg=b] / 3, + 0x4C => dec[flags, reg=sp] / 3, + 0x4D => dec[flags, reg=bp] / 3, + 0x4E => dec[flags, reg=si] / 3, + 0x4F => dec[flags, reg=di] / 3, 0x50 => push[bus, regval=ss, reg=sp, regval=a] / 15, 0x51 => push[bus, regval=ss, reg=sp, regval=c] / 15, 0x52 => push[bus, regval=ss, reg=sp, regval=d] / 15, @@ -524,10 +534,10 @@ impl i8088 { 0xE8 => call[reg=ip, bus, regval=ss, reg=sp, rel16] / 23, 0xF2 => nop[rep=NotEqual, prefix] / 0, // REPNE/REPNZ 0xF3 => nop[rep=Equal, prefix] / 0, // REP/REPE/REPZ - 0xFE: { 00 => inc[width=byte, flags, modrm8] / "3/23+", // INC r/m8 - 08 => dec[width=byte, flags, modrm8] / "3/23+", }, // DEC r/m8 - 0xFF: { 00 => inc[width=word, flags, modrm16] / "3/23+", // INC r/m16 - 08 => dec[width=word, flags, modrm16] / "3/23+", // DEC r/m16 + 0xFE: { 00 => inc[form=unary_byte, flags, modrm8] / "3/23+", // INC r/m8 + 08 => dec[form=unary_byte, flags, modrm8] / "3/23+", }, // DEC r/m8 + 0xFF: { 00 => inc[form=unary_word, flags, modrm16] / "3/23+", // INC r/m16 + 08 => dec[form=unary_word, flags, modrm16] / "3/23+", // DEC r/m16 30 => push_modrm[unsafe_bus_maybe, regval=ss, reg=sp, modrm16] / "15/24+" }, }, modrm: { diff --git a/src/emu/operations.rs b/src/emu/operations.rs index 6a2a29f..1d1c461 100644 --- a/src/emu/operations.rs +++ b/src/emu/operations.rs @@ -1,6 +1,5 @@ use std::convert::Into; use std::fmt::Debug; -use std::marker::PhantomData; use emu::dos; use emu::i8088::{Flags, RepPrefix, i8088}; @@ -137,17 +136,13 @@ pub fn cmpsw(flags: &mut Flags, }); } -pub fn dec(_width: PhantomData, // Needed to disambiguate when dst is a FarPtr - flags: &mut Flags, - mut dst: impl LValue) { +pub fn dec>(flags: &mut Flags, mut dst: LVal) { let res = update_flags!(flags, T, dst.read().overflowing_sub(&T::one()), sf, zf, af, pf); flags.of = res == T::HI_BIT_MASK - T::one(); dst.write(res); } -pub fn inc(_width: PhantomData, // Needed to disambiguate when dst is a FarPtr - flags: &mut Flags, - mut dst: impl LValue) { +pub fn inc>(flags: &mut Flags, mut dst: LVal) { let res = update_flags!(flags, T, dst.read().overflowing_add(&T::one()), sf, zf, af, pf); flags.of = res == T::HI_BIT_MASK; dst.write(res);