more decode and encode code
This commit is contained in:
parent
87ae4e7890
commit
768e83dfb8
223
Cargo.lock
generated
223
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
@ -8,6 +8,7 @@ pub enum AddressMode {
|
||||
Immediate(u8),
|
||||
ZeroPage(u8),
|
||||
ZeroPageX(u8),
|
||||
ZeroPageY(u8),
|
||||
Absolute(u16),
|
||||
AbsoluteX(u16),
|
||||
AbsoluteY(u16),
|
||||
|
||||
@ -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;
|
||||
57
core/src/constants/constants_isa_stub.rs
Normal file
57
core/src/constants/constants_isa_stub.rs
Normal 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";
|
||||
2
core/src/constants/mod.rs
Normal file
2
core/src/constants/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod constants_isa_stub;
|
||||
pub mod constants_isa_op;
|
||||
285
core/src/instruction/execute.rs
Normal file
285
core/src/instruction/execute.rs
Normal 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 => {}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
183
core/src/instruction/from_bytes.rs
Normal file
183
core/src/instruction/from_bytes.rs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
71
core/src/instruction/stub.rs
Normal file
71
core/src/instruction/stub.rs
Normal 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()
|
||||
}
|
||||
|
||||
}
|
||||
193
core/src/instruction/to_bytes.rs
Normal file
193
core/src/instruction/to_bytes.rs
Normal 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![] }
|
||||
}
|
||||
}
|
||||
}
|
||||
42
core/src/instruction/to_string.rs
Normal file
42
core/src/instruction/to_string.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
pub mod encode;
|
||||
pub mod decoder;
|
||||
pub mod microcode_steps;
|
||||
|
||||
@ -4,4 +4,3 @@ pub mod instruction;
|
||||
pub mod mos6502flags;
|
||||
pub mod isa;
|
||||
pub mod constants;
|
||||
mod instruction_stringify;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,3 +2,6 @@
|
||||
name = "macroquad"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
macroquad = "0.4"
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user