diff --git a/Cargo.lock b/Cargo.lock index a5de6d7..e428cac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,15 @@ dependencies = [ "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" @@ -21,48 +30,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] -name = "anstream" -version = "0.6.13" +name = "anes" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +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.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -70,15 +86,26 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +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.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bdf" @@ -113,27 +140,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "cassowary" @@ -141,6 +156,12 @@ 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" @@ -152,12 +173,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -166,10 +184,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "clap" -version = "4.5.4" +name = "ciborium" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +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", @@ -177,21 +234,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", - "clap_lex", + "clap_lex 0.7.1", "strsim", ] [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck", "proc-macro2", @@ -201,15 +258,24 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +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.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "compact_str" @@ -224,13 +290,74 @@ dependencies = [ "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.4.2", + "bitflags 2.5.0", "crossterm_winapi", "libc", "mio", @@ -249,6 +376,12 @@ 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" @@ -266,9 +399,9 @@ dependencies = [ [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "either" @@ -284,9 +417,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -294,15 +427,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "futures" @@ -399,8 +526,8 @@ version = "0.1.0" dependencies = [ "anyhow", "bdf", - "bitvec", - "clap", + "clap 4.5.7", + "criterion", "crossterm", "minifb", "ratatui", @@ -409,10 +536,26 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.14.3" +name = "half" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +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", @@ -424,6 +567,25 @@ 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" version = "2.2.6" @@ -431,14 +593,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", "js-sys", @@ -446,6 +608,21 @@ dependencies = [ "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" @@ -463,9 +640,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -478,18 +655,18 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.5", ] [[package]] @@ -498,16 +675,16 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "libc", "redox_syscall 0.4.1", ] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -521,9 +698,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru" @@ -531,14 +708,14 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -599,12 +776,27 @@ dependencies = [ "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" @@ -617,6 +809,12 @@ dependencies = [ "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" @@ -637,7 +835,7 @@ dependencies = [ "libc", "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -648,9 +846,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -660,45 +858,67 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +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.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "ratatui" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f44c9e68fd46eda15c646fbb85e1040b657a58cdc8c98db1d97a55930d991eef" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cassowary", "compact_str", "crossterm", - "itertools", + "itertools 0.12.1", "lru", "paste", "stability", @@ -717,6 +937,26 @@ 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" @@ -732,16 +972,45 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", ] [[package]] -name = "rustix" -version = "0.38.31" +name = "regex" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ - "bitflags 2.4.2", + "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", @@ -760,6 +1029,15 @@ 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" @@ -797,18 +1075,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -816,10 +1094,21 @@ dependencies = [ ] [[package]] -name = "serde_spanned" -version = "0.6.5" +name = "serde_json" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -865,9 +1154,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "stability" @@ -915,48 +1204,47 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.4.1", "rustix", "windows-sys 0.52.0", ] [[package]] -name = "thiserror" -version = "1.0.56" +name = "textwrap" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -964,10 +1252,20 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.8.12" +name = "tinytemplate" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "toml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", @@ -977,20 +1275,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ - "indexmap", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -1015,7 +1313,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226" dependencies = [ - "itertools", + "itertools 0.12.1", "unicode-width", ] @@ -1027,9 +1325,9 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version-compare" @@ -1043,6 +1341,16 @@ 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" @@ -1051,9 +1359,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1061,9 +1369,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -1076,9 +1384,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -1088,9 +1396,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1098,9 +1406,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -1111,9 +1419,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wayland-client" @@ -1190,9 +1498,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -1214,6 +1522,15 @@ 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" @@ -1235,7 +1552,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -1255,17 +1572,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -1276,9 +1594,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -1288,9 +1606,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -1300,9 +1618,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -1312,9 +1636,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -1324,9 +1648,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -1336,9 +1660,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -1348,28 +1672,19 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "x11-dl" version = "2.21.0" @@ -1389,9 +1704,9 @@ checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" [[package]] name = "zerocopy" diff --git a/Cargo.toml b/Cargo.toml index fba75a2..abd0a3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,18 @@ edition = "2021" [dependencies] anyhow = "1.0.81" bdf = "0.6.0" -bitvec = "1.0.1" clap = { version = "4.5.4", features = ["derive"] } +criterion = "0.4" crossterm = "0.27.0" 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/config.toml index 5295807..b6e611a 100644 --- a/config.toml +++ b/config.toml @@ -1,3 +1,3 @@ char_rom = "./src/roms/cozette.rom" -rom = "./src/roms/test.rom" +rom = "./src/roms/george.rom" diff --git a/src/cpu.rs b/src/cpu.rs index d813631..90090a1 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -1,6 +1,7 @@ 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::time::Duration; @@ -68,6 +69,7 @@ pub struct CpuState { pub nmi: bool, } +// #[derive(Clone)] pub struct Cpu { pub a: Byte, // Accumulator Register pub x: Byte, // X Register @@ -81,8 +83,14 @@ pub struct Cpu { pub pending_cycles: usize, receiver: CpuReceiver, stopped: bool, - cycle_count: usize, - state_tx: Sender, + // cycle_count: usize, + // state_tx: Sender, +} + +impl Display for Cpu { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{},{}", self.a, self.x) + } } impl MemoryReader for Cpu { @@ -97,7 +105,8 @@ impl MemoryWriter for Cpu { } impl Cpu { - pub fn new(memory: MemHandle, receiver: CpuReceiver, state_tx: Sender) -> Self { + pub fn new(memory: MemHandle, receiver: CpuReceiver) -> Self { + // pub fn new(memory: MemHandle) -> Self { Cpu { a: 0x00, x: 0x00, @@ -111,8 +120,8 @@ impl Cpu { memory, stopped: false, pending_cycles: 0, - cycle_count: 0, - state_tx, + // cycle_count: 0, + // state_tx, } } pub fn reset(&mut self) -> Result<()> { @@ -121,15 +130,6 @@ impl Cpu { self.pending_cycles = 0; Ok(()) } - // pub fn read(&self, address: Word) -> Result { - // let memory = match self.memory.lock() { - // Ok(read) => read, - // Err(_) => { - // bail!("Couldn't acquire lock on memory in cpu thread") - // } - // }; - // Ok(memory.read(address)) - // } pub fn read_word(&self, address: Word) -> Result { let low_byte = self.read(address); let high_byte = self.read(address + 0x1); @@ -209,24 +209,24 @@ impl Cpu { CpuControl::Irq => self.irq = true, CpuControl::Stop => self.stopped = true, CpuControl::Resume => self.stopped = false, - CpuControl::Data => self - .state_tx - .send(CpuState { - a: self.a.clone(), // Accumulator Register - x: self.x.clone(), // X Register - y: self.y.clone(), // Y Register - pc: self.pc.clone(), // Program Counter - s: self.s.clone(), // Stack Pointer - p: self.p.clone(), // Status Register - irq: self.irq.clone(), - nmi: self.nmi.clone(), - }) - .unwrap(), + CpuControl::Data => {} // self + // .state_tx + // .send(CpuState { + // a: self.a.clone(), // Accumulator Register + // x: self.x.clone(), // X Register + // y: self.y.clone(), // Y Register + // pc: self.pc.clone(), // Program Counter + // s: self.s.clone(), // Stack Pointer + // p: self.p.clone(), // Status Register + // irq: self.irq.clone(), + // nmi: self.nmi.clone(), + // }) + // .unwrap(), } } pub fn cycle(&mut self) { - self.receive_control(); + // self.receive_control(); if self.stopped { return; } @@ -239,13 +239,6 @@ impl Cpu { self.interrupt(); } let opcode = self.read(self.pc); - // let opcode = match self.read(&self.memory, self.pc) { - // Ok(byte) => byte, - // Err(_) => { - // println!("Failed to read from memory at address {:#06x}!", self.pc); - // return; - // } - // }; let instruction = get_instruction(opcode); match instruction { Instruction::Valid(valid_instruction) => { @@ -278,7 +271,8 @@ impl Cpu { } }, } - self.cycle_count += 1; + // self.cycle_count += 1; + sleep(Duration::from_nanos(100)); } pub fn stop(&mut self) { self.stopped = true; diff --git a/src/georgeencoding.txt b/src/georgeencoding.txt index df5a821..8e8a149 100644 --- a/src/georgeencoding.txt +++ b/src/georgeencoding.txt @@ -7,259 +7,259 @@ # column #2 is the Unicode (in hex as 0xXXXX) # column #3 the Unicode name (follows a comment sign, '#') -0x00 0x00 # -0x01 0x2591 # -0x02 0x2592 # ᴥ -0x03 0x2593 # ʔ -0x04 0x2661 # White heart -0x05 0x2665 # Black heart -0x06 0x2B50 # White star -0x07 0x272D # Black star -0x08 0xF005 # Alternate Black Star -0x09 0x2726 # Black four pointed star -0x0a 0x2728 # Sparkles -0x0b 0x2640 # Female Sign -0x0c 0x2642 # Male Sign -0x0d 0x26A2 # Doubled female sign -0x0E 0x26A3 # Doubled male sign -0x0F 0x26A5 # Male and Female sign0x000E -0x10 0x2669 # Quarter Note -0x11 0x266A # Eighth note -0x12 0x266B # Beamed eighth notes -0x13 0x266C # Beamed sixteenth notes -0x14 0xFC5D # -0x15 0xF026 # -0x16 0xF027 # -0x17 0xF028 # -0x18 0xFA7E # -0x19 0xFA7F # -0x1A 0xFA80 # -0x1B 0xFC5C # -0x1C 0xFC5B # -0x1D 0xF0AC # -0x1E 0xF04B # -0x1F 0xF04D # -0x20 0x0020 # SPACE -0x21 0x0021 # EXCLAMATION MARK -0x22 0x0022 # QUOTATION MARK -0x23 0x0023 # NUMBER SIGN -0x24 0x0024 # DOLLAR SIGN -0x25 0x0025 # PERCENT SIGN -0x26 0x0026 # AMPERSAND -0x27 0x0027 # APOSTROPHE -0x28 0x0028 # LEFT PARENTHESIS -0x29 0x0029 # RIGHT PARENTHESIS -0x2A 0x002A # ASTERISK -0x2B 0x002B # PLUS SIGN -0x2C 0x002C # COMMA -0x2D 0x002D # HYPHEN-MINUS -0x2E 0x002E # FULL STOP -0x2F 0x002F # SOLIDUS -0x30 0x0030 # DIGIT ZERO -0x31 0x0031 # DIGIT ONE -0x32 0x0032 # DIGIT TWO -0x33 0x0033 # DIGIT THREE -0x34 0x0034 # DIGIT FOUR -0x35 0x0035 # DIGIT FIVE -0x36 0x0036 # DIGIT SIX -0x37 0x0037 # DIGIT SEVEN -0x38 0x0038 # DIGIT EIGHT -0x39 0x0039 # DIGIT NINE -0x3A 0x003A # COLON -0x3B 0x003B # SEMICOLON -0x3C 0x003C # LESS-THAN SIGN -0x3D 0x003D # EQUALS SIGN -0x3E 0x003E # GREATER-THAN SIGN -0x3F 0x003F # QUESTION MARK -0x40 0x0040 # COMMERCIAL AT -0x41 0x0041 # LATIN CAPITAL LETTER A -0x42 0x0042 # LATIN CAPITAL LETTER B -0x43 0x0043 # LATIN CAPITAL LETTER C -0x44 0x0044 # LATIN CAPITAL LETTER D -0x45 0x0045 # LATIN CAPITAL LETTER E -0x46 0x0046 # LATIN CAPITAL LETTER F -0x47 0x0047 # LATIN CAPITAL LETTER G -0x48 0x0048 # LATIN CAPITAL LETTER H -0x49 0x0049 # LATIN CAPITAL LETTER I -0x4A 0x004A # LATIN CAPITAL LETTER J -0x4B 0x004B # LATIN CAPITAL LETTER K -0x4C 0x004C # LATIN CAPITAL LETTER L -0x4D 0x004D # LATIN CAPITAL LETTER M -0x4E 0x004E # LATIN CAPITAL LETTER N -0x4F 0x004F # LATIN CAPITAL LETTER O -0x50 0x0050 # LATIN CAPITAL LETTER P -0x51 0x0051 # LATIN CAPITAL LETTER Q -0x52 0x0052 # LATIN CAPITAL LETTER R -0x53 0x0053 # LATIN CAPITAL LETTER S -0x54 0x0054 # LATIN CAPITAL LETTER T -0x55 0x0055 # LATIN CAPITAL LETTER U -0x56 0x0056 # LATIN CAPITAL LETTER V -0x57 0x0057 # LATIN CAPITAL LETTER W -0x58 0x0058 # LATIN CAPITAL LETTER X -0x59 0x0059 # LATIN CAPITAL LETTER Y -0x5A 0x005A # LATIN CAPITAL LETTER Z -0x5B 0x005B # LEFT SQUARE BRACKET -0x5C 0x005C # REVERSE SOLIDUS -0x5D 0x005D # RIGHT SQUARE BRACKET -0x5E 0x005E # CIRCUMFLEX ACCENT -0x5F 0x005F # LOW LINE -0x60 0x0060 # GRAVE ACCENT -0x61 0x0061 # LATIN SMALL LETTER A -0x62 0x0062 # LATIN SMALL LETTER B -0x63 0x0063 # LATIN SMALL LETTER C -0x64 0x0064 # LATIN SMALL LETTER D -0x65 0x0065 # LATIN SMALL LETTER E -0x66 0x0066 # LATIN SMALL LETTER F -0x67 0x0067 # LATIN SMALL LETTER G -0x68 0x0068 # LATIN SMALL LETTER H -0x69 0x0069 # LATIN SMALL LETTER I -0x6A 0x006A # LATIN SMALL LETTER J -0x6B 0x006B # LATIN SMALL LETTER K -0x6C 0x006C # LATIN SMALL LETTER L -0x6D 0x006D # LATIN SMALL LETTER M -0x6E 0x006E # LATIN SMALL LETTER N -0x6F 0x006F # LATIN SMALL LETTER O -0x70 0x0070 # LATIN SMALL LETTER P -0x71 0x0071 # LATIN SMALL LETTER Q -0x72 0x0072 # LATIN SMALL LETTER R -0x73 0x0073 # LATIN SMALL LETTER S -0x74 0x0074 # LATIN SMALL LETTER T -0x75 0x0075 # LATIN SMALL LETTER U -0x76 0x0076 # LATIN SMALL LETTER V -0x77 0x0077 # LATIN SMALL LETTER W -0x78 0x0078 # LATIN SMALL LETTER X -0x79 0x0079 # LATIN SMALL LETTER Y -0x7A 0x007A # LATIN SMALL LETTER Z -0x7B 0x007B # LEFT CURLY BRACKET -0x7C 0x007C # VERTICAL LINE -0x7D 0x007D # RIGHT CURLY BRACKET -0x7E 0x007E # TILDE -0x7F 0x2500 # Box Drawings light horizontal -0x80 0x2502 # Box drawings light vertical -0x81 0x250C # Box drawing light down and right -0x82 0x2514 # Box drawing light up and right -0x83 0x251C # Box drawings light vertical and right -0x84 0x2524 # -0x85 0x252C # -0x86 0x2534 # -0x87 0x253C # -0x88 0x256D # -0x89 0x256E # -0x8A 0x256F # -0x8B 0x2570 # -0x8C 0x2571 # -0x8D 0x2572 # -0x8E 0x2573 # -0x8F 0x2550 # -0x90 0x2551 # -0x91 0x2554 # -0x92 0x2557 # -0x93 0x255a # -0x94 0x255D # -0x95 0x2560 # -0x96 0x2563 # -0x97 0x2566 # -0x98 0x2569 # -0x99 0x256C # -0x9A 0xF04E # -0x9B 0xF050 # -0x9C 0xF051 # -0x9D 0xF052 # -0x9E 0xF048 # -0x9F 0xE0B0 # -0xA0 0xE0B2 # -0xA1 0xE0B4 # -0xA2 0xE0B6 # -0xA3 0xE0B8 # -0xA4 0xE0BA # -0xA5 0xE0BC # -0xA6 0xE0BE # -0xA7 0x2581 # -0xA8 0x2582 # -0xA9 0x2583 # -0xAA 0x2584 # -0xAB 0x2585 # -0xAC 0x2586 # -0xAD 0x2587 # -0xAE 0x2588 # -0xAF 0x2589 # -0xB0 0x258A # -0xB1 0x258B # -0xB2 0x258C # -0xB3 0x258D # -0xB4 0x258E # -0xB5 0x258F # -0xB6 0x0295 # -0xB7 0x00B7 # -0xB8 0x1D25 # -0xB9 0x0294 -0xBA 0x2596 -0xBB 0x2597 -0xBC 0x2598 -0xBD 0x2599 -0xBE 0x259A -0xBF 0x259B -0xC0 0x259C -0xC1 0x259D -0xC2 0x259E -0xC3 0x259F -0xC4 0x2190 -0xC5 0x2191 -0xC6 0x2192 -0xC7 0x2193 -0xC8 0x2B60 -0xC9 0x2B61 -0xCA 0x2B62 -0xCB 0x2B63 -0xCC 0x2B80 -0xCD 0x2B81 -0xCE 0x2B82 -0xCF 0x2B83 -0xD0 0xF049 -0xD1 0xF04A -0xD2 0x23F3 -0xD3 0xF07B -0xD4 0xF07C -0xD5 0xF114 -0xD6 0xF115 -0xD7 0xF250 -0xD8 0xF251 -0xD9 0xF253 -0xDA 0xF254 -0xDB 0xF461 -0xDC 0xF016 -0xDD 0xF401 -0xDE 0x1F52E -0xDF 0xF2DB -0xE0 0xF008 -0xE1 0x25C7 -0xE2 0x25C8 -0xE3 0x1F311 -0xE4 0x1F312 -0xE5 0x1F313 -0xE6 0x1F314 -0xE7 0x1F315 -0xE8 0x1F316 -0xE9 0x1F317 -0xEA 0x1F318 -0xEB 0xF04C -0xEC 0x2714 -0xED 0x2718 -0xEE 0x25C6 -0xEF 0xF15D -0xF0 0xF15E -0xF1 0xF071 -0xF2 0xF449 -0xF3 0xF529 -0xF4 0xF658 -0xF5 0xF659 # -0xF6 0x1f381 # Space -0xF7 0xf05a # Space -0xF8 0xf06a # Space -0xF9 0xf834 # Space -0xFA 0xf835 # Space -0xFB 0x2690 # Space -0xFC 0x2691 # Space -0xFD 0xf8d7 # Space -0xFE 0xf0e7 # Space -0xFF 0xf7d9 # Space +0x00 0x00 # +0x01 0x2591 # ░ +0x02 0x2592 # ▒ +0x03 0x2593 # ▓ +0x04 0x2661 # ♡ +0x05 0x2665 # ♥ +0x06 0x2B50 # ⭐ +0x07 0x272D # ✭ +0x08 0xF005 #  +0x09 0x2726 # ✦ +0x0a 0x2728 # ✨ +0x0b 0x2640 # ♀ +0x0c 0x2642 # ♂ +0x0d 0x26A2 # ⚢ +0x0E 0x26A3 # ⚣ +0x0F 0x26A5 # ⚥ +0x10 0x2669 # ♩ +0x11 0x266A # ♪ +0x12 0x266B # ♫ +0x13 0x266C # ♬ +0x14 0xFC5D # ﱝ +0x15 0xF026 #  +0x16 0xF027 #  +0x17 0xF028 #  +0x18 0xFA7E # 奄 +0x19 0xFA7F # 奔 +0x1A 0xFA80 # 婢 +0x1B 0xFC5C # ﱜ +0x1C 0xFC5B # ﱛ +0x1D 0xF0AC #  +0x1E 0xF04B #  +0x1F 0xF04D #  +0x20 0x0020 # +0x21 0x0021 # ! +0x22 0x0022 # " +0x23 0x0023 # # +0x24 0x0024 # $ +0x25 0x0025 # % +0x26 0x0026 # & +0x27 0x0027 # ' +0x28 0x0028 # ( +0x29 0x0029 # ) +0x2A 0x002A # * +0x2B 0x002B # + +0x2C 0x002C # , +0x2D 0x002D # - +0x2E 0x002E # . +0x2F 0x002F # / +0x30 0x0030 # 0 +0x31 0x0031 # 1 +0x32 0x0032 # 2 +0x33 0x0033 # 3 +0x34 0x0034 # 4 +0x35 0x0035 # 5 +0x36 0x0036 # 6 +0x37 0x0037 # 7 +0x38 0x0038 # 8 +0x39 0x0039 # 9 +0x3A 0x003A # : +0x3B 0x003B # ; +0x3C 0x003C # < +0x3D 0x003D # = +0x3E 0x003E # > +0x3F 0x003F # ? +0x40 0x0040 # @ +0x41 0x0041 # A +0x42 0x0042 # B +0x43 0x0043 # C +0x44 0x0044 # D +0x45 0x0045 # E +0x46 0x0046 # F +0x47 0x0047 # G +0x48 0x0048 # H +0x49 0x0049 # I +0x4A 0x004A # J +0x4B 0x004B # K +0x4C 0x004C # L +0x4D 0x004D # M +0x4E 0x004E # N +0x4F 0x004F # O +0x50 0x0050 # P +0x51 0x0051 # Q +0x52 0x0052 # R +0x53 0x0053 # S +0x54 0x0054 # T +0x55 0x0055 # U +0x56 0x0056 # V +0x57 0x0057 # W +0x58 0x0058 # X +0x59 0x0059 # Y +0x5A 0x005A # Z +0x5B 0x005B # [ +0x5C 0x005C # \ +0x5D 0x005D # ] +0x5E 0x005E # ^ +0x5F 0x005F # _ +0x60 0x0060 # ` +0x61 0x0061 # a +0x62 0x0062 # b +0x63 0x0063 # c +0x64 0x0064 # d +0x65 0x0065 # e +0x66 0x0066 # f +0x67 0x0067 # g +0x68 0x0068 # h +0x69 0x0069 # i +0x6A 0x006A # j +0x6B 0x006B # k +0x6C 0x006C # l +0x6D 0x006D # m +0x6E 0x006E # n +0x6F 0x006F # o +0x70 0x0070 # p +0x71 0x0071 # q +0x72 0x0072 # r +0x73 0x0073 # s +0x74 0x0074 # t +0x75 0x0075 # u +0x76 0x0076 # v +0x77 0x0077 # w +0x78 0x0078 # x +0x79 0x0079 # y +0x7A 0x007A # z +0x7B 0x007B # { +0x7C 0x007C # | +0x7D 0x007D # } +0x7E 0x007E # ~ +0x7F 0x2500 # ─ +0x80 0x2502 # │ +0x81 0x250C # ┌ +0x82 0x2514 # └ +0x83 0x251C # ├ +0x84 0x2524 # ┤ +0x85 0x252C # ┬ +0x86 0x2534 # ┴ +0x87 0x253C # ┼ +0x88 0x256D # ╭ +0x89 0x256E # ╮ +0x8A 0x256F # ╯ +0x8B 0x2570 # ╰ +0x8C 0x2571 # ╱ +0x8D 0x2572 # ╲ +0x8E 0x2573 # ╳ +0x8F 0x2550 # ═ +0x90 0x2551 # ║ +0x91 0x2554 # ╔ +0x92 0x2557 # ╗ +0x93 0x255a # ╚ +0x94 0x255D # ╝ +0x95 0x2560 # ╠ +0x96 0x2563 # ╣ +0x97 0x2566 # ╦ +0x98 0x2569 # ╩ +0x99 0x256C # ╬ +0x9A 0xF04E #  +0x9B 0xF050 #  +0x9C 0xF051 #  +0x9D 0xF052 #  +0x9E 0xF048 #  +0x9F 0xE0B0 #  +0xA0 0xE0B2 #  +0xA1 0xE0B4 #  +0xA2 0xE0B6 #  +0xA3 0xE0B8 #  +0xA4 0xE0BA #  +0xA5 0xE0BC #  +0xA6 0xE0BE #  +0xA7 0x2581 # ▁ +0xA8 0x2582 # ▂ +0xA9 0x2583 # ▃ +0xAA 0x2584 # ▄ +0xAB 0x2585 # ▅ +0xAC 0x2586 # ▆ +0xAD 0x2587 # ▇ +0xAE 0x2588 # █ +0xAF 0x2589 # ▉ +0xB0 0x258A # ▊ +0xB1 0x258B # ▋ +0xB2 0x258C # ▌ +0xB3 0x258D # ▍ +0xB4 0x258E # ▎ +0xB5 0x258F # ▏ +0xB6 0x0295 # ʕ +0xB7 0x00B7 # · +0xB8 0x1D25 # ᴥ +0xB9 0x0294 # ʔ +0xBA 0x2596 # ▖ +0xBB 0x2597 # ▗ +0xBC 0x2598 # ▘ +0xBD 0x2599 # ▙ +0xBE 0x259A # ▚ +0xBF 0x259B # ▛ +0xC0 0x259C # ▜ +0xC1 0x259D # ▝ +0xC2 0x259E # ▞ +0xC3 0x259F # ▟ +0xC4 0x2190 # ← +0xC5 0x2191 # ↑ +0xC6 0x2192 # → +0xC7 0x2193 # ↓ +0xC8 0x2B60 # ⭠ +0xC9 0x2B61 # ⭡ +0xCA 0x2B62 # ⭢ +0xCB 0x2B63 # ⭣ +0xCC 0x2B80 # ⮀ +0xCD 0x2B81 # ⮁ +0xCE 0x2B82 # ⮂ +0xCF 0x2B83 # ⮃ +0xD0 0xF049 #  +0xD1 0xF04A #  +0xD2 0x23F3 # ⏳ +0xD3 0xF07B #  +0xD4 0xF07C #  +0xD5 0xF114 #  +0xD6 0xF115 #  +0xD7 0xF250 #  +0xD8 0xF251 #  +0xD9 0xF253 #  +0xDA 0xF254 #  +0xDB 0xF461 #  +0xDC 0xF016 #  +0xDD 0xF401 #  +0xDE 0x1F52E # 🔮 +0xDF 0xF2DB #  +0xE0 0xF008 #  +0xE1 0x25C7 # ◇ +0xE2 0x25C8 # ◈ +0xE3 0x1F311 # 🌑 +0xE4 0x1F312 # 🌒 +0xE5 0x1F313 # 🌓 +0xE6 0x1F314 # 🌔 +0xE7 0x1F315 # 🌕 +0xE8 0x1F316 # 🌖 +0xE9 0x1F317 # 🌗 +0xEA 0x1F318 # 🌘 +0xEB 0xF04C #  +0xEC 0x2714 # ✔ +0xED 0x2718 # ✘ +0xEE 0x25C6 # ◆ +0xEF 0xF15D #  +0xF0 0xF15E #  +0xF1 0xF071 #  +0xF2 0xF449 #  +0xF3 0xF529 #  +0xF4 0xF658 #  +0xF5 0xF659 #  +0xF6 0x1f381 # 🎁 +0xF7 0xf05a #  +0xF8 0xf06a #  +0xF9 0xf834 #  +0xFA 0xf835 #  +0xFB 0x2690 # ⚐ +0xFC 0x2691 # ⚑ +0xFD 0xf8d7 #  +0xFE 0xf0e7 #  +0xFF 0xf7d9 #  diff --git a/src/instructions.rs b/src/instructions.rs index ddc8189..a51fe42 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -2,30 +2,27 @@ use crate::cpu::{Cpu, StatusFlag}; use crate::memory::{MemoryReader, MemoryWriter}; -use crate::types::{Byte, Word}; - -use std::collections::HashMap; use anyhow::{bail, Result}; -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum Instruction { Valid(ValidInstruction), Invalid(InvalidInstruction), } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ValidInstruction { pub opcode: Opcode, - pub cycles: Byte, + pub cycles: u8, } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct InvalidInstruction { - pub opcode: Byte, + pub opcode: u8, } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum AddressingMode { AbsoluteA, // a AbsoluteIndexedWithX, // a, x @@ -50,1672 +47,11 @@ pub enum AddressingMode { // if you want to optimize this later https://llx.com/Neil/a2/opcodes.html pub fn get_instruction(opcode: u8) -> Instruction { - let opcodes: HashMap = HashMap::from([ - ( - 0x00, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BRK(AddressingMode::Implied), - cycles: 7, - }), - ), - ( - 0x01, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0x02, - Instruction::Invalid(InvalidInstruction { opcode: 0x02 }), - ), - ( - 0x03, - Instruction::Invalid(InvalidInstruction { opcode: 0x03 }), - ), - ( - 0x04, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TSB(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x05, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x06, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ASL(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x07, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB0(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x08, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PHP(AddressingMode::Stack), - cycles: 3, - }), - ), - ( - 0x09, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0x0a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ASL(AddressingMode::Accumulator), - cycles: 2, - }), - ), - ( - 0x0b, - Instruction::Invalid(InvalidInstruction { opcode: 0x0b }), - ), - ( - 0x0c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TSB(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x0d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x0e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ASL(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x0f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR0(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x10, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BPL(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0x11, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::AbsoluteIndexedWithY), - cycles: 5, - }), - ), - ( - 0x12, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::ZeroPageIndirect), - cycles: 5, - }), - ), - ( - 0x13, - Instruction::Invalid(InvalidInstruction { opcode: 0x13 }), - ), - ( - 0x14, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TRB(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x15, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x16, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ASL(AddressingMode::ZeroPageIndexedWithX), - cycles: 6, - }), - ), - ( - 0x17, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB1(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x18, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CLC(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x19, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0x1a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INC(AddressingMode::Accumulator), - cycles: 2, - }), - ), - ( - 0x1b, - Instruction::Invalid(InvalidInstruction { opcode: 0x1b }), - ), - ( - 0x1c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TRB(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x1d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ORA(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0x1e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ASL(AddressingMode::AbsoluteIndexedWithX), - cycles: 7, - }), - ), - ( - 0x1f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR1(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x20, - Instruction::Valid(ValidInstruction { - opcode: Opcode::JSR(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x21, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0x22, - Instruction::Invalid(InvalidInstruction { opcode: 0x22 }), - ), - ( - 0x23, - Instruction::Invalid(InvalidInstruction { opcode: 0x23 }), - ), - ( - 0x24, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BIT(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x25, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x26, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROL(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x27, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB2(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x28, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PLP(AddressingMode::Stack), - cycles: 4, - }), - ), - ( - 0x29, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0x2a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROL(AddressingMode::Accumulator), - cycles: 2, - }), - ), - ( - 0x2b, - Instruction::Invalid(InvalidInstruction { opcode: 0x2b }), - ), - ( - 0x2c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BIT(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x2d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x2e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROL(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x2f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR2(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x30, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BMI(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0x31, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 5, - }), - ), - ( - 0x32, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::ZeroPageIndirect), - cycles: 5, - }), - ), - ( - 0x33, - Instruction::Invalid(InvalidInstruction { opcode: 0x33 }), - ), - ( - 0x34, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BIT(AddressingMode::ZeroPageIndexedWithX), - cycles: 3, - }), - ), - ( - 0x35, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x36, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROL(AddressingMode::ZeroPageIndexedWithX), - cycles: 6, - }), - ), - ( - 0x37, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB3(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x38, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SEC(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x39, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0x3a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEC(AddressingMode::Accumulator), - cycles: 2, - }), - ), - ( - 0x3b, - Instruction::Invalid(InvalidInstruction { opcode: 0x3b }), - ), - ( - 0x3c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BIT(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0x3d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::AND(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0x3e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROL(AddressingMode::AbsoluteIndexedWithX), - cycles: 7, - }), - ), - ( - 0x3f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR3(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x40, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RTI(AddressingMode::Implied), - cycles: 6, - }), - ), - ( - 0x41, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0x42, - Instruction::Invalid(InvalidInstruction { opcode: 0x42 }), - ), - ( - 0x43, - Instruction::Invalid(InvalidInstruction { opcode: 0x43 }), - ), - ( - 0x44, - Instruction::Invalid(InvalidInstruction { opcode: 0x44 }), - ), - ( - 0x45, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x46, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LSR(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x47, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB4(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x48, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PHA(AddressingMode::Stack), - cycles: 3, - }), - ), - ( - 0x49, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0x4a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LSR(AddressingMode::Accumulator), - cycles: 2, - }), - ), - ( - 0x4b, - Instruction::Invalid(InvalidInstruction { opcode: 0x4b }), - ), - ( - 0x4c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::JMP(AddressingMode::AbsoluteA), - cycles: 3, - }), - ), - ( - 0x4d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x4e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LSR(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x4f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR4(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x50, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BVC(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0x51, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 5, - }), - ), - ( - 0x52, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::ZeroPageIndirect), - cycles: 5, - }), - ), - ( - 0x53, - Instruction::Invalid(InvalidInstruction { opcode: 0x53 }), - ), - ( - 0x54, - Instruction::Invalid(InvalidInstruction { opcode: 0x54 }), - ), - ( - 0x55, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x56, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LSR(AddressingMode::ZeroPageIndexedWithX), - cycles: 6, - }), - ), - ( - 0x57, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB5(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x58, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CLI(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x59, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0x5a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PHY(AddressingMode::Stack), - cycles: 3, - }), - ), - ( - 0x5b, - Instruction::Invalid(InvalidInstruction { opcode: 0x5b }), - ), - ( - 0x5c, - Instruction::Invalid(InvalidInstruction { opcode: 0x5c }), - ), - ( - 0x5d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::EOR(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0x5e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LSR(AddressingMode::AbsoluteIndexedWithX), - cycles: 7, - }), - ), - ( - 0x5f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR5(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x60, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RTS(AddressingMode::Stack), - cycles: 6, - }), - ), - ( - 0x61, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0x62, - Instruction::Invalid(InvalidInstruction { opcode: 0x62 }), - ), - ( - 0x63, - Instruction::Invalid(InvalidInstruction { opcode: 0x63 }), - ), - ( - 0x64, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STZ(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x65, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x66, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROR(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x67, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB6(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x68, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PLA(AddressingMode::Stack), - cycles: 4, - }), - ), - ( - 0x69, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0x6a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROR(AddressingMode::Accumulator), - cycles: 2, - }), - ), - ( - 0x6b, - Instruction::Invalid(InvalidInstruction { opcode: 0x6b }), - ), - ( - 0x6c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::JMP(AddressingMode::AbsoluteIndirect), - cycles: 5, - }), - ), - ( - 0x6d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x6e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROR(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0x6f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR6(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x70, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BVS(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0x71, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 5, - }), - ), - ( - 0x72, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::ZeroPageIndirect), - cycles: 5, - }), - ), - ( - 0x73, - Instruction::Invalid(InvalidInstruction { opcode: 0x73 }), - ), - ( - 0x74, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STZ(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x75, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x76, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROR(AddressingMode::ZeroPageIndexedWithX), - cycles: 6, - }), - ), - ( - 0x77, - Instruction::Valid(ValidInstruction { - opcode: Opcode::RMB7(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x78, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SEI(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x79, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0x7a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PLY(AddressingMode::Stack), - cycles: 4, - }), - ), - ( - 0x7b, - Instruction::Invalid(InvalidInstruction { opcode: 0x7b }), - ), - ( - 0x7c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::JMP(AddressingMode::AbsoluteIndexedIndirect), - cycles: 6, - }), - ), - ( - 0x7d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ADC(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0x7e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::ROR(AddressingMode::AbsoluteIndexedWithX), - cycles: 7, - }), - ), - ( - 0x7f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBR7(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x80, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BRA(AddressingMode::ProgramCounterRelative), - cycles: 3, - }), - ), - ( - 0x81, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0x82, - Instruction::Invalid(InvalidInstruction { opcode: 0x82 }), - ), - ( - 0x83, - Instruction::Invalid(InvalidInstruction { opcode: 0x83 }), - ), - ( - 0x84, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STY(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x85, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x86, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STX(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0x87, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB0(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x88, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEY(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x89, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BIT(AddressingMode::Immediate), - cycles: 3, - }), - ), - ( - 0x8a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TXA(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x8b, - Instruction::Invalid(InvalidInstruction { opcode: 0x8b }), - ), - ( - 0x8c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STY(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x8d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x8e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STX(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x8f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS0(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0x90, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BCC(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0x91, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 6, - }), - ), - ( - 0x92, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::ZeroPageIndirect), - cycles: 5, - }), - ), - ( - 0x93, - Instruction::Invalid(InvalidInstruction { opcode: 0x93 }), - ), - ( - 0x94, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STY(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x95, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0x96, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STX(AddressingMode::ZeroPageIndexedWithY), - cycles: 4, - }), - ), - ( - 0x97, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB1(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0x98, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TYA(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x99, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::AbsoluteIndexedWithY), - cycles: 5, - }), - ), - ( - 0x9a, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TXS(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0x9b, - Instruction::Invalid(InvalidInstruction { opcode: 0x9b }), - ), - ( - 0x9c, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STZ(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0x9d, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STA(AddressingMode::AbsoluteIndexedWithX), - cycles: 5, - }), - ), - ( - 0x9e, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STZ(AddressingMode::AbsoluteIndexedWithX), - cycles: 5, - }), - ), - ( - 0x9f, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS1(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0xa0, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDY(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xa1, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0xa2, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDX(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xa3, - Instruction::Invalid(InvalidInstruction { opcode: 0xa3 }), - ), - ( - 0xa4, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDY(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xa5, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xa6, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDX(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xa7, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB2(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xa8, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TAY(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xa9, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xaa, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TAX(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xab, - Instruction::Invalid(InvalidInstruction { opcode: 0xab }), - ), - ( - 0xac, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDY(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xad, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xae, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDX(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xaf, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS2(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0xb0, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BCS(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0xb1, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 5, - }), - ), - ( - 0xb2, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::ZeroPageIndirect), - cycles: 5, // Unsure, see https://cx16.dk/65c02/reference.html#LDA - }), - ), - ( - 0xb3, - Instruction::Invalid(InvalidInstruction { opcode: 0xb3 }), - ), - ( - 0xb4, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDY(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0xb5, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0xb6, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDX(AddressingMode::ZeroPageIndexedWithY), - cycles: 4, - }), - ), - ( - 0xb7, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB3(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xb8, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CLV(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xb9, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0xba, - Instruction::Valid(ValidInstruction { - opcode: Opcode::TSX(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xbb, - Instruction::Invalid(InvalidInstruction { opcode: 0xbb }), - ), - ( - 0xbc, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDY(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0xbd, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDA(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0xbe, - Instruction::Valid(ValidInstruction { - opcode: Opcode::LDX(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0xbf, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS3(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0xc0, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CPY(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xc1, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0xc2, - Instruction::Invalid(InvalidInstruction { opcode: 0xc2 }), - ), - ( - 0xc3, - Instruction::Invalid(InvalidInstruction { opcode: 0xc3 }), - ), - ( - 0xc4, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CPY(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xc5, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xc6, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEC(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xc7, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB4(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xc8, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INY(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xc9, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xca, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEX(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xcb, - Instruction::Valid(ValidInstruction { - opcode: Opcode::WAI(AddressingMode::Implied), - cycles: 3, - }), - ), - ( - 0xcc, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CPY(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xcd, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xce, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEC(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0xcf, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS4(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0xd0, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BNE(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0xd1, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 5, - }), - ), - ( - 0xd2, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::ZeroPageIndirect), - cycles: 5, // Unsure, look here: https://cx16.dk/65c02/reference.html#CMP - }), - ), - ( - 0xd3, - Instruction::Invalid(InvalidInstruction { opcode: 0xd3 }), - ), - ( - 0xd4, - Instruction::Invalid(InvalidInstruction { opcode: 0xd4 }), - ), - ( - 0xd5, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0xd6, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEC(AddressingMode::ZeroPageIndexedWithX), - cycles: 6, - }), - ), - ( - 0xd7, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB5(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xd8, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CLD(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xd9, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0xda, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PHX(AddressingMode::Stack), - cycles: 3, - }), - ), - ( - 0xdb, - Instruction::Valid(ValidInstruction { - opcode: Opcode::STP(AddressingMode::Implied), - cycles: 3, - }), - ), - ( - 0xdc, - Instruction::Invalid(InvalidInstruction { opcode: 0xdc }), - ), - ( - 0xdd, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CMP(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0xde, - Instruction::Valid(ValidInstruction { - opcode: Opcode::DEC(AddressingMode::AbsoluteIndexedWithX), - cycles: 7, - }), - ), - ( - 0xdf, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS5(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0xe0, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CPX(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xe1, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::ZeroPageIndexedIndirect), - cycles: 6, - }), - ), - ( - 0xe2, - Instruction::Invalid(InvalidInstruction { opcode: 0xe2 }), - ), - ( - 0xe3, - Instruction::Invalid(InvalidInstruction { opcode: 0xe3 }), - ), - ( - 0xe4, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CPX(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xe5, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::ZeroPage), - cycles: 3, - }), - ), - ( - 0xe6, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INC(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xe7, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB6(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xe8, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INX(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xe9, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::Immediate), - cycles: 2, - }), - ), - ( - 0xea, - Instruction::Valid(ValidInstruction { - opcode: Opcode::NOP(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xeb, - Instruction::Invalid(InvalidInstruction { opcode: 0xeb }), - ), - ( - 0xec, - Instruction::Valid(ValidInstruction { - opcode: Opcode::CPX(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xed, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::AbsoluteA), - cycles: 4, - }), - ), - ( - 0xee, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INC(AddressingMode::AbsoluteA), - cycles: 6, - }), - ), - ( - 0xef, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS6(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ( - 0xf0, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BEQ(AddressingMode::ProgramCounterRelative), - cycles: 2, - }), - ), - ( - 0xf1, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::ZeroPageIndirectIndexedWithY), - cycles: 5, - }), - ), - ( - 0xf2, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::ZeroPageIndirect), - cycles: 5, - }), - ), - ( - 0xf3, - Instruction::Invalid(InvalidInstruction { opcode: 0xf3 }), - ), - ( - 0xf4, - Instruction::Invalid(InvalidInstruction { opcode: 0xf4 }), - ), - ( - 0xf5, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::ZeroPageIndexedWithX), - cycles: 4, - }), - ), - ( - 0xf6, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INC(AddressingMode::ZeroPageIndexedWithX), - cycles: 6, - }), - ), - ( - 0xf7, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SMB7(AddressingMode::ZeroPage), - cycles: 5, - }), - ), - ( - 0xf8, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SED(AddressingMode::Implied), - cycles: 2, - }), - ), - ( - 0xf9, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::AbsoluteIndexedWithY), - cycles: 4, - }), - ), - ( - 0xfa, - Instruction::Valid(ValidInstruction { - opcode: Opcode::PLX(AddressingMode::Stack), - cycles: 4, - }), - ), - ( - 0xfb, - Instruction::Invalid(InvalidInstruction { opcode: 0xfb }), - ), - ( - 0xfc, - Instruction::Invalid(InvalidInstruction { opcode: 0xfc }), - ), - ( - 0xfd, - Instruction::Valid(ValidInstruction { - opcode: Opcode::SBC(AddressingMode::AbsoluteIndexedWithX), - cycles: 4, - }), - ), - ( - 0xfe, - Instruction::Valid(ValidInstruction { - opcode: Opcode::INC(AddressingMode::AbsoluteIndexedWithX), - cycles: 7, - }), - ), - ( - 0xff, - Instruction::Valid(ValidInstruction { - opcode: Opcode::BBS7(AddressingMode::ProgramCounterRelativeTest), - cycles: 4, - }), - ), - ]); - opcodes.get(&opcode).unwrap().clone() + let opcodes = include!("./opcodes.in"); + opcodes[opcode as usize] } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum Opcode { ADC(AddressingMode), AND(AddressingMode), @@ -1819,26 +155,26 @@ pub enum Opcode { #[derive(Clone, Copy)] enum AddressingModeValue { - Implied, // Used when an instruction doesn't need an operation, e.g. RTS - Relative(Byte), // Used by branch instructions to offset the program counter - RelativeTest(Byte, Byte), // Used by branch instructions to offset the program counter - Absolute(Word), // Just a plain ol' address - Accumulator(Byte), // This isn't technically accurate, since the datasheet says this would be - // Implied, but we do use the value of the accumulator as the operand so this - // is how i'm gonna do it + Implied, // Used when an instruction doesn't need an operation, e.g. RTS + Relative(u8), // Used by branch instructions to offset the program counter + RelativeTest(u8, u8), // Used by branch instructions to offset the program counter + Absolute(u16), // Just a plain ol' address + Accumulator(u8), // This isn't technically accurate, since the datasheet says this would be + // Implied, but we do use the value of the accumulator as the operand so this + // is how i'm gonna do it } -impl TryFrom for Word { +impl TryFrom for u16 { type Error = anyhow::Error; fn try_from(value: AddressingModeValue) -> Result { match value { AddressingModeValue::Implied => bail!( "An addressing mode value without an address was attempted to turn into a u16" ), - AddressingModeValue::RelativeTest(_zero_page, offset) => Ok(offset as Word), - AddressingModeValue::Relative(inner_value) => Ok(inner_value as Word), + AddressingModeValue::RelativeTest(_zero_page, offset) => Ok(offset as u16), + AddressingModeValue::Relative(inner_value) => Ok(inner_value as u16), AddressingModeValue::Absolute(inner_value) => Ok(inner_value), - AddressingModeValue::Accumulator(inner_value) => Ok(inner_value as Word), + AddressingModeValue::Accumulator(inner_value) => Ok(inner_value as u16), } } } @@ -1856,7 +192,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result AddressingModeValue { // # - let address: Word = cpu.pc; + let address: u16 = cpu.pc; cpu.pc = cpu.pc.wrapping_add(1); AddressingModeValue::Absolute(address) } @@ -1872,7 +208,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result Result { let word = cpu.read_word(cpu.pc)?; cpu.pc = cpu.pc.wrapping_add(2); - let address: Word = word + cpu.x as Word; + let address: u16 = word + cpu.x as u16; Ok(AddressingModeValue::Absolute(address)) } @@ -1891,7 +227,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { let word = cpu.read_word(cpu.pc)?; cpu.pc = cpu.pc.wrapping_add(2); - let address: Word = word + cpu.y as Word; + let address: u16 = word + cpu.y as u16; Ok(AddressingModeValue::Absolute(address)) } @@ -1901,7 +237,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { let byte = cpu.read(cpu.pc); cpu.pc = cpu.pc.wrapping_add(1); - let address: Word = (byte.wrapping_add(cpu.x)) as Word; + let address: u16 = (byte.wrapping_add(cpu.x)) as u16; Ok(AddressingModeValue::Absolute(address)) } @@ -1911,7 +247,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { let byte = cpu.read(cpu.pc); cpu.pc = cpu.pc.wrapping_add(1); - let address: Word = (byte + cpu.y) as Word; + let address: u16 = (byte + cpu.y) as u16; Ok(AddressingModeValue::Absolute(address)) } @@ -1930,7 +266,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { let word = cpu.read_word(cpu.pc)?; - let address = cpu.read_word(word + cpu.x as Word)?; + let address = cpu.read_word(word + cpu.x as u16)?; cpu.pc = cpu.pc.wrapping_add(2); Ok(AddressingModeValue::Absolute(address)) } @@ -1939,10 +275,10 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { - let byte: Byte = cpu.read(cpu.pc); - let address: Word = cpu.read_word(byte as Word)?; + let byte: u8 = cpu.read(cpu.pc); + let address: u16 = cpu.read_word(byte as u16)?; cpu.pc = cpu.pc.wrapping_add(1); - Ok(AddressingModeValue::Absolute(address as Word)) + Ok(AddressingModeValue::Absolute(address)) } fn zero_page_indexed_indirect( @@ -1950,7 +286,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { let byte = cpu.read(cpu.pc); - let address = cpu.read_word((byte.wrapping_add(cpu.x)) as Word)?; // Anytime you see something like `byte as Word`, it's using the byte as a zero-page address + let address = cpu.read_word((byte.wrapping_add(cpu.x)) as u16)?; // Anytime you see something like `byte as u16`, it's using the byte as a zero-page address cpu.pc = cpu.pc.wrapping_add(1); Ok(AddressingModeValue::Absolute(address)) } @@ -1959,8 +295,8 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { - let byte: Byte = cpu.read(cpu.pc); - let address: Word = cpu.read_word(byte.wrapping_add(cpu.y) as Word)?; + let byte: u8 = cpu.read(cpu.pc); + let address: u16 = cpu.read_word(byte.wrapping_add(cpu.y) as u16)?; cpu.pc = cpu.pc.wrapping_add(1); Ok(AddressingModeValue::Absolute(address)) } @@ -1969,7 +305,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { - let byte: Byte = cpu.read(cpu.pc); + let byte: u8 = cpu.read(cpu.pc); cpu.pc = cpu.pc.wrapping_add(1); Ok(AddressingModeValue::Relative(byte)) } @@ -1978,7 +314,7 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result { - let byte: Byte = cpu.read(cpu.pc); + let byte: u8 = cpu.read(cpu.pc); cpu.pc = cpu.pc.wrapping_add(1); let address = cpu.read(cpu.pc); cpu.pc = cpu.pc.wrapping_add(1); @@ -2006,8 +342,8 @@ fn get_address(mode: &AddressingMode, cpu: &mut Cpu) -> Result Result<()> { - fn signed_byte_to_word(value: Byte) -> Word { - let mut value = Word::from(value); + fn signed_byte_to_word(value: u8) -> u16 { + let mut value = u16::from(value); if value & 0x80 > 0 { value |= 0xff00; } @@ -2058,17 +394,17 @@ impl Opcode { let address = get_address(mode, cpu)?; let byte = cpu.read(address.try_into()?); let carry = cpu.get_flag(StatusFlag::Carry); - let result = cpu.a as Word + byte as Word + carry as Word; - cpu.set_flag(StatusFlag::Carry, result > Word::from(u8::max_value())); - cpu.set_flag(StatusFlag::Zero, result as Byte == 0); + let result = cpu.a as u16 + byte as u16 + carry as u16; + cpu.set_flag(StatusFlag::Carry, result > u16::from(u8::max_value())); + cpu.set_flag(StatusFlag::Zero, result as u8 == 0); cpu.set_flag( StatusFlag::Overflow, - (cpu.a ^ byte) & (cpu.a ^ result as Byte) & 0b1000_0000 > 0, + (cpu.a ^ byte) & (cpu.a ^ result as u8) & 0b1000_0000 > 0, // Truly have no idea what's happening here, // check out https://docs.rs/emulator_6502/latest/src/emulator_6502/opcodes/mod.rs.html ); - cpu.set_flag(StatusFlag::Negative, cpu.is_negative(result as Byte)); - cpu.a = result as Byte; + cpu.set_flag(StatusFlag::Negative, cpu.is_negative(result as u8)); + cpu.a = result as u8; Ok(()) } _ => bail!("An incompatible addressing mode was used for instruction {self:#?} at address {:#04x}", cpu.pc) @@ -2092,7 +428,7 @@ impl Opcode { _ => bail!("An incompatible addressing mode was used for instruction {self:#?} at address {:#04x}", cpu.pc) }, Opcode::ASL(mode) => { - fn asl(cpu: &mut Cpu, value: Byte) -> Byte { + fn asl(cpu: &mut Cpu, value: u8) -> u8 { cpu.set_flag(StatusFlag::Carry, value & 0b1000_0000 == 0b1000_0000); let shifted_value = value << 1; cpu.set_flag(StatusFlag::Negative, cpu.is_negative(shifted_value)); @@ -2123,7 +459,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_0001 != 0b0000_0001, value)?; Ok(()) @@ -2138,7 +474,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_0010 != 0b0000_0010, value)?; Ok(()) @@ -2153,7 +489,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_0100 != 0b0000_0100, value)?; Ok(()) @@ -2168,7 +504,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_1000 != 0b0000_1000, value)?; Ok(()) @@ -2183,7 +519,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0001_0000 != 0b0001_0000, value)?; Ok(()) @@ -2198,7 +534,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0010_0000 != 0b0010_0000, value)?; Ok(()) @@ -2213,7 +549,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0100_0000 != 0b0100_0000, value)?; Ok(()) @@ -2228,7 +564,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b1000_0000 != 0b1000_0000, value)?; Ok(()) @@ -2243,7 +579,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_0001 == 0b0000_0001, value)?; Ok(()) @@ -2258,7 +594,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_0010 == 0b0000_0010, value)?; Ok(()) @@ -2273,7 +609,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_0100 == 0b0000_0100, value)?; Ok(()) @@ -2288,7 +624,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0000_1000 == 0b0000_1000, value)?; Ok(()) @@ -2303,7 +639,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0001_0000 == 0b0001_0000, value)?; Ok(()) @@ -2318,7 +654,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0010_0000 == 0b0010_0000, value)?; Ok(()) @@ -2333,7 +669,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b0100_0000 == 0b0100_0000, value)?; Ok(()) @@ -2348,7 +684,7 @@ impl Opcode { AddressingMode::ProgramCounterRelativeTest => match get_address(mode, cpu) { Ok(value) => match value { AddressingModeValue::RelativeTest(byte, _address) => { - let zero_page_address = byte as Word; + let zero_page_address = byte as u16; let test_byte = cpu.read(zero_page_address); branch(cpu, test_byte & 0b1000_0000 == 0b1000_0000, value)?; Ok(()) @@ -2394,11 +730,11 @@ impl Opcode { cpu.set_flag(StatusFlag::Zero, result == 0); cpu.set_flag( StatusFlag::Overflow, - result & StatusFlag::Overflow as Byte == StatusFlag::Overflow as Byte, + result & StatusFlag::Overflow as u8 == StatusFlag::Overflow as u8, ); cpu.set_flag( StatusFlag::Negative, - result & StatusFlag::Negative as Byte == StatusFlag::Negative as Byte, + result & StatusFlag::Negative as u8 == StatusFlag::Negative as u8, ); Ok(()) } @@ -2692,7 +1028,7 @@ impl Opcode { _ => bail!("An incompatible addressing mode was used for instruction {self:#?} at address {:#04x}", cpu.pc) }, Opcode::LSR(mode) => { - fn lsr(cpu: &mut Cpu, value: Byte) -> Byte { + fn lsr(cpu: &mut Cpu, value: u8) -> u8 { cpu.set_flag(StatusFlag::Carry, value & 1 == 1); let shifted_value = value >> 1; cpu.set_flag(StatusFlag::Zero, shifted_value == 0); @@ -2876,8 +1212,8 @@ impl Opcode { _ => bail!("An incompatible addressing mode was used for instruction {self:#?} at address {:#04x}", cpu.pc) }, Opcode::ROL(mode) => { - fn rol(cpu: &mut Cpu, value: Byte) -> Byte { - let carry = cpu.get_flag(StatusFlag::Carry) as Byte; + fn rol(cpu: &mut Cpu, value: u8) -> u8 { + let carry = cpu.get_flag(StatusFlag::Carry) as u8; cpu.set_flag(StatusFlag::Carry, value >> 7 == 1); let shifted_value = (value << 1) + carry; cpu.set_flag(StatusFlag::Negative, cpu.is_negative(shifted_value)); @@ -2903,8 +1239,8 @@ impl Opcode { } } Opcode::ROR(mode) => { - fn ror(cpu: &mut Cpu, value: Byte) -> Byte { - let carry = cpu.get_flag(StatusFlag::Carry) as Byte; + fn ror(cpu: &mut Cpu, value: u8) -> u8 { + let carry = cpu.get_flag(StatusFlag::Carry) as u8; cpu.set_flag(StatusFlag::Carry, value & 1 == 1); let shifted_value = (value >> 1) + (carry << 7); cpu.set_flag(StatusFlag::Negative, cpu.is_negative(shifted_value)); @@ -2958,16 +1294,16 @@ impl Opcode { let address = get_address(mode, cpu)?; let byte = cpu.read(address.try_into()?); let carry = cpu.get_flag(StatusFlag::Carry); - let result = cpu.a as Word + byte as Word + !carry as Word; - cpu.set_flag(StatusFlag::Carry, result > Word::from(u8::max_value())); - cpu.set_flag(StatusFlag::Zero, result as Byte == 0); + let result = cpu.a as u16 + byte as u16 + !carry as u16; + cpu.set_flag(StatusFlag::Carry, result > u16::from(u8::max_value())); + cpu.set_flag(StatusFlag::Zero, result as u8 == 0); cpu.set_flag( StatusFlag::Overflow, - (cpu.a ^ byte) & (cpu.a ^ result as Byte) & 0b1000_0000 > 0, + (cpu.a ^ byte) & (cpu.a ^ result as u8) & 0b1000_0000 > 0, // Truly have no idea what's happening here, // check out https://docs.rs/emulator_6502/latest/src/emulator_6502/opcodes/mod.rs.html ); - cpu.set_flag(StatusFlag::Negative, cpu.is_negative(result as Byte)); + cpu.set_flag(StatusFlag::Negative, cpu.is_negative(result as u8)); Ok(()) } _ => bail!("An incompatible addressing mode was used for instruction {self:#?} at address {:#04x}", cpu.pc) diff --git a/src/main.rs b/src/main.rs index 60fff2e..f1d758b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,12 +12,16 @@ mod video; use crate::cpu::Cpu; use crate::keyboard::Keyboard; use crate::memory::Mem; -use crate::video::Crtc; +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 minifb::{Scale, ScaleMode, Window, WindowOptions}; use serde::{Deserialize, Serialize}; use std::{ @@ -30,13 +34,12 @@ use std::{ }; use crossterm::{ + cursor, event::{self, KeyCode, KeyEventKind}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, - ExecutableCommand, + // ExecutableCommand, }; -use ratatui::prelude::{CrosstermBackend, Terminal}; - // use toml::Table; //#[derive(Parser)] @@ -53,10 +56,10 @@ struct Config { } fn main() -> Result<()> { - stdout().execute(EnterAlternateScreen)?; + let mut stdout = stdout(); + let (cols, rows) = size()?; + execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?; enable_raw_mode()?; - let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; - terminal.clear()?; let config: Config = match File::open("./config.toml") { Ok(mut file) => { @@ -86,50 +89,60 @@ fn main() -> Result<()> { let keyboard_memory = shared_memory.clone(); let (cpu_tx, cpu_rx) = mpsc::channel(); - let (state_tx, state_rx) = mpsc::channel(); + // let (state_tx, state_rx) = mpsc::channel(); let screen_cpu_tx = cpu_tx.clone(); - let (window_tx, window_rx) = mpsc::channel(); + // let (window_tx, window_rx) = mpsc::channel(); - thread::spawn(move || { - let mut screen = Crtc::new( - screen_memory, - config.char_rom.as_ref(), - CpuController::new(screen_cpu_tx), - window_tx, - ); - screen.run(); - }); + // thread::spawn(move || { + // let mut screen = Crtc::new( + // screen_memory, + // config.char_rom.as_ref(), + // CpuController::new(screen_cpu_tx), + // window_tx, + // ); + // screen.run(); + // }); - let mut window = Window::new( - "ʕ·ᴥ·ʔ-☆", - 512, - 380, - WindowOptions { - resize: true, - borderless: true, - title: true, - transparency: false, - scale: Scale::X2, - scale_mode: ScaleMode::AspectRatioStretch, - topmost: false, - none: true, - }, - ) - .unwrap(); + // let mut window = Window::new( + // "ʕ·ᴥ·ʔ-☆", + // 512, + // 380, + // WindowOptions { + // resize: true, + // borderless: true, + // title: true, + // transparency: false, + // scale: Scale::X2, + // scale_mode: ScaleMode::AspectRatioStretch, + // topmost: false, + // none: true, + // }, + // ) + // .unwrap(); - window.set_input_callback(Box::new(Keyboard::new(keyboard_memory))); + // window.set_input_callback(Box::new(Keyboard::new(keyboard_memory))); - let mut cpu = Cpu::new(cpu_memory, CpuReceiver::new(cpu_rx), state_tx); - let mut tui = tui::App::new( - CpuController::new(cpu_tx.clone()), - shared_memory.clone(), - state_rx, - ); + 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 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(); + // }); + loop { if event::poll(std::time::Duration::from_millis(16))? { if let event::Event::Key(key) = event::read()? { @@ -138,11 +151,17 @@ fn main() -> Result<()> { } } } - let buffer = window_rx.recv().unwrap(); - window.update_with_buffer(&buffer, 512, 380).unwrap(); - tui.update(&mut terminal)?; + // let buffer = window_rx.recv().unwrap(); + screen.draw() + // tui.update(&mut terminal)?; } - stdout().execute(LeaveAlternateScreen)?; + + execute!( + stdout, + LeaveAlternateScreen, + SetSize(cols, rows), + Clear(ClearType::Purge) + )?; disable_raw_mode()?; Ok(()) } diff --git a/src/memory.rs b/src/memory.rs index fb5e739..634a832 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -53,12 +53,18 @@ pub struct Mem { pub data: Vec, } -impl Mem { - pub fn new() -> Self { +impl Default for Mem { + fn default() -> Self { Self { data: vec![0; u16::MAX as usize + 1], } } +} + +impl Mem { + pub fn new() -> Self { + Mem::default() + } pub fn dump(&self, path: PathBuf) -> io::Result<()> { let mut outfile = File::create(path)?; outfile.write_all(&self.data)?; diff --git a/src/opcodes.in b/src/opcodes.in new file mode 100644 index 0000000..39e1d74 --- /dev/null +++ b/src/opcodes.in @@ -0,0 +1,894 @@ +vec![ + Instruction::Valid(ValidInstruction { + opcode: Opcode::BRK(AddressingMode::Implied), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x02 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x03 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TSB(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ASL(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB0(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PHP(AddressingMode::Stack), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ASL(AddressingMode::Accumulator), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x0b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TSB(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ASL(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR0(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BPL(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::AbsoluteIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::ZeroPageIndirect), + cycles: 5, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x13 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TRB(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ASL(AddressingMode::ZeroPageIndexedWithX), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB1(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CLC(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INC(AddressingMode::Accumulator), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x1b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TRB(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ORA(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ASL(AddressingMode::AbsoluteIndexedWithX), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR1(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::JSR(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x22 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x23 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BIT(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROL(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB2(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PLP(AddressingMode::Stack), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROL(AddressingMode::Accumulator), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x2b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BIT(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROL(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR2(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BMI(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::ZeroPageIndirect), + cycles: 5, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x33 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BIT(AddressingMode::ZeroPageIndexedWithX), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROL(AddressingMode::ZeroPageIndexedWithX), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB3(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SEC(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEC(AddressingMode::Accumulator), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x3b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BIT(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::AND(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROL(AddressingMode::AbsoluteIndexedWithX), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR3(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RTI(AddressingMode::Implied), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x42 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x43 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x44 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LSR(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB4(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PHA(AddressingMode::Stack), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LSR(AddressingMode::Accumulator), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x4b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::JMP(AddressingMode::AbsoluteA), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LSR(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR4(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BVC(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::ZeroPageIndirect), + cycles: 5, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x53 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x54 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LSR(AddressingMode::ZeroPageIndexedWithX), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB5(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CLI(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PHY(AddressingMode::Stack), + cycles: 3, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x5b }), + Instruction::Invalid(InvalidInstruction { opcode: 0x5c }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::EOR(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LSR(AddressingMode::AbsoluteIndexedWithX), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR5(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RTS(AddressingMode::Stack), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x62 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x63 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STZ(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROR(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB6(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PLA(AddressingMode::Stack), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROR(AddressingMode::Accumulator), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x6b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::JMP(AddressingMode::AbsoluteIndirect), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROR(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR6(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BVS(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::ZeroPageIndirect), + cycles: 5, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x73 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STZ(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROR(AddressingMode::ZeroPageIndexedWithX), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::RMB7(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SEI(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PLY(AddressingMode::Stack), + cycles: 4, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x7b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::JMP(AddressingMode::AbsoluteIndexedIndirect), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ADC(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::ROR(AddressingMode::AbsoluteIndexedWithX), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBR7(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BRA(AddressingMode::ProgramCounterRelative), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x82 }), + Instruction::Invalid(InvalidInstruction { opcode: 0x83 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STY(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STX(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB0(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEY(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BIT(AddressingMode::Immediate), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TXA(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x8b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STY(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STX(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS0(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BCC(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::ZeroPageIndirect), + cycles: 5, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x93 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STY(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STX(AddressingMode::ZeroPageIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB1(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TYA(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::AbsoluteIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TXS(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0x9b }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STZ(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STA(AddressingMode::AbsoluteIndexedWithX), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STZ(AddressingMode::AbsoluteIndexedWithX), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS1(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDY(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDX(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xa3 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDY(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDX(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB2(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TAY(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TAX(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xab }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDY(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDX(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS2(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BCS(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::ZeroPageIndirect), + cycles: 5, // Unsure, see https://cx16.dk/65c02/reference.html#LDA + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xb3 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDY(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDX(AddressingMode::ZeroPageIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB3(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CLV(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::TSX(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xbb }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDY(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDA(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::LDX(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS3(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CPY(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xc2 }), + Instruction::Invalid(InvalidInstruction { opcode: 0xc3 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CPY(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEC(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB4(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INY(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEX(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::WAI(AddressingMode::Implied), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CPY(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEC(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS4(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BNE(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::ZeroPageIndirect), + cycles: 5, // Unsure, look here: https://cx16.dk/65c02/reference.html#CMP + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xd3 }), + Instruction::Invalid(InvalidInstruction { opcode: 0xd4 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEC(AddressingMode::ZeroPageIndexedWithX), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB5(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CLD(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PHX(AddressingMode::Stack), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::STP(AddressingMode::Implied), + cycles: 3, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xdc }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CMP(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::DEC(AddressingMode::AbsoluteIndexedWithX), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS5(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CPX(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::ZeroPageIndexedIndirect), + cycles: 6, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xe2 }), + Instruction::Invalid(InvalidInstruction { opcode: 0xe3 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CPX(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::ZeroPage), + cycles: 3, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INC(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB6(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INX(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::Immediate), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::NOP(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xeb }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::CPX(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::AbsoluteA), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INC(AddressingMode::AbsoluteA), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS6(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BEQ(AddressingMode::ProgramCounterRelative), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::ZeroPageIndirectIndexedWithY), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::ZeroPageIndirect), + cycles: 5, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xf3 }), + Instruction::Invalid(InvalidInstruction { opcode: 0xf4 }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::ZeroPageIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INC(AddressingMode::ZeroPageIndexedWithX), + cycles: 6, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SMB7(AddressingMode::ZeroPage), + cycles: 5, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SED(AddressingMode::Implied), + cycles: 2, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::AbsoluteIndexedWithY), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::PLX(AddressingMode::Stack), + cycles: 4, + }), + Instruction::Invalid(InvalidInstruction { opcode: 0xfb }), + Instruction::Invalid(InvalidInstruction { opcode: 0xfc }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::SBC(AddressingMode::AbsoluteIndexedWithX), + cycles: 4, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::INC(AddressingMode::AbsoluteIndexedWithX), + cycles: 7, + }), + Instruction::Valid(ValidInstruction { + opcode: Opcode::BBS7(AddressingMode::ProgramCounterRelativeTest), + cycles: 4, + }), +] diff --git a/src/video.rs b/src/video.rs index bbd4a4c..d8943be 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1,9 +1,22 @@ +use crossterm::{ + cursor::{MoveTo, SavePosition}, + execute, queue, + style::{Color, PrintStyledContent, Stylize}, +}; + use crate::{ cpu::CpuController, - memory::{MemHandle, MemoryReader}, + memory::{self, MemHandle, MemoryReader}, types::{Byte, Word}, }; -use std::{fs::File, io::Read, path::Path, sync::mpsc::Sender, thread::sleep, time::Duration}; +use std::{ + fs::File, + io::{Read, Stdout, StdoutLock, Write}, + path::Path, + sync::mpsc::Sender, + thread::sleep, + time::Duration, +}; const FG_COLOR: u32 = 0xFFCC00; const BG_COLOR: u32 = 0x110500; @@ -27,44 +40,37 @@ where } } -pub struct Crtc { - memory: MemHandle, - buffer: Vec, +trait Renderer { + fn render(&mut self) {} +} + +pub struct WindowRenderer { char_rom: Vec, - cpu_controller: CpuController, window: Sender>, + memory: MemHandle, } -impl MemoryReader for Crtc { - fn read(&self, address: Word) -> Byte { - self.memory.read(address) - } -} - -impl Crtc { - pub fn new

( - memory: MemHandle, - char_rom: Option

, - cpu_controller: CpuController, - window: Sender>, - ) -> Self +impl WindowRenderer { + pub fn new

(memory: MemHandle, char_rom: Option

, window: Sender>) -> Self where P: AsRef, { let char_rom = get_char_bin(char_rom); Self { memory, - buffer: vec![0; 512 * 380], window, char_rom, - cpu_controller, } } - fn draw(&mut self) { +} + +impl Renderer for WindowRenderer { + fn render(&mut self) { // the rest of this function is arcane wizardry // based on the specifics of george's weird // display and characters... don't fuck around w it let mut i = 0; + 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); @@ -75,23 +81,114 @@ impl Crtc { let buffer_index = ((char_row) * 13 + (row)) * 512 + (char_col * 8 + bit_index); if (byte << bit_index) & 0x80 == 0x80 { - self.buffer[buffer_index] = FG_COLOR; + buffer[buffer_index] = FG_COLOR; } else { - self.buffer[buffer_index] = BG_COLOR; + buffer[buffer_index] = BG_COLOR; } } } } + + let _ = self.window.send(buffer.clone()); } + } +} - let buffer = self.buffer.to_owned(); +impl MemoryReader for WindowRenderer { + fn read(&self, address: Word) -> Byte { + self.memory.read(address) + } +} - let _ = self.window.send(buffer); +pub struct TerminalRenderer<'a> { + memory: MemHandle, + // stdout: Stdout, + stdout: StdoutLock<'a>, +} + +impl<'a> TerminalRenderer<'a> { + pub fn new(memory: MemHandle, stdout: StdoutLock<'a>) -> Self { + Self { memory, stdout } + } +} + +impl MemoryReader for TerminalRenderer<'_> { + fn read(&self, address: Word) -> Byte { + self.memory.read(address) + } +} + +static ASCII_LOOPUP: [&str; 256] = [ + " ", "░", "▒", "▓", "♡", "♥", "⭐", "✭", "", "✦", "✨", "♀", "♂", "⚢", "⚣", "⚥", "♩", "♪", + "♫", "♬", "ﱝ", "", "", "", "奄", "奔", "婢", "ﱜ", "ﱛ", "", "", "", " ", "!", "\"", "#", + "$", "%", "&", "\'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", + "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", + "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "─", "│", "┌", "└", + "├", "┤", "┬", "┴", "┼", "╭", "╮", "╯", "╰", "╱", "╲", "╳", "═", "║", "╔", "╗", "╚", "╝", "╠", + "╣", "╦", "╩", "╬", "", "", "", "", "", "", "", "", "", "", "", "", "", "▁", "▂", + "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", "ʕ", "·", "ᴥ", "ʔ", "▖", "▗", + "▘", "▙", "▚", "▛", "▜", "▝", "▞", "▟", "←", "↑", "→", "↓", "⭠", "⭡", "⭢", "⭣", "⮀", "⮁", "⮂", + "⮃", "", "", "⏳", "", "", "", "", "", "", "", "", "", "", "", "🔮", "", "", + "◇", "◈", "🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘", "", "✔", "✘", "◆", "", "", "", + "", "", "", "", "🎁", "", "", "", "", "⚐", "⚑", "", "", "", +]; + +impl Renderer for TerminalRenderer<'_> { + fn render(&mut self) { + 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); + i += 1; + let char = ASCII_LOOPUP[ascii as usize]; + let _ = queue!( + // FG_COLOR = 0xFFCC00 + // BG_COLOR = 0x110500 + self.stdout, + MoveTo(char_col, char_row), + PrintStyledContent( + char.with(Color::Rgb { + r: 0xFF, + g: 0xCC, + b: 0x00 + }) + .on(Color::Rgb { + r: 0x11, + g: 0x05, + b: 0x00 + }) + ) + ); + } + } + let _ = self.stdout.flush(); + } +} + +pub struct Screen<'a> { + cpu_controller: CpuController, + // renderer: Box, + renderer: TerminalRenderer<'a>, +} + +impl<'a> Screen<'a> { + // pub fn new(cpu_controller: CpuController, renderer: Box) -> Self { + pub fn new(cpu_controller: CpuController, renderer: TerminalRenderer<'a>) -> Self { + Self { + cpu_controller, + renderer, + } + } + pub fn draw(&mut self) { + self.renderer.render(); } pub fn run(&mut self) { loop { - let _ = self.cpu_controller.irq(); + self.cpu_controller.irq(); sleep(Duration::from_millis(16)); self.draw(); }