fix adds and flags

This commit is contained in:
Alex Janka 2023-01-18 12:45:56 +11:00
parent 3cf0df204d
commit 9533768bd9

View file

@ -16,12 +16,16 @@ enum FLAGS {
pub struct CPU {
pub memory: Memory,
pub state: State,
pub last_instruction: u8,
pub last_instruction_addr: u16,
}
impl CPU {
pub fn exec_next(&mut self) {
unsafe { self.last_instruction_addr = self.state.pc.as_u16 };
let opcode = self.next_opcode();
// unsafe { println!("exec {:#4X} from {:#4X}", opcode, self.state.pc.as_u16 - 1) };
self.last_instruction = opcode;
match opcode {
0x0 => {
// noop
@ -31,12 +35,12 @@ impl CPU {
let address = self.state.bc.as_u16;
self.memory.set(address, self.state.af.as_u8s.left);
},
0x03 => unsafe { self.state.bc.as_u16 = self.state.bc.as_u16.wrapping_add(1) },
0x03 => unsafe { self.state.bc.as_u16 = self.add_u16s(self.state.bc.as_u16, 1) },
0x04 => unsafe {
self.state.bc.as_u8s.left = self.state.bc.as_u8s.left.wrapping_add(1)
self.state.bc.as_u8s.left = self.add_u8s(self.state.bc.as_u8s.left, 1)
},
0x05 => unsafe {
self.state.bc.as_u8s.left = self.state.bc.as_u8s.left.wrapping_sub(1)
self.state.bc.as_u8s.left = self.sub_u8s(self.state.bc.as_u8s.left, 1)
},
0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(),
0x07 => panic!("RCLA rotate instruction: 0x07"),
@ -46,15 +50,15 @@ impl CPU {
self.store_word(address, word);
},
0x09 => unsafe {
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(self.state.bc.as_u16)
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.bc.as_u16)
},
0x0A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.bc.as_u16) },
0x0B => unsafe { self.state.bc.as_u16 = self.state.bc.as_u16.wrapping_sub(0x1) },
0x0B => unsafe { self.state.bc.as_u16 = self.sub_u16s(self.state.bc.as_u16, 0x1) },
0x0C => unsafe {
self.state.bc.as_u8s.right = self.state.bc.as_u8s.right.wrapping_add(0x1)
self.state.bc.as_u8s.right = self.add_u8s(self.state.bc.as_u8s.right, 0x1)
},
0x0D => unsafe {
self.state.bc.as_u8s.right = self.state.bc.as_u8s.right.wrapping_sub(0x1)
self.state.bc.as_u8s.right = self.sub_u8s(self.state.bc.as_u8s.right, 0x1)
},
0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(),
0x0F => panic!("RRCA rotate instruction: 0x0F"),
@ -65,32 +69,32 @@ impl CPU {
let data = self.state.af.as_u8s.left;
self.memory.set(address, data);
},
0x13 => unsafe { self.state.de.as_u16 = self.state.de.as_u16.wrapping_sub(0x1) },
0x13 => unsafe { self.state.de.as_u16 = self.sub_u16s(self.state.de.as_u16, 0x1) },
0x14 => unsafe {
self.state.de.as_u8s.left = self.state.de.as_u8s.left.wrapping_add(0x1)
self.state.de.as_u8s.left = self.add_u8s(self.state.de.as_u8s.left, 0x1)
},
0x15 => unsafe {
self.state.de.as_u8s.left = self.state.de.as_u8s.left.wrapping_sub(0x1)
self.state.de.as_u8s.left = self.sub_u8s(self.state.de.as_u8s.left, 0x1)
},
0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(),
0x17 => panic!("RLA rotate instruction: 0x17"),
0x18 => unsafe {
self.state.pc.as_u16 = self
.state
.pc
.as_u16
.wrapping_add((as_signed(self.ld_immediate_byte()) as i16) as u16)
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
self.state.pc.as_u16 = self.add_u16s(self.state.pc.as_u16, t)
},
0x19 => unsafe {
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(self.state.de.as_u16)
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.de.as_u16)
},
0x1A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.de.as_u16) },
0x1B => unsafe { self.state.de.as_u16 = self.state.de.as_u16.wrapping_sub(1) },
0x1A => unsafe {
// println!("loading from {:#X}", self.state.de.as_u16);
self.state.af.as_u8s.left = self.memory.get(self.state.de.as_u16);
},
0x1B => unsafe { self.state.de.as_u16 = self.sub_u16s(self.state.de.as_u16, 1) },
0x1C => unsafe {
self.state.de.as_u8s.right = self.state.de.as_u8s.right.wrapping_add(1)
self.state.de.as_u8s.right = self.add_u8s(self.state.de.as_u8s.right, 1)
},
0x1D => unsafe {
self.state.de.as_u8s.right = self.state.de.as_u8s.right.wrapping_sub(1)
self.state.de.as_u8s.right = self.sub_u8s(self.state.de.as_u8s.right, 1)
},
0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(),
0x1F => panic!("RRA rotate instruction: 0x1F"),
@ -99,10 +103,7 @@ impl CPU {
if self.get_flag(FLAGS::Z) == 0 {
unsafe {
self.state.pc.as_u16 = self
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
}
}
}
@ -110,14 +111,14 @@ impl CPU {
0x22 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(1);
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, 1);
},
0x23 => unsafe { self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(1) },
0x23 => unsafe { self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, 1) },
0x24 => unsafe {
self.state.hl.as_u8s.left = self.state.hl.as_u8s.left.wrapping_add(1)
self.state.hl.as_u8s.left = self.add_u8s(self.state.hl.as_u8s.left, 1)
},
0x25 => unsafe {
self.state.hl.as_u8s.left = self.state.hl.as_u8s.left.wrapping_sub(1)
self.state.hl.as_u8s.left = self.sub_u8s(self.state.hl.as_u8s.left, 1)
},
0x26 => self.state.hl.as_u8s.left = self.ld_immediate_byte(),
0x27 => unsafe {
@ -137,30 +138,31 @@ impl CPU {
self.state.af.as_u8s.left -= 0x6;
}
}
println!(
" ...this set register a to {:#X}...",
self.state.af.as_u8s.left
);
},
0x28 => {
let jump_size = self.ld_immediate_byte();
if self.get_flag(FLAGS::Z) == 1 {
unsafe {
self.state.pc.as_u16 = self
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
}
}
}
0x29 => unsafe { self.state.hl.as_u16 *= 2 },
0x2A => unsafe {
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(1);
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, 1);
},
0x2B => unsafe { self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_sub(1) },
0x2B => unsafe { self.state.hl.as_u16 = self.sub_u16s(self.state.hl.as_u16, 1) },
0x2C => unsafe {
self.state.hl.as_u8s.right = self.state.hl.as_u8s.right.wrapping_add(1)
self.state.hl.as_u8s.right = self.add_u8s(self.state.hl.as_u8s.right, 1)
},
0x2D => unsafe {
self.state.hl.as_u8s.right = self.state.hl.as_u8s.right.wrapping_sub(1)
self.state.hl.as_u8s.right = self.sub_u8s(self.state.hl.as_u8s.right, 1)
},
0x2E => self.state.hl.as_u8s.right = self.ld_immediate_byte(),
0x2F => unsafe { self.state.af.as_u8s.left = !self.state.af.as_u8s.left },
@ -169,10 +171,7 @@ impl CPU {
if self.get_flag(FLAGS::C) == 0 {
unsafe {
self.state.pc.as_u16 = self
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
}
}
}
@ -180,9 +179,9 @@ impl CPU {
0x32 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_sub(1);
self.state.hl.as_u16 = self.sub_u16s(self.state.hl.as_u16, 1);
},
0x33 => unsafe { self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(1) },
0x33 => unsafe { self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 1) },
0x34 => unsafe {
let address = self.state.hl.as_u16;
let data = self.memory.get(address) + 1;
@ -203,26 +202,23 @@ impl CPU {
if self.get_flag(FLAGS::C) == 1 {
unsafe {
self.state.pc.as_u16 = self
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
}
}
}
0x39 => unsafe {
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(self.state.sp.as_u16)
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.sp.as_u16)
},
0x3A => unsafe {
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_sub(1);
self.state.hl.as_u16 = self.sub_u16s(self.state.hl.as_u16, 1);
},
0x3B => unsafe { self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_sub(1) },
0x3B => unsafe { self.state.sp.as_u16 = self.sub_u16s(self.state.sp.as_u16, 1) },
0x3C => unsafe {
self.state.af.as_u8s.left = self.state.af.as_u8s.left.wrapping_add(1)
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, 1)
},
0x3D => unsafe {
self.state.af.as_u8s.left = self.state.af.as_u8s.left.wrapping_sub(1)
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, 1)
},
0x3E => self.state.af.as_u8s.left = self.ld_immediate_byte(),
0x3F => self.toggle_flag(FLAGS::C),
@ -312,256 +308,156 @@ impl CPU {
0x7E => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16) },
0x7F => {}
0x80 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.bc.as_u8s.left)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left)
},
0x81 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.bc.as_u8s.right)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right)
},
0x82 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.de.as_u8s.left)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left)
},
0x83 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.de.as_u8s.right)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right)
},
0x84 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.hl.as_u8s.left)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left)
},
0x85 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.hl.as_u8s.right)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right)
},
0x86 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.memory.get(self.state.hl.as_u16))
self.state.af.as_u8s.left = self.add_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16),
)
},
0x87 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.af.as_u8s.left)
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left)
},
0x88 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.bc.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left + f)
},
0x89 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.bc.as_u8s.right + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right + f)
},
0x8A => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.de.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left + f)
},
0x8B => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.de.as_u8s.right + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right + f)
},
0x8C => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.hl.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left + f)
},
0x8D => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.hl.as_u8s.right + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right + f)
},
0x8E => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.wrapping_add(
self.memory.get(self.state.hl.as_u16) + self.get_flag(FLAGS::C),
)
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.add_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16) + f,
)
},
0x8F => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.state.af.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left + f)
},
0x90 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.bc.as_u8s.left)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left)
},
0x91 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.bc.as_u8s.right)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right)
},
0x92 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.de.as_u8s.left)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left)
},
0x93 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.de.as_u8s.right)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right)
},
0x94 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.hl.as_u8s.left)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left)
},
0x95 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.hl.as_u8s.right)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right)
},
0x96 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.memory.get(self.state.hl.as_u16))
self.state.af.as_u8s.left = self.sub_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16),
)
},
0x97 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.af.as_u8s.left)
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left)
},
0x98 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.bc.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left + f)
},
0x99 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.bc.as_u8s.right + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right + f)
},
0x9A => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.de.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left + f)
},
0x9B => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.de.as_u8s.right + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right + f)
},
0x9C => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.hl.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left + f)
},
0x9D => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.hl.as_u8s.right + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right + f)
},
0x9E => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.wrapping_sub(
self.memory.get(self.state.hl.as_u16) + self.get_flag(FLAGS::C),
)
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.sub_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16) + f,
)
},
0x9F => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.state.af.as_u8s.left + self.get_flag(FLAGS::C))
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left + f)
},
0xA0 => unsafe {
self.state.af.as_u8s.left =
@ -712,14 +608,14 @@ impl CPU {
let address = self.state.sp.as_u16;
self.state.pc.as_u8s.left = self.memory.get(address);
self.state.pc.as_u8s.right = self.memory.get(address + 1);
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
}
},
0xC1 => unsafe {
let address = self.state.sp.as_u16;
self.state.bc.as_u8s.left = self.memory.get(address);
self.state.bc.as_u8s.right = self.memory.get(address + 1);
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
},
0xC2 => {
let word = self.ld_immediate_word();
@ -739,12 +635,8 @@ impl CPU {
}
0xC5 => self.push(self.state.bc),
0xC6 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.ld_immediate_byte())
let t = self.ld_immediate_byte();
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, t)
},
0xC7 => self.rst(0x00),
0xC8 => {
@ -775,12 +667,8 @@ impl CPU {
self.state.pc = self.ld_immediate_word();
}
0xCE => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_add(self.ld_immediate_byte() + self.get_flag(FLAGS::C))
let t = self.ld_immediate_byte() + self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, t)
},
0xCF => self.rst(0x08),
0xD0 => unsafe {
@ -788,14 +676,14 @@ impl CPU {
let address = self.state.sp.as_u16;
self.state.pc.as_u8s.left = self.memory.get(address);
self.state.pc.as_u8s.right = self.memory.get(address + 1);
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
}
},
0xD1 => unsafe {
let address = self.state.sp.as_u16;
self.state.de.as_u8s.left = self.memory.get(address);
self.state.de.as_u8s.right = self.memory.get(address + 1);
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
},
0xD2 => {
let word = self.ld_immediate_word();
@ -813,12 +701,8 @@ impl CPU {
}
0xD5 => self.push(self.state.de),
0xD6 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.ld_immediate_byte())
let t = self.ld_immediate_byte();
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, t)
},
0xD7 => self.rst(0x10),
0xD8 => {
@ -846,12 +730,8 @@ impl CPU {
}
0xDD => undefined(0xDE),
0xDE => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.wrapping_sub(self.ld_immediate_byte() + self.get_flag(FLAGS::C))
let t = self.ld_immediate_byte() + self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, t)
},
0xDF => self.rst(0x18),
0xE0 => {
@ -869,7 +749,7 @@ impl CPU {
let address = self.state.sp.as_u16;
self.state.hl.as_u8s.left = self.memory.get(address);
self.state.hl.as_u8s.right = self.memory.get(address + 1);
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
},
0xE2 => {
unsafe {
@ -891,11 +771,8 @@ impl CPU {
},
0xE7 => self.rst(0x20),
0xE8 => unsafe {
self.state.sp.as_u16 = self
.state
.sp
.as_u16
.wrapping_add((as_signed(self.ld_immediate_byte()) as i16) as u16);
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, t);
},
0xE9 => self.state.pc = self.state.hl,
0xEA => unsafe {
@ -925,7 +802,7 @@ impl CPU {
let address = self.state.sp.as_u16;
self.state.af.as_u8s.left = self.memory.get(address);
self.state.af.as_u8s.right = self.memory.get(address + 1);
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
},
0xF2 => {
unsafe {
@ -947,11 +824,8 @@ impl CPU {
},
0xF7 => self.rst(0x30),
0xF8 => unsafe {
self.state.hl.as_u16 = self
.state
.sp
.as_u16
.wrapping_add((as_signed(self.ld_immediate_byte()) as i16) as u16)
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
self.state.hl.as_u16 = self.add_u16s(self.state.sp.as_u16, t)
},
0xF9 => self.state.sp = self.state.hl,
0xFA => unsafe {
@ -971,13 +845,18 @@ impl CPU {
}
fn cb_subop(&mut self, subop: u8) {
panic!("Unimplemented sub-opcode: {:#X}", subop);
match subop {
0x7C => unsafe {
self.set_or_clear_flag(FLAGS::Z, !get_bit(self.state.hl.as_u8s.left, 7))
},
_ => panic!("Unimplemented sub-opcode: {:#X}", subop),
}
}
fn next_opcode(&mut self) -> u8 {
unsafe {
let opcode = self.memory.get(self.state.pc.as_u16);
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(0x1);
self.state.pc.as_u16 += 0x1;
return opcode;
};
}
@ -1000,7 +879,7 @@ impl CPU {
fn pop_word(&mut self) -> Register {
unsafe {
let address = self.state.sp.as_u16;
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
self.state.sp.as_u16 += 0x2;
Register {
as_u8s: Inner {
left: self.memory.get(address),
@ -1032,7 +911,11 @@ impl CPU {
fn get_flag(&mut self, flag: FLAGS) -> u8 {
unsafe {
return self.state.af.as_u8s.right & (1 << flag as u8);
if get_bit(self.state.af.as_u8s.right, flag as u8) {
0x1
} else {
0x0
}
}
}
@ -1042,7 +925,6 @@ impl CPU {
};
}
#[allow(dead_code)]
fn clear_flag(&mut self, flag: FLAGS) {
unsafe {
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitand(!(1 << flag as u8));
@ -1054,6 +936,56 @@ impl CPU {
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitxor(1 << flag as u8);
};
}
fn set_or_clear_flag(&mut self, flag: FLAGS, state: bool) {
if state {
self.set_flag(flag)
} else {
self.clear_flag(flag)
}
}
fn add_u8s(&mut self, first: u8, second: u8) -> u8 {
let (result, carry) = first.overflowing_add(second);
self.clear_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0);
self.set_or_clear_flag(FLAGS::H, (first & 0xF) + (second & 0xF) > 0xF);
return result;
}
fn add_u16s(&mut self, first: u16, second: u16) -> u16 {
let (result, carry) = first.overflowing_add(second);
self.clear_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0);
self.set_or_clear_flag(FLAGS::H, (first & 0xF) + (second & 0xF) > 0xF);
return result;
}
fn sub_u8s(&mut self, first: u8, second: u8) -> u8 {
let (result, carry) = first.overflowing_sub(second);
self.set_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0);
self.set_or_clear_flag(
FLAGS::H,
((first & 0xF) as i32 - (second & 0xF) as i32) < 0xF,
);
return result;
}
fn sub_u16s(&mut self, first: u16, second: u16) -> u16 {
let (result, carry) = first.overflowing_sub(second);
self.set_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0);
self.set_or_clear_flag(
FLAGS::H,
((first & 0xF) as i32 - (second & 0xF) as i32) < 0xF,
);
return result;
}
}
fn undefined(opcode: u8) {
@ -1065,3 +997,9 @@ fn as_signed(unsigned: u8) -> i8 {
return transmute(unsigned);
}
}
fn get_bit(byte: u8, flag: u8) -> bool {
let mask = 1 << flag;
let got = byte & mask;
return got > 0x0;
}