add more instructions
This commit is contained in:
parent
48b76193d2
commit
b8d5b8f029
14
src/cpu.rs
14
src/cpu.rs
|
@ -60,22 +60,31 @@ impl CPU
|
||||||
const UNDEF_INSTR: Option<Instruction> = None;
|
const UNDEF_INSTR: Option<Instruction> = None;
|
||||||
let mut instr_set = [UNDEF_INSTR; 256];
|
let mut instr_set = [UNDEF_INSTR; 256];
|
||||||
|
|
||||||
|
instr_set[0x08] = instr!(php, imp, 3, 1);
|
||||||
|
instr_set[0x09] = instr!(ora, imm, 2, 2);
|
||||||
|
|
||||||
instr_set[0x10] = instr!(bpl, rel, 2, 2);
|
instr_set[0x10] = instr!(bpl, rel, 2, 2);
|
||||||
instr_set[0x18] = instr!(clc, imp, 2, 1);
|
instr_set[0x18] = instr!(clc, imp, 2, 1);
|
||||||
|
|
||||||
instr_set[0x20] = instr!(jsr, abs, 6, 3);
|
instr_set[0x20] = instr!(jsr, abs, 6, 3);
|
||||||
instr_set[0x24] = instr!(bit, zpg, 3, 2);
|
instr_set[0x24] = instr!(bit, zpg, 3, 2);
|
||||||
|
instr_set[0x28] = instr!(plp, imp, 4, 1);
|
||||||
|
instr_set[0x29] = instr!(and, imm, 2, 2);
|
||||||
|
|
||||||
instr_set[0x30] = instr!(bmi, rel, 2, 2);
|
instr_set[0x30] = instr!(bmi, rel, 2, 2);
|
||||||
instr_set[0x38] = instr!(sec, imp, 2, 1);
|
instr_set[0x38] = instr!(sec, imp, 2, 1);
|
||||||
|
|
||||||
|
instr_set[0x48] = instr!(pha, imp, 3, 1);
|
||||||
|
instr_set[0x49] = instr!(eor, imm, 2, 2);
|
||||||
instr_set[0x4C] = instr!(jmp, abs, 3, 3);
|
instr_set[0x4C] = instr!(jmp, abs, 3, 3);
|
||||||
|
|
||||||
instr_set[0x50] = instr!(bvc, rel, 2, 2);
|
instr_set[0x50] = instr!(bvc, rel, 2, 2);
|
||||||
|
|
||||||
instr_set[0x60] = instr!(rts, imp, 6, 1);
|
instr_set[0x60] = instr!(rts, imp, 6, 1);
|
||||||
|
instr_set[0x68] = instr!(pla, imp, 4, 1);
|
||||||
|
|
||||||
instr_set[0x70] = instr!(bvs, rel, 2, 2);
|
instr_set[0x70] = instr!(bvs, rel, 2, 2);
|
||||||
|
instr_set[0x78] = instr!(sei, imp, 2, 1);
|
||||||
|
|
||||||
instr_set[0x85] = instr!(sta, zpg, 3, 2);
|
instr_set[0x85] = instr!(sta, zpg, 3, 2);
|
||||||
instr_set[0x86] = instr!(stx, zpg, 3, 2);
|
instr_set[0x86] = instr!(stx, zpg, 3, 2);
|
||||||
|
@ -86,12 +95,17 @@ impl CPU
|
||||||
instr_set[0xA9] = instr!(lda, imm, 2, 2);
|
instr_set[0xA9] = instr!(lda, imm, 2, 2);
|
||||||
|
|
||||||
instr_set[0xB0] = instr!(bcs, rel, 2, 2);
|
instr_set[0xB0] = instr!(bcs, rel, 2, 2);
|
||||||
|
instr_set[0xB8] = instr!(clv, imp, 2, 1);
|
||||||
|
|
||||||
|
instr_set[0xC9] = instr!(cmp, imm, 2, 2);
|
||||||
|
|
||||||
instr_set[0xD0] = instr!(bne, rel, 2, 2);
|
instr_set[0xD0] = instr!(bne, rel, 2, 2);
|
||||||
|
instr_set[0xD8] = instr!(cld, imp, 2, 1);
|
||||||
|
|
||||||
instr_set[0xEA] = instr!(nop, imp, 2, 1);
|
instr_set[0xEA] = instr!(nop, imp, 2, 1);
|
||||||
|
|
||||||
instr_set[0xF0] = instr!(beq, rel, 2, 2);
|
instr_set[0xF0] = instr!(beq, rel, 2, 2);
|
||||||
|
instr_set[0xF8] = instr!(sed, imp, 2, 1);
|
||||||
|
|
||||||
CPU {
|
CPU {
|
||||||
cycle: 0,
|
cycle: 0,
|
||||||
|
|
|
@ -7,6 +7,7 @@ enum Bit
|
||||||
{
|
{
|
||||||
Negative = 7,
|
Negative = 7,
|
||||||
Overflow = 6,
|
Overflow = 6,
|
||||||
|
Break = 4,
|
||||||
Decimal = 3,
|
Decimal = 3,
|
||||||
Interrupt = 2,
|
Interrupt = 2,
|
||||||
Zero = 1,
|
Zero = 1,
|
||||||
|
@ -131,6 +132,22 @@ macro_rules! store_fn
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! cmp_fn
|
||||||
|
{
|
||||||
|
($name: ident, $register: ident) =>
|
||||||
|
{
|
||||||
|
pub fn $name(&mut self)
|
||||||
|
{
|
||||||
|
let value = self.fetch();
|
||||||
|
let result = self.$register.wrapping_sub(value);
|
||||||
|
|
||||||
|
set_flag_to!(self.p, Bit::Zero, self.$register == value);
|
||||||
|
set_flag_to!(self.p, Bit::Carry, self.$register >= value);
|
||||||
|
set_flag_to!(self.p, Bit::Negative, (value >> 7) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CPU
|
impl CPU
|
||||||
{
|
{
|
||||||
fn fetch(&mut self) -> u8
|
fn fetch(&mut self) -> u8
|
||||||
|
@ -150,6 +167,11 @@ impl CPU
|
||||||
|
|
||||||
set_flag_fn!(clc, Bit::Carry, false);
|
set_flag_fn!(clc, Bit::Carry, false);
|
||||||
set_flag_fn!(sec, Bit::Carry, true);
|
set_flag_fn!(sec, Bit::Carry, true);
|
||||||
|
set_flag_fn!(sei, Bit::Interrupt, true);
|
||||||
|
set_flag_fn!(cli, Bit::Interrupt, false);
|
||||||
|
set_flag_fn!(sed, Bit::Decimal, true);
|
||||||
|
set_flag_fn!(cld, Bit::Decimal, false);
|
||||||
|
set_flag_fn!(clv, Bit::Overflow, false);
|
||||||
|
|
||||||
load_fn!(lda, acc);
|
load_fn!(lda, acc);
|
||||||
load_fn!(ldx, x);
|
load_fn!(ldx, x);
|
||||||
|
@ -159,6 +181,19 @@ impl CPU
|
||||||
store_fn!(stx, x);
|
store_fn!(stx, x);
|
||||||
store_fn!(sty, y);
|
store_fn!(sty, y);
|
||||||
|
|
||||||
|
cmp_fn!(cmp, acc);
|
||||||
|
cmp_fn!(cpx, x);
|
||||||
|
cmp_fn!(cpy, y);
|
||||||
|
|
||||||
|
pub fn and(&mut self)
|
||||||
|
{
|
||||||
|
let val = self.fetch();
|
||||||
|
|
||||||
|
self.acc &= val;
|
||||||
|
set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0);
|
||||||
|
set_flag_to!(self.p, Bit::Zero, self.acc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bit(&mut self)
|
pub fn bit(&mut self)
|
||||||
{
|
{
|
||||||
let bus = self.bus.upgrade().unwrap();
|
let bus = self.bus.upgrade().unwrap();
|
||||||
|
@ -169,6 +204,15 @@ impl CPU
|
||||||
set_flag_to!(self.p, Bit::Zero, (self.acc & value) == 0);
|
set_flag_to!(self.p, Bit::Zero, (self.acc & value) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eor(&mut self)
|
||||||
|
{
|
||||||
|
let val = self.fetch();
|
||||||
|
|
||||||
|
self.acc ^= val;
|
||||||
|
set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0);
|
||||||
|
set_flag_to!(self.p, Bit::Zero, self.acc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn jmp(&mut self)
|
pub fn jmp(&mut self)
|
||||||
{
|
{
|
||||||
self.pc = self.absolute_addr;
|
self.pc = self.absolute_addr;
|
||||||
|
@ -190,6 +234,54 @@ impl CPU
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ora(&mut self)
|
||||||
|
{
|
||||||
|
let val = self.fetch();
|
||||||
|
|
||||||
|
self.acc |= val;
|
||||||
|
set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0);
|
||||||
|
set_flag_to!(self.p, Bit::Zero, self.acc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pha(&mut self)
|
||||||
|
{
|
||||||
|
let bus = self.bus.upgrade().unwrap();
|
||||||
|
|
||||||
|
push!(bus.borrow_mut(), self.sp, self.acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pla(&mut self)
|
||||||
|
{
|
||||||
|
let bus = self.bus.upgrade().unwrap();
|
||||||
|
|
||||||
|
self.acc = pop(bus.borrow(), &mut self.sp);
|
||||||
|
set_flag_to!(self.p, Bit::Negative, (self.acc & (1u8 << 7)) > 0);
|
||||||
|
set_flag_to!(self.p, Bit::Zero, self.acc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn php(&mut self)
|
||||||
|
{
|
||||||
|
let bus = self.bus.upgrade().unwrap();
|
||||||
|
|
||||||
|
let mut value = self.p;
|
||||||
|
set_flag!(value, Bit::Break);
|
||||||
|
set_flag!(value, 5);
|
||||||
|
|
||||||
|
push!(bus.borrow_mut(), self.sp, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn plp(&mut self)
|
||||||
|
{
|
||||||
|
let bus = self.bus.upgrade().unwrap();
|
||||||
|
|
||||||
|
let flag: u8 = pop(bus.borrow(), &mut self.sp);
|
||||||
|
let mask: u8 = 0b1100111;
|
||||||
|
|
||||||
|
self.p &= !mask;
|
||||||
|
self.p |= flag & mask;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rts(&mut self)
|
pub fn rts(&mut self)
|
||||||
{
|
{
|
||||||
let bus = self.bus.upgrade().unwrap();
|
let bus = self.bus.upgrade().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue