emu: near/short JUMP instructions. Use u16+wrapping_add for all rels
This commit is contained in:
@@ -253,11 +253,16 @@ macro_rules! step {
|
||||
step!(@arg $cookie, $cpu.$reg.get());
|
||||
};
|
||||
|
||||
(@rel8 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { {
|
||||
let rel8 = i8088::next_ip($cpu.cs.get(), &mut $cpu.ip, $bus) as i8;
|
||||
step!(@arg $cookie, rel8 as u16)
|
||||
} };
|
||||
|
||||
(@rel16 $cookie:tt, $cpu:expr, $bus:expr, $prefix:tt, $modrm:tt) => { {
|
||||
let mut buf = [0; 2];
|
||||
buf[0] = i8088::next_ip($cpu.cs.get(), &mut $cpu.ip, $bus);
|
||||
buf[1] = i8088::next_ip($cpu.cs.get(), &mut $cpu.ip, $bus);
|
||||
step!(@arg $cookie, LittleEndian::read_i16(&buf))
|
||||
step!(@arg $cookie, LittleEndian::read_i16(&buf) as u16)
|
||||
} };
|
||||
|
||||
(@rep $cookie:tt, $cpu:expr, $bus:expr,
|
||||
@@ -393,6 +398,22 @@ impl i8088 {
|
||||
0x61 => peek[seg=ds, addr] / 0, // Fake opcode for debugging
|
||||
0x62 _ => assert[modrm8, d8] / 0, // Fake opcode for debugging
|
||||
0x63 _ => assert[modrm16, d16] / 0, // Fake opcode for debugging
|
||||
0x70 => jo[flags, reg=ip, rel8] / "16/4", // JO rel8
|
||||
0x71 => jno[flags, reg=ip, rel8] / "16/4", // JNO rel8
|
||||
0x72 => jb[flags, reg=ip, rel8] / "16/4", // JB/JNAE/JC rel8
|
||||
0x73 => jae[flags, reg=ip, rel8] / "16/4", // JNB/JAE/JNC rel8
|
||||
0x74 => jz[flags, reg=ip, rel8] / "16/4", // JE/JZ rel8
|
||||
0x75 => jnz[flags, reg=ip, rel8] / "16/4", // JNE/JNZ rel8
|
||||
0x76 => jbe[flags, reg=ip, rel8] / "16/4", // JBE/JNA rel8
|
||||
0x77 => ja[flags, reg=ip, rel8] / "16/4", // JNBE/JA rel8
|
||||
0x78 => js[flags, reg=ip, rel8] / "16/4", // JS rel8
|
||||
0x79 => jns[flags, reg=ip, rel8] / "16/4", // JNS rel8
|
||||
//0x7A => jpe[flags, reg=ip, rel8] / "16/4", // JP/JPE rel8 XXX: Parity flag not implemented
|
||||
//0x7B => jpo[flags, reg=ip, rel8] / "16/4", // JNP/JPO rel8 XXX: Parity flag not implemented
|
||||
0x7C => jl[flags, reg=ip, rel8] / "16/4", // JL/JNGE rel8
|
||||
0x7D => jge[flags, reg=ip, rel8] / "16/4", // JNL/JGE rel8
|
||||
0x7E => jle[flags, reg=ip, rel8] / "16/4", // JLE/JNG rel8
|
||||
0x7F => jg[flags, reg=ip, rel8] / "16/4", // JNLE/JG rel8
|
||||
0x80: { 0x38 => cmp[flags, modrm8, d8] / "4/23+", },
|
||||
0x81: { 0x38 => cmp[flags, modrm16, d16] / "4/23+", },
|
||||
0x83: { 0x38 => cmp[flags, modrm16, d8_as_d16] / "4/23+", },
|
||||
@@ -442,6 +463,9 @@ impl i8088 {
|
||||
0xBF => mov[reg=di, d16] / 4,
|
||||
0xC3 => pop[bus, regval=ss, reg=sp, reg=ip] / 20, // RET
|
||||
0xCD => int[cpu, bus, d8] / 71,
|
||||
0xE3 => jcxz[reg=ip, reg=c, rel8] / "18/6", // JCXZ rel8
|
||||
0xE9 => jmp[reg=ip, rel16] / 15, // JMP rel16
|
||||
0xEB => jmp[reg=ip, rel8] / 15, // JMP rel8
|
||||
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
|
||||
|
||||
@@ -89,8 +89,8 @@ pub fn peek(addr: &(impl Address + RValue<u8>)) {
|
||||
println!("PEEK: @{:#X} = {:#X} ({})", addr.addr(), addr.read(), addr.read());
|
||||
}
|
||||
|
||||
pub fn call(ip: &mut Reg, bus: &mut Bus, ss: u16, sp: &mut Reg, addr: i16) {
|
||||
let target = ip.read().wrapping_add(addr as u16);
|
||||
pub fn call(ip: &mut Reg, bus: &mut Bus, ss: u16, sp: &mut Reg, rel16: u16) {
|
||||
let target = ip.read().wrapping_add(rel16);
|
||||
push(bus, ss, sp, ip.read());
|
||||
ip.write(target);
|
||||
}
|
||||
@@ -142,6 +142,100 @@ pub fn int(cpu: &mut i8088, bus: &mut Bus, num: &u8) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ja(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if !flags.cf && !flags.zf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jae(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if !flags.cf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jb(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.cf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jbe(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.cf || flags.zf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jcxz(ip: &mut Reg, cx: &mut Reg, rel8: u16) {
|
||||
if cx.read() == 0 {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jg(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.zf && flags.sf == flags.of {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jge(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.sf == flags.of {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jl(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.sf != flags.of {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jle(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.zf || flags.sf != flags.of {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jmp(ip: &mut Reg, rel: u16) {
|
||||
ip.write(ip.read().wrapping_add(rel));
|
||||
}
|
||||
|
||||
pub fn jno(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if !flags.of {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jns(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if !flags.sf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jnz(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if !flags.zf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jo(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.of {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn js(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.sf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jz(flags: &Flags, ip: &mut Reg, rel8: u16) {
|
||||
if flags.zf {
|
||||
ip.write(ip.read().wrapping_add(rel8));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lea(dst: &mut Reg, addr: &FarPtr) {
|
||||
dst.write(addr.offset)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user