the only thing broken is interrupts lol
This commit is contained in:
		
							parent
							
								
									fb4fae430b
								
							
						
					
					
						commit
						7f8e00af23
					
				| 
						 | 
				
			
			@ -69,6 +69,31 @@ version = "1.0.0"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "dlib"
 | 
			
		||||
version = "0.5.2"
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		|||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "libc",
 | 
			
		||||
 "windows-sys",
 | 
			
		||||
 "windows-sys 0.52.0",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -201,6 +226,7 @@ version = "0.1.0"
 | 
			
		|||
dependencies = [
 | 
			
		||||
 "anyhow",
 | 
			
		||||
 "bdf",
 | 
			
		||||
 "crossterm",
 | 
			
		||||
 "minifb",
 | 
			
		||||
 "serde",
 | 
			
		||||
 "termion",
 | 
			
		||||
| 
						 | 
				
			
			@ -263,7 +289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		|||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "cfg-if",
 | 
			
		||||
 "windows-targets",
 | 
			
		||||
 "windows-targets 0.52.5",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +300,7 @@ checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
 | 
			
		|||
dependencies = [
 | 
			
		||||
 "bitflags 2.5.0",
 | 
			
		||||
 "libc",
 | 
			
		||||
 "redox_syscall",
 | 
			
		||||
 "redox_syscall 0.4.1",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -283,6 +309,16 @@ version = "0.4.14"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "log"
 | 
			
		||||
version = "0.4.21"
 | 
			
		||||
| 
						 | 
				
			
			@ -330,6 +366,18 @@ dependencies = [
 | 
			
		|||
 "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]]
 | 
			
		||||
name = "nix"
 | 
			
		||||
version = "0.24.3"
 | 
			
		||||
| 
						 | 
				
			
			@ -366,6 +414,29 @@ dependencies = [
 | 
			
		|||
 "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]]
 | 
			
		||||
name = "pin-project-lite"
 | 
			
		||||
version = "0.2.14"
 | 
			
		||||
| 
						 | 
				
			
			@ -417,6 +488,15 @@ dependencies = [
 | 
			
		|||
 "bitflags 1.3.2",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "redox_syscall"
 | 
			
		||||
version = "0.5.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "bitflags 2.5.0",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "redox_termios"
 | 
			
		||||
version = "0.1.3"
 | 
			
		||||
| 
						 | 
				
			
			@ -433,7 +513,7 @@ dependencies = [
 | 
			
		|||
 "errno",
 | 
			
		||||
 "libc",
 | 
			
		||||
 "linux-raw-sys",
 | 
			
		||||
 "windows-sys",
 | 
			
		||||
 "windows-sys 0.52.0",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -442,6 +522,12 @@ version = "1.0.1"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "scopeguard"
 | 
			
		||||
version = "1.2.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "sdl2"
 | 
			
		||||
version = "0.35.2"
 | 
			
		||||
| 
						 | 
				
			
			@ -494,6 +580,36 @@ dependencies = [
 | 
			
		|||
 "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]]
 | 
			
		||||
name = "slab"
 | 
			
		||||
version = "0.4.9"
 | 
			
		||||
| 
						 | 
				
			
			@ -529,7 +645,7 @@ dependencies = [
 | 
			
		|||
 "cfg-if",
 | 
			
		||||
 "fastrand",
 | 
			
		||||
 "rustix",
 | 
			
		||||
 "windows-sys",
 | 
			
		||||
 "windows-sys 0.52.0",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -610,6 +726,12 @@ version = "0.1.1"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "wasm-bindgen"
 | 
			
		||||
version = "0.2.92"
 | 
			
		||||
| 
						 | 
				
			
			@ -781,13 +903,37 @@ version = "0.4.0"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "windows-sys"
 | 
			
		||||
version = "0.52.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "windows-targets",
 | 
			
		||||
 "windows-targets 0.52.5",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[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]]
 | 
			
		||||
| 
						 | 
				
			
			@ -796,28 +942,46 @@ version = "0.52.5"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "windows_aarch64_gnullvm",
 | 
			
		||||
 "windows_aarch64_msvc",
 | 
			
		||||
 "windows_i686_gnu",
 | 
			
		||||
 "windows_aarch64_gnullvm 0.52.5",
 | 
			
		||||
 "windows_aarch64_msvc 0.52.5",
 | 
			
		||||
 "windows_i686_gnu 0.52.5",
 | 
			
		||||
 "windows_i686_gnullvm",
 | 
			
		||||
 "windows_i686_msvc",
 | 
			
		||||
 "windows_x86_64_gnu",
 | 
			
		||||
 "windows_x86_64_gnullvm",
 | 
			
		||||
 "windows_x86_64_msvc",
 | 
			
		||||
 "windows_i686_msvc 0.52.5",
 | 
			
		||||
 "windows_x86_64_gnu 0.52.5",
 | 
			
		||||
 "windows_x86_64_gnullvm 0.52.5",
 | 
			
		||||
 "windows_x86_64_msvc 0.52.5",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_gnullvm"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_gnullvm"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_msvc"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_msvc"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_gnu"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_gnu"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
| 
						 | 
				
			
			@ -830,24 +994,48 @@ version = "0.52.5"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_msvc"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_msvc"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "windows_x86_64_gnu"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "windows_x86_64_gnullvm"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
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]]
 | 
			
		||||
name = "windows_x86_64_msvc"
 | 
			
		||||
version = "0.52.5"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ edition = "2021"
 | 
			
		|||
[dependencies]
 | 
			
		||||
anyhow = "1.0.81"
 | 
			
		||||
bdf = "0.6.0"
 | 
			
		||||
crossterm = "0.27.0"
 | 
			
		||||
minifb = "0.27.0"
 | 
			
		||||
# minifb = "0.25.0"
 | 
			
		||||
# ratatui = "0.26.3"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								src/cpu.rs
								
								
								
								
							
							
						
						
									
										17
									
								
								src/cpu.rs
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
use crate::instructions::{get_instruction, Instruction};
 | 
			
		||||
use crate::memory::{MemHandle, MemoryReader, MemoryWriter};
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
use std::io::{self, Write};
 | 
			
		||||
use std::process::exit;
 | 
			
		||||
use std::sync::mpsc::{channel, Receiver, Sender};
 | 
			
		||||
use std::thread::sleep;
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +21,7 @@ pub enum StatusFlag {
 | 
			
		|||
    Carry = 0b0000_0001,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct CpuController(Sender<CpuControl>);
 | 
			
		||||
 | 
			
		||||
pub enum CpuControl {
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +30,7 @@ pub enum CpuControl {
 | 
			
		|||
    Stop,
 | 
			
		||||
    Resume,
 | 
			
		||||
    Data,
 | 
			
		||||
    Cycle,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl CpuController {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +49,9 @@ impl CpuController {
 | 
			
		|||
    pub fn resume(&self) {
 | 
			
		||||
        self.0.send(CpuControl::Resume);
 | 
			
		||||
    }
 | 
			
		||||
    pub fn cycle(&self) {
 | 
			
		||||
        self.0.send(CpuControl::Cycle);
 | 
			
		||||
    }
 | 
			
		||||
    pub fn data(&self) {
 | 
			
		||||
        self.0.send(CpuControl::Data);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -70,8 +77,8 @@ pub struct Cpu {
 | 
			
		|||
    pub pending_cycles: usize,
 | 
			
		||||
    receiver: Option<CpuReceiver>,
 | 
			
		||||
    stopped: bool,
 | 
			
		||||
    // cycle_count: usize,
 | 
			
		||||
    // state_tx: Sender<CpuState>,
 | 
			
		||||
    cycle: bool, // cycle_count: usize,
 | 
			
		||||
                 // state_tx: Sender<CpuState>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Display for Cpu {
 | 
			
		||||
| 
						 | 
				
			
			@ -107,8 +114,8 @@ impl Cpu {
 | 
			
		|||
            memory,
 | 
			
		||||
            stopped: false,
 | 
			
		||||
            pending_cycles: 0,
 | 
			
		||||
            // cycle_count: 0,
 | 
			
		||||
            // state_tx,
 | 
			
		||||
            cycle: false, // cycle_count: 0,
 | 
			
		||||
                          // state_tx,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn with_receiver(mut self, receiver: CpuReceiver) -> Self {
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +132,7 @@ impl Cpu {
 | 
			
		|||
    pub fn reset(&mut self) {
 | 
			
		||||
        let reset_vector_pointer = self.read_word(0xFFFC);
 | 
			
		||||
        self.pc = reset_vector_pointer;
 | 
			
		||||
        self.a = 0;
 | 
			
		||||
        self.pending_cycles = 0;
 | 
			
		||||
    }
 | 
			
		||||
    pub fn read_word(&self, address: u16) -> u16 {
 | 
			
		||||
| 
						 | 
				
			
			@ -209,6 +217,7 @@ impl Cpu {
 | 
			
		|||
                    CpuControl::Irq => self.irq = true,
 | 
			
		||||
                    CpuControl::Stop => self.stopped = true,
 | 
			
		||||
                    CpuControl::Resume => self.stopped = false,
 | 
			
		||||
                    CpuControl::Cycle => self.cycle = true,
 | 
			
		||||
                    CpuControl::Data => {} // self
 | 
			
		||||
                                           // .state_tx
 | 
			
		||||
                                           // .send(CpuState {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										562
									
								
								src/keyboard.rs
								
								
								
								
							
							
						
						
									
										562
									
								
								src/keyboard.rs
								
								
								
								
							| 
						 | 
				
			
			@ -1,10 +1,6 @@
 | 
			
		|||
use std::io::{self, stdin, Read};
 | 
			
		||||
 | 
			
		||||
// use minifb::{InputCallback, Key};
 | 
			
		||||
use termion::{
 | 
			
		||||
    event::Key,
 | 
			
		||||
    input::{Keys, TermRead},
 | 
			
		||||
};
 | 
			
		||||
use minifb::InputCallback;
 | 
			
		||||
use minifb::Key as MKey;
 | 
			
		||||
use termion::event::Key;
 | 
			
		||||
 | 
			
		||||
use crate::memory::{MemHandle, MemoryWriter};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,280 +8,6 @@ pub struct Keyboard {
 | 
			
		|||
    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 {
 | 
			
		||||
    pub fn new(memory: MemHandle) -> Self {
 | 
			
		||||
        Self { memory }
 | 
			
		||||
| 
						 | 
				
			
			@ -300,8 +22,7 @@ impl Keyboard {
 | 
			
		|||
        self.memory.write(0x4405, 0x00);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // pub fn read_keys(&self, key: KeyEvent) {
 | 
			
		||||
    pub fn read_keys(&self) {
 | 
			
		||||
    pub fn read_keys(&self, key: Key) {
 | 
			
		||||
        let mut row0 = 0;
 | 
			
		||||
        let mut row1 = 0;
 | 
			
		||||
        let mut row2 = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -309,60 +30,100 @@ impl Keyboard {
 | 
			
		|||
        let mut row4 = 0;
 | 
			
		||||
        let mut row5 = 0;
 | 
			
		||||
 | 
			
		||||
        let modifiers = termion::async_stdin().get_modifiers();
 | 
			
		||||
        for m in modifiers {
 | 
			
		||||
            match m.unwrap() {
 | 
			
		||||
                ControlKey::Shift => row2 ^= 0b1000_0000,
 | 
			
		||||
                ControlKey::Ctrl => row3 ^= 0b1000_0000,
 | 
			
		||||
                ControlKey::Alt => row4 ^= 0b1000_0000,
 | 
			
		||||
                ControlKey::Esc => row0 ^= 0b1000_0000,
 | 
			
		||||
                ControlKey::Backspace => row0 ^= 0b0000_0001,
 | 
			
		||||
                ControlKey::Tab => row1 ^= 0b1000_0000,
 | 
			
		||||
                ControlKey::Enter => row1 ^= 0b0000_0001,
 | 
			
		||||
                _ => {}
 | 
			
		||||
            }
 | 
			
		||||
        // these are just so the match statements are easier to read lol
 | 
			
		||||
        macro_rules! set_shift {
 | 
			
		||||
            ($char:expr) => {
 | 
			
		||||
                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' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '(' | ')' | '~'
 | 
			
		||||
                    | '_' | '+' | '|' | '}' | '{' | '"' | ':' | '?' | '>' | '<' => {
 | 
			
		||||
                        row2 ^= 0b1000_0000
 | 
			
		||||
                    }
 | 
			
		||||
                    _ => {}
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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,
 | 
			
		||||
                _ => {}
 | 
			
		||||
            }
 | 
			
		||||
        macro_rules! set_plain {
 | 
			
		||||
            ($char:expr) => {
 | 
			
		||||
                match $char {
 | 
			
		||||
                    'w' | 'W' => row0 ^= 0b0100_0000,
 | 
			
		||||
                    'e' | 'E' => row0 ^= 0b0010_0000,
 | 
			
		||||
                    'r' | 'R' => row0 ^= 0b0001_0000,
 | 
			
		||||
                    't' | 'T' => row0 ^= 0b0000_1000,
 | 
			
		||||
                    'u' | 'U' => row0 ^= 0b0000_0100,
 | 
			
		||||
                    'o' | 'O' => row0 ^= 0b0000_0010,
 | 
			
		||||
                    'q' | 'Q' => row1 ^= 0b0100_0000,
 | 
			
		||||
                    's' | 'S' => row1 ^= 0b0010_0000,
 | 
			
		||||
                    'g' | 'G' => row1 ^= 0b0001_0000,
 | 
			
		||||
                    'y' | 'Y' => row1 ^= 0b0000_1000,
 | 
			
		||||
                    'i' | 'I' => row1 ^= 0b0000_0100,
 | 
			
		||||
                    'p' | 'P' => row1 ^= 0b0000_0010,
 | 
			
		||||
                    'd' | 'D' => row2 ^= 0b0100_0000,
 | 
			
		||||
                    'v' | 'V' => row2 ^= 0b0010_0000,
 | 
			
		||||
                    'h' | 'H' => row2 ^= 0b0001_0000,
 | 
			
		||||
                    'k' | 'K' => row2 ^= 0b0000_1000,
 | 
			
		||||
                    '\\' | '|' => row2 ^= 0b0000_0100,
 | 
			
		||||
                    '/' | '?' => row2 ^= 0b0000_0010,
 | 
			
		||||
                    'a' | 'A' => row2 ^= 0b0000_0001,
 | 
			
		||||
                    'z' | 'Z' => row3 ^= 0b0100_0000,
 | 
			
		||||
                    'f' | 'F' => row3 ^= 0b0010_0000,
 | 
			
		||||
                    'b' | 'B' => row3 ^= 0b0001_0000,
 | 
			
		||||
                    'j' | 'J' => row3 ^= 0b0000_1000,
 | 
			
		||||
                    'l' | 'L' => row3 ^= 0b0000_0100,
 | 
			
		||||
                    '2' | '@' => row3 ^= 0b0000_0010,
 | 
			
		||||
                    '4' | '$' => row3 ^= 0b0000_0001,
 | 
			
		||||
                    'x' | 'X' => row4 ^= 0b0100_0000,
 | 
			
		||||
                    'c' | 'C' => row4 ^= 0b0010_0000,
 | 
			
		||||
                    'n' | 'N' => row4 ^= 0b0001_0000,
 | 
			
		||||
                    'm' | 'M' => row4 ^= 0b0000_1000,
 | 
			
		||||
                    ',' | '<' => row4 ^= 0b0000_0100,
 | 
			
		||||
                    '1' | '!' => row4 ^= 0b0000_0010,
 | 
			
		||||
                    '3' | '#' => row4 ^= 0b0000_0001,
 | 
			
		||||
                    ' ' => row5 ^= 0b0100_0000,
 | 
			
		||||
                    _ => {}
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        match key {
 | 
			
		||||
            Key::Esc => row0 ^= 0b1000_0000,
 | 
			
		||||
            Key::Backspace => row0 ^= 0b0000_0001,
 | 
			
		||||
            Key::Char('\t') => row1 ^= 0b1000_0000,
 | 
			
		||||
            Key::Char('\n') | Key::Char('\r') => row1 ^= 0b0000_0001,
 | 
			
		||||
            Key::Char(char) => {
 | 
			
		||||
                set_shift!(char);
 | 
			
		||||
                set_plain!(char);
 | 
			
		||||
            }
 | 
			
		||||
            Key::ShiftLeft | Key::ShiftUp | Key::ShiftDown | Key::ShiftRight => row2 ^= 0b1000_0000,
 | 
			
		||||
            Key::Ctrl(char) => {
 | 
			
		||||
                set_shift!(char);
 | 
			
		||||
                set_plain!(char);
 | 
			
		||||
                row3 ^= 0b1000_0000;
 | 
			
		||||
            }
 | 
			
		||||
            Key::CtrlUp | Key::CtrlLeft | Key::CtrlDown | Key::CtrlRight => {
 | 
			
		||||
                row3 ^= 0b1000_0000;
 | 
			
		||||
            }
 | 
			
		||||
            Key::Alt(char) => {
 | 
			
		||||
                set_plain!(char);
 | 
			
		||||
                set_shift!(char);
 | 
			
		||||
                row4 ^= 0b1000_0000;
 | 
			
		||||
            }
 | 
			
		||||
            Key::AltUp | Key::AltLeft | Key::AltDown | Key::AltRight => {
 | 
			
		||||
                row4 ^= 0b1000_0000;
 | 
			
		||||
            }
 | 
			
		||||
            _ => {}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.memory.write(0x4400, row0);
 | 
			
		||||
        self.memory.write(0x4401, row1);
 | 
			
		||||
        self.memory.write(0x4402, row2);
 | 
			
		||||
        self.memory.write(0x4403, row3);
 | 
			
		||||
        self.memory.write(0x4404, row4);
 | 
			
		||||
        self.memory.write(0x4405, row5);
 | 
			
		||||
 | 
			
		||||
        // keeping this list around to make future changes easier
 | 
			
		||||
        // match key.code {
 | 
			
		||||
        //     KeyCode::Esc => row0 ^= 0b1000_0000,
 | 
			
		||||
        //     KeyCode::Char('w') => row0 ^= 0b0100_0000,
 | 
			
		||||
| 
						 | 
				
			
			@ -411,13 +172,6 @@ impl Keyboard {
 | 
			
		|||
        //         row5 = 0;
 | 
			
		||||
        //     }
 | 
			
		||||
        // };
 | 
			
		||||
 | 
			
		||||
        self.memory.write(0x4400, row0);
 | 
			
		||||
        self.memory.write(0x4401, row1);
 | 
			
		||||
        self.memory.write(0x4402, row2);
 | 
			
		||||
        self.memory.write(0x4403, row3);
 | 
			
		||||
        self.memory.write(0x4404, row4);
 | 
			
		||||
        self.memory.write(0x4405, row5);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -430,68 +184,68 @@ impl MemoryWriter for Keyboard {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// impl InputCallback for Keyboard {
 | 
			
		||||
//     fn add_char(&mut self, _uni_char: u32) {}
 | 
			
		||||
//     fn set_key_state(&mut self, key: Key, _state: bool) {
 | 
			
		||||
//         let mut row0 = 0;
 | 
			
		||||
//         let mut row1 = 0;
 | 
			
		||||
//         let mut row2 = 0;
 | 
			
		||||
//         let mut row3 = 0;
 | 
			
		||||
//         let mut row4 = 0;
 | 
			
		||||
//         let mut row5 = 0;
 | 
			
		||||
impl InputCallback for Keyboard {
 | 
			
		||||
    fn add_char(&mut self, _uni_char: u32) {}
 | 
			
		||||
    fn set_key_state(&mut self, key: MKey, _state: bool) {
 | 
			
		||||
        let mut row0 = 0;
 | 
			
		||||
        let mut row1 = 0;
 | 
			
		||||
        let mut row2 = 0;
 | 
			
		||||
        let mut row3 = 0;
 | 
			
		||||
        let mut row4 = 0;
 | 
			
		||||
        let mut row5 = 0;
 | 
			
		||||
 | 
			
		||||
//         match key {
 | 
			
		||||
//             Key::Escape => row0 ^= 0b1000_0000,
 | 
			
		||||
//             Key::W => row0 ^= 0b0100_0000,
 | 
			
		||||
//             Key::E => row0 ^= 0b0010_0000,
 | 
			
		||||
//             Key::R => row0 ^= 0b0001_0000,
 | 
			
		||||
//             Key::T => row0 ^= 0b0000_1000,
 | 
			
		||||
//             Key::U => row0 ^= 0b0000_0100,
 | 
			
		||||
//             Key::O => row0 ^= 0b0000_0010,
 | 
			
		||||
//             Key::Backspace => row0 ^= 0b0000_0001,
 | 
			
		||||
//             Key::Tab => row1 ^= 0b1000_0000,
 | 
			
		||||
//             Key::Q => row1 ^= 0b0100_0000,
 | 
			
		||||
//             Key::S => row1 ^= 0b0010_0000,
 | 
			
		||||
//             Key::G => row1 ^= 0b0001_0000,
 | 
			
		||||
//             Key::Y => row1 ^= 0b0000_1000,
 | 
			
		||||
//             Key::I => row1 ^= 0b0000_0100,
 | 
			
		||||
//             Key::P => row1 ^= 0b0000_0010,
 | 
			
		||||
//             Key::Enter => row1 ^= 0b0000_0001,
 | 
			
		||||
//             Key::LeftShift | Key::RightShift => row2 ^= 0b1000_0000,
 | 
			
		||||
//             Key::D => row2 ^= 0b0100_0000,
 | 
			
		||||
//             Key::V => row2 ^= 0b0010_0000,
 | 
			
		||||
//             Key::H => row2 ^= 0b0001_0000,
 | 
			
		||||
//             Key::K => row2 ^= 0b0000_1000,
 | 
			
		||||
//             Key::Apostrophe => row2 ^= 0b0000_0100,
 | 
			
		||||
//             Key::Slash => row2 ^= 0b0000_0010,
 | 
			
		||||
//             Key::A => row2 ^= 0b0000_0001,
 | 
			
		||||
//             Key::LeftCtrl | Key::RightCtrl => row3 ^= 0b1000_0000,
 | 
			
		||||
//             Key::Z => row3 ^= 0b0100_0000,
 | 
			
		||||
//             Key::F => row3 ^= 0b0010_0000,
 | 
			
		||||
//             Key::B => row3 ^= 0b0001_0000,
 | 
			
		||||
//             Key::J => row3 ^= 0b0000_1000,
 | 
			
		||||
//             Key::L => row3 ^= 0b0000_0100,
 | 
			
		||||
//             Key::Key2 => row3 ^= 0b0000_0010,
 | 
			
		||||
//             Key::Key4 => row3 ^= 0b0000_0001,
 | 
			
		||||
//             Key::LeftAlt | Key::RightAlt => row4 ^= 0b1000_0000,
 | 
			
		||||
//             Key::X => row4 ^= 0b0100_0000,
 | 
			
		||||
//             Key::C => row4 ^= 0b0010_0000,
 | 
			
		||||
//             Key::N => row4 ^= 0b0001_0000,
 | 
			
		||||
//             Key::M => row4 ^= 0b0000_1000,
 | 
			
		||||
//             Key::Comma => row4 ^= 0b0000_0100,
 | 
			
		||||
//             Key::Key1 => row4 ^= 0b0000_0010,
 | 
			
		||||
//             Key::Key3 => row4 ^= 0b0000_0001,
 | 
			
		||||
//             Key::LeftSuper => row5 ^= 0b1000_0000,
 | 
			
		||||
//             Key::Space => row5 ^= 0b0100_0000,
 | 
			
		||||
//             Key::RightSuper => row5 ^= 0b0010_0000,
 | 
			
		||||
//             _ => {}
 | 
			
		||||
//         };
 | 
			
		||||
        match key {
 | 
			
		||||
            MKey::Escape => row0 ^= 0b1000_0000,
 | 
			
		||||
            MKey::W => row0 ^= 0b0100_0000,
 | 
			
		||||
            MKey::E => row0 ^= 0b0010_0000,
 | 
			
		||||
            MKey::R => row0 ^= 0b0001_0000,
 | 
			
		||||
            MKey::T => row0 ^= 0b0000_1000,
 | 
			
		||||
            MKey::U => row0 ^= 0b0000_0100,
 | 
			
		||||
            MKey::O => row0 ^= 0b0000_0010,
 | 
			
		||||
            MKey::Backspace => row0 ^= 0b0000_0001,
 | 
			
		||||
            MKey::Tab => row1 ^= 0b1000_0000,
 | 
			
		||||
            MKey::Q => row1 ^= 0b0100_0000,
 | 
			
		||||
            MKey::S => row1 ^= 0b0010_0000,
 | 
			
		||||
            MKey::G => row1 ^= 0b0001_0000,
 | 
			
		||||
            MKey::Y => row1 ^= 0b0000_1000,
 | 
			
		||||
            MKey::I => row1 ^= 0b0000_0100,
 | 
			
		||||
            MKey::P => row1 ^= 0b0000_0010,
 | 
			
		||||
            MKey::Enter => row1 ^= 0b0000_0001,
 | 
			
		||||
            MKey::LeftShift | MKey::RightShift => row2 ^= 0b1000_0000,
 | 
			
		||||
            MKey::D => row2 ^= 0b0100_0000,
 | 
			
		||||
            MKey::V => row2 ^= 0b0010_0000,
 | 
			
		||||
            MKey::H => row2 ^= 0b0001_0000,
 | 
			
		||||
            MKey::K => row2 ^= 0b0000_1000,
 | 
			
		||||
            MKey::Apostrophe => row2 ^= 0b0000_0100,
 | 
			
		||||
            MKey::Slash => row2 ^= 0b0000_0010,
 | 
			
		||||
            MKey::A => row2 ^= 0b0000_0001,
 | 
			
		||||
            MKey::LeftCtrl | MKey::RightCtrl => row3 ^= 0b1000_0000,
 | 
			
		||||
            MKey::Z => row3 ^= 0b0100_0000,
 | 
			
		||||
            MKey::F => row3 ^= 0b0010_0000,
 | 
			
		||||
            MKey::B => row3 ^= 0b0001_0000,
 | 
			
		||||
            MKey::J => row3 ^= 0b0000_1000,
 | 
			
		||||
            MKey::L => row3 ^= 0b0000_0100,
 | 
			
		||||
            MKey::Key2 => row3 ^= 0b0000_0010,
 | 
			
		||||
            MKey::Key4 => row3 ^= 0b0000_0001,
 | 
			
		||||
            MKey::LeftAlt | MKey::RightAlt => row4 ^= 0b1000_0000,
 | 
			
		||||
            MKey::X => row4 ^= 0b0100_0000,
 | 
			
		||||
            MKey::C => row4 ^= 0b0010_0000,
 | 
			
		||||
            MKey::N => row4 ^= 0b0001_0000,
 | 
			
		||||
            MKey::M => row4 ^= 0b0000_1000,
 | 
			
		||||
            MKey::Comma => row4 ^= 0b0000_0100,
 | 
			
		||||
            MKey::Key1 => row4 ^= 0b0000_0010,
 | 
			
		||||
            MKey::Key3 => row4 ^= 0b0000_0001,
 | 
			
		||||
            MKey::LeftSuper => row5 ^= 0b1000_0000,
 | 
			
		||||
            MKey::Space => row5 ^= 0b0100_0000,
 | 
			
		||||
            MKey::RightSuper => row5 ^= 0b0010_0000,
 | 
			
		||||
            _ => {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
//         self.memory.write(0x4400, row0);
 | 
			
		||||
//         self.memory.write(0x4401, row1);
 | 
			
		||||
//         self.memory.write(0x4402, row2);
 | 
			
		||||
//         self.memory.write(0x4403, row3);
 | 
			
		||||
//         self.memory.write(0x4404, row4);
 | 
			
		||||
//         self.memory.write(0x4405, row5);
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
        self.memory.write(0x4400, row0);
 | 
			
		||||
        self.memory.write(0x4401, row1);
 | 
			
		||||
        self.memory.write(0x4402, row2);
 | 
			
		||||
        self.memory.write(0x4403, row3);
 | 
			
		||||
        self.memory.write(0x4404, row4);
 | 
			
		||||
        self.memory.write(0x4405, row5);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										51
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										51
									
								
								src/main.rs
								
								
								
								
							| 
						 | 
				
			
			@ -13,34 +13,25 @@ use crate::memory::Mem;
 | 
			
		|||
use crate::video::Screen;
 | 
			
		||||
 | 
			
		||||
use cli::get_input;
 | 
			
		||||
// use cpu::CpuController;
 | 
			
		||||
use crossterm::cursor;
 | 
			
		||||
use memory::MemHandle;
 | 
			
		||||
use std::io::{stdin, stdout, Result};
 | 
			
		||||
use std::io::{stdout, Read, Result, Write};
 | 
			
		||||
use std::thread::{self, sleep};
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
use termion::cursor::Goto;
 | 
			
		||||
use termion::event::Key;
 | 
			
		||||
use termion::input::TermRead;
 | 
			
		||||
use termion::raw::IntoRawMode;
 | 
			
		||||
// use termion::raw::IntoRawMode;
 | 
			
		||||
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
 | 
			
		||||
use termion::{self, clear, cursor, screen};
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<()> {
 | 
			
		||||
    let mut stdout = stdout().into_raw_mode().unwrap();
 | 
			
		||||
    // let (cols, rows) = size()?;
 | 
			
		||||
use termion::screen::IntoAlternateScreen;
 | 
			
		||||
use termion::{async_stdin, clear, screen};
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let _stdout = stdout().into_raw_mode();
 | 
			
		||||
    let config = get_input();
 | 
			
		||||
 | 
			
		||||
    let mut memory = Mem::new();
 | 
			
		||||
    let _ = memory.load_rom(&config.rom);
 | 
			
		||||
 | 
			
		||||
    write!(stdout, "{}{}", cursor::Hide, screen::ToAlternateScreen)?;
 | 
			
		||||
 | 
			
		||||
    // execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?;
 | 
			
		||||
    // enable_raw_mode()?;
 | 
			
		||||
 | 
			
		||||
    let shared_memory = MemHandle::new(memory);
 | 
			
		||||
    let screen_memory = shared_memory.clone();
 | 
			
		||||
    let cpu_memory = shared_memory.clone();
 | 
			
		||||
| 
						 | 
				
			
			@ -49,30 +40,32 @@ fn main() -> Result<()> {
 | 
			
		|||
    let keyboard = Keyboard::new(keyboard_memory);
 | 
			
		||||
 | 
			
		||||
    let (mut cpu, cpu_controller) = Cpu::new_with_control(cpu_memory);
 | 
			
		||||
    let _ = cpu.reset();
 | 
			
		||||
    cpu.reset();
 | 
			
		||||
 | 
			
		||||
    thread::spawn(move || loop {
 | 
			
		||||
        cpu.cycle();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let mut screen = Screen::new(&config, cpu_controller, screen_memory);
 | 
			
		||||
    let screen_remote = cpu_controller.clone();
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        keyboard.clear_keys(); // nasty hack until i can figure out a good way of clearing keyboard
 | 
			
		||||
                               // memory when no keys are pressed
 | 
			
		||||
    let mut screen = Screen::new(&config, screen_remote, screen_memory);
 | 
			
		||||
 | 
			
		||||
    let mut stdin = async_stdin().keys();
 | 
			
		||||
    print!("{}{}", cursor::Hide, clear::All,);
 | 
			
		||||
 | 
			
		||||
    'main: loop {
 | 
			
		||||
        screen.draw();
 | 
			
		||||
        // if event::poll(std::time::Duration::from_millis(16))? {
 | 
			
		||||
        keyboard.read_keys();
 | 
			
		||||
        for key in stdin().keys() {
 | 
			
		||||
            match key.unwrap() {
 | 
			
		||||
        if let Some(Ok(key)) = stdin.next() {
 | 
			
		||||
            match key {
 | 
			
		||||
                Key::Char('q') => {
 | 
			
		||||
                    write!(stdout, "{}", clear::All)?;
 | 
			
		||||
                    return Ok(());
 | 
			
		||||
                    break 'main;
 | 
			
		||||
                }
 | 
			
		||||
                _ => {}
 | 
			
		||||
                // Key::Char(' ') => cpu_controller.stop(),
 | 
			
		||||
                // Key::Char('\n') => cpu_controller.resume(),
 | 
			
		||||
                _ => keyboard.read_keys(key),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // }
 | 
			
		||||
        sleep(Duration::from_millis(16));
 | 
			
		||||
    }
 | 
			
		||||
    print!("{}{}{}", clear::All, cursor::Show, Goto(1, 1));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,9 @@
 | 
			
		|||
use anyhow::{bail, Result};
 | 
			
		||||
use core::panic;
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::io::{self, Write};
 | 
			
		||||
use std::path::{Path, PathBuf};
 | 
			
		||||
use std::process::exit;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
use std::str::FromStr;
 | 
			
		||||
use std::sync::{Arc, Mutex};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								src/video.rs
								
								
								
								
							
							
						
						
									
										28
									
								
								src/video.rs
								
								
								
								
							| 
						 | 
				
			
			@ -3,11 +3,13 @@ use serde::{Deserialize, Serialize};
 | 
			
		|||
use termion::{
 | 
			
		||||
    color::{self, Bg, Color, Fg},
 | 
			
		||||
    cursor::Goto,
 | 
			
		||||
    screen::IntoAlternateScreen,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    cli::Config,
 | 
			
		||||
    cpu::CpuController,
 | 
			
		||||
    keyboard::Keyboard,
 | 
			
		||||
    memory::{MemHandle, MemoryReader},
 | 
			
		||||
    types::{Byte, Word},
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +18,8 @@ use std::{
 | 
			
		|||
    io::{self, Read, Write},
 | 
			
		||||
    path::Path,
 | 
			
		||||
    process::exit,
 | 
			
		||||
    time::Instant,
 | 
			
		||||
    thread::sleep,
 | 
			
		||||
    time::{Duration, Instant},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const FG_COLOR: u32 = 0xFFCC00;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,11 +98,10 @@ impl Renderer for WindowRenderer {
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            self.window
 | 
			
		||||
                .update_with_buffer(&buffer, WIDTH, HEIGHT)
 | 
			
		||||
                .unwrap();
 | 
			
		||||
        }
 | 
			
		||||
        self.window
 | 
			
		||||
            .update_with_buffer(&buffer, WIDTH, HEIGHT)
 | 
			
		||||
            .unwrap();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -109,22 +111,16 @@ impl MemoryReader for WindowRenderer {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// pub struct TerminalRenderer<'a> {
 | 
			
		||||
pub struct TerminalRenderer {
 | 
			
		||||
    memory: MemHandle,
 | 
			
		||||
    // stdout: Stdout,
 | 
			
		||||
    // stdout: StdoutLock<'a>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// impl<'a> TerminalRenderer<'a> {
 | 
			
		||||
impl TerminalRenderer {
 | 
			
		||||
    // pub fn new(memory: MemHandle, stdout: StdoutLock<'a>) -> Self {
 | 
			
		||||
    pub fn new(memory: MemHandle) -> Self {
 | 
			
		||||
        Self { memory }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// impl MemoryReader for TerminalRenderer<'_> {
 | 
			
		||||
impl MemoryReader for TerminalRenderer {
 | 
			
		||||
    fn read(&self, address: Word) -> Byte {
 | 
			
		||||
        self.memory.read(address)
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +144,6 @@ const ASCII_LOOPUP: [&str; 256] = [
 | 
			
		|||
    "", "", "", "", "🎁", "", "", "", "", "⚐", "⚑", "", "", "",
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
// impl Renderer for TerminalRenderer<'_> {
 | 
			
		||||
impl Renderer for TerminalRenderer {
 | 
			
		||||
    fn render(&mut self) {
 | 
			
		||||
        let mut stdout = io::stdout();
 | 
			
		||||
| 
						 | 
				
			
			@ -172,10 +167,8 @@ impl Renderer for TerminalRenderer {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// pub struct Screen<'a> {
 | 
			
		||||
pub struct Screen {
 | 
			
		||||
    renderer: Box<dyn Renderer>,
 | 
			
		||||
    // renderer: TerminalRenderer<'a>,
 | 
			
		||||
    controller: CpuController,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +176,7 @@ impl Screen {
 | 
			
		|||
    pub fn new(config: &Config, controller: CpuController, memory: MemHandle) -> Self {
 | 
			
		||||
        let renderer: Box<dyn Renderer> = match config.screen {
 | 
			
		||||
            ScreenType::Window => {
 | 
			
		||||
                let window = Window::new(
 | 
			
		||||
                let mut window = Window::new(
 | 
			
		||||
                    "ʕ·ᴥ·ʔ-☆",
 | 
			
		||||
                    512,
 | 
			
		||||
                    380,
 | 
			
		||||
| 
						 | 
				
			
			@ -192,13 +185,14 @@ impl Screen {
 | 
			
		|||
                        borderless: true,
 | 
			
		||||
                        title: true,
 | 
			
		||||
                        transparency: false,
 | 
			
		||||
                        scale: Scale::X2,
 | 
			
		||||
                        scale: Scale::FitScreen,
 | 
			
		||||
                        scale_mode: ScaleMode::AspectRatioStretch,
 | 
			
		||||
                        topmost: false,
 | 
			
		||||
                        none: true,
 | 
			
		||||
                    },
 | 
			
		||||
                )
 | 
			
		||||
                .unwrap();
 | 
			
		||||
                window.set_input_callback(Box::new(Keyboard::new(memory.clone())));
 | 
			
		||||
                Box::new(WindowRenderer::new(memory, config.char_rom.clone(), window))
 | 
			
		||||
            }
 | 
			
		||||
            ScreenType::Terminal => Box::new(TerminalRenderer::new(memory)),
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +204,7 @@ impl Screen {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn draw(&mut self) {
 | 
			
		||||
        self.controller.irq();
 | 
			
		||||
        // self.controller.irq();
 | 
			
		||||
        self.renderer.render();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue