1
0
mirror of https://github.com/mre/mos6502.git synced 2024-12-23 03:29:51 +00:00

Merge pull request #16 from typelist/jam-bmi

Implement the BMI instruction
This commit is contained in:
Johannes Muenzel 2014-10-25 17:19:09 -04:00
commit 36843cce70
3 changed files with 41 additions and 2 deletions

View File

@ -37,6 +37,8 @@ pub struct Address(pub u16);
impl Add<AddressDiff, Address> for Address { impl Add<AddressDiff, Address> for Address {
fn add(&self, &AddressDiff(rhs): &AddressDiff) -> Address { fn add(&self, &AddressDiff(rhs): &AddressDiff) -> Address {
let &Address(lhs) = self; let &Address(lhs) = self;
// TODO akeeton: Do a checked cast.
Address(((lhs as i32) + rhs) as u16) Address(((lhs as i32) + rhs) as u16)
} }
} }

View File

@ -102,6 +102,13 @@ impl Machine {
self.jump(addr) self.jump(addr)
}, },
(instruction::BMI, instruction::UseRelative(rel)) => {
let addr = self.registers.program_counter
+ AddressDiff(rel as i32);
log!(log::DEBUG, "branch if minus relative. address: {}", addr);
self.branch_if_minus(addr);
},
(instruction::LDA, instruction::UseImmediate(val)) => { (instruction::LDA, instruction::UseImmediate(val)) => {
log!(log::DEBUG, "load A immediate: {}", val); log!(log::DEBUG, "load A immediate: {}", val);
self.load_accumulator(val as i8); self.load_accumulator(val as i8);
@ -238,6 +245,12 @@ impl Machine {
pub fn jump(&mut self, addr: Address) { pub fn jump(&mut self, addr: Address) {
self.registers.program_counter = addr; self.registers.program_counter = addr;
} }
pub fn branch_if_minus(&mut self, addr: Address) {
if self.registers.status.contains(PS_NEGATIVE) {
self.registers.program_counter = addr;
}
}
} }
impl std::fmt::Show for Machine { impl std::fmt::Show for Machine {
@ -249,7 +262,6 @@ impl std::fmt::Show for Machine {
#[test] #[test]
fn add_with_carry_test() { fn add_with_carry_test() {
let mut machine = Machine::new(); let mut machine = Machine::new();
machine.add_with_carry(1); machine.add_with_carry(1);
@ -404,3 +416,26 @@ fn jump_test() {
machine.jump(addr); machine.jump(addr);
assert_eq!(machine.registers.program_counter, addr); assert_eq!(machine.registers.program_counter, addr);
} }
#[test]
fn branch_if_minus_test() {
{
let mut machine = Machine::new();
let registers_before = machine.registers;
machine.branch_if_minus(Address(0xABCD));
assert_eq!(machine.registers, registers_before);
assert_eq!(machine.registers.program_counter, Address(0));
}
{
let mut machine = Machine::new();
machine.registers.status.set_with_mask(PS_NEGATIVE, PS_NEGATIVE);
let registers_before = machine.registers;
machine.branch_if_minus(Address(0xABCD));
assert_eq!(machine.registers.status, registers_before.status);
assert_eq!(machine.registers.program_counter, Address(0xABCD));
}
}

View File

@ -54,6 +54,7 @@ impl StatusArgs {
} }
pub bitflags! { pub bitflags! {
#[deriving(Show)]
flags Status: u8 { flags Status: u8 {
const PS_NEGATIVE = 0b10000000, const PS_NEGATIVE = 0b10000000,
const PS_OVERFLOW = 0b01000000, const PS_OVERFLOW = 0b01000000,
@ -112,7 +113,7 @@ impl Status {
} }
} }
#[deriving(PartialEq, Eq, PartialOrd, Ord)] #[deriving(PartialEq, Eq, PartialOrd, Ord, Show)]
pub struct StackPointer(pub u8); pub struct StackPointer(pub u8);
impl StackPointer { impl StackPointer {
@ -122,6 +123,7 @@ impl StackPointer {
} }
} }
#[deriving(PartialEq, Eq, Show)]
pub struct Registers { pub struct Registers {
pub accumulator: i8, pub accumulator: i8,
pub index_x: i8, pub index_x: i8,