Skip to content

Commit

Permalink
Implement BCC instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
lyrakisk committed Apr 1, 2024
1 parent a885a22 commit 2f212b5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
- [X] ADC
- [X] AND
- [X] ASL
- [ ] BCC
- [X] BCC
- [ ] BCS
- [ ] BEQ
- [ ] BIT
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::collections::HashMap;
pub enum AddressingMode {
Implicit,
Accumulator,
Relative,
Immediate,
ZeroPage,
ZeroPage_X,
Expand Down Expand Up @@ -62,6 +63,7 @@ pub static INSTRUCTIONS: Lazy<HashMap<u8, Instruction>> = Lazy::new(|| {
Instruction {opcode: 0x16, name: "ASL", bytes: 2, addressing_mode: AddressingMode::ZeroPage_X},
Instruction {opcode: 0x0E, name: "ASL", bytes: 3, addressing_mode: AddressingMode::Absolute},
Instruction {opcode: 0x1E, name: "ASL", bytes: 3, addressing_mode: AddressingMode::Absolute_X},
Instruction {opcode: 0x90, name: "BCC", bytes: 2, addressing_mode: AddressingMode::Relative},
Instruction {opcode: 0x00, name: "BRK", bytes: 1, addressing_mode: AddressingMode::Implicit},
Instruction {opcode: 0xA9, name: "LDA", bytes: 2, addressing_mode: AddressingMode::Immediate},
Instruction {opcode: 0xA5, name: "LDA", bytes: 2, addressing_mode: AddressingMode::ZeroPage},
Expand Down
41 changes: 34 additions & 7 deletions src/cpu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod instructions;

use std::ops::{Add, Shl};
use std::ops::{Add, Shl, Sub};

use crate::cpu::instructions::*;

Expand Down Expand Up @@ -127,6 +127,10 @@ impl CPU {
self.status = self.status & 0b1111_1110;
}

fn carry_flag_is_clear(&self) -> bool {
return self.status & 0b0000_0001 == 0;
}

fn set_overflow_flag(&mut self) {
self.status = self.status | 0b0100_0000;
}
Expand All @@ -141,12 +145,6 @@ impl CPU {

fn get_operand_address(&mut self, addressing_mode: &AddressingMode) -> u16 {
match addressing_mode {
AddressingMode::Implicit => {
panic!("Cannot get operand address when the Addressing Mode is Implicit");
}
AddressingMode::Accumulator => {
panic!("Cannot get operand address when the Addressing Mode is Accumulator");
}
AddressingMode::Immediate => self.program_counter,
AddressingMode::ZeroPage => self.mem_read(self.program_counter) as u16,
AddressingMode::ZeroPage_X => self
Expand Down Expand Up @@ -188,6 +186,12 @@ impl CPU {
self.mem_read_u16(indirect_address)
.wrapping_add(self.register_y as u16)
}
_ => {
panic!(
"Cannot get operand address when the Addressing Mode is {:?}",
addressing_mode
);
}
}
}

Expand Down Expand Up @@ -250,6 +254,17 @@ impl CPU {
}
}

fn bcc(&mut self) {
if self.carry_flag_is_clear() {
if self.mem_read(self.program_counter) > 0x7F {
let distance = 0xFF - self.mem_read(self.program_counter) + 1;
self.program_counter -= distance as u16;
} else {
self.program_counter += self.mem_read(self.program_counter) as u16 - 1;
}
}
}

fn lda(&mut self, addressing_mode: &AddressingMode) {
let operand = self.get_operand(addressing_mode);
self.register_a = operand;
Expand Down Expand Up @@ -471,6 +486,18 @@ mod test_cpu {
assert_eq!(cpu.status, expected_status);
}

#[test_case(0b0000_0001, 0x8080, 0x8080, 0x06)]
#[test_case(0b0000_0000, 0xE004, 0xE009, 0x06)]
#[test_case(0b0000_0000, 0xE009, 0xE003, 0xFA)]
fn test_bcc(status: u8, program_counter: u16, expected_program_counter: u16, distance: u8) {
let mut cpu = CPU::new();
cpu.status = status;
cpu.program_counter = program_counter;
cpu.memory[cpu.program_counter as usize] = distance;
cpu.bcc();
assert_eq!(cpu.program_counter, expected_program_counter);
}

#[test_case(0b0000_0001, 0x5, 0x4, 0x1, 0b0000_0001)]
#[test_case(0b0000_0001, 0x5, 0x5, 0x0, 0b0000_0011)]
#[test_case(0b0000_0001, 0x0, 0x1, 0xFF, 0b1000_0000)]
Expand Down

0 comments on commit 2f212b5

Please sign in to comment.