Browse Source

some broken stuff I'll have to figure out another time

master
Stephanie Gredell 12 months ago
parent
commit
779a4dfc8b
  1. 7
      Cargo.lock
  2. 1
      Cargo.toml
  3. 184
      cpu.rs
  4. 1
      main.rs
  5. 231
      opcodes.rs

7
Cargo.lock generated

@ -642,6 +642,12 @@ version = "1.0.14" @@ -642,6 +642,12 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.169"
@ -908,6 +914,7 @@ dependencies = [ @@ -908,6 +914,7 @@ dependencies = [
"bitflags",
"env_logger",
"futures",
"lazy_static",
"log",
"serde",
"serde_json",

1
Cargo.toml

@ -7,6 +7,7 @@ edition = "2021" @@ -7,6 +7,7 @@ edition = "2021"
bitflags = "2.8.0"
env_logger = "0.11.6"
futures = "0.3.31"
lazy_static = "1.5.0"
log = "0.4.25"
serde = "1.0.217"
serde_json = "1.0.135"

184
cpu.rs

@ -1,6 +1,10 @@ @@ -1,6 +1,10 @@
use std::collections::HashMap;
// This is all new to me so it's heavily commented so we can understand what is happening.
use bitflags::{bitflags, Flags};
use crate::opcodes;
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct CpuFlags: u8 {
@ -457,6 +461,20 @@ impl CPU { @@ -457,6 +461,20 @@ impl CPU {
self.stack_pointer = self.stack_pointer.wrapping_sub(1)
}
fn stack_push_u16(&mut self, data: u16) {
let hi = (data >> 8) as u8;
let lo = (data & 0xff) as u8;
self.stack_push(hi);
self.stack_push(lo);
}
fn stack_pop_u16(&mut self) -> u16 {
let lo = self.stack_pop() as u16;
let hi = self.stack_pop() as u16;
hi << 8 | lo
}
fn asl_accumulator(&mut self) {
let mut data = self.register_a;
if data >> 6 == 1 {
@ -468,6 +486,17 @@ impl CPU { @@ -468,6 +486,17 @@ impl CPU {
self.set_register_a(data);
}
fn lsr_accumulator(&mut self) {
let mut data = self.register_a;
if data & 1 == 1 {
self.set_carry_flag();
} else {
self.clear_carry_flag();
}
data = data >> 1;
self.set_register_a(data)
}
fn asl(&mut self, mode: &AddressingMode) -> u8 {
let addr = self.get_operand_address(mode);
let mut data = self.mem_read(addr);
@ -644,6 +673,30 @@ impl CPU { @@ -644,6 +673,30 @@ impl CPU {
self.status.set(CpuFlags::OVERFLOW, data & 0b01000000 > 0);
}
fn compare(&mut self, mode: &AddressingMode, compare_with: u8) {
let addr = self.get_operand_address(mode);
let data = self.mem_read(addr);
if data <= compare_with {
self.status.insert(CpuFlags::CARRY);
} else {
self.status.remove(CpuFlags::CARRY);
}
self.update_zero_and_negative_flags(compare_with.wrapping_sub(data));
}
fn branch(&mut self, condition: bool) {
if condition {
let jump: i8 = self.mem_read(self.program_counter) as i8;
let jump_addr = self
.program_counter
.wrapping_add(1)
.wrapping_add(jump as u16);
self.program_counter = jump_addr
}
}
/// INX stands for Increment Index Register X - increase the value of the X register
/// by one and update specific processor flags based on the result.
fn inx(&mut self) {
@ -655,6 +708,10 @@ impl CPU { @@ -655,6 +708,10 @@ impl CPU {
self.register_y = self.register_y.wrapping_add(1);
self.update_zero_and_negative_flags(self.register_y);
}
pub fn run(&mut self) {
self.run_with_callback(|_| {});
}
// The interpret method takes in mutalbe reference to self as we know we will need to modify
// register_a during execution
@ -663,31 +720,121 @@ impl CPU { @@ -663,31 +720,121 @@ impl CPU {
// - Decode instruction
// - Execute the instruction
// - Repeat
pub fn run(&mut self) {
// We need an infinite loop to continuously fetch instructions from the program array. We
// use the program_counter to keep track fo the current instruction.
pub fn run_with_callback<F>(&mut self, mut callback: F)
where
F: FnMut(&mut CPU),
{
let ref opcodes: HashMap<u8, &'static opcodes::OpCode> = *opcodes::OPCODES_MAP;
loop {
// set the opscode to the current byte in the program at the address indicated by
// program counter
let opscode = self.mem_read(self.program_counter);
// we increment program counterto point to the next byte
let code = self.mem_read(self.program_counter);
self.program_counter += 1;
let opcode = opcodes.get(&code).unwrap();
match opscode {
// This will implement LDA (0xA9) opcode. 0xA9 is the LDA Immediate instruction in
// the 6502 CPU.
//
// 0x42 tells the CPU to execute a specific operation: LDA Immediate. An opscode is
// a command for the CPU, instructing it what to do next. Essentially, this means
// "Load the immediate value from the next memory location into the accumulator"
//
// Immediate value refers to the constant value that is directly embedded in the
// instruction itself, rather than being fetched from memory or calculated
// directly.
match code {
0xA9 | 0xa5 | 0xb4 | 0xad | 0xbd | 0xb9 | 0xa1 | 0xb1 => {
self.lda(&AddressingMode::Immediate);
self.program_counter += 1;
}
0xAA => self.tax(),
0xe8 => self.inx(),
0x00 => return,
0xd8 => self.status.remove(CpuFlags::DECIMAL_MODE),
0x58 => self.status.remove(CpuFlags::INTERRUPT_DISABLE),
0xb8 => self.status.remove(CpuFlags::OVERFLOW),
0x18 => self.clear_carry_flag(),
0x38 => self.set_carry_flag(),
0x78 => self.status.insert(CpuFlags::INTERRUPT_DISABLE),
0xf8 => self.status.insert(CpuFlags::DECIMAL_MODE),
0x48 => self.stack_push(self.register_a),
0x68 => {
self.pla();
}
0x08 => {
self.php();
}
0x28 => {
self.plp();
}
0x69 | 0x65 | 0x75 | 0x6d | 0x7d | 0x79 | 0x61 | 0x71 => {
self.adc(&opcode.mod);
}
0xe9 | 0xe5 | 0xf5 | 0xed | 0xfd | 0xf9 | 0xe1 | 0xf1 => {
self.adc(&opcode.mode);
}
0x29 | 0x25 | 0x35 | 0x2d | 0x3d | 0x39 | 0x21 | 0x31 => {
self.and(&opcode.mode);
}
0x49 | 0x45 | 0x55 | 0x4d | 0x5d | 0x41 | 0x51 => {
self.eor(&opcode.mode);
}
0x09 | 0x05 | 0x15 | 0x0d | 0x1d | 0x19 | 0x01 | 0x11 => {
self.ora(&opcode.mode);
}
0x4a => self.lsr_accumulator(),
0x46 | 0x56 | 0x4e | 0x5e => {
self.lsr(&opcode.mode)
}
0x0a => self.asl_accumulator(),
0x06 | 0x16 | 0x0e | 0x1e => {
self.asl(&opcode.mode);
}
0x2a => self.rol_accumulator(),
0x26 | 0x36 | 0x23 | 0x3e => {
self.rol(&opcode.mode);
}
0x6a => self.ror_accumulator(),
0x66 | 0x76 | 0x6e | 0x7e => {
self.ror(&opcode.mode);
}
0xe6 | 0xf6 | 0xee | 0xfe => {
self.inc(&opcode.mode);
}
0xc8 => self.iny(),
0xc6 | 0xd6 | 0xce | 0xde => {
self.dec(&opcode.mode);
}
0xca => self.dex(),
0x88 => self.dey,
0xc9 | 0xc5 | 0xd5 | 0xcd | 0xdd | 0xd9 | 0xc1 | 0xd1 => {
self.compare(&opcode.mode, self.register_a);
}
0xc0 | 0xc4 | 0xcc => {
self.compare(&opcode.mode, self.register_y);
}
0xe0 | 0xe4 | 0xec => self.compare(&opcode, self.register_x),
0x4c => {
let mem_address = self.mem_read_u16(self.program_counter);
self.program_counter = mem_address;
}
0x6c => {
let mem_address = self.mem_read_u16(self.program_counter);
let indirect_ref = if mem_address & 0x00FF == 0x00FF {
let lo = self.mem_read(mem_address);
let hi = self.mem_read(mem_address & 0xFF00);
} else {
self.mem_read_u16(mem_address)
};
self.program_counter = indirect_ref;
}
0x20 => {
self.stack_push_u16(self.program_counter + 2 - 1);
let target_address = self.mem_read_u16(self.program_counter);
self.program_counter = target_address
}
0x60 => {
self.program_counter = self.stack_pop_u16() + 1;
}
0x40 => {
self.status.bits = self.stack_pop();
self.status.remove(CpuFlags::BREAK);
self.status.insert(CpuFlags::BREAK2);
self.program_counter = self.stack_pop_u16();
}
// come back here
0xA5 => {
self.lda(&AddressingMode::ZeroPage);
self.program_counter += 1;
@ -710,7 +857,6 @@ impl CPU { @@ -710,7 +857,6 @@ impl CPU {
// INX stands for Increment Index Register X - increase the value of the X register
// by one and update specific processor flags based on the result.
0xe8 => self.inx(),
0x00 => return,
_ => todo!(),
}
}

1
main.rs

@ -5,6 +5,7 @@ use std::net::SocketAddr; @@ -5,6 +5,7 @@ use std::net::SocketAddr;
use tokio::net::{TcpListener, TcpStream};
use tokio_tungstenite::{accept_async, tungstenite::protocol::Message};
mod cpu;
mod opcodes;
// this file is overly commented because I'm learning Rust while I program. I want just want to
// thnk aloud.
#[tokio::main]

231
opcodes.rs

@ -0,0 +1,231 @@ @@ -0,0 +1,231 @@
use crate::cpu::AddressingMode;
use lazy_static::lazy_static;
use std::collections::HashMap;
pub struct OpCode {
pub code: u8,
pub mnemonic: &'static str,
pub len: u8,
pub cycles: u8,
pub mode: AddressingMode,
}
impl OpCode {
fn new(code: u8, mnemonic: &'static str, len: u8, cycles: u8, mode: AddressingMode) -> Self {
OpCode {
code,
mnemonic,
len,
cycles,
mode,
}
}
}
lazy_static! {
pub static ref CPU_OPS_CODES: Vec<OpCode> = vec![
OpCode::new(0x00, "BRK", 1, 7, AddressingMode::NoneAddressing),
OpCode::new(0xea, "NOP", 1, 2, AddressingMode::NoneAddressing),
/* Arithmetic */
OpCode::new(0x69, "ADC", 2, 2, AddressingMode::Immediate),
OpCode::new(0x65, "ADC", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x75, "ADC", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0x6d, "ADC", 3, 4, AddressingMode::Absolute),
OpCode::new(0x7d, "ADC", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0x79, "ADC", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0x61, "ADC", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0x71, "ADC", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
OpCode::new(0xe9, "SBC", 2, 2, AddressingMode::Immediate),
OpCode::new(0xe5, "SBC", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xf5, "SBC", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0xed, "SBC", 3, 4, AddressingMode::Absolute),
OpCode::new(0xfd, "SBC", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0xf9, "SBC", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0xe1, "SBC", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0xf1, "SBC", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
OpCode::new(0x29, "AND", 2, 2, AddressingMode::Immediate),
OpCode::new(0x25, "AND", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x35, "AND", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0x2d, "AND", 3, 4, AddressingMode::Absolute),
OpCode::new(0x3d, "AND", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0x39, "AND", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0x21, "AND", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0x31, "AND", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
OpCode::new(0x49, "EOR", 2, 2, AddressingMode::Immediate),
OpCode::new(0x45, "EOR", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x55, "EOR", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0x4d, "EOR", 3, 4, AddressingMode::Absolute),
OpCode::new(0x5d, "EOR", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0x59, "EOR", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0x41, "EOR", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0x51, "EOR", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
OpCode::new(0x09, "ORA", 2, 2, AddressingMode::Immediate),
OpCode::new(0x05, "ORA", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x15, "ORA", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0x0d, "ORA", 3, 4, AddressingMode::Absolute),
OpCode::new(0x1d, "ORA", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0x19, "ORA", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0x01, "ORA", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0x11, "ORA", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
/* Shifts */
OpCode::new(0x0a, "ASL", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x06, "ASL", 2, 5, AddressingMode::ZeroPage),
OpCode::new(0x16, "ASL", 2, 6, AddressingMode::ZeroPage_X),
OpCode::new(0x0e, "ASL", 3, 6, AddressingMode::Absolute),
OpCode::new(0x1e, "ASL", 3, 7, AddressingMode::Absolute_X),
OpCode::new(0x4a, "LSR", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x46, "LSR", 2, 5, AddressingMode::ZeroPage),
OpCode::new(0x56, "LSR", 2, 6, AddressingMode::ZeroPage_X),
OpCode::new(0x4e, "LSR", 3, 6, AddressingMode::Absolute),
OpCode::new(0x5e, "LSR", 3, 7, AddressingMode::Absolute_X),
OpCode::new(0x2a, "ROL", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x26, "ROL", 2, 5, AddressingMode::ZeroPage),
OpCode::new(0x36, "ROL", 2, 6, AddressingMode::ZeroPage_X),
OpCode::new(0x2e, "ROL", 3, 6, AddressingMode::Absolute),
OpCode::new(0x3e, "ROL", 3, 7, AddressingMode::Absolute_X),
OpCode::new(0x6a, "ROR", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x66, "ROR", 2, 5, AddressingMode::ZeroPage),
OpCode::new(0x76, "ROR", 2, 6, AddressingMode::ZeroPage_X),
OpCode::new(0x6e, "ROR", 3, 6, AddressingMode::Absolute),
OpCode::new(0x7e, "ROR", 3, 7, AddressingMode::Absolute_X),
OpCode::new(0xe6, "INC", 2, 5, AddressingMode::ZeroPage),
OpCode::new(0xf6, "INC", 2, 6, AddressingMode::ZeroPage_X),
OpCode::new(0xee, "INC", 3, 6, AddressingMode::Absolute),
OpCode::new(0xfe, "INC", 3, 7, AddressingMode::Absolute_X),
OpCode::new(0xe8, "INX", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xc8, "INY", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xc6, "DEC", 2, 5, AddressingMode::ZeroPage),
OpCode::new(0xd6, "DEC", 2, 6, AddressingMode::ZeroPage_X),
OpCode::new(0xce, "DEC", 3, 6, AddressingMode::Absolute),
OpCode::new(0xde, "DEC", 3, 7, AddressingMode::Absolute_X),
OpCode::new(0xca, "DEX", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x88, "DEY", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xc9, "CMP", 2, 2, AddressingMode::Immediate),
OpCode::new(0xc5, "CMP", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xd5, "CMP", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0xcd, "CMP", 3, 4, AddressingMode::Absolute),
OpCode::new(0xdd, "CMP", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0xd9, "CMP", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0xc1, "CMP", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0xd1, "CMP", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
OpCode::new(0xc0, "CPY", 2, 2, AddressingMode::Immediate),
OpCode::new(0xc4, "CPY", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xcc, "CPY", 3, 4, AddressingMode::Absolute),
OpCode::new(0xe0, "CPX", 2, 2, AddressingMode::Immediate),
OpCode::new(0xe4, "CPX", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xec, "CPX", 3, 4, AddressingMode::Absolute),
/* Branching */
OpCode::new(0x4c, "JMP", 3, 3, AddressingMode::NoneAddressing), //AddressingMode that acts as Immidiate
OpCode::new(0x6c, "JMP", 3, 5, AddressingMode::NoneAddressing), //AddressingMode:Indirect with 6502 bug
OpCode::new(0x20, "JSR", 3, 6, AddressingMode::NoneAddressing),
OpCode::new(0x60, "RTS", 1, 6, AddressingMode::NoneAddressing),
OpCode::new(0x40, "RTI", 1, 6, AddressingMode::NoneAddressing),
OpCode::new(0xd0, "BNE", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0x70, "BVS", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0x50, "BVC", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0x30, "BMI", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0xf0, "BEQ", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0xb0, "BCS", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0x90, "BCC", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0x10, "BPL", 2, 2 /*(+1 if branch succeeds +2 if to a new page)*/, AddressingMode::NoneAddressing),
OpCode::new(0x24, "BIT", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x2c, "BIT", 3, 4, AddressingMode::Absolute),
/* Stores, Loads */
OpCode::new(0xa9, "LDA", 2, 2, AddressingMode::Immediate),
OpCode::new(0xa5, "LDA", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xb5, "LDA", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0xad, "LDA", 3, 4, AddressingMode::Absolute),
OpCode::new(0xbd, "LDA", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0xb9, "LDA", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0xa1, "LDA", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0xb1, "LDA", 2, 5/*+1 if page crossed*/, AddressingMode::Indirect_Y),
OpCode::new(0xa2, "LDX", 2, 2, AddressingMode::Immediate),
OpCode::new(0xa6, "LDX", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xb6, "LDX", 2, 4, AddressingMode::ZeroPage_Y),
OpCode::new(0xae, "LDX", 3, 4, AddressingMode::Absolute),
OpCode::new(0xbe, "LDX", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_Y),
OpCode::new(0xa0, "LDY", 2, 2, AddressingMode::Immediate),
OpCode::new(0xa4, "LDY", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0xb4, "LDY", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0xac, "LDY", 3, 4, AddressingMode::Absolute),
OpCode::new(0xbc, "LDY", 3, 4/*+1 if page crossed*/, AddressingMode::Absolute_X),
OpCode::new(0x85, "STA", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x95, "STA", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0x8d, "STA", 3, 4, AddressingMode::Absolute),
OpCode::new(0x9d, "STA", 3, 5, AddressingMode::Absolute_X),
OpCode::new(0x99, "STA", 3, 5, AddressingMode::Absolute_Y),
OpCode::new(0x81, "STA", 2, 6, AddressingMode::Indirect_X),
OpCode::new(0x91, "STA", 2, 6, AddressingMode::Indirect_Y),
OpCode::new(0x86, "STX", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x96, "STX", 2, 4, AddressingMode::ZeroPage_Y),
OpCode::new(0x8e, "STX", 3, 4, AddressingMode::Absolute),
OpCode::new(0x84, "STY", 2, 3, AddressingMode::ZeroPage),
OpCode::new(0x94, "STY", 2, 4, AddressingMode::ZeroPage_X),
OpCode::new(0x8c, "STY", 3, 4, AddressingMode::Absolute),
/* Flags clear */
OpCode::new(0xD8, "CLD", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x58, "CLI", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xb8, "CLV", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x18, "CLC", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x38, "SEC", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x78, "SEI", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xf8, "SED", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xaa, "TAX", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xa8, "TAY", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0xba, "TSX", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x8a, "TXA", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x9a, "TXS", 1, 2, AddressingMode::NoneAddressing),
OpCode::new(0x98, "TYA", 1, 2, AddressingMode::NoneAddressing),
/* Stack */
OpCode::new(0x48, "PHA", 1, 3, AddressingMode::NoneAddressing),
OpCode::new(0x68, "PLA", 1, 4, AddressingMode::NoneAddressing),
OpCode::new(0x08, "PHP", 1, 3, AddressingMode::NoneAddressing),
OpCode::new(0x28, "PLP", 1, 4, AddressingMode::NoneAddressing),
];
pub static ref OPCODES_MAP: HashMap<u8, &'static OpCode> = {
let mut map = HashMap::new();
for cpuop in &*CPU_OPS_CODES {
map.insert(cpuop.code, cpuop);
}
map
};
}
Loading…
Cancel
Save