From 001d3e434c821baad1574f798eb87506984bb8cf Mon Sep 17 00:00:00 2001 From: august kline Date: Sat, 29 Jun 2024 23:38:02 -0400 Subject: [PATCH] terminal mode! i like this better, also functional cli now --- Cargo.lock | 1232 +----------------------------------- Cargo.toml | 14 +- config.toml => george.toml | 0 run.sh | 11 +- src/cpu.rs | 22 +- src/keyboard.rs | 182 ++++-- src/main.rs | 179 ++++-- src/memory.rs | 65 +- src/roms/george.asm | 164 +---- src/roms/george.rom | Bin 32768 -> 32768 bytes src/roms/keyboard.asm | 72 +-- src/roms/template.asm | 88 +++ src/video.rs | 41 +- 13 files changed, 446 insertions(+), 1624 deletions(-) rename config.toml => george.toml (100%) create mode 100644 src/roms/template.asm diff --git a/Cargo.lock b/Cargo.lock index e428cac..36c6fd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,105 +2,12 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - [[package]] name = "anyhow" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.3.0" @@ -132,232 +39,25 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "castaway" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" -dependencies = [ - "rustversion", -] - -[[package]] -name = "cc" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "bitflags 1.3.2", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "textwrap", -] - -[[package]] -name = "clap" -version = "4.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" -dependencies = [ - "anstream", - "anstyle", - "clap_lex 0.7.1", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "clap_lex" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "compact_str" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "ryu", - "static_assertions", -] - -[[package]] -name = "criterion" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" -dependencies = [ - "anes", - "atty", - "cast", - "ciborium", - "clap 3.2.25", - "criterion-plot", - "itertools 0.10.5", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools 0.10.5", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - [[package]] name = "crossterm" version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags", "crossterm_winapi", "libc", "mio", @@ -376,215 +76,28 @@ dependencies = [ "winapi", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "either" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" - [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "georgeemu" version = "0.1.0" dependencies = [ "anyhow", "bdf", - "clap 4.5.7", - "criterion", "crossterm", - "minifb", - "ratatui", "serde", "toml", ] -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] [[package]] name = "indexmap" @@ -593,99 +106,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" -[[package]] -name = "libloading" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" -dependencies = [ - "cfg-if", - "windows-targets 0.52.5", -] - -[[package]] -name = "libredox" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" -dependencies = [ - "bitflags 2.5.0", - "libc", - "redox_syscall 0.4.1", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - [[package]] name = "lock_api" version = "0.4.12" @@ -702,56 +131,12 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" -[[package]] -name = "lru" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" -dependencies = [ - "hashbrown 0.14.5", -] - [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "minifb" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05eddefadb505d3dcb66a89fa77dd0936e72ec84e891cc8fc36e3c05bfe61103" -dependencies = [ - "cc", - "dlib", - "futures", - "instant", - "js-sys", - "lazy_static", - "libc", - "orbclient", - "raw-window-handle", - "serde", - "serde_derive", - "tempfile", - "wasm-bindgen-futures", - "wayland-client", - "wayland-cursor", - "wayland-protocols", - "winapi", - "x11-dl", -] - [[package]] name = "mio" version = "0.8.11" @@ -761,60 +146,9 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys 0.48.0", + "windows-sys", ] -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "orbclient" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" -dependencies = [ - "libc", - "libredox", - "sdl2", - "sdl2-sys", -] - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "parking_lot" version = "0.12.3" @@ -833,63 +167,11 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall", "smallvec", "windows-targets 0.52.5", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "plotters" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" - -[[package]] -name = "plotters-svg" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" -dependencies = [ - "plotters-backend", -] - [[package]] name = "proc-macro2" version = "1.0.86" @@ -908,171 +190,21 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "ratatui" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44c9e68fd46eda15c646fbb85e1040b657a58cdc8c98db1d97a55930d991eef" -dependencies = [ - "bitflags 2.5.0", - "cassowary", - "compact_str", - "crossterm", - "itertools 0.12.1", - "lru", - "paste", - "stability", - "strum", - "unicode-segmentation", - "unicode-truncate", - "unicode-width", -] - -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 2.5.0", + "bitflags", ] -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sdl2" -version = "0.35.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a" -dependencies = [ - "bitflags 1.3.2", - "lazy_static", - "libc", - "sdl2-sys", -] - -[[package]] -name = "sdl2-sys" -version = "0.35.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0" -dependencies = [ - "cfg-if", - "libc", - "version-compare", -] - [[package]] name = "serde" version = "1.0.203" @@ -1093,17 +225,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "serde_spanned" version = "0.6.6" @@ -1143,65 +264,12 @@ dependencies = [ "libc", ] -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "stability" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "syn" version = "2.0.67" @@ -1213,24 +281,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - [[package]] name = "thiserror" version = "1.0.61" @@ -1251,16 +301,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "toml" version = "0.8.14" @@ -1288,7 +328,7 @@ version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ - "indexmap 2.2.6", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -1301,211 +341,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-truncate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226" -dependencies = [ - "itertools 0.12.1", - "unicode-width", -] - -[[package]] -name = "unicode-width" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "version-compare" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "wayland-client" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" -dependencies = [ - "bitflags 1.3.2", - "downcast-rs", - "libc", - "nix", - "scoped-tls", - "wayland-commons", - "wayland-scanner", - "wayland-sys", -] - -[[package]] -name = "wayland-commons" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" -dependencies = [ - "nix", - "once_cell", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-cursor" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" -dependencies = [ - "nix", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" -dependencies = [ - "bitflags 1.3.2", - "wayland-client", - "wayland-commons", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" -dependencies = [ - "proc-macro2", - "quote", - "xml-rs", -] - -[[package]] -name = "wayland-sys" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" -dependencies = [ - "dlib", - "lazy_static", - "pkg-config", -] - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "winapi" version = "0.3.9" @@ -1522,15 +363,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1546,15 +378,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -1684,46 +507,3 @@ checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "xcursor" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" - -[[package]] -name = "xml-rs" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" - -[[package]] -name = "zerocopy" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/Cargo.toml b/Cargo.toml index abd0a3b..7f3e624 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,18 +8,8 @@ edition = "2021" [dependencies] anyhow = "1.0.81" bdf = "0.6.0" -clap = { version = "4.5.4", features = ["derive"] } -criterion = "0.4" crossterm = "0.27.0" -minifb = "0.25.0" -ratatui = "0.26.3" +# minifb = "0.25.0" +# ratatui = "0.26.3" serde = { version = "1.0.197", features = ["serde_derive", "derive"] } toml = "0.8.12" - -[dev-dependencies] -criterion = {version = "0.4", features = ["html_reports"]} - -[[bench]] -name = "benchmark" -path = "src/benches/benchmark.rs" -harness = false diff --git a/config.toml b/george.toml similarity index 100% rename from config.toml rename to george.toml diff --git a/run.sh b/run.sh index 55bd644..89193f6 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,12 @@ #!/usr/bin/env bash -vasm6502_oldstyle ./src/roms/george.asm -dotdir -wdc02 -ldots -Fbin -o ./src/roms/george.rom; -cargo run; +if [ $# -eq 0 ]; then + echo "Provide the name of the rom/asm file to run" + exit 1 +fi + +set -e + +vasm6502_oldstyle ./src/roms/$1.asm -dotdir -wdc02 -ldots -Fbin -o ./src/roms/$1.rom; +cargo run rom "./src/roms/$1.rom"; # hexdump -C ./cpu_dump.bin; diff --git a/src/cpu.rs b/src/cpu.rs index 90090a1..e5cf6f9 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -2,8 +2,8 @@ use crate::instructions::{get_instruction, Instruction}; use crate::memory::{MemHandle, MemoryReader, MemoryWriter}; use crate::types::{Byte, Word}; use std::fmt::Display; -use std::sync::mpsc::{Receiver, Sender}; -use std::thread::sleep; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::thread::{sleep, LocalKey}; use std::time::Duration; use anyhow::Result; @@ -124,6 +124,13 @@ impl Cpu { // state_tx, } } + pub fn new_with_control(memory: MemHandle) -> (Self, CpuController) { + let (tx, rx) = channel::(); + let controller = CpuController(tx); + let receiver = CpuReceiver(rx); + let cpu = Cpu::new(memory, receiver); + (cpu, controller) + } pub fn reset(&mut self) -> Result<()> { let reset_vector_pointer = self.read_word(0xFFFC)?; self.pc = reset_vector_pointer; @@ -203,7 +210,11 @@ impl Cpu { } fn receive_control(&mut self) { - let control = self.receiver.0.recv().unwrap(); + let control = match self.receiver.0.try_recv() { + Ok(control) => control, + Err(_error) => return, // most of the time we won't have any impending control + // messages, just return if that's the case + }; match control { CpuControl::Nmi => self.nmi = true, CpuControl::Irq => self.irq = true, @@ -226,13 +237,13 @@ impl Cpu { } pub fn cycle(&mut self) { - // self.receive_control(); + self.receive_control(); if self.stopped { return; } while self.pending_cycles != 0 { // roughly cycle-accurate timing - sleep(Duration::from_nanos(100)); + sleep(Duration::from_nanos(500)); self.pending_cycles -= 1; } if !self.get_flag(StatusFlag::IrqDisable) && self.irq { @@ -272,7 +283,6 @@ impl Cpu { }, } // self.cycle_count += 1; - sleep(Duration::from_nanos(100)); } pub fn stop(&mut self) { self.stopped = true; diff --git a/src/keyboard.rs b/src/keyboard.rs index 91931a2..1efca0c 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -1,4 +1,5 @@ -use minifb::{InputCallback, Key}; +use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; +// use minifb::{InputCallback, Key}; use crate::memory::{MemHandle, MemoryWriter}; @@ -10,69 +11,64 @@ impl Keyboard { pub fn new(memory: MemHandle) -> Self { Self { memory } } -} - -impl MemoryWriter for Keyboard { - fn write(&self, address: u16, data: u8) { - self.memory.write(address, data); - } -} - -impl InputCallback for Keyboard { - fn add_char(&mut self, _uni_char: u32) {} - fn set_key_state(&mut self, key: Key, _state: bool) { + pub fn read_keys(&self, key: KeyEvent) { let mut row0 = 0; let mut row1 = 0; let mut row2 = 0; let mut row3 = 0; let mut row4 = 0; let mut row5 = 0; + if key.kind == KeyEventKind::Press || key.kind == KeyEventKind::Repeat { + match key.modifiers { + KeyModifiers::SHIFT => row2 ^= 0b1000_0000, + KeyModifiers::CONTROL => row3 ^= 0b1000_0000, + KeyModifiers::ALT => row4 ^= 0b1000_0000, + KeyModifiers::META => row5 ^= 0b1000_0000, + KeyModifiers::SUPER => row5 ^= 0b0010_0000, + _ => {} + }; - match key { - Key::Escape => row0 ^= 0b1000_0000, - Key::W => row0 ^= 0b0100_0000, - Key::E => row0 ^= 0b0010_0000, - Key::R => row0 ^= 0b0001_0000, - Key::T => row0 ^= 0b0000_1000, - Key::U => row0 ^= 0b0000_0100, - Key::O => row0 ^= 0b0000_0010, - Key::Backspace => row0 ^= 0b0000_0001, - Key::Tab => row1 ^= 0b1000_0000, - Key::Q => row1 ^= 0b0100_0000, - Key::S => row1 ^= 0b0010_0000, - Key::G => row1 ^= 0b0001_0000, - Key::Y => row1 ^= 0b0000_1000, - Key::I => row1 ^= 0b0000_0100, - Key::P => row1 ^= 0b0000_0010, - Key::Enter => row1 ^= 0b0000_0001, - Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000, - Key::D => row2 ^= 0b0100_0000, - Key::V => row2 ^= 0b0010_0000, - Key::H => row2 ^= 0b0001_0000, - Key::K => row2 ^= 0b0000_1000, - Key::Apostrophe => row2 ^= 0b0000_0100, - Key::Slash => row2 ^= 0b0000_0010, - Key::A => row2 ^= 0b0000_0001, - Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000, - Key::Z => row3 ^= 0b0100_0000, - Key::F => row3 ^= 0b0010_0000, - Key::B => row3 ^= 0b0001_0000, - Key::J => row3 ^= 0b0000_1000, - Key::L => row3 ^= 0b0000_0100, - Key::Key2 => row3 ^= 0b0000_0010, - Key::Key4 => row3 ^= 0b0000_0001, - Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000, - Key::X => row4 ^= 0b0100_0000, - Key::C => row4 ^= 0b0010_0000, - Key::N => row4 ^= 0b0001_0000, - Key::M => row4 ^= 0b0000_1000, - Key::Comma => row4 ^= 0b0000_0100, - Key::Key1 => row4 ^= 0b0000_0010, - Key::Key3 => row4 ^= 0b0000_0001, - Key::LeftSuper => row5 ^= 0b1000_0000, - Key::Space => row5 ^= 0b0100_0000, - Key::RightSuper => row5 ^= 0b0010_0000, - _ => {} + match key.code { + KeyCode::Esc => row0 ^= 0b1000_0000, + KeyCode::Char('w') => row0 ^= 0b0100_0000, + KeyCode::Char('e') => row0 ^= 0b0010_0000, + KeyCode::Char('r') => row0 ^= 0b0001_0000, + KeyCode::Char('t') => row0 ^= 0b0000_1000, + KeyCode::Char('u') => row0 ^= 0b0000_0100, + KeyCode::Char('o') => row0 ^= 0b0000_0010, + KeyCode::Backspace => row0 ^= 0b0000_0001, + KeyCode::Tab => row1 ^= 0b1000_0000, + KeyCode::Char('q') => row1 ^= 0b0100_0000, + KeyCode::Char('s') => row1 ^= 0b0010_0000, + KeyCode::Char('g') => row1 ^= 0b0001_0000, + KeyCode::Char('y') => row1 ^= 0b0000_1000, + KeyCode::Char('i') => row1 ^= 0b0000_0100, + KeyCode::Char('p') => row1 ^= 0b0000_0010, + KeyCode::Enter => row1 ^= 0b0000_0001, + KeyCode::Char('d') => row2 ^= 0b0100_0000, + KeyCode::Char('v') => row2 ^= 0b0010_0000, + KeyCode::Char('h') => row2 ^= 0b0001_0000, + KeyCode::Char('k') => row2 ^= 0b0000_1000, + KeyCode::Char('\'') => row2 ^= 0b0000_0100, + KeyCode::Char('/') => row2 ^= 0b0000_0010, + KeyCode::Char('a') => row2 ^= 0b0000_0001, + KeyCode::Char('z') => row3 ^= 0b0100_0000, + KeyCode::Char('f') => row3 ^= 0b0010_0000, + KeyCode::Char('b') => row3 ^= 0b0001_0000, + KeyCode::Char('j') => row3 ^= 0b0000_1000, + KeyCode::Char('l') => row3 ^= 0b0000_0100, + KeyCode::Char('2') => row3 ^= 0b0000_0010, + KeyCode::Char('4') => row3 ^= 0b0000_0001, + KeyCode::Char('x') => row4 ^= 0b0100_0000, + KeyCode::Char('c') => row4 ^= 0b0010_0000, + KeyCode::Char('n') => row4 ^= 0b0001_0000, + KeyCode::Char('m') => row4 ^= 0b0000_1000, + KeyCode::Char(',') => row4 ^= 0b0000_0100, + KeyCode::Char('1') => row4 ^= 0b0000_0010, + KeyCode::Char('3') => row4 ^= 0b0000_0001, + KeyCode::Char(' ') => row5 ^= 0b0100_0000, + _ => {} + } }; self.memory.write(0x4400, row0); @@ -83,3 +79,75 @@ impl InputCallback for Keyboard { self.memory.write(0x4405, row5); } } + +impl MemoryWriter for Keyboard { + fn write(&self, address: u16, data: u8) { + self.memory.write(address, data); + } +} + +// impl InputCallback for Keyboard { +// fn add_char(&mut self, _uni_char: u32) {} +// fn set_key_state(&mut self, key: Key, _state: bool) { +// let mut row0 = 0; +// let mut row1 = 0; +// let mut row2 = 0; +// let mut row3 = 0; +// let mut row4 = 0; +// let mut row5 = 0; + +// match key { +// Key::Escape => row0 ^= 0b1000_0000, +// Key::W => row0 ^= 0b0100_0000, +// Key::E => row0 ^= 0b0010_0000, +// Key::R => row0 ^= 0b0001_0000, +// Key::T => row0 ^= 0b0000_1000, +// Key::U => row0 ^= 0b0000_0100, +// Key::O => row0 ^= 0b0000_0010, +// Key::Backspace => row0 ^= 0b0000_0001, +// Key::Tab => row1 ^= 0b1000_0000, +// Key::Q => row1 ^= 0b0100_0000, +// Key::S => row1 ^= 0b0010_0000, +// Key::G => row1 ^= 0b0001_0000, +// Key::Y => row1 ^= 0b0000_1000, +// Key::I => row1 ^= 0b0000_0100, +// Key::P => row1 ^= 0b0000_0010, +// Key::Enter => row1 ^= 0b0000_0001, +// Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000, +// Key::D => row2 ^= 0b0100_0000, +// Key::V => row2 ^= 0b0010_0000, +// Key::H => row2 ^= 0b0001_0000, +// Key::K => row2 ^= 0b0000_1000, +// Key::Apostrophe => row2 ^= 0b0000_0100, +// Key::Slash => row2 ^= 0b0000_0010, +// Key::A => row2 ^= 0b0000_0001, +// Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000, +// Key::Z => row3 ^= 0b0100_0000, +// Key::F => row3 ^= 0b0010_0000, +// Key::B => row3 ^= 0b0001_0000, +// Key::J => row3 ^= 0b0000_1000, +// Key::L => row3 ^= 0b0000_0100, +// Key::Key2 => row3 ^= 0b0000_0010, +// Key::Key4 => row3 ^= 0b0000_0001, +// Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000, +// Key::X => row4 ^= 0b0100_0000, +// Key::C => row4 ^= 0b0010_0000, +// Key::N => row4 ^= 0b0001_0000, +// Key::M => row4 ^= 0b0000_1000, +// Key::Comma => row4 ^= 0b0000_0100, +// Key::Key1 => row4 ^= 0b0000_0010, +// Key::Key3 => row4 ^= 0b0000_0001, +// Key::LeftSuper => row5 ^= 0b1000_0000, +// Key::Space => row5 ^= 0b0100_0000, +// Key::RightSuper => row5 ^= 0b0010_0000, +// _ => {} +// }; + +// self.memory.write(0x4400, row0); +// self.memory.write(0x4401, row1); +// self.memory.write(0x4402, row2); +// self.memory.write(0x4403, row3); +// self.memory.write(0x4404, row4); +// self.memory.write(0x4405, row5); +// } +// } diff --git a/src/main.rs b/src/main.rs index f1d758b..b42b3a7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ mod error; mod instructions; mod keyboard; mod memory; -mod tui; mod types; mod video; @@ -14,41 +13,31 @@ use crate::keyboard::Keyboard; use crate::memory::Mem; use crate::video::{Screen, TerminalRenderer}; -use cpu::{CpuController, CpuReceiver}; -use crossterm::cursor::Hide; use crossterm::execute; use crossterm::terminal::{size, Clear, ClearType, SetSize}; // use cpu::CpuController; use memory::MemHandle; -// use clap::Parser; // use minifb::{Scale, ScaleMode, Window, WindowOptions}; use serde::{Deserialize, Serialize}; +use std::env; +use std::io::ErrorKind; +use std::process::exit; +use std::thread::{self, sleep}; +use std::time::Duration; use std::{ fs::File, io::{stdout, Read, Result}, path::PathBuf, str::FromStr, - sync::mpsc, - thread, }; use crossterm::{ cursor, event::{self, KeyCode, KeyEventKind}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, - // ExecutableCommand, }; -// use toml::Table; - -//#[derive(Parser)] -//struct Cli { -// // Load a rom onto the system rom -// #[arg(short, required = true)] -// rom: Option, -//} - #[derive(Serialize, Deserialize, Debug)] struct Config { char_rom: Option, @@ -56,29 +45,114 @@ struct Config { } fn main() -> Result<()> { + let args: Vec = env::args().collect(); + + let mut memory = Mem::new(); + match args.len() { + 0 => { + println!("george-emu must be run in the terminal, don't know what went wrong here!"); + exit(1) + } + 1 => { + let config: Config = match File::open("./george.toml") { + Ok(mut file) => { + let mut string = String::new(); + file.read_to_string(&mut string).unwrap(); + toml::from_str(string.as_str()).unwrap() + } + Err(_) => { + println!("couldn't find a `george.toml` in the current directory!"); + exit(1); + } + }; + let rom = match std::fs::File::open(config.rom) { + Ok(file) => file, + Err(error) => panic!("Couldn't open main rom! {:?}", error), + }; + if let Err(error) = memory.load_rom(rom) { + println!("{:?}", error); + }; + } + 2 => match &args[1] as &str { + "help" => { + println!("ʕ·ᴥ·ʔ- george-emu is an emulator for george:"); + println!("https://git.augustkline.com/august/george\n"); + println!("commands:"); + println!(" help: print this help screen"); + println!(" help : print help info for any command"); + println!(" rom : load a rom/binary from path\n"); + println!("configuration:"); + println!(" george-emu searches for a `george.toml` in the current directory. in `george.toml` you can specify a path for the character rom using the key `char_rom` and the main rom/binary with the key `rom`"); + exit(0); + } + _ => { + println!( + "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", + &args[1], &args[0] + ); + exit(1); + } + }, + 3 => match &args[1] as &str { + "help" => match &args[2] as &str { + "rom" => { + println!("{:?} rom \nload a rom/binary from path", &args[0]); + } + _ => { + println!( + "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", + &args[2], &args[0] + ); + exit(1); + } + }, + "rom" => { + let rom = match std::fs::File::open(&args[2]) { + Ok(file) => file, + Err(error) => { + match error.kind() { + ErrorKind::NotFound => { + println!("couldn't find the rom at {:?}", &args[2]); + } + ErrorKind::PermissionDenied => { + println!( + "didn't have sufficient permissions to open the rom at {:?}", + &args[2] + ); + } + _ => { + println!("something went wrong! try again in a moment? really not sure why you're getting this error"); + } + } + exit(1); + } + }; + if let Err(error) = memory.load_rom(rom) { + println!("oh no! this rom couldn't be loaded: {:?}", error); + exit(1); + }; + } + _ => { + println!( + "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", + &args[1], &args[0] + ); + exit(1); + } + }, + _ => { + println!( + "too many arguments were provided!\n\nuse `{} help` to see all valid commands", + &args[0] + ); + exit(1); + } + } let mut stdout = stdout(); let (cols, rows) = size()?; execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?; enable_raw_mode()?; - let config: Config = match File::open("./config.toml") { - Ok(mut file) => { - let mut string = String::new(); - file.read_to_string(&mut string).unwrap(); - toml::from_str(string.as_str()).unwrap() - } - Err(_) => return Ok(()), - }; - - let mut memory = Mem::new(); - let rom = match std::fs::File::open(config.rom) { - Ok(file) => file, - Err(error) => panic!("Couldn't open main rom! {:?}", error), - }; - if let Err(error) = memory.load_rom(rom) { - println!("{:?}", error); - }; - memory .dump(PathBuf::from_str("./coredump.bin").unwrap()) .unwrap(); @@ -88,11 +162,8 @@ fn main() -> Result<()> { let cpu_memory = shared_memory.clone(); let keyboard_memory = shared_memory.clone(); - let (cpu_tx, cpu_rx) = mpsc::channel(); - // let (state_tx, state_rx) = mpsc::channel(); - let screen_cpu_tx = cpu_tx.clone(); - // let (window_tx, window_rx) = mpsc::channel(); - + // For when we want to leave the terminal again :sigh: + // // thread::spawn(move || { // let mut screen = Crtc::new( // screen_memory, @@ -120,40 +191,30 @@ fn main() -> Result<()> { // ) // .unwrap(); - // window.set_input_callback(Box::new(Keyboard::new(keyboard_memory))); + let keyboard = Keyboard::new(keyboard_memory); - let mut cpu = Cpu::new(cpu_memory, CpuReceiver::new(cpu_rx)); - // let mut cpu = Cpu::new(cpu_memory); - // let mut tui = tui::App::new( - // CpuController::new(cpu_tx.clone()), - // shared_memory.clone(), - // state_rx, - // ); - thread::spawn(move || { - cpu.reset().unwrap(); - cpu.memory.write(0x4400, 0b0000_0100); - cpu.execute() + let (mut cpu, cpu_controller) = Cpu::new_with_control(cpu_memory); + let _ = cpu.reset(); + + thread::spawn(move || loop { + cpu.cycle(); }); let stdout_lock = stdout.lock(); let renderer = TerminalRenderer::new(screen_memory, stdout_lock); - let mut screen = Screen::new(CpuController::new(cpu_tx.clone()), renderer); - - // thread::spawn(move || { - // screen.run(); - // }); + let mut screen = Screen::new(renderer, cpu_controller); loop { + sleep(Duration::from_millis(16)); + screen.draw(); if event::poll(std::time::Duration::from_millis(16))? { if let event::Event::Key(key) = event::read()? { + keyboard.read_keys(key); if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { break; } } } - // let buffer = window_rx.recv().unwrap(); - screen.draw() - // tui.update(&mut terminal)?; } execute!( diff --git a/src/memory.rs b/src/memory.rs index 634a832..2f65fa2 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,10 +1,10 @@ -use crate::types::{Byte, Word}; use anyhow::{bail, Result}; +use std::cell::RefCell; use std::io::{self, Write}; use std::path::PathBuf; +use std::rc::Rc; use std::str::FromStr; -use std::sync::{Arc, Mutex, MutexGuard}; -use std::u16; +use std::sync::{Arc, Mutex}; use std::{fs::File, io::Read}; #[derive(Clone, Debug)] @@ -13,30 +13,25 @@ impl MemHandle { pub fn new(memory: Mem) -> Self { Self(Arc::new(Mutex::new(memory))) } - pub fn read(&self, address: Word) -> Byte { - let memory = self.lock().unwrap(); + pub fn read(&self, address: u16) -> u8 { + let memory = self.0.lock().unwrap(); memory.read(address) } - pub fn write(&self, address: Word, data: Byte) { - let mut memory = self.lock().unwrap(); + pub fn write(&self, address: u16, data: u8) { + let mut memory = self.0.lock().unwrap(); memory.write(address, data); } pub fn dump(&self) { - let memory = self.lock().unwrap(); - memory.dump(PathBuf::from_str("./cpu_dump.bin").unwrap()); + let memory = self.0.lock().unwrap(); + let _ = memory.dump(PathBuf::from_str("./cpu_dump.bin").unwrap()); } - - fn lock(&self) -> Result> { - match self.0.lock() { - Ok(result) => Ok(result), - Err(error) => bail!("{error}"), - } + pub fn poke(&self, address: u16) { + let memory = self.0.lock().unwrap(); + memory.poke(address) } } -// TODO: impl Iterator for MemHandle so we can get references to the underlying data from other threads without cloning - pub trait MemoryReader { fn read(&self, address: u16) -> u8; } @@ -45,19 +40,16 @@ pub trait MemoryWriter { fn write(&self, address: u16, data: u8); } -// pub trait MemoryAccess: MemoryReader + MemoryWriter {} -// impl MemoryAccess for T where T: MemoryReader + MemoryWriter {} - -#[derive(Debug, Clone)] -pub struct Mem { - pub data: Vec, -} +#[derive(Debug, Clone, Copy)] +// This always feels wrong instead of 0xFFFF, +// but remember it's the number of elements, +// not the maximum index. 0x0000 to 0xFFFF addresses +// 0x10000 elements +pub struct Mem([u8; 0x10000]); impl Default for Mem { fn default() -> Self { - Self { - data: vec![0; u16::MAX as usize + 1], - } + Self([0; 0x10000]) } } @@ -67,23 +59,24 @@ impl Mem { } pub fn dump(&self, path: PathBuf) -> io::Result<()> { let mut outfile = File::create(path)?; - outfile.write_all(&self.data)?; + outfile.write_all(&self.0)?; Ok(()) } - pub fn read(&self, address: Word) -> Byte { - self.data[address as usize] + pub fn read(&self, address: u16) -> u8 { + self.0[address as usize] } - pub fn write(&mut self, address: Word, data: Byte) { - self.data[address as usize] = data; + pub fn write(&mut self, address: u16, data: u8) { + self.0[address as usize] = data; } pub fn load_rom(&mut self, rom: File) -> Result<()> { let bytes = rom.bytes(); for (address, byte) in bytes.enumerate() { + // println!("{address}"); match byte { - Ok(value) => self.write(address as Word + 0x8000, value), + Ok(value) => self.write(address as u16 + 0x8000, value), Err(_) => { bail!("Loading rom: couldn't write byte {:#04x}", address); } @@ -91,11 +84,15 @@ impl Mem { } Ok(()) } + + pub fn poke(&self, address: u16) { + println!("{:02x}", self.read(address)); + } //pub fn read_from_bin(&mut self, f: File) -> Result<()> { // let bytes = f.bytes(); // for (address, byte) in bytes.enumerate() { // match byte { - // Ok(value) => self.write(address as Word, value), + // Ok(value) => self.write(address as u16, value), // Err(_) => { // bail!("couldn't write byte {:#04x}", address); // } diff --git a/src/roms/george.asm b/src/roms/george.asm index 154811f..0c57541 100644 --- a/src/roms/george.asm +++ b/src/roms/george.asm @@ -37,7 +37,7 @@ cleardisplay: ; cli main: - jsr keyboard + jsr printtext ; key_zero: ; stz keyboard_cache, x ; dex @@ -45,164 +45,28 @@ main: ; fim: ; cli ; bra fim - ; jsr kitty_keys jmp main -; ; copying @smal rn: https://github.com/smaldragon/KittyEMU/blob/main/roms/foxmon.asm -; char_timer = $10 -; line_buffer = $0200 -; char_cur = $11 -; line_buffer_i = $12 -; line_buffer_l = $13 +printtext: + ldx 0 + loop: + lda text, x + beq end + sta $6000, x + inx + bra loop + end: + rts -; keyboard_cache = $14 -; line_cur = $20 +text: + .asciiz "hi <3" -; irq: - -; lda line_buffer_i -; lda $e0 -; lda $6f -; sei -; stz char_cur -; lda line_buffer_i -; sta line_buffer_l -; ldx #4 - -; kitty_keys: ; reads pressed key and writes keymap value to char_cur -; phx -; txa -; asl -; asl -; asl -; asl -; asl ; i think this is supposed to be once for every keyboard row -; tax -; lda kb_row, x -; plx - -; pha -; cmp keyboard_cache, x -; bne change -; jmp nochange -; change: -; bit7: -; asl keyboard_cache, x -; bcs bit6 -; bit #0b10000000 -; beq bit6 -; pha -; lda keymap_7, x -; sta char_cur -; pla -; bit6: -; asl keyboard_cache, x -; bcs bit5 -; bit #0b01000000 -; beq bit5 -; pha -; lda keymap_6, x -; sta char_cur -; pla -; bit5: -; asl keyboard_cache, x -; bcs bit4 -; bit #0b00100000 -; beq bit4 -; pha -; lda keymap_5, x -; sta char_cur -; pla -; bit4: -; asl keyboard_cache, x -; bcs bit3 -; bit #0b00010000 -; beq bit3 -; pha -; lda keymap_4, x -; sta char_cur -; pla -; bit3: -; asl keyboard_cache, x -; bcs bit2 -; bit #0b00001000 -; beq bit2 -; pha -; lda keymap_3, x -; sta char_cur -; pla -; bit2: -; asl keyboard_cache, x -; bcs bit1 -; bit #0b00000100 -; beq bit1 -; pha -; lda keymap_2, x -; sta char_cur -; pla -; bit1: -; asl keyboard_cache, x -; bcs bit0 -; bit #0b00000010 -; beq bit0 -; pha -; lda keymap_1, x -; sta char_cur -; pla -; bit0: -; asl keyboard_cache, x -; bcs bitend -; bit #0b00000001 -; beq bitend -; pha -; lda keymap_0, x -; sta char_cur -; pla -; bitend: -; nochange: -; pla -; sta keyboard_cache, x -; dex -; bmi keyend -; jmp kitty_keys -; keyend: - -; write: -; lda char_cur -; ldy cursor -; sta $6000, y -; inc cursor -; rts - - -; ; col = keyboard row, row = keyboard bit placement inverted -; keymap_0: -; .byte "??????" -; keymap_1: -; .byte "wqdzx " -; keymap_2: -; .byte "esvfc " -; keymap_3: -; .byte "rghbn?" -; keymap_4: -; .byte "tykjm?" -; keymap_5: -; .byte "ui?l??" -; keymap_6: -; .byte "op?21?" -; keymap_7: -; .byte "??a43?" -; -; keyboard: - ldy #0 - x - -not_keyboard: ldy #0 .check_row: ; loop through each row lda kb_row, y beq .skip_row ; if row has no key pressed, skip checking which key + ; jmp key_down sta kb_row_cache, y ; if key pressed, cache it lda kb_row, y cmp kb_row_cache, y ; has key changed? diff --git a/src/roms/george.rom b/src/roms/george.rom index 53b0e931ba98a39653faf879578f5106fe81ca79..e161e97397f6989c08a5f3fae929aa7e128e2bc8 100644 GIT binary patch delta 90 zcmZo@U}|V!nxG-FjA5@?!w0sx3<)n9z9wX3D%cn^Ow@4UVsBLV-msNn#m;FH%bb)i qHZ(FMc&v0db!sX@38Mm7a%BRL$5_GuRF{#UaB<^pzIx_{4-EiWY$baD delta 73 zcmZo@U}|V!nxHY!#)a#1gTmv6tqd!6HcjkuQr_Fp$dKT%(&5ypsSG8I3Sh~V2|ylW Z2?J1FMuNiLjqmyDCp$2TFgM(3004_qAFKcX diff --git a/src/roms/keyboard.asm b/src/roms/keyboard.asm index 0797a58..b3a9289 100644 --- a/src/roms/keyboard.asm +++ b/src/roms/keyboard.asm @@ -1,26 +1,16 @@ ; .setcpu "65C02" .include "./macro.inc" -; okay so rn i wanna set up a very basic system init, and write a few subroutines to draw characters at x,y coordinates -n = $01 ; temporary storage for data stack operations - -key_row = $200 ; used for character lookup when key pressed -key_col = $201 -cursor = $202 - -char_buffer = $300 ; 256 byte character buffer - -kb_row = $4400 ; keyboard hardware register, there are 5 more but i can just increment from here -kb_row_cache = $203 ; cache - .org $8000 +n = $01 ; temporary storage for data stack operations + reset: sei ldx #0; initialize data stack pointer initdisplay: - lda #$20 + lda #0 ldy #0 cleardisplay: @@ -37,56 +27,13 @@ cleardisplay: cli main: - jsr draw + ; jmp draw + jmp cleardisplay jmp main -keyboard: - ldy #5 - .loop: ; loop through each row - lda kb_row, y - bne key_down; if row has key pressed, go to key_down subroutine - dey - bne .loop - rts - -key_down: ; a is loaded with the row byte - sty key_row ; store character row - inc cursor - pha - phy - ldy #0 - .find_col: ; test each row bit, store column if key pressed - lsr ; test bit 7 - bcs store_col ; if unset, don't go store character columnb - .skip: - iny - cpy #8 - bne .find_col ; loop until we've checked each bit - -do_something_w_key: ; we've stored the character position, now let's - lda keymap, y - ldy cursor - sta $6000, y - ply - pla - rts - -keymap_0: - .byte "?outrew?" -keymap_1: - .byte "?piygsq?" -keymap_2: - .byte "a??khvd?" -keymap_3: - .byte "42ljbfz?" -keymap_4: - .byte "31?mncx?" -keymap_5: - .byte "????? m" - draw: push_coords #0, #0 - push_char #$00 + push_char #$af jsr draw_char rts @@ -125,11 +72,16 @@ get_char_address: ; gets vram address for a character at (x, y), fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1 n3: y1 n4: x2 n5: y2 -- ) jsr get_char_address +irq: + + keyboard: + rts + isr: ; interrupt service routine pha phx phy - jsr keyboard + jsr irq ply plx pla diff --git a/src/roms/template.asm b/src/roms/template.asm new file mode 100644 index 0000000..dd200e9 --- /dev/null +++ b/src/roms/template.asm @@ -0,0 +1,88 @@ +; .setcpu "65C02" + .include "./macro.inc" + + .org $8000 + +n = $01 ; temporary storage for data stack operations + +reset: + sei + ldx #0; initialize data stack pointer + +initdisplay: + lda #0 + ldy #0 + +cleardisplay: + sta $6000,y + sta $6100,y + sta $6200,y + sta $6300,y + sta $6400,y + sta $6500,y + sta $6600,y + sta $6700,y ; this goes slightly over but it's fine + iny + bne cleardisplay + cli + +main: + jmp draw + jmp main + +draw: + push_coords #0, #0 + push_char #$af + jsr draw_char + rts + +draw_char: ; draw a character c at (x, y) (n1: x n2: y n3: c -- ) + lda 0, x ; load a with character to draw + pop ; and pop it off the stack + jsr get_char_address ; calculate where to put the character in memory + sta (0, x) ; store a at the address pointed to on the stack + rts + +get_char_address: ; gets vram address for a character at (x, y), + ; (n1: x n2: y -- n: $6000 + x + (64 * y)) + ;jsr push_lit ; push 64 onto stack, low byte first + ;.byte 64 + ;.byte 0 + pha + lda #64 + push ; doing this instead until `push_lit` is fixed + sta 0, x + stz 1, x + jsr mult ; multiply 64 with y (n2) + jsr plus ; add result with x (n1) + + ;jsr push_lit ; push vram address onto the stack + ;.byte $00 + ;.byte $60 + lda #$60 + push + sta 1, x + stz 0, x + jsr plus ; add vram start address to result + + pla + rts + +fill: ; fills an area from (x1, y1) to (x2, y2) will character c, (n1: c n2: x1 n3: y1 n4: x2 n5: y2 -- ) + jsr get_char_address + +isr: ; interrupt service routine + pha + phx + phy + ; jsr irq + ply + plx + pla + rti + + .include "math.inc" + + .org $fffc + .word reset + .word isr diff --git a/src/video.rs b/src/video.rs index d8943be..e496c32 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1,21 +1,21 @@ use crossterm::{ - cursor::{MoveTo, SavePosition}, + cursor::{MoveTo, RestorePosition, SavePosition}, execute, queue, style::{Color, PrintStyledContent, Stylize}, }; use crate::{ cpu::CpuController, - memory::{self, MemHandle, MemoryReader}, + memory::{MemHandle, MemoryReader}, types::{Byte, Word}, }; use std::{ fs::File, - io::{Read, Stdout, StdoutLock, Write}, + io::{Read, StdoutLock, Write}, path::Path, + process::exit, sync::mpsc::Sender, - thread::sleep, - time::Duration, + time::Instant, }; const FG_COLOR: u32 = 0xFFCC00; @@ -73,7 +73,7 @@ impl Renderer for WindowRenderer { let mut buffer = vec![0; 512 * 380]; for char_row in 0..29 { for char_col in 0..64 { - let ascii = self.memory.read(0x6000 + i); + let ascii = self.read(0x6000 + i); i += 1; for row in 0..13 { let byte = self.char_rom[ascii as usize + (row * 0x100)]; @@ -118,7 +118,7 @@ impl MemoryReader for TerminalRenderer<'_> { } } -static ASCII_LOOPUP: [&str; 256] = [ +const ASCII_LOOPUP: [&str; 256] = [ " ", "░", "▒", "▓", "♡", "♥", "⭐", "✭", "", "✦", "✨", "♀", "♂", "⚢", "⚣", "⚥", "♩", "♪", "♫", "♬", "ﱝ", "", "", "", "奄", "奔", "婢", "ﱜ", "ﱛ", "", "", "", " ", "!", "\"", "#", "$", "%", "&", "\'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", @@ -137,11 +137,12 @@ static ASCII_LOOPUP: [&str; 256] = [ impl Renderer for TerminalRenderer<'_> { fn render(&mut self) { + // let now = Instant::now(); let _ = execute!(self.stdout, SavePosition); let mut i = 0; for char_row in 0..29 { for char_col in 0..64 { - let ascii = self.memory.read(0x6000 + i); + let ascii = self.read(0x6000 + i); i += 1; let char = ASCII_LOOPUP[ascii as usize]; let _ = queue!( @@ -165,32 +166,36 @@ impl Renderer for TerminalRenderer<'_> { } } let _ = self.stdout.flush(); + let _ = execute!(self.stdout, RestorePosition); + // let elapsed = now.elapsed(); + // println!("{elapsed:?}"); + // exit(0); } } pub struct Screen<'a> { - cpu_controller: CpuController, // renderer: Box, renderer: TerminalRenderer<'a>, + controller: CpuController, } impl<'a> Screen<'a> { // pub fn new(cpu_controller: CpuController, renderer: Box) -> Self { - pub fn new(cpu_controller: CpuController, renderer: TerminalRenderer<'a>) -> Self { + pub fn new(renderer: TerminalRenderer<'a>, controller: CpuController) -> Self { Self { - cpu_controller, renderer, + controller, } } pub fn draw(&mut self) { + self.controller.irq(); self.renderer.render(); } - pub fn run(&mut self) { - loop { - self.cpu_controller.irq(); - sleep(Duration::from_millis(16)); - self.draw(); - } - } + // pub fn run(&mut self) { + // loop { + // // sleep(Duration::from_millis(16)); + // self.draw(); + // } + // } }