diff --git a/src/emu/i8088.rs b/src/emu/i8088.rs index e5b6410..7275958 100644 --- a/src/emu/i8088.rs +++ b/src/emu/i8088.rs @@ -46,65 +46,72 @@ pub enum RepPrefix { macro_rules! step { // Base case: all args processed and ready to call op - (@code $(form=($($tyargs:tt),*),)? ( $($done:tt)* ), - $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + (@code ( $($done:tt)* ), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, + $(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal, ()) => { - ops::$name$(::<$($tyargs),*>)?($($done),*); + $(ops::$name$(::<$($tyargs),*>)?)?($($done),*); }; // Inductive case: decode next arg to be placed in list - (@code $(form=$form:tt,)? ( $($done:tt)* ), - $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + (@code ( $($done:tt)* ), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, + $(name=$name:ident$(<$($tyargs:tt),*>)?,)? $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 - ( $(form=$form,)? ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ($($rest $(= $restrhs)?)*) ), + ( ($($done)*), $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, ($($rest $(= $restrhs)?)*) ), $cpu, $bus, $prefix, $modrm) }; // accept an argument from a decoder and recur to look for next arg - (@arg ( $(form=$form:tt,)? ($($done:tt)*), - $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + (@arg ( ($($done:tt)*), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, + $(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal, $rest:tt ) $(, $arg:expr)?) => { - step!(@code $(form=$form,)? ($($done)* $($arg)?), $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest) + step!(@code ($($done)* $($arg)?), $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, $rest) }; // decoder deferring to sub-decoders, push them onto the decoder stack to process next - (@push ( $(form=$form:tt,)? ($($done:tt)*), - $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, ( $($rest:tt)* ) ), + (@push ( ($($done:tt)*), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, + $(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal, + ( $($rest:tt)* ) ), ( $($args:tt)* )) => { - step!(@code $(form=$form,)? ($($done)*), $cpu, $bus, $prefix, $modrm, $name, $cycles, ( $($args)* $($rest)* )) + step!(@code ($($done)*), $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $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, + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, name=$name:ident, $cycles:literal, $rest:tt ), - form=$form:tt) => { - step!(@code form=$form, $done, $cpu, $bus, $prefix, $modrm, $name, $cycles, $rest) + form=<$($tyargs:tt),*> ) => { + step!(@code $done, $cpu, $bus, $prefix, $modrm, name=$name<$($tyargs),*>, $cycles, $rest) }; // Adds tokens to the last argument. Used by @convert to append ".into()" to the last arg (@append-to-last ($($done:tt)*) - ( $(form=$form:tt,)? ($last:tt), - $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + ( ($last:tt), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, + $(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal, $rest:tt ) { $($conv:tt)+ } ) => { - step!(@code $(form=$form,)? ($($done)* ($last$($conv)+)), - $cpu, $bus, $prefix, $modrm, $name, $cycles, + step!(@code ($($done)* ($last$($conv)+)), + $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, $rest ) }; // Recursive case for @append-to-last, walks through already // processed args to find the last one for appending (@append-to-last ($($done:tt)*) - ( $(form=$form:tt,)? ($next:tt $($restdone:tt)+), - $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, $name:ident, $cycles:literal, + ( ($next:tt $($restdone:tt)+), + $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt, + $(name=$name:ident$(<$($tyargs:tt),*>)?,)? $cycles:literal, $rest:tt ) { $($conv:tt)+ } ) => { step!(@append-to-last ($($done)* $next) - ( $(form=$form,)? ($($restdone)+), - $cpu, $bus, $prefix, $modrm, $name, $cycles, - $rest ) { $($conv)+ } ) + ( ($($restdone)+), + $cpu, $bus, $prefix, $modrm, $(name=$name$(<$($tyargs),*>)?,)? $cycles, + $rest ) { $($conv)+ } ) }; // === OP DIRECTIVES === @@ -179,27 +186,27 @@ macro_rules! step { }; (@form=byte0 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u8)) + step!(@form $cookie, form=) }; (@form=byte1 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u8, _)) + step!(@form $cookie, form=) }; (@form=byte3 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u8, _, _, _)) + step!(@form $cookie, form=) }; (@form=word0 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u16)) + step!(@form $cookie, form=) }; (@form=word1 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u16, _)) + step!(@form $cookie, form=) }; (@form=word3 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { - step!(@form $cookie, form=(u16, _, _, _)) + step!(@form $cookie, form=) }; (@mem $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { @@ -347,7 +354,7 @@ macro_rules! step { $name:ident[$($args:ident $(= $argrhs:tt)?),*] / $cycles:literal),*$(,)? } ) => { { let subcode = $modrm_val & 0x38; match subcode { - $( $subcode => step!(@code (), $cpu, $bus, $prefix, ($modrm_val, $modrm, $modrm16, $modrm8), $name, $cycles, ($($args $(= $argrhs)?)*)) ),*, + $( $subcode => step!(@code (), $cpu, $bus, $prefix, ($modrm_val, $modrm, $modrm16, $modrm8), name=$name, $cycles, ($($args $(= $argrhs)?)*)) ),*, _ => unimplemented!("opcode: {:02X} {:02X}({:02X})\ncpu: {:#X?}", $code, $modrm_val, subcode, $cpu) } } }; @@ -380,7 +387,7 @@ macro_rules! step { $( $( $code => { $( let $ext = (); /* No-op just to trigger expansion. */ modrm_val = i8088::next_ip($cpu.cs.get(), &mut $cpu.ip, $bus); )? - step!(@code (), $cpu, $bus, (segment, repeat, 'prefix_loop), (modrm_val, $modrm, $modrm16, $modrm8), $name, $cycles, ($($args $(= $argrhs)?)*)) + step!(@code (), $cpu, $bus, (segment, repeat, 'prefix_loop), (modrm_val, $modrm, $modrm16, $modrm8), name=$name, $cycles, ($($args $(= $argrhs)?)*)) } )? $( $code => { diff --git a/src/emu/operands.rs b/src/emu/operands.rs index cedb356..082db61 100644 --- a/src/emu/operands.rs +++ b/src/emu/operands.rs @@ -216,6 +216,7 @@ impl<'a> From> for DynLValue<'a> { DynLValue::FarPtr { segment: farptr.segment, offset: farptr.offset } } } + impl, T> LValue for &mut LVal { fn write(&mut self, val: T) { (**self).write(val);