Compare commits

..

27 Commits

Author SHA1 Message Date
Mwa
128a53bd3b improved debug 2026-03-27 22:40:28 +01:00
Mwa
689f4b77fd slightly improved asm debug message 2026-03-26 21:24:14 +01:00
Mwa
96c3a514f2 fixed up debug PC/SP addr 2026-03-26 20:26:51 +01:00
Mwa
e97b4c4ee4 fixed up debug command 2026-03-26 20:11:32 +01:00
Mwa
a51b6589f0 removed subdir 2026-03-26 17:07:00 +01:00
Mwa
cebc8fcc5b bitmap to asm moved to the other repo 2026-03-26 13:18:51 +01:00
Mwa
b664538923 added color to img 2026-03-25 09:42:23 +01:00
Mwa
3525db5299 added a warn when frame lag 2026-03-24 23:16:33 +01:00
Mwa
8d7cb5e6f3 fixed import on non-debug build 2026-03-24 15:36:52 +01:00
Mwa
ced0e13f6b improved debug interface 2026-03-23 19:19:38 +01:00
Mwa
c6b58dbc21 again, some minor perf improvement, probably be the last 2026-03-21 00:08:45 +01:00
Mwa
af111c5992 minor interupt on halt responsivity improvement and final Cargo.toml args 2026-03-20 19:30:00 +01:00
Mwa
b5962c6b50 minor performance improvement for jump/call 2026-03-20 11:18:48 +01:00
Mwa
ff6427b020 performance improvement 2026-03-20 11:08:18 +01:00
Mwa
c72e133cde Implemented correct behavior for lsl, asr, lsr (mask and correct for input = 32) 2026-03-19 21:35:49 +01:00
Mwa
c844f8d806 added nosize arg 2026-03-18 15:07:05 +01:00
Mwa
5c5d8471fa minor graphic modification 2026-03-17 23:10:58 +01:00
Mwa
94120273bb better rgba 2026-03-17 22:04:21 +01:00
Mwa
978bb30fdb Merge branch 'main' of ssh://gitea.jthillard.fr:222/mwa/bisare_sim_rs 2026-03-17 21:21:53 +01:00
Mwa
5dd9328008 fic debug build 2026-03-17 21:21:46 +01:00
mwa
f6cc53075a clarified entry point meaning 2026-03-17 20:16:33 +00:00
Mwa
8fa56c5b6f compilation fix 2026-03-17 21:05:51 +01:00
Mwa
902ed046ca futex feature explained 2026-03-17 20:32:33 +01:00
Mwa
f17b849da2 busy wait for macos 2026-03-17 17:23:00 +01:00
Mwa
d04b6f35c3 busy wait for macos 2026-03-17 17:21:52 +01:00
Mwa
47efeef83d changed futex crate for mac compat (maybe) and image to bitmap assembly converter 2026-03-17 16:31:45 +01:00
Mwa
20f7c289ed -1 on unrecognized input and start bitmap converter 2026-03-17 13:22:33 +01:00
9 changed files with 1211 additions and 540 deletions

2
.cargo/config.toml Normal file
View File

@@ -0,0 +1,2 @@
[build]
rustflags = ["-Ctarget-cpu=native"]

617
Cargo.lock generated
View File

@@ -82,6 +82,56 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "arrayref" name = "arrayref"
version = "0.3.9" version = "0.3.9"
@@ -117,16 +167,6 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "atomic-wait"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55b94919229f2c42292fd71ffa4b75e83193bffdd77b1e858cd55fd2d0b0ea8"
dependencies = [
"libc",
"windows-sys 0.42.0",
]
[[package]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.2" version = "1.1.2"
@@ -165,6 +205,9 @@ name = "bitflags"
version = "2.11.0" version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
dependencies = [
"serde_core",
]
[[package]] [[package]]
name = "block" name = "block"
@@ -227,9 +270,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.56" version = "1.2.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -261,6 +304,92 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
"iana-time-zone",
"num-traits",
"serde",
"windows-link",
]
[[package]]
name = "clap"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap-repl"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ffd4e57297ee7a10fb637964a79fd4bf5c8d22fd4ceaac5d3964d55df9e9e38"
dependencies = [
"clap",
"clap_complete",
"console",
"nu-ansi-term",
"reedline",
"shlex",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstream",
"anstyle",
"clap_lex 1.1.0",
"strsim",
]
[[package]]
name = "clap_complete"
version = "4.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c677cd0126f3026d8b093fa29eae5d812fde5c05bc66dbb29d0374eea95113a"
dependencies = [
"clap",
"clap_lex 0.7.7",
"is_executable",
"pathdiff",
"shlex",
"unicode-xid",
]
[[package]]
name = "clap_derive"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "clap_lex"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32"
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]] [[package]]
name = "codespan-reporting" name = "codespan-reporting"
version = "0.11.1" version = "0.11.1"
@@ -268,9 +397,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [ dependencies = [
"termcolor", "termcolor",
"unicode-width", "unicode-width 0.1.14",
] ]
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]] [[package]]
name = "com" name = "com"
version = "0.6.0" version = "0.6.0"
@@ -321,6 +456,19 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "console"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width 0.2.2",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@@ -367,6 +515,32 @@ version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crossterm"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
"bitflags 2.11.0",
"crossterm_winapi",
"mio",
"parking_lot",
"rustix 0.38.44",
"serde",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "cursor-icon" name = "cursor-icon"
version = "1.2.0" version = "1.2.0"
@@ -411,6 +585,18 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.2" version = "1.0.2"
@@ -427,6 +613,17 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "fd-lock"
version = "4.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78"
dependencies = [
"cfg-if",
"rustix 1.1.4",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.9"
@@ -621,6 +818,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.5.2" version = "0.5.2"
@@ -633,6 +836,30 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core 0.62.2",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.13.0" version = "2.13.0"
@@ -643,6 +870,30 @@ dependencies = [
"hashbrown 0.16.1", "hashbrown 0.16.1",
] ]
[[package]]
name = "is_executable"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baabb8b4867b26294d818bf3f651a454b6901431711abb96e296245888d6e8c4"
dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.21.1" version = "0.21.1"
@@ -806,6 +1057,18 @@ dependencies = [
"paste", "paste",
] ]
[[package]]
name = "mio"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "naga" name = "naga"
version = "0.19.2" version = "0.19.2"
@@ -865,6 +1128,15 @@ dependencies = [
"jni-sys", "jni-sys",
] ]
[[package]]
name = "nu-ansi-term"
version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@@ -876,9 +1148,9 @@ dependencies = [
[[package]] [[package]]
name = "num_enum" name = "num_enum"
version = "0.7.5" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
dependencies = [ dependencies = [
"num_enum_derive", "num_enum_derive",
"rustversion", "rustversion",
@@ -886,9 +1158,9 @@ dependencies = [
[[package]] [[package]]
name = "num_enum_derive" name = "num_enum_derive"
version = "0.7.5" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
dependencies = [ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
@@ -1120,15 +1392,21 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]] [[package]]
name = "orbclient" name = "orbclient"
version = "0.3.50" version = "0.3.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ad2c6bae700b7aa5d1cc30c59bdd3a1c180b09dbaea51e2ae2b8e1cf211fdd" checksum = "59aed3b33578edcfa1bc96a321d590d31832b6ad55a26f0313362ce687e9abd6"
dependencies = [ dependencies = [
"libc", "libc",
"libredox", "libredox",
@@ -1181,6 +1459,12 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pathdiff"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.2" version = "2.3.2"
@@ -1352,6 +1636,26 @@ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
] ]
[[package]]
name = "reedline"
version = "0.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bfa8cb0ad84c396c936d8abb814703d7042a433d2da75a0c7060cbdc89109f3"
dependencies = [
"chrono",
"crossterm",
"fd-lock",
"itertools",
"nu-ansi-term",
"serde",
"strip-ansi-escapes",
"strum",
"strum_macros",
"thiserror",
"unicode-segmentation",
"unicode-width 0.1.14",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.12.3" version = "1.12.3"
@@ -1475,6 +1779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [ dependencies = [
"serde_core", "serde_core",
"serde_derive",
] ]
[[package]] [[package]]
@@ -1503,13 +1808,46 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [
"errno",
"libc",
]
[[package]] [[package]]
name = "simu" name = "simu"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"atomic-wait", "clap",
"clap-repl",
"parse_int", "parse_int",
"pixels", "pixels",
"wait_on_address",
"winit", "winit",
"winit_input_helper", "winit_input_helper",
] ]
@@ -1590,6 +1928,40 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
[[package]]
name = "strip-ansi-escapes"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025"
dependencies = [
"vte",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
[[package]]
name = "strum_macros"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.117",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@@ -1668,18 +2040,18 @@ dependencies = [
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "1.0.0+spec-1.1.0" version = "1.0.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9"
dependencies = [ dependencies = [
"serde_core", "serde_core",
] ]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.25.4+spec-1.1.0" version = "0.25.5+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"toml_datetime", "toml_datetime",
@@ -1689,9 +2061,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_parser" name = "toml_parser"
version = "1.0.9+spec-1.1.0" version = "1.0.10+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420"
dependencies = [ dependencies = [
"winnow", "winnow",
] ]
@@ -1745,18 +2117,53 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unicode-width"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.6" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "vte"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077"
dependencies = [
"memchr",
]
[[package]]
name = "wait_on_address"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f46f0d222fdc7fac38a2ad9f0fabdc5af18d0c9d12c5fc52438509cf88674cf"
dependencies = [
"js-sys",
"libc",
"rustversion",
"wasm-bindgen",
"web-sys",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.5.0" version = "2.5.0"
@@ -1767,6 +2174,12 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]] [[package]]
name = "wasip2" name = "wasip2"
version = "1.0.2+wasi-0.2.9" version = "1.0.2+wasi-0.2.9"
@@ -2124,7 +2537,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [ dependencies = [
"windows-core", "windows-core 0.52.0",
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
@@ -2137,6 +2550,41 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]] [[package]]
name = "windows-link" name = "windows-link"
version = "0.2.1" version = "0.2.1"
@@ -2144,18 +2592,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]] [[package]]
name = "windows-sys" name = "windows-result"
version = "0.42.0" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.42.2", "windows-link",
"windows_aarch64_msvc 0.42.2", ]
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2", [[package]]
"windows_x86_64_gnu 0.42.2", name = "windows-strings"
"windows_x86_64_gnullvm 0.42.2", version = "0.5.1"
"windows_x86_64_msvc 0.42.2", source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
] ]
[[package]] [[package]]
@@ -2185,6 +2636,15 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.61.2" version = "0.61.2"
@@ -2218,13 +2678,30 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm", "windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6", "windows_x86_64_msvc 0.52.6",
] ]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.42.2" version = "0.42.2"
@@ -2237,6 +2714,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.42.2" version = "0.42.2"
@@ -2249,6 +2732,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.42.2" version = "0.42.2"
@@ -2261,12 +2750,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]] [[package]]
name = "windows_i686_gnullvm" name = "windows_i686_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.42.2" version = "0.42.2"
@@ -2279,6 +2780,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.42.2" version = "0.42.2"
@@ -2291,6 +2798,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.42.2" version = "0.42.2"
@@ -2303,6 +2816,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.42.2" version = "0.42.2"
@@ -2315,6 +2834,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.30.13" version = "0.30.13"
@@ -2379,9 +2904,9 @@ dependencies = [
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.7.15" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -2457,18 +2982,18 @@ checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.42" version = "0.8.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.8.42" version = "0.8.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@@ -3,4 +3,5 @@ resolver = "3"
members = ["simu","asm"] members = ["simu","asm"]
[profile.release] [profile.release]
debug = "line-tables-only" opt-level = 2
# panic = "abort"

View File

@@ -31,9 +31,10 @@ syntaxe supplémentaire supportée:
## Features ## Features
rajouter --features=[liste séparé par des virgules] rajouter --features=[liste séparé par des virgules]
- div_mul: Support des instruction de multiplication / division - div_mul: Support des instruction de multiplication / division
- rgba: Écran au format RGBA plutot que 0BGR - rgba: Écran au format RGBA plutot que 0BGR (alpha ignoré mais stocké)
- rich_keyboard: rajoute trois champs de mmio pour le clavier. Voir MMIO - rich_keyboard: rajoute trois champs de mmio pour le clavier. Voir MMIO
- debug: repl similaire a la version python du simulateur - debug: repl similaire a la version python du simulateur
- futex: accélère le programme. ne marche pas sur les macs. actif par default, utiliser --no-default-features pour le desactiver
### instruction spéciale: ### instruction spéciale:
halt (jump 0) met le programme en pause, mais on peut se reveiller par des interuptions halt (jump 0) met le programme en pause, mais on peut se reveiller par des interuptions
@@ -43,7 +44,7 @@ call 0 termine l'exécution du simulateur proprement
## mmio: ## mmio:
- 0x01000000 à 0x0112c000 : Écran en lecture/écriture. un pixel par 32bits, de gauche a droite puis de bas en haut. - 0x01000000 à 0x0112c000 : Écran en lecture/écriture. un pixel par 32bits, de gauche a droite puis de bas en haut.
Format de pixel en 0BGR, 4 bits par couleur. Format de pixel en 0BGR, 4 bits par couleur.
Passage au format RGBA (a pour alpha) avec la feature rgba Passage au format RGBA (alpha ignoré, mais stocké) avec la feature rgba
- 0x01200000 : Clavier (scancode) (lecture seule) - 0x01200000 : Clavier (scancode) (lecture seule)
- 0x01200004 : Horloge (millisecondes écoulé depuis le début de la simulation, wrappe tout les 49 jours) (lecture seule) - 0x01200004 : Horloge (millisecondes écoulé depuis le début de la simulation, wrappe tout les 49 jours) (lecture seule)
- 0x01200008 : Boutons de la souris (OR des boutons préssés) Gauche = 1, Droit=2, Clic Molette = 3, Autres non testé (lecture seule) - 0x01200008 : Boutons de la souris (OR des boutons préssés) Gauche = 1, Droit=2, Clic Molette = 3, Autres non testé (lecture seule)
@@ -78,6 +79,7 @@ de même, `reti` ne peut pas être appellé par une sous fonction appellée depu
Les intéruptions et leurs arguments, par priorité croissante: Les intéruptions et leurs arguments, par priorité croissante:
### 0: Point d'entrée ### 0: Point d'entrée
C'est ici que le programme commence. Seul cas d'utilisation C'est ici que le programme commence. Seul cas d'utilisation
(ce n'est pas vraiment une interruption, juste la première entrée dans la jump table)
### 1: MMIO ### 1: MMIO
Doivent être activé par le MMIO a l'adresse 0x01201000, en y écrivant le OR des (1<<identifiant) Doivent être activé par le MMIO a l'adresse 0x01201000, en y écrivant le OR des (1<<identifiant)
On toujours pour argument (r0) leur identifiant On toujours pour argument (r0) leur identifiant

View File

@@ -207,7 +207,9 @@ impl Instruction {
} }
}; };
if jump_distance > 15 { if jump_distance > 15 {
println!("Error, cannot skip more than 15 instructions"); println!(
"Error, cannot skip {jump_distance} which is more than 15 instructions"
);
return Err(()); return Err(());
} }
encode_op2(11, cond.into(), jump_distance, reg.into(), *op2) encode_op2(11, cond.into(), jump_distance, reg.into(), *op2)

View File

@@ -4,15 +4,21 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
atomic-wait = "1.1.0"
pixels = "0.15.0" pixels = "0.15.0"
winit = { version = "0.30.13", features = ["x11", "x11-dl", "x11rb", "ahash", "bytemuck", "memmap2", "rwh_06", "sctk", "sctk-adwaita"] } winit = { version = "0.30.13", features = ["x11", "x11-dl", "x11rb", "ahash", "bytemuck", "memmap2", "rwh_06", "sctk", "sctk-adwaita"] }
winit_input_helper = "0.17.0" winit_input_helper = "0.17.0"
parse_int = { version = "0.9.0", optional = true } parse_int = { version = "0.9.0", optional = true }
wait_on_address = { version = "0.1.4", optional = true }
clap-repl = { version = "0.3.2", optional = true }
clap = { version = "4.6.0", optional = true }
[features] [features]
default = ["futex"]
div_mul = [] div_mul = []
rgba = [] rgba = []
rich_keyboard = [] rich_keyboard = []
debug = ["dep:parse_int"] debug = ["dep:parse_int","dep:clap-repl","dep:clap"]
futex = ["dep:wait_on_address"]
clap-repl = ["dep:clap-repl"]
clap = ["dep:clap"]

View File

@@ -1,15 +1,17 @@
use crate::wait::WaitOnAtomic;
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
use std::collections::HashMap; use std::collections::HashMap;
use std::{ use std::{
hint::{likely, unlikely, unreachable_unchecked}, hint::{cold_path, likely, unlikely, unreachable_unchecked},
io::Read, io::Read,
mem::transmute, mem::transmute,
ops::{Index, IndexMut}, ops::{Index, IndexMut},
process::exit,
sync::atomic::AtomicU32, sync::atomic::AtomicU32,
time::{self, Instant}, time::{self, Instant},
}; };
#[cfg(not(feature = "debug"))]
use std::process::exit;
pub(crate) struct SharedState { pub(crate) struct SharedState {
pub(crate) keyboard: [AtomicU32; 4], pub(crate) keyboard: [AtomicU32; 4],
pub(crate) screen_buf: [AtomicU32; 480 * 640], pub(crate) screen_buf: [AtomicU32; 480 * 640],
@@ -32,17 +34,26 @@ enum Op2 {
} }
struct Reg(u8); struct Reg(u8);
#[allow(unused)] //constructed by transmute
#[repr(u8)]
enum Cond { enum Cond {
Ifeq, Ifeq = 0b000,
Ifne, Ifne = 0b0001,
Iflt, UK1 = 2,
Ifge, UK2 = 3,
Ifgt, UK3 = 4,
Ifle, UK4 = 5,
Ifult, UK5 = 6,
Ifuge, UK6 = 7,
Ifugt, Iflt = 0b1000,
Ifule, Ifge = 0b1001,
Ifgt = 0b1010,
Ifle = 0b1011,
Ifult = 0b1100,
Ifuge = 0b1101,
Ifugt = 0b1110,
Ifule = 0b1111,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -73,20 +84,10 @@ pub enum MMIOInterupt {
} }
impl From<u8> for Cond { impl From<u8> for Cond {
#[inline(always)]
fn from(value: u8) -> Self { fn from(value: u8) -> Self {
match value { //unsafe if called with value >= 15 buuut only ever called on actually an u4 so it's ok
0b0000 => Cond::Ifeq, unsafe { transmute(value) }
0b0001 => Cond::Ifne,
0b1000 => Cond::Iflt,
0b1001 => Cond::Ifge,
0b1010 => Cond::Ifgt,
0b1011 => Cond::Ifle,
0b1100 => Cond::Ifult,
0b1101 => Cond::Ifuge,
0b1110 => Cond::Ifugt,
0b1111 => Cond::Ifule,
_ => iot(),
}
} }
} }
@@ -108,8 +109,9 @@ impl From<u32> for InteruptKind {
} }
impl Cond { impl Cond {
fn eval(self, a: u32, b: u32) -> bool { #[inline(always)]
match self { fn eval(self, a: u32, b: u32) -> Option<bool> {
Some(match self {
Cond::Ifeq => a == b, Cond::Ifeq => a == b,
Cond::Ifne => a != b, Cond::Ifne => a != b,
Cond::Iflt => (a as i32) < (b as i32), Cond::Iflt => (a as i32) < (b as i32),
@@ -120,10 +122,12 @@ impl Cond {
Cond::Ifuge => a >= b, Cond::Ifuge => a >= b,
Cond::Ifugt => a > b, Cond::Ifugt => a > b,
Cond::Ifule => a <= b, Cond::Ifule => a <= b,
} _ => return None,
})
} }
} }
#[allow(unused)] //depen on features
enum Instruction { enum Instruction {
Copy(Reg, Op2), Copy(Reg, Op2),
Add(Reg, Reg, Op2), Add(Reg, Reg, Op2),
@@ -162,7 +166,6 @@ impl TryFrom<u32> for Instruction {
Ok(match value >> 30 { Ok(match value >> 30 {
0b00 => { 0b00 => {
let t = value & (1 << 29); // 3rd bit set let t = value & (1 << 29); // 3rd bit set
let value = value - t;
let t = t != 0; let t = t != 0;
if t { if t {
Self::Call(value) Self::Call(value)
@@ -274,6 +277,7 @@ impl Display for Cond {
Cond::Ifuge => write!(f, "ifuge"), Cond::Ifuge => write!(f, "ifuge"),
Cond::Ifugt => write!(f, "ifugt"), Cond::Ifugt => write!(f, "ifugt"),
Cond::Ifule => write!(f, "ifule"), Cond::Ifule => write!(f, "ifule"),
_ => write!(f, "unknown"),
} }
} }
} }
@@ -312,7 +316,7 @@ pub(crate) fn instr_to_text(i: u32, a: u32, book: &HashMap<u32, String>) -> Stri
format!("skip {} {cond} {reg} {op2}", addr(d as u32)) format!("skip {} {cond} {reg} {op2}", addr(d as u32))
} }
Instruction::Jump(a) => format!("jump {}", addr(a)), Instruction::Jump(a) => format!("jump {}", addr(a)),
Instruction::Call(a) => format!("call {}", addr(a)), Instruction::Call(a) => format!("call {}", addr(a % 0x1000_0000)),
Instruction::Ret() => format!("ret"), Instruction::Ret() => format!("ret"),
Instruction::Reti() => format!("reti"), Instruction::Reti() => format!("reti"),
Instruction::Swi() => format!("swi"), Instruction::Swi() => format!("swi"),
@@ -337,7 +341,7 @@ pub struct Computer {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
pub(crate) error: bool, pub(crate) error: bool,
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
pub(crate) book: HashMap<u32, String>, pub(crate) book: (HashMap<u32, String>, HashMap<String, u32>),
} }
impl Index<Reg> for Computer { impl Index<Reg> for Computer {
@@ -354,10 +358,6 @@ impl IndexMut<Reg> for Computer {
} }
} }
fn iot() -> ! {
exit(1);
}
impl Computer { impl Computer {
pub fn new(filename: String) -> Self { pub fn new(filename: String) -> Self {
let mut new = Self { let mut new = Self {
@@ -370,7 +370,7 @@ impl Computer {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
error: false, error: false,
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
book: HashMap::new(), book: (HashMap::new(), HashMap::new()),
}; };
let mut buf = String::new(); let mut buf = String::new();
std::fs::File::open(filename) std::fs::File::open(filename)
@@ -388,14 +388,16 @@ impl Computer {
while let Some((_, line)) = lines.next() { while let Some((_, line)) = lines.next() {
if let Some([addr, s]) = line.split_ascii_whitespace().collect::<Vec<_>>().as_array() { if let Some([addr, s]) = line.split_ascii_whitespace().collect::<Vec<_>>().as_array() {
if let Ok(i) = u32::from_str_radix(addr, 16) { if let Ok(i) = u32::from_str_radix(addr, 16) {
new.book.insert(i, s.to_string()); new.book.0.insert(i, s.to_string());
new.book.1.insert(s.to_string(), i);
} }
} }
} }
new new
} }
#[inline(always)] #[inline(always)]
pub fn step(&mut self) { pub fn step(&mut self, s: usize) {
match self.interupts { match self.interupts {
InteruptState::Disabled => {} InteruptState::Disabled => {}
InteruptState::Enabled => { InteruptState::Enabled => {
@@ -414,7 +416,7 @@ impl Computer {
} }
InteruptState::Serving(..) => {} InteruptState::Serving(..) => {}
} }
for _ in 0..s {
//potentially just changed by interupt. //potentially just changed by interupt.
let next_opcode = self.ram[self.pc]; let next_opcode = self.ram[self.pc];
@@ -448,15 +450,15 @@ impl Computer {
self.pc += 1; self.pc += 1;
} }
Instruction::Lsl(reg, reg1, op2) => { Instruction::Lsl(reg, reg1, op2) => {
self[reg] = self[reg1] << self.resolve(op2); self[reg] = (self[reg1] as u64).wrapping_shl(self.resolve(op2)) as u32;
self.pc += 1; self.pc += 1;
} }
Instruction::Lsr(reg, reg1, op2) => { Instruction::Lsr(reg, reg1, op2) => {
self[reg] = self[reg1] >> self.resolve(op2); self[reg] = (self[reg1] as u64).wrapping_shr(self.resolve(op2)) as u32;
self.pc += 1; self.pc += 1;
} }
Instruction::Asr(reg, reg1, op2) => { Instruction::Asr(reg, reg1, op2) => {
self[reg] = (self[reg1] as i32 >> self.resolve(op2)) as u32; self[reg] = (self[reg1] as i64).wrapping_shr(self.resolve(op2)) as u32;
self.pc += 1; self.pc += 1;
} }
Instruction::Umull(reg, reg1, op2) => { Instruction::Umull(reg, reg1, op2) => {
@@ -507,13 +509,18 @@ impl Computer {
self.ram[addr / 4] = self[reg1]; self.ram[addr / 4] = self[reg1];
} else if addr <= 0x00ff_ffff + 480 * 640 * 4 { } else if addr <= 0x00ff_ffff + 480 * 640 * 4 {
let buf_addr = (addr - 0x0100_0000) / 4; let buf_addr = (addr - 0x0100_0000) / 4;
let dat = self[reg1] & 0x00FF_FFFF; let dat = if cfg!(feature = "rgba") {
self[reg1]
} else {
self[reg1] & 0x00FF_FFFF
};
(&SHARED.screen_buf[buf_addr]) (&SHARED.screen_buf[buf_addr])
.store(dat, std::sync::atomic::Ordering::Relaxed); .store(dat, std::sync::atomic::Ordering::Relaxed);
} else if addr == 0x0120_1000 { } else if addr == 0x0120_1000 {
(&SHARED.external_enabled_interupts) (&SHARED.external_enabled_interupts)
.store(self[reg1], std::sync::atomic::Ordering::Relaxed); .store(self[reg1], std::sync::atomic::Ordering::Relaxed);
} else { } else {
cold_path();
self.serve_interupt(InteruptKind::IllegalOpcode, [next_opcode]); self.serve_interupt(InteruptKind::IllegalOpcode, [next_opcode]);
} }
} }
@@ -536,23 +543,34 @@ impl Computer {
} else { } else {
match addr as isize - 0x0120_0000 { match addr as isize - 0x0120_0000 {
#[cfg(feature = "rich_keyboard")] #[cfg(feature = "rich_keyboard")]
-12 => { -12 => SHARED.keyboard[0]
SHARED.keyboard[0].load(std::sync::atomic::Ordering::Relaxed) .load(std::sync::atomic::Ordering::Relaxed),
}
#[cfg(feature = "rich_keyboard")] #[cfg(feature = "rich_keyboard")]
-8 => SHARED.keyboard[1].load(std::sync::atomic::Ordering::Relaxed), -8 => SHARED.keyboard[1]
.load(std::sync::atomic::Ordering::Relaxed),
#[cfg(feature = "rich_keyboard")] #[cfg(feature = "rich_keyboard")]
-4 => SHARED.keyboard[2].load(std::sync::atomic::Ordering::Relaxed), -4 => SHARED.keyboard[2]
0 => SHARED.keyboard[3].load(std::sync::atomic::Ordering::Relaxed), .load(std::sync::atomic::Ordering::Relaxed),
0 => SHARED.keyboard[3]
.load(std::sync::atomic::Ordering::Relaxed),
4 => time::Instant::now() 4 => time::Instant::now()
.duration_since(self.creation) .duration_since(self.creation)
.as_millis() as u32, .as_millis()
as u32,
8 => SHARED.mouse[0].load(std::sync::atomic::Ordering::Relaxed), 8 => SHARED.mouse[0].load(std::sync::atomic::Ordering::Relaxed),
12 => SHARED.mouse[1].load(std::sync::atomic::Ordering::Relaxed), 12 => {
16 => SHARED.mouse[2].load(std::sync::atomic::Ordering::Relaxed), SHARED.mouse[1].load(std::sync::atomic::Ordering::Relaxed)
}
16 => {
SHARED.mouse[2].load(std::sync::atomic::Ordering::Relaxed)
}
//guaranted by the inequality and is multiple of 4 //guaranted by the inequality and is multiple of 4
_ => { _ => {
self.serve_interupt(InteruptKind::IllegalOpcode, [next_opcode]); cold_path();
self.serve_interupt(
InteruptKind::IllegalOpcode,
[next_opcode],
);
return; return;
} }
} }
@@ -570,14 +588,17 @@ impl Computer {
} }
Instruction::Skip(d, cond, reg, op2) => { Instruction::Skip(d, cond, reg, op2) => {
self.pc += 1; self.pc += 1;
if cond.eval(self[reg], self.resolve(op2)) { match cond.eval(self[reg], self.resolve(op2)) {
self.pc += d as usize Some(false) => { /*Nothing*/ }
Some(true) => self.pc += d as usize,
None => {
cold_path();
self.serve_interupt(InteruptKind::IllegalOpcode, [next_opcode])
} }
} }
Instruction::Jump(mut addr) => { }
if addr & (1 << 28) != 0 { Instruction::Jump(addr) => {
addr += 7 << 29; if unlikely(addr == 0) {
} else if addr == 0 {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
{ {
match self.interupts { match self.interupts {
@@ -599,17 +620,17 @@ impl Computer {
} }
println!("awaiting interupt..."); println!("awaiting interupt...");
} }
atomic_wait::wait(&SHARED.external_interupts, 0); SHARED.external_interupts.wait(0);
return;
} }
self.pc = (addr + self.pc as u32) as usize; self.pc = ((addr + self.pc as u32) & 0x1FFF_FFFF) as usize;
} }
Instruction::Call(mut addr) => { Instruction::Call(addr) => {
//WARNING! addr still has the type bit set at this point!
self.sp -= 1; self.sp -= 1;
self.ram[self.sp] = ((self.pc << 2) + 4) as u32; self.ram[self.sp] = ((self.pc << 2) + 4) as u32;
if addr & (1 << 28) != 0 { if unlikely(addr == 0 + (1 << 29) /*t bit*/) {
addr += 7 << 29;
} else if unlikely(addr == 0) {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
{ {
println!("program terminated"); println!("program terminated");
@@ -619,7 +640,8 @@ impl Computer {
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
exit(0); exit(0);
} }
self.pc = (addr + self.pc as u32) as usize; //The mask take care of both wrapping and shedding the t bit
self.pc = ((addr + self.pc as u32) & 0x1FFF_FFFF) as usize;
} }
Instruction::Ret() => { Instruction::Ret() => {
self.pc = (self.ram[self.sp] >> 2) as usize; self.pc = (self.ram[self.sp] >> 2) as usize;
@@ -642,12 +664,13 @@ impl Computer {
InteruptKind::MMIO => { InteruptKind::MMIO => {
(&SHARED.external_interupts) (&SHARED.external_interupts)
.store(0, std::sync::atomic::Ordering::Release); .store(0, std::sync::atomic::Ordering::Release);
atomic_wait::wake_all(&SHARED.external_interupts); SHARED.external_interupts.signal();
//no need to check prev because MMIO is the lowest priority //no need to check prev because MMIO is the lowest priority
self.interupts = InteruptState::Enabled self.interupts = InteruptState::Enabled
} }
InteruptKind::Swi => {} InteruptKind::Swi => {}
InteruptKind::DivByZero | InteruptKind::UnsupportedOpcode => { InteruptKind::DivByZero
| InteruptKind::UnsupportedOpcode => {
ret_index = Some(self.regs[0]); ret_index = Some(self.regs[0]);
ret_value = self.regs[1]; ret_value = self.regs[1];
} }
@@ -686,8 +709,9 @@ impl Computer {
(&SHARED.external_enabled_interupts) (&SHARED.external_enabled_interupts)
.store(0, std::sync::atomic::Ordering::Relaxed); .store(0, std::sync::atomic::Ordering::Relaxed);
(&SHARED.external_interupts).store(0, std::sync::atomic::Ordering::Relaxed); (&SHARED.external_interupts)
atomic_wait::wake_all(&SHARED.external_interupts); .store(0, std::sync::atomic::Ordering::Relaxed);
SHARED.external_interupts.signal();
} }
Instruction::Swi() => { Instruction::Swi() => {
self.pc += 1; self.pc += 1;
@@ -711,14 +735,26 @@ impl Computer {
Err((kind, rx, ry, op2, opcode)) => { Err((kind, rx, ry, op2, opcode)) => {
self.pc += 1; self.pc += 1;
match kind { match kind {
InteruptKind::UnsupportedOpcode => self InteruptKind::UnsupportedOpcode => self.serve_interupt(
.serve_interupt(kind, [rx.0.into(), self[ry], self.resolve(op2), opcode]), kind,
InteruptKind::IllegalOpcode => self.serve_interupt(kind, [next_opcode]), [rx.0.into(), self[ry], self.resolve(op2), opcode],
),
InteruptKind::IllegalOpcode => {
cold_path();
self.serve_interupt(kind, [next_opcode])
}
_ => unsafe { unreachable_unchecked() }, _ => unsafe { unreachable_unchecked() },
} }
} }
} }
} }
}
#[cfg(feature = "debug")]
pub fn debug_step(&mut self, s: usize) {
self.step(s);
}
#[inline(always)]
fn resolve(&self, op2: Op2) -> u32 { fn resolve(&self, op2: Op2) -> u32 {
match op2 { match op2 {
Op2::Direct(v) => v, Op2::Direct(v) => v,

View File

@@ -1,14 +1,8 @@
#![feature( #![feature(likely_unlikely, widening_mul, int_lowest_highest_one)]
likely_unlikely,
widening_mul,
sync_unsafe_cell,
int_lowest_highest_one
)]
#![deny(clippy::all)] #![deny(clippy::all)]
use std::env::args; use std::env::args;
use std::hint::unlikely; use std::hint::unlikely;
use std::io::stdin;
use std::process::exit; use std::process::exit;
use std::sync::{ use std::sync::{
Arc, Arc,
@@ -17,18 +11,18 @@ use std::sync::{
use std::thread::scope; use std::thread::scope;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use pixels::{Error, Pixels, SurfaceTexture}; use pixels::wgpu::{BlendState, Color};
use pixels::{Error, Pixels, PixelsBuilder, SurfaceTexture};
use winit::application::ApplicationHandler; use winit::application::ApplicationHandler;
use winit::dpi::LogicalSize; use winit::dpi::LogicalSize;
use winit::event::WindowEvent; use winit::event::WindowEvent;
use winit::event_loop::EventLoop; use winit::event_loop::EventLoop;
use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
use winit::platform::scancode::PhysicalKeyExtScancode; use winit::platform::scancode::PhysicalKeyExtScancode;
use winit::window::Window; use winit::window::Window;
// use winit_input_helper::WinitInputHelper;
use crate::cpu::{Computer, MMIOInterupt}; use crate::cpu::{Computer, MMIOInterupt};
mod wait;
use wait::WaitOnAtomic;
mod cpu; mod cpu;
use cpu::SHARED; use cpu::SHARED;
@@ -37,7 +31,7 @@ fn wait_int() {
while unlikely(v != 0) { while unlikely(v != 0) {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
println!("wating for interupt clear {v}"); println!("wating for interupt clear {v}");
atomic_wait::wait(&SHARED.external_interupts, v); SHARED.external_interupts.wait(v);
v = (&SHARED.external_interupts).load(Acquire); v = (&SHARED.external_interupts).load(Acquire);
} }
} }
@@ -68,7 +62,12 @@ impl<'a> ApplicationHandler for App<'a> {
self.w = Some(window.clone()); self.w = Some(window.clone());
let size = window.inner_size(); let size = window.inner_size();
let surface_texture = SurfaceTexture::new(size.width, size.height, window); let surface_texture = SurfaceTexture::new(size.width, size.height, window);
self.pixels = Some(Pixels::new(WIDTH, HEIGHT, surface_texture).unwrap()); let pix = PixelsBuilder::new(WIDTH, HEIGHT, surface_texture)
.clear_color(Color::BLACK)
.blend_state(BlendState::REPLACE)
.build();
self.pixels = Some(pix.unwrap());
} }
fn window_event( fn window_event(
@@ -93,20 +92,22 @@ impl<'a> ApplicationHandler for App<'a> {
print!("Keyboard event: "); print!("Keyboard event: ");
#[cfg(feature = "rich_keyboard")] #[cfg(feature = "rich_keyboard")]
{ {
let kb0 = key_event use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
.text_with_all_modifiers() let kb0 = key_event.text_with_all_modifiers().map_or(u32::MAX, |s| {
.unwrap_or("") s.as_bytes()
.as_bytes()
.into_iter() .into_iter()
.fold(0, |a, e| a << 8 | (*e as u32)); .fold(0, |a, e| a << 8 | (*e as u32))
});
SHARED.keyboard[0].store(kb0, Relaxed); SHARED.keyboard[0].store(kb0, Relaxed);
let kb1 = key_event let kb1 = key_event
.key_without_modifiers() .key_without_modifiers()
.to_text() .to_text()
.unwrap_or("") .map_or(u32::MAX, |s| {
.as_bytes() s.as_bytes()
.into_iter() .into_iter()
.fold(0, |a, e| a << 8 | (*e as u32)); .fold(0, |a, e| a << 8 | (*e as u32))
});
SHARED.keyboard[1].store(kb1, Relaxed); SHARED.keyboard[1].store(kb1, Relaxed);
let kb2 = let kb2 =
key_event.state.is_pressed() as u32 | ((key_event.repeat as u32) << 1); key_event.state.is_pressed() as u32 | ((key_event.repeat as u32) << 1);
@@ -122,7 +123,7 @@ impl<'a> ApplicationHandler for App<'a> {
(&SHARED.external_interupts).store(MMIOInterupt::Keyboard.into(), Release); (&SHARED.external_interupts).store(MMIOInterupt::Keyboard.into(), Release);
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
println!("wake due to keyboard event"); println!("wake due to keyboard event");
atomic_wait::wake_all(&SHARED.external_interupts); SHARED.external_interupts.signal();
} }
} }
WindowEvent::CursorMoved { position, .. } => { WindowEvent::CursorMoved { position, .. } => {
@@ -151,7 +152,7 @@ impl<'a> ApplicationHandler for App<'a> {
(&SHARED.external_interupts).store(MMIOInterupt::MouseMove.into(), Release); (&SHARED.external_interupts).store(MMIOInterupt::MouseMove.into(), Release);
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
println!("wake due mouse move"); println!("wake due mouse move");
atomic_wait::wake_all(&SHARED.external_interupts); SHARED.external_interupts.signal();
} }
} }
// WindowEvent::MouseWheel { // WindowEvent::MouseWheel {
@@ -185,7 +186,7 @@ impl<'a> ApplicationHandler for App<'a> {
(&SHARED.external_interupts).store(MMIOInterupt::MouseClick.into(), Release); (&SHARED.external_interupts).store(MMIOInterupt::MouseClick.into(), Release);
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
println!("wake mouse click"); println!("wake mouse click");
atomic_wait::wake_all(&SHARED.external_interupts); SHARED.external_interupts.signal();
} }
} }
WindowEvent::ScaleFactorChanged { .. } => { WindowEvent::ScaleFactorChanged { .. } => {
@@ -198,7 +199,7 @@ impl<'a> ApplicationHandler for App<'a> {
!= 0; != 0;
if enabled { if enabled {
(&SHARED.external_interupts).store(MMIOInterupt::VSync.into(), Relaxed); (&SHARED.external_interupts).store(MMIOInterupt::VSync.into(), Relaxed);
atomic_wait::wake_all(&SHARED.external_interupts); SHARED.external_interupts.signal();
wait_int(); wait_int();
} }
let pix = self.pixels.as_mut().unwrap(); let pix = self.pixels.as_mut().unwrap();
@@ -207,14 +208,9 @@ impl<'a> ApplicationHandler for App<'a> {
for (addr, ubgr) in cpu::SHARED.screen_buf.iter().enumerate() { for (addr, ubgr) in cpu::SHARED.screen_buf.iter().enumerate() {
let raw = ubgr.load(std::sync::atomic::Ordering::Relaxed); let raw = ubgr.load(std::sync::atomic::Ordering::Relaxed);
#[cfg(not(feature = "rgba"))] #[cfg(not(feature = "rgba"))]
let rgba = [raw as u8, (raw >> 8) as u8, (raw >> 16) as u8, 0xff]; let rgba: [u8; 4] = raw.to_le_bytes();
#[cfg(feature = "rgba")] #[cfg(feature = "rgba")]
let rgba = [ let rgba = raw.to_be_bytes();
(raw >> 24) as u8,
(raw >> 16) as u8,
(raw >> 8) as u8,
raw as u8,
];
for i in 0..4 { for i in 0..4 {
screen[addr * 4 + i] = rgba[i]; screen[addr * 4 + i] = rgba[i];
} }
@@ -265,6 +261,7 @@ impl<'a> ApplicationHandler for App<'a> {
let now = Instant::now(); let now = Instant::now();
if next < now { if next < now {
next = now + Duration::from_secs_f64(1. / 30.); next = now + Duration::from_secs_f64(1. / 30.);
println!("Warning: rendering is lagging!")
} }
event_loop.set_control_flow(winit::event_loop::ControlFlow::WaitUntil(next)); event_loop.set_control_flow(winit::event_loop::ControlFlow::WaitUntil(next));
if let Some(w) = self.w.as_ref() { if let Some(w) = self.w.as_ref() {
@@ -302,147 +299,13 @@ fn main() -> Result<(), Error> {
let mut simulation = Computer::new(program); let mut simulation = Computer::new(program);
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
loop { loop {
simulation.step(); simulation.step(64);
} }
//ugly debug code, I should improve that using a real TUI crate
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
{ {
let mut input = stdin().lines(); debug_loop(&mut simulation);
loop {
{
println!(
"interrupts are {:?}, with mmio interupts flags {}",
simulation.interupts,
SHARED.external_enabled_interupts.load(Relaxed)
);
for i in 0..8 {
println!(
"r{i} 0x{:08x} r{} 0x{:08x}",
simulation.regs[i],
i + 8,
simulation.regs[i + 8]
);
}
println!(
"SP: {:08x} PC: {:08x}",
simulation.sp * 4,
simulation.pc * 4
);
println!("RAM near SP");
let min_pc = (simulation.pc).min(0x0100_0000 / 4 - 8);
let min_sp = (simulation.sp).min(0x0100_0000 / 4 - 8);
for i in 0..8 {
println!(
"{:8x}: 0x{:08x}",
(min_sp + i) * 4,
simulation.ram[min_sp + i],
);
}
println!("Ram near PC");
for i in 0..8 {
let idx = min_pc + i;
let istr = simulation.ram[idx];
if let Some(s) = simulation.book.get(&(idx as u32 * 4)) {
println!("{s}:")
};
println!(
"{:8x}: 0x{:08x} {}",
idx * 4,
istr,
cpu::instr_to_text(istr, idx as u32 * 4, &simulation.book)
)
}
}
while {
let next = input.next().unwrap().unwrap();
let next: Vec<_> = next.split_ascii_whitespace().collect();
if next.len() > 0 {
match next[0] {
"s" | "step" => {
let n: usize = {
if next.len() >= 2 {
parse_int::parse(next[1]).unwrap_or(1)
} else {
1
}
};
for _ in 0..n {
if simulation.error {
println!("cannot step, cpu killed");
break;
}
simulation.step();
}
false
}
"r" | "run" => {
while !simulation.error {
simulation.step();
}
false
}
"p" | "print" => {
if next.len() >= 2 {
match parse_int::parse::<u32>(next[1]) {
Ok(i) => {
let v = simulation.ram[i as usize / 4];
println!(
"0x{:8x} -- {}",
v,
cpu::instr_to_text(v, i, &simulation.book)
);
true
}
Err(e) => {
println!("{e}");
true
}
}
} else {
println!("{HELP_MSG}");
true
}
}
"c" | "context" => false,
"u" | "up" => {
while !simulation.error
&& simulation.ram[simulation.pc] != 0x8800_0000
{
simulation.step();
}
false
}
"t" | "to" => {
if next.len() >= 2 {
match parse_int::parse::<u32>(next[1]) {
Ok(v) => {
while !simulation.error
&& simulation.pc != (v as usize / 4)
{
simulation.step();
}
false
}
Err(e) => {
println!("{e}");
true
}
}
} else {
println!("{HELP_MSG}");
true
}
}
_ => {
println!("{HELP_MSG}");
true
}
}
} else {
println!("{HELP_MSG}");
true
}
} {}
}
} }
}); });
@@ -459,11 +322,210 @@ fn main() -> Result<(), Error> {
} }
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
const HELP_MSG: &str = " fn debug_loop(com: &mut Computer) {
step n - step trough n instructions (alias s) struct Wrap(DefaultCompleter, DefaultCompleter);
run - run program until exit / error (alias r)
context - print context (alias c) use clap::Parser;
print n - print ram content at address n and next 8 (alias p) use clap_repl::ClapEditor;
up - run until the nex ret is reached (alias u) use clap_repl::reedline::{
to n - tun until PC = n (alias t) Completer, DefaultCompleter, DefaultPrompt, DefaultPromptSegment, FileBackedHistory,
"; };
use crate::cpu::instr_to_text;
#[derive(Debug, Parser)]
#[command(name = "")] // This name will show up in clap's error messages, so it is important to set it to "".
enum Commands {
/// Step by single instrcution
#[command(alias = "s")]
Step {
///number of instruction to step (default one)
num: Option<usize>,
},
/// Run until program halt, or specified instruction is reached
#[command(alias = "r")]
Run {
/// Can be either a label or a address (support hex format)
desigantor: Option<String>,
},
/// run until the current function return.
#[command(alias = "u")]
Up,
/// Print memory at address. Support hexa format
#[command(alias = "p")]
Print { address: String },
/// Print the address associated with a label
#[command(alias = "l")]
Label { label: String },
/// Print context
#[command(alias = "c")]
Context,
}
let prompt = DefaultPrompt {
left_prompt: DefaultPromptSegment::Basic(">>".to_owned()),
right_prompt: DefaultPromptSegment::Empty,
};
let commands_comp = DefaultCompleter::new_with_wordlen(
["step", "run", "up", "print", "label", "help", "context"]
.map(|s| s.to_string())
.to_vec(),
0,
);
let mut labels_comp =
DefaultCompleter::with_inclusions("_0123456789".chars().collect::<Vec<_>>().as_slice())
.set_min_word_len(0);
labels_comp.insert(com.book.0.values().cloned().collect());
let editor = ClapEditor::<Commands>::builder()
.with_prompt(Box::new(prompt))
.with_editor_hook(|reed| {
reed.with_history(Box::new(
FileBackedHistory::with_file(1000, "debug_cmd.hist".into()).unwrap(),
))
.with_completer(Box::new(Wrap(commands_comp, labels_comp)))
.with_quick_completions(true)
.with_partial_completions(true)
})
.build();
debug_context(com);
editor.repl(|command| match command {
Commands::Step { num } => {
let steps = num.unwrap_or(1);
com.debug_step(steps);
debug_context(com);
}
Commands::Run { desigantor } => match desigantor {
Some(s) => match parse_int::parse::<usize>(s.as_str()) {
Ok(addr) => {
while com.pc != (addr / 4) && !com.error {
com.debug_step(1);
}
debug_context(com);
}
Err(_) => match com.book.1.get(s.as_str()).cloned() {
Some(addr) => {
while com.pc != (addr as usize / 4) && !com.error {
com.debug_step(1);
}
debug_context(com);
}
None => {
println!("Error, {s} cannot be interpreted as addr nor label")
}
},
},
None => {
while !com.error {
com.debug_step(64);
}
debug_context(com);
}
},
Commands::Up => {
let curr_sp = com.sp;
while (com.sp < curr_sp
|| (com.ram[com.pc] != (0b10001000 << 24) && com.ram[com.pc] != (0b10101000 << 24)))
&& !com.error
{
com.debug_step(1);
}
debug_context(com);
}
Commands::Print { address } => match parse_int::parse::<usize>(address.as_str()) {
Ok(addr) => match com.ram.get(addr / 4) {
Some(i) => {
println!(
"RAM at {addr:8x}: {:8x} {}",
i,
instr_to_text(*i, u32::MAX, &com.book.0)
)
}
None => println!("Cannot index RAM at address {addr:8x}"),
},
Err(_) => match com.book.1.get(address.as_str()).cloned() {
Some(addr) => println!(
"RAM at {addr:8x}: {:8x} {}",
com.ram[addr as usize / 4],
instr_to_text(com.ram[addr as usize / 4], addr, &com.book.0)
),
None => {
println!("Error, {address} cannot be interpreted as addr nor label")
}
},
},
Commands::Label { label } => match com.book.1.get(label.as_str()) {
Some(addr) => println!("label is at addr {addr}"),
None => println!("error: label not found"),
},
Commands::Context => debug_context(com),
});
exit(0);
impl Completer for Wrap {
fn complete(&mut self, line: &str, pos: usize) -> Vec<clap_repl::reedline::Suggestion> {
let trimmed = line.trim_start();
let line_parts = trimmed.splitn(2, ' ').collect::<Vec<_>>();
if line_parts.len() <= 1 {
self.0.complete(line, pos)
} else {
match line_parts[0] {
"r" | "run" | "p" | "print" | "l" | "label" => {
let trimmed_2 = line_parts[1].trim_start();
let offset = line.len() - trimmed_2.len();
let mut sub = self.1.complete(trimmed_2, pos - offset);
for sug in sub.iter_mut() {
use clap_repl::reedline::Span;
sug.span = Span {
start: sug.span.start + offset,
end: sug.span.end + offset,
}
}
sub
}
_ => Vec::new(),
}
}
}
}
}
#[cfg(feature = "debug")]
fn debug_context(com: &Computer) {
use crate::cpu::instr_to_text;
println!("Interupt state: {:?}", com.interupts);
for i in 0..8 {
println!(
"r{i} = {:8x} r{:<2} = {:8x}",
com.regs[i],
i + 8,
com.regs[i + 8]
);
}
println!("SP={:08x} PC={:08x}", com.sp * 4, com.pc * 4);
println!("RAM at SP | Ram at PC:");
let mut pc_lines = Vec::new();
for i in 0..16 {
match com.book.0.get(&((com.pc + i) as u32 * 4)) {
Some(label) => pc_lines.push(format!(" {label}:")),
None => {}
};
pc_lines.push(format!(
"{:08x} {}",
com.ram[com.pc + i],
instr_to_text(com.ram[com.pc + i], (com.pc + i) as u32 * 4, &com.book.0)
));
}
for (i, pc_l) in pc_lines.iter().enumerate() {
if com.sp + i < com.ram.len() {
println!("{:08x} | {pc_l}", com.ram[com.sp + i])
} else {
println!(" -- | {pc_l}")
}
}
}

35
simu/src/wait.rs Normal file
View File

@@ -0,0 +1,35 @@
use std::sync::atomic::AtomicU32;
#[cfg(feature = "futex")]
use wait_on_address::AtomicWait;
pub trait WaitOnAtomic {
fn wait(&self, v: u32);
fn signal(&self);
}
#[cfg(feature = "futex")]
impl WaitOnAtomic for AtomicU32 {
fn wait(&self, v: u32) {
<AtomicU32 as AtomicWait>::wait(self, v);
}
fn signal(&self) {
self.notify_one();
}
}
#[cfg(not(feature = "futex"))]
impl WaitOnAtomic for AtomicU32 {
fn wait(&self, v: u32) {
while self.load(std::sync::atomic::Ordering::Acquire) == v {
use std::{thread::sleep, time::Duration};
sleep(Duration::from_micros(500));
}
}
fn signal(&self) {
//
}
}