fix adds and such
This commit is contained in:
parent
0e674af1b2
commit
043f333c7d
1 changed files with 60 additions and 19 deletions
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue