From c0d534ed4e23fd7ffcdb6a12fd287074b96e3e0f Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Wed, 27 Dec 2023 21:21:05 -0500 Subject: [PATCH] some branch instructions --- snes-core/src/cpu/instructionstemp/bcc.rs | 12 +--- snes-core/src/cpu/instructionstemp/bcs.rs | 12 +--- snes-core/src/cpu/instructionstemp/beq.rs | 12 +--- snes-core/src/cpu/instructionstemp/bmi.rs | 59 ++++++++++++++++++ snes-core/src/cpu/instructionstemp/bne.rs | 12 +--- snes-core/src/cpu/instructionstemp/bpl.rs | 59 ++++++++++++++++++ snes-core/src/cpu/instructionstemp/bra.rs | 55 +++++++++++++++++ .../src/cpu/instructionstemp/branch_common.rs | 14 ++++- snes-core/src/cpu/instructionstemp/brk.rs | 39 ++++++++++++ snes-core/src/cpu/instructionstemp/brl.rs | 61 +++++++++++++++++++ snes-core/src/cpu/instructionstemp/bvc.rs | 59 ++++++++++++++++++ snes-core/src/cpu/instructionstemp/bvs.rs | 59 ++++++++++++++++++ .../cpu/instructionstemp/decoder_common.rs | 4 ++ snes-core/src/cpu/instructionstemp/mod.rs | 8 +++ .../src/cpu/instructionstemp/push_common.rs | 9 +++ 15 files changed, 433 insertions(+), 41 deletions(-) create mode 100644 snes-core/src/cpu/instructionstemp/bmi.rs create mode 100644 snes-core/src/cpu/instructionstemp/bpl.rs create mode 100644 snes-core/src/cpu/instructionstemp/bra.rs create mode 100644 snes-core/src/cpu/instructionstemp/brk.rs create mode 100644 snes-core/src/cpu/instructionstemp/brl.rs create mode 100644 snes-core/src/cpu/instructionstemp/bvc.rs create mode 100644 snes-core/src/cpu/instructionstemp/bvs.rs create mode 100644 snes-core/src/cpu/instructionstemp/push_common.rs diff --git a/snes-core/src/cpu/instructionstemp/bcc.rs b/snes-core/src/cpu/instructionstemp/bcc.rs index cbbb147..a14ea66 100644 --- a/snes-core/src/cpu/instructionstemp/bcc.rs +++ b/snes-core/src/cpu/instructionstemp/bcc.rs @@ -1,6 +1,5 @@ use crate::cpu::{bus::Bus, registers::Registers}; -use crate::cpu::cycles; use super::{CPUInstruction, Decode}; use super::decoder_common; use super::branch_common; @@ -11,14 +10,7 @@ pub struct BCC {} impl CPUInstruction for BCC { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { - let nearlabel = bus.read(registers.get_pc_address().wrapping_add(1)); - let (bytes, cycles) = cycles::increment_cycles_branch(); - registers.increment_pc(bytes); registers.cycles += cycles; - if !registers.get_carry_flag() { - let page_boundary_crossed = branch_common::do_branch(nearlabel, registers); - let (bytes, cycles) = cycles::increment_cycles_branch_taken(page_boundary_crossed); - registers.increment_pc(bytes); registers.cycles += cycles; - } + branch_common::do_branch_instr(registers, bus, !registers.get_carry_flag()); } } @@ -34,7 +26,7 @@ mod cpu_instructions_tests { use super::*; #[test] - fn test_bcc() { + fn test() { let instruction = BCC{}; // test with positive nearlabel // branch not taken diff --git a/snes-core/src/cpu/instructionstemp/bcs.rs b/snes-core/src/cpu/instructionstemp/bcs.rs index a92458c..0524869 100644 --- a/snes-core/src/cpu/instructionstemp/bcs.rs +++ b/snes-core/src/cpu/instructionstemp/bcs.rs @@ -1,6 +1,5 @@ use crate::cpu::{bus::Bus, registers::Registers}; -use crate::cpu::cycles; use super::{CPUInstruction, Decode}; use super::decoder_common; use super::branch_common; @@ -11,14 +10,7 @@ pub struct BCS {} impl CPUInstruction for BCS { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { - let nearlabel = bus.read(registers.get_pc_address().wrapping_add(1)); - let (bytes, cycles) = cycles::increment_cycles_branch(); - registers.increment_pc(bytes); registers.cycles += cycles; - if registers.get_carry_flag() { - let page_boundary_crossed = branch_common::do_branch(nearlabel, registers); - let (bytes, cycles) = cycles::increment_cycles_branch_taken(page_boundary_crossed); - registers.increment_pc(bytes); registers.cycles += cycles; - } + branch_common::do_branch_instr(registers, bus, registers.get_carry_flag()); } } @@ -34,7 +26,7 @@ mod cpu_instructions_tests { use super::*; #[test] - fn test_bcs() { + fn test() { let instruction = BCS{}; // test with positive nearlabel // branch not taken diff --git a/snes-core/src/cpu/instructionstemp/beq.rs b/snes-core/src/cpu/instructionstemp/beq.rs index 884b69a..d79e519 100644 --- a/snes-core/src/cpu/instructionstemp/beq.rs +++ b/snes-core/src/cpu/instructionstemp/beq.rs @@ -1,6 +1,5 @@ use crate::cpu::{bus::Bus, registers::Registers}; -use crate::cpu::cycles; use super::{CPUInstruction, Decode}; use super::decoder_common; use super::branch_common; @@ -11,14 +10,7 @@ pub struct BEQ {} impl CPUInstruction for BEQ { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { - let nearlabel = bus.read(registers.get_pc_address().wrapping_add(1)); - let (bytes, cycles) = cycles::increment_cycles_branch(); - registers.increment_pc(bytes); registers.cycles += cycles; - if registers.get_zero_flag() { - let page_boundary_crossed = branch_common::do_branch(nearlabel, registers); - let (bytes, cycles) = cycles::increment_cycles_branch_taken(page_boundary_crossed); - registers.increment_pc(bytes); registers.cycles += cycles; - } + branch_common::do_branch_instr(registers, bus, registers.get_zero_flag()); } } @@ -34,7 +26,7 @@ mod cpu_instructions_tests { use super::*; #[test] - fn test_beq() { + fn test() { let instruction = BEQ{}; // test with positive nearlabel // branch not taken diff --git a/snes-core/src/cpu/instructionstemp/bmi.rs b/snes-core/src/cpu/instructionstemp/bmi.rs new file mode 100644 index 0000000..ded22c8 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/bmi.rs @@ -0,0 +1,59 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use super::branch_common; + +static INSTR_NAME: &'static str = "BMI"; + +pub struct BMI {} + +impl CPUInstruction for BMI { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + branch_common::do_branch_instr(registers, bus, registers.get_negative_flag()); + } +} + +impl Decode for BMI { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_branch_nearlabel(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let instruction = BMI{}; + // test with positive nearlabel + // branch not taken + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_negative_flag(false); + bus.write(0x02, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02); + assert_eq!(registers.cycles, 2); + // branch taken + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_negative_flag(true); + bus.write(0x01, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02 + 0b00001111); + assert_eq!(registers.cycles, 3); + // test with negative nearlabel and boundary cross + registers.pc = 0x0100; + registers.cycles = 0; + registers.set_negative_flag(true); + bus.write(0x101, 0xFB); // write -5 + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0xFD); + assert_eq!(registers.cycles, 4); + } +} diff --git a/snes-core/src/cpu/instructionstemp/bne.rs b/snes-core/src/cpu/instructionstemp/bne.rs index ad630ac..c4f83a1 100644 --- a/snes-core/src/cpu/instructionstemp/bne.rs +++ b/snes-core/src/cpu/instructionstemp/bne.rs @@ -1,6 +1,5 @@ use crate::cpu::{bus::Bus, registers::Registers}; -use crate::cpu::cycles; use super::{CPUInstruction, Decode}; use super::decoder_common; use super::branch_common; @@ -11,14 +10,7 @@ pub struct BNE {} impl CPUInstruction for BNE { fn execute(&self, registers: &mut Registers, bus: &mut Bus) { - let nearlabel = bus.read(registers.get_pc_address().wrapping_add(1)); - let (bytes, cycles) = cycles::increment_cycles_branch(); - registers.increment_pc(bytes); registers.cycles += cycles; - if !registers.get_zero_flag() { - let page_boundary_crossed = branch_common::do_branch(nearlabel, registers); - let (bytes, cycles) = cycles::increment_cycles_branch_taken(page_boundary_crossed); - registers.increment_pc(bytes); registers.cycles += cycles; - } + branch_common::do_branch_instr(registers, bus, !registers.get_zero_flag()); } } @@ -34,7 +26,7 @@ mod cpu_instructions_tests { use super::*; #[test] - fn test_beq() { + fn test() { let instruction = BNE{}; // test with positive nearlabel // branch not taken diff --git a/snes-core/src/cpu/instructionstemp/bpl.rs b/snes-core/src/cpu/instructionstemp/bpl.rs new file mode 100644 index 0000000..dd8288e --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/bpl.rs @@ -0,0 +1,59 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use super::branch_common; + +static INSTR_NAME: &'static str = "BPL"; + +pub struct BPL {} + +impl CPUInstruction for BPL { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + branch_common::do_branch_instr(registers, bus, !registers.get_negative_flag()); + } +} + +impl Decode for BPL { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_branch_nearlabel(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let instruction = BPL{}; + // test with positive nearlabel + // branch not taken + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_negative_flag(true); + bus.write(0x02, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02); + assert_eq!(registers.cycles, 2); + // branch taken + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_negative_flag(false); + bus.write(0x01, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02 + 0b00001111); + assert_eq!(registers.cycles, 3); + // test with negative nearlabel and boundary cross + registers.pc = 0x0100; + registers.cycles = 0; + registers.set_negative_flag(false); + bus.write(0x101, 0xFB); // write -5 + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0xFD); + assert_eq!(registers.cycles, 4); + } +} diff --git a/snes-core/src/cpu/instructionstemp/bra.rs b/snes-core/src/cpu/instructionstemp/bra.rs new file mode 100644 index 0000000..80226a6 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/bra.rs @@ -0,0 +1,55 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use super::branch_common; +use crate::cpu::cycles; + +static INSTR_NAME: &'static str = "BRA"; + +pub struct BRA {} + +impl CPUInstruction for BRA { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + let nearlabel = bus.read(registers.get_pc_address().wrapping_add(1)); + let (bytes, cycles) = cycles::increment_cycles_branch(); + registers.increment_pc(bytes); registers.cycles += cycles; + let page_boundary_crossed = branch_common::do_branch(nearlabel, registers); + let (bytes, cycles) = cycles::increment_cycles_branch_taken(page_boundary_crossed); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for BRA { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_branch_nearlabel(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let instruction = BRA{}; + // test with positive nearlabel + // branch always taken + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + registers.cycles = 0; + bus.write(0x01, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02 + 0b00001111); + assert_eq!(registers.cycles, 3); + // test with negative nearlabel and boundary cross + registers.pc = 0x0100; + registers.cycles = 0; + bus.write(0x101, 0xFB); // write -5 + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0xFD); + assert_eq!(registers.cycles, 4); + } +} diff --git a/snes-core/src/cpu/instructionstemp/branch_common.rs b/snes-core/src/cpu/instructionstemp/branch_common.rs index 1e8a6b7..f46cba9 100644 --- a/snes-core/src/cpu/instructionstemp/branch_common.rs +++ b/snes-core/src/cpu/instructionstemp/branch_common.rs @@ -1,4 +1,16 @@ -use crate::cpu::registers::Registers; +use crate::cpu::{registers::Registers, bus::Bus}; +use crate::cpu::cycles; + +pub fn do_branch_instr(registers: &mut Registers, bus: &mut Bus, condition: bool) { + let nearlabel = bus.read(registers.get_pc_address().wrapping_add(1)); + let (bytes, cycles) = cycles::increment_cycles_branch(); + registers.increment_pc(bytes); registers.cycles += cycles; + if condition { + let page_boundary_crossed = do_branch(nearlabel, registers); + let (bytes, cycles) = cycles::increment_cycles_branch_taken(page_boundary_crossed); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} pub fn do_branch(nearlabel: u8, registers: &mut Registers) -> bool { let is_negative = (nearlabel >> 7) != 0; diff --git a/snes-core/src/cpu/instructionstemp/brk.rs b/snes-core/src/cpu/instructionstemp/brk.rs new file mode 100644 index 0000000..1db5240 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/brk.rs @@ -0,0 +1,39 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use super::branch_common; +use super::push_common; +use crate::cpu::cycles; + +static INSTR_NAME: &'static str = "BRK"; + +pub struct BRK {} + +impl CPUInstruction for BRK { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + push_common::do_push(registers, bus, &[registers.pbr]); + push_common::do_push(registers, bus, &[(registers.pc >> 8) as u8, registers.pc as u8]); + push_common::do_push(registers, bus, &[registers.p]); + registers.set_decimal_mode_flag(false); + registers.set_irq_disable_flag(true); + let (bytes, cycles) = cycles::increment_cycles_brk(registers.emulation_mode); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for BRK { + fn mnemonic(&self, _registers: &Registers, _bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_single_byte_instr(opcode, INSTR_NAME) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + } +} diff --git a/snes-core/src/cpu/instructionstemp/brl.rs b/snes-core/src/cpu/instructionstemp/brl.rs new file mode 100644 index 0000000..669e18c --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/brl.rs @@ -0,0 +1,61 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use crate::cpu::cycles; + +static INSTR_NAME: &'static str = "BRL"; + +pub struct BRL {} + +impl CPUInstruction for BRL { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + let label = bus.read(registers.get_pc_address()) as u16 | + ((bus.read(registers.get_pc_address() + 1) as u16) << 8); + let is_negative = (label >> 15) != 0; + if is_negative { + let label = !label + 1; + registers.decrement_pc(label); + } else { + registers.increment_pc(label); + } + let (bytes, cycles) = cycles::increment_cycles_branch_long(); + registers.increment_pc(bytes); registers.cycles += cycles; + } +} + +impl Decode for BRL { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_absolute(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let instruction = BRL{}; + // test with positive nearlabel + // branch always taken + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0001; + registers.cycles = 0; + bus.write(0x01, 0b00000000); + bus.write(0x02, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x04 + 0b00001111_00000000); + assert_eq!(registers.cycles, 4); + // test with negative nearlabel and boundary cross + registers.pc = 0x00FD; + registers.cycles = 0; + bus.write(0xFD, 0xFF); // write -1 + bus.write(0xFE, 0xFF); // write -1 + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0xFF); + assert_eq!(registers.cycles, 4); + } +} diff --git a/snes-core/src/cpu/instructionstemp/bvc.rs b/snes-core/src/cpu/instructionstemp/bvc.rs new file mode 100644 index 0000000..401d262 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/bvc.rs @@ -0,0 +1,59 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use super::branch_common; + +static INSTR_NAME: &'static str = "BVC"; + +pub struct BVC {} + +impl CPUInstruction for BVC { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + branch_common::do_branch_instr(registers, bus, !registers.get_overflow_flag()); + } +} + +impl Decode for BVC { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_branch_nearlabel(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let instruction = BVC{}; + // test with positive nearlabel + // branch not taken + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_overflow_flag(true); + bus.write(0x02, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02); + assert_eq!(registers.cycles, 2); + // branch taken + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_overflow_flag(false); + bus.write(0x01, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02 + 0b00001111); + assert_eq!(registers.cycles, 3); + // test with negative nearlabel and boundary cross + registers.pc = 0x0100; + registers.cycles = 0; + registers.set_overflow_flag(false); + bus.write(0x101, 0xFB); // write -5 + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0xFD); + assert_eq!(registers.cycles, 4); + } +} diff --git a/snes-core/src/cpu/instructionstemp/bvs.rs b/snes-core/src/cpu/instructionstemp/bvs.rs new file mode 100644 index 0000000..d116cb9 --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/bvs.rs @@ -0,0 +1,59 @@ +use crate::cpu::{bus::Bus, registers::Registers}; + +use super::{CPUInstruction, Decode}; +use super::decoder_common; +use super::branch_common; + +static INSTR_NAME: &'static str = "BVS"; + +pub struct BVS {} + +impl CPUInstruction for BVS { + fn execute(&self, registers: &mut Registers, bus: &mut Bus) { + branch_common::do_branch_instr(registers, bus, registers.get_overflow_flag()); + } +} + +impl Decode for BVS { + fn mnemonic(&self, registers: &Registers, bus: &Bus, opcode: u8) -> String { + decoder_common::mnemonic_branch_nearlabel(opcode, INSTR_NAME, registers, bus) + } +} + + +#[cfg(test)] +mod cpu_instructions_tests { + use super::*; + + #[test] + fn test() { + let instruction = BVS{}; + // test with positive nearlabel + // branch not taken + let mut registers = Registers::new(); + let mut bus = Bus::new(); + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_overflow_flag(false); + bus.write(0x02, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02); + assert_eq!(registers.cycles, 2); + // branch taken + registers.pc = 0x0000; + registers.cycles = 0; + registers.set_overflow_flag(true); + bus.write(0x01, 0b00001111); + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0x02 + 0b00001111); + assert_eq!(registers.cycles, 3); + // test with negative nearlabel and boundary cross + registers.pc = 0x0100; + registers.cycles = 0; + registers.set_overflow_flag(true); + bus.write(0x101, 0xFB); // write -5 + instruction.execute(&mut registers, &mut bus); + assert_eq!(registers.pc, 0xFD); + assert_eq!(registers.cycles, 4); + } +} diff --git a/snes-core/src/cpu/instructionstemp/decoder_common.rs b/snes-core/src/cpu/instructionstemp/decoder_common.rs index ec3a2a4..5038139 100644 --- a/snes-core/src/cpu/instructionstemp/decoder_common.rs +++ b/snes-core/src/cpu/instructionstemp/decoder_common.rs @@ -116,3 +116,7 @@ pub fn mnemonic_branch_nearlabel(opcode: u8, instr_name: &str, registers: &Regis let nearlabel = bus.read_external(registers.get_pc_address() + 1); format!("{:02X} {:02X} __ __ | {} ${:02X}", opcode, nearlabel, instr_name, nearlabel) } + +pub fn mnemonic_single_byte_instr(opcode: u8, instr_name: &str) -> String { + format!("{:02X} __ __ __ | {}", opcode, instr_name) +} diff --git a/snes-core/src/cpu/instructionstemp/mod.rs b/snes-core/src/cpu/instructionstemp/mod.rs index c3d36a6..49224c6 100644 --- a/snes-core/src/cpu/instructionstemp/mod.rs +++ b/snes-core/src/cpu/instructionstemp/mod.rs @@ -9,8 +9,16 @@ pub mod bcc; pub mod bcs; pub mod beq; pub mod bne; +pub mod bmi; +pub mod bpl; +pub mod bra; +pub mod brk; +pub mod brl; +pub mod bvc; +pub mod bvs; pub mod decoder_common; pub mod branch_common; +pub mod push_common; pub trait CPUInstruction { fn execute(&self, registers: &mut Registers, bus: &mut Bus); diff --git a/snes-core/src/cpu/instructionstemp/push_common.rs b/snes-core/src/cpu/instructionstemp/push_common.rs new file mode 100644 index 0000000..62c648c --- /dev/null +++ b/snes-core/src/cpu/instructionstemp/push_common.rs @@ -0,0 +1,9 @@ +use crate::cpu::{registers::Registers, bus::Bus}; + +pub fn do_push(registers: &mut Registers, bus: &mut Bus, bytes: &[u8]) { + for byte in bytes { + let address = registers.sp as u32; + bus.write(address, *byte); + registers.decrement_sp(1); + } +}