some decode. some encode. some to_string
This commit is contained in:
parent
bbb263d4d1
commit
a550fe40b9
125
Cargo.lock
generated
125
Cargo.lock
generated
@ -53,7 +53,7 @@ version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -64,7 +64,7 @@ checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -124,6 +124,7 @@ name = "cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"core",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
"trevors_utilities",
|
||||
@ -138,6 +139,9 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
[[package]]
|
||||
name = "core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
@ -163,12 +167,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
|
||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -225,7 +229,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -236,9 +240,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.173"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
@ -313,9 +317,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
@ -356,7 +360,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -367,9 +371,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.103"
|
||||
version = "2.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -386,7 +390,7 @@ dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -435,7 +439,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -444,7 +448,16 @@ version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets 0.53.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -453,14 +466,30 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm 0.52.6",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
"windows_i686_gnullvm 0.53.0",
|
||||
"windows_i686_msvc 0.53.0",
|
||||
"windows_x86_64_gnu 0.53.0",
|
||||
"windows_x86_64_gnullvm 0.53.0",
|
||||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -469,48 +498,96 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
|
||||
@ -8,3 +8,4 @@ pretty_env_logger.workspace = true
|
||||
log.workspace = true
|
||||
clap.workspace = true
|
||||
trevors_utilities.workspace = true
|
||||
core = { path = "../core" }
|
||||
|
||||
12
cli/src/bin/decode.rs
Normal file
12
cli/src/bin/decode.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use core::instruction::Instruction;
|
||||
use core::address_mode::AddressMode;
|
||||
use core::isa::decoder::Decoder;
|
||||
|
||||
fn main() {
|
||||
println!("Taxation is Theft");
|
||||
|
||||
Decoder::decode(vec![0b11100011]);
|
||||
|
||||
let instruction = Instruction::ADC(AddressMode::Immediate(0x45));
|
||||
println!("Instruction = {:?}", instruction.to_string());
|
||||
}
|
||||
@ -2,4 +2,4 @@ fn main() {
|
||||
println!("Taxation is theft.");
|
||||
println!("TODO:");
|
||||
println!(" Load specified binary and parse it out to ASM");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,3 +2,5 @@
|
||||
name = "core"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
[dependencies]
|
||||
log = "0.4.26"
|
||||
15
core/src/address_mode.rs
Normal file
15
core/src/address_mode.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use std::ops::Add;
|
||||
use crate::mos6502cpu::Mos6502Cpu;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum AddressMode {
|
||||
Accumulator,
|
||||
Immediate(u8),
|
||||
ZeroPage(u8),
|
||||
ZeroPageX(u8),
|
||||
Absolute(u16),
|
||||
AbsoluteX(u16),
|
||||
AbsoluteY(u16),
|
||||
IndirectX(u8),
|
||||
IndirectY(u8),
|
||||
}
|
||||
207
core/src/constants.rs
Normal file
207
core/src/constants.rs
Normal file
@ -0,0 +1,207 @@
|
||||
// Instruction OP Codes
|
||||
|
||||
/// ADC
|
||||
pub const ISA_OP_ADC_I: u8 = 0x69;
|
||||
pub const ISA_OP_ADC_Z: u8 = 0x65;
|
||||
pub const ISA_OP_ADC_ZX: u8 = 0x75;
|
||||
pub const ISA_OP_ADC_ABS: u8 = 0x6d;
|
||||
pub const ISA_OP_ADC_ABSX: u8 = 0x7d;
|
||||
pub const ISA_OP_ADC_ABSY: u8 = 0x79;
|
||||
pub const ISA_OP_ADC_INDX: u8 = 0x61;
|
||||
pub const ISA_OP_ADC_INDY: u8 = 0x71;
|
||||
/// AND
|
||||
pub const ISA_OP_AND_I: u8 = 0x29;
|
||||
pub const ISA_OP_AND_Z: u8 = 0x25;
|
||||
pub const ISA_OP_AND_ZX: u8 = 0x35;
|
||||
pub const ISA_OP_AND_ABS: u8 = 0x2d;
|
||||
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;
|
||||
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;
|
||||
pub const ISA_OP_EOR_ABS: u8 = 0x4d;
|
||||
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;
|
||||
pub const ISA_OP_LDA_ABS: u8 = 0xAD;
|
||||
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_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;
|
||||
pub const ISA_OP_ORA_ABS: u8 = 0x0d;
|
||||
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;
|
||||
pub const ISA_OP_ROR_ABS: u8 = 0x6e;
|
||||
pub const ISA_OP_ROR_ABSX: u8 = 0x7e;
|
||||
pub const ISA_OP_RTI: u8 = 0x40;
|
||||
pub const ISA_OP_RTS: u8 = 0x60;
|
||||
pub const ISA_OP_SBC_I: u8 = 0xe9;
|
||||
pub const ISA_OP_SBC_ZP: u8 = 0xe5;
|
||||
pub const ISA_OP_SBC_ZPX: u8 = 0xf5;
|
||||
pub const ISA_OP_SBC_ABS: u8 = 0xed;
|
||||
pub const ISA_OP_SBC_ABSX: u8 = 0xfd;
|
||||
pub const ISA_OP_SBC_ABSY: u8 = 0xf9;
|
||||
pub const ISA_OP_SBC_INDX: u8 = 0xe1;
|
||||
pub const ISA_OP_SBC_INDY: u8 = 0xf1;
|
||||
pub const ISA_OP_SEC: u8 = 0x38;
|
||||
pub const ISA_OP_SED: u8 = 0xf8;
|
||||
pub const ISA_OP_SEI: u8 = 0x78;
|
||||
pub const ISA_OP_STA_ZP: u8 = 0x85;
|
||||
pub const ISA_OP_STA_ZPX: u8 = 0x95;
|
||||
pub const ISA_OP_STA_ABS: u8 = 0x8d;
|
||||
pub const ISA_OP_STA_ABSX: u8 = 0x9d;
|
||||
pub const ISA_OP_STA_ABSY: u8 = 0x99;
|
||||
pub const ISA_OP_STA_INDX: u8 = 0x81;
|
||||
pub const ISA_OP_STA_INDY: u8 = 0x91;
|
||||
pub const ISA_OP_STX_ZP: u8 = 0x86;
|
||||
pub const ISA_OP_STX_ZPX: u8 = 0x96;
|
||||
pub const ISA_OP_STX_ABS: u8 = 0x8e;
|
||||
pub const ISA_OP_STY_ZP: u8 = 0x84;
|
||||
pub const ISA_OP_STY_ZPX: u8 = 0x94;
|
||||
pub const ISA_OP_STY_ABS: u8 = 0x8c;
|
||||
pub const ISA_OP_TAX: u8 = 0xaa;
|
||||
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;
|
||||
1730
core/src/instruction.rs
Normal file
1730
core/src/instruction.rs
Normal file
File diff suppressed because it is too large
Load Diff
74
core/src/isa/decoder.rs
Normal file
74
core/src/isa/decoder.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use crate::address_mode::AddressMode::*;
|
||||
use crate::constants::*;
|
||||
use crate::instruction::Instruction;
|
||||
use crate::instruction::Instruction::*;
|
||||
|
||||
pub struct Decoder {}
|
||||
|
||||
|
||||
impl Decoder {
|
||||
/// decode
|
||||
///
|
||||
/// Returns the decoded instruction or a NOP.
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
|
||||
#[test]
|
||||
fn valid_decodes() {
|
||||
let params = vec![
|
||||
(vec![ISA_OP_ADC_I, 0xab], ADC(Immediate(0xab))),
|
||||
(vec![ISA_OP_ADC_Z, 0xab], ADC(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ADC_ZX, 0xab], ADC(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ADC_ABS, 0xab, 0xcd], ADC(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ADC_ABSX, 0xcd, 0xab], ADC(AbsoluteX(0xabcd))),
|
||||
(vec![ISA_OP_ADC_ABSY, 0xcd, 0xab], ADC(AbsoluteY(0xabcd))),
|
||||
(vec![ISA_OP_ADC_INDX, 0xab], ADC(IndirectX(0xab))),
|
||||
(vec![ISA_OP_ADC_INDY, 0xcd], ADC(IndirectY(0xcd))),
|
||||
|
||||
(vec![ISA_OP_AND_I, 0xab], AND(Immediate(0xab))),
|
||||
(vec![ISA_OP_AND_Z, 0xab], AND(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_AND_ZX, 0xab], AND(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_AND_ABS, 0xcd, 0xab], AND(Absolute(0xabcd))),
|
||||
|
||||
(vec![ISA_OP_ASL_A], ASL(Accumulator)),
|
||||
(vec![ISA_OP_ASL_Z, 0xab], ASL(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ASL_ZX, 0xab], ASL(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ASL_ABS, 0xab, 0xcd], ASL(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ASL_ABSX, 0xab, 0xcd], ASL(AbsoluteX(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BCC, 0xab], BCC(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BEQ, 0xab], BEQ(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BIT_ZP, 0xab], BIT(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_BIT_ABS, 0xab, 0xcd], BIT(Absolute(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BMI, 0xab], BMI(Immediate(0xab))),
|
||||
(vec![ISA_OP_BNE, 0xab], BNE(Immediate(0xab))),
|
||||
(vec![ISA_OP_BPL, 0xab], BPL(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVC, 0xab], BVC(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVS, 0xab], BVS(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BRK], BRK),
|
||||
|
||||
];
|
||||
|
||||
for (bytes, instruction) in params {
|
||||
println!("Expecting {:?} to be {:?}", bytes, instruction);
|
||||
|
||||
assert_eq!(
|
||||
Decoder::decode(bytes),
|
||||
instruction
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
129
core/src/isa/encode.rs
Normal file
129
core/src/isa/encode.rs
Normal file
@ -0,0 +1,129 @@
|
||||
use crate::address_mode::AddressMode::*;
|
||||
use crate::constants::*;
|
||||
use crate::instruction::Instruction;
|
||||
use crate::instruction::Instruction::*;
|
||||
|
||||
pub struct Encoder {}
|
||||
|
||||
impl Encoder {
|
||||
pub fn encode(to_encode: Instruction) -> Vec<u8> {
|
||||
match to_encode {
|
||||
// ADC(_) => {}
|
||||
// AND(_) => {}
|
||||
// ASL(_) => {}
|
||||
BCC(mode) => {
|
||||
match mode {
|
||||
Immediate(address)=> {
|
||||
vec![ISA_OP_BCC, address]
|
||||
}
|
||||
_ => NOP.to_bytes()
|
||||
}
|
||||
}
|
||||
// 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 => {}
|
||||
_ => NOP.to_bytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::constants::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn adc_decode() {
|
||||
let params = vec![
|
||||
(vec![ISA_OP_ADC_I, 0xab], ADC(Immediate(0xab))),
|
||||
(vec![ISA_OP_ADC_Z, 0xab], ADC(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ADC_ZX, 0xab], ADC(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ADC_ABS, 0xab, 0xcd], ADC(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ADC_ABSX, 0xcd, 0xab], ADC(AbsoluteX(0xabcd))),
|
||||
(vec![ISA_OP_ADC_ABSY, 0xcd, 0xab], ADC(AbsoluteY(0xabcd))),
|
||||
(vec![ISA_OP_ADC_INDX, 0xab], ADC(IndirectX(0xab))),
|
||||
(vec![ISA_OP_ADC_INDY, 0xcd], ADC(IndirectY(0xcd))),
|
||||
|
||||
(vec![ISA_OP_AND_I, 0xab], AND(Immediate(0xab))),
|
||||
(vec![ISA_OP_AND_Z, 0xab], AND(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_AND_ZX, 0xab], AND(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_AND_ABS, 0xcd, 0xab], AND(Absolute(0xabcd))),
|
||||
|
||||
(vec![ISA_OP_ASL_A], ASL(Accumulator)),
|
||||
(vec![ISA_OP_ASL_Z, 0xab], ASL(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_ASL_ZX, 0xab], ASL(ZeroPageX(0xab))),
|
||||
(vec![ISA_OP_ASL_ABS, 0xab, 0xcd], ASL(Absolute(0xcdab))),
|
||||
(vec![ISA_OP_ASL_ABSX, 0xab, 0xcd], ASL(AbsoluteX(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BCC, 0xab], BCC(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BEQ, 0xab], BEQ(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BIT_ZP, 0xab], BIT(ZeroPage(0xab))),
|
||||
(vec![ISA_OP_BIT_ABS, 0xab, 0xcd], BIT(Absolute(0xcdab))),
|
||||
|
||||
(vec![ISA_OP_BMI, 0xab], BMI(Immediate(0xab))),
|
||||
(vec![ISA_OP_BNE, 0xab], BNE(Immediate(0xab))),
|
||||
(vec![ISA_OP_BPL, 0xab], BPL(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVC, 0xab], BVC(Immediate(0xab))),
|
||||
(vec![ISA_OP_BVS, 0xab], BVS(Immediate(0xab))),
|
||||
|
||||
(vec![ISA_OP_BRK], BRK),
|
||||
|
||||
];
|
||||
|
||||
for (bytes, instruction) in params {
|
||||
let encoded = Encoder::encode(bytes);
|
||||
assert_eq!(encoded, instruction.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
18
core/src/isa/microcode_steps.rs
Normal file
18
core/src/isa/microcode_steps.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::mos6502flags::Mos6502Flag;
|
||||
|
||||
pub enum MicrocodeStep {
|
||||
ReadRegisterA,
|
||||
ReadRegisterX,
|
||||
ReadRegisterY,
|
||||
ReadFlag(Mos6502Flag),
|
||||
WriteRegisterA,
|
||||
WriteRegisterX,
|
||||
WriteRegisterY,
|
||||
WriteFlag(Mos6502Flag, bool),
|
||||
ReadMemory(u16),
|
||||
WriteMemory(u16, u8),
|
||||
ALUAdd(u8, u8),
|
||||
ALUSub(u8, u8),
|
||||
ALUAddC(u8, u8, bool),
|
||||
ALUSubC(u8, u8, bool),
|
||||
}
|
||||
4
core/src/isa/mod.rs
Normal file
4
core/src/isa/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
pub mod encode;
|
||||
pub mod decoder;
|
||||
pub mod microcode_steps;
|
||||
@ -0,0 +1,6 @@
|
||||
pub mod address_mode;
|
||||
pub mod mos6502cpu;
|
||||
pub mod instruction;
|
||||
pub mod mos6502flags;
|
||||
pub mod isa;
|
||||
pub mod constants;
|
||||
72
core/src/mos6502cpu.rs
Normal file
72
core/src/mos6502cpu.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use crate::mos6502flags::{Mos6502Flag, Mos6502Flags};
|
||||
|
||||
pub const SIZE_1KB: usize = 1024 * 1024;
|
||||
pub const SIZE_64KB: usize = SIZE_1KB * 64;
|
||||
|
||||
pub struct Mos6502Cpu {
|
||||
memory: [u8; SIZE_64KB],
|
||||
a: u8,
|
||||
x: u8,
|
||||
y: u8,
|
||||
flags: Mos6502Flags,
|
||||
pc: u16,
|
||||
s: u8,
|
||||
microcode_step: u8
|
||||
}
|
||||
|
||||
impl Mos6502Cpu {
|
||||
pub fn new() -> Mos6502Cpu {
|
||||
Mos6502Cpu {
|
||||
memory: [0; SIZE_64KB],
|
||||
a: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
flags: Mos6502Flags::default(),
|
||||
pc: 0,
|
||||
s: 0xfd,
|
||||
microcode_step: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peek_flag(&self, flag_to_read: Mos6502Flag) -> bool {
|
||||
self.flags.flag(flag_to_read)
|
||||
}
|
||||
pub fn poke_flag(&mut self, flag_to_set: Mos6502Flag, new_value: bool) {
|
||||
if new_value { self.flags.set_flag(flag_to_set) } else { self.flags.clear_flag(flag_to_set) }
|
||||
}
|
||||
|
||||
pub fn peek(&self, offset: u16) -> u8 {
|
||||
self.memory[offset as usize]
|
||||
}
|
||||
|
||||
pub fn poke(&mut self, offset: u16, value: u8) {
|
||||
self.memory[offset as usize] = value
|
||||
}
|
||||
|
||||
pub fn peek_a(&self) -> u8 {
|
||||
self.a
|
||||
}
|
||||
pub fn poke_a(&mut self, new_a: u8) {
|
||||
self.a = new_a;
|
||||
}
|
||||
|
||||
pub fn peek_x(&self) -> u8 {
|
||||
self.x
|
||||
}
|
||||
|
||||
pub fn poke_x(&mut self, new_x: u8) {
|
||||
self.x = new_x
|
||||
}
|
||||
|
||||
pub fn peek_y(&self) -> u8 {
|
||||
self.y
|
||||
}
|
||||
|
||||
pub fn poke_y(&mut self, new_y: u8) {
|
||||
self.y = new_y
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
|
||||
}
|
||||
}
|
||||
98
core/src/mos6502flags.rs
Normal file
98
core/src/mos6502flags.rs
Normal file
@ -0,0 +1,98 @@
|
||||
|
||||
pub enum Mos6502Flag {
|
||||
Carry,
|
||||
Zero,
|
||||
Interrupt,
|
||||
Decimal,
|
||||
Break,
|
||||
Overflow,
|
||||
Negative
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Mos6502Flags {
|
||||
carry: bool,
|
||||
zero: bool,
|
||||
interrupt: bool,
|
||||
decimal: bool,
|
||||
break_flag: bool,
|
||||
overflow: bool,
|
||||
negative: bool,
|
||||
}
|
||||
|
||||
impl Mos6502Flags {
|
||||
|
||||
pub fn set_flag(&mut self, flag_to_set: Mos6502Flag) {
|
||||
self.change_flag(flag_to_set, true);
|
||||
}
|
||||
|
||||
pub fn clear_flag(&mut self, flag_to_clear: Mos6502Flag) {
|
||||
self.change_flag(flag_to_clear, false);
|
||||
}
|
||||
|
||||
fn change_flag(&mut self, flag_to_change: Mos6502Flag, new_value: bool) {
|
||||
match flag_to_change {
|
||||
Mos6502Flag::Carry => {
|
||||
self.carry = new_value
|
||||
}
|
||||
Mos6502Flag::Zero => {
|
||||
self.zero = new_value
|
||||
}
|
||||
Mos6502Flag::Interrupt => {
|
||||
self.interrupt = new_value
|
||||
}
|
||||
Mos6502Flag::Decimal => {
|
||||
self.decimal = new_value
|
||||
}
|
||||
Mos6502Flag::Break => {
|
||||
self.break_flag = new_value
|
||||
}
|
||||
Mos6502Flag::Overflow => {
|
||||
self.overflow = new_value
|
||||
}
|
||||
Mos6502Flag::Negative => {
|
||||
self.negative = new_value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flag(&self, flag_to_read: Mos6502Flag) -> bool {
|
||||
match flag_to_read {
|
||||
Mos6502Flag::Carry => {
|
||||
self.carry
|
||||
}
|
||||
Mos6502Flag::Zero => {
|
||||
self.zero
|
||||
}
|
||||
Mos6502Flag::Interrupt => {
|
||||
self.interrupt
|
||||
}
|
||||
Mos6502Flag::Decimal => {
|
||||
self.decimal
|
||||
}
|
||||
Mos6502Flag::Break => {
|
||||
self.break_flag
|
||||
}
|
||||
Mos6502Flag::Overflow => {
|
||||
self.overflow
|
||||
}
|
||||
Mos6502Flag::Negative => {
|
||||
self.negative
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
let expected = Mos6502Flag::default();
|
||||
|
||||
assert_eq!(expected,
|
||||
Mos6502Flag::default());
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user