fix adds and such

This commit is contained in:
Alex Janka 2023-01-22 09:18:07 +11:00
parent 0e674af1b2
commit 043f333c7d

View file

@ -6,6 +6,7 @@ use std::{
use crate::{Inner, Memory, Register, State}; use crate::{Inner, Memory, Register, State};
#[allow(dead_code)] #[allow(dead_code)]
#[derive(PartialEq)]
enum FLAGS { enum FLAGS {
Z = 7, Z = 7,
N = 6, N = 6,
@ -87,7 +88,7 @@ impl CPU {
}, },
0x18 => unsafe { 0x18 => unsafe {
let t = (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) self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(t)
}, },
0x19 => unsafe { 0x19 => unsafe {
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.de.as_u16) self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.de.as_u16)
@ -110,9 +111,21 @@ impl CPU {
0x20 => { 0x20 => {
let jump_size = self.ld_immediate_byte(); let jump_size = self.ld_immediate_byte();
if self.get_flag(FLAGS::Z) == 0 { if self.get_flag(FLAGS::Z) == 0 {
println!("z flag is 0... so doing jump...");
unsafe { unsafe {
self.state.pc.as_u16 = self self.state.pc.as_u16 = self
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16) .state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
}
} else {
unsafe {
println!(
"not jumping! z flag is {0:#b}, flags are {1:#b} / {1:#X}",
self.get_flag(FLAGS::Z),
self.state.af.as_u8s.right
);
} }
} }
} }
@ -157,7 +170,10 @@ impl CPU {
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
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16) .state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
} }
} }
} }
@ -182,7 +198,10 @@ 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
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16) .state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
} }
} }
} }
@ -213,7 +232,10 @@ 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
.add_u16s(self.state.pc.as_u16, (as_signed(jump_size) as i16) as u16) .state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
} }
} }
} }
@ -359,8 +381,10 @@ impl CPU {
}, },
0x89 => unsafe { 0x89 => unsafe {
let f = self.get_flag(FLAGS::C); let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.state.af.as_u8s.left = self.add_u8s(
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right + f) self.state.af.as_u8s.left,
self.state.bc.as_u8s.right.wrapping_add(f),
)
}, },
0x8A => unsafe { 0x8A => unsafe {
let f = self.get_flag(FLAGS::C); let f = self.get_flag(FLAGS::C);
@ -386,7 +410,7 @@ impl CPU {
let f = 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.add_u8s(
self.state.af.as_u8s.left, self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16) + f, self.memory.get(self.state.hl.as_u16).wrapping_add(f),
) )
}, },
0x8F => unsafe { 0x8F => unsafe {
@ -1305,11 +1329,11 @@ 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 += 0x2; self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(0x2);
Register { Register {
as_u8s: Inner { as_u8s: Inner {
left: self.memory.get(address), left: self.memory.get(address),
right: self.memory.get(address + 1), right: self.memory.get(address.wrapping_add(1)),
}, },
} }
} }
@ -1346,8 +1370,19 @@ impl CPU {
} }
fn set_flag(&mut self, flag: FLAGS) { fn set_flag(&mut self, flag: FLAGS) {
if flag == FLAGS::Z {
println!("setting z flag");
}
unsafe { unsafe {
println!(
"setting flag: currently {0:#b} / {0:#X}",
self.state.af.as_u8s.right
);
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitor(1 << flag as u8); self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitor(1 << flag as u8);
println!(
" now {0:#b} / {0:#X}",
self.state.af.as_u8s.right
);
}; };
} }
@ -1375,8 +1410,11 @@ impl CPU {
let (result, carry) = first.overflowing_add(second); let (result, carry) = first.overflowing_add(second);
self.clear_flag(FLAGS::N); self.clear_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry); self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0); self.set_or_clear_flag(FLAGS::Z, result == 0x0);
self.set_or_clear_flag(FLAGS::H, (first & 0xF) + (second & 0xF) > 0xF); self.set_or_clear_flag(
FLAGS::H,
(((first & 0xF).wrapping_add(second & 0xF)) & 0x10) == 0x10,
);
return result; return result;
} }
@ -1384,8 +1422,11 @@ impl CPU {
let (result, carry) = first.overflowing_add(second); let (result, carry) = first.overflowing_add(second);
self.clear_flag(FLAGS::N); self.clear_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry); self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0); self.set_or_clear_flag(FLAGS::Z, result == 0x0);
self.set_or_clear_flag(FLAGS::H, (first & 0xF) + (second & 0xF) > 0xF); self.set_or_clear_flag(
FLAGS::H,
(((first & 0xFFF).wrapping_add(second & 0xFFF)) & 0x1000) == 0x1000,
);
return result; return result;
} }
@ -1393,10 +1434,10 @@ impl CPU {
let (result, carry) = first.overflowing_sub(second); let (result, carry) = first.overflowing_sub(second);
self.set_flag(FLAGS::N); self.set_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry); self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0); self.set_or_clear_flag(FLAGS::Z, result == 0x0);
self.set_or_clear_flag( self.set_or_clear_flag(
FLAGS::H, FLAGS::H,
((first & 0xF) as i32 - (second & 0xF) as i32) < 0xF, (((first & 0xF).wrapping_sub(second & 0xF)) & 0x10) == 0x10,
); );
return result; return result;
} }
@ -1405,17 +1446,17 @@ impl CPU {
let (result, carry) = first.overflowing_sub(second); let (result, carry) = first.overflowing_sub(second);
self.set_flag(FLAGS::N); self.set_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry); self.set_or_clear_flag(FLAGS::C, carry);
self.set_or_clear_flag(FLAGS::Z, !carry && result == 0x0); self.set_or_clear_flag(FLAGS::Z, result == 0x0);
self.set_or_clear_flag( self.set_or_clear_flag(
FLAGS::H, FLAGS::H,
((first & 0xF) as i32 - (second & 0xF) as i32) < 0xF, (((first & 0xFFF).wrapping_sub(second & 0xFFF)) & 0x1000) == 0x1000,
); );
return result; return result;
} }
} }
fn undefined(opcode: u8) { fn undefined(opcode: u8) {
println!("Undefined behaviour: opcode {:#X}", opcode); panic!("Undefined behaviour: opcode {:#X}", opcode);
} }
fn as_signed(unsigned: u8) -> i8 { fn as_signed(unsigned: u8) -> i8 {