more decode and encode code

This commit is contained in:
Trevor Merritt 2025-06-23 15:35:36 -04:00
parent 87ae4e7890
commit 768e83dfb8
19 changed files with 1281 additions and 786 deletions

223
Cargo.lock generated
View File

@ -17,6 +17,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "anstream"
version = "0.6.19"
@ -67,12 +73,36 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bytemuck"
version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.1"
@ -130,6 +160,12 @@ dependencies = [
"trevors_utilities",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.4"
@ -165,6 +201,12 @@ dependencies = [
"termcolor",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.13"
@ -181,6 +223,15 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fdeflate"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
dependencies = [
"simd-adler32",
]
[[package]]
name = "flate2"
version = "1.1.2"
@ -191,6 +242,22 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "fontdue"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e57e16b3fe8ff4364c0661fdaac543fb38b29ea9bc9c2f45612d90adf931d2b"
dependencies = [
"hashbrown",
"ttf-parser",
]
[[package]]
name = "getrandom"
version = "0.3.3"
@ -203,6 +270,23 @@ dependencies = [
"wasi",
]
[[package]]
name = "glam"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
[[package]]
name = "hashbrown"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
[[package]]
name = "heck"
version = "0.5.0"
@ -221,6 +305,19 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f"
[[package]]
name = "image"
version = "0.24.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"num-traits",
"png",
]
[[package]]
name = "is-terminal"
version = "0.4.16"
@ -259,6 +356,38 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "macroquad"
version = "0.1.0"
dependencies = [
"macroquad 0.4.14",
]
[[package]]
name = "macroquad"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2befbae373456143ef55aa93a73594d080adfb111dc32ec96a1123a3e4ff4ae"
dependencies = [
"fontdue",
"glam",
"image",
"macroquad_macro",
"miniquad",
"quad-rand",
]
[[package]]
name = "macroquad_macro"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64b1d96218903768c1ce078b657c0d5965465c95a60d2682fd97443c9d2483dd"
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
@ -266,6 +395,18 @@ version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "miniquad"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fb3e758e46dbc45716a8a49ca9edc54b15bcca826277e80b1f690708f67f9e3"
dependencies = [
"libc",
"ndk-sys",
"objc-rs",
"winapi",
]
[[package]]
name = "miniz_oxide"
version = "0.8.9"
@ -273,6 +414,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
name = "ndk-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "objc-rs"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a1e7069a2525126bf12a9f1f7916835fafade384fb27cabf698e745e2a1eb8"
dependencies = [
"malloc_buf",
]
[[package]]
@ -287,6 +453,19 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "png"
version = "0.17.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]]
name = "pretty_env_logger"
version = "0.5.0"
@ -306,6 +485,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quad-rand"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a651516ddc9168ebd67b24afd085a718be02f8858fe406591b013d101ce2f40"
[[package]]
name = "quote"
version = "1.0.40"
@ -356,13 +541,19 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags",
"bitflags 2.9.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "strsim"
version = "0.11.1"
@ -412,6 +603,12 @@ dependencies = [
"tempfile",
]
[[package]]
name = "ttf-parser"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
[[package]]
name = "unicode-ident"
version = "1.0.18"
@ -433,6 +630,22 @@ dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.9"
@ -442,6 +655,12 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.59.0"
@ -594,5 +813,5 @@ version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
"bitflags 2.9.1",
]

View File

@ -8,6 +8,7 @@ pub enum AddressMode {
Immediate(u8),
ZeroPage(u8),
ZeroPageX(u8),
ZeroPageY(u8),
Absolute(u16),
AbsoluteX(u16),
AbsoluteY(u16),

View File

@ -1,4 +1,5 @@
// Instruction OP Codes
/// Instruction OP Codes
/// ADC
pub const ISA_OP_ADC_I: u8 = 0x69;
@ -18,53 +19,39 @@ pub const ISA_OP_AND_ABSX: u8 = 0x3d;
pub const ISA_OP_AND_ABSY: u8 = 0x39;
pub const ISA_OP_AND_INDX: u8 = 0x21;
pub const ISA_OP_AND_INDY: u8 = 0x31;
/// ASL
pub const ISA_OP_ASL_A: u8 = 0x0a;
pub const ISA_OP_ASL_Z: u8 = 0x06;
pub const ISA_OP_ASL_ZX: u8 = 0x16;
pub const ISA_OP_ASL_ABS: u8 = 0x0e;
pub const ISA_OP_ASL_ABSX: u8 = 0x1e;
/// BCC
pub const ISA_OP_BCC: u8 = 0x90;
/// BCS
pub const ISA_OP_BCS: u8 = 0xb0;
/// BEQ
pub const ISA_OP_BEQ: u8 = 0xf0;
/// BIT
pub const ISA_OP_BIT_ZP: u8 = 0x24;
pub const ISA_OP_BIT_ABS: u8 = 0x2c;
/// BMI
pub const ISA_OP_BMI: u8 = 0x30;
/// BNE
pub const ISA_OP_BNE: u8 = 0xd0;
/// BPL
pub const ISA_OP_BPL: u8 = 0x10;
/// BRK
pub const ISA_OP_BRK: u8 = 0x00;
/// BVC
pub const ISA_OP_BVC: u8 = 0x50;
/// BVS
pub const ISA_OP_BVS: u8 = 0x70;
pub const ISA_OP_CLC: u8 = 0x18;
pub const ISA_OP_CLD: u8 = 0xd8;
pub const ISA_OP_CLI: u8 = 0x58;
pub const ISA_OP_CLV: u8 = 0xb8;
pub const ISA_OP_CMP_I: u8 = 0xc9;
pub const ISA_OP_CMP_ZP: u8 = 0xc5;
pub const ISA_OP_CMP_ZPX: u8 = 0xd5;
@ -72,24 +59,18 @@ pub const ISA_OP_CMP_ABS: u8 = 0xcd;
pub const ISA_OP_CMP_ABSX: u8 = 0xdd;
pub const ISA_OP_CMP_INDX: u8 = 0xc1;
pub const ISA_OP_CMP_INDY: u8 = 0xd1;
pub const ISA_OP_CPX_I: u8 = 0xe0;
pub const ISA_OP_CPX_ZP: u8 = 0xe4;
pub const ISA_OP_CPX_ABS: u8 = 0xec;
pub const ISA_OP_CPY_I: u8 = 0xc0;
pub const ISA_OP_CPY_ZP: u8 = 0xc4;
pub const ISA_OP_CPY_ABS: u8 = 0xcc;
pub const ISA_OP_DEC_ZP: u8 = 0xc6;
pub const ISA_OP_DEC_ZPX: u8 = 0xd6;
pub const ISA_OP_DEC_ABS: u8 = 0xce;
pub const ISA_OP_DEC_ABSX: u8 = 0xde;
pub const ISA_OP_DEX: u8 = 0xca;
pub const ISA_OP_DEY: u8 = 0x88;
pub const ISA_OP_EOR_I: u8 = 0x49;
pub const ISA_OP_EOR_ZP: u8 = 0x45;
pub const ISA_OP_EOR_ZPX: u8 = 0x55;
@ -98,22 +79,15 @@ pub const ISA_OP_EOR_ABSX: u8 = 0x5d;
pub const ISA_OP_EOR_ABSY: u8 = 0x59;
pub const ISA_OP_EOR_INDX: u8 = 0x41;
pub const ISA_OP_EOR_INDY: u8 = 0x51;
pub const ISA_OP_INC_ZP: u8 = 0xe6;
pub const ISA_OP_INC_ZPX: u8 = 0xf6;
pub const ISA_OP_INC_ABS: u8 = 0xee;
pub const ISA_OP_INC_ABSX: u8 = 0xfe;
pub const ISA_OP_INX: u8 = 0xe8;
pub const ISA_OP_INY: u8 = 0xc8;
pub const ISA_OP_JMP_ABS: u8 = 0x4c;
pub const ISA_OP_JMP_IND: u8 = 0x6c;
pub const ISA_OP_JSR: u8 = 0x20;
pub const ISA_OP_LDA_I: u8 = 0xA9;
pub const ISA_OP_LDA_Z: u8 = 0xA5;
pub const ISA_OP_LDA_ZX: u8 = 0xB5;
@ -122,26 +96,23 @@ pub const IAS_OP_LDA_ABSX: u8 = 0xBD;
pub const ISA_OP_LDA_ABSY: u8 = 0xB9;
pub const ISA_OP_LDA_INDX: u8 = 0xA1;
pub const ISA_OP_LDA_INDY: u8 = 0xB1;
pub const ISA_OP_LDX_I: u8 = 0xa2;
pub const ISA_OP_LDX_ZP: u8 = 0xa6;
pub const ISA_OP_LDX_ZPY: u8 = 0x86;
pub const ISA_OP_LDX_ABS: u8 = 0xae;
pub const ISA_OP_LDX_ABSY: u8 = 0xbe;
pub const ISA_OP_LDY_I: u8 = 0xa0;
pub const ISA_OP_LDY_ZP: u8 = 0xa4;
pub const ISA_OP_LDY_ZPX: u8 = 0xb4;
pub const ISA_OP_LDY_ABS: u8 = 0xac;
pub const ISA_OP_LDY_ABSX: u8 = 0xac;
pub const ISA_OP_LDY_ABSX: u8 = 0xbc;
pub const ISA_OP_LSR_A: u8 = 0x4a;
pub const ISA_OP_LSR_ZP: u8 = 0x46;
pub const ISA_OP_LSR_ZPX: u8 = 0x56;
pub const ISA_OP_LSR_ABS: u8 = 0x4e;
pub const ISA_OP_LSR_ABSX: u8 = 0x5e;
pub const ISA_OP_NOP: u8 = 0xEA;
pub const ISA_OP_ORA_I: u8 = 0x09;
pub const ISA_OP_ORA_ZP: u8 = 0x05;
pub const ISA_OP_ORA_ZPX: u8 = 0x15;
@ -150,24 +121,15 @@ pub const ISA_OP_ORA_ABSX: u8 = 0x1d;
pub const ISA_OP_ORA_ABSY: u8 = 0x19;
pub const ISA_OP_ORA_INDX: u8 = 0x01;
pub const ISA_OP_ORA_INDY: u8 = 0x11;
pub const ISA_OP_PHA: u8 = 0x48;
pub const ISA_OP_PHP: u8 = 0x08;
///
pub const ISA_OP_PLA: u8 = 0x68;
///
pub const ISA_OP_PLP: u8 = 0x28;
///
///
pub const ISA_OP_ROL_A: u8 = 0x2a;
pub const ISA_OP_ROL_ZP: u8 = 0x26;
pub const ISA_OP_ROL_ZPX: u8 = 0x36;
pub const ISA_OP_ROL_ABS: u8 = 0x2e;
pub const ISA_OP_ROL_ABSX: u8 = 0x3e;
///
pub const ISA_OP_ROR_A: u8 = 0x6a;
pub const ISA_OP_ROR_ZP: u8 = 0x66;
pub const ISA_OP_ROR_ZPX: u8 = 0x76;
@ -204,4 +166,4 @@ pub const ISA_OP_TAY: u8 = 0xa8;
pub const ISA_OP_TSX: u8 = 0xba;
pub const ISA_OP_TXA: u8 = 0x8a;
pub const ISA_OP_TXS: u8 = 0x9a;
pub const ISA_OP_TYA: u8 = 0x98;
pub const ISA_OP_TYA: u8 = 0x98;

View File

@ -0,0 +1,57 @@
/// STUB Parts
pub const ISA_STUB_ADC: &str = "ADC";
pub const ISA_STUB_AND: &str = "AND";
pub const ISA_STUB_ASL: &str = "ASL";
pub const ISA_STUB_BCC: &str = "BCC";
pub const ISA_STUB_BCS: &str = "BCS";
pub const ISA_STUB_BEQ: &str = "BEQ";
pub const ISA_STUB_BIT: &str = "BIT";
pub const ISA_STUB_BMI: &str = "BMI";
pub const ISA_STUB_BNE: &str = "BNE";
pub const ISA_STUB_BPL: &str = "BPL";
pub const ISA_STUB_BRK: &str = "BRK";
pub const ISA_STUB_BVC: &str = "BVC";
pub const ISA_STUB_BVS: &str = "BVS";
pub const ISA_STUB_CLC: &str = "CLC";
pub const ISA_STUB_CLD: &str = "CLD";
pub const ISA_STUB_CLI: &str = "CLI";
pub const ISA_STUB_CLV: &str = "CLV";
pub const ISA_STUB_CMP: &str = "CMP";
pub const ISA_STUB_CPX: &str = "CPX";
pub const ISA_STUB_CPY: &str = "CPY";
pub const ISA_STUB_DEC: &str = "DEC";
pub const ISA_STUB_DEX: &str = "DEX";
pub const ISA_STUB_DEY: &str = "DEY";
pub const ISA_STUB_EOR: &str = "EOR";
pub const ISA_STUB_INC: &str = "INC";
pub const ISA_STUB_INX: &str = "INX";
pub const ISA_STUB_INY: &str = "INY";
pub const ISA_STUB_JMP: &str = "JMP";
pub const ISA_STUB_JSR: &str = "JSR";
pub const ISA_STUB_LDA: &str = "LDA";
pub const ISA_STUB_LDX: &str = "LDX";
pub const ISA_STUB_LDY: &str = "LDY";
pub const ISA_STUB_LSR: &str = "LSR";
pub const ISA_STUB_NOP: &str = "NOP";
pub const ISA_STUB_ORA: &str = "ORA";
pub const ISA_STUB_PHA: &str = "PHA";
pub const ISA_STUB_PHP: &str = "PHP";
pub const ISA_STUB_PLA: &str = "PLA";
pub const ISA_STUB_PLP: &str = "PLP";
pub const ISA_STUB_ROL: &str = "ROL";
pub const ISA_STUB_ROR: &str = "ROR";
pub const ISA_STUB_RTI: &str = "RTI";
pub const ISA_STUB_RTS: &str = "RTS";
pub const ISA_STUB_SBC: &str = "SBC";
pub const ISA_STUB_SEC: &str = "SEC";
pub const ISA_STUB_SED: &str = "SED";
pub const ISA_STUB_SEI: &str = "SEI";
pub const ISA_STUB_STA: &str = "STA";
pub const ISA_STUB_STX: &str = "STX";
pub const ISA_STUB_STY: &str = "STY";
pub const ISA_STUB_TAX: &str = "TAX";
pub const ISA_STUB_TAY: &str = "TAY";
pub const ISA_STUB_TSX: &str = "TSX";
pub const ISA_STUB_TXA: &str = "TXA";
pub const ISA_STUB_TXS: &str = "TXS";
pub const ISA_STUB_TYA: &str = "TYA";

View File

@ -0,0 +1,2 @@
pub mod constants_isa_stub;
pub mod constants_isa_op;

View File

@ -0,0 +1,285 @@
use log::debug;
use crate::address_mode::AddressMode;
use crate::instruction::Instruction;
use crate::mos6502cpu::Mos6502Cpu;
use crate::mos6502flags::Mos6502Flag::{Carry, Decimal, Interrupt, Overflow};
impl Instruction {
fn execute(&self, mut system: Mos6502Cpu) {
match self {
// ADC Add with Carry
// A,Z,C,N = A+M+C
//
// This instruction adds the contents of a memory location to the accumulator together with the carry bit. If overflow occurs the carry bit is set, this enables multiple byte addition to be performed.
//
// Processor Status after use:
//
// C Carry Flag Set if overflow in bit 7
// Z Zero Flag Set if A = 0
// I Interrupt Disable Not affected
// D Decimal Mode Flag Not affected
// B Break Command Not affected
// V Overflow Flag Set if sign bit is incorrect
// N Negative Flag Set if bit 7 set
Instruction::ADC(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::AND(address) => {
match address {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {
// NOOP
}
}
}
Instruction::ASL(mode) => {
match mode {
// ISA_OP_ASL_A
AddressMode::Accumulator => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
_ => {}
}
}
Instruction::BCC(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BCS(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BEQ(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BIT(mode) => {
match mode {
AddressMode::ZeroPage(value) => {}
AddressMode::Absolute(value) => {}
_ => {}
}
}
Instruction::BMI(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BNE(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BPL(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BRK => {}
Instruction::BVC(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BVS(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::CLC => {
system.poke_flag(Carry, false)
}
Instruction::CLD => {
system.poke_flag(Decimal, false)
}
Instruction::CLI => {
system.poke_flag(Interrupt, false)
}
Instruction::CLV => {
system.poke_flag(Overflow, false)
}
Instruction::CMP(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::CPX(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::CPY(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::DEC(mode) => {
match mode {
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
_ => {}
}
}
Instruction::DEX => {
let mut x = system.peek_x();
x -= 1;
system.poke_x(x);
}
Instruction::DEY => {
let mut y = system.peek_y();
y -= 1;
system.poke_y(y);
}
Instruction::EOR(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::INC(mode) => {
match mode {
AddressMode::ZeroPage(value) => {}
AddressMode::ZeroPageX(value) => {}
AddressMode::Absolute(value) => {}
AddressMode::AbsoluteX(value) => {}
_ => {}
}
}
Instruction::INX => {
let mut x = system.peek_x();
x += 1;
system.poke_x(x);
}
Instruction::INY => {
let mut y = system.peek_y();
y += 1;
system.poke_y(y);
}
Instruction::JMP(mode) => {
match mode {
AddressMode::Absolute(_) => {}
AddressMode::IndirectX(_) => {}
_ => {}
}
}
Instruction::JSR(mode) => {
match mode {
AddressMode::Absolute(address) => {}
_ => {}
}
}
Instruction::LDA(mode) => {
match mode {
AddressMode::Immediate(value) => {
system.poke_a(*value)
}
AddressMode::ZeroPage(offset) => {
let value_to_write = system.peek(*offset as u16);
system.poke_a(value_to_write);
}
AddressMode::ZeroPageX(_) => {
let current_x = system.peek_x();
}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {
debug!("Invalid LDA instruction");
}
};
}
Instruction::LDX(_) => {}
Instruction::LDY(_) => {}
Instruction::LSR(_) => {}
Instruction::NOP => {}
Instruction::ORA(_) => {}
Instruction::PHA => {}
Instruction::PHP => {}
Instruction::PLA => {}
Instruction::PLP => {}
Instruction::ROL(_) => {}
Instruction::ROR(_) => {}
Instruction::RTI => {}
Instruction::RTS => {}
Instruction::SBC(_) => {}
Instruction::SEC => {}
Instruction::SED => {}
Instruction::SEI => {}
Instruction::STA(_) => {}
Instruction::STX(_) => {}
Instruction::STY(_) => {}
Instruction::TAX => {}
Instruction::TAY => {}
Instruction::TSX => {}
Instruction::TXA => {}
Instruction::TXS => {}
Instruction::TYA => {}
};
}
}

View File

@ -0,0 +1,183 @@
use crate::address_mode::AddressMode::{Absolute, AbsoluteX, AbsoluteY, Accumulator, Immediate, Implied, IndirectX, IndirectY, ZeroPage, ZeroPageX, ZeroPageY};
use crate::constants::constants_isa_op::*;
use crate::instruction::Instruction;
use crate::instruction::Instruction::*;
fn join_word(low: u8, high: u8) -> u16 {
((high as u16) << 8) & low as u16
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_join_word() {
let low: u8 = 0xcd;
let high: u8 = 0xab;
assert_eq!(
join_word(low, high),
0xabcd
);
}
}
impl Instruction {
pub fn from_bytes(decode_from: Vec<u8>) -> Instruction {
let id_byte = decode_from[0];
match id_byte {
/// ADC
ISA_OP_ADC_I..=ISA_OP_ADC_I => ADC(Immediate(decode_from[1])),
ISA_OP_ADC_Z..=ISA_OP_ADC_Z => ADC(ZeroPage(decode_from[1])),
ISA_OP_ADC_ZX..=ISA_OP_ADC_ZX => ADC(ZeroPageX(decode_from[1])),
ISA_OP_ADC_ABS..=ISA_OP_ADC_ABS => ADC(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_ADC_ABSX..=ISA_OP_ADC_ABSX => ADC(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_ADC_ABSY..=ISA_OP_ADC_ABSY => ADC(AbsoluteY(join_word(decode_from[1], decode_from[2]))),
ISA_OP_ADC_INDX..=ISA_OP_ADC_INDX => ADC(IndirectX(decode_from[1])),
ISA_OP_ADC_INDY..=ISA_OP_ADC_INDY => ADC(IndirectY(decode_from[1])),
ISA_OP_AND_I..=ISA_OP_AND_I => AND(Immediate(decode_from[1])),
ISA_OP_AND_Z..=ISA_OP_AND_Z => AND(ZeroPage(decode_from[1])),
ISA_OP_AND_ZX..=ISA_OP_AND_ZX => AND(ZeroPageX(decode_from[1])),
ISA_OP_AND_ABS..=ISA_OP_AND_ABS => AND(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_AND_ABSX..=ISA_OP_AND_ABSX => AND(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_AND_ABSY..=ISA_OP_AND_ABSY => AND(AbsoluteY(join_word(decode_from[1], decode_from[2]))),
ISA_OP_AND_INDX..=ISA_OP_AND_INDX => AND(IndirectX(decode_from[1])),
ISA_OP_AND_INDY..=ISA_OP_AND_INDY => AND(IndirectY(decode_from[1])),
ISA_OP_ASL_A..=ISA_OP_ASL_A => ASL(Accumulator),
ISA_OP_ASL_Z..=ISA_OP_ASL_Z => ASL(ZeroPage(decode_from[1])),
ISA_OP_ASL_ZX..=ISA_OP_ASL_ZX => ASL(ZeroPageX(decode_from[1])),
ISA_OP_ASL_ABS..=ISA_OP_ASL_ABS => ASL(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_ASL_ABSX..=ISA_OP_ASL_ABSX => ASL(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_BCC..=ISA_OP_BCC => BCC(Immediate(decode_from[1])),
ISA_OP_BCS..=ISA_OP_BCS => BCS(Immediate(decode_from[1])),
ISA_OP_BEQ..=ISA_OP_BEQ => BEQ(Immediate(decode_from[1])),
ISA_OP_BIT_ZP..=ISA_OP_BIT_ZP => BIT(ZeroPage(decode_from[1])),
ISA_OP_BIT_ABS..=ISA_OP_BIT_ABS => BIT(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_BMI..=ISA_OP_BMI => BMI(Immediate(decode_from[1])),
ISA_OP_BNE..=ISA_OP_BNE => BNE(Immediate(decode_from[1])),
ISA_OP_BPL..=ISA_OP_BPL => BPL(Immediate(decode_from[1])),
ISA_OP_BRK..=ISA_OP_BRK => BRK,
ISA_OP_BVC..=ISA_OP_BVC => BVC(Immediate(decode_from[1])),
ISA_OP_BVS..=ISA_OP_BVS => BVS(Immediate(decode_from[1])),
ISA_OP_CLC..=ISA_OP_CLC => CLC,
ISA_OP_CLD..=ISA_OP_CLD => CLD,
ISA_OP_CLI..=ISA_OP_CLI => CLI,
ISA_OP_CLV..=ISA_OP_CLV => CLV,
ISA_OP_CMP_I..=ISA_OP_CMP_I => CMP(Immediate(decode_from[1])),
ISA_OP_CMP_ZP..=ISA_OP_CMP_ZP => CMP(ZeroPage(decode_from[1])),
ISA_OP_CMP_ZPX..=ISA_OP_CMP_ZPX => CMP(ZeroPageX(decode_from[1])),
ISA_OP_CMP_ABS..=ISA_OP_CMP_ABS => CMP(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_CMP_ABSX..=ISA_OP_CMP_ABSX => CMP(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_CMP_INDX..=ISA_OP_CMP_INDX => CMP(IndirectX(decode_from[1])),
ISA_OP_CMP_INDY..=ISA_OP_CMP_INDY => CMP(IndirectY(decode_from[1])),
ISA_OP_CPX_I..=ISA_OP_CPX_I => CPX(Immediate(decode_from[1])),
ISA_OP_CPX_ZP..=ISA_OP_CPX_ZP => CPX(ZeroPage(decode_from[1])),
ISA_OP_CPX_ABS..=ISA_OP_CPX_ABS => CPX(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_CPY_I..=ISA_OP_CPY_I => CPY(Immediate(decode_from[1])),
ISA_OP_CPY_ZP..=ISA_OP_CPY_ZP => CPY(ZeroPage(decode_from[1])),
ISA_OP_CPY_ABS..=ISA_OP_CPY_ABS => CPY(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_DEC_ZP..=ISA_OP_DEC_ZP => DEC(ZeroPage(decode_from[1])),
ISA_OP_DEC_ZPX..=ISA_OP_DEC_ZPX => DEC(ZeroPageX(decode_from[1])),
ISA_OP_DEX..=ISA_OP_DEX => DEX,
ISA_OP_DEY..=ISA_OP_DEY => DEY,
ISA_OP_EOR_I..=ISA_OP_EOR_I => EOR(Immediate(decode_from[1])),
ISA_OP_EOR_ZP..=ISA_OP_EOR_ZP => EOR(ZeroPage(decode_from[1])),
ISA_OP_EOR_ZPX..=ISA_OP_EOR_ZPX => EOR(ZeroPageX(decode_from[1])),
ISA_OP_EOR_ABS..=ISA_OP_EOR_ABS => EOR(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_EOR_ABSX..=ISA_OP_EOR_ABSX => EOR(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_EOR_ABSY..=ISA_OP_EOR_ABSY => EOR(AbsoluteY(join_word(decode_from[1], decode_from[2]))),
ISA_OP_EOR_INDX..=ISA_OP_EOR_INDX => EOR(IndirectX(decode_from[1])),
ISA_OP_EOR_INDY..=ISA_OP_EOR_INDY => EOR(IndirectY(decode_from[1])),
ISA_OP_INC_ZP..=ISA_OP_INC_ZP => INC(ZeroPage(decode_from[1])),
ISA_OP_INC_ZPX..=ISA_OP_INC_ZPX => INC(ZeroPageX(decode_from[1])),
ISA_OP_INC_ABS..=ISA_OP_INC_ABS => INC(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_INC_ABSX..=ISA_OP_INC_ABSX => INC(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_INX..=ISA_OP_INX => INX,
ISA_OP_INY..=ISA_OP_INY => INY,
ISA_OP_JMP_ABS..=ISA_OP_JMP_ABS => JMP(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_JMP_IND..=ISA_OP_JMP_IND => JMP(IndirectX(decode_from[1])),
ISA_OP_JSR..=ISA_OP_JSR => JSR(Immediate(decode_from[1])),
ISA_OP_LDA_I..=ISA_OP_LDA_I => LDA(Immediate(decode_from[1])),
ISA_OP_LDA_Z..=ISA_OP_LDA_Z => LDA(ZeroPage(decode_from[1])),
ISA_OP_LDA_ZX..=ISA_OP_LDA_ZX => LDA(ZeroPageX(decode_from[1])),
ISA_OP_LDA_ABS..=ISA_OP_LDA_ABS => LDA(Absolute(join_word(decode_from[1], decode_from[2]))),
IAS_OP_LDA_ABSX..=IAS_OP_LDA_ABSX => LDA(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LDA_ABSY..=ISA_OP_LDA_ABSY => LDA(AbsoluteY(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LDA_INDX..=ISA_OP_LDA_INDX => LDA(IndirectX(decode_from[1])),
ISA_OP_LDA_INDY..=ISA_OP_LDA_INDY => LDA(IndirectY(decode_from[1])),
ISA_OP_LDX_I..=ISA_OP_LDX_I => LDX(Immediate(decode_from[1])),
ISA_OP_LDX_ZP..=ISA_OP_LDX_ZP => LDX(ZeroPage(decode_from[1])),
ISA_OP_LDX_ZPY..=ISA_OP_LDX_ZPY => LDX(ZeroPageY(decode_from[1])),
ISA_OP_LDX_ABS..=ISA_OP_LDX_ABS => LDX(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LDX_ABSY..=ISA_OP_LDX_ABSY => LDX(AbsoluteY(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LDY_I..=ISA_OP_LDY_I => LDY(Immediate(decode_from[1])),
ISA_OP_LDY_ZP..=ISA_OP_LDY_ZP => LDY(ZeroPage(decode_from[1])),
ISA_OP_LDY_ZPX..=ISA_OP_LDY_ZPX => LDY(ZeroPageX(decode_from[1])),
ISA_OP_LDY_ABS..=ISA_OP_LDY_ABS => LDY(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LDY_ABSX..=ISA_OP_LDY_ABSX => LDY(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LSR_A..=ISA_OP_LSR_A => LSR(Accumulator),
ISA_OP_LSR_ZP..=ISA_OP_LSR_ZP => LSR(ZeroPage(decode_from[1])),
ISA_OP_LSR_ZPX..=ISA_OP_LSR_ZPX => LSR(ZeroPageX(decode_from[1])),
ISA_OP_LSR_ABS..=ISA_OP_LSR_ABS => LSR(Absolute(join_word(decode_from[1], decode_from[2]))),
ISA_OP_LSR_ABSX..=ISA_OP_LSR_ABSX => LSR(AbsoluteX(join_word(decode_from[1], decode_from[2]))),
ISA_OP_NOP..=ISA_OP_NOP => NOP,
// ISA_OP_ORA_I..=ISA_OP_ORA_I => {}
// ISA_OP_ORA_ZP..=ISA_OP_ORA_ZP => {}
// ISA_OP_ORA_ZPX..=ISA_OP_ORA_ZPX => {}
// ISA_OP_ORA_ABS..=ISA_OP_ORA_ABS => {}
// ISA_OP_ORA_ABSX..=ISA_OP_ORA_ABSX => {}
// ISA_OP_ORA_ABSY..=ISA_OP_ORA_ABSY => {}
// ISA_OP_ORA_INDX..=ISA_OP_ORA_INDX => {}
// ISA_OP_ORA_INDY..=ISA_OP_ORA_INDY => {}
// ISA_OP_PHA..=ISA_OP_PHA => {}
// ISA_OP_PHP..=ISA_OP_PHP => {}
// ISA_OP_PLA..=ISA_OP_PLA => {}
// ISA_OP_PLP..=ISA_OP_PLP => {}
// ISA_OP_ROL_A..=ISA_OP_ROL_A => {}
// ISA_OP_ROL_ZP..=ISA_OP_ROL_ZP => {}
// ISA_OP_ROL_ZPX..=ISA_OP_ROL_ZPX => {}
// ISA_OP_ROL_ABS..=ISA_OP_ROL_ABS => {}
// ISA_OP_ROL_ABSX..=ISA_OP_ROL_ABSX => {}
// ISA_OP_ROR_A..=ISA_OP_ROR_A => {}
// ISA_OP_ROR_ZP..=ISA_OP_ROR_ZP => {}
// ISA_OP_ROR_ZPX..=ISA_OP_ROR_ZPX => {}
// ISA_OP_ROR_ABS..=ISA_OP_ROR_ABS => {}
// ISA_OP_ROR_ABSX..=ISA_OP_ROR_ABSX => {}
// ISA_OP_RTI..=ISA_OP_RTI => {}
// ISA_OP_RTS..=ISA_OP_RTS => {}
// ISA_OP_SBC_I..=ISA_OP_SBC_I => {}
// ISA_OP_SBC_ZP..=ISA_OP_SBC_ZP => {}
// ISA_OP_SBC_ZPX..=ISA_OP_SBC_ZPX => {}
// ISA_OP_SBC_ABS..=ISA_OP_SBC_ABS => {}
// ISA_OP_SBC_ABSX..=ISA_OP_SBC_ABSX => {}
// ISA_OP_SBC_ABSY..=ISA_OP_SBC_ABSY => {}
// ISA_OP_SBC_INDX..=ISA_OP_SBC_INDX => {}
// ISA_OP_SBC_INDY..=ISA_OP_SBC_INDY => {}
// ISA_OP_SEC..=ISA_OP_SEC => {}
// ISA_OP_SED..=ISA_OP_SED => {}
// ISA_OP_SEI..=ISA_OP_SEI => {}
// ISA_OP_STA_ZP..=ISA_OP_STA_ZP => {}
// ISA_OP_STA_ZPX..=ISA_OP_STA_ZPX => {}
// ISA_OP_STA_ABS..=ISA_OP_STA_ABS => {}
// ISA_OP_STA_ABSX..=ISA_OP_STA_ABSX => {}
// ISA_OP_STA_ABSY..=ISA_OP_STA_ABSY => {}
// ISA_OP_STA_INDX..=ISA_OP_STA_INDX => {}
// ISA_OP_STA_INDY..=ISA_OP_STA_INDY => {}
// ISA_OP_STX_ZP..=ISA_OP_STX_ZP => {}
// ISA_OP_STX_ZPX..=ISA_OP_STX_ZPX => {}
// ISA_OP_STX_ABS..=ISA_OP_STX_ABS => {}
// ISA_OP_STY_ZP..=ISA_OP_STY_ZP => {}
// ISA_OP_STY_ZPX..=ISA_OP_STY_ZPX => {}
// ISA_OP_STY_ABS..=ISA_OP_STY_ABS => {}
// ISA_OP_TAX..=ISA_OP_TAX => {}
// ISA_OP_TAY..=ISA_OP_TAY => {}
// ISA_OP_TSX..=ISA_OP_TSX => {}
// ISA_OP_TXA..=ISA_OP_TXA => {}
// ISA_OP_TXS..=ISA_OP_TXS => {}
// ISA_OP_TYA..=ISA_OP_TYA => {}
_ => NOP
}
}
}

View File

@ -1,15 +1,14 @@
use std::fmt::format;
use log::debug;
use crate::address_mode::AddressMode;
use crate::address_mode::AddressMode::*;
use crate::constants::*;
use crate::instruction::Instruction::*;
use crate::instruction_stringify::InstructionStringify;
use crate::isa::microcode_steps::MicrocodeStep;
use crate::isa::microcode_steps::MicrocodeStep::{ALUAddC, ReadRegisterA};
use crate::mos6502cpu::Mos6502Cpu;
use crate::mos6502flags::Mos6502Flag::*;
mod from_bytes;
mod to_bytes;
mod execute;
mod stub;
mod to_string;
#[derive(PartialEq, Debug)]
pub enum Instruction {
/// ADC Add with Carry
@ -1020,694 +1019,6 @@ pub enum Instruction {
TYA,
}
impl Instruction {
pub fn from_bytes(decode_from: Vec<u8>) -> Instruction {
let id_byte = decode_from[0];
match id_byte {
/// ADC
ISA_OP_ADC_I..=ISA_OP_ADC_I => {
if decode_from.len() == 2 {
ADC(Immediate(decode_from[1]))
} else {
NOP
}
}
ISA_OP_ADC_Z..=ISA_OP_ADC_Z => {
ADC(ZeroPage(decode_from[1]))
}
ISA_OP_ADC_ZX..=ISA_OP_ADC_ZX => {
ADC(ZeroPageX(decode_from[1]))
}
ISA_OP_ADC_ABS..=ISA_OP_ADC_ABS => {
// build the u16 from the u8[1] and u8[2]
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
ADC(Absolute(word))
}
ISA_OP_ADC_ABSX..=ISA_OP_ADC_ABSX => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
ADC(AbsoluteX(word))
}
ISA_OP_ADC_ABSY..=ISA_OP_ADC_ABSY => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
ADC(AbsoluteY(word))
}
ISA_OP_ADC_INDX..=ISA_OP_ADC_INDX => {
ADC(IndirectX(decode_from[1]))
}
ISA_OP_ADC_INDY..=ISA_OP_ADC_INDY => {
ADC(IndirectY(decode_from[1]))
}
/// AND
ISA_OP_AND_I..=ISA_OP_AND_I => {
AND(Immediate(decode_from[1]))
}
ISA_OP_AND_Z..=ISA_OP_AND_Z => {
AND(ZeroPage(decode_from[1]))
}
ISA_OP_AND_ZX..=ISA_OP_AND_ZX => {
AND(ZeroPageX(decode_from[1]))
}
ISA_OP_AND_ABS..=ISA_OP_AND_ABS => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
AND(Absolute(word))
}
ISA_OP_AND_ABSX..=ISA_OP_AND_ABSX => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
AND(AbsoluteX(word))
}
ISA_OP_AND_ABSY..=ISA_OP_AND_ABSY => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
AND(AbsoluteY(word))
}
ISA_OP_AND_INDX..=ISA_OP_AND_INDX => {
AND(IndirectX(decode_from[1]))
}
ISA_OP_AND_INDY..=ISA_OP_AND_INDY => {
AND(IndirectY(decode_from[1]))
}
ISA_OP_ASL_A..=ISA_OP_ASL_A => {
ASL(Accumulator)
}
ISA_OP_ASL_Z..=ISA_OP_ASL_Z => {
ASL(ZeroPage(decode_from[1]))
}
ISA_OP_ASL_ZX..=ISA_OP_ASL_ZX => {
ASL(ZeroPageX(decode_from[1]))
}
ISA_OP_ASL_ABS..=ISA_OP_ASL_ABS => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
ASL(Absolute(word))
}
ISA_OP_ASL_ABSX..=ISA_OP_ASL_ABSX => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
ASL(AbsoluteX(word))
}
ISA_OP_BCC..=ISA_OP_BCC => {
BCC(Immediate(decode_from[1]))
}
ISA_OP_BCS..=ISA_OP_BCS => {
BCS(Immediate(decode_from[1]))
}
ISA_OP_BEQ..=ISA_OP_BEQ => {
BEQ(Immediate(decode_from[1]))
}
ISA_OP_BIT_ZP..=ISA_OP_BIT_ZP => {
BIT(ZeroPage(decode_from[1]))
}
ISA_OP_BIT_ABS..=ISA_OP_BIT_ABS => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
BIT(Absolute(word))
}
ISA_OP_BMI..=ISA_OP_BMI => {
BMI(Immediate(decode_from[1]))
}
ISA_OP_BNE..=ISA_OP_BNE => {
BNE(Immediate(decode_from[1]))
}
ISA_OP_BPL..=ISA_OP_BPL => {
BPL(Immediate(decode_from[1]))
}
ISA_OP_BRK..=ISA_OP_BRK => {
BRK
}
ISA_OP_BVC..=ISA_OP_BVC => {
BVC(AddressMode::Immediate(decode_from[1]))
}
ISA_OP_BVS..=ISA_OP_BVS => {
BVS(Immediate(decode_from[1]))
}
ISA_OP_CLC..=ISA_OP_CLC => {
CLC
}
ISA_OP_CLD..=ISA_OP_CLD => {
CLD
}
ISA_OP_CLI..=ISA_OP_CLI => {
CLI
}
ISA_OP_CLV..=ISA_OP_CLV => {
CLV
}
ISA_OP_CMP_I..=ISA_OP_CMP_I => {
CMP(Immediate(decode_from[1]))
}
ISA_OP_CMP_ZP..=ISA_OP_CMP_ZP => {
CMP(ZeroPage(decode_from[1]))
}
ISA_OP_CMP_ZPX..=ISA_OP_CMP_ZPX => {
CMP(ZeroPageX(decode_from[1]))
}
ISA_OP_CMP_ABS..=ISA_OP_CMP_ABS => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
CMP(Absolute(word))
}
ISA_OP_CMP_ABSX..=ISA_OP_CMP_ABSX => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
CMP(AbsoluteX(word))
}
ISA_OP_CMP_INDX..=ISA_OP_CMP_INDX => {
CMP(IndirectX(decode_from[1]))
}
ISA_OP_CMP_INDY..=ISA_OP_CMP_INDY => {
CMP(IndirectY(decode_from[1]))
}
ISA_OP_CPX_I..=ISA_OP_CPX_I => {
CPX(Immediate(decode_from[1]))
}
ISA_OP_CPX_ZP..=ISA_OP_CPX_ZP => {
CPX(ZeroPage(decode_from[1]))
}
ISA_OP_CPX_ABS..=ISA_OP_CPX_ABS => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
CPX(Absolute(word))
}
ISA_OP_CPY_I..=ISA_OP_CPY_I => {
CPY(Immediate(decode_from[1]))
}
ISA_OP_CPY_ZP..=ISA_OP_CPY_ZP => {
CPY(ZeroPage(decode_from[1]))
}
ISA_OP_CPY_ABS..=ISA_OP_CPY_ABS => {
let word = ((decode_from[2] as u16) << 8 | decode_from[1] as u16) as u16;
CPY(Absolute(word))
}
ISA_OP_DEC_ZP..=ISA_OP_DEC_ZP => {
DEC(ZeroPage(decode_from[1]))
}
ISA_OP_DEC_ZPX..=ISA_OP_DEC_ZPX => {
DEC(ZeroPageX(decode_from[1]))
}
_ => NOP
}
}
pub fn to_bytes(&self) -> Vec<u8> {
match self {
ADC(mode) => {
match mode {
Immediate(value) =>
vec![ISA_OP_ADC_I, *value],
ZeroPage(offset) =>
vec![ISA_OP_ADC_Z, *offset],
ZeroPageX(value) =>
vec![ISA_OP_ADC_ZX, *value],
Absolute(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_ADC_ABS, low, high]
}
AbsoluteX(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_ADC_ABSX, low, high]
}
AbsoluteY(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_ADC_ABSY, low, high]
}
IndirectX(offset) =>
vec![ISA_OP_ADC_INDX, *offset],
IndirectY(offset) =>
vec![ISA_OP_ADC_INDY, *offset],
_ => { vec![] }
}
}
AND(mode) => {
match mode {
Immediate(value) => vec![ISA_OP_AND_I, *value],
ZeroPage(value) => vec![ISA_OP_AND_Z, *value],
ZeroPageX(value) => vec![ISA_OP_AND_ZX, *value],
Absolute(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_AND_ABS, low, high]
}
AbsoluteX(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_AND_ABSX, low, high]
}
AbsoluteY(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_AND_ABSY, low, high]
}
IndirectX(value) => vec![ISA_OP_AND_INDX, *value],
IndirectY(value) => vec![ISA_OP_AND_INDY, *value],
_ => vec![]
}
}
// ASL(_) => {}
// BCC(_) => {}
// BCS(_) => {}
// BEQ(_) => {}
// BIT(_) => {}
// BMI(_) => {}
// BNE(_) => {}
// BPL(_) => {}
// BRK => {}
// BVC(_) => {}
// BVS(_) => {}
// CLC => {}
// CLD => {}
// CLI => {}
// CLV => {}
// CMP(_) => {}
// CPX(_) => {}
// CPY(_) => {}
// DEC(_) => {}
// DEX => {}
// DEY => {}
// EOR(_) => {}
// INC(_) => {}
// INX => {}
// INY => {}
// JMP(_) => {}
// JSR(_) => {}
// LDA(_) => {}
// LDX(_) => {}
// LDY(_) => {}
// LSR(_) => {}
// NOP => {}
// ORA(_) => {}
// PHA => {}
// PHP => {}
// PLA => {}
// PLP => {}
// ROL(_) => {}
// ROR(_) => {}
// RTI => {}
// RTS => {}
// SBC(_) => {}
// SEC => {}
// SED => {}
// SEI => {}
// STA(_) => {}
// STX(_) => {}
// STY(_) => {}
// TAX => {}
// TAY => {}
// TSX => {}
// TXA => {}
// TXS => {}
// TYA => {}
_ => { vec![] }
}
}
pub fn to_string(&self) -> String {
match self {
Instruction::ADC(newmode) => {
let prefix = "ADC";
match newmode {
Immediate(value) => {
InstructionStringify::format(Immediate(*value), prefix)
}
ZeroPage(address) => {
InstructionStringify::format(ZeroPage(*address), prefix)
}
ZeroPageX(address) => {
InstructionStringify::format(ZeroPageX(*address), prefix)
}
Absolute(address) => {
InstructionStringify::format(Absolute(*address), prefix)
}
AbsoluteX(offset) => {
InstructionStringify::format(AbsoluteX(*offset), prefix)
}
AbsoluteY(offset) => {
InstructionStringify::format(AbsoluteY(*offset), prefix)
}
IndirectX(value) => {
InstructionStringify::format(IndirectX(*value), prefix)
}
IndirectY(value) => {
InstructionStringify::format(IndirectY(*value), prefix)
}
_ => String::from("Invalid instruction")
}
}
Instruction::AND(newmode) => {
let prefix = "AND";
match newmode {
Immediate(value) => {
InstructionStringify::format(Immediate(*value), prefix)
}
ZeroPage(address) => {
InstructionStringify::format(ZeroPage(*address), prefix)
}
ZeroPageX(address) => {
InstructionStringify::format(ZeroPageX(*address), prefix)
}
Absolute(address) => {
InstructionStringify::format(Absolute(*address), prefix)
}
AbsoluteX(offset) => {
InstructionStringify::format(AbsoluteX(*offset), prefix)
}
AbsoluteY(offset) => {
InstructionStringify::format(AbsoluteY(*offset), prefix)
}
IndirectX(value) => {
InstructionStringify::format(IndirectX(*value), prefix)
}
IndirectY(value) => {
InstructionStringify::format(IndirectY(*value), prefix)
}
_ => String::from("Invalid instruction")
}
}
Instruction::ASL(_) => {
String::from("TBD")
}
Instruction::BCC(_) => {
String::from("TBD")
}
Instruction::BCS(_) => {
String::from("TBD")
}
Instruction::BEQ(_) => {
String::from("TBD")
}
Instruction::BIT(_) => {
String::from("TBD")
}
Instruction::BMI(_) => {
String::from("TBD")
}
Instruction::BNE(_) => {
String::from("TBD")
}
Instruction::BPL(_) => {
String::from("TBD")
}
Instruction::BRK => {
String::from("TBD")
}
Instruction::BVC(_) => {
String::from("TBD")
}
Instruction::BVS(_) => {
String::from("TBD")
}
Instruction::CLC => {
String::from("CLC")
}
Instruction::CLD => {
String::from("CLD")
}
_ => {
String::from("TBD")
}
}
}
fn execute(&self, mut system: Mos6502Cpu) {
match self {
// ADC Add with Carry
// A,Z,C,N = A+M+C
//
// This instruction adds the contents of a memory location to the accumulator together with the carry bit. If overflow occurs the carry bit is set, this enables multiple byte addition to be performed.
//
// Processor Status after use:
//
// C Carry Flag Set if overflow in bit 7
// Z Zero Flag Set if A = 0
// I Interrupt Disable Not affected
// D Decimal Mode Flag Not affected
// B Break Command Not affected
// V Overflow Flag Set if sign bit is incorrect
// N Negative Flag Set if bit 7 set
Instruction::ADC(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::AND(address) => {
match address {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {
// NOOP
}
}
}
Instruction::ASL(mode) => {
match mode {
// ISA_OP_ASL_A
AddressMode::Accumulator => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
_ => {}
}
}
Instruction::BCC(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BCS(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BEQ(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BIT(mode) => {
match mode {
AddressMode::ZeroPage(value) => {}
AddressMode::Absolute(value) => {}
_ => {}
}
}
Instruction::BMI(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BNE(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BPL(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BRK => {}
Instruction::BVC(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::BVS(mode) => {
match mode {
AddressMode::Immediate(value) => {}
_ => {}
}
}
Instruction::CLC => {
system.poke_flag(Carry, false)
}
Instruction::CLD => {
system.poke_flag(Decimal, false)
}
Instruction::CLI => {
system.poke_flag(Interrupt, false)
}
Instruction::CLV => {
system.poke_flag(Overflow, false)
}
Instruction::CMP(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::CPX(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::CPY(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::DEC(mode) => {
match mode {
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
_ => {}
}
}
Instruction::DEX => {
let mut x = system.peek_x();
x -= 1;
system.poke_x(x);
}
Instruction::DEY => {
let mut y = system.peek_y();
y -= 1;
system.poke_y(y);
}
Instruction::EOR(mode) => {
match mode {
AddressMode::Immediate(_) => {}
AddressMode::ZeroPage(_) => {}
AddressMode::ZeroPageX(_) => {}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {}
}
}
Instruction::INC(mode) => {
match mode {
AddressMode::ZeroPage(value) => {}
AddressMode::ZeroPageX(value) => {}
AddressMode::Absolute(value) => {}
AddressMode::AbsoluteX(value) => {}
_ => {}
}
}
Instruction::INX => {
let mut x = system.peek_x();
x += 1;
system.poke_x(x);
}
Instruction::INY => {
let mut y = system.peek_y();
y += 1;
system.poke_y(y);
}
Instruction::JMP(mode) => {
match mode {
AddressMode::Absolute(_) => {}
AddressMode::IndirectX(_) => {}
_ => {}
}
}
Instruction::JSR(mode) => {
match mode {
AddressMode::Absolute(address) => {}
_ => {}
}
}
Instruction::LDA(mode) => {
match mode {
AddressMode::Immediate(value) => {
system.poke_a(*value)
}
AddressMode::ZeroPage(offset) => {
let value_to_write = system.peek(*offset as u16);
system.poke_a(value_to_write);
}
AddressMode::ZeroPageX(_) => {
let current_x = system.peek_x();
}
AddressMode::Absolute(_) => {}
AddressMode::AbsoluteX(_) => {}
AddressMode::AbsoluteY(_) => {}
AddressMode::IndirectX(_) => {}
AddressMode::IndirectY(_) => {}
_ => {
debug!("Invalid LDA instruction");
}
};
}
Instruction::LDX(_) => {}
Instruction::LDY(_) => {}
Instruction::LSR(_) => {}
Instruction::NOP => {}
Instruction::ORA(_) => {}
Instruction::PHA => {}
Instruction::PHP => {}
Instruction::PLA => {}
Instruction::PLP => {}
Instruction::ROL(_) => {}
Instruction::ROR(_) => {}
Instruction::RTI => {}
Instruction::RTS => {}
Instruction::SBC(_) => {}
Instruction::SEC => {}
Instruction::SED => {}
Instruction::SEI => {}
Instruction::STA(_) => {}
Instruction::STX(_) => {}
Instruction::STY(_) => {}
Instruction::TAX => {}
Instruction::TAY => {}
Instruction::TSX => {}
Instruction::TXA => {}
Instruction::TXS => {}
Instruction::TYA => {}
};
}
}
#[cfg(test)]
mod test {
use crate::address_mode::AddressMode::*;
@ -1715,24 +1026,186 @@ mod test {
use super::*;
#[test]
fn to_string() {
fn to_string_to_bytes_from_bytes() {
let params = vec![
(ADC(Immediate(0x01)), "ADC #$01"),
(ADC(ZeroPage(0x01)), "ADC $01"),
(ADC(ZeroPageX(0x01)), "ADC $01,X"),
(ADC(Absolute(0xabcd)), "ADC $abcd"),
(ADC(AbsoluteX(0xabcd)), "ADC $abcd,X"),
(ADC(AbsoluteY(0xabcd)), "ADC $abcd,Y"),
(ADC(IndirectX(0xab)), "ADC ($ab,X)"),
(ADC(IndirectY(0xab)), "ADC ($ab),Y"),
(SBC(Immediate(0x01)), "SBC #$01"),
(SBC(ZeroPage(0x01)), "SBC $01"),
(SBC(ZeroPageX(0x01)), "SBC $01,X"),
(SBC(Absolute(0xabcd)), "SBC $abcd"),
(SBC(AbsoluteX(0xabcd)), "SBC $abcd,X"),
(SBC(AbsoluteY(0xabcd)), "SBC $abcd,Y"),
(SBC(IndirectX(0xab)), "SBC ($ab,X)"),
(SBC(IndirectY(0xab)), "SBC ($ab),Y"),
(ADC(Immediate(0x01)), "ADC #$01", vec![0x69, 0x01]),
(ADC(ZeroPage(0x01)), "ADC $01", vec![0x65, 0x01]),
(ADC(ZeroPageX(0x01)), "ADC $01,X", vec![0x75, 0x01]),
(ADC(Absolute(0xabcd)), "ADC $abcd", vec![0x6d, 0xcd, 0xab]),
(ADC(AbsoluteX(0xabcd)), "ADC $abcd,X", vec![0x7d, 0xcd, 0xab]),
(ADC(AbsoluteY(0xabcd)), "ADC $abcd,Y", vec![0x79, 0xcd, 0xab]),
(ADC(IndirectX(0xab)), "ADC ($ab,X)", vec![0x61, 0xab]),
(ADC(IndirectY(0xab)), "ADC ($ab),Y", vec![0x71, 0xab]),
(AND(Immediate(0x01)), "AND #$01", vec![0x29, 0x01]),
(AND(ZeroPage(0x01)), "AND $01", vec![0x25, 0x01]),
(AND(ZeroPageX(0x01)), "AND $01,X", vec![0x35, 0x01]),
(AND(Absolute(0xabcd)), "AND $abcd", vec![0x2d, 0xcd, 0xab]),
(AND(AbsoluteX(0xabcd)), "AND $abcd,X", vec![0x3d, 0xcd, 0xab]),
(AND(AbsoluteY(0xabcd)), "AND $abcd,Y", vec![0x39, 0xcd, 0xab]),
(AND(IndirectX(0xab)), "AND ($ab,X)", vec![0x21, 0xab]),
(AND(IndirectY(0xab)), "AND ($ab),Y", vec![0x31, 0xab]),
(ASL(Accumulator), "ASL A", vec![0x0a]),
(ASL(ZeroPage(0xab)), "ASL $ab", vec![0x06, 0xab]),
(ASL(ZeroPageX(0xab)), "ASL $ab,X", vec![0x16, 0xab]),
(ASL(Absolute(0xabcd)), "ASL $abcd", vec![0x0e, 0xcd, 0xab]),
(ASL(AbsoluteX(0xabcd)), "ASL $abcd,X", vec![0x1e, 0xcd, 0xab]),
(BCC(Immediate(0xab)), "BCC #$ab", vec![0x90, 0xab]),
(BCS(Immediate(0xab)), "BCS #$ab", vec![0xb0, 0xab]),
(BEQ(Immediate(0xab)), "BEQ #$ab", vec![0xf0, 0xab]),
(BIT(ZeroPage(0xab)), "BIT $ab", vec![0x24, 0xab]),
(BIT(Absolute(0xabcd)), "BIT $abcd", vec![0x2c, 0xcd, 0xab]),
(BMI(Immediate(0xab)), "BMI #$ab", vec![0x30, 0xab]),
(BNE(Immediate(0xab)), "BNE #$ab", vec![0xd0, 0xab]),
(BPL(Immediate(0xab)), "BPL #$ab", vec![0x10, 0xab]),
(BVC(Immediate(0xab)), "BVC #$ab", vec![0x50, 0xab]),
(BVS(Immediate(0xab)), "BVS #$ab", vec![0x70, 0xab]),
(CLC, "CLC", vec![0x18]),
(CLD, "CLD", vec![0xd8]),
(CLV, "CLV", vec![0x58]),
(CLI, "CLI", vec![0xb8]),
(CMP(Immediate(0xab)), "CMP #$ab", vec![0xc9, 0xab]),
(CMP(ZeroPage(0xab)), "CMP $ab", vec![0xc5, 0xab]),
(CMP(ZeroPageX(0xab)), "CMP $ab,X", vec![0xd5, 0xab]),
(CMP(Absolute(0xabcd)), "CMP $abcd", vec![0xcd, 0xcd, 0xab]),
(CMP(AbsoluteX(0xabcd)), "CMP $abcd,X", vec![0xdd, 0xcd, 0xab]),
(CMP(IndirectX(0xab)), "CMP ($ab,X)", vec![0xc1, 0xab]),
(CMP(IndirectY(0xab)), "CMP ($ab),Y", vec![0xd1, 0xab]),
(CPX(Immediate(0xab)), "CPX #$ab", vec![0xe0, 0xab]),
(CPX(ZeroPage(0xab)), "CPX $ab", vec![0xe4, 0xab]),
(CPX(Absolute(0xabcd)), "CPX $abcd", vec![0xec, 0xcd, 0xab]),
(CPY(Immediate(0xab)), "CPY #$ab", vec![0xc0, 0xab]),
(CPY(Immediate(0xab)), "CPY #$ab", vec![0xc0, 0xab]),
(CPY(ZeroPage(0xab)), "CPY $ab", vec![0xc4, 0xab]),
(CPY(Absolute(0xabcd)), "CPY $abcd", vec![0xcc, 0xcd, 0xab]),
(DEC(ZeroPage(0xab)), "DEC $ab", vec![0xc6, 0xab]),
(DEC(ZeroPageX(0xab)), "DEC $ab,X", vec![0xd6, 0xab]),
(DEC(Absolute(0xabcd)), "DEC $abcd", vec![0xce, 0xcd, 0xab]),
(DEC(AbsoluteX(0xabcd)), "DEC $abcd,X", vec![0xde, 0xcd, 0xab]),
(DEX, "DEX", vec![0xca]),
(DEY, "DEY", vec![0x88]),
(EOR(Immediate(0xab)), "EOR #$ab", vec![0x49, 0xab]),
(EOR(ZeroPage(0xab)), "EOR $ab", vec![0x45, 0xab]),
(EOR(ZeroPageX(0xab)), "EOR $ab,X", vec![0x55, 0xab]),
(EOR(Absolute(0xabcd)), "EOR $abcd", vec![0x4d, 0xcd, 0xab]),
(EOR(AbsoluteX(0xabcd)), "EOR $abcd,X", vec![0x5d, 0xcd, 0xab]),
(EOR(IndirectX(0xab)), "EOR ($ab,X)", vec![0x41, 0xab]),
(EOR(IndirectY(0xab)), "EOR ($ab),Y", vec![0x51, 0xab]),
(INC(ZeroPage(0xab)), "INC $ab", vec![0xe6, 0xab]),
(INC(ZeroPageX(0xab)), "INC $ab,X", vec![0xf6, 0xab]),
(INC(Absolute(0xabcd)), "INC $abcd", vec![0xee, 0xcd, 0xab]),
(INC(AbsoluteX(0xabcd)), "INC $abcd,X", vec![0xfe, 0xcd, 0xab]),
(INX, "INX", vec![0xe8]),
(INY, "INY", vec![0xc8]),
(JMP(Absolute(0xabcd)), "JMP $abcd", vec![0x4c, 0xcd, 0xab]),
(JMP(IndirectX(0xab)), "JMP $ab,X", vec![0x6c, 0xab]),
(JSR(Immediate(0xab)), "JSR", vec![0x20, 0xab]),
(LDA(Immediate(0xab)), "LDA #$ab", vec![0xa9, 0xab]),
(LDA(ZeroPage(0xab)), "LDA $ab", vec![0xa5, 0xab]),
(LDA(ZeroPageX(0xab)), "LDA $ab,X", vec![0xb5, 0xab]),
(LDA(Absolute(0xabcd)), "LDA $abcd", vec![0xad, 0xcd, 0xab]),
(LDA(AbsoluteX(0xabcd)), "LDA $abcd,X", vec![0xbd, 0xcd, 0xab]),
(LDA(AbsoluteY(0xabcd)), "LDA $abcd,Y", vec![0xb9, 0xcd, 0xab]),
(LDA(IndirectX(0xab)), "LDA ($ab,X)", vec![0xa1, 0xab]),
(LDA(IndirectY(0xab)), "LDA ($ab),Y", vec![0xb1, 0xab]),
(LDX(Immediate(0xab)), "LDX #$ab", vec![0xa2, 0xab]),
(LDX(ZeroPage(0xab)), "LDX $ab", vec![0xa6, 0xab]),
(LDX(ZeroPageX(0xab)), "LDX $ab,X", vec![0x86, 0xab]),
(LDX(Absolute(0xabcd)), "LDX $abcd", vec![0xae, 0xcd, 0xab]),
(LDX(AbsoluteX(0xabcd)), "LDX $abcd,X", vec![0xbe, 0xcd, 0xab]),
(LDY(Immediate(0xab)), "LDY #$ab", vec![0xa0, 0xab]),
(LDY(ZeroPage(0xab)), "LDY $ab", vec![0xa4, 0xab]),
(LDY(ZeroPageX(0xab)), "LDY $ab,X", vec![0x84, 0xab]),
(LDY(Absolute(0xabcd)), "LDY $abcd", vec![0xac, 0xcd, 0xab]),
(LDY(AbsoluteX(0xabcd)), "LDY $abcd,X", vec![0xbc, 0xcd, 0xab]),
(LSR(Accumulator), "LSR A", vec![0x4a]),
(LSR(ZeroPage(0xab)), "LSR $ab", vec![0x46, 0xab]),
(LSR(ZeroPageX(0xab)), "LSR $ab,X", vec![0x56, 0xab]),
(LSR(Absolute(0xabcd)), "LSR $abcd", vec![0x4e, 0xcd, 0xab]),
(LSR(AbsoluteX(0xabcd)), "LSR $abcd,X", vec![0x5e, 0xcd, 0xab]),
// Nop nop nop.
(NOP, "NOP", vec![0xea]),
(ORA(Immediate(0xab)), "ORA #$ab", vec![0x09, 0xab]),
(ORA(ZeroPage(0xab)), "ORA $ab", vec![0x05, 0xab]),
(ORA(ZeroPageX(0xab)), "ORA $ab,X", vec![0x15, 0xab]),
(ORA(Absolute(0xabcd)), "ORA $abcd", vec![0x0d, 0xcd, 0xab]),
(ORA(AbsoluteX(0xabcd)), "ORA $abcd,X", vec![0x1d, 0xcd, 0xab]),
(ORA(AbsoluteY(0xabcd)), "ORA $abcd,Y", vec![0x19, 0xcd, 0xab]),
(ORA(IndirectX(0xab)), "ORA ($ab,X)", vec![0x01, 0xab]),
(ORA(IndirectY(0xab)), "ORA ($ab),Y", vec![0x11, 0xab]),
(PHA, "PHA", vec![0x48]),
(PHP, "PHP", vec![0x08]),
(PLA, "PLA", vec![0x68]),
(PLP, "PLP", vec![0x28]),
(ROL(Accumulator), "ROL A", vec![0x2a]),
(ROL(ZeroPage(0xab)), "ROL $ab", vec![0x26, 0xab]),
(ROL(ZeroPageX(0xab)), "ROL $ab,X", vec![0x36, 0xab]),
(ROL(Absolute(0xabcd)), "ROL $abcd", vec![0x2e, 0xcd, 0xab]),
(ROL(AbsoluteX(0xabcd)), "ROL $abcd,X", vec![0x3e, 0xcd, 0xab]),
(ROR(Accumulator), "ROR A", vec![0x6a]),
(ROR(ZeroPage(0xab)), "ROR $ab", vec![0x66, 0xab]),
(ROR(ZeroPageX(0xab)), "ROR $ab,X", vec![0x76, 0xab]),
(ROR(Absolute(0xabcd)), "ROR $abcd", vec![0x6e, 0xcd, 0xab]),
(ROR(AbsoluteX(0xabcd)), "ROR $abcd,X", vec![0x7e, 0xcd, 0xab]),
(RTI, "RTI", vec![0x40]),
(RTS, "RTS", vec![0x60]),
(SBC(Immediate(0xab)), "SBC #$ab", vec![0xe9, 0xcd, 0xab]),
(SBC(ZeroPage(0xab)), "SBC $ab", vec![0xe5, 0xab]),
(SBC(ZeroPageX(0xab)), "SBC $ab,X", vec![0xf5, 0xab]),
(SBC(Absolute(0xabcd)), "SBC $abcd", vec![0xed, 0xcd, 0xab]),
(SBC(AbsoluteX(0xabcd)), "SBC $abcd,X", vec![0xfd, 0xcd, 0xab]),
(SBC(AbsoluteY(0xabcd)), "SBC $abcd,Y", vec![0xf9, 0xcd, 0xab]),
(SBC(IndirectX(0xab)), "SBC ($ab,X)", vec![0xe1, 0xab]),
(SBC(IndirectY(0xab)), "SBC ($ab),Y", vec![0xf1, 0xab]),
(SEC, "SEC", vec![0x38]),
(SED, "SED", vec![0xf8]),
(SEI, "SEI", vec![0x78]),
(STA(ZeroPage(0xab)), "STA $ab", vec![0x85, 0xab]),
(STA(ZeroPageX(0xab)), "STA $ab,X", vec![0x95, 0xab]),
(STA(Absolute(0xabcd)), "STA $abcd", vec![0x8d, 0xcd, 0xab]),
(STA(AbsoluteX(0xabcd)), "STA $abcd,X", vec![0x9d, 0xcd, 0xab]),
(STA(AbsoluteY(0xabcd)), "STA $abcd,Y", vec![0x99, 0xcd, 0xab]),
(STA(IndirectX(0xab)), "STA ($ab,X)", vec![0x81, 0xab]),
(STA(IndirectY(0xab)), "STA ($ab),Y", vec![0x91, 0xab]),
(STX(ZeroPage(0xab)), "STX $ab", vec![0x86, 0xab]),
(STX(ZeroPageX(0xab)), "STX $ab,X", vec![0x96, 0xab]),
(STX(Absolute(0xabcd)), "STX $abcd", vec![0x8e, 0xcd, 0xab]),
(STY(ZeroPage(0xab)), "STY $ab", vec![0x84, 0xab]),
(STY(ZeroPageX(0xab)), "STY $ab,X", vec![0x94, 0xab]),
(STY(Absolute(0xabcd)), "STY $abcd", vec![0x8c, 0xcd, 0xab]),
(TAX, "TAX", vec![0xaa]),
(TAY, "TAY", vec![0xa8]),
(TSX, "TSX", vec![0xba]),
(TXA, "TXA", vec![0x8a]),
(TXS, "TXS", vec![0x9a]),
(TYA, "TYA", vec![0x98])
];
for (instruction, string, bytes) in params {
// from instruction to string
assert_eq!(
instruction.to_string(),
string
);
// from instruction to bytes
println!("COMPARE OF {} to {:?}", instruction.to_string(), bytes);
assert_eq!(
instruction.to_bytes(),
bytes
);
// from bytes to instruction
assert_eq!(
instruction,
Instruction::from_bytes(bytes)
);
}
}
}

View File

@ -0,0 +1,71 @@
use crate::instruction::Instruction;
use crate::constants::constants_isa_stub::*;
use crate::instruction::Instruction::*;
impl Instruction {
/// returns the 'stub' of the instruction.
///
/// ex: LDA $4452 -> LDA
/// BCC $43 -> BCC
pub fn stub(&self) -> String {
match self {
ADC(_) => ISA_STUB_ADC,
AND(_) => ISA_STUB_AND,
ASL(_) => ISA_STUB_ASL,
BCC(_) => ISA_STUB_BCC,
BCS(_) => ISA_STUB_BCS,
BEQ(_) => ISA_STUB_BEQ,
BIT(_) => ISA_STUB_BIT,
BMI(_) => ISA_STUB_BMI,
BNE(_) => ISA_STUB_BNE,
BPL(_) => ISA_STUB_BPL,
BRK => ISA_STUB_BRK,
BVC(_) => ISA_STUB_BVC,
BVS(_) => ISA_STUB_BVS,
CLC => ISA_STUB_CLC,
CLD => ISA_STUB_CLD,
CLI => ISA_STUB_CLI,
CLV => ISA_STUB_CLV,
CMP(_) => ISA_STUB_CMP,
CPX(_) => ISA_STUB_CPX,
CPY(_) => ISA_STUB_CPY,
DEC(_) => ISA_STUB_DEC,
DEX => ISA_STUB_DEX,
DEY => ISA_STUB_DEY,
EOR(_) => ISA_STUB_EOR,
INC(_) => ISA_STUB_INC,
INX => ISA_STUB_INX,
INY => ISA_STUB_INY,
JMP(_) => ISA_STUB_JMP,
JSR(_) => ISA_STUB_JSR,
LDA(_) => ISA_STUB_LDA,
LDX(_) => ISA_STUB_LDX,
LDY(_) => ISA_STUB_LDY,
LSR(_) => ISA_STUB_LSR,
NOP => ISA_STUB_NOP,
ORA(_) => ISA_STUB_ORA,
PHA => ISA_STUB_PHA,
PHP => ISA_STUB_PHP,
PLA => ISA_STUB_PLA,
PLP => ISA_STUB_PLP,
ROL(_) => ISA_STUB_ROL,
ROR(_) => ISA_STUB_ROR,
RTI => ISA_STUB_RTI,
RTS => ISA_STUB_RTS,
SBC(_) => ISA_STUB_SBC,
SEC => ISA_STUB_SEC,
SED => ISA_STUB_SED,
SEI => ISA_STUB_SEI,
STA(_) => ISA_STUB_STA,
STX(_) => ISA_STUB_STX,
STY(_) => ISA_STUB_STY,
TAX => ISA_STUB_TAX,
TAY => ISA_STUB_TAY,
TSX => ISA_STUB_TSX,
TXA => ISA_STUB_TXA,
TXS => ISA_STUB_TXS,
TYA => ISA_STUB_TYA
}.to_string()
}
}

View File

@ -0,0 +1,193 @@
use crate::address_mode::AddressMode;
use crate::address_mode::AddressMode::{Absolute, AbsoluteX, AbsoluteY, Immediate, IndirectX, IndirectY, ZeroPage, ZeroPageX};
use crate::constants::constants_isa_op::*;
use crate::instruction::Instruction;
use crate::instruction::Instruction::*;
fn split_word_hl(to_split: u16) -> (u8, u8) {
let low = (to_split & 0xff) as u8;
let high = ((to_split & 0xff00) >> 8) as u8;
(high, low)
}
fn split_word_lh(to_split: u16) -> (u8, u8) {
let low = (to_split & 0xff) as u8;
let high = ((to_split & 0xff00) >> 8) as u8;
(low, high)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn split_le() {
let value = 0xabcd;
let (high, low) = split_word_hl(value);
assert_eq!(low, 0xcd);
assert_eq!(high, 0xab);
}
#[test]
fn split_be() {
let value = 0xabcd;
let (low, high) = split_word_lh(value);
assert_eq!(low, 0xcd);
assert_eq!(high, 0xab);
}
}
impl Instruction {
pub fn to_bytes(&self) -> Vec<u8> {
match self {
ADC(mode) => {
match mode {
Immediate(value) =>
vec![ISA_OP_ADC_I, *value],
ZeroPage(offset) =>
vec![ISA_OP_ADC_Z, *offset],
ZeroPageX(value) =>
vec![ISA_OP_ADC_ZX, *value],
Absolute(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_ADC_ABS, low, high]
}
AbsoluteX(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_ADC_ABSX, low, high]
}
AbsoluteY(offset) => {
let high = ((offset & 0xff00) >> 8) as u8;
let low = (offset & 0x00ff) as u8;
vec![ISA_OP_ADC_ABSY, low, high]
}
IndirectX(offset) =>
vec![ISA_OP_ADC_INDX, *offset],
IndirectY(offset) =>
vec![ISA_OP_ADC_INDY, *offset],
_ => { vec![] }
}
}
AND(mode) => {
match mode {
Immediate(value) => vec![ISA_OP_AND_I, *value],
ZeroPage(value) => vec![ISA_OP_AND_Z, *value],
ZeroPageX(value) => vec![ISA_OP_AND_ZX, *value],
Absolute(offset) => {
let (h, l) = split_word_hl(*offset);
vec![ISA_OP_AND_ABS, l, h]
}
AbsoluteX(offset) => {
let (h, l) = split_word_hl(*offset);
vec![ISA_OP_AND_ABSX, l,h]
}
AbsoluteY(offset) => {
let (h, l) = split_word_hl(*offset);
vec![ISA_OP_AND_ABSY, l,h]
}
IndirectX(value) => vec![ISA_OP_AND_INDX, *value],
IndirectY(value) => vec![ISA_OP_AND_INDY, *value],
_ => vec![]
}
}
ASL(mode) => {
match mode {
AddressMode::Accumulator => {
vec![ISA_OP_ASL_A]
}
ZeroPage(value) => {
vec![ISA_OP_ASL_Z, *value]
}
ZeroPageX(value) => {
vec![ISA_OP_ASL_ZX, *value]
}
Absolute(offset) => {
let (h, l) = split_word_hl(*offset);
vec![ISA_OP_ASL_ABS, l,h]
}
AbsoluteX(offset) => {
let (h, l) = split_word_hl(*offset);
vec![ISA_OP_ASL_ABSX, l, h]
}
_ => vec![ISA_OP_NOP]
}
}
BCC(mode) => {
match mode {
Immediate(value) => {
vec![ISA_OP_BCC, *value]
}
_ => vec![ISA_OP_NOP]
}
}
BCS(mode) => {
match mode {
Immediate(value) => {
vec![ISA_OP_BCS, *value]
},
_ => vec![ISA_OP_NOP]
}
}
// BEQ(_) => {}
// BIT(_) => {}
// BMI(_) => {}
// BNE(_) => {}
// BPL(_) => {}
// BRK => {}
// BVC(_) => {}
// BVS(_) => {}
// CLC => {}
// CLD => {}
// CLI => {}
// CLV => {}
// CMP(_) => {}
// CPX(_) => {}
// CPY(_) => {}
// DEC(_) => {}
// DEX => {}
// DEY => {}
// EOR(_) => {}
// INC(_) => {}
// INX => {}
// INY => {}
// JMP(_) => {}
// JSR(_) => {}
// LDA(_) => {}
// LDX(_) => {}
// LDY(_) => {}
// LSR(_) => {}
// NOP => {}
// ORA(_) => {}
// PHA => {}
// PHP => {}
// PLA => {}
// PLP => {}
// ROL(_) => {}
// ROR(_) => {}
// RTI => {}
// RTS => {}
// SBC(_) => {}
// SEC => {}
// SED => {}
// SEI => {}
// STA(_) => {}
// STX(_) => {}
// STY(_) => {}
// TAX => {}
// TAY => {}
// TSX => {}
TXA => vec![ISA_OP_TXA],
TXS => vec![ISA_OP_TXS],
TYA => vec![ISA_OP_TYA],
_ => { vec![] }
}
}
}

View File

@ -0,0 +1,42 @@
use crate::address_mode::AddressMode;
use crate::address_mode::AddressMode::Implied;
use crate::instruction::Instruction;
use crate::instruction::Instruction::*;
impl Instruction {
pub fn to_string(&self) -> String {
let mode = match self {
ADC(newmode) | AND(newmode) | ASL(newmode) |
BCC(newmode) | BCS(newmode) | BEQ(newmode) |
BIT(newmode) | BMI(newmode) | BNE(newmode) |
BPL(newmode) | BVC(newmode) | BVS(newmode) |
CMP(newmode) | CPX(newmode) | CPY(newmode) |
DEC(newmode) | EOR(newmode) | INC(newmode) |
JMP(newmode) | JSR(newmode) | LDA(newmode) |
LDX(newmode) | LDY(newmode) | LSR(newmode) |
ORA(newmode) | ROL(newmode) | ROR(newmode) |
SBC(newmode) | STA(newmode) | STX(newmode) |
STY(newmode) => newmode,
_ => &Implied
};
Instruction::format(mode, &self.stub())
}
fn format(mode: &AddressMode, prefix: &str) -> String {
let suffix = match mode {
AddressMode::Implied => "",
AddressMode::Accumulator => " A",
AddressMode::Immediate(value) => &*format!(" #${value:02x}"),
AddressMode::ZeroPage(value) => &*format!(" ${value:02x}"),
AddressMode::ZeroPageX(value) => &*format!(" ${value:02x},X"),
AddressMode::Absolute(offset) => &*format!(" ${offset:04x}"),
AddressMode::AbsoluteX(offset) => &*format!(" ${offset:04x},X"),
AddressMode::AbsoluteY(offset) => &*format!(" ${offset:04x},Y"),
AddressMode::IndirectX(value) => &*format!(" (${value:02x},X)"),
AddressMode::IndirectY(value) => &*format!(" (${value:02x}),Y"),
AddressMode::ZeroPageY(value) => &*format!(" ${value:02x},Y")
};
format!("{}{}", prefix, suffix)
}
}

View File

@ -1,21 +0,0 @@
use crate::address_mode::AddressMode;
pub struct InstructionStringify {}
impl InstructionStringify {
pub fn format(mode: AddressMode, prefix: &str) -> String {
let suffix = match mode {
AddressMode::Implied => "",
AddressMode::Accumulator => "A",
AddressMode::Immediate(value) => &*format!("#${value:02x}"),
AddressMode::ZeroPage(value) => &*format!("${value:02x}"),
AddressMode::ZeroPageX(value) => &*format!("${value:02x},X"),
AddressMode::Absolute(offset) => &*format!("${offset:04x}"),
AddressMode::AbsoluteX(offset) => &*format!("${offset:04x},X"),
AddressMode::AbsoluteY(offset) => &*format!("${offset:04x},Y"),
AddressMode::IndirectX(value) => &*format!("(${value:02x},X)"),
AddressMode::IndirectY(value) => &*format!("(${value:02x}),Y")
};
format!("{} {}", prefix, suffix)
}
}

View File

@ -1,5 +1,4 @@
use crate::address_mode::AddressMode::*;
use crate::constants::*;
use crate::instruction::Instruction;
use crate::instruction::Instruction::*;
@ -13,12 +12,13 @@ impl Decoder {
/// NOP will be returned when an instruction without a valid parameter
/// and more data is required to decode.
pub fn decode(decode_from: Vec<u8>) -> Instruction {
NOP
Instruction::from_bytes(decode_from)
}
}
#[cfg(test)]
mod test {
use crate::constants::constants_isa_op::{ISA_OP_ADC_ABS, ISA_OP_ADC_ABSX, ISA_OP_ADC_ABSY, ISA_OP_ADC_I, ISA_OP_ADC_INDX, ISA_OP_ADC_INDY, ISA_OP_ADC_Z, ISA_OP_ADC_ZX, ISA_OP_AND_ABS, ISA_OP_AND_I, ISA_OP_AND_Z, ISA_OP_AND_ZX, ISA_OP_ASL_A, ISA_OP_ASL_ABS, ISA_OP_ASL_ABSX, ISA_OP_ASL_Z, ISA_OP_ASL_ZX, ISA_OP_BCC, ISA_OP_BEQ, ISA_OP_BIT_ABS, ISA_OP_BIT_ZP, ISA_OP_BMI, ISA_OP_BNE, ISA_OP_BPL, ISA_OP_BRK, ISA_OP_BVC, ISA_OP_BVS};
use super::*;
@ -60,6 +60,8 @@ mod test {
(vec![ISA_OP_BRK], BRK),
];
for (bytes, instruction) in params {

View File

@ -1,5 +1,5 @@
use crate::address_mode::AddressMode::*;
use crate::constants::*;
use crate::constants::constants_isa_op::ISA_OP_BCC;
use crate::instruction::Instruction;
use crate::instruction::Instruction::*;
@ -78,7 +78,7 @@ impl Encoder {
#[cfg(test)]
mod test {
use crate::constants::*;
use crate::constants::constants_isa_op::{ISA_OP_ADC_ABS, ISA_OP_ADC_ABSX, ISA_OP_ADC_ABSY, ISA_OP_ADC_I, ISA_OP_ADC_INDX, ISA_OP_ADC_INDY, ISA_OP_ADC_Z, ISA_OP_ADC_ZX, ISA_OP_AND_ABS, ISA_OP_AND_I, ISA_OP_AND_Z, ISA_OP_AND_ZX, ISA_OP_ASL_A, ISA_OP_ASL_ABS, ISA_OP_ASL_ABSX, ISA_OP_ASL_Z, ISA_OP_ASL_ZX, ISA_OP_BEQ, ISA_OP_BIT_ABS, ISA_OP_BIT_ZP, ISA_OP_BMI, ISA_OP_BNE, ISA_OP_BPL, ISA_OP_BRK, ISA_OP_BVC, ISA_OP_BVS};
use super::*;
#[test]

View File

@ -1,4 +1,3 @@
pub mod encode;
pub mod decoder;
pub mod microcode_steps;

View File

@ -4,4 +4,3 @@ pub mod instruction;
pub mod mos6502flags;
pub mod isa;
pub mod constants;
mod instruction_stringify;

View File

@ -11,7 +11,9 @@ pub struct Mos6502Cpu {
flags: Mos6502Flags,
pc: u16,
s: u8,
microcode_step: u8
microcode_step: u8,
address_bus: u16,
data_bus: u8
}
impl Mos6502Cpu {
@ -24,7 +26,9 @@ impl Mos6502Cpu {
flags: Mos6502Flags::default(),
pc: 0,
s: 0xfd,
microcode_step: 0
microcode_step: 0,
address_bus: 0x0000,
data_bus: 0x00
}
}
@ -69,4 +73,9 @@ impl Mos6502Cpu {
pub fn tick(&mut self) {
}
pub fn dump(&self) {
println!("CPU State: PC: {:04x} / A: {:02x} / X: {:02x} / Y: {:02x} / ADDRESS: {:04x} / DATA: {:02x}",
self.pc, self.a, self.x, self.y, self.address_bus, self.data_bus);
}
}

View File

@ -2,3 +2,6 @@
name = "macroquad"
version = "0.1.0"
edition = "2024"
[dependencies]
macroquad = "0.4"

View File

@ -0,0 +1,16 @@
use macroquad::prelude::*;
#[macroquad::main("BasicShapes")]
async fn main() {
loop {
clear_background(RED);
draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
draw_text("IT WORKS!", 20.0, 20.0, 30.0, DARKGRAY);
next_frame().await
}
}