1304 lines
36 KiB
Rust
1304 lines
36 KiB
Rust
use crate::address_mode::AddressMode;
|
|
use crate::address_mode::AddressMode::*;
|
|
use crate::address_mode::AddressMode::*;
|
|
use crate::instruction_table::INSTRUCTION_TABLE;
|
|
use crate::op_info::OpInfo;
|
|
use crate::operand::Operand;
|
|
use crate::operation::Operation;
|
|
use crate::operation::Operation::*;
|
|
use log::trace;
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub struct Instruction {
|
|
pub op: Operation,
|
|
pub mode: AddressMode,
|
|
pub operand: Operand,
|
|
}
|
|
|
|
impl Instruction {
|
|
pub fn opinfo(bytes: &[u8]) -> Option<OpInfo> {
|
|
trace!("DECODING : {bytes:?}");
|
|
let opcode = bytes.get(0).copied()?;
|
|
Some(INSTRUCTION_TABLE[opcode as usize].clone())?
|
|
}
|
|
|
|
pub fn decode(bytes: &[u8]) -> Option<Instruction> {
|
|
let info = Instruction::opinfo(bytes)?;
|
|
|
|
let operand = match info.length {
|
|
2 => Operand::Byte(*bytes.get(1)?),
|
|
3 => Operand::Word(u16::from_le_bytes([*bytes.get(1)?, *bytes.get(2)?])),
|
|
_ => Operand::None,
|
|
};
|
|
|
|
let instruction = Instruction {
|
|
op: info.operation,
|
|
mode: info.mode,
|
|
operand,
|
|
};
|
|
|
|
trace!("RETURNING: {:?}", instruction);
|
|
Some(instruction)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
use crate::address_mode::AddressMode::*;
|
|
use crate::instruction::Instruction;
|
|
use crate::operation::Operation::*;
|
|
|
|
#[test]
|
|
fn decode_instruction() {
|
|
let params = vec![
|
|
// ADC
|
|
(
|
|
vec![0x69, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x65, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x75, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x6d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x7d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x79, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x61, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x71, 0xab],
|
|
Instruction {
|
|
op: ADC,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// AND
|
|
(
|
|
vec![0x29, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x25, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x35, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x2d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x3d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x39, 0xcd, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x21, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x31, 0xab],
|
|
Instruction {
|
|
op: AND,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// ASL
|
|
(
|
|
vec![0x0a],
|
|
Instruction {
|
|
op: ASL,
|
|
mode: Accumulator,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x06, 0xab],
|
|
Instruction {
|
|
op: ASL,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x16, 0xab],
|
|
Instruction {
|
|
op: ASL,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x0e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ASL,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x1e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ASL,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// BIT
|
|
(
|
|
vec![0x24, 0xab],
|
|
Instruction {
|
|
op: BIT,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x2c, 0xcd, 0xab],
|
|
Instruction {
|
|
op: BIT,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// BCC, BCS, BEQ, BMI, BNE, BPL, BVC, BVS
|
|
(
|
|
vec![0x10, 0xab],
|
|
Instruction {
|
|
op: BPL,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x30, 0xab],
|
|
Instruction {
|
|
op: BMI,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x50, 0xab],
|
|
Instruction {
|
|
op: BVC,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x70, 0xab],
|
|
Instruction {
|
|
op: BVS,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x90, 0xab],
|
|
Instruction {
|
|
op: BCC,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xb0, 0xab],
|
|
Instruction {
|
|
op: BCS,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xd0, 0xab],
|
|
Instruction {
|
|
op: BNE,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xf0, 0xab],
|
|
Instruction {
|
|
op: BEQ,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// BRK
|
|
(
|
|
vec![0x00],
|
|
Instruction {
|
|
op: BRK,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// CLC, CLD, CLI, CLV
|
|
(
|
|
vec![0x18],
|
|
Instruction {
|
|
op: CLC,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0xd8],
|
|
Instruction {
|
|
op: CLD,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x58],
|
|
Instruction {
|
|
op: CLI,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0xb8],
|
|
Instruction {
|
|
op: CLV,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// CMP
|
|
(
|
|
vec![0xc9, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xc5, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xd5, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xcd, 0xcd, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xdd, 0xcd, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xd9, 0xcd, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xc1, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xd1, 0xab],
|
|
Instruction {
|
|
op: CMP,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// CPX
|
|
(
|
|
vec![0xe0, 0xab],
|
|
Instruction {
|
|
op: CPX,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xe4, 0xab],
|
|
Instruction {
|
|
op: CPX,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xec, 0xcd, 0xab],
|
|
Instruction {
|
|
op: CPX,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// CPY
|
|
(
|
|
vec![0xc0, 0xab],
|
|
Instruction {
|
|
op: CPY,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xc4, 0xab],
|
|
Instruction {
|
|
op: CPY,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xcc, 0xcd, 0xab],
|
|
Instruction {
|
|
op: CPY,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// DEC, DEX, DEY
|
|
(
|
|
vec![0xc6, 0xab],
|
|
Instruction {
|
|
op: DEC,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xd6, 0xab],
|
|
Instruction {
|
|
op: DEC,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xce, 0xcd, 0xab],
|
|
Instruction {
|
|
op: DEC,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xde, 0xcd, 0xab],
|
|
Instruction {
|
|
op: DEC,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xca],
|
|
Instruction {
|
|
op: DEX,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x88],
|
|
Instruction {
|
|
op: DEY,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// EOR
|
|
(
|
|
vec![0x49, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x45, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x55, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x4d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x5d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x59, 0xcd, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x41, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x51, 0xab],
|
|
Instruction {
|
|
op: EOR,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// INC, INX, INY
|
|
(
|
|
vec![0xe6, 0xab],
|
|
Instruction {
|
|
op: INC,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xf6, 0xab],
|
|
Instruction {
|
|
op: INC,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xee, 0xcd, 0xab],
|
|
Instruction {
|
|
op: INC,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xfe, 0xcd, 0xab],
|
|
Instruction {
|
|
op: INC,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xe8],
|
|
Instruction {
|
|
op: INX,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0xc8],
|
|
Instruction {
|
|
op: INY,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// JMP, JSR
|
|
(
|
|
vec![0x4c, 0xcd, 0xab],
|
|
Instruction {
|
|
op: JMP,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x6c, 0xcd, 0xab],
|
|
Instruction {
|
|
op: JMP,
|
|
mode: Indirect,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x20],
|
|
Instruction {
|
|
op: JSR,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// LDA
|
|
(
|
|
vec![0xa9, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xa5, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xb5, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xad, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xbd, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xb9, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xa1, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xb1, 0xab],
|
|
Instruction {
|
|
op: LDA,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// LDX
|
|
(
|
|
vec![0xa2, 0xab],
|
|
Instruction {
|
|
op: LDX,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xa6, 0xab],
|
|
Instruction {
|
|
op: LDX,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xb6, 0xab],
|
|
Instruction {
|
|
op: LDX,
|
|
mode: ZeroPageY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xae, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDX,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xbe, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDX,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// LDY
|
|
(
|
|
vec![0xa0, 0xab],
|
|
Instruction {
|
|
op: LDY,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xa4, 0xab],
|
|
Instruction {
|
|
op: LDY,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xb4, 0xab],
|
|
Instruction {
|
|
op: LDY,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xac, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDY,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xbc, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LDY,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// LSR
|
|
(
|
|
vec![0x4a],
|
|
Instruction {
|
|
op: LSR,
|
|
mode: Accumulator,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x46, 0xab],
|
|
Instruction {
|
|
op: LSR,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x56, 0xab],
|
|
Instruction {
|
|
op: LSR,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x4e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LSR,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x5e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: LSR,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// NOP
|
|
(
|
|
vec![0xea],
|
|
Instruction {
|
|
op: NOP,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// ORA
|
|
(
|
|
vec![0x09, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x05, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x15, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x0d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x1d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x19, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x01, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x11, 0xab],
|
|
Instruction {
|
|
op: ORA,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// PHA, PHP, PLA, PLP
|
|
(
|
|
vec![0x48],
|
|
Instruction {
|
|
op: PHA,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x08],
|
|
Instruction {
|
|
op: PHP,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x68],
|
|
Instruction {
|
|
op: PLA,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x28],
|
|
Instruction {
|
|
op: PLP,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// ROL
|
|
(
|
|
vec![0x2a],
|
|
Instruction {
|
|
op: ROL,
|
|
mode: Accumulator,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x26, 0xab],
|
|
Instruction {
|
|
op: ROL,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x36, 0xab],
|
|
Instruction {
|
|
op: ROL,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x2e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ROL,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x3e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ROL,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// ROR
|
|
(
|
|
vec![0x6a],
|
|
Instruction {
|
|
op: ROR,
|
|
mode: Accumulator,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x66, 0xab],
|
|
Instruction {
|
|
op: ROR,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x76, 0xab],
|
|
Instruction {
|
|
op: ROR,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x6e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ROR,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x7e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: ROR,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// RTI, RTS
|
|
(
|
|
vec![0x40],
|
|
Instruction {
|
|
op: RTI,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x60],
|
|
Instruction {
|
|
op: RTS,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// SBC
|
|
(
|
|
vec![0xe9, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: Immediate,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xe5, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xf5, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xed, 0xcd, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xfd, 0xcd, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xf9, 0xcd, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0xe1, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0xf1, 0xab],
|
|
Instruction {
|
|
op: SBC,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// SEC, SED, SEI
|
|
(
|
|
vec![0x38],
|
|
Instruction {
|
|
op: SEC,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0xf8],
|
|
Instruction {
|
|
op: SED,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x78],
|
|
Instruction {
|
|
op: SEI,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
// STA
|
|
(
|
|
vec![0x85, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x95, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x8d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x9d, 0xcd, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: AbsoluteX,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x99, 0xcd, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: AbsoluteY,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
(
|
|
vec![0x81, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: IndirectX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x91, 0xab],
|
|
Instruction {
|
|
op: STA,
|
|
mode: IndirectY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
// STX
|
|
(
|
|
vec![0x86, 0xab],
|
|
Instruction {
|
|
op: STX,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x96, 0xab],
|
|
Instruction {
|
|
op: STX,
|
|
mode: ZeroPageY,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x8e, 0xcd, 0xab],
|
|
Instruction {
|
|
op: STX,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// STY
|
|
(
|
|
vec![0x84, 0xab],
|
|
Instruction {
|
|
op: STY,
|
|
mode: ZeroPage,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x94, 0xab],
|
|
Instruction {
|
|
op: STY,
|
|
mode: ZeroPageX,
|
|
operand: Operand::Byte(0xab),
|
|
},
|
|
),
|
|
(
|
|
vec![0x8c, 0xcd, 0xab],
|
|
Instruction {
|
|
op: STY,
|
|
mode: Absolute,
|
|
operand: Operand::Word(0xabcd),
|
|
},
|
|
),
|
|
// TAX, TAY, TSX, TXA, TXS, TYA
|
|
(
|
|
vec![0xaa],
|
|
Instruction {
|
|
op: TAX,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0xa8],
|
|
Instruction {
|
|
op: TAY,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0xba],
|
|
Instruction {
|
|
op: TSX,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x8a],
|
|
Instruction {
|
|
op: TXA,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x9a],
|
|
Instruction {
|
|
op: TXS,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
(
|
|
vec![0x98],
|
|
Instruction {
|
|
op: TYA,
|
|
mode: Implied,
|
|
operand: Operand::None,
|
|
},
|
|
),
|
|
];
|
|
for (bytes, instruction) in params {
|
|
let result1 = Instruction::decode(&bytes);
|
|
if let Some(instruction1) = result1 {
|
|
assert_eq!(instruction, instruction1)
|
|
} else {
|
|
println!("Failed to decode {:?}", bytes);
|
|
}
|
|
}
|
|
}
|
|
}
|