fix adds and flags
This commit is contained in:
parent
3cf0df204d
commit
9533768bd9
1 changed files with 223 additions and 285 deletions
508
src/processor.rs
508
src/processor.rs
|
@ -16,12 +16,16 @@ enum FLAGS {
|
||||||
pub struct CPU {
|
pub struct CPU {
|
||||||
pub memory: Memory,
|
pub memory: Memory,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
|
pub last_instruction: u8,
|
||||||
|
pub last_instruction_addr: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CPU {
|
impl CPU {
|
||||||
pub fn exec_next(&mut self) {
|
pub fn exec_next(&mut self) {
|
||||||
|
unsafe { self.last_instruction_addr = self.state.pc.as_u16 };
|
||||||
let opcode = self.next_opcode();
|
let opcode = self.next_opcode();
|
||||||
// unsafe { println!("exec {:#4X} from {:#4X}", opcode, self.state.pc.as_u16 - 1) };
|
self.last_instruction = opcode;
|
||||||
|
|
||||||
match opcode {
|
match opcode {
|
||||||
0x0 => {
|
0x0 => {
|
||||||
// noop
|
// noop
|
||||||
|
@ -31,12 +35,12 @@ impl CPU {
|
||||||
let address = self.state.bc.as_u16;
|
let address = self.state.bc.as_u16;
|
||||||
self.memory.set(address, self.state.af.as_u8s.left);
|
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 {
|
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 {
|
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(),
|
0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(),
|
||||||
0x07 => panic!("RCLA rotate instruction: 0x07"),
|
0x07 => panic!("RCLA rotate instruction: 0x07"),
|
||||||
|
@ -46,15 +50,15 @@ impl CPU {
|
||||||
self.store_word(address, word);
|
self.store_word(address, word);
|
||||||
},
|
},
|
||||||
0x09 => unsafe {
|
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) },
|
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 {
|
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 {
|
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(),
|
0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(),
|
||||||
0x0F => panic!("RRCA rotate instruction: 0x0F"),
|
0x0F => panic!("RRCA rotate instruction: 0x0F"),
|
||||||
|
@ -65,32 +69,32 @@ impl CPU {
|
||||||
let data = self.state.af.as_u8s.left;
|
let data = self.state.af.as_u8s.left;
|
||||||
self.memory.set(address, data);
|
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 {
|
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 {
|
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(),
|
0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(),
|
||||||
0x17 => panic!("RLA rotate instruction: 0x17"),
|
0x17 => panic!("RLA rotate instruction: 0x17"),
|
||||||
0x18 => unsafe {
|
0x18 => unsafe {
|
||||||
self.state.pc.as_u16 = self
|
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
|
||||||
.state
|
self.state.pc.as_u16 = self.add_u16s(self.state.pc.as_u16, t)
|
||||||
.pc
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(self.ld_immediate_byte()) as i16) as u16)
|
|
||||||
},
|
},
|
||||||
0x19 => unsafe {
|
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) },
|
0x1A => unsafe {
|
||||||
0x1B => unsafe { self.state.de.as_u16 = self.state.de.as_u16.wrapping_sub(1) },
|
// 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 {
|
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 {
|
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(),
|
0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(),
|
||||||
0x1F => panic!("RRA rotate instruction: 0x1F"),
|
0x1F => panic!("RRA rotate instruction: 0x1F"),
|
||||||
|
@ -99,10 +103,7 @@ impl CPU {
|
||||||
if self.get_flag(FLAGS::Z) == 0 {
|
if self.get_flag(FLAGS::Z) == 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.state.pc.as_u16 = self
|
self.state.pc.as_u16 = self
|
||||||
.state
|
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
|
||||||
.pc
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(jump_size) as i16) as u16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,14 +111,14 @@ impl CPU {
|
||||||
0x22 => unsafe {
|
0x22 => unsafe {
|
||||||
self.memory
|
self.memory
|
||||||
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
|
.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 {
|
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 {
|
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(),
|
0x26 => self.state.hl.as_u8s.left = self.ld_immediate_byte(),
|
||||||
0x27 => unsafe {
|
0x27 => unsafe {
|
||||||
|
@ -137,30 +138,31 @@ impl CPU {
|
||||||
self.state.af.as_u8s.left -= 0x6;
|
self.state.af.as_u8s.left -= 0x6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!(
|
||||||
|
" ...this set register a to {:#X}...",
|
||||||
|
self.state.af.as_u8s.left
|
||||||
|
);
|
||||||
},
|
},
|
||||||
0x28 => {
|
0x28 => {
|
||||||
let jump_size = self.ld_immediate_byte();
|
let jump_size = self.ld_immediate_byte();
|
||||||
if self.get_flag(FLAGS::Z) == 1 {
|
if self.get_flag(FLAGS::Z) == 1 {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.state.pc.as_u16 = self
|
self.state.pc.as_u16 = self
|
||||||
.state
|
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
|
||||||
.pc
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(jump_size) as i16) as u16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x29 => unsafe { self.state.hl.as_u16 *= 2 },
|
0x29 => unsafe { self.state.hl.as_u16 *= 2 },
|
||||||
0x2A => unsafe {
|
0x2A => unsafe {
|
||||||
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
|
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 {
|
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 {
|
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(),
|
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 },
|
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 {
|
if self.get_flag(FLAGS::C) == 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.state.pc.as_u16 = self
|
self.state.pc.as_u16 = self
|
||||||
.state
|
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
|
||||||
.pc
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(jump_size) as i16) as u16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,9 +179,9 @@ impl CPU {
|
||||||
0x32 => unsafe {
|
0x32 => unsafe {
|
||||||
self.memory
|
self.memory
|
||||||
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
|
.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 {
|
0x34 => unsafe {
|
||||||
let address = self.state.hl.as_u16;
|
let address = self.state.hl.as_u16;
|
||||||
let data = self.memory.get(address) + 1;
|
let data = self.memory.get(address) + 1;
|
||||||
|
@ -203,26 +202,23 @@ impl CPU {
|
||||||
if self.get_flag(FLAGS::C) == 1 {
|
if self.get_flag(FLAGS::C) == 1 {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.state.pc.as_u16 = self
|
self.state.pc.as_u16 = self
|
||||||
.state
|
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16)
|
||||||
.pc
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(jump_size) as i16) as u16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x39 => unsafe {
|
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 {
|
0x3A => unsafe {
|
||||||
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
|
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 {
|
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 {
|
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(),
|
0x3E => self.state.af.as_u8s.left = self.ld_immediate_byte(),
|
||||||
0x3F => self.toggle_flag(FLAGS::C),
|
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) },
|
0x7E => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16) },
|
||||||
0x7F => {}
|
0x7F => {}
|
||||||
0x80 => unsafe {
|
0x80 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.bc.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x81 => unsafe {
|
0x81 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.bc.as_u8s.right)
|
|
||||||
},
|
},
|
||||||
0x82 => unsafe {
|
0x82 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.de.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x83 => unsafe {
|
0x83 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.de.as_u8s.right)
|
|
||||||
},
|
},
|
||||||
0x84 => unsafe {
|
0x84 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.hl.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x85 => unsafe {
|
0x85 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.hl.as_u8s.right)
|
|
||||||
},
|
},
|
||||||
0x86 => unsafe {
|
0x86 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left = self.add_u8s(
|
||||||
.state
|
self.state.af.as_u8s.left,
|
||||||
.af
|
self.memory.get(self.state.hl.as_u16),
|
||||||
.as_u8s
|
)
|
||||||
.left
|
|
||||||
.wrapping_add(self.memory.get(self.state.hl.as_u16))
|
|
||||||
},
|
},
|
||||||
0x87 => unsafe {
|
0x87 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.add_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.af.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x88 => unsafe {
|
0x88 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.bc.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x89 => unsafe {
|
0x89 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.bc.as_u8s.right + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x8A => unsafe {
|
0x8A => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.de.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x8B => unsafe {
|
0x8B => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.de.as_u8s.right + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x8C => unsafe {
|
0x8C => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.hl.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x8D => unsafe {
|
0x8D => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.hl.as_u8s.right + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x8E => unsafe {
|
0x8E => unsafe {
|
||||||
self.state.af.as_u8s.left =
|
let f = self.get_flag(FLAGS::C);
|
||||||
self.state.af.as_u8s.left.wrapping_add(
|
self.state.af.as_u8s.left = self.add_u8s(
|
||||||
self.memory.get(self.state.hl.as_u16) + self.get_flag(FLAGS::C),
|
self.state.af.as_u8s.left,
|
||||||
)
|
self.memory.get(self.state.hl.as_u16) + f,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
0x8F => unsafe {
|
0x8F => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.add_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.state.af.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x90 => unsafe {
|
0x90 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.bc.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x91 => unsafe {
|
0x91 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.bc.as_u8s.right)
|
|
||||||
},
|
},
|
||||||
0x92 => unsafe {
|
0x92 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.de.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x93 => unsafe {
|
0x93 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.de.as_u8s.right)
|
|
||||||
},
|
},
|
||||||
0x94 => unsafe {
|
0x94 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.hl.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x95 => unsafe {
|
0x95 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.hl.as_u8s.right)
|
|
||||||
},
|
},
|
||||||
0x96 => unsafe {
|
0x96 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left = self.sub_u8s(
|
||||||
.state
|
self.state.af.as_u8s.left,
|
||||||
.af
|
self.memory.get(self.state.hl.as_u16),
|
||||||
.as_u8s
|
)
|
||||||
.left
|
|
||||||
.wrapping_sub(self.memory.get(self.state.hl.as_u16))
|
|
||||||
},
|
},
|
||||||
0x97 => unsafe {
|
0x97 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
self.state.af.as_u8s.left =
|
||||||
.state
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.af.as_u8s.left)
|
|
||||||
},
|
},
|
||||||
0x98 => unsafe {
|
0x98 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.bc.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x99 => unsafe {
|
0x99 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.bc.as_u8s.right + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x9A => unsafe {
|
0x9A => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.de.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x9B => unsafe {
|
0x9B => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.de.as_u8s.right + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x9C => unsafe {
|
0x9C => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.hl.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x9D => unsafe {
|
0x9D => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.hl.as_u8s.right + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0x9E => unsafe {
|
0x9E => unsafe {
|
||||||
self.state.af.as_u8s.left =
|
let f = self.get_flag(FLAGS::C);
|
||||||
self.state.af.as_u8s.left.wrapping_sub(
|
self.state.af.as_u8s.left = self.sub_u8s(
|
||||||
self.memory.get(self.state.hl.as_u16) + self.get_flag(FLAGS::C),
|
self.state.af.as_u8s.left,
|
||||||
)
|
self.memory.get(self.state.hl.as_u16) + f,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
0x9F => unsafe {
|
0x9F => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let f = self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left =
|
||||||
.af
|
self.sub_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left + f)
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.state.af.as_u8s.left + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0xA0 => unsafe {
|
0xA0 => unsafe {
|
||||||
self.state.af.as_u8s.left =
|
self.state.af.as_u8s.left =
|
||||||
|
@ -712,14 +608,14 @@ impl CPU {
|
||||||
let address = self.state.sp.as_u16;
|
let address = self.state.sp.as_u16;
|
||||||
self.state.pc.as_u8s.left = self.memory.get(address);
|
self.state.pc.as_u8s.left = self.memory.get(address);
|
||||||
self.state.pc.as_u8s.right = self.memory.get(address + 1);
|
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 {
|
0xC1 => unsafe {
|
||||||
let address = self.state.sp.as_u16;
|
let address = self.state.sp.as_u16;
|
||||||
self.state.bc.as_u8s.left = self.memory.get(address);
|
self.state.bc.as_u8s.left = self.memory.get(address);
|
||||||
self.state.bc.as_u8s.right = self.memory.get(address + 1);
|
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 => {
|
0xC2 => {
|
||||||
let word = self.ld_immediate_word();
|
let word = self.ld_immediate_word();
|
||||||
|
@ -739,12 +635,8 @@ impl CPU {
|
||||||
}
|
}
|
||||||
0xC5 => self.push(self.state.bc),
|
0xC5 => self.push(self.state.bc),
|
||||||
0xC6 => unsafe {
|
0xC6 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let t = self.ld_immediate_byte();
|
||||||
.state
|
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, t)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.ld_immediate_byte())
|
|
||||||
},
|
},
|
||||||
0xC7 => self.rst(0x00),
|
0xC7 => self.rst(0x00),
|
||||||
0xC8 => {
|
0xC8 => {
|
||||||
|
@ -775,12 +667,8 @@ impl CPU {
|
||||||
self.state.pc = self.ld_immediate_word();
|
self.state.pc = self.ld_immediate_word();
|
||||||
}
|
}
|
||||||
0xCE => unsafe {
|
0xCE => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let t = self.ld_immediate_byte() + self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, t)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_add(self.ld_immediate_byte() + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0xCF => self.rst(0x08),
|
0xCF => self.rst(0x08),
|
||||||
0xD0 => unsafe {
|
0xD0 => unsafe {
|
||||||
|
@ -788,14 +676,14 @@ impl CPU {
|
||||||
let address = self.state.sp.as_u16;
|
let address = self.state.sp.as_u16;
|
||||||
self.state.pc.as_u8s.left = self.memory.get(address);
|
self.state.pc.as_u8s.left = self.memory.get(address);
|
||||||
self.state.pc.as_u8s.right = self.memory.get(address + 1);
|
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 {
|
0xD1 => unsafe {
|
||||||
let address = self.state.sp.as_u16;
|
let address = self.state.sp.as_u16;
|
||||||
self.state.de.as_u8s.left = self.memory.get(address);
|
self.state.de.as_u8s.left = self.memory.get(address);
|
||||||
self.state.de.as_u8s.right = self.memory.get(address + 1);
|
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 => {
|
0xD2 => {
|
||||||
let word = self.ld_immediate_word();
|
let word = self.ld_immediate_word();
|
||||||
|
@ -813,12 +701,8 @@ impl CPU {
|
||||||
}
|
}
|
||||||
0xD5 => self.push(self.state.de),
|
0xD5 => self.push(self.state.de),
|
||||||
0xD6 => unsafe {
|
0xD6 => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let t = self.ld_immediate_byte();
|
||||||
.state
|
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, t)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.ld_immediate_byte())
|
|
||||||
},
|
},
|
||||||
0xD7 => self.rst(0x10),
|
0xD7 => self.rst(0x10),
|
||||||
0xD8 => {
|
0xD8 => {
|
||||||
|
@ -846,12 +730,8 @@ impl CPU {
|
||||||
}
|
}
|
||||||
0xDD => undefined(0xDE),
|
0xDD => undefined(0xDE),
|
||||||
0xDE => unsafe {
|
0xDE => unsafe {
|
||||||
self.state.af.as_u8s.left = self
|
let t = self.ld_immediate_byte() + self.get_flag(FLAGS::C);
|
||||||
.state
|
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, t)
|
||||||
.af
|
|
||||||
.as_u8s
|
|
||||||
.left
|
|
||||||
.wrapping_sub(self.ld_immediate_byte() + self.get_flag(FLAGS::C))
|
|
||||||
},
|
},
|
||||||
0xDF => self.rst(0x18),
|
0xDF => self.rst(0x18),
|
||||||
0xE0 => {
|
0xE0 => {
|
||||||
|
@ -869,7 +749,7 @@ impl CPU {
|
||||||
let address = self.state.sp.as_u16;
|
let address = self.state.sp.as_u16;
|
||||||
self.state.hl.as_u8s.left = self.memory.get(address);
|
self.state.hl.as_u8s.left = self.memory.get(address);
|
||||||
self.state.hl.as_u8s.right = self.memory.get(address + 1);
|
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 => {
|
0xE2 => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -891,11 +771,8 @@ impl CPU {
|
||||||
},
|
},
|
||||||
0xE7 => self.rst(0x20),
|
0xE7 => self.rst(0x20),
|
||||||
0xE8 => unsafe {
|
0xE8 => unsafe {
|
||||||
self.state.sp.as_u16 = self
|
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
|
||||||
.state
|
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, t);
|
||||||
.sp
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(self.ld_immediate_byte()) as i16) as u16);
|
|
||||||
},
|
},
|
||||||
0xE9 => self.state.pc = self.state.hl,
|
0xE9 => self.state.pc = self.state.hl,
|
||||||
0xEA => unsafe {
|
0xEA => unsafe {
|
||||||
|
@ -925,7 +802,7 @@ impl CPU {
|
||||||
let address = self.state.sp.as_u16;
|
let address = self.state.sp.as_u16;
|
||||||
self.state.af.as_u8s.left = self.memory.get(address);
|
self.state.af.as_u8s.left = self.memory.get(address);
|
||||||
self.state.af.as_u8s.right = self.memory.get(address + 1);
|
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 => {
|
0xF2 => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -947,11 +824,8 @@ impl CPU {
|
||||||
},
|
},
|
||||||
0xF7 => self.rst(0x30),
|
0xF7 => self.rst(0x30),
|
||||||
0xF8 => unsafe {
|
0xF8 => unsafe {
|
||||||
self.state.hl.as_u16 = self
|
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
|
||||||
.state
|
self.state.hl.as_u16 = self.add_u16s(self.state.sp.as_u16, t)
|
||||||
.sp
|
|
||||||
.as_u16
|
|
||||||
.wrapping_add((as_signed(self.ld_immediate_byte()) as i16) as u16)
|
|
||||||
},
|
},
|
||||||
0xF9 => self.state.sp = self.state.hl,
|
0xF9 => self.state.sp = self.state.hl,
|
||||||
0xFA => unsafe {
|
0xFA => unsafe {
|
||||||
|
@ -971,13 +845,18 @@ impl CPU {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cb_subop(&mut self, subop: u8) {
|
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 {
|
fn next_opcode(&mut self) -> u8 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let opcode = self.memory.get(self.state.pc.as_u16);
|
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;
|
return opcode;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1000,7 +879,7 @@ impl CPU {
|
||||||
fn pop_word(&mut self) -> Register {
|
fn pop_word(&mut self) -> Register {
|
||||||
unsafe {
|
unsafe {
|
||||||
let address = self.state.sp.as_u16;
|
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 {
|
Register {
|
||||||
as_u8s: Inner {
|
as_u8s: Inner {
|
||||||
left: self.memory.get(address),
|
left: self.memory.get(address),
|
||||||
|
@ -1032,7 +911,11 @@ impl CPU {
|
||||||
|
|
||||||
fn get_flag(&mut self, flag: FLAGS) -> u8 {
|
fn get_flag(&mut self, flag: FLAGS) -> u8 {
|
||||||
unsafe {
|
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) {
|
fn clear_flag(&mut self, flag: FLAGS) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitand(!(1 << flag as u8));
|
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);
|
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) {
|
fn undefined(opcode: u8) {
|
||||||
|
@ -1065,3 +997,9 @@ fn as_signed(unsigned: u8) -> i8 {
|
||||||
return transmute(unsigned);
|
return transmute(unsigned);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_bit(byte: u8, flag: u8) -> bool {
|
||||||
|
let mask = 1 << flag;
|
||||||
|
let got = byte & mask;
|
||||||
|
return got > 0x0;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue