Adds ASL instruction - Still needs testing

master
Joey Pollack 2 years ago
parent 6af0fb3cb3
commit 2f64343196

@ -7,7 +7,7 @@ use super::{R6502, Bus};
pub enum ModeID
{
IMP, // Implied
ACM, // Accumulator - Not using, IMP might cover this
ACM, // Accumulator
IMM, // Immediate
ZP0, // Zero Page
ZPX, // Zero Page, X
@ -19,6 +19,7 @@ pub enum ModeID
IND, // Indirect
IZX, // Indirect, X
IZY, // Indirect, Y
ERR, // Error mode - this is an invalid mode
}
@ -38,9 +39,11 @@ pub enum ModeID
// GROUP TWO ADDRESS MODES
// 000 #immediate IMM
// 001 zero page ZP0
// 010 accumulator IMP
// 010 accumulator ACM
// 011 absolute ABS
// 100 NONE ERR
// 101 zero page,X ZPX
// 110 NONE ERR
// 111 absolute,X ABX
pub struct AddressingModes;
@ -57,18 +60,37 @@ impl AddressingModes
AddressingModes::ABX,
];
pub const GROUP_TWO_ADDRS: [fn(&mut R6502, &mut dyn Bus) -> ModeID; 8] = [
AddressingModes::IMM,
AddressingModes::ZP0,
AddressingModes::ACM,
AddressingModes::ABS,
AddressingModes::ERR,
AddressingModes::ZPX,
AddressingModes::ERR,
AddressingModes::ABX,
];
}
impl AddressingModes
{
// This is also the accumulator mode
pub fn ERR(cpu: &mut R6502, bus: &mut dyn Bus) -> ModeID
{
ModeID::ERR
}
pub fn IMP(cpu: &mut R6502, bus: &mut dyn Bus) -> ModeID
{
cpu.working_data = cpu.a as u16;
ModeID::IMP
}
pub fn ACM(cpu: &mut R6502, bus: &mut dyn Bus) -> ModeID
{
cpu.working_data = cpu.a as u16;
ModeID::ACM
}
pub fn IMM(cpu: &mut R6502, bus: &mut dyn Bus) -> ModeID
{
cpu.working_data = bus.read(cpu.pc) as u16;

@ -2,7 +2,7 @@
#![allow(dead_code, non_snake_case)]
use super::{R6502, Bus, Flags};
use super::{R6502, Bus, Flags, addressing_modes::{AddressingModes, ModeID}};
// Instruction decoding:
// https://llx.com/Neil/a2/opcodes.html
@ -22,14 +22,25 @@ pub struct Instructions;
impl Instructions
{
pub const GROUP_ONE_OPS: [fn(&mut R6502, &mut dyn Bus); 8] = [
Instructions::ORA,
Instructions::AND,
Instructions::EOR,
Instructions::ADC,
Instructions::STA,
Instructions::LDA,
Instructions::CMP,
Instructions::SBC,
Instructions::ORA,
Instructions::AND,
Instructions::EOR,
Instructions::ADC,
Instructions::STA,
Instructions::LDA,
Instructions::CMP,
Instructions::SBC,
];
pub const GROUP_TWO_OPS: [fn(&mut R6502, &mut dyn Bus); 8] = [
Instructions::ASL, // 000
Instructions::ROL, // 001
Instructions::LSR, // 010
Instructions::ROR, // 011
Instructions::STX, // 100
Instructions::LDX, // 101
Instructions::DEC, // 110
Instructions::INC, // 111
];
}
@ -213,6 +224,71 @@ impl Instructions
///////////////////////////////////////////////////////////
// GROUP TWO
pub fn ASL(cpu: &mut R6502, bus: &mut dyn Bus)
{
cpu.clear_flag(Flags::C);
if cpu.working_data as u8 & 0x80 > 0
{
cpu.set_flag(Flags::C);
}
let result = cpu.working_data << 1;
cpu.clear_flag(Flags::Z);
if result == 0
{
cpu.set_flag(Flags::Z);
}
if result as u8 & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
if cpu.addr_mode == ModeID::ACM
{
cpu.a = result as u8;
}
else
{
bus.write(cpu.working_addr, result as u8);
}
}
pub fn ROL(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
pub fn LSR(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
pub fn ROR(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
pub fn STX(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
pub fn LDX(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
pub fn DEC(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
pub fn INC(cpu: &mut R6502, bus: &mut dyn Bus)
{
}
///////////////////////////////////////////////////////////
// GROUP THREE

@ -199,6 +199,41 @@ fn exe_group_one(instruction: u8, cpu: &mut R6502, bus: &mut dyn Bus)
fn exe_group_two(instruction: u8, cpu: &mut R6502, bus: &mut dyn Bus)
{
let addr_mask = (instruction & 0x1C) >> 2;
let op_mask = (instruction & 0xE0) >> 5;
// With STX and LDX, "zero page,X" addressing becomes "zero page,Y", and with LDX, "absolute,X" becomes "absolute,Y".
const STX_ZPX: u8 = 0x96;
const LDX_ZPX: u8 = 0xB6;
const LDX_ABX: u8 = 0xBE;
match instruction
{
STX_ZPX =>
{
cpu.addr_mode = AddressingModes::ZPY(cpu, bus);
Instructions::STX(cpu, bus);
},
LDX_ZPX =>
{
cpu.addr_mode = AddressingModes::ZPY(cpu, bus);
Instructions::LDX(cpu, bus);
}
LDX_ABX =>
{
cpu.addr_mode = AddressingModes::ABY(cpu, bus);
Instructions::LDX(cpu, bus);
}
_ =>
{
cpu.addr_mode = AddressingModes::GROUP_TWO_ADDRS[addr_mask as usize](cpu, bus);
Instructions::GROUP_TWO_OPS[op_mask as usize](cpu, bus);
}
}
}

@ -2,8 +2,11 @@
#![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers, Flags};
use crate::r6502::{R6502, Bus, Registers};
/////////////////////////////////////////////////////////////////////
// GROUP ONE
/////////////////////////////////////////////////////////////////////
#[test]
fn ORA()
@ -163,4 +166,10 @@ fn STA()
mod CMP;
#[cfg(test)]
mod SBC;
mod SBC;
/////////////////////////////////////////////////////////////////////
// GROUP TWO
/////////////////////////////////////////////////////////////////////
// TODO: TEST ASL
Loading…
Cancel
Save