cleaned up instructions, using termion now but is kinda broken, might switch back to crossterm
This commit is contained in:
parent
ac4619406d
commit
fb4fae430b
|
@ -69,31 +69,6 @@ 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 = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossterm"
|
|
||||||
version = "0.27.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.5.0",
|
|
||||||
"crossterm_winapi",
|
|
||||||
"libc",
|
|
||||||
"mio",
|
|
||||||
"parking_lot",
|
|
||||||
"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 = "dlib"
|
name = "dlib"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -122,7 +97,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -226,9 +201,9 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bdf",
|
"bdf",
|
||||||
"crossterm",
|
|
||||||
"minifb",
|
"minifb",
|
||||||
"serde",
|
"serde",
|
||||||
|
"termion",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -288,7 +263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.52.5",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -299,7 +274,7 @@ checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall 0.4.1",
|
"redox_syscall",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -308,16 +283,6 @@ version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lock_api"
|
|
||||||
version = "0.4.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.21"
|
version = "0.4.21"
|
||||||
|
@ -365,18 +330,6 @@ dependencies = [
|
||||||
"x11-dl",
|
"x11-dl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio"
|
|
||||||
version = "0.8.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"wasi",
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.24.3"
|
version = "0.24.3"
|
||||||
|
@ -389,6 +342,12 @@ dependencies = [
|
||||||
"memoffset",
|
"memoffset",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "numtoa"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.19.0"
|
version = "1.19.0"
|
||||||
|
@ -407,29 +366,6 @@ dependencies = [
|
||||||
"sdl2-sys",
|
"sdl2-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot"
|
|
||||||
version = "0.12.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
|
||||||
dependencies = [
|
|
||||||
"lock_api",
|
|
||||||
"parking_lot_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot_core"
|
|
||||||
version = "0.9.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall 0.5.2",
|
|
||||||
"smallvec",
|
|
||||||
"windows-targets 0.52.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -482,13 +418,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_termios"
|
||||||
version = "0.5.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
|
checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.5.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
|
@ -500,7 +433,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -509,12 +442,6 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sdl2"
|
name = "sdl2"
|
||||||
version = "0.35.2"
|
version = "0.35.2"
|
||||||
|
@ -567,36 +494,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"signal-hook-registry",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-mio"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"mio",
|
|
||||||
"signal-hook",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-registry"
|
|
||||||
version = "1.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -632,7 +529,19 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termion"
|
||||||
|
version = "4.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ccce68e518d1173e80876edd54760b60b792750d0cab6444a79101c6ea03848"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"libredox",
|
||||||
|
"numtoa",
|
||||||
|
"redox_termios",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -701,12 +610,6 @@ 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 = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.92"
|
version = "0.2.92"
|
||||||
|
@ -878,37 +781,13 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.48.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
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 = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.52.5",
|
"windows-targets",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.48.5",
|
|
||||||
"windows_aarch64_msvc 0.48.5",
|
|
||||||
"windows_i686_gnu 0.48.5",
|
|
||||||
"windows_i686_msvc 0.48.5",
|
|
||||||
"windows_x86_64_gnu 0.48.5",
|
|
||||||
"windows_x86_64_gnullvm 0.48.5",
|
|
||||||
"windows_x86_64_msvc 0.48.5",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -917,46 +796,28 @@ version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm 0.52.5",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc 0.52.5",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu 0.52.5",
|
"windows_i686_gnu",
|
||||||
"windows_i686_gnullvm",
|
"windows_i686_gnullvm",
|
||||||
"windows_i686_msvc 0.52.5",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu 0.52.5",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_gnullvm 0.52.5",
|
"windows_x86_64_gnullvm",
|
||||||
"windows_x86_64_msvc 0.52.5",
|
"windows_x86_64_msvc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
|
@ -969,48 +830,24 @@ version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.52.5"
|
version = "0.52.5"
|
||||||
|
|
|
@ -8,9 +8,9 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.81"
|
anyhow = "1.0.81"
|
||||||
bdf = "0.6.0"
|
bdf = "0.6.0"
|
||||||
crossterm = "0.27.0"
|
|
||||||
minifb = "0.27.0"
|
minifb = "0.27.0"
|
||||||
# minifb = "0.25.0"
|
# minifb = "0.25.0"
|
||||||
# ratatui = "0.26.3"
|
# ratatui = "0.26.3"
|
||||||
serde = { version = "1.0.197", features = ["serde_derive", "derive"] }
|
serde = { version = "1.0.197", features = ["serde_derive", "derive"] }
|
||||||
|
termion = "4.0.2"
|
||||||
toml = "0.8.12"
|
toml = "0.8.12"
|
||||||
|
|
2
run.sh
2
run.sh
|
@ -8,5 +8,5 @@ fi
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
vasm6502_oldstyle ./src/roms/$1.asm -dotdir -wdc02 -ldots -Fbin -o ./src/roms/$1.rom;
|
vasm6502_oldstyle ./src/roms/$1.asm -dotdir -wdc02 -ldots -Fbin -o ./src/roms/$1.rom;
|
||||||
cargo run rom "./src/roms/$1.rom";
|
cargo run -- rom "./src/roms/$1.rom";
|
||||||
# hexdump -C ./cpu_dump.bin;
|
# hexdump -C ./cpu_dump.bin;
|
||||||
|
|
167
src/cpu.rs
167
src/cpu.rs
|
@ -1,9 +1,8 @@
|
||||||
use crate::instructions::{get_instruction, Instruction};
|
use crate::instructions::{get_instruction, Instruction};
|
||||||
use crate::memory::{MemHandle, MemoryReader, MemoryWriter};
|
use crate::memory::{MemHandle, MemoryReader, MemoryWriter};
|
||||||
use crate::types::{Byte, Word};
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use std::thread::{sleep, LocalKey};
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -58,30 +57,18 @@ impl CpuReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CpuState {
|
|
||||||
pub a: Byte, // Accumulator Register
|
|
||||||
pub x: Byte, // X Register
|
|
||||||
pub y: Byte, // Y Register
|
|
||||||
pub pc: Word, // Program Counter
|
|
||||||
pub s: Byte, // Stack Pointer
|
|
||||||
pub p: Byte, // Status Register
|
|
||||||
pub irq: bool,
|
|
||||||
pub nmi: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[derive(Clone)]
|
|
||||||
pub struct Cpu {
|
pub struct Cpu {
|
||||||
pub a: Byte, // Accumulator Register
|
pub a: u8, // Accumulator Register
|
||||||
pub x: Byte, // X Register
|
pub x: u8, // X Register
|
||||||
pub y: Byte, // Y Register
|
pub y: u8, // Y Register
|
||||||
pub pc: Word, // Program Counter
|
pub pc: u16, // Program Counter
|
||||||
pub s: Byte, // Stack Pointer
|
pub s: u8, // Stack Pointer
|
||||||
pub p: Byte, // Status Register
|
pub p: u8, // Status Register
|
||||||
pub irq: bool,
|
pub irq: bool,
|
||||||
pub nmi: bool,
|
pub nmi: bool,
|
||||||
pub memory: MemHandle,
|
pub memory: MemHandle,
|
||||||
pub pending_cycles: usize,
|
pub pending_cycles: usize,
|
||||||
receiver: CpuReceiver,
|
receiver: Option<CpuReceiver>,
|
||||||
stopped: bool,
|
stopped: bool,
|
||||||
// cycle_count: usize,
|
// cycle_count: usize,
|
||||||
// state_tx: Sender<CpuState>,
|
// state_tx: Sender<CpuState>,
|
||||||
|
@ -94,18 +81,18 @@ impl Display for Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemoryReader for Cpu {
|
impl MemoryReader for Cpu {
|
||||||
fn read(&self, address: Word) -> Byte {
|
fn read(&self, address: u16) -> u8 {
|
||||||
self.memory.read(address)
|
self.memory.read(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl MemoryWriter for Cpu {
|
impl MemoryWriter for Cpu {
|
||||||
fn write(&self, address: Word, data: Byte) {
|
fn write(&self, address: u16, data: u8) {
|
||||||
self.memory.write(address, data);
|
self.memory.write(address, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
pub fn new(memory: MemHandle, receiver: CpuReceiver) -> Self {
|
pub fn new(memory: MemHandle) -> Self {
|
||||||
// pub fn new(memory: MemHandle) -> Self {
|
// pub fn new(memory: MemHandle) -> Self {
|
||||||
Cpu {
|
Cpu {
|
||||||
a: 0x00,
|
a: 0x00,
|
||||||
|
@ -116,7 +103,7 @@ impl Cpu {
|
||||||
p: 0b0010_0100,
|
p: 0b0010_0100,
|
||||||
irq: false,
|
irq: false,
|
||||||
nmi: false,
|
nmi: false,
|
||||||
receiver,
|
receiver: None,
|
||||||
memory,
|
memory,
|
||||||
stopped: false,
|
stopped: false,
|
||||||
pending_cycles: 0,
|
pending_cycles: 0,
|
||||||
|
@ -124,78 +111,78 @@ impl Cpu {
|
||||||
// state_tx,
|
// state_tx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn with_receiver(mut self, receiver: CpuReceiver) -> Self {
|
||||||
|
self.receiver = Some(receiver);
|
||||||
|
self
|
||||||
|
}
|
||||||
pub fn new_with_control(memory: MemHandle) -> (Self, CpuController) {
|
pub fn new_with_control(memory: MemHandle) -> (Self, CpuController) {
|
||||||
let (tx, rx) = channel::<CpuControl>();
|
let (tx, rx) = channel::<CpuControl>();
|
||||||
let controller = CpuController(tx);
|
let controller = CpuController(tx);
|
||||||
let receiver = CpuReceiver(rx);
|
let receiver = CpuReceiver(rx);
|
||||||
let cpu = Cpu::new(memory, receiver);
|
let cpu = Cpu::new(memory).with_receiver(receiver);
|
||||||
(cpu, controller)
|
(cpu, controller)
|
||||||
}
|
}
|
||||||
pub fn reset(&mut self) -> Result<()> {
|
pub fn reset(&mut self) {
|
||||||
let reset_vector_pointer = self.read_word(0xFFFC)?;
|
let reset_vector_pointer = self.read_word(0xFFFC);
|
||||||
self.pc = reset_vector_pointer;
|
self.pc = reset_vector_pointer;
|
||||||
self.pending_cycles = 0;
|
self.pending_cycles = 0;
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
pub fn read_word(&self, address: Word) -> Result<Word> {
|
pub fn read_word(&self, address: u16) -> u16 {
|
||||||
let low_byte = self.read(address);
|
let low_byte = self.read(address);
|
||||||
let high_byte = self.read(address + 0x1);
|
let high_byte = self.read(address.wrapping_add(0x1));
|
||||||
Ok((high_byte as u16) << 8 | (low_byte as u16))
|
(high_byte as u16) << 8 | (low_byte as u16)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_addr(&self) -> Word {
|
fn stack_addr(&self) -> u16 {
|
||||||
// Dunno if this is necessary, i just don't like adding the 0x0100 every time
|
// Dunno if this is necessary, i just don't like adding the 0x0100 every time
|
||||||
0x0100 + self.s as u16
|
0x0100 + self.s as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_stack(&mut self, data: Byte) -> Result<()> {
|
pub fn push_stack(&mut self, data: u8) {
|
||||||
self.s = self.s.wrapping_sub(0x1);
|
self.s = self.s.wrapping_sub(0x1);
|
||||||
self.write(self.stack_addr(), data);
|
self.write(self.stack_addr(), data);
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_stack_word(&mut self, address: Word) -> Result<()> {
|
pub fn push_stack_word(&mut self, address: u16) {
|
||||||
self.s = self.s.wrapping_sub(0x1);
|
self.s = self.s.wrapping_sub(0x1);
|
||||||
self.write(self.stack_addr(), address.to_le_bytes()[1]); // Upper byte first
|
self.write(self.stack_addr(), address.to_le_bytes()[1]); // Upper byte first
|
||||||
self.s = self.s.wrapping_sub(0x1);
|
self.s = self.s.wrapping_sub(0x1);
|
||||||
self.write(self.stack_addr(), address.to_le_bytes()[0]); // Lower byte second
|
self.write(self.stack_addr(), address.to_le_bytes()[0]); // Lower byte second
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_stack(&mut self) -> Result<Byte> {
|
pub fn pop_stack(&mut self) -> u8 {
|
||||||
let byte = self.read(self.stack_addr());
|
let byte = self.read(self.stack_addr());
|
||||||
self.s = self.s.wrapping_add(0x1);
|
self.s = self.s.wrapping_add(0x1);
|
||||||
Ok(byte)
|
byte
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_stack_word(&mut self) -> Result<Word> {
|
pub fn pop_stack_word(&mut self) -> u16 {
|
||||||
let low_byte = self.pop_stack()?;
|
let low_byte = self.pop_stack();
|
||||||
let high_byte = self.pop_stack()?;
|
let high_byte = self.pop_stack();
|
||||||
let word = ((high_byte as Word) << 8) + low_byte as u16;
|
((high_byte as u16) << 8) + low_byte as u16
|
||||||
Ok(word)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_flag(&mut self, flag: StatusFlag, value: bool) {
|
pub fn set_flag(&mut self, flag: StatusFlag, value: bool) {
|
||||||
self.p &= !(flag as Byte);
|
self.p &= !(flag as u8);
|
||||||
if value {
|
if value {
|
||||||
self.p |= flag as Byte
|
self.p |= flag as u8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_flag(&self, flag: StatusFlag) -> bool {
|
pub fn get_flag(&self, flag: StatusFlag) -> bool {
|
||||||
(self.p & flag as Byte) > 0
|
(self.p & flag as u8) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_negative(&self, value: Byte) -> bool {
|
pub fn is_negative(&self, value: u8) -> bool {
|
||||||
value & 0b1000_0000 == 0b1000_0000
|
value & 0b1000_0000 == 0b1000_0000
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&mut self) {
|
// pub fn execute(&mut self) {
|
||||||
self.cycle();
|
// self.cycle();
|
||||||
while self.pending_cycles != 0 {
|
// while self.pending_cycles != 0 {
|
||||||
self.cycle();
|
// self.cycle();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn wait_for_interrupt(&self) {
|
pub fn wait_for_interrupt(&self) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -203,14 +190,16 @@ impl Cpu {
|
||||||
|
|
||||||
pub fn interrupt(&mut self) {
|
pub fn interrupt(&mut self) {
|
||||||
self.irq = false;
|
self.irq = false;
|
||||||
self.push_stack_word(self.pc).unwrap();
|
self.push_stack_word(self.pc);
|
||||||
self.push_stack(self.p).unwrap();
|
self.push_stack(self.p);
|
||||||
self.set_flag(StatusFlag::IrqDisable, true);
|
self.set_flag(StatusFlag::IrqDisable, true);
|
||||||
self.pc = self.read_word(0xFFFE).unwrap();
|
self.pc = self.read_word(0xFFFE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_control(&mut self) {
|
fn receive_control(&mut self) {
|
||||||
let control = match self.receiver.0.try_recv() {
|
match &self.receiver {
|
||||||
|
Some(receiver) => {
|
||||||
|
let control = match receiver.0.try_recv() {
|
||||||
Ok(control) => control,
|
Ok(control) => control,
|
||||||
Err(_error) => return, // most of the time we won't have any impending control
|
Err(_error) => return, // most of the time we won't have any impending control
|
||||||
// messages, just return if that's the case
|
// messages, just return if that's the case
|
||||||
|
@ -235,6 +224,9 @@ impl Cpu {
|
||||||
// .unwrap(),
|
// .unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cycle(&mut self) {
|
pub fn cycle(&mut self) {
|
||||||
self.receive_control();
|
self.receive_control();
|
||||||
|
@ -251,37 +243,38 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
let opcode = self.read(self.pc);
|
let opcode = self.read(self.pc);
|
||||||
let instruction = get_instruction(opcode);
|
let instruction = get_instruction(opcode);
|
||||||
match instruction {
|
instruction.call(self);
|
||||||
Instruction::Valid(valid_instruction) => {
|
// match instruction {
|
||||||
// println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq, nmi = self.nmi);
|
// Instruction::Valid(valid_instruction) => {
|
||||||
|
// // println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq, nmi = self.nmi);
|
||||||
|
// // println!(
|
||||||
|
// // "Instruction: {:?}, {:#04x}",
|
||||||
|
// // valid_instruction.opcode, opcode
|
||||||
|
// // );
|
||||||
|
// // println!("");
|
||||||
|
// self.pc += 1;
|
||||||
|
// match valid_instruction.opcode.call(self) {
|
||||||
|
// Ok(_) => {
|
||||||
|
// self.pending_cycles += valid_instruction.cycles as usize;
|
||||||
|
// }
|
||||||
|
// Err(_) => {
|
||||||
|
// println!("An IncompatibleAddrMode was used at address {:#06x} for instruction {:?}", self.pc, valid_instruction);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// Instruction::Invalid(invalid_instruction) => match invalid_instruction.opcode {
|
||||||
|
// 0x02 => {
|
||||||
|
// // println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq.try_recv().unwrap_or_default(), nmi = self.nmi);
|
||||||
|
// let _ = &self.memory.dump();
|
||||||
|
// }
|
||||||
|
// _ => {
|
||||||
// println!(
|
// println!(
|
||||||
// "Instruction: {:?}, {:#04x}",
|
// "An invalid instruction with opcode {:#04x} was called at address {:#06x}",
|
||||||
// valid_instruction.opcode, opcode
|
// invalid_instruction.opcode, self.pc
|
||||||
// );
|
// );
|
||||||
// println!("");
|
// }
|
||||||
self.pc += 1;
|
// },
|
||||||
match valid_instruction.opcode.call(self) {
|
// }
|
||||||
Ok(_) => {
|
|
||||||
self.pending_cycles += valid_instruction.cycles as usize;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
println!("An IncompatibleAddrMode was used at address {:#06x} for instruction {:?}", self.pc, valid_instruction);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Instruction::Invalid(invalid_instruction) => match invalid_instruction.opcode {
|
|
||||||
0x02 => {
|
|
||||||
// println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq.try_recv().unwrap_or_default(), nmi = self.nmi);
|
|
||||||
&self.memory.dump();
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
println!(
|
|
||||||
"An invalid instruction with opcode {:#04x} was called at address {:#06x}",
|
|
||||||
invalid_instruction.opcode, self.pc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
// self.cycle_count += 1;
|
// self.cycle_count += 1;
|
||||||
}
|
}
|
||||||
pub fn stop(&mut self) {
|
pub fn stop(&mut self) {
|
||||||
|
|
3005
src/instructions.rs
3005
src/instructions.rs
File diff suppressed because it is too large
Load Diff
581
src/keyboard.rs
581
src/keyboard.rs
|
@ -1,5 +1,10 @@
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
use std::io::{self, stdin, Read};
|
||||||
use minifb::{InputCallback, Key};
|
|
||||||
|
// use minifb::{InputCallback, Key};
|
||||||
|
use termion::{
|
||||||
|
event::Key,
|
||||||
|
input::{Keys, TermRead},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::memory::{MemHandle, MemoryWriter};
|
use crate::memory::{MemHandle, MemoryWriter};
|
||||||
|
|
||||||
|
@ -7,74 +12,405 @@ pub struct Keyboard {
|
||||||
memory: MemHandle,
|
memory: MemHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PlainKeys<R> {
|
||||||
|
iter: Keys<R>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read> Iterator for PlainKeys<R> {
|
||||||
|
type Item = Result<char, io::Error>;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
loop {
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(Ok(key)) => match key {
|
||||||
|
Key::Ctrl(char) => return Some(Ok(char)),
|
||||||
|
Key::Alt(char) => return Some(Ok(char)),
|
||||||
|
Key::Char('A') => return Some(Ok('a')),
|
||||||
|
Key::Char('B') => return Some(Ok('b')),
|
||||||
|
Key::Char('C') => return Some(Ok('c')),
|
||||||
|
Key::Char('D') => return Some(Ok('d')),
|
||||||
|
Key::Char('E') => return Some(Ok('e')),
|
||||||
|
Key::Char('F') => return Some(Ok('f')),
|
||||||
|
Key::Char('G') => return Some(Ok('g')),
|
||||||
|
Key::Char('H') => return Some(Ok('h')),
|
||||||
|
Key::Char('I') => return Some(Ok('i')),
|
||||||
|
Key::Char('J') => return Some(Ok('j')),
|
||||||
|
Key::Char('K') => return Some(Ok('k')),
|
||||||
|
Key::Char('L') => return Some(Ok('l')),
|
||||||
|
Key::Char('M') => return Some(Ok('m')),
|
||||||
|
Key::Char('N') => return Some(Ok('n')),
|
||||||
|
Key::Char('O') => return Some(Ok('o')),
|
||||||
|
Key::Char('P') => return Some(Ok('p')),
|
||||||
|
Key::Char('Q') => return Some(Ok('q')),
|
||||||
|
Key::Char('R') => return Some(Ok('r')),
|
||||||
|
Key::Char('S') => return Some(Ok('s')),
|
||||||
|
Key::Char('T') => return Some(Ok('t')),
|
||||||
|
Key::Char('U') => return Some(Ok('u')),
|
||||||
|
Key::Char('V') => return Some(Ok('v')),
|
||||||
|
Key::Char('W') => return Some(Ok('w')),
|
||||||
|
Key::Char('X') => return Some(Ok('x')),
|
||||||
|
Key::Char('Y') => return Some(Ok('y')),
|
||||||
|
Key::Char('Z') => return Some(Ok('z')),
|
||||||
|
Key::Char('!') => return Some(Ok('1')),
|
||||||
|
Key::Char('@') => return Some(Ok('2')),
|
||||||
|
Key::Char('#') => return Some(Ok('3')),
|
||||||
|
Key::Char('$') => return Some(Ok('4')),
|
||||||
|
Key::Char('%') => return Some(Ok('5')),
|
||||||
|
Key::Char('^') => return Some(Ok('6')),
|
||||||
|
Key::Char('&') => return Some(Ok('7')),
|
||||||
|
Key::Char('*') => return Some(Ok('8')),
|
||||||
|
Key::Char('(') => return Some(Ok('9')),
|
||||||
|
Key::Char(')') => return Some(Ok('0')),
|
||||||
|
Key::Char('~') => return Some(Ok('`')),
|
||||||
|
Key::Char('_') => return Some(Ok('-')),
|
||||||
|
Key::Char('+') => return Some(Ok('=')),
|
||||||
|
Key::Char('|') => return Some(Ok('\\')),
|
||||||
|
Key::Char('}') => return Some(Ok(']')),
|
||||||
|
Key::Char('{') => return Some(Ok('[')),
|
||||||
|
Key::Char('"') => return Some(Ok('\'')),
|
||||||
|
Key::Char(':') => return Some(Ok(';')),
|
||||||
|
Key::Char('?') => return Some(Ok('/')),
|
||||||
|
Key::Char('>') => return Some(Ok('.')),
|
||||||
|
Key::Char('<') => return Some(Ok(',')),
|
||||||
|
Key::Char(char) => return Some(Ok(char)),
|
||||||
|
_ => continue,
|
||||||
|
},
|
||||||
|
Some(Err(e)) => return Some(Err(e)),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Ord, Eq, PartialEq, PartialOrd)]
|
||||||
|
enum ControlKey {
|
||||||
|
Alt,
|
||||||
|
Shift,
|
||||||
|
Ctrl,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Esc,
|
||||||
|
Enter,
|
||||||
|
Home,
|
||||||
|
End,
|
||||||
|
Tab,
|
||||||
|
Backspace,
|
||||||
|
Delete,
|
||||||
|
Insert,
|
||||||
|
PageDown,
|
||||||
|
PageUp,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ControlKeys<R> {
|
||||||
|
iter: Keys<R>,
|
||||||
|
extra: Option<ControlKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read> Iterator for ControlKeys<R> {
|
||||||
|
type Item = Result<ControlKey, io::Error>;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
loop {
|
||||||
|
if let Some(key) = self.extra {
|
||||||
|
return Some(Ok(key));
|
||||||
|
}
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(Ok(key)) => match key {
|
||||||
|
Key::Ctrl(char) => match char {
|
||||||
|
'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' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '(' | ')'
|
||||||
|
| '~' | '_' | '+' | '|' | '}' | '{' | '"' | ':' | '?' | '>' | '<' => {
|
||||||
|
self.extra = Some(ControlKey::Shift);
|
||||||
|
return Some(Ok(ControlKey::Ctrl));
|
||||||
|
}
|
||||||
|
_ => return Some(Ok(ControlKey::Ctrl)),
|
||||||
|
},
|
||||||
|
Key::CtrlUp => {
|
||||||
|
self.extra = Some(ControlKey::Ctrl);
|
||||||
|
return Some(Ok(ControlKey::Up));
|
||||||
|
}
|
||||||
|
Key::CtrlDown => {
|
||||||
|
self.extra = Some(ControlKey::Ctrl);
|
||||||
|
return Some(Ok(ControlKey::Down));
|
||||||
|
}
|
||||||
|
Key::CtrlRight => {
|
||||||
|
self.extra = Some(ControlKey::Ctrl);
|
||||||
|
return Some(Ok(ControlKey::Right));
|
||||||
|
}
|
||||||
|
Key::CtrlLeft => {
|
||||||
|
self.extra = Some(ControlKey::Ctrl);
|
||||||
|
return Some(Ok(ControlKey::Left));
|
||||||
|
}
|
||||||
|
Key::CtrlEnd => {
|
||||||
|
self.extra = Some(ControlKey::Ctrl);
|
||||||
|
return Some(Ok(ControlKey::End));
|
||||||
|
}
|
||||||
|
Key::CtrlHome => {
|
||||||
|
self.extra = Some(ControlKey::Ctrl);
|
||||||
|
return Some(Ok(ControlKey::Home));
|
||||||
|
}
|
||||||
|
Key::Alt(char) => match char {
|
||||||
|
'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' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '(' | ')'
|
||||||
|
| '~' | '_' | '+' | '|' | '}' | '{' | '"' | ':' | '?' | '>' | '<' => {
|
||||||
|
self.extra = Some(ControlKey::Shift);
|
||||||
|
return Some(Ok(ControlKey::Alt));
|
||||||
|
}
|
||||||
|
_ => return Some(Ok(ControlKey::Alt)),
|
||||||
|
},
|
||||||
|
Key::AltUp => {
|
||||||
|
self.extra = Some(ControlKey::Alt);
|
||||||
|
return Some(Ok(ControlKey::Up));
|
||||||
|
}
|
||||||
|
Key::AltDown => {
|
||||||
|
self.extra = Some(ControlKey::Alt);
|
||||||
|
return Some(Ok(ControlKey::Down));
|
||||||
|
}
|
||||||
|
Key::AltRight => {
|
||||||
|
self.extra = Some(ControlKey::Alt);
|
||||||
|
return Some(Ok(ControlKey::Right));
|
||||||
|
}
|
||||||
|
Key::AltLeft => {
|
||||||
|
self.extra = Some(ControlKey::Alt);
|
||||||
|
return Some(Ok(ControlKey::Left));
|
||||||
|
}
|
||||||
|
Key::Char('A')
|
||||||
|
| Key::Char('B')
|
||||||
|
| Key::Char('C')
|
||||||
|
| Key::Char('D')
|
||||||
|
| Key::Char('E')
|
||||||
|
| Key::Char('F')
|
||||||
|
| Key::Char('G')
|
||||||
|
| Key::Char('H')
|
||||||
|
| Key::Char('I')
|
||||||
|
| Key::Char('J')
|
||||||
|
| Key::Char('K')
|
||||||
|
| Key::Char('L')
|
||||||
|
| Key::Char('M')
|
||||||
|
| Key::Char('N')
|
||||||
|
| Key::Char('O')
|
||||||
|
| Key::Char('P')
|
||||||
|
| Key::Char('Q')
|
||||||
|
| Key::Char('R')
|
||||||
|
| Key::Char('S')
|
||||||
|
| Key::Char('T')
|
||||||
|
| Key::Char('U')
|
||||||
|
| Key::Char('V')
|
||||||
|
| Key::Char('W')
|
||||||
|
| Key::Char('X')
|
||||||
|
| Key::Char('Y')
|
||||||
|
| Key::Char('Z')
|
||||||
|
| Key::Char('!')
|
||||||
|
| Key::Char('@')
|
||||||
|
| Key::Char('#')
|
||||||
|
| Key::Char('$')
|
||||||
|
| Key::Char('%')
|
||||||
|
| Key::Char('^')
|
||||||
|
| Key::Char('&')
|
||||||
|
| Key::Char('*')
|
||||||
|
| Key::Char('(')
|
||||||
|
| Key::Char(')')
|
||||||
|
| Key::Char('~')
|
||||||
|
| Key::Char('_')
|
||||||
|
| Key::Char('+')
|
||||||
|
| Key::Char('|')
|
||||||
|
| Key::Char('}')
|
||||||
|
| Key::Char('{')
|
||||||
|
| Key::Char('"')
|
||||||
|
| Key::Char(':')
|
||||||
|
| Key::Char('?')
|
||||||
|
| Key::Char('>')
|
||||||
|
| Key::Char('<') => return Some(Ok(ControlKey::Shift)),
|
||||||
|
Key::ShiftUp => {
|
||||||
|
self.extra = Some(ControlKey::Shift);
|
||||||
|
return Some(Ok(ControlKey::Up));
|
||||||
|
}
|
||||||
|
Key::ShiftDown => {
|
||||||
|
self.extra = Some(ControlKey::Shift);
|
||||||
|
return Some(Ok(ControlKey::Down));
|
||||||
|
}
|
||||||
|
Key::ShiftRight => {
|
||||||
|
self.extra = Some(ControlKey::Shift);
|
||||||
|
return Some(Ok(ControlKey::Right));
|
||||||
|
}
|
||||||
|
Key::ShiftLeft => {
|
||||||
|
self.extra = Some(ControlKey::Shift);
|
||||||
|
return Some(Ok(ControlKey::Left));
|
||||||
|
}
|
||||||
|
Key::Backspace => return Some(Ok(ControlKey::Backspace)),
|
||||||
|
Key::Up => return Some(Ok(ControlKey::Up)),
|
||||||
|
Key::Down => return Some(Ok(ControlKey::Down)),
|
||||||
|
Key::Right => return Some(Ok(ControlKey::Right)),
|
||||||
|
Key::Left => return Some(Ok(ControlKey::Left)),
|
||||||
|
Key::Home => return Some(Ok(ControlKey::Home)),
|
||||||
|
Key::End => return Some(Ok(ControlKey::End)),
|
||||||
|
Key::PageUp => return Some(Ok(ControlKey::PageUp)),
|
||||||
|
Key::PageDown => return Some(Ok(ControlKey::PageDown)),
|
||||||
|
Key::Insert => return Some(Ok(ControlKey::Insert)),
|
||||||
|
Key::Delete => return Some(Ok(ControlKey::Delete)),
|
||||||
|
_ => continue,
|
||||||
|
},
|
||||||
|
Some(Err(e)) => return Some(Err(e)),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait GetKeys {
|
||||||
|
fn get_plain(self) -> PlainKeys<Self>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn get_modifiers(self) -> ControlKeys<Self>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read + TermRead> GetKeys for R {
|
||||||
|
fn get_plain(self) -> PlainKeys<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
PlainKeys { iter: self.keys() }
|
||||||
|
}
|
||||||
|
fn get_modifiers(self) -> ControlKeys<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
ControlKeys {
|
||||||
|
iter: self.keys(),
|
||||||
|
extra: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Keyboard {
|
impl Keyboard {
|
||||||
pub fn new(memory: MemHandle) -> Self {
|
pub fn new(memory: MemHandle) -> Self {
|
||||||
Self { memory }
|
Self { memory }
|
||||||
}
|
}
|
||||||
pub fn read_keys(&self, key: KeyEvent) {
|
|
||||||
|
pub fn clear_keys(&self) {
|
||||||
|
self.memory.write(0x4400, 0x00);
|
||||||
|
self.memory.write(0x4401, 0x00);
|
||||||
|
self.memory.write(0x4402, 0x00);
|
||||||
|
self.memory.write(0x4403, 0x00);
|
||||||
|
self.memory.write(0x4404, 0x00);
|
||||||
|
self.memory.write(0x4405, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn read_keys(&self, key: KeyEvent) {
|
||||||
|
pub fn read_keys(&self) {
|
||||||
let mut row0 = 0;
|
let mut row0 = 0;
|
||||||
let mut row1 = 0;
|
let mut row1 = 0;
|
||||||
let mut row2 = 0;
|
let mut row2 = 0;
|
||||||
let mut row3 = 0;
|
let mut row3 = 0;
|
||||||
let mut row4 = 0;
|
let mut row4 = 0;
|
||||||
let mut row5 = 0;
|
let mut row5 = 0;
|
||||||
match key.modifiers {
|
|
||||||
KeyModifiers::SHIFT => row2 ^= 0b1000_0000,
|
|
||||||
KeyModifiers::CONTROL => row3 ^= 0b1000_0000,
|
|
||||||
KeyModifiers::ALT => row4 ^= 0b1000_0000,
|
|
||||||
KeyModifiers::META => row5 ^= 0b1000_0000,
|
|
||||||
KeyModifiers::SUPER => row5 ^= 0b0010_0000,
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
match key.code {
|
let modifiers = termion::async_stdin().get_modifiers();
|
||||||
KeyCode::Esc => row0 ^= 0b1000_0000,
|
for m in modifiers {
|
||||||
KeyCode::Char('w') => row0 ^= 0b0100_0000,
|
match m.unwrap() {
|
||||||
KeyCode::Char('e') => row0 ^= 0b0010_0000,
|
ControlKey::Shift => row2 ^= 0b1000_0000,
|
||||||
KeyCode::Char('r') => row0 ^= 0b0001_0000,
|
ControlKey::Ctrl => row3 ^= 0b1000_0000,
|
||||||
KeyCode::Char('t') => row0 ^= 0b0000_1000,
|
ControlKey::Alt => row4 ^= 0b1000_0000,
|
||||||
KeyCode::Char('u') => row0 ^= 0b0000_0100,
|
ControlKey::Esc => row0 ^= 0b1000_0000,
|
||||||
KeyCode::Char('o') => row0 ^= 0b0000_0010,
|
ControlKey::Backspace => row0 ^= 0b0000_0001,
|
||||||
KeyCode::Backspace => row0 ^= 0b0000_0001,
|
ControlKey::Tab => row1 ^= 0b1000_0000,
|
||||||
KeyCode::Tab => row1 ^= 0b1000_0000,
|
ControlKey::Enter => row1 ^= 0b0000_0001,
|
||||||
KeyCode::Char('q') => row1 ^= 0b0100_0000,
|
_ => {}
|
||||||
KeyCode::Char('s') => row1 ^= 0b0010_0000,
|
|
||||||
KeyCode::Char('g') => row1 ^= 0b0001_0000,
|
|
||||||
KeyCode::Char('y') => row1 ^= 0b0000_1000,
|
|
||||||
KeyCode::Char('i') => row1 ^= 0b0000_0100,
|
|
||||||
KeyCode::Char('p') => row1 ^= 0b0000_0010,
|
|
||||||
KeyCode::Enter => row1 ^= 0b0000_0001,
|
|
||||||
KeyCode::Char('d') => row2 ^= 0b0100_0000,
|
|
||||||
KeyCode::Char('v') => row2 ^= 0b0010_0000,
|
|
||||||
KeyCode::Char('h') => row2 ^= 0b0001_0000,
|
|
||||||
KeyCode::Char('k') => row2 ^= 0b0000_1000,
|
|
||||||
KeyCode::Char('\'') => row2 ^= 0b0000_0100,
|
|
||||||
KeyCode::Char('/') => row2 ^= 0b0000_0010,
|
|
||||||
KeyCode::Char('a') => row2 ^= 0b0000_0001,
|
|
||||||
KeyCode::Char('z') => row3 ^= 0b0100_0000,
|
|
||||||
KeyCode::Char('f') => row3 ^= 0b0010_0000,
|
|
||||||
KeyCode::Char('b') => row3 ^= 0b0001_0000,
|
|
||||||
KeyCode::Char('j') => row3 ^= 0b0000_1000,
|
|
||||||
KeyCode::Char('l') => row3 ^= 0b0000_0100,
|
|
||||||
KeyCode::Char('2') => row3 ^= 0b0000_0010,
|
|
||||||
KeyCode::Char('4') => row3 ^= 0b0000_0001,
|
|
||||||
KeyCode::Char('x') => row4 ^= 0b0100_0000,
|
|
||||||
KeyCode::Char('c') => row4 ^= 0b0010_0000,
|
|
||||||
KeyCode::Char('n') => row4 ^= 0b0001_0000,
|
|
||||||
KeyCode::Char('m') => row4 ^= 0b0000_1000,
|
|
||||||
KeyCode::Char(',') => row4 ^= 0b0000_0100,
|
|
||||||
KeyCode::Char('1') => row4 ^= 0b0000_0010,
|
|
||||||
KeyCode::Char('3') => row4 ^= 0b0000_0001,
|
|
||||||
KeyCode::Char(' ') => row5 ^= 0b0100_0000,
|
|
||||||
_ => {
|
|
||||||
row0 = 0;
|
|
||||||
row1 = 0;
|
|
||||||
row2 = 0;
|
|
||||||
row3 = 0;
|
|
||||||
row4 = 0;
|
|
||||||
row5 = 0;
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
let keys = termion::async_stdin().get_plain();
|
||||||
|
for k in keys {
|
||||||
|
match k.unwrap() {
|
||||||
|
'w' => row0 ^= 0b0100_0000,
|
||||||
|
'e' => row0 ^= 0b0010_0000,
|
||||||
|
'r' => row0 ^= 0b0001_0000,
|
||||||
|
't' => row0 ^= 0b0000_1000,
|
||||||
|
'u' => row0 ^= 0b0000_0100,
|
||||||
|
'o' => row0 ^= 0b0000_0010,
|
||||||
|
'q' => row1 ^= 0b0100_0000,
|
||||||
|
's' => row1 ^= 0b0010_0000,
|
||||||
|
'g' => row1 ^= 0b0001_0000,
|
||||||
|
'y' => row1 ^= 0b0000_1000,
|
||||||
|
'i' => row1 ^= 0b0000_0100,
|
||||||
|
'p' => row1 ^= 0b0000_0010,
|
||||||
|
'd' => row2 ^= 0b0100_0000,
|
||||||
|
'v' => row2 ^= 0b0010_0000,
|
||||||
|
'h' => row2 ^= 0b0001_0000,
|
||||||
|
'k' => row2 ^= 0b0000_1000,
|
||||||
|
'\\' => row2 ^= 0b0000_0100,
|
||||||
|
'/' => row2 ^= 0b0000_0010,
|
||||||
|
'a' => row2 ^= 0b0000_0001,
|
||||||
|
'z' => row3 ^= 0b0100_0000,
|
||||||
|
'f' => row3 ^= 0b0010_0000,
|
||||||
|
'b' => row3 ^= 0b0001_0000,
|
||||||
|
'j' => row3 ^= 0b0000_1000,
|
||||||
|
'l' => row3 ^= 0b0000_0100,
|
||||||
|
'2' => row3 ^= 0b0000_0010,
|
||||||
|
'4' => row3 ^= 0b0000_0001,
|
||||||
|
'x' => row4 ^= 0b0100_0000,
|
||||||
|
'c' => row4 ^= 0b0010_0000,
|
||||||
|
'n' => row4 ^= 0b0001_0000,
|
||||||
|
'm' => row4 ^= 0b0000_1000,
|
||||||
|
',' => row4 ^= 0b0000_0100,
|
||||||
|
'1' => row4 ^= 0b0000_0010,
|
||||||
|
'3' => row4 ^= 0b0000_0001,
|
||||||
|
' ' => row5 ^= 0b0100_0000,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// match key.code {
|
||||||
|
// KeyCode::Esc => row0 ^= 0b1000_0000,
|
||||||
|
// KeyCode::Char('w') => row0 ^= 0b0100_0000,
|
||||||
|
// KeyCode::Char('e') => row0 ^= 0b0010_0000,
|
||||||
|
// KeyCode::Char('r') => row0 ^= 0b0001_0000,
|
||||||
|
// KeyCode::Char('t') => row0 ^= 0b0000_1000,
|
||||||
|
// KeyCode::Char('u') => row0 ^= 0b0000_0100,
|
||||||
|
// KeyCode::Char('o') => row0 ^= 0b0000_0010,
|
||||||
|
// KeyCode::Backspace => row0 ^= 0b0000_0001,
|
||||||
|
// KeyCode::Tab => row1 ^= 0b1000_0000,
|
||||||
|
// KeyCode::Char('q') => row1 ^= 0b0100_0000,
|
||||||
|
// KeyCode::Char('s') => row1 ^= 0b0010_0000,
|
||||||
|
// KeyCode::Char('g') => row1 ^= 0b0001_0000,
|
||||||
|
// KeyCode::Char('y') => row1 ^= 0b0000_1000,
|
||||||
|
// KeyCode::Char('i') => row1 ^= 0b0000_0100,
|
||||||
|
// KeyCode::Char('p') => row1 ^= 0b0000_0010,
|
||||||
|
// KeyCode::Enter => row1 ^= 0b0000_0001,
|
||||||
|
// KeyCode::Char('d') => row2 ^= 0b0100_0000,
|
||||||
|
// KeyCode::Char('v') => row2 ^= 0b0010_0000,
|
||||||
|
// KeyCode::Char('h') => row2 ^= 0b0001_0000,
|
||||||
|
// KeyCode::Char('k') => row2 ^= 0b0000_1000,
|
||||||
|
// KeyCode::Char('\'') => row2 ^= 0b0000_0100,
|
||||||
|
// KeyCode::Char('/') => row2 ^= 0b0000_0010,
|
||||||
|
// KeyCode::Char('a') => row2 ^= 0b0000_0001,
|
||||||
|
// KeyCode::Char('z') => row3 ^= 0b0100_0000,
|
||||||
|
// KeyCode::Char('f') => row3 ^= 0b0010_0000,
|
||||||
|
// KeyCode::Char('b') => row3 ^= 0b0001_0000,
|
||||||
|
// KeyCode::Char('j') => row3 ^= 0b0000_1000,
|
||||||
|
// KeyCode::Char('l') => row3 ^= 0b0000_0100,
|
||||||
|
// KeyCode::Char('2') => row3 ^= 0b0000_0010,
|
||||||
|
// KeyCode::Char('4') => row3 ^= 0b0000_0001,
|
||||||
|
// KeyCode::Char('x') => row4 ^= 0b0100_0000,
|
||||||
|
// KeyCode::Char('c') => row4 ^= 0b0010_0000,
|
||||||
|
// KeyCode::Char('n') => row4 ^= 0b0001_0000,
|
||||||
|
// KeyCode::Char('m') => row4 ^= 0b0000_1000,
|
||||||
|
// KeyCode::Char(',') => row4 ^= 0b0000_0100,
|
||||||
|
// KeyCode::Char('1') => row4 ^= 0b0000_0010,
|
||||||
|
// KeyCode::Char('3') => row4 ^= 0b0000_0001,
|
||||||
|
// KeyCode::Char(' ') => row5 ^= 0b0100_0000,
|
||||||
|
// _ => {
|
||||||
|
// row0 = 0;
|
||||||
|
// row1 = 0;
|
||||||
|
// row2 = 0;
|
||||||
|
// row3 = 0;
|
||||||
|
// row4 = 0;
|
||||||
|
// row5 = 0;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
self.memory.write(0x4400, row0);
|
self.memory.write(0x4400, row0);
|
||||||
self.memory.write(0x4401, row1);
|
self.memory.write(0x4401, row1);
|
||||||
|
@ -87,72 +423,75 @@ impl Keyboard {
|
||||||
|
|
||||||
impl MemoryWriter for Keyboard {
|
impl MemoryWriter for Keyboard {
|
||||||
fn write(&self, address: u16, data: u8) {
|
fn write(&self, address: u16, data: u8) {
|
||||||
|
if data != 0x00 {
|
||||||
|
println!("wrote {:02x} to address {:04x}", data, address);
|
||||||
|
}
|
||||||
self.memory.write(address, data);
|
self.memory.write(address, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputCallback for Keyboard {
|
// impl InputCallback for Keyboard {
|
||||||
fn add_char(&mut self, _uni_char: u32) {}
|
// fn add_char(&mut self, _uni_char: u32) {}
|
||||||
fn set_key_state(&mut self, key: Key, _state: bool) {
|
// fn set_key_state(&mut self, key: Key, _state: bool) {
|
||||||
let mut row0 = 0;
|
// let mut row0 = 0;
|
||||||
let mut row1 = 0;
|
// let mut row1 = 0;
|
||||||
let mut row2 = 0;
|
// let mut row2 = 0;
|
||||||
let mut row3 = 0;
|
// let mut row3 = 0;
|
||||||
let mut row4 = 0;
|
// let mut row4 = 0;
|
||||||
let mut row5 = 0;
|
// let mut row5 = 0;
|
||||||
|
|
||||||
match key {
|
// match key {
|
||||||
Key::Escape => row0 ^= 0b1000_0000,
|
// Key::Escape => row0 ^= 0b1000_0000,
|
||||||
Key::W => row0 ^= 0b0100_0000,
|
// Key::W => row0 ^= 0b0100_0000,
|
||||||
Key::E => row0 ^= 0b0010_0000,
|
// Key::E => row0 ^= 0b0010_0000,
|
||||||
Key::R => row0 ^= 0b0001_0000,
|
// Key::R => row0 ^= 0b0001_0000,
|
||||||
Key::T => row0 ^= 0b0000_1000,
|
// Key::T => row0 ^= 0b0000_1000,
|
||||||
Key::U => row0 ^= 0b0000_0100,
|
// Key::U => row0 ^= 0b0000_0100,
|
||||||
Key::O => row0 ^= 0b0000_0010,
|
// Key::O => row0 ^= 0b0000_0010,
|
||||||
Key::Backspace => row0 ^= 0b0000_0001,
|
// Key::Backspace => row0 ^= 0b0000_0001,
|
||||||
Key::Tab => row1 ^= 0b1000_0000,
|
// Key::Tab => row1 ^= 0b1000_0000,
|
||||||
Key::Q => row1 ^= 0b0100_0000,
|
// Key::Q => row1 ^= 0b0100_0000,
|
||||||
Key::S => row1 ^= 0b0010_0000,
|
// Key::S => row1 ^= 0b0010_0000,
|
||||||
Key::G => row1 ^= 0b0001_0000,
|
// Key::G => row1 ^= 0b0001_0000,
|
||||||
Key::Y => row1 ^= 0b0000_1000,
|
// Key::Y => row1 ^= 0b0000_1000,
|
||||||
Key::I => row1 ^= 0b0000_0100,
|
// Key::I => row1 ^= 0b0000_0100,
|
||||||
Key::P => row1 ^= 0b0000_0010,
|
// Key::P => row1 ^= 0b0000_0010,
|
||||||
Key::Enter => row1 ^= 0b0000_0001,
|
// Key::Enter => row1 ^= 0b0000_0001,
|
||||||
Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000,
|
// Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000,
|
||||||
Key::D => row2 ^= 0b0100_0000,
|
// Key::D => row2 ^= 0b0100_0000,
|
||||||
Key::V => row2 ^= 0b0010_0000,
|
// Key::V => row2 ^= 0b0010_0000,
|
||||||
Key::H => row2 ^= 0b0001_0000,
|
// Key::H => row2 ^= 0b0001_0000,
|
||||||
Key::K => row2 ^= 0b0000_1000,
|
// Key::K => row2 ^= 0b0000_1000,
|
||||||
Key::Apostrophe => row2 ^= 0b0000_0100,
|
// Key::Apostrophe => row2 ^= 0b0000_0100,
|
||||||
Key::Slash => row2 ^= 0b0000_0010,
|
// Key::Slash => row2 ^= 0b0000_0010,
|
||||||
Key::A => row2 ^= 0b0000_0001,
|
// Key::A => row2 ^= 0b0000_0001,
|
||||||
Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000,
|
// Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000,
|
||||||
Key::Z => row3 ^= 0b0100_0000,
|
// Key::Z => row3 ^= 0b0100_0000,
|
||||||
Key::F => row3 ^= 0b0010_0000,
|
// Key::F => row3 ^= 0b0010_0000,
|
||||||
Key::B => row3 ^= 0b0001_0000,
|
// Key::B => row3 ^= 0b0001_0000,
|
||||||
Key::J => row3 ^= 0b0000_1000,
|
// Key::J => row3 ^= 0b0000_1000,
|
||||||
Key::L => row3 ^= 0b0000_0100,
|
// Key::L => row3 ^= 0b0000_0100,
|
||||||
Key::Key2 => row3 ^= 0b0000_0010,
|
// Key::Key2 => row3 ^= 0b0000_0010,
|
||||||
Key::Key4 => row3 ^= 0b0000_0001,
|
// Key::Key4 => row3 ^= 0b0000_0001,
|
||||||
Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000,
|
// Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000,
|
||||||
Key::X => row4 ^= 0b0100_0000,
|
// Key::X => row4 ^= 0b0100_0000,
|
||||||
Key::C => row4 ^= 0b0010_0000,
|
// Key::C => row4 ^= 0b0010_0000,
|
||||||
Key::N => row4 ^= 0b0001_0000,
|
// Key::N => row4 ^= 0b0001_0000,
|
||||||
Key::M => row4 ^= 0b0000_1000,
|
// Key::M => row4 ^= 0b0000_1000,
|
||||||
Key::Comma => row4 ^= 0b0000_0100,
|
// Key::Comma => row4 ^= 0b0000_0100,
|
||||||
Key::Key1 => row4 ^= 0b0000_0010,
|
// Key::Key1 => row4 ^= 0b0000_0010,
|
||||||
Key::Key3 => row4 ^= 0b0000_0001,
|
// Key::Key3 => row4 ^= 0b0000_0001,
|
||||||
Key::LeftSuper => row5 ^= 0b1000_0000,
|
// Key::LeftSuper => row5 ^= 0b1000_0000,
|
||||||
Key::Space => row5 ^= 0b0100_0000,
|
// Key::Space => row5 ^= 0b0100_0000,
|
||||||
Key::RightSuper => row5 ^= 0b0010_0000,
|
// Key::RightSuper => row5 ^= 0b0010_0000,
|
||||||
_ => {}
|
// _ => {}
|
||||||
};
|
// };
|
||||||
|
|
||||||
self.memory.write(0x4400, row0);
|
// self.memory.write(0x4400, row0);
|
||||||
self.memory.write(0x4401, row1);
|
// self.memory.write(0x4401, row1);
|
||||||
self.memory.write(0x4402, row2);
|
// self.memory.write(0x4402, row2);
|
||||||
self.memory.write(0x4403, row3);
|
// self.memory.write(0x4403, row3);
|
||||||
self.memory.write(0x4404, row4);
|
// self.memory.write(0x4404, row4);
|
||||||
self.memory.write(0x4405, row5);
|
// self.memory.write(0x4405, row5);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
83
src/main.rs
83
src/main.rs
|
@ -10,64 +10,36 @@ mod video;
|
||||||
use crate::cpu::Cpu;
|
use crate::cpu::Cpu;
|
||||||
use crate::keyboard::Keyboard;
|
use crate::keyboard::Keyboard;
|
||||||
use crate::memory::Mem;
|
use crate::memory::Mem;
|
||||||
use crate::video::{Screen, TerminalRenderer};
|
use crate::video::Screen;
|
||||||
|
|
||||||
use cli::get_input;
|
use cli::get_input;
|
||||||
use crossterm::execute;
|
|
||||||
use crossterm::terminal::{size, Clear, ClearType, SetSize};
|
|
||||||
// use cpu::CpuController;
|
// use cpu::CpuController;
|
||||||
use memory::MemHandle;
|
use memory::MemHandle;
|
||||||
use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
use std::io::{stdin, stdout, Result};
|
||||||
use std::io::{stdout, Result};
|
|
||||||
use std::thread::{self, sleep};
|
use std::thread::{self, sleep};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use termion::event::Key;
|
||||||
|
use termion::input::TermRead;
|
||||||
|
use termion::raw::IntoRawMode;
|
||||||
|
// use termion::raw::IntoRawMode;
|
||||||
|
|
||||||
use crossterm::{
|
use std::io::Write;
|
||||||
cursor,
|
|
||||||
event::{self, KeyCode, KeyEventKind},
|
|
||||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
|
||||||
};
|
|
||||||
|
|
||||||
// For when we want to leave the terminal again :sigh:
|
use termion::{self, clear, cursor, screen};
|
||||||
//
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut stdout = stdout();
|
let mut stdout = stdout().into_raw_mode().unwrap();
|
||||||
let (cols, rows) = size()?;
|
// let (cols, rows) = size()?;
|
||||||
|
|
||||||
let config = get_input();
|
let config = get_input();
|
||||||
|
|
||||||
let mut memory = Mem::new();
|
let mut memory = Mem::new();
|
||||||
let _ = memory.load_rom(&config.rom);
|
let _ = memory.load_rom(&config.rom);
|
||||||
|
|
||||||
execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?;
|
write!(stdout, "{}{}", cursor::Hide, screen::ToAlternateScreen)?;
|
||||||
enable_raw_mode()?;
|
|
||||||
|
// execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?;
|
||||||
|
// enable_raw_mode()?;
|
||||||
|
|
||||||
let shared_memory = MemHandle::new(memory);
|
let shared_memory = MemHandle::new(memory);
|
||||||
let screen_memory = shared_memory.clone();
|
let screen_memory = shared_memory.clone();
|
||||||
|
@ -86,24 +58,21 @@ fn main() -> Result<()> {
|
||||||
let mut screen = Screen::new(&config, cpu_controller, screen_memory);
|
let mut screen = Screen::new(&config, cpu_controller, screen_memory);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
sleep(Duration::from_millis(16));
|
keyboard.clear_keys(); // nasty hack until i can figure out a good way of clearing keyboard
|
||||||
|
// memory when no keys are pressed
|
||||||
screen.draw();
|
screen.draw();
|
||||||
// if event::poll(std::time::Duration::from_millis(16))? {
|
// if event::poll(std::time::Duration::from_millis(16))? {
|
||||||
if let event::Event::Key(key) = event::read()? {
|
keyboard.read_keys();
|
||||||
keyboard.read_keys(key);
|
for key in stdin().keys() {
|
||||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
match key.unwrap() {
|
||||||
break;
|
Key::Char('q') => {
|
||||||
|
write!(stdout, "{}", clear::All)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
sleep(Duration::from_millis(16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execute!(
|
|
||||||
stdout,
|
|
||||||
LeaveAlternateScreen,
|
|
||||||
SetSize(cols, rows),
|
|
||||||
Clear(ClearType::Purge)
|
|
||||||
)?;
|
|
||||||
disable_raw_mode()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ cleardisplay:
|
||||||
main:
|
main:
|
||||||
; jsr read_keys
|
; jsr read_keys
|
||||||
; lda key_buffer
|
; lda key_buffer
|
||||||
lda $4402
|
lda $4400
|
||||||
sta $6000
|
sta $6000
|
||||||
jmp main
|
jmp main
|
||||||
|
|
||||||
|
|
37
src/video.rs
37
src/video.rs
|
@ -1,10 +1,9 @@
|
||||||
use crossterm::{
|
|
||||||
cursor::{MoveTo, RestorePosition, SavePosition},
|
|
||||||
execute, queue,
|
|
||||||
style::{Color, PrintStyledContent, Stylize},
|
|
||||||
};
|
|
||||||
use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use termion::{
|
||||||
|
color::{self, Bg, Color, Fg},
|
||||||
|
cursor::Goto,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::Config,
|
cli::Config,
|
||||||
|
@ -16,6 +15,8 @@ use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
path::Path,
|
path::Path,
|
||||||
|
process::exit,
|
||||||
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
const FG_COLOR: u32 = 0xFFCC00;
|
const FG_COLOR: u32 = 0xFFCC00;
|
||||||
|
@ -150,40 +151,24 @@ const ASCII_LOOPUP: [&str; 256] = [
|
||||||
// impl Renderer for TerminalRenderer<'_> {
|
// impl Renderer for TerminalRenderer<'_> {
|
||||||
impl Renderer for TerminalRenderer {
|
impl Renderer for TerminalRenderer {
|
||||||
fn render(&mut self) {
|
fn render(&mut self) {
|
||||||
// let now = Instant::now();
|
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
let _ = execute!(stdout, SavePosition);
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for char_row in 0..29 {
|
for char_row in 0..29 {
|
||||||
for char_col in 0..64 {
|
for char_col in 0..64 {
|
||||||
let ascii = self.read(0x6000 + i);
|
let ascii = self.read(0x6000 + i);
|
||||||
i += 1;
|
i += 1;
|
||||||
let char = ASCII_LOOPUP[ascii as usize];
|
let char = ASCII_LOOPUP[ascii as usize];
|
||||||
let _ = queue!(
|
let _ = write!(
|
||||||
// FG_COLOR = 0xFFCC00
|
// FG_COLOR = 0xFFCC00
|
||||||
// BG_COLOR = 0x110500
|
// BG_COLOR = 0x110500
|
||||||
stdout,
|
stdout,
|
||||||
MoveTo(char_col, char_row),
|
"{}{}{}{char}",
|
||||||
PrintStyledContent(
|
Goto(char_col + 1, char_row + 1),
|
||||||
char.with(Color::Rgb {
|
Fg(color::Rgb(0xFF, 0xCC, 0x00)),
|
||||||
r: 0xFF,
|
Bg(color::Rgb(0x11, 0x05, 0x00))
|
||||||
g: 0xCC,
|
|
||||||
b: 0x00
|
|
||||||
})
|
|
||||||
.on(Color::Rgb {
|
|
||||||
r: 0x11,
|
|
||||||
g: 0x05,
|
|
||||||
b: 0x00
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = stdout.flush();
|
|
||||||
let _ = execute!(stdout, RestorePosition);
|
|
||||||
// let elapsed = now.elapsed();
|
|
||||||
// println!("{elapsed:?}");
|
|
||||||
// exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue