mirror of
https://github.com/mre/mos6502.git
synced 2025-01-13 19:29:51 +00:00
Add no_std support
This commit is contained in:
parent
d5e9281969
commit
5ee12bdbc0
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
Cargo.lock
|
|
||||||
*.a
|
*.a
|
||||||
*.aux
|
*.aux
|
||||||
*.bc
|
*.bc
|
||||||
|
383
Cargo.lock
generated
Normal file
383
Cargo.lock
generated
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace-sys"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytecount"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-chain"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon-sys"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mos6502"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"skeptic 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-complex"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-iter"
|
||||||
|
version = "0.1.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "remove_dir_all"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.80"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.80"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "skeptic"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "0.15.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempdir"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
|
||||||
|
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
|
||||||
|
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||||
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
|
"checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8"
|
||||||
|
"checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0"
|
||||||
|
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
|
||||||
|
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||||
|
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||||
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
|
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||||
|
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
|
||||||
|
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
|
||||||
|
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||||
|
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
|
||||||
|
"checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8"
|
||||||
|
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||||
|
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
|
||||||
|
"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10"
|
||||||
|
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||||
|
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
|
||||||
|
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
||||||
|
"checksum quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5829244f52738cfee93b3a165c1911388675be000c888d2fae620dee8fa5b"
|
||||||
|
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
|
||||||
|
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||||
|
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
|
||||||
|
"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
|
||||||
|
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
|
||||||
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
|
||||||
|
"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
|
||||||
|
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
|
||||||
|
"checksum skeptic 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4474d6da9593171bcb086890fc344a3a12783cb24e5b141f8a5d0e43561f4b6"
|
||||||
|
"checksum syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)" = "90c39a061e2f412a9f869540471ab679e85e50c6b05604daf28bc3060f75c430"
|
||||||
|
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
|
"checksum walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ffb549f212c31e19f3667c55a7f515b983a84aef10fd0a4d1f9c125425115f3"
|
||||||
|
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||||
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
|
||||||
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
21
Cargo.toml
21
Cargo.toml
@ -30,18 +30,25 @@
|
|||||||
name = "mos6502"
|
name = "mos6502"
|
||||||
description = "A MOS 6502 Emulator"
|
description = "A MOS 6502 Emulator"
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
version = "0.0.1"
|
version = "0.1.0"
|
||||||
authors = ["The 6502-rs Developers"]
|
authors = ["The 6502-rs Developers"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
# This will look in src/lib.rs
|
# This will look in src/lib.rs
|
||||||
name = "mos6502"
|
name = "mos6502"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
# This will look in src/bin/mos6502.rs
|
|
||||||
name = "mos6502"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "0.9.1"
|
bitflags = "0.9.1"
|
||||||
log = "0.3.8"
|
log = "0.4.6"
|
||||||
num = "0.1"
|
|
||||||
|
[dependencies.num]
|
||||||
|
version = "0.2"
|
||||||
|
# no_std support
|
||||||
|
default-features = false
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
skeptic = "0.13"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
skeptic = "0.13"
|
||||||
|
108
README.md
108
README.md
@ -7,3 +7,111 @@ This started off as a fork of [6502-rs](https://github.com/amw-zero/6502-rs),
|
|||||||
which seems to be unmaintained at this point.
|
which seems to be unmaintained at this point.
|
||||||
|
|
||||||
It builds with the latest stable Rust.
|
It builds with the latest stable Rust.
|
||||||
|
|
||||||
|
## Usage example
|
||||||
|
|
||||||
|
```rust
|
||||||
|
extern crate mos6502;
|
||||||
|
|
||||||
|
use mos6502::cpu;
|
||||||
|
use mos6502::address::Address;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut cpu = cpu::CPU::new();
|
||||||
|
|
||||||
|
let zero_page_data = [
|
||||||
|
// ZeroPage data start
|
||||||
|
0x00,
|
||||||
|
0x02, // ADC ZeroPage target
|
||||||
|
0x00,
|
||||||
|
0x04, // ADC ZeroPageX target
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x10, // ADC IndexedIndirectX address
|
||||||
|
0x80, // ADC IndexedIndirectX address
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x08, // ADC IndirectIndexedY address
|
||||||
|
0x80, // ADC IndirectIndexedY address
|
||||||
|
];
|
||||||
|
|
||||||
|
let program = [
|
||||||
|
// Code start
|
||||||
|
0xA9, // LDA Immediate
|
||||||
|
0x01, // Immediate operand
|
||||||
|
0x69, // ADC Immediate
|
||||||
|
0x07, // Immediate operand
|
||||||
|
0x65, // ADC ZeroPage
|
||||||
|
0x01, // ZeroPage operand
|
||||||
|
0xA2, // LDX Immediate
|
||||||
|
0x01, // Immediate operand
|
||||||
|
0x75, // ADC ZeroPageX
|
||||||
|
0x02, // ZeroPageX operand
|
||||||
|
0x6D, // ADC Absolute
|
||||||
|
0x01, // Absolute operand
|
||||||
|
0x80, // Absolute operand
|
||||||
|
0xA2, // LDX immediate
|
||||||
|
0x08, // Immediate operand
|
||||||
|
0x7D, // ADC AbsoluteX
|
||||||
|
0x00, // AbsoluteX operand
|
||||||
|
0x80, // AbsoluteX operand
|
||||||
|
0xA0, // LDY immediate
|
||||||
|
0x04, // Immediate operand
|
||||||
|
0x79, // ADC AbsoluteY
|
||||||
|
0x00, // AbsoluteY operand
|
||||||
|
0x80, // AbsoluteY operand
|
||||||
|
0xA2, // LDX immediate
|
||||||
|
0x05, // Immediate operand
|
||||||
|
0x61, // ADC IndexedIndirectX
|
||||||
|
0x03, // IndexedIndirectX operand
|
||||||
|
0xA0, // LDY immediate
|
||||||
|
0x10, // Immediate operand
|
||||||
|
0x71, // ADC IndirectIndexedY
|
||||||
|
0x0F, // IndirectIndexedY operand
|
||||||
|
0xEA, // NOP :)
|
||||||
|
0xFF, // Something invalid -- the end!
|
||||||
|
];
|
||||||
|
|
||||||
|
let data: [u8; 25] = [
|
||||||
|
0x00,
|
||||||
|
0x09, // ADC Absolute target
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x40, // ADC AbsoluteY target
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x11, // ADC AbsoluteX target
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x12, // ADC IndexedIndirectX target
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x06, // ADC IndirectIndexedY target
|
||||||
|
];
|
||||||
|
|
||||||
|
// "Load" a program
|
||||||
|
cpu.memory.set_bytes(Address(0x0000), &zero_page_data);
|
||||||
|
cpu.memory.set_bytes(Address(0x4000), &program);
|
||||||
|
cpu.memory.set_bytes(Address(0x8000), &data);
|
||||||
|
|
||||||
|
cpu.registers.program_counter = Address(0x4000);
|
||||||
|
|
||||||
|
cpu.run();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
5
build.rs
Normal file
5
build.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extern crate skeptic;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
skeptic::generate_doc_tests(&["README.md"]);
|
||||||
|
}
|
@ -25,7 +25,7 @@
|
|||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
use std::ops::Add;
|
use core::ops::Add;
|
||||||
|
|
||||||
// The idea here is that it doesn't make sense to add two addresses, but it
|
// The idea here is that it doesn't make sense to add two addresses, but it
|
||||||
// does make sense to add an address and an "address-difference". (If this
|
// does make sense to add an address and an "address-difference". (If this
|
||||||
@ -42,8 +42,7 @@ impl Add<AddressDiff> for Address {
|
|||||||
fn add(self, AddressDiff(rhs): AddressDiff) -> Address {
|
fn add(self, AddressDiff(rhs): AddressDiff) -> Address {
|
||||||
let Address(lhs) = self;
|
let Address(lhs) = self;
|
||||||
|
|
||||||
// TODO akeeton: Do a checked cast.
|
Address(((i32::from(lhs)) + rhs) as u16)
|
||||||
Address(((lhs as i32) + rhs) as u16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +39,8 @@ fn main() {
|
|||||||
|
|
||||||
// "Load" a program
|
// "Load" a program
|
||||||
|
|
||||||
// JAM: FIXME: What's the syntax for specifying the array element type,
|
|
||||||
// but not the length? (For a fixed-size array)
|
|
||||||
|
|
||||||
let zero_page_data: [u8; 17] = [
|
let zero_page_data = [
|
||||||
// ZeroPage data start
|
// ZeroPage data start
|
||||||
0x00,
|
0x00,
|
||||||
0x02, // ADC ZeroPage target
|
0x02, // ADC ZeroPage target
|
||||||
@ -63,7 +61,7 @@ fn main() {
|
|||||||
0x80, // ADC IndirectIndexedY address
|
0x80, // ADC IndirectIndexedY address
|
||||||
];
|
];
|
||||||
|
|
||||||
let program: [u8; 33] = [
|
let program = [
|
||||||
// Code start
|
// Code start
|
||||||
0xA9, // LDA Immediate
|
0xA9, // LDA Immediate
|
||||||
0x01, // Immediate operand
|
0x01, // Immediate operand
|
||||||
@ -100,7 +98,7 @@ fn main() {
|
|||||||
0xFF, // Something invalid -- the end!
|
0xFF, // Something invalid -- the end!
|
||||||
];
|
];
|
||||||
|
|
||||||
let data: [u8; 25] = [
|
let data = [
|
||||||
0x00,
|
0x00,
|
||||||
0x09, // ADC Absolute target
|
0x09, // ADC Absolute target
|
||||||
0x00,
|
0x00,
|
661
src/cpu.rs
661
src/cpu.rs
@ -25,15 +25,14 @@
|
|||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
use std;
|
|
||||||
|
|
||||||
use address::{Address, AddressDiff};
|
use address::{Address, AddressDiff};
|
||||||
use instruction;
|
use instruction;
|
||||||
use instruction::{DecodedInstr, Instruction, OpInput};
|
use instruction::{DecodedInstr, Instruction, OpInput};
|
||||||
use memory::Memory;
|
use memory::Memory;
|
||||||
use registers::{Registers, StackPointer, Status, StatusArgs};
|
use registers::{Registers, StackPointer, Status, StatusArgs};
|
||||||
use registers::{PS_CARRY, PS_DECIMAL_MODE, PS_DISABLE_INTERRUPTS, PS_NEGATIVE, PS_OVERFLOW,
|
use registers::{
|
||||||
PS_ZERO};
|
PS_CARRY, PS_DECIMAL_MODE, PS_DISABLE_INTERRUPTS, PS_NEGATIVE, PS_OVERFLOW, PS_ZERO,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CPU {
|
pub struct CPU {
|
||||||
@ -410,12 +409,8 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
loop {
|
while let Some(decoded_instr) = self.fetch_next_and_decode() {
|
||||||
if let Some(decoded_instr) = self.fetch_next_and_decode() {
|
|
||||||
self.execute_instruction(decoded_instr);
|
self.execute_instruction(decoded_instr);
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,8 +753,8 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for CPU {
|
impl core::fmt::Debug for CPU {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"CPU Dump:\n\nAccumulator: {}",
|
"CPU Dump:\n\nAccumulator: {}",
|
||||||
@ -776,385 +771,385 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_with_carry_test() {
|
fn add_with_carry_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.add_with_carry(1);
|
cpu.add_with_carry(1);
|
||||||
assert_eq!(CPU.registers.accumulator, 1);
|
assert_eq!(cpu.registers.accumulator, 1);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.add_with_carry(-1);
|
cpu.add_with_carry(-1);
|
||||||
assert_eq!(CPU.registers.accumulator, 0);
|
assert_eq!(cpu.registers.accumulator, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.add_with_carry(1);
|
cpu.add_with_carry(1);
|
||||||
assert_eq!(CPU.registers.accumulator, 2);
|
assert_eq!(cpu.registers.accumulator, 2);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.add_with_carry(127);
|
cpu.add_with_carry(127);
|
||||||
assert_eq!(CPU.registers.accumulator, 127);
|
assert_eq!(cpu.registers.accumulator, 127);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.add_with_carry(-127);
|
cpu.add_with_carry(-127);
|
||||||
assert_eq!(CPU.registers.accumulator, 0);
|
assert_eq!(cpu.registers.accumulator, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.registers.status.remove(PS_CARRY);
|
cpu.registers.status.remove(PS_CARRY);
|
||||||
CPU.add_with_carry(-128);
|
cpu.add_with_carry(-128);
|
||||||
assert_eq!(CPU.registers.accumulator, -128);
|
assert_eq!(cpu.registers.accumulator, -128);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.add_with_carry(127);
|
cpu.add_with_carry(127);
|
||||||
assert_eq!(CPU.registers.accumulator, -1);
|
assert_eq!(cpu.registers.accumulator, -1);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.add_with_carry(127);
|
cpu.add_with_carry(127);
|
||||||
assert_eq!(CPU.registers.accumulator, 127);
|
assert_eq!(cpu.registers.accumulator, 127);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.add_with_carry(1);
|
cpu.add_with_carry(1);
|
||||||
assert_eq!(CPU.registers.accumulator, -128);
|
assert_eq!(cpu.registers.accumulator, -128);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), true);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn and_test() {
|
fn and_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.registers.accumulator = 0;
|
cpu.registers.accumulator = 0;
|
||||||
CPU.and(-1);
|
cpu.and(-1);
|
||||||
assert_eq!(CPU.registers.accumulator, 0);
|
assert_eq!(cpu.registers.accumulator, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
|
|
||||||
CPU.registers.accumulator = -1;
|
cpu.registers.accumulator = -1;
|
||||||
CPU.and(0);
|
cpu.and(0);
|
||||||
assert_eq!(CPU.registers.accumulator, 0);
|
assert_eq!(cpu.registers.accumulator, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
|
|
||||||
CPU.registers.accumulator = -1;
|
cpu.registers.accumulator = -1;
|
||||||
CPU.and(0x0f);
|
cpu.and(0x0f);
|
||||||
assert_eq!(CPU.registers.accumulator, 0x0f);
|
assert_eq!(cpu.registers.accumulator, 0x0f);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
|
|
||||||
CPU.registers.accumulator = -1;
|
cpu.registers.accumulator = -1;
|
||||||
CPU.and(-128);
|
cpu.and(-128);
|
||||||
assert_eq!(CPU.registers.accumulator, -128);
|
assert_eq!(cpu.registers.accumulator, -128);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subtract_with_carry_test() {
|
fn subtract_with_carry_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
||||||
CPU.registers.accumulator = 0;
|
cpu.registers.accumulator = 0;
|
||||||
|
|
||||||
CPU.subtract_with_carry(1);
|
cpu.subtract_with_carry(1);
|
||||||
assert_eq!(CPU.registers.accumulator, -1);
|
assert_eq!(cpu.registers.accumulator, -1);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
||||||
CPU.registers.accumulator = -128;
|
cpu.registers.accumulator = -128;
|
||||||
CPU.subtract_with_carry(1);
|
cpu.subtract_with_carry(1);
|
||||||
assert_eq!(CPU.registers.accumulator, 127);
|
assert_eq!(cpu.registers.accumulator, 127);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), true);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), true);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
||||||
CPU.registers.accumulator = 127;
|
cpu.registers.accumulator = 127;
|
||||||
CPU.subtract_with_carry(-1);
|
cpu.subtract_with_carry(-1);
|
||||||
assert_eq!(CPU.registers.accumulator, -128);
|
assert_eq!(cpu.registers.accumulator, -128);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), true);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), true);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
||||||
CPU.registers.accumulator = -64;
|
cpu.registers.accumulator = -64;
|
||||||
CPU.subtract_with_carry(64);
|
cpu.subtract_with_carry(64);
|
||||||
assert_eq!(CPU.registers.accumulator, 127);
|
assert_eq!(cpu.registers.accumulator, 127);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), true);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), true);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
||||||
CPU.registers.accumulator = 0;
|
cpu.registers.accumulator = 0;
|
||||||
CPU.subtract_with_carry(-128);
|
cpu.subtract_with_carry(-128);
|
||||||
assert_eq!(CPU.registers.accumulator, -128);
|
assert_eq!(cpu.registers.accumulator, -128);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), true);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), true);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
||||||
CPU.registers.accumulator = 0;
|
cpu.registers.accumulator = 0;
|
||||||
CPU.subtract_with_carry(127);
|
cpu.subtract_with_carry(127);
|
||||||
assert_eq!(CPU.registers.accumulator, -128);
|
assert_eq!(cpu.registers.accumulator, -128);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decrement_memory_test() {
|
fn decrement_memory_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
let addr = Address(0xA1B2);
|
let addr = Address(0xA1B2);
|
||||||
|
|
||||||
CPU.memory.set_byte(addr, 5);
|
cpu.memory.set_byte(addr, 5);
|
||||||
|
|
||||||
CPU.decrement_memory(addr);
|
cpu.decrement_memory(addr);
|
||||||
assert_eq!(CPU.memory.get_byte(addr), 4);
|
assert_eq!(cpu.memory.get_byte(addr), 4);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
|
|
||||||
CPU.decrement_memory(addr);
|
cpu.decrement_memory(addr);
|
||||||
assert_eq!(CPU.memory.get_byte(addr), 3);
|
assert_eq!(cpu.memory.get_byte(addr), 3);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
|
|
||||||
CPU.decrement_memory(addr);
|
cpu.decrement_memory(addr);
|
||||||
CPU.decrement_memory(addr);
|
cpu.decrement_memory(addr);
|
||||||
CPU.decrement_memory(addr);
|
cpu.decrement_memory(addr);
|
||||||
assert_eq!(CPU.memory.get_byte(addr), 0);
|
assert_eq!(cpu.memory.get_byte(addr), 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
|
|
||||||
CPU.decrement_memory(addr);
|
cpu.decrement_memory(addr);
|
||||||
assert_eq!(CPU.memory.get_byte(addr) as i8, -1);
|
assert_eq!(cpu.memory.get_byte(addr) as i8, -1);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn logical_shift_right_test() {
|
fn logical_shift_right_test() {
|
||||||
// Testing UseImplied version (which targets the accumulator) only, for now
|
// Testing UseImplied version (which targets the accumulator) only, for now
|
||||||
|
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
CPU.execute_instruction((Instruction::LDA, OpInput::UseImmediate(0)));
|
cpu.execute_instruction((Instruction::LDA, OpInput::UseImmediate(0)));
|
||||||
CPU.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
||||||
assert_eq!(CPU.registers.accumulator, 0);
|
assert_eq!(cpu.registers.accumulator, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::LDA, OpInput::UseImmediate(1)));
|
cpu.execute_instruction((Instruction::LDA, OpInput::UseImmediate(1)));
|
||||||
CPU.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
||||||
assert_eq!(CPU.registers.accumulator, 0);
|
assert_eq!(cpu.registers.accumulator, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::LDA, OpInput::UseImmediate(255)));
|
cpu.execute_instruction((Instruction::LDA, OpInput::UseImmediate(255)));
|
||||||
CPU.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
||||||
assert_eq!(CPU.registers.accumulator, 0x7F);
|
assert_eq!(cpu.registers.accumulator, 0x7F);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), true);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::LDA, OpInput::UseImmediate(254)));
|
cpu.execute_instruction((Instruction::LDA, OpInput::UseImmediate(254)));
|
||||||
CPU.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::LSR, OpInput::UseImplied));
|
||||||
assert_eq!(CPU.registers.accumulator, 0x7F);
|
assert_eq!(cpu.registers.accumulator, 0x7F);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dec_x_test() {
|
fn dec_x_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
assert_eq!(CPU.registers.index_x, -1);
|
assert_eq!(cpu.registers.index_x, -1);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
assert_eq!(CPU.registers.index_x, -2);
|
assert_eq!(cpu.registers.index_x, -2);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.load_x_register(5);
|
cpu.load_x_register(5);
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
assert_eq!(CPU.registers.index_x, 4);
|
assert_eq!(cpu.registers.index_x, 4);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
|
|
||||||
assert_eq!(CPU.registers.index_x, 0);
|
assert_eq!(cpu.registers.index_x, 0);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), true);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), false);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
|
|
||||||
CPU.dec_x();
|
cpu.dec_x();
|
||||||
assert_eq!(CPU.registers.index_x, -1);
|
assert_eq!(cpu.registers.index_x, -1);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_CARRY), false);
|
assert_eq!(cpu.registers.status.contains(PS_CARRY), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_ZERO), false);
|
assert_eq!(cpu.registers.status.contains(PS_ZERO), false);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_NEGATIVE), true);
|
assert_eq!(cpu.registers.status.contains(PS_NEGATIVE), true);
|
||||||
assert_eq!(CPU.registers.status.contains(PS_OVERFLOW), false);
|
assert_eq!(cpu.registers.status.contains(PS_OVERFLOW), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn jump_test() {
|
fn jump_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
let addr = Address(0xA1B1);
|
let addr = Address(0xA1B1);
|
||||||
|
|
||||||
CPU.jump(addr);
|
cpu.jump(addr);
|
||||||
assert_eq!(CPU.registers.program_counter, addr);
|
assert_eq!(cpu.registers.program_counter, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_carry_clear_test() {
|
fn branch_if_carry_clear_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
||||||
CPU.branch_if_carry_clear(Address(0xABCD));
|
cpu.branch_if_carry_clear(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
||||||
CPU.branch_if_carry_clear(Address(0xABCD));
|
cpu.branch_if_carry_clear(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_carry_set_test() {
|
fn branch_if_carry_set_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::CLC, OpInput::UseImplied));
|
||||||
CPU.branch_if_carry_set(Address(0xABCD));
|
cpu.branch_if_carry_set(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
|
|
||||||
CPU.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
cpu.execute_instruction((Instruction::SEC, OpInput::UseImplied));
|
||||||
CPU.branch_if_carry_set(Address(0xABCD));
|
cpu.branch_if_carry_set(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_equal_test() {
|
fn branch_if_equal_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.branch_if_equal(Address(0xABCD));
|
cpu.branch_if_equal(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
|
|
||||||
CPU.registers.status.or(PS_ZERO);
|
cpu.registers.status.or(PS_ZERO);
|
||||||
CPU.branch_if_equal(Address(0xABCD));
|
cpu.branch_if_equal(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_minus_test() {
|
fn branch_if_minus_test() {
|
||||||
{
|
{
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
let registers_before = CPU.registers;
|
let registers_before = cpu.registers;
|
||||||
|
|
||||||
CPU.branch_if_minus(Address(0xABCD));
|
cpu.branch_if_minus(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers, registers_before);
|
assert_eq!(cpu.registers, registers_before);
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.registers.status.or(PS_NEGATIVE);
|
cpu.registers.status.or(PS_NEGATIVE);
|
||||||
let registers_before = CPU.registers;
|
let registers_before = cpu.registers;
|
||||||
|
|
||||||
CPU.branch_if_minus(Address(0xABCD));
|
cpu.branch_if_minus(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.status, registers_before.status);
|
assert_eq!(cpu.registers.status, registers_before.status);
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_positive_test() {
|
fn branch_if_positive_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.registers.status.insert(PS_NEGATIVE);
|
cpu.registers.status.insert(PS_NEGATIVE);
|
||||||
CPU.branch_if_positive(Address(0xABCD));
|
cpu.branch_if_positive(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
|
|
||||||
CPU.registers.status.remove(PS_NEGATIVE);
|
cpu.registers.status.remove(PS_NEGATIVE);
|
||||||
CPU.branch_if_positive(Address(0xABCD));
|
cpu.branch_if_positive(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_overflow_clear_test() {
|
fn branch_if_overflow_clear_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.registers.status.insert(PS_OVERFLOW);
|
cpu.registers.status.insert(PS_OVERFLOW);
|
||||||
CPU.branch_if_overflow_clear(Address(0xABCD));
|
cpu.branch_if_overflow_clear(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
|
|
||||||
CPU.registers.status.remove(PS_OVERFLOW);
|
cpu.registers.status.remove(PS_OVERFLOW);
|
||||||
CPU.branch_if_overflow_clear(Address(0xABCD));
|
cpu.branch_if_overflow_clear(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn branch_if_overflow_set_test() {
|
fn branch_if_overflow_set_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.branch_if_overflow_set(Address(0xABCD));
|
cpu.branch_if_overflow_set(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0));
|
assert_eq!(cpu.registers.program_counter, Address(0));
|
||||||
|
|
||||||
CPU.registers.status.insert(PS_OVERFLOW);
|
cpu.registers.status.insert(PS_OVERFLOW);
|
||||||
CPU.branch_if_overflow_set(Address(0xABCD));
|
cpu.branch_if_overflow_set(Address(0xABCD));
|
||||||
assert_eq!(CPU.registers.program_counter, Address(0xABCD));
|
assert_eq!(cpu.registers.program_counter, Address(0xABCD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -1162,61 +1157,56 @@ mod tests {
|
|||||||
where
|
where
|
||||||
F: FnMut(&mut CPU, u8),
|
F: FnMut(&mut CPU, u8),
|
||||||
{
|
{
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
CPU.execute_instruction((load_instruction, OpInput::UseImmediate(127)));
|
cpu.execute_instruction((load_instruction, OpInput::UseImmediate(127)));
|
||||||
|
|
||||||
compare(&mut CPU, 127);
|
compare(&mut cpu, 127);
|
||||||
assert!(CPU.registers.status.contains(PS_ZERO));
|
assert!(cpu.registers.status.contains(PS_ZERO));
|
||||||
assert!(CPU.registers.status.contains(PS_CARRY));
|
assert!(cpu.registers.status.contains(PS_CARRY));
|
||||||
assert!(!CPU.registers.status.contains(PS_NEGATIVE));
|
assert!(!cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
|
|
||||||
|
cpu.execute_instruction((load_instruction, OpInput::UseImmediate(127)));
|
||||||
|
|
||||||
CPU.execute_instruction((load_instruction, OpInput::UseImmediate(127)));
|
compare(&mut cpu, 1);
|
||||||
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
|
assert!(cpu.registers.status.contains(PS_CARRY));
|
||||||
|
assert!(!cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
|
|
||||||
compare(&mut CPU, 1);
|
cpu.execute_instruction((load_instruction, OpInput::UseImmediate(1)));
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
|
||||||
assert!(CPU.registers.status.contains(PS_CARRY));
|
|
||||||
assert!(!CPU.registers.status.contains(PS_NEGATIVE));
|
|
||||||
|
|
||||||
|
compare(&mut cpu, 2);
|
||||||
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
|
assert!(!cpu.registers.status.contains(PS_CARRY));
|
||||||
|
assert!(cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
|
|
||||||
CPU.execute_instruction((load_instruction, OpInput::UseImmediate(1)));
|
cpu.execute_instruction((load_instruction, OpInput::UseImmediate(20)));
|
||||||
|
|
||||||
compare(&mut CPU, 2);
|
compare(&mut cpu, -50i8 as u8);
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
assert!(!CPU.registers.status.contains(PS_CARRY));
|
assert!(!cpu.registers.status.contains(PS_CARRY));
|
||||||
assert!(CPU.registers.status.contains(PS_NEGATIVE));
|
assert!(!cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
|
|
||||||
|
cpu.execute_instruction((load_instruction, OpInput::UseImmediate(1)));
|
||||||
|
|
||||||
CPU.execute_instruction((load_instruction, OpInput::UseImmediate(20)));
|
compare(&mut cpu, -1i8 as u8);
|
||||||
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
|
assert!(!cpu.registers.status.contains(PS_CARRY));
|
||||||
|
assert!(!cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
|
|
||||||
compare(&mut CPU, -50i8 as u8);
|
cpu.execute_instruction((load_instruction, OpInput::UseImmediate(127)));
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
|
||||||
assert!(!CPU.registers.status.contains(PS_CARRY));
|
|
||||||
assert!(!CPU.registers.status.contains(PS_NEGATIVE));
|
|
||||||
|
|
||||||
|
compare(&mut cpu, -128i8 as u8);
|
||||||
CPU.execute_instruction((load_instruction, OpInput::UseImmediate(1)));
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
|
assert!(!cpu.registers.status.contains(PS_CARRY));
|
||||||
compare(&mut CPU, -1i8 as u8);
|
assert!(cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
|
||||||
assert!(!CPU.registers.status.contains(PS_CARRY));
|
|
||||||
assert!(!CPU.registers.status.contains(PS_NEGATIVE));
|
|
||||||
|
|
||||||
|
|
||||||
CPU.execute_instruction((load_instruction, OpInput::UseImmediate(127)));
|
|
||||||
|
|
||||||
compare(&mut CPU, -128i8 as u8);
|
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
|
||||||
assert!(!CPU.registers.status.contains(PS_CARRY));
|
|
||||||
assert!(CPU.registers.status.contains(PS_NEGATIVE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare_with_a_register_test() {
|
fn compare_with_a_register_test() {
|
||||||
compare_test_helper(
|
compare_test_helper(
|
||||||
&mut |CPU: &mut CPU, val: u8| {
|
&mut |cpu: &mut CPU, val: u8| {
|
||||||
CPU.compare_with_a_register(val);
|
cpu.compare_with_a_register(val);
|
||||||
},
|
},
|
||||||
Instruction::LDA,
|
Instruction::LDA,
|
||||||
);
|
);
|
||||||
@ -1225,8 +1215,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn compare_with_x_register_test() {
|
fn compare_with_x_register_test() {
|
||||||
compare_test_helper(
|
compare_test_helper(
|
||||||
&mut |CPU: &mut CPU, val: u8| {
|
&mut |cpu: &mut CPU, val: u8| {
|
||||||
CPU.compare_with_x_register(val);
|
cpu.compare_with_x_register(val);
|
||||||
},
|
},
|
||||||
Instruction::LDX,
|
Instruction::LDX,
|
||||||
);
|
);
|
||||||
@ -1235,8 +1225,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn compare_with_y_register_test() {
|
fn compare_with_y_register_test() {
|
||||||
compare_test_helper(
|
compare_test_helper(
|
||||||
&mut |CPU: &mut CPU, val: u8| {
|
&mut |cpu: &mut CPU, val: u8| {
|
||||||
CPU.compare_with_y_register(val);
|
cpu.compare_with_y_register(val);
|
||||||
},
|
},
|
||||||
Instruction::LDY,
|
Instruction::LDY,
|
||||||
);
|
);
|
||||||
@ -1244,27 +1234,27 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exclusive_or_test() {
|
fn exclusive_or_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
for a_before in range_inclusive(0u8, 255u8) {
|
for a_before in range_inclusive(0u8, 255u8) {
|
||||||
for val in range_inclusive(0u8, 255u8) {
|
for val in range_inclusive(0u8, 255u8) {
|
||||||
CPU.execute_instruction((Instruction::LDA, OpInput::UseImmediate(a_before)));
|
cpu.execute_instruction((Instruction::LDA, OpInput::UseImmediate(a_before)));
|
||||||
|
|
||||||
CPU.exclusive_or(val);
|
cpu.exclusive_or(val);
|
||||||
|
|
||||||
let a_after = a_before ^ val;
|
let a_after = a_before ^ val;
|
||||||
assert_eq!(CPU.registers.accumulator, a_after as i8);
|
assert_eq!(cpu.registers.accumulator, a_after as i8);
|
||||||
|
|
||||||
if a_after == 0 {
|
if a_after == 0 {
|
||||||
assert!(CPU.registers.status.contains(PS_ZERO));
|
assert!(cpu.registers.status.contains(PS_ZERO));
|
||||||
} else {
|
} else {
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_after as i8) < 0 {
|
if (a_after as i8) < 0 {
|
||||||
assert!(CPU.registers.status.contains(PS_NEGATIVE));
|
assert!(cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
} else {
|
} else {
|
||||||
assert!(!CPU.registers.status.contains(PS_NEGATIVE));
|
assert!(!cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1272,29 +1262,30 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inclusive_or_test() {
|
fn inclusive_or_test() {
|
||||||
let mut CPU = CPU::new();
|
let mut cpu = CPU::new();
|
||||||
|
|
||||||
for a_before in range_inclusive(0u8, 255u8) {
|
for a_before in range_inclusive(0u8, 255u8) {
|
||||||
for val in range_inclusive(0u8, 255u8) {
|
for val in range_inclusive(0u8, 255u8) {
|
||||||
CPU.execute_instruction((Instruction::LDA, OpInput::UseImmediate(a_before)));
|
cpu.execute_instruction((Instruction::LDA, OpInput::UseImmediate(a_before)));
|
||||||
|
|
||||||
CPU.inclusive_or(val);
|
cpu.inclusive_or(val);
|
||||||
|
|
||||||
let a_after = a_before | val;
|
let a_after = a_before | val;
|
||||||
assert_eq!(CPU.registers.accumulator, a_after as i8);
|
assert_eq!(cpu.registers.accumulator, a_after as i8);
|
||||||
|
|
||||||
if a_after == 0 {
|
if a_after == 0 {
|
||||||
assert!(CPU.registers.status.contains(PS_ZERO));
|
assert!(cpu.registers.status.contains(PS_ZERO));
|
||||||
} else {
|
} else {
|
||||||
assert!(!CPU.registers.status.contains(PS_ZERO));
|
assert!(!cpu.registers.status.contains(PS_ZERO));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_after as i8) < 0 {
|
if (a_after as i8) < 0 {
|
||||||
assert!(CPU.registers.status.contains(PS_NEGATIVE));
|
assert!(cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
} else {
|
} else {
|
||||||
assert!(!CPU.registers.status.contains(PS_NEGATIVE));
|
assert!(!cpu.registers.status.contains(PS_NEGATIVE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ pub enum AddressingMode {
|
|||||||
fn arr_to_addr(arr: &[u8]) -> Address {
|
fn arr_to_addr(arr: &[u8]) -> Address {
|
||||||
debug_assert!(arr.len() == 2);
|
debug_assert!(arr.len() == 2);
|
||||||
|
|
||||||
let x = (arr[0] as u16) + ((arr[1] as u16) << 8usize);
|
let x = u16::from(arr[0]) + (u16::from(arr[1]) << 8usize);
|
||||||
Address(x)
|
Address(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,19 +187,19 @@ impl AddressingMode {
|
|||||||
// Use [u8, ..1] from instruction
|
// Use [u8, ..1] from instruction
|
||||||
// Interpret as zero page address
|
// Interpret as zero page address
|
||||||
// (Output: an 8-bit zero-page address)
|
// (Output: an 8-bit zero-page address)
|
||||||
OpInput::UseAddress(Address(arr[0] as u16))
|
OpInput::UseAddress(Address(u16::from(arr[0])))
|
||||||
}
|
}
|
||||||
AddressingMode::ZeroPageX => {
|
AddressingMode::ZeroPageX => {
|
||||||
// Use [u8, ..1] from instruction
|
// Use [u8, ..1] from instruction
|
||||||
// Add to X register (as u8 -- the final address is in 0-page)
|
// Add to X register (as u8 -- the final address is in 0-page)
|
||||||
// (Output: an 8-bit zero-page address)
|
// (Output: an 8-bit zero-page address)
|
||||||
OpInput::UseAddress(Address((arr[0] + x) as u16))
|
OpInput::UseAddress(Address(u16::from(arr[0] + x)))
|
||||||
}
|
}
|
||||||
AddressingMode::ZeroPageY => {
|
AddressingMode::ZeroPageY => {
|
||||||
// Use [u8, ..1] from instruction
|
// Use [u8, ..1] from instruction
|
||||||
// Add to Y register (as u8 -- the final address is in 0-page)
|
// Add to Y register (as u8 -- the final address is in 0-page)
|
||||||
// (Output: an 8-bit zero-page address)
|
// (Output: an 8-bit zero-page address)
|
||||||
OpInput::UseAddress(Address((arr[0] + y) as u16))
|
OpInput::UseAddress(Address(u16::from(arr[0] + y)))
|
||||||
}
|
}
|
||||||
AddressingMode::Relative => {
|
AddressingMode::Relative => {
|
||||||
// Use [u8, ..1] from instruction
|
// Use [u8, ..1] from instruction
|
||||||
@ -214,12 +214,12 @@ impl AddressingMode {
|
|||||||
AddressingMode::AbsoluteX => {
|
AddressingMode::AbsoluteX => {
|
||||||
// Use [u8, ..2] from instruction as address, add X
|
// Use [u8, ..2] from instruction as address, add X
|
||||||
// (Output: a 16-bit address)
|
// (Output: a 16-bit address)
|
||||||
OpInput::UseAddress(arr_to_addr(arr) + AddressDiff(x as i32))
|
OpInput::UseAddress(arr_to_addr(arr) + AddressDiff(i32::from(x)))
|
||||||
}
|
}
|
||||||
AddressingMode::AbsoluteY => {
|
AddressingMode::AbsoluteY => {
|
||||||
// Use [u8, ..2] from instruction as address, add Y
|
// Use [u8, ..2] from instruction as address, add Y
|
||||||
// (Output: a 16-bit address)
|
// (Output: a 16-bit address)
|
||||||
OpInput::UseAddress(arr_to_addr(arr) + AddressDiff(y as i32))
|
OpInput::UseAddress(arr_to_addr(arr) + AddressDiff(i32::from(y)))
|
||||||
}
|
}
|
||||||
AddressingMode::Indirect => {
|
AddressingMode::Indirect => {
|
||||||
// Use [u8, ..2] from instruction as an address. Interpret the
|
// Use [u8, ..2] from instruction as an address. Interpret the
|
||||||
@ -234,7 +234,7 @@ impl AddressingMode {
|
|||||||
// This is where the absolute (16-bit) target address is stored.
|
// This is where the absolute (16-bit) target address is stored.
|
||||||
// (Output: a 16-bit address)
|
// (Output: a 16-bit address)
|
||||||
let start = arr[0] + x;
|
let start = arr[0] + x;
|
||||||
let slice = memory.get_slice(Address(start as u16), AddressDiff(2));
|
let slice = memory.get_slice(Address(u16::from(start)), AddressDiff(2));
|
||||||
OpInput::UseAddress(arr_to_addr(slice))
|
OpInput::UseAddress(arr_to_addr(slice))
|
||||||
}
|
}
|
||||||
AddressingMode::IndirectIndexedY => {
|
AddressingMode::IndirectIndexedY => {
|
||||||
@ -243,8 +243,8 @@ impl AddressingMode {
|
|||||||
// Add Y register to this address to get the final address
|
// Add Y register to this address to get the final address
|
||||||
// (Output: a 16-bit address)
|
// (Output: a 16-bit address)
|
||||||
let start = arr[0];
|
let start = arr[0];
|
||||||
let slice = memory.get_slice(Address(start as u16), AddressDiff(2));
|
let slice = memory.get_slice(Address(u16::from(start)), AddressDiff(2));
|
||||||
OpInput::UseAddress(arr_to_addr(slice) + AddressDiff(y as i32))
|
OpInput::UseAddress(arr_to_addr(slice) + AddressDiff(i32::from(y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// Needed for debug! / log! macros
|
#![no_std]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
@ -35,7 +36,8 @@ extern crate num;
|
|||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
|
||||||
pub mod address;
|
pub mod address;
|
||||||
pub mod instruction;
|
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
|
pub mod instruction;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod registers;
|
pub mod registers;
|
||||||
|
|
||||||
|
@ -58,17 +58,17 @@ impl StatusArgs {
|
|||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct Status: u8 {
|
pub struct Status: u8 {
|
||||||
const PS_NEGATIVE = 0b10000000;
|
const PS_NEGATIVE = 0b1000_0000;
|
||||||
const PS_OVERFLOW = 0b01000000;
|
const PS_OVERFLOW = 0b0100_0000;
|
||||||
const PS_UNUSED = 0b00100000; // JAM: Should this exist?
|
const PS_UNUSED = 0b0010_0000; // JAM: Should this exist?
|
||||||
// (note that it affects the
|
// (note that it affects the
|
||||||
// behavior of things like
|
// behavior of things like
|
||||||
// from_bits_truncate)
|
// from_bits_truncate)
|
||||||
const PS_BRK = 0b00010000;
|
const PS_BRK = 0b0001_0000;
|
||||||
const PS_DECIMAL_MODE = 0b00001000;
|
const PS_DECIMAL_MODE = 0b0000_1000;
|
||||||
const PS_DISABLE_INTERRUPTS = 0b00000100;
|
const PS_DISABLE_INTERRUPTS = 0b0000_0100;
|
||||||
const PS_ZERO = 0b00000010;
|
const PS_ZERO = 0b0000_0010;
|
||||||
const PS_CARRY = 0b00000001;
|
const PS_CARRY = 0b0000_0001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,39 +100,39 @@ impl Status {
|
|||||||
let mut out = Status::empty();
|
let mut out = Status::empty();
|
||||||
|
|
||||||
if negative {
|
if negative {
|
||||||
out = out | PS_NEGATIVE
|
out |= PS_NEGATIVE
|
||||||
}
|
}
|
||||||
if overflow {
|
if overflow {
|
||||||
out = out | PS_OVERFLOW
|
out |= PS_OVERFLOW
|
||||||
}
|
}
|
||||||
if unused {
|
if unused {
|
||||||
out = out | PS_UNUSED
|
out |= PS_UNUSED
|
||||||
}
|
}
|
||||||
if brk {
|
if brk {
|
||||||
out = out | PS_BRK
|
out |= PS_BRK
|
||||||
}
|
}
|
||||||
if decimal_mode {
|
if decimal_mode {
|
||||||
out = out | PS_DECIMAL_MODE
|
out |= PS_DECIMAL_MODE
|
||||||
}
|
}
|
||||||
if disable_interrupts {
|
if disable_interrupts {
|
||||||
out = out | PS_DISABLE_INTERRUPTS
|
out |= PS_DISABLE_INTERRUPTS
|
||||||
}
|
}
|
||||||
if zero {
|
if zero {
|
||||||
out = out | PS_ZERO
|
out |= PS_ZERO
|
||||||
}
|
}
|
||||||
if carry {
|
if carry {
|
||||||
out = out | PS_CARRY
|
out |= PS_CARRY
|
||||||
}
|
}
|
||||||
|
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn and(&mut self, rhs: Status) {
|
pub fn and(&mut self, rhs: Status) {
|
||||||
*self = *self & rhs;
|
*self &= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn or(&mut self, rhs: Status) {
|
pub fn or(&mut self, rhs: Status) {
|
||||||
*self = *self | rhs;
|
*self |= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_with_mask(&mut self, mask: Status, rhs: Status) {
|
pub fn set_with_mask(&mut self, mask: Status, rhs: Status) {
|
||||||
@ -146,7 +146,7 @@ pub struct StackPointer(pub u8);
|
|||||||
impl StackPointer {
|
impl StackPointer {
|
||||||
pub fn to_address(&self) -> Address {
|
pub fn to_address(&self) -> Address {
|
||||||
let StackPointer(sp) = *self;
|
let StackPointer(sp) = *self;
|
||||||
STACK_ADDRESS_LO + AddressDiff(sp as i32)
|
STACK_ADDRESS_LO + AddressDiff(i32::from(sp))
|
||||||
}
|
}
|
||||||
|
|
||||||
// JAM: FIXME: Should we prevent overflow here? What would a 6502 do?
|
// JAM: FIXME: Should we prevent overflow here? What would a 6502 do?
|
||||||
|
1
tests/skeptic.rs
Normal file
1
tests/skeptic.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs"));
|
Loading…
x
Reference in New Issue
Block a user