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

@ -2,7 +2,7 @@
#![allow(dead_code, non_snake_case)] #![allow(dead_code, non_snake_case)]
use super::{R6502, Bus, Flags}; use super::{R6502, Bus, Flags, addressing_modes::{AddressingModes, ModeID}};
// Instruction decoding: // Instruction decoding:
// https://llx.com/Neil/a2/opcodes.html // https://llx.com/Neil/a2/opcodes.html
@ -31,6 +31,17 @@ impl Instructions
Instructions::CMP, Instructions::CMP,
Instructions::SBC, 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
];
} }
impl Instructions impl Instructions
@ -213,6 +224,71 @@ impl Instructions
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// GROUP TWO // 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 // 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) 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)] #![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus; use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers, Flags}; use crate::r6502::{R6502, Bus, Registers};
/////////////////////////////////////////////////////////////////////
// GROUP ONE
/////////////////////////////////////////////////////////////////////
#[test] #[test]
fn ORA() fn ORA()
@ -164,3 +167,9 @@ mod CMP;
#[cfg(test)] #[cfg(test)]
mod SBC; mod SBC;
/////////////////////////////////////////////////////////////////////
// GROUP TWO
/////////////////////////////////////////////////////////////////////
// TODO: TEST ASL
Loading…
Cancel
Save