mirror of
https://github.com/mre/mos6502.git
synced 2024-09-29 02:55:06 +00:00
769 lines
25 KiB
Rust
769 lines
25 KiB
Rust
// Copyright (C) 2014 The 6502-rs Developers
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions
|
|
// are met:
|
|
// 1. Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
// 3. Neither the names of the copyright holders nor the names of any
|
|
// contributors may be used to endorse or promote products derived from this
|
|
// software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
use crate::address::Address;
|
|
use crate::address::AddressDiff;
|
|
use crate::cpu::CPU;
|
|
|
|
// Abbreviations
|
|
//
|
|
// General
|
|
//
|
|
// M | `Memory location`
|
|
//
|
|
// Registers
|
|
//
|
|
// A | accumulator
|
|
// X | general purpose register
|
|
// Y | general purpose register
|
|
// F | processor status flags, collectively
|
|
// NV-BDIZC | processor status flags, individually
|
|
// S | stack pointer
|
|
// PC | program counter
|
|
//
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum Instruction {
|
|
ADC, // ADd with Carry................ | NV ...ZC A = A + M + C
|
|
AND, // logical AND (bitwise)......... | N. ...Z. A = A && M
|
|
ASL, // Arithmetic Shift Left......... | N. ...ZC A = M << 1
|
|
BCC, // Branch if Carry Clear......... | .. ..... PC = !C
|
|
BCS, // Branch if Carry Set........... | .. ..... PC = C
|
|
BEQ, // Branch if Equal (to zero?).... | .. ..... PC = Z
|
|
BIT, // BIT test...................... | NV ...Z. = A & M
|
|
BMI, // Branch if Minus............... | .. ..... PC = N
|
|
BNE, // Branch if Not Equal........... | .. ..... PC = !Z
|
|
BPL, // Branch if Positive............ | .. ..... PC = Z
|
|
BRK, // BReaK......................... | .. B.... S PC =
|
|
BVC, // Branch if oVerflow Clear...... | .. ..... PC = !V
|
|
BVS, // Branch if oVerflow Set........ | .. ..... PC = V
|
|
CLC, // CLear Carry flag.............. | .. ....C = 0
|
|
CLD, // Clear Decimal Mode............ | .. .D... = 0
|
|
CLI, // Clear Interrupt Disable....... | .. ..I.. = 0
|
|
CLV, // Clear oVerflow flag........... | .V ..... = 0
|
|
CMP, // Compare....................... | N. ...ZC = A - M
|
|
CPX, // Compare X register............ | N. ...ZC = X - M
|
|
CPY, // Compare Y register............ | N. ...ZC = Y - M
|
|
DEC, // DECrement memory.............. | N. ...Z. M = M - 1
|
|
DEX, // DEcrement X register.......... | N. ...Z. X = X - 1
|
|
DEY, // DEcrement Y register.......... | N. ...Z. Y = Y - 1
|
|
EOR, // Exclusive OR (bitwise)........ | N. ...Z. A = A ^ M
|
|
INC, // INCrement memory.............. | N. ...Z. M = M + 1
|
|
INX, // INcrement X register.......... | N. ...Z. X = X + 1
|
|
INY, // INcrement Y register.......... | N. ...Z. Y = Y + 1
|
|
JMP, // JuMP.......................... | .. ..... S PC =
|
|
JSR, // Jump to SubRoutine............ | .. ..... S PC =
|
|
LDA, // LoaD Accumulator.............. | N. ...Z. A = M
|
|
LDX, // LoaD X register............... | N. ...Z. X = M
|
|
LDY, // LoaD Y register............... | N. ...Z. Y = M
|
|
LSR, // Logical Shift Right........... | N. ...ZC A = A/2
|
|
// or N. ...ZC M = M/2
|
|
NOP, // No OPeration.................. | .. ..... =
|
|
ORA, // inclusive OR (bitwise)........ | N. ...Z. A = A | M
|
|
PHA, // PusH Accumulator.............. | .. ..... S M = A
|
|
PHP, // PusH Processor status......... | .. ..... S M = F
|
|
PLA, // PuLl Accumulator.............. | N. ...Z. A S = M (stack)
|
|
PLP, // PuLl Processor status......... | NV BDIZC S = M (stack)
|
|
ROL, // ROtate Left................... | N. ...ZC A = C A rotated
|
|
// or N. ...ZC M = C M rotated
|
|
ROR, // ROtate Right.................. | N. ...ZC A = C A rotated
|
|
// or N. ...ZC M = C M rotated
|
|
RTI, // ReTurn from Interrupt......... | NV BDIZC PC = M (stack)
|
|
RTS, // ReTurn from Subroutine........ | .. ..... PC = M (stack)
|
|
SBC, // SuBtract with Carry........... | NV ...ZC A = A-M-(1-C)
|
|
SEC, // SEt Carry flag................ | .. ....C = 1
|
|
SED, // SEt Decimal flag.............. | .. .D... = 1
|
|
SEI, // SEt Interrupt disable......... | .. ..I.. = 1
|
|
STA, // STore Accumulator............. | .. ..... M = A
|
|
STX, // STore X register.............. | .. ..... M = X
|
|
STY, // STore Y register.............. | .. ..... M = Y
|
|
TAX, // Transfer Accumulator to X..... | N. ...Z. X = A
|
|
TAY, // Transfer Accumulator to Y..... | N. ...Z. Y = A
|
|
TSX, // Transfer Stack pointer to X... | N. ...Z. X = S
|
|
TXA, // Transfer X to Accumulator..... | N. ...Z. A = X
|
|
TXS, // Transfer X to Stack pointer... | .. ..... S = X
|
|
TYA, // Transfer Y to Accumulator..... | N. ...Z. A = Y
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub enum OpInput {
|
|
UseImplied,
|
|
UseImmediate(u8),
|
|
UseRelative(i8),
|
|
UseAddress(Address),
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub enum AddressingMode {
|
|
Accumulator, // 1 LSR A work directly on accumulator
|
|
Implied, // 1 BRK
|
|
Immediate, // 2 LDA #10 8-bit constant in instruction
|
|
ZeroPage, // 2 LDA $00 zero-page address
|
|
ZeroPageX, // 2 LDA $80,X address is X register + 8-bit constant
|
|
ZeroPageY, // 2 LDX $10,Y address is Y register + 8-bit constant
|
|
Relative, // 2 BNE LABEL branch target as signed relative offset
|
|
Absolute, // 3 JMP $1000 full 16-bit address
|
|
AbsoluteX, // 3 STA $1000,X full 16-bit address plus X register
|
|
AbsoluteY, // 3 STA $1000,Y full 16-bit address plus Y register
|
|
Indirect, // 3 JMP ($1000) jump to address stored at address
|
|
IndexedIndirectX, // 2 LDA ($10,X) load from address stored at (constant
|
|
// zero page address plus X register)
|
|
IndirectIndexedY, // 2 LDA ($10),Y load from (address stored at constant
|
|
// zero page address) plus Y register
|
|
}
|
|
|
|
fn arr_to_addr(arr: &[u8]) -> Address {
|
|
debug_assert!(arr.len() == 2);
|
|
|
|
let x = u16::from(arr[0]) + (u16::from(arr[1]) << 8usize);
|
|
Address(x)
|
|
}
|
|
|
|
impl AddressingMode {
|
|
pub fn extra_bytes(self) -> AddressDiff {
|
|
let x = match self {
|
|
AddressingMode::Accumulator => 0,
|
|
AddressingMode::Implied => 0,
|
|
AddressingMode::Immediate => 1,
|
|
AddressingMode::ZeroPage => 1,
|
|
AddressingMode::ZeroPageX => 1,
|
|
AddressingMode::ZeroPageY => 1,
|
|
AddressingMode::Relative => 1,
|
|
AddressingMode::Absolute => 2,
|
|
AddressingMode::AbsoluteX => 2,
|
|
AddressingMode::AbsoluteY => 2,
|
|
AddressingMode::Indirect => 2,
|
|
AddressingMode::IndexedIndirectX => 1,
|
|
AddressingMode::IndirectIndexedY => 1,
|
|
};
|
|
AddressDiff(x)
|
|
}
|
|
|
|
pub fn process(self, cpu: &CPU, arr: &[u8]) -> OpInput {
|
|
debug_assert!({
|
|
let AddressDiff(x) = self.extra_bytes();
|
|
arr.len() == x as usize
|
|
});
|
|
|
|
let x = cpu.registers.index_x as u8;
|
|
let y = cpu.registers.index_y as u8;
|
|
|
|
let memory = &cpu.memory;
|
|
|
|
match self {
|
|
AddressingMode::Accumulator | AddressingMode::Implied => {
|
|
// Always the same -- no input
|
|
OpInput::UseImplied
|
|
}
|
|
AddressingMode::Immediate => {
|
|
// Use [u8, ..1] specified in instruction as input
|
|
OpInput::UseImmediate(arr[0])
|
|
}
|
|
AddressingMode::ZeroPage => {
|
|
// Use [u8, ..1] from instruction
|
|
// Interpret as zero page address
|
|
// (Output: an 8-bit zero-page address)
|
|
OpInput::UseAddress(Address(u16::from(arr[0])))
|
|
}
|
|
AddressingMode::ZeroPageX => {
|
|
// Use [u8, ..1] from instruction
|
|
// Add to X register (as u8 -- the final address is in 0-page)
|
|
// (Output: an 8-bit zero-page address)
|
|
OpInput::UseAddress(Address(u16::from(arr[0] + x)))
|
|
}
|
|
AddressingMode::ZeroPageY => {
|
|
// Use [u8, ..1] from instruction
|
|
// Add to Y register (as u8 -- the final address is in 0-page)
|
|
// (Output: an 8-bit zero-page address)
|
|
OpInput::UseAddress(Address(u16::from(arr[0] + y)))
|
|
}
|
|
AddressingMode::Relative => {
|
|
// Use [u8, ..1] from instruction
|
|
// (interpret as relative...)
|
|
OpInput::UseRelative(arr[0] as i8)
|
|
}
|
|
AddressingMode::Absolute => {
|
|
// Use [u8, ..2] from instruction as address
|
|
// (Output: a 16-bit address)
|
|
OpInput::UseAddress(arr_to_addr(arr))
|
|
}
|
|
AddressingMode::AbsoluteX => {
|
|
// Use [u8, ..2] from instruction as address, add X
|
|
// (Output: a 16-bit address)
|
|
OpInput::UseAddress(arr_to_addr(arr) + AddressDiff(i32::from(x)))
|
|
}
|
|
AddressingMode::AbsoluteY => {
|
|
// Use [u8, ..2] from instruction as address, add Y
|
|
// (Output: a 16-bit address)
|
|
OpInput::UseAddress(arr_to_addr(arr) + AddressDiff(i32::from(y)))
|
|
}
|
|
AddressingMode::Indirect => {
|
|
// Use [u8, ..2] from instruction as an address. Interpret the
|
|
// two bytes starting at that address as an address.
|
|
// (Output: a 16-bit address)
|
|
let slice = memory.get_slice(arr_to_addr(arr), AddressDiff(2));
|
|
OpInput::UseAddress(arr_to_addr(slice))
|
|
}
|
|
AddressingMode::IndexedIndirectX => {
|
|
// Use [u8, ..1] from instruction
|
|
// Add to X register with 0-page wraparound, like ZeroPageX.
|
|
// This is where the absolute (16-bit) target address is stored.
|
|
// (Output: a 16-bit address)
|
|
let start = arr[0] + x;
|
|
let slice = memory.get_slice(Address(u16::from(start)), AddressDiff(2));
|
|
OpInput::UseAddress(arr_to_addr(slice))
|
|
}
|
|
AddressingMode::IndirectIndexedY => {
|
|
// Use [u8, ..1] from instruction
|
|
// This is where the absolute (16-bit) target address is stored.
|
|
// Add Y register to this address to get the final address
|
|
// (Output: a 16-bit address)
|
|
let start = arr[0];
|
|
let slice = memory.get_slice(Address(u16::from(start)), AddressDiff(2));
|
|
OpInput::UseAddress(arr_to_addr(slice) + AddressDiff(i32::from(y)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type DecodedInstr = (Instruction, OpInput);
|
|
|
|
pub static OPCODES: [Option<(Instruction, AddressingMode)>; 256] = [
|
|
/*0x00*/
|
|
Some((Instruction::BRK, AddressingMode::Implied)),
|
|
/*0x01*/
|
|
Some((Instruction::ORA, AddressingMode::IndexedIndirectX)),
|
|
/*0x02*/
|
|
None,
|
|
/*0x03*/
|
|
None,
|
|
/*0x04*/
|
|
None,
|
|
/*0x05*/
|
|
Some((Instruction::ORA, AddressingMode::ZeroPage)),
|
|
/*0x06*/
|
|
Some((Instruction::ASL, AddressingMode::ZeroPage)),
|
|
/*0x07*/
|
|
None,
|
|
/*0x08*/
|
|
Some((Instruction::PHP, AddressingMode::Implied)),
|
|
/*0x09*/
|
|
Some((Instruction::ORA, AddressingMode::Immediate)),
|
|
/*0x0A*/
|
|
Some((Instruction::ASL, AddressingMode::Accumulator)),
|
|
/*0x0B*/
|
|
None,
|
|
/*0x0C*/
|
|
None,
|
|
/*0x0D*/
|
|
Some((Instruction::ORA, AddressingMode::Absolute)),
|
|
/*0x0E*/
|
|
Some((Instruction::ASL, AddressingMode::Absolute)),
|
|
/*0x0F*/
|
|
None,
|
|
/*0x10*/
|
|
Some((Instruction::BPL, AddressingMode::Relative)),
|
|
/*0x11*/
|
|
Some((Instruction::ORA, AddressingMode::IndirectIndexedY)),
|
|
/*0x12*/
|
|
None,
|
|
/*0x13*/
|
|
None,
|
|
/*0x14*/
|
|
None,
|
|
/*0x15*/
|
|
Some((Instruction::ORA, AddressingMode::ZeroPageX)),
|
|
/*0x16*/
|
|
Some((Instruction::ASL, AddressingMode::ZeroPageX)),
|
|
/*0x17*/
|
|
None,
|
|
/*0x18*/
|
|
Some((Instruction::CLC, AddressingMode::Implied)),
|
|
/*0x19*/
|
|
Some((Instruction::ORA, AddressingMode::AbsoluteY)),
|
|
/*0x1A*/
|
|
None,
|
|
/*0x1B*/
|
|
None,
|
|
/*0x1C*/
|
|
None,
|
|
/*0x1D*/
|
|
Some((Instruction::ORA, AddressingMode::AbsoluteX)),
|
|
/*0x1E*/
|
|
Some((Instruction::ASL, AddressingMode::AbsoluteX)),
|
|
/*0x1F*/
|
|
None,
|
|
/*0x20*/
|
|
Some((Instruction::JSR, AddressingMode::Absolute)),
|
|
/*0x21*/
|
|
Some((Instruction::AND, AddressingMode::IndexedIndirectX)),
|
|
/*0x22*/
|
|
None,
|
|
/*0x23*/
|
|
None,
|
|
/*0x24*/
|
|
Some((Instruction::BIT, AddressingMode::ZeroPage)),
|
|
/*0x25*/
|
|
Some((Instruction::AND, AddressingMode::ZeroPage)),
|
|
/*0x26*/
|
|
Some((Instruction::ROL, AddressingMode::ZeroPage)),
|
|
/*0x27*/
|
|
None,
|
|
/*0x28*/
|
|
Some((Instruction::PLP, AddressingMode::Implied)),
|
|
/*0x29*/
|
|
Some((Instruction::AND, AddressingMode::Immediate)),
|
|
/*0x2A*/
|
|
Some((Instruction::ROL, AddressingMode::Accumulator)),
|
|
/*0x2B*/
|
|
None,
|
|
/*0x2C*/
|
|
Some((Instruction::BIT, AddressingMode::Absolute)),
|
|
/*0x2D*/
|
|
Some((Instruction::AND, AddressingMode::Absolute)),
|
|
/*0x2E*/
|
|
Some((Instruction::ROL, AddressingMode::Absolute)),
|
|
/*0x2F*/
|
|
None,
|
|
/*0x30*/
|
|
Some((Instruction::BMI, AddressingMode::Relative)),
|
|
/*0x31*/
|
|
Some((Instruction::AND, AddressingMode::IndirectIndexedY)),
|
|
/*0x32*/
|
|
None,
|
|
/*0x33*/
|
|
None,
|
|
/*0x34*/
|
|
None,
|
|
/*0x35*/
|
|
Some((Instruction::AND, AddressingMode::ZeroPageX)),
|
|
/*0x36*/
|
|
Some((Instruction::ROL, AddressingMode::ZeroPageX)),
|
|
/*0x37*/
|
|
None,
|
|
/*0x38*/
|
|
Some((Instruction::SEC, AddressingMode::Implied)),
|
|
/*0x39*/
|
|
Some((Instruction::AND, AddressingMode::AbsoluteY)),
|
|
/*0x3A*/
|
|
None,
|
|
/*0x3B*/
|
|
None,
|
|
/*0x3C*/
|
|
None,
|
|
/*0x3D*/
|
|
Some((Instruction::AND, AddressingMode::AbsoluteX)),
|
|
/*0x3E*/
|
|
Some((Instruction::ROL, AddressingMode::AbsoluteX)),
|
|
/*0x3F*/
|
|
None,
|
|
/*0x40*/
|
|
Some((Instruction::RTI, AddressingMode::Implied)),
|
|
/*0x41*/
|
|
Some((Instruction::EOR, AddressingMode::IndexedIndirectX)),
|
|
/*0x42*/
|
|
None,
|
|
/*0x43*/
|
|
None,
|
|
/*0x44*/
|
|
None,
|
|
/*0x45*/
|
|
Some((Instruction::EOR, AddressingMode::ZeroPage)),
|
|
/*0x46*/
|
|
Some((Instruction::LSR, AddressingMode::ZeroPage)),
|
|
/*0x47*/
|
|
None,
|
|
/*0x48*/
|
|
Some((Instruction::PHA, AddressingMode::Implied)),
|
|
/*0x49*/
|
|
Some((Instruction::EOR, AddressingMode::Immediate)),
|
|
/*0x4A*/
|
|
Some((Instruction::LSR, AddressingMode::Accumulator)),
|
|
/*0x4B*/
|
|
None,
|
|
/*0x4C*/
|
|
Some((Instruction::JMP, AddressingMode::Absolute)),
|
|
/*0x4D*/
|
|
Some((Instruction::EOR, AddressingMode::Absolute)),
|
|
/*0x4E*/
|
|
Some((Instruction::LSR, AddressingMode::Absolute)),
|
|
/*0x4F*/
|
|
None,
|
|
/*0x50*/
|
|
Some((Instruction::BVC, AddressingMode::Relative)),
|
|
/*0x51*/
|
|
Some((Instruction::EOR, AddressingMode::IndirectIndexedY)),
|
|
/*0x52*/
|
|
None,
|
|
/*0x53*/
|
|
None,
|
|
/*0x54*/
|
|
None,
|
|
/*0x55*/
|
|
Some((Instruction::EOR, AddressingMode::ZeroPageX)),
|
|
/*0x56*/
|
|
Some((Instruction::LSR, AddressingMode::ZeroPageX)),
|
|
/*0x57*/
|
|
None,
|
|
/*0x58*/
|
|
None,
|
|
/*0x59*/
|
|
Some((Instruction::EOR, AddressingMode::AbsoluteY)),
|
|
/*0x5A*/
|
|
None,
|
|
/*0x5B*/
|
|
None,
|
|
/*0x5C*/
|
|
None,
|
|
/*0x5D*/
|
|
Some((Instruction::EOR, AddressingMode::AbsoluteX)),
|
|
/*0x5E*/
|
|
Some((Instruction::LSR, AddressingMode::AbsoluteX)),
|
|
/*0x5F*/
|
|
None,
|
|
/*0x60*/
|
|
Some((Instruction::RTS, AddressingMode::Implied)),
|
|
/*0x61*/
|
|
Some((Instruction::ADC, AddressingMode::IndexedIndirectX)),
|
|
/*0x62*/
|
|
None,
|
|
/*0x63*/
|
|
None,
|
|
/*0x64*/
|
|
None,
|
|
/*0x65*/
|
|
Some((Instruction::ADC, AddressingMode::ZeroPage)),
|
|
/*0x66*/
|
|
Some((Instruction::ROR, AddressingMode::ZeroPage)),
|
|
/*0x67*/
|
|
None,
|
|
/*0x68*/
|
|
Some((Instruction::PLA, AddressingMode::Implied)),
|
|
/*0x69*/
|
|
Some((Instruction::ADC, AddressingMode::Immediate)),
|
|
/*0x6A*/
|
|
Some((Instruction::ROR, AddressingMode::Accumulator)),
|
|
/*0x6B*/
|
|
None,
|
|
/*0x6C*/
|
|
Some((Instruction::JMP, AddressingMode::Indirect)),
|
|
/*0x6D*/
|
|
Some((Instruction::ADC, AddressingMode::Absolute)),
|
|
/*0x6E*/
|
|
Some((Instruction::ROR, AddressingMode::Absolute)),
|
|
/*0x6F*/
|
|
None,
|
|
/*0x70*/
|
|
Some((Instruction::BVS, AddressingMode::Relative)),
|
|
/*0x71*/
|
|
Some((Instruction::ADC, AddressingMode::IndirectIndexedY)),
|
|
/*0x72*/
|
|
None,
|
|
/*0x73*/
|
|
None,
|
|
/*0x74*/
|
|
None,
|
|
/*0x75*/
|
|
Some((Instruction::ADC, AddressingMode::ZeroPageX)),
|
|
/*0x76*/
|
|
Some((Instruction::ROR, AddressingMode::ZeroPageX)),
|
|
/*0x77*/
|
|
None,
|
|
/*0x78*/
|
|
Some((Instruction::SEI, AddressingMode::Implied)),
|
|
/*0x79*/
|
|
Some((Instruction::ADC, AddressingMode::AbsoluteY)),
|
|
/*0x7A*/
|
|
None,
|
|
/*0x7B*/
|
|
None,
|
|
/*0x7C*/
|
|
None,
|
|
/*0x7D*/
|
|
Some((Instruction::ADC, AddressingMode::AbsoluteX)),
|
|
/*0x7E*/
|
|
Some((Instruction::ROR, AddressingMode::AbsoluteX)),
|
|
/*0x7F*/
|
|
None,
|
|
/*0x80*/
|
|
None,
|
|
/*0x81*/
|
|
Some((Instruction::STA, AddressingMode::IndexedIndirectX)),
|
|
/*0x82*/
|
|
None,
|
|
/*0x83*/
|
|
None,
|
|
/*0x84*/
|
|
Some((Instruction::STY, AddressingMode::ZeroPage)),
|
|
/*0x85*/
|
|
Some((Instruction::STA, AddressingMode::ZeroPage)),
|
|
/*0x86*/
|
|
Some((Instruction::STX, AddressingMode::ZeroPage)),
|
|
/*0x87*/
|
|
None,
|
|
/*0x88*/
|
|
Some((Instruction::DEY, AddressingMode::Implied)),
|
|
/*0x89*/
|
|
None,
|
|
/*0x8A*/
|
|
Some((Instruction::TXA, AddressingMode::Implied)),
|
|
/*0x8B*/
|
|
None,
|
|
/*0x8C*/
|
|
Some((Instruction::STY, AddressingMode::Absolute)),
|
|
/*0x8D*/
|
|
Some((Instruction::STA, AddressingMode::Absolute)),
|
|
/*0x8E*/
|
|
Some((Instruction::STX, AddressingMode::Absolute)),
|
|
/*0x8F*/
|
|
None,
|
|
/*0x90*/
|
|
Some((Instruction::BCC, AddressingMode::Relative)),
|
|
/*0x91*/
|
|
Some((Instruction::STA, AddressingMode::IndirectIndexedY)),
|
|
/*0x92*/
|
|
None,
|
|
/*0x93*/
|
|
None,
|
|
/*0x94*/
|
|
Some((Instruction::STY, AddressingMode::ZeroPageX)),
|
|
/*0x95*/
|
|
Some((Instruction::STA, AddressingMode::ZeroPageX)),
|
|
/*0x96*/
|
|
Some((Instruction::STX, AddressingMode::ZeroPageY)),
|
|
/*0x97*/
|
|
None,
|
|
/*0x98*/
|
|
Some((Instruction::TYA, AddressingMode::Implied)),
|
|
/*0x99*/
|
|
Some((Instruction::STA, AddressingMode::AbsoluteY)),
|
|
/*0x9A*/
|
|
Some((Instruction::TXS, AddressingMode::Implied)),
|
|
/*0x9B*/
|
|
None,
|
|
/*0x9C*/
|
|
None,
|
|
/*0x9D*/
|
|
Some((Instruction::STA, AddressingMode::AbsoluteX)),
|
|
/*0x9E*/
|
|
None,
|
|
/*0x9F*/
|
|
None,
|
|
/*0xA0*/
|
|
Some((Instruction::LDY, AddressingMode::Immediate)),
|
|
/*0xA1*/
|
|
Some((Instruction::LDA, AddressingMode::IndexedIndirectX)),
|
|
/*0xA2*/
|
|
Some((Instruction::LDX, AddressingMode::Immediate)),
|
|
/*0xA3*/
|
|
None,
|
|
/*0xA4*/
|
|
Some((Instruction::LDY, AddressingMode::ZeroPage)),
|
|
/*0xA5*/
|
|
Some((Instruction::LDA, AddressingMode::ZeroPage)),
|
|
/*0xA6*/
|
|
Some((Instruction::LDX, AddressingMode::ZeroPage)),
|
|
/*0xA7*/
|
|
None,
|
|
/*0xA8*/
|
|
Some((Instruction::TAY, AddressingMode::Implied)),
|
|
/*0xA9*/
|
|
Some((Instruction::LDA, AddressingMode::Immediate)),
|
|
/*0xAA*/
|
|
Some((Instruction::TAX, AddressingMode::Implied)),
|
|
/*0xAB*/
|
|
None,
|
|
/*0xAC*/
|
|
Some((Instruction::LDY, AddressingMode::Absolute)),
|
|
/*0xAD*/
|
|
Some((Instruction::LDA, AddressingMode::Absolute)),
|
|
/*0xAE*/
|
|
Some((Instruction::LDX, AddressingMode::Absolute)),
|
|
/*0xAF*/
|
|
None,
|
|
/*0xB0*/
|
|
Some((Instruction::BCS, AddressingMode::Relative)),
|
|
/*0xB1*/
|
|
Some((Instruction::LDA, AddressingMode::IndirectIndexedY)),
|
|
/*0xB2*/
|
|
None,
|
|
/*0xB3*/
|
|
None,
|
|
/*0xB4*/
|
|
Some((Instruction::LDY, AddressingMode::ZeroPageX)),
|
|
/*0xB5*/
|
|
Some((Instruction::LDA, AddressingMode::ZeroPageX)),
|
|
/*0xB6*/
|
|
Some((Instruction::LDX, AddressingMode::ZeroPageY)),
|
|
/*0xB7*/
|
|
None,
|
|
/*0xB8*/
|
|
Some((Instruction::CLV, AddressingMode::Implied)),
|
|
/*0xB9*/
|
|
Some((Instruction::LDA, AddressingMode::AbsoluteY)),
|
|
/*0xBA*/
|
|
Some((Instruction::TSX, AddressingMode::Implied)),
|
|
/*0xBB*/
|
|
None,
|
|
/*0xBC*/
|
|
Some((Instruction::LDY, AddressingMode::AbsoluteX)),
|
|
/*0xBD*/
|
|
Some((Instruction::LDA, AddressingMode::AbsoluteX)),
|
|
/*0xBE*/
|
|
Some((Instruction::LDX, AddressingMode::AbsoluteY)),
|
|
/*0xBF*/
|
|
None,
|
|
/*0xC0*/
|
|
Some((Instruction::CPY, AddressingMode::Immediate)),
|
|
/*0xC1*/
|
|
Some((Instruction::CMP, AddressingMode::IndexedIndirectX)),
|
|
/*0xC2*/
|
|
None,
|
|
/*0xC3*/
|
|
None,
|
|
/*0xC4*/
|
|
Some((Instruction::CPY, AddressingMode::ZeroPage)),
|
|
/*0xC5*/
|
|
Some((Instruction::CMP, AddressingMode::ZeroPage)),
|
|
/*0xC6*/
|
|
Some((Instruction::DEC, AddressingMode::ZeroPage)),
|
|
/*0xC7*/
|
|
None,
|
|
/*0xC8*/
|
|
Some((Instruction::INY, AddressingMode::Implied)),
|
|
/*0xC9*/
|
|
Some((Instruction::CMP, AddressingMode::Immediate)),
|
|
/*0xCA*/
|
|
Some((Instruction::DEX, AddressingMode::Implied)),
|
|
/*0xCB*/
|
|
None,
|
|
/*0xCC*/
|
|
Some((Instruction::CPY, AddressingMode::Absolute)),
|
|
/*0xCD*/
|
|
Some((Instruction::CMP, AddressingMode::Absolute)),
|
|
/*0xCE*/
|
|
Some((Instruction::DEC, AddressingMode::Absolute)),
|
|
/*0xCF*/
|
|
None,
|
|
/*0xD0*/
|
|
Some((Instruction::BNE, AddressingMode::Relative)),
|
|
/*0xD1*/
|
|
Some((Instruction::CMP, AddressingMode::IndirectIndexedY)),
|
|
/*0xD2*/
|
|
None,
|
|
/*0xD3*/
|
|
None,
|
|
/*0xD4*/
|
|
None,
|
|
/*0xD5*/
|
|
Some((Instruction::CMP, AddressingMode::ZeroPageX)),
|
|
/*0xD6*/
|
|
Some((Instruction::DEC, AddressingMode::ZeroPageX)),
|
|
/*0xD7*/
|
|
None,
|
|
/*0xD8*/
|
|
Some((Instruction::CLD, AddressingMode::Implied)),
|
|
/*0xD9*/
|
|
Some((Instruction::CMP, AddressingMode::AbsoluteY)),
|
|
/*0xDA*/
|
|
None,
|
|
/*0xDB*/
|
|
None,
|
|
/*0xDC*/
|
|
None,
|
|
/*0xDD*/
|
|
Some((Instruction::CMP, AddressingMode::AbsoluteX)),
|
|
/*0xDE*/
|
|
Some((Instruction::DEC, AddressingMode::AbsoluteX)),
|
|
/*0xDF*/
|
|
None,
|
|
/*0xE0*/
|
|
Some((Instruction::CPX, AddressingMode::Immediate)),
|
|
/*0xE1*/
|
|
Some((Instruction::SBC, AddressingMode::IndexedIndirectX)),
|
|
/*0xE2*/
|
|
None,
|
|
/*0xE3*/
|
|
None,
|
|
/*0xE4*/
|
|
Some((Instruction::CPX, AddressingMode::ZeroPage)),
|
|
/*0xE5*/
|
|
Some((Instruction::SBC, AddressingMode::ZeroPage)),
|
|
/*0xE6*/
|
|
Some((Instruction::INC, AddressingMode::ZeroPage)),
|
|
/*0xE7*/
|
|
None,
|
|
/*0xE8*/
|
|
Some((Instruction::INX, AddressingMode::Implied)),
|
|
/*0xE9*/
|
|
Some((Instruction::SBC, AddressingMode::Immediate)),
|
|
/*0xEA*/
|
|
Some((Instruction::NOP, AddressingMode::Implied)),
|
|
/*0xEB*/
|
|
None,
|
|
/*0xEC*/
|
|
Some((Instruction::CPX, AddressingMode::Absolute)),
|
|
/*0xED*/
|
|
Some((Instruction::SBC, AddressingMode::Absolute)),
|
|
/*0xEE*/
|
|
Some((Instruction::INC, AddressingMode::Absolute)),
|
|
/*0xEF*/
|
|
None,
|
|
/*0xF0*/
|
|
Some((Instruction::BEQ, AddressingMode::Relative)),
|
|
/*0xF1*/
|
|
Some((Instruction::SBC, AddressingMode::IndirectIndexedY)),
|
|
/*0xF2*/
|
|
None,
|
|
/*0xF3*/
|
|
None,
|
|
/*0xF4*/
|
|
None,
|
|
/*0xF5*/
|
|
Some((Instruction::SBC, AddressingMode::ZeroPageX)),
|
|
/*0xF6*/
|
|
Some((Instruction::INC, AddressingMode::ZeroPageX)),
|
|
/*0xF7*/
|
|
None,
|
|
/*0xF8*/
|
|
Some((Instruction::SED, AddressingMode::Implied)),
|
|
/*0xF9*/
|
|
Some((Instruction::SBC, AddressingMode::AbsoluteY)),
|
|
/*0xFA*/
|
|
None,
|
|
/*0xFB*/
|
|
None,
|
|
/*0xFC*/
|
|
None,
|
|
/*0xFD*/
|
|
Some((Instruction::SBC, AddressingMode::AbsoluteX)),
|
|
/*0xFE*/
|
|
Some((Instruction::INC, AddressingMode::AbsoluteX)),
|
|
/*0xFF*/
|
|
None,
|
|
];
|