more fixed stuff

This commit is contained in:
Trevor Merritt 2025-07-16 15:01:16 -04:00
parent ff43a99e0c
commit 6fcf1547d1
29 changed files with 625 additions and 139 deletions

271
Cargo.lock generated
View File

@ -31,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell 1.21.3",
"version_check", "version_check",
"zerocopy", "zerocopy",
] ]
@ -119,6 +119,15 @@ dependencies = [
"lewton", "lewton",
] ]
[[package]]
name = "autocfg"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
dependencies = [
"autocfg 1.5.0",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.5.0" version = "1.5.0"
@ -229,9 +238,9 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.40" version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -239,9 +248,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.40" version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -251,9 +260,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.40" version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@ -287,6 +296,15 @@ dependencies = [
"error-code", "error-code",
] ]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "color_quant" name = "color_quant"
version = "1.1.0" version = "1.1.0"
@ -327,14 +345,15 @@ name = "core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"log", "log",
"rand", "once_cell 0.1.8",
"rand 0.9.1",
] ]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.4.2" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
@ -466,7 +485,7 @@ dependencies = [
"emath", "emath",
"epaint_default_fonts", "epaint_default_fonts",
"nohash-hasher", "nohash-hasher",
"parking_lot", "parking_lot 0.12.4",
"profiling", "profiling",
] ]
@ -539,6 +558,12 @@ dependencies = [
"ttf-parser 0.21.1", "ttf-parser 0.21.1",
] ]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]] [[package]]
name = "gethostname" name = "gethostname"
version = "0.4.3" version = "0.4.3"
@ -649,7 +674,7 @@ version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [ dependencies = [
"once_cell", "once_cell 1.21.3",
"wasm-bindgen", "wasm-bindgen",
] ]
@ -692,14 +717,23 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]]
name = "lock_api"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
dependencies = [
"scopeguard 0.3.3",
]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.13" version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
dependencies = [ dependencies = [
"autocfg", "autocfg 1.5.0",
"scopeguard", "scopeguard 1.2.0",
] ]
[[package]] [[package]]
@ -761,9 +795,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]] [[package]]
name = "memmap2" name = "memmap2"
version = "0.9.5" version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -808,7 +842,7 @@ version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [ dependencies = [
"autocfg", "autocfg 1.5.0",
] ]
[[package]] [[package]]
@ -928,6 +962,15 @@ dependencies = [
"byteorder", "byteorder",
] ]
[[package]]
name = "once_cell"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37"
dependencies = [
"parking_lot 0.7.1",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.3"
@ -949,14 +992,37 @@ dependencies = [
"ttf-parser 0.25.1", "ttf-parser 0.25.1",
] ]
[[package]]
name = "parking_lot"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
dependencies = [
"lock_api 0.1.5",
"parking_lot_core 0.4.0",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.4" version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [ dependencies = [
"lock_api", "lock_api 0.4.13",
"parking_lot_core", "parking_lot_core 0.9.11",
]
[[package]]
name = "parking_lot_core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
dependencies = [
"libc",
"rand 0.6.5",
"rustc_version",
"smallvec 0.6.14",
"winapi",
] ]
[[package]] [[package]]
@ -1007,7 +1073,7 @@ dependencies = [
"concurrent-queue", "concurrent-queue",
"hermit-abi", "hermit-abi",
"pin-project-lite", "pin-project-lite",
"rustix 1.0.7", "rustix 1.0.8",
"tracing", "tracing",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@ -1108,14 +1174,43 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
dependencies = [
"autocfg 0.1.8",
"libc",
"rand_chacha 0.1.1",
"rand_core 0.4.2",
"rand_hc",
"rand_isaac",
"rand_jitter",
"rand_os",
"rand_pcg",
"rand_xorshift",
"winapi",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
dependencies = [ dependencies = [
"rand_chacha", "rand_chacha 0.9.0",
"rand_core", "rand_core 0.9.3",
]
[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
dependencies = [
"autocfg 0.1.8",
"rand_core 0.3.1",
] ]
[[package]] [[package]]
@ -1125,9 +1220,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core 0.9.3",
] ]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.9.3" version = "0.9.3"
@ -1137,6 +1247,77 @@ dependencies = [
"getrandom 0.3.3", "getrandom 0.3.3",
] ]
[[package]]
name = "rand_hc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rand_isaac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rand_jitter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
dependencies = [
"libc",
"rand_core 0.4.2",
"winapi",
]
[[package]]
name = "rand_os"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
dependencies = [
"cloudabi",
"fuchsia-cprng",
"libc",
"rand_core 0.4.2",
"rdrand",
"winapi",
]
[[package]]
name = "rand_pcg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
dependencies = [
"autocfg 0.1.8",
"rand_core 0.4.2",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.13" version = "0.5.13"
@ -1175,6 +1356,15 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.44" version = "0.38.44"
@ -1190,15 +1380,15 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "1.0.7" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [ dependencies = [
"bitflags 2.9.1", "bitflags 2.9.1",
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.9.4", "linux-raw-sys 0.9.4",
"windows-sys 0.59.0", "windows-sys 0.60.2",
] ]
[[package]] [[package]]
@ -1213,12 +1403,33 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
@ -1313,8 +1524,8 @@ checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"getrandom 0.3.3", "getrandom 0.3.3",
"once_cell", "once_cell 1.21.3",
"rustix 1.0.7", "rustix 1.0.8",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@ -1425,7 +1636,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell 1.21.3",
"wasm-bindgen-macro", "wasm-bindgen-macro",
] ]
@ -1567,7 +1778,7 @@ checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615"
dependencies = [ dependencies = [
"dlib", "dlib",
"log", "log",
"once_cell", "once_cell 1.21.3",
"pkg-config", "pkg-config",
] ]

View File

@ -7,7 +7,7 @@ pub struct CpuDisplay {}
impl CpuDisplay { impl CpuDisplay {
pub fn render(cpu: &Mos6502Cpu, x_offset: f32, y_offset: f32) { pub fn render(cpu: &Mos6502Cpu, x_offset: f32, y_offset: f32) {
// get the data to display... // get the data to display...
let (pc, a, x, y, address_bus, data_bus, microsteps_remaining, reset_vector, interrupt_vector) = cpu.dump_data(); let (pc, a, x, y, address_bus, data_bus, microsteps_remaining, reset_vector, interrupt_vector, nmi_vector) = cpu.dump_data();
// ...build the interface // ...build the interface
Self::draw_square(x_offset, y_offset, x_offset + 300.0, y_offset + 85.0, BLACK); Self::draw_square(x_offset, y_offset, x_offset + 300.0, y_offset + 85.0, BLACK);

21
cli/src/bin/ram_rom.rs Normal file
View File

@ -0,0 +1,21 @@
use std::fs;
fn main() {
println!("Taxation is Theft");
// let opts = CliOptions::parse();
let path = "/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256/checksum.bin";
let bytes = match fs::read(path) {
Ok(bytes) => {
println!("Read {} bytes.", bytes.len());
bytes
},
Err(e) => {
eprintln!("FAIL to read rom.");
panic!("No rom no run.");
vec![]
}
};
}

View File

@ -1,5 +1,7 @@
use std::fs;
use clap::Parser; use clap::Parser;
use core::computers::rom_only::backplane::RomOnlyComputer; use core::computers::rom_only::backplane::RomOnlyComputer;
use core::periph::backplane::Backplane;
#[derive(Parser)] #[derive(Parser)]
struct CliOptions { struct CliOptions {
@ -11,8 +13,35 @@ struct CliOptions {
fn main() { fn main() {
println!("Taxation is theft"); println!("Taxation is theft");
let opts = CliOptions::parse(); // let opts = CliOptions::parse();
let path = "/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256/checksum.bin";
let mut rom_only = RomOnlyComputer::new(); let bytes = match fs::read(path) {
rom_only.tick() Ok(bytes) => {
println!("Read {} bytes.", bytes.len());
bytes
},
Err(e) => {
eprintln!("FAIL to read rom.");
panic!("No rom no run.");
vec![]
}
};
let mut rom_only = RomOnlyComputer::program((&bytes[..]).to_vec());
rom_only.set_read_mode(true);
rom_only.set_address_bus(0x05);
rom_only.tick();
println!("COMPUTER: Read {:02x} from ROM", rom_only.data_bus()) ;
println!("COMPUTER: Read {:04x} from Address Bus", rom_only.address_bus());
println!("----");
rom_only.set_read_mode(true);
rom_only.set_address_bus(0x07);
rom_only.tick();
println!("COMPUTER: Read {:02x} from ROM", rom_only.data_bus()) ;
println!("COMPUTER: Read {:04x} from Address Bus", rom_only.address_bus());
println!("----");
} }

View File

@ -5,3 +5,4 @@ edition = "2024"
[dependencies] [dependencies]
log = "0.4" log = "0.4"
rand = "0.9.0" rand = "0.9.0"
once_cell = "0.1"

25
core/src/backplane.rs Normal file
View File

@ -0,0 +1,25 @@
use crate::mos6502cpu::cpu::Mos6502Cpu;
use crate::periph::ram_chip::RamChip;
/// BackplaneBuilder
///
/// Builds a Backplane for a 6502 Emulated PC
struct BackplaneBuilder {
cpu: Mos6502Cpu,
// ram_modules: Vec<dyn RamChip>
}
impl BackplaneBuilder {
pub fn add_cpu(mut self, new_cpu: Mos6502Cpu) -> Self {
self.cpu = new_cpu;
self
}
pub fn add_ram(mut self, new_ram: impl RamChip) -> Self {
// self.ram_modules.push(new_ram);
self
}
}

View File

@ -1,3 +1,4 @@
pub mod beneater; pub mod beneater;
pub mod rom_only; pub mod rom_only;
pub mod kim1; pub mod kim1;
pub mod ram_rom;

View File

@ -0,0 +1,53 @@
use crate::periph::at28c256::At28C256;
use crate::periph::backplane::Backplane;
use crate::periph::hm62256::Hm62256;
pub struct RamRomComputer {
rom: At28C256,
ram: Hm62256,
data_bus: u8,
address_bus: u16,
read_mode: bool,
}
impl Backplane for RamRomComputer {
fn data_bus(&self) -> u8 {
self.data_bus
}
fn address_bus(&self) -> u16 {
self.address_bus
}
fn read_mode(&self) -> bool {
self.read_mode
}
fn tick(&mut self) {
todo!()
}
fn set_read_mode(&mut self, new_mode: bool) {
self.read_mode = new_mode;
}
fn set_address_bus(&mut self, new_value: u16) {
self.address_bus = new_value;
}
fn set_data_bus(&mut self, new_value: u8) {
self.data_bus = new_value;
}
}
impl RamRomComputer {
pub fn new() -> RamRomComputer {
RamRomComputer {
rom: At28C256::default(),
ram: Hm62256::default(),
data_bus: 0x00,
address_bus: 0x0000,
/// is the CPU reading from the 'other' device?
read_mode: true
}
}
}

View File

@ -0,0 +1 @@
pub mod backplane;

View File

@ -1,34 +1,59 @@
use crate::constants::constants_system::{SIZE_32KB, SIZE_64KB}; use crate::constants::constants_system::{SIZE_32KB, SIZE_64KB};
use crate::periph::at28c256::At28C256; use crate::periph::at28c256::At28C256;
use crate::periph::hm62256::Hm62256; use crate::periph::backplane::Backplane;
use crate::periph::rom_chip::RomChip; use crate::periph::rom_chip::RomChip;
pub struct RomOnlyComputer { pub struct RomOnlyComputer {
rom: At28C256, rom: At28C256,
data_bus: u8, data_bus: u8,
address_bus: u16 address_bus: u16,
read_mode: bool,
}
impl Backplane for RomOnlyComputer {
fn data_bus(&self) -> u8 { self.data_bus }
fn address_bus(&self) -> u16 { self.address_bus }
fn read_mode(&self) -> bool { self.read_mode }
fn set_read_mode(&mut self, new_mode: bool) {
self.read_mode = new_mode
}
fn set_data_bus(&mut self, new_value: u8) {
self.data_bus = new_value
}
fn set_address_bus(&mut self, new_value: u16) {
self.address_bus = new_value
}
fn tick(&mut self) {
println!("COMPUTER: Preparing to tick.");
// do are we being addressed?
println!("COMPUTER: BUSSES PRE: 0x{:04x} 0x{:02x} {}", self.address_bus, self.data_bus, self.read_mode);
let (new_addr, new_data) = self.rom.tick(self.address_bus, self.data_bus, self.read_mode);
self.set_address_bus(new_addr);
self.set_data_bus(new_data);
println!("COMPUTER: BUSSES POST: 0x{:04x} 0x{:02x} {}", self.address_bus, self.data_bus, self.read_mode);
println!("COMPUTER: Done ticking.");
}
} }
impl RomOnlyComputer { impl RomOnlyComputer {
pub fn new() -> RomOnlyComputer { pub fn new() -> RomOnlyComputer {
RomOnlyComputer::program(&[0x00; SIZE_32KB]) let mut working = vec![0x00u8; SIZE_32KB];
for index in 0..SIZE_32KB {
working[index] = index as u8;
}
RomOnlyComputer::program(working)
} }
pub fn program(rom: &[u8; SIZE_32KB]) -> RomOnlyComputer { pub fn program(rom: Vec<u8>) -> RomOnlyComputer {
RomOnlyComputer { RomOnlyComputer {
rom: *At28C256::new(0x000, rom), rom: At28C256::new(0x000, 0x3fff, rom),
address_bus: 0x0000, address_bus: 0x0000,
data_bus: 0x00 data_bus: 0x00,
read_mode: true,
} }
} }
pub fn tick(&mut self) {
println!("Preparing to tick.");
// do are we being addressed?
println!("Done ticking.");
}
} }

View File

@ -0,0 +1,7 @@
use std::borrow::ToOwned;
use once_cell::unsync::Lazy;
pub const TEST_RESOURCES_ROOT: &str = "/home/tmerritt/Projects/resources/test";
pub const TEST_PERIPH_ROOT: &str = "/home/tmerritt/Projects/resources/test/periph";
pub const TEST_PERIPH_AT28C256_ROOT: &str = "/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256";

View File

@ -3,3 +3,4 @@ pub mod constants_isa_stub;
pub mod constants_system; pub mod constants_system;
pub mod constants_via6522; pub mod constants_via6522;
pub mod constants_mos6530; pub mod constants_mos6530;
pub mod constants_test;

View File

@ -11,3 +11,4 @@ pub mod op_info;
pub mod operand; pub mod operand;
pub mod operation; pub mod operation;
pub mod periph; pub mod periph;
mod backplane;

View File

@ -526,7 +526,7 @@ impl Mos6502Cpu {
} }
} }
} }
/*
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@ -537,6 +537,12 @@ mod test {
fn clc() { fn clc() {
// setup the CPU for our test // setup the CPU for our test
let mut cpu = Mos6502Cpu::default(); let mut cpu = Mos6502Cpu::default();
// tick through the reset cycle
while !cpu.has_reset {
cpu.tick();
}
println!("DONE RESET TICKS");
cpu.flags.set_flag(Carry); cpu.flags.set_flag(Carry);
// Load our 'test program' // Load our 'test program'
cpu.memory[0x6000] = ISA_OP_CLC; cpu.memory[0x6000] = ISA_OP_CLC;
@ -763,3 +769,4 @@ mod test {
assert_eq!(cpu.memory[0xab], 0b1010_1010);; assert_eq!(cpu.memory[0xab], 0b1010_1010);;
} }
} }
*/

View File

@ -13,14 +13,12 @@ impl Mos6502Cpu {
working working
} }
pub(crate) fn reset_cpu(&mut self) { pub(crate) fn reset_cpu(&mut self) {
self.microcode_step = 7 + 4; self.microcode_step = 7 + 6;
// self = &mut Mos6502Cpu::default(); // self = &mut Mos6502Cpu::default();
println!("Should tick 7 times, then 4 cycles to read the reset and int vectors."); println!("Should tick 7 times, then 6 cycles to read the reset and int vectors.");
// read the value at 0xfffa 0xfffb for our NMI vector.
// read the value at 0xfffc 0xfffd for our reset vector. // read the value at 0xfffc 0xfffd for our reset vector.
// read the value at 0xfffe 0xffff for our int vector // read the value at 0xfffe 0xffff for our int vector
} }
} }

View File

@ -0,0 +1,80 @@
use crate::constants::constants_system::SIZE_32KB;
use crate::periph::at28c256::At28C256;
use crate::constants::constants_test::*;
impl At28C256 {
/// checksum
///
/// calculates and returns the checksum for the loaded binary.
/// files with all zero will calculate to zero
pub fn checksum(&self) -> u8 {
At28C256::checksum_static(&self.data[..])
}
pub fn checksum_static(data: &[u8]) -> u8 {
data.iter().fold(0u8, |acc, &b| acc.wrapping_add(b))
}
}
#[cfg(test)]
mod test {
use std::fs;
use std::path::Path;
use crate::constants::constants_system::SIZE_1KB;
use crate::periph::rom_chip::RomChip;
use super::*;
#[test]
fn smoke() { assert!(true); }
#[test]
fn programmed_data_reads_back_same() {
let mut data = At28C256::default();
for i in 0..SIZE_32KB {
data.data[i] = 0xeau8;
}
for offset in 0..SIZE_32KB {
if offset.is_multiple_of(SIZE_1KB) {};
assert_eq!(0xea, data.read(&(offset as u16)));
}
}
#[test]
fn checksums_calculate_correctly_for_zero() {
let data1 = [0x00u8; SIZE_32KB];
assert_eq!(0x00, At28C256::checksum_static(&data1));
}
#[test]
fn checksums_calculate_for_1_byte() {
let data = [0xff; 1];
assert_eq!(0xff, At28C256::checksum_static(&data));
}
#[test]
fn checksums_calculate_for_2_bytes() {
let data = [0xff; 2];
// 0xff + 0xff = 0x1fe
assert_eq!(0xfe, At28C256::checksum_static(&data));
}
#[test]
fn checksums_calculate_for_first_80_bytes() {
println!("STARTING TEST");
let mut checksum = 0x00;
let path = format!("{}{}", TEST_PERIPH_AT28C256_ROOT, "/checksum.bin");
println!("READING [{path}]");
let data = fs::read(path);
match data {
Ok(bytes) => {
println!("Read {} bytes", bytes.len());
checksum = At28C256::checksum_static(&bytes);
println!("Checksum: 0x{:02x}", checksum);
}
Err(e) => eprintln!("Failed to read file: {}", e),
}
assert_eq!(0x58, checksum);
println!("TEST COMPLETE");
}
}

View File

@ -9,10 +9,12 @@ impl Default for At28C256 {
let boxed_array: Box<[u8; SIZE_32KB]> = boxed_slice let boxed_array: Box<[u8; SIZE_32KB]> = boxed_slice
.try_into() .try_into()
.expect("Failed to convert Vec to boxed array"); .expect("Failed to convert Vec to boxed array");
At28C256 { data: boxed_array, At28C256 {
data: boxed_array,
address_bus: 0x0000, address_bus: 0x0000,
data_bus: 0x00, data_bus: 0x00,
offset: 0x0000 offset: 0x0000,
max_offset: 0x3fff,
} }
} }
} }

View File

@ -4,6 +4,7 @@ pub mod tick;
mod new; mod new;
mod program; mod program;
mod dump; mod dump;
mod checksum;
use crate::constants::constants_system::SIZE_32KB; use crate::constants::constants_system::SIZE_32KB;
use crate::periph::rom_chip::RomChip; use crate::periph::rom_chip::RomChip;
@ -11,37 +12,15 @@ use std::io::Read;
/// At28C256 /// At28C256
/// ///
/// Represents a single At28C256 Chip /// Represents a single At28C256 EEPROM Chip
/// ///
/// 256kbit storage /// 256kbit storage
/// 32kbyte storage /// 32kbyte storage
pub struct At28C256 { pub struct At28C256 {
data_bus: u8, data_bus: u8,
address_bus: u16, address_bus: u16,
data: Box<[u8; SIZE_32KB]>, data: Box<[u8]>,
// where in the computer memory map do we live? // where in the computer memory map do we live?
offset: u16 offset: u16,
} max_offset: u16
#[cfg(test)]
mod test {
use super::*;
use crate::constants::constants_system::SIZE_1KB;
#[test]
fn smoke() {
assert!(true)
}
#[test]
fn programmed_data_reads_back_same() {
let mut data = At28C256::default();
for i in 0..SIZE_32KB {
data.data[i] = 0xea;
}
for offset in 0..SIZE_32KB {
if offset.is_multiple_of(SIZE_1KB) {};
assert_eq!(0xea, data.read(&(offset as u16)));
}
}
} }

View File

@ -2,12 +2,15 @@ use crate::constants::constants_system::SIZE_32KB;
use crate::periph::at28c256::At28C256; use crate::periph::at28c256::At28C256;
impl At28C256 { impl At28C256 {
pub fn new(offset: u16, data: &[u8; SIZE_32KB]) -> Self { pub fn new(offset: u16, max_offset: u16, data: Vec<u8>) -> Self {
println!("NEW At28C256 with checksum ${:02x}", At28C256::checksum_static(&data[..]));
At28C256 { At28C256 {
data: (*data).into(), data: data.into_boxed_slice(),
address_bus: 0x0000, address_bus: 0x0000,
data_bus: 0x00, data_bus: 0x00,
offset offset,
max_offset
} }
} }
} }

View File

@ -3,40 +3,66 @@ use crate::periph::at28c256::At28C256;
use crate::periph::hm62256::Hm62256; use crate::periph::hm62256::Hm62256;
impl At28C256 { impl At28C256 {
fn max_address(&self) -> u16 { fn talking_to_me(&self, address: u16) -> bool {
self.offset + SIZE_32KB as u16 address >= self.offset && address < self.max_offset
} }
pub fn tick(&mut self, address_bus: u16, data_bus: u8, read_mode: bool) -> (u16, u8) { pub fn tick(&mut self, address_bus: u16, data_bus: u8, read_mode: bool) -> (u16, u8) {
if address_bus.gt(&self.offset) & address_bus.lt(&self.max_address()) { println!("At28C256: Tick starting for A${address_bus:04x} D${data_bus:02x} R{read_mode}");
if read_mode {
panic!("UNABLE TO WRITE TO ROM"); // we aren't being addressed
} else { // OR
// has to be read mode. its a rom. // we arent reading from the ROM...
if !self.talking_to_me(address_bus) ||
!read_mode {
// ...go away.
return (address_bus, data_bus) return (address_bus, data_bus)
} }
let effective = address_bus - self.offset;
if effective < self.max_offset {
if effective < self.data.len() as u16 {
self.data_bus = self.data[effective as usize];
} else {
self.data_bus = 0x00;
} }
// not for us. } else {
(address_bus, self.data[address_bus as usize]) println!("At28C256: OUTSIDE RANGE. :(");
} return (address_bus, data_bus)
} }
println!("At28C256: Read... {:02x}", self.data_bus);
println!("At28C256: Done with ticking the AtC256");
(address_bus, self.data_bus)
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::fs;
use crate::periph::rom_chip::RomChip;
use super::*; use super::*;
#[test] #[test]
fn smoke() { assert!(true); } fn smoke() { assert!(true); }
#[test] #[test]
fn write_to_memory_read_back_works_at_0() { fn checksum_binary_loads() {
let mut rom = At28C256::default(); let path = "/home/tmerritt/Projects/mos6502/resources/test/periph/at28c256/checksum.bin";
let bytes = match fs::read(path) {
Ok(bytes) => {
println!("Read {} bytes.", bytes.len());
bytes
},
Err(e) => {
eprintln!("FAIL to read rom.");
panic!("No rom no run.");
vec![]
}
};
rom.tick(0x0000, 0xab, false); let mut rom = At28C256::new(0x0000, 0x3fff, bytes);
let (_, new_data) = rom.tick(0x0000, 0x00, true);
assert_eq!(new_data, 0xab); assert_eq!(rom.checksum(), 0x58);
} }
} }

View File

@ -0,0 +1,9 @@
pub trait Backplane {
fn data_bus(&self) -> u8;
fn address_bus(&self) -> u16;
fn read_mode(&self) -> bool;
fn set_read_mode(&mut self, new_mode: bool);
fn set_data_bus(&mut self, new_value: u8);
fn set_address_bus(&mut self, new_value: u16);
fn tick(&mut self);
}

View File

@ -7,12 +7,11 @@ impl Hm62256 {
} }
pub fn tick(&mut self, address_bus: u16, data_bus: u8, read_mode: bool, cs: bool) -> (u16, u8) { pub fn tick(&mut self, address_bus: u16, data_bus: u8, read_mode: bool, cs: bool) -> (u16, u8) {
println!("HM62256RAM TICK START -> 0x{address_bus:04x} 0x{data_bus:02x} {read_mode} {cs}");
if !(address_bus.gt( &self.offset) && address_bus.le(&self.max_address())) { if !(address_bus.gt( &self.offset) && address_bus.le(&self.max_address())) {
return (address_bus, data_bus); return (address_bus, data_bus);
} }
println!("HM62256RAM TICK START -> 0x{address_bus:04x} 0x{data_bus:02x} {read_mode} {cs}");
self.address_bus = address_bus; self.address_bus = address_bus;
self.data_bus = data_bus; self.data_bus = data_bus;
let addr = address_bus.wrapping_sub(self.offset) + self.offset; let addr = address_bus.wrapping_sub(self.offset) + self.offset;

View File

@ -6,3 +6,4 @@ pub mod mos6522;
pub mod mos6530; pub mod mos6530;
pub mod kim1_keypad; pub mod kim1_keypad;
mod bus_device; mod bus_device;
pub mod backplane;

View File

@ -46,6 +46,10 @@ pub struct Mos6522 {
} }
impl Mos6522 { impl Mos6522 {
pub fn max_offset(&self) -> u16 {
self.offset + 0x10
}
pub fn start_clocks(&mut self) { pub fn start_clocks(&mut self) {
loop { loop {
let cycle_start = Instant::now(); let cycle_start = Instant::now();
@ -66,40 +70,40 @@ mod test {
#[test] #[test]
fn registers() { fn registers() {
let mut x = Mos6522::new(); let mut x = Mos6522::new();
x.tick(0b0000_0000, VIA6522_DDRA, false, true); x.tick(VIA6522_DDRA as u16, 0b0000_0000, false, true);
assert_eq!(x.dda, 0b0000_0000); assert_eq!(x.dda, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_DDRA, false, true); x.tick(VIA6522_DDRA as u16, 0b1111_1111, false, true);
assert_eq!(x.dda, 0b1111_1111); assert_eq!(x.dda, 0b1111_1111);
x.tick(0b0000_0000, VIA6522_DDRB, false, true); x.tick(VIA6522_DDRB as u16, 0b0000_0000, false, true);
assert_eq!(x.ddb, 0b0000_0000); assert_eq!(x.ddb, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_DDRB, false, true); x.tick(VIA6522_DDRB as u16, 0b1111_1111, false, true);
assert_eq!(x.ddb, 0b1111_1111); assert_eq!(x.ddb, 0b1111_1111);
x.tick(0b0000_0000, VIA6522_ORA, false, true); x.tick(VIA6522_ORA as u16, 0b0000_0000, false, true);
assert_eq!(x.porta, 0b0000_0000); assert_eq!(x.ora, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_ORA, false, true); x.tick(VIA6522_ORA as u16, 0b1111_1111, false, true);
assert_eq!(x.porta, 0b1111_1111); assert_eq!(x.ora, 0b1111_1111);
x.tick(0b0000_0000, VIA6522_ORB, false, true); x.tick(VIA6522_ORB as u16, 0b0000_0000, false, true);
assert_eq!(x.portb, 0b0000_0000); assert_eq!(x.orb, 0b0000_0000);
x.tick(0b1111_1111, VIA6522_ORB, false, true); x.tick(VIA6522_ORB as u16, 0b1111_1111, false, true);
assert_eq!(x.portb, 0b1111_1111); assert_eq!(x.orb, 0b1111_1111);
} }
#[test] #[test]
fn partial_output_porta() { fn partial_output_porta() {
let mut x = Mos6522::new(); let mut x = Mos6522::new();
x.tick(0b1010_1010, VIA6522_DDRA, false, true); x.tick(VIA6522_DDRA as u16, 0b1010_1010, false, true);
x.tick(0b1111_1111, VIA6522_ORA, false, true); x.tick(VIA6522_ORA as u16,0b1111_1111, false, true);
assert_eq!(x.porta, 0b1010_1010); assert_eq!(x.porta, 0b1010_1010);
} }
#[test] #[test]
fn partial_output_portb() { fn partial_output_portb() {
let mut x = Mos6522::new(); let mut x = Mos6522::new();
x.tick(0b0101_0101, VIA6522_DDRB, false, true); x.tick(VIA6522_DDRB as u16, 0b0101_0101, false, true);
x.tick(0b1111_1111, VIA6522_ORB, false, true); x.tick(VIA6522_ORB as u16, 0b1111_1111, false, true);
assert_eq!(x.portb, 0b0101_0101); assert_eq!(x.portb, 0b0101_0101);
} }
} }

View File

@ -12,13 +12,13 @@ impl Mos6522 {
/// data_bus -> 8 bits from the data bus /// data_bus -> 8 bits from the data bus
/// control -> 4 bits to identify which register to control /// control -> 4 bits to identify which register to control
pub fn tick(&mut self, address_bus: u16, data_bus: u8,reset: bool, rw: bool) -> (u16, u8) { pub fn tick(&mut self, address_bus: u16, data_bus: u8,reset: bool, rw: bool) -> (u16, u8) {
if !(address_bus.gt( &self.offset) && address_bus.le(&self.max_address())) { if !(address_bus >= self.offset && address_bus.le(&self.max_address())) {
return (address_bus, data_bus); return (address_bus, data_bus);
} }
let local_address = address_bus - self.offset; let local_address = address_bus - self.offset;
println!("Mos6522 Tick Start -> D:0x{data_bus:02x} / A:0x{address_bus:02x} / {rw} (Actual 0x{local_address:02x}"); println!("Mos6522 Tick Start -> D:0x{data_bus:02x} / A:0x{address_bus:02x} / {rw} (Actual 0x{local_address:02x} / 0b{local_address:08b})");
if reset { if reset {
// reset process // reset process
println!("Resetting Mos6522"); println!("Resetting Mos6522");
@ -35,25 +35,28 @@ impl Mos6522 {
self.data_bus = data_bus; self.data_bus = data_bus;
match local_address as u8 { match local_address as u8 {
VIA6522_DDRA => { VIA6522_DDRA => {
debug!("Setting DDA to 0x{data_bus:02x}"); println!("Setting DDA to 0x{data_bus:02x}");
// setting the Data Direction for Port A // setting the Data Direction for Port A
self.dda = data_bus; self.dda = data_bus;
}, },
VIA6522_DDRB => {
debug!("Setting DDB to 0x{data_bus:02x}");
// setting the data direction for port b
self.ddb = data_bus;
},
VIA6522_ORB => { VIA6522_ORB => {
// writing data to ORB // writing data to ORB
let masked_data = data_bus & self.ddb; let masked_data = data_bus & self.ddb;
debug!("Setting ORB to 0x{data_bus:02x} / masked at 0x{masked_data:02x}"); println!("Setting ORB to 0x{data_bus:02x} / masked at 0x{masked_data:02x}");
self.orb = data_bus;
self.portb = masked_data; self.portb = masked_data;
}, },
VIA6522_DDRB => {
println!("Setting DDB to 0x{data_bus:02x}");
// setting the data direction for port b
self.ddb = data_bus;
},
VIA6522_ORA => { VIA6522_ORA => {
// writing data to ORA // writing data to ORA
let masked_data = data_bus & self.dda; let masked_data = data_bus & self.dda;
debug!("Setting ORA to 0x{data_bus:02x} / masked at 0x{masked_data:02x}"); println!("Setting ORA to 0x{data_bus:02x} / masked at 0x{masked_data:02x}");
self.ora = data_bus;
self.porta = masked_data; self.porta = masked_data;
}, },
_ => {} _ => {}

View File

@ -12,8 +12,6 @@ use crate::periph::mos6522::mos6522::Mos6522;
/// 64 bytes RAM /// 64 bytes RAM
/// IO Ports (A, B) /// IO Ports (A, B)
/// Timer /// Timer
///
/// SEE ALSO Mos6532
pub struct Mos6530 { pub struct Mos6530 {
pub(crate) data: [u8; SIZE_1KB], pub(crate) data: [u8; SIZE_1KB],
pub(crate) ram: [u8; 64], pub(crate) ram: [u8; 64],
@ -30,3 +28,4 @@ pub struct Mos6530 {
pub(crate) ram_offset: u16, pub(crate) ram_offset: u16,
pub(crate) rom_offset: u16 pub(crate) rom_offset: u16
} }

View File

Binary file not shown.