fix: call opcode now pushes correct address onto stack

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-01-17 22:12:00 -06:00
parent c0b8b8bda2
commit 386a780a6f
2 changed files with 36 additions and 53 deletions

View File

@ -91,29 +91,19 @@ impl Cpu {
} }
impl Cpu { impl Cpu {
pub fn dbg_read_byte(&self, addr: u16) -> u8 { pub fn read_imm_byte(&mut self, addr: u16) -> u8 {
self.inc_pc();
self.bus.read_byte(addr) self.bus.read_byte(addr)
} }
pub fn dbg_write_byte(&mut self, addr: u16, byte: u8) { pub fn read_imm_word(&mut self, addr: u16) -> u16 {
self.bus.write_byte(addr, byte); self.inc_pc();
} self.inc_pc();
pub fn dbg_read_word(&self, addr: u16) -> u16 {
self.bus.read_word(addr) self.bus.read_word(addr)
} }
pub fn dbg_write_word(&mut self, addr: u16, word: u16) {
self.bus.write_word(addr, word)
}
}
impl Cpu {
pub fn read_byte(&mut self, addr: u16) -> u8 { pub fn read_byte(&mut self, addr: u16) -> u8 {
let byte = self.bus.read_byte(addr); self.bus.read_byte(addr)
self.inc_pc();
byte
} }
pub fn write_byte(&mut self, addr: u16, byte: u8) { pub fn write_byte(&mut self, addr: u16, byte: u8) {
@ -121,11 +111,7 @@ impl Cpu {
} }
pub fn read_word(&mut self, addr: u16) -> u16 { pub fn read_word(&mut self, addr: u16) -> u16 {
let word = self.bus.read_word(addr); self.bus.read_word(addr)
self.inc_pc();
self.inc_pc();
word
} }
pub fn write_word(&mut self, addr: u16, word: u16) { pub fn write_word(&mut self, addr: u16, word: u16) {

View File

@ -1021,12 +1021,13 @@ impl Instruction {
// CALL cc[y], nn | Store nn on the stack, then store nn in the program coutner if cond is met // CALL cc[y], nn | Store nn on the stack, then store nn in the program coutner if cond is met
// CALL nn | Store nn on the stack, then store nn in the program counter // CALL nn | Store nn on the stack, then store nn in the program counter
let flags: Flags = cpu.register(Register::Flag).into(); let flags: Flags = cpu.register(Register::Flag).into();
let pc = cpu.register_pair(RegisterPair::PC);
match cond { match cond {
JumpCondition::NotZero => { JumpCondition::NotZero => {
if !flags.z { if !flags.z {
Self::push(cpu, nn); Self::push(cpu, nn);
cpu.set_register_pair(RegisterPair::PC, nn); cpu.set_register_pair(RegisterPair::PC, pc + 1);
return Cycles(24); return Cycles(24);
} }
Cycles(12) Cycles(12)
@ -1034,7 +1035,7 @@ impl Instruction {
JumpCondition::Zero => { JumpCondition::Zero => {
if flags.z { if flags.z {
Self::push(cpu, nn); Self::push(cpu, nn);
cpu.set_register_pair(RegisterPair::PC, nn); cpu.set_register_pair(RegisterPair::PC, pc + 1);
return Cycles(24); return Cycles(24);
} }
Cycles(12) Cycles(12)
@ -1042,7 +1043,7 @@ impl Instruction {
JumpCondition::NotCarry => { JumpCondition::NotCarry => {
if !flags.c { if !flags.c {
Self::push(cpu, nn); Self::push(cpu, nn);
cpu.set_register_pair(RegisterPair::PC, nn); cpu.set_register_pair(RegisterPair::PC, pc + 1);
return Cycles(24); return Cycles(24);
} }
Cycles(12) Cycles(12)
@ -1050,14 +1051,14 @@ impl Instruction {
JumpCondition::Carry => { JumpCondition::Carry => {
if flags.c { if flags.c {
Self::push(cpu, nn); Self::push(cpu, nn);
cpu.set_register_pair(RegisterPair::PC, nn); cpu.set_register_pair(RegisterPair::PC, pc + 1);
return Cycles(24); return Cycles(24);
} }
Cycles(12) Cycles(12)
} }
JumpCondition::Always => { JumpCondition::Always => {
Self::push(cpu, nn); Self::push(cpu, nn);
cpu.set_register_pair(RegisterPair::PC, nn); cpu.set_register_pair(RegisterPair::PC, pc + 1);
Cycles(24) Cycles(24)
} }
} }
@ -1509,12 +1510,10 @@ impl Instruction {
fn push(cpu: &mut Cpu, value: u16) { fn push(cpu: &mut Cpu, value: u16) {
let mut sp = cpu.register_pair(RegisterPair::SP); let mut sp = cpu.register_pair(RegisterPair::SP);
// FIXME: Are these debug functions really necessary?
sp -= 1; sp -= 1;
cpu.dbg_write_byte(sp, (value >> 8) as u8); cpu.write_byte(sp, (value >> 8) as u8);
sp -= 1; sp -= 1;
cpu.dbg_write_byte(sp, value as u8); cpu.write_byte(sp, value as u8);
cpu.set_register_pair(RegisterPair::SP, sp); cpu.set_register_pair(RegisterPair::SP, sp);
} }
@ -1525,11 +1524,9 @@ impl Instruction {
fn pop(cpu: &mut Cpu) -> u16 { fn pop(cpu: &mut Cpu) -> u16 {
let mut sp = cpu.register_pair(RegisterPair::SP); let mut sp = cpu.register_pair(RegisterPair::SP);
// FIXME: Are these debug functions really necessary? let low = cpu.read_byte(sp);
let low = cpu.dbg_read_byte(sp);
sp += 1; sp += 1;
let high = cpu.dbg_read_byte(sp); let high = cpu.read_byte(sp);
sp += 1; sp += 1;
cpu.set_register_pair(RegisterPair::SP, sp); cpu.set_register_pair(RegisterPair::SP, sp);
@ -1664,16 +1661,16 @@ impl Instruction {
(0, 0, _, 0, _) => Self::NOP, // NOP (0, 0, _, 0, _) => Self::NOP, // NOP
(0, 0, _, 1, _) => Self::LD( (0, 0, _, 1, _) => Self::LD(
// LD (nn), SP // LD (nn), SP
LDTarget::ByteAtAddress(cpu.read_word(pc)), LDTarget::ByteAtAddress(cpu.read_imm_word(pc)),
LDTarget::RegisterPair(RegisterPair::SP), LDTarget::RegisterPair(RegisterPair::SP),
), ),
(0, 0, _, 2, _) => Self::STOP, // STOP (0, 0, _, 2, _) => Self::STOP, // STOP
(0, 0, _, 3, _) => Self::JR(JumpCondition::Always, cpu.read_byte(pc) as i8), // JR d (0, 0, _, 3, _) => Self::JR(JumpCondition::Always, cpu.read_imm_byte(pc) as i8), // JR d
(0, 0, _, 4..=7, _) => Self::JR(Table::cc(y - 4), cpu.read_byte(pc) as i8), // JR cc[y - 4], d (0, 0, _, 4..=7, _) => Self::JR(Table::cc(y - 4), cpu.read_imm_byte(pc) as i8), // JR cc[y - 4], d
(0, 1, 0, _, _) => Self::LD( (0, 1, 0, _, _) => Self::LD(
// LD rp[p], nn // LD rp[p], nn
LDTarget::RegisterPair(Table::rp(p)), LDTarget::RegisterPair(Table::rp(p)),
LDTarget::ImmediateWord(cpu.read_word(pc)), LDTarget::ImmediateWord(cpu.read_imm_word(pc)),
), ),
(0, 1, 1, _, _) => Self::ADD( (0, 1, 1, _, _) => Self::ADD(
// ADD HL, rp[p] // ADD HL, rp[p]
@ -1739,7 +1736,7 @@ impl Instruction {
(0, 6, _, _, _) => Self::LD( (0, 6, _, _, _) => Self::LD(
// LD r[y], n // LD r[y], n
LDTarget::Register(Table::r(y)), LDTarget::Register(Table::r(y)),
LDTarget::ImmediateByte(cpu.read_byte(pc)), LDTarget::ImmediateByte(cpu.read_imm_byte(pc)),
), ),
(0, 7, _, 0, _) => Self::RLCA, (0, 7, _, 0, _) => Self::RLCA,
(0, 7, _, 1, _) => Self::RRCA, (0, 7, _, 1, _) => Self::RRCA,
@ -1759,20 +1756,20 @@ impl Instruction {
(3, 0, _, 0..=3, _) => Self::RET(Table::cc(y)), // RET cc[y] (3, 0, _, 0..=3, _) => Self::RET(Table::cc(y)), // RET cc[y]
(3, 0, _, 4, _) => Self::LD( (3, 0, _, 4, _) => Self::LD(
// LD (0xFF00 + n), A // LD (0xFF00 + n), A
LDTarget::ByteAtAddressWithOffset(cpu.read_byte(pc)), LDTarget::ByteAtAddressWithOffset(cpu.read_imm_byte(pc)),
LDTarget::Register(InstrRegister::A), LDTarget::Register(InstrRegister::A),
), ),
(3, 0, _, 5, _) => Self::ADD( (3, 0, _, 5, _) => Self::ADD(
// ADD SP, d // ADD SP, d
MATHTarget::RegisterPair(RegisterPair::SP), MATHTarget::RegisterPair(RegisterPair::SP),
MATHTarget::ImmediateByte(cpu.read_byte(pc)), MATHTarget::ImmediateByte(cpu.read_imm_byte(pc)),
), ),
(3, 0, _, 6, _) => Self::LD( (3, 0, _, 6, _) => Self::LD(
// LD A, (0xFF00 + n) // LD A, (0xFF00 + n)
LDTarget::Register(InstrRegister::A), LDTarget::Register(InstrRegister::A),
LDTarget::ByteAtAddressWithOffset(cpu.read_byte(pc)), LDTarget::ByteAtAddressWithOffset(cpu.read_imm_byte(pc)),
), ),
(3, 0, _, 7, _) => Self::LDHL(cpu.read_byte(pc) as i8), // LD HL, SP + d (3, 0, _, 7, _) => Self::LDHL(cpu.read_imm_byte(pc) as i8), // LD HL, SP + d
(3, 1, 0, _, _) => Self::POP(Table::rp2(p)), // POP rp2[p] (3, 1, 0, _, _) => Self::POP(Table::rp2(p)), // POP rp2[p]
(3, 1, 1, _, 0) => Self::RET(JumpCondition::Always), // RET (3, 1, 1, _, 0) => Self::RET(JumpCondition::Always), // RET
(3, 1, 1, _, 1) => Self::RETI, (3, 1, 1, _, 1) => Self::RETI,
@ -1789,7 +1786,7 @@ impl Instruction {
(3, 2, _, 0..=3, _) => Self::JP( (3, 2, _, 0..=3, _) => Self::JP(
// JP cc[y], nn // JP cc[y], nn
Table::cc(y), Table::cc(y),
JPTarget::ImmediateWord(cpu.read_word(pc)), JPTarget::ImmediateWord(cpu.read_imm_word(pc)),
), ),
(3, 2, _, 4, _) => Self::LD( (3, 2, _, 4, _) => Self::LD(
// LD (0xFF00 + C) ,A // LD (0xFF00 + C) ,A
@ -1798,7 +1795,7 @@ impl Instruction {
), ),
(3, 2, _, 5, _) => Self::LD( (3, 2, _, 5, _) => Self::LD(
// LD (nn), A // LD (nn), A
LDTarget::ByteAtAddress(cpu.read_word(pc)), LDTarget::ByteAtAddress(cpu.read_imm_word(pc)),
LDTarget::Register(InstrRegister::A), LDTarget::Register(InstrRegister::A),
), ),
(3, 2, _, 6, _) => Self::LD( (3, 2, _, 6, _) => Self::LD(
@ -1809,12 +1806,12 @@ impl Instruction {
(3, 2, _, 7, _) => Self::LD( (3, 2, _, 7, _) => Self::LD(
// LD A, (nn) // LD A, (nn)
LDTarget::Register(InstrRegister::A), LDTarget::Register(InstrRegister::A),
LDTarget::ByteAtAddress(cpu.read_word(pc)), LDTarget::ByteAtAddress(cpu.read_imm_word(pc)),
), ),
(3, 3, _, 0, _) => Self::JP( (3, 3, _, 0, _) => Self::JP(
// JP nn // JP nn
JumpCondition::Always, JumpCondition::Always,
JPTarget::ImmediateWord(cpu.read_word(pc)), JPTarget::ImmediateWord(cpu.read_imm_word(pc)),
), ),
(3, 3, _, 1, _) => unreachable!("This is the 0xCB Prefix"), (3, 3, _, 1, _) => unreachable!("This is the 0xCB Prefix"),
// (3, 3, _, 2, _) => unreachable!(), ("removed" in documentation) // (3, 3, _, 2, _) => unreachable!(), ("removed" in documentation)
@ -1823,12 +1820,12 @@ impl Instruction {
// (3, 3, _, 5, _) => unreachable!(), ("removed" in documentation) // (3, 3, _, 5, _) => unreachable!(), ("removed" in documentation)
(3, 3, _, 6, _) => Self::DI, (3, 3, _, 6, _) => Self::DI,
(3, 3, _, 7, _) => Self::EI, (3, 3, _, 7, _) => Self::EI,
(3, 4, _, 0..=3, _) => Self::CALL(Table::cc(y), cpu.read_word(pc)), // CALL cc[y], nn (3, 4, _, 0..=3, _) => Self::CALL(Table::cc(y), cpu.read_imm_word(pc)), // CALL cc[y], nn
// (3, 4, _, 4..=7, _) => unreachable!(), ("removed" in documentation) // (3, 4, _, 4..=7, _) => unreachable!(), ("removed" in documentation)
(3, 5, 0, _, _) => Self::PUSH(Table::rp2(p)), // PUSH rp2[p] (3, 5, 0, _, _) => Self::PUSH(Table::rp2(p)), // PUSH rp2[p]
(3, 5, 1, _, 0) => Self::CALL(JumpCondition::Always, cpu.read_word(pc)), // CALL nn (3, 5, 1, _, 0) => Self::CALL(JumpCondition::Always, cpu.read_imm_word(pc)), // CALL nn
// (3, 5, 1, _, 1..=3) => unreachable!(), ("removed" in documentation) // (3, 5, 1, _, 1..=3) => unreachable!(), ("removed" in documentation)
(3, 6, _, _, _) => Table::x3_alu(y, cpu.read_byte(pc)), (3, 6, _, _, _) => Table::x3_alu(y, cpu.read_imm_byte(pc)),
(3, 7, _, _, _) => Self::RST(y * 8), // RST n (3, 7, _, _, _) => Self::RST(y * 8), // RST n
_ => panic!( _ => panic!(
"Unknown Opcode: {:#x?}\n x: {}, z: {}, q: {}, y: {}, p: {}", "Unknown Opcode: {:#x?}\n x: {}, z: {}, q: {}, y: {}, p: {}",
@ -1839,7 +1836,7 @@ impl Instruction {
fn from_prefixed_byte(cpu: &mut Cpu) -> Self { fn from_prefixed_byte(cpu: &mut Cpu) -> Self {
let pc = cpu.register_pair(RegisterPair::PC); let pc = cpu.register_pair(RegisterPair::PC);
let opcode = cpu.read_byte(pc); // FIXME: Should the PC be incremented here? let opcode = cpu.read_imm_byte(pc); // FIXME: Should the PC be incremented here?
// https://gb-archive.github.io/salvage/decoding_gbz80_opcodes/Decoding%20Gamboy%20Z80%20Opcodes.html // https://gb-archive.github.io/salvage/decoding_gbz80_opcodes/Decoding%20Gamboy%20Z80%20Opcodes.html
let x = (opcode >> 6) & 0b00000011; let x = (opcode >> 6) & 0b00000011;