implemented branching operations
This commit is contained in:
+41
@@ -109,6 +109,14 @@ impl Cpu {
|
||||
0x00 => self.brk_imp(bus),
|
||||
0xEA => self.nop_imp(bus),
|
||||
0x38 => self.sec_imp(bus),
|
||||
0x90 => self.bcc_rel(bus),
|
||||
0xB0 => self.bcs_rel(bus),
|
||||
0xF0 => self.beq_rel(bus),
|
||||
0xD0 => self.bne_rel(bus),
|
||||
0x10 => self.bpl_rel(bus),
|
||||
0x30 => self.bmi_rel(bus),
|
||||
0x50 => self.bvc_rel(bus),
|
||||
0x70 => self.bvs_rel(bus),
|
||||
_ => panic!("illegal/unkown opcode {opcode:#04X} at {:#06X}", self.pc.wrapping_sub(1)),
|
||||
};
|
||||
self.cycles += cycles as u64;
|
||||
@@ -191,6 +199,21 @@ impl Cpu {
|
||||
self.pc.wrapping_add((offset as i8) as u16) // sign-extend + add, this allows to move the PC backwards
|
||||
}
|
||||
|
||||
// Branching helper for general Branch operations
|
||||
|
||||
fn branch(&mut self, bus: &mut impl Bus, condition: bool) -> u8 {
|
||||
let target: u16 = self.address_rel(bus);
|
||||
if !condition {
|
||||
return 2;
|
||||
}
|
||||
let mut cycles: u8 = 3;
|
||||
if (self.pc & 0xFF00) != (target & 0xFF00) {
|
||||
cycles += 1;
|
||||
}
|
||||
self.pc = target;
|
||||
cycles
|
||||
}
|
||||
|
||||
// NES 6502 opcode -> functions
|
||||
fn jmp_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x4C, 3 bytes, 3 cycles
|
||||
self.pc = self.fetch16(bus);
|
||||
@@ -274,6 +297,16 @@ impl Cpu {
|
||||
2
|
||||
}
|
||||
|
||||
// all branching alternatives here all 2 bytes
|
||||
fn bcs_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_CARRY)) } // 0x90
|
||||
fn bcc_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, !self.flag(FLAG_CARRY)) } // 0xB0
|
||||
fn beq_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_ZERO)) } // 0xF0
|
||||
fn bne_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, !self.flag(FLAG_ZERO)) } // 0xD0
|
||||
fn bpl_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, !self.flag(FLAG_NEGATIVE)) } // 0x10
|
||||
fn bmi_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_NEGATIVE)) } // 0x30
|
||||
fn bvc_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, !self.flag(FLAG_OVERFLOW)) } // 0x50
|
||||
fn bvs_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_OVERFLOW)) } //0x70
|
||||
|
||||
// NES 6502 opcode length table/matcher
|
||||
fn opcode_len(opcode: u8) -> u8 {
|
||||
match opcode {
|
||||
@@ -290,6 +323,14 @@ impl Cpu {
|
||||
0x00 => 1, // BRK imp
|
||||
0xEA => 1, // NOP
|
||||
0x38 => 1, // SEC imp
|
||||
0x90 => 2, // BCS rel
|
||||
0xB0 => 2, // BCC rel
|
||||
0xF0 => 2, // BEQ rel
|
||||
0xD0 => 2, // BNE rel
|
||||
0x10 => 2, // BPL rel
|
||||
0x30 => 2, // BMI rel
|
||||
0x50 => 2, // BVC rel
|
||||
0x70 => 2, // BVS rel
|
||||
_ => 1, // fallback, would show the invalid/unknown opcode only not its parameters
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user