mirror of
https://github.com/BlueTheDuck/crustacean_6502_emulator.git
synced 2025-01-13 22:31:00 +00:00
+10000 lines changed: First commit
This commit is contained in:
commit
e66085eb25
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
**/*.rs.bk
|
429
Cargo.lock
generated
Normal file
429
Cargo.lock
generated
Normal file
@ -0,0 +1,429 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "atk"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atk-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cairo-sys-rs"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "crustacean_6502_emulator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cairo-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gtk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cairo-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-pixbuf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cairo-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-pixbuf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gtk-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk-sys"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango-sys"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0-alpha.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum atk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "444daefa55f229af145ea58d77efd23725024ee1f6f3102743709aa6b18c663e"
|
||||
"checksum atk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e552c1776737a4c80110d06b36d099f47c727335f9aaa5d942a72b6863a8ec6f"
|
||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
"checksum cairo-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b528aca2ef1026235d0122495dbaee0b09479f77c51f6df8d9bb9cb1c6d6f87"
|
||||
"checksum cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff65ba02cac715be836f63429ab00a767d48336efc5497c5637afb53b4f14d63"
|
||||
"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
|
||||
"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86"
|
||||
"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866"
|
||||
"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231"
|
||||
"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff"
|
||||
"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764"
|
||||
"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9"
|
||||
"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
|
||||
"checksum gdk 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2739c12374f83bad563ee839c2b3ea5c60391465a254fd4a54b6e3e9648dc61f"
|
||||
"checksum gdk-pixbuf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e248220c46b329b097d4b158d2717f8c688f16dd76d0399ace82b3e98062bdd7"
|
||||
"checksum gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d8991b060a9e9161bafd09bf4a202e6fd404f5b4dd1a08d53a1e84256fb34ab0"
|
||||
"checksum gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6adf679e91d1bff0c06860287f80403e7db54c2d2424dce0a470023b56c88fbb"
|
||||
"checksum gio 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "879a5eb1a91623819d658669104fb587c1ae68695d50947f3e4949a00c6bc218"
|
||||
"checksum gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4fad225242b9eae7ec8a063bb86974aca56885014672375e5775dc0ea3533911"
|
||||
"checksum glib 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "121c502fc6895e62d2ce084e677d3289ccbdd7f56edd4ac9a5ab8bd95d4a8670"
|
||||
"checksum glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "95856f3802f446c05feffa5e24859fe6a183a7cb849c8449afc35c86b1e316e2"
|
||||
"checksum gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31d1a804f62034eccf370006ccaef3708a71c31d561fee88564abe71177553d9"
|
||||
"checksum gtk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cd1d646cc9a2cb795f33b538779a3f22e71dc172f2aba08a41e84a2f72c0dec"
|
||||
"checksum gtk-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53def660c7b48b00b510c81ef2d2fbd3c570f1527081d8d7947f471513e1a4c1"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
"checksum pango 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9c6b728f1be8edb5f9f981420b651d5ea30bdb9de89f1f1262d0084a020577"
|
||||
"checksum pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86b93d84907b3cf0819bff8f13598ba72843bee579d5ebc2502e4b0367b4be7d"
|
||||
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
|
||||
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||
"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
|
||||
"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
|
||||
"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
|
||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "crustacean_6502_emulator"
|
||||
version = "0.1.0"
|
||||
authors = ["PeronTheDuck <pedroignacioperezvargas@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
gtk = "0.8.0"
|
||||
glib = "0.9.0"
|
||||
gio = "*"
|
||||
cairo-rs = "*"
|
BIN
src/color.hex
Normal file
BIN
src/color.hex
Normal file
Binary file not shown.
32
src/emulator/addr
Normal file
32
src/emulator/addr
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
# ___0 _0__
|
||||
A 0__0 1010
|
||||
--------abs---------
|
||||
|
||||
abs ___0 11__
|
||||
absX ___1 11__
|
||||
absY ___1 1___
|
||||
--------------------
|
||||
rel 0000 ___1
|
||||
--------ind---------
|
||||
ind ___a bb0c
|
||||
a b c
|
||||
ind 0 1 0
|
||||
X 0 0 1
|
||||
Y 1 0 1
|
||||
|
||||
_: opcode?
|
||||
|
||||
ind 0110 1100
|
||||
Xind ___0 0001
|
||||
indY ___1 0001
|
||||
--------------------
|
||||
zpg ___0 01__
|
||||
zpgX ___1 01__
|
||||
zpgY 10_1 0110
|
||||
|
||||
|
||||
|
||||
___a bb_c
|
||||
c => uses X|Y
|
||||
a => x / y
|
24
src/emulator/addressing_modes.rs
Normal file
24
src/emulator/addressing_modes.rs
Normal file
@ -0,0 +1,24 @@
|
||||
pub fn get_size(addr_mode: AddressingMode) -> usize {
|
||||
OP_SIZES[addr_mode as usize]
|
||||
}
|
||||
|
||||
//A,abs,absX,absY,imm,impl,ind,indX,indY,rel,zpg,zpgX,zpgY
|
||||
//1, 3, 3, 3, 2, 1, 3, 2, 2, 2, 2, 2, 2
|
||||
pub static OP_SIZES: [usize; 13] = [1, 3, 3, 3, 2, 1, 3, 2, 2, 2, 2, 2, 2];
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum AddressingMode {
|
||||
A = 0, // LSR A
|
||||
ABS, // LDA $1234
|
||||
ABSX, // STA $3000,X
|
||||
ABSY, // AND $4000,Y
|
||||
IMM, // LDA #$10
|
||||
IMPL, // CLC
|
||||
IND, // JMP ($FFFC)
|
||||
INDX, // LDA ($40,X)
|
||||
INDY, // LDA ($40),Y
|
||||
REL, // LABEL // +4
|
||||
ZPG, // LDA $10
|
||||
ZPGX, // LDA $10,X
|
||||
ZPGY, // LDA $10,Y
|
||||
}
|
145
src/emulator/emulator.rs
Normal file
145
src/emulator/emulator.rs
Normal file
@ -0,0 +1,145 @@
|
||||
use super::error;
|
||||
use super::opcodes;
|
||||
use super::OpcodeType;
|
||||
use super::{addressing_modes::get_size, AddressingMode};
|
||||
|
||||
fn invalid_mode<T>(mode_used: AddressingMode) -> T {
|
||||
panic!("The addressign mode used ({:?}) is either not valid for this opcode, or expects an argument which was not provided",mode_used)
|
||||
}
|
||||
|
||||
macro_rules! fetch {
|
||||
($self:ident PC+$off:expr) => {
|
||||
$self.ram[$self.cpu.PC as usize + $off]
|
||||
};
|
||||
($self:ident $addr:expr) => {
|
||||
$self.ram[$addr as usize]
|
||||
};
|
||||
($self:ident D $addr:expr) => {
|
||||
($self.ram[$addr as usize + 1] as u16) << 8 | $self.ram[$addr as usize] as u16
|
||||
};
|
||||
}
|
||||
|
||||
pub struct Emulator {
|
||||
pub cycles: usize,
|
||||
pub ram: [u8; 0x10000],
|
||||
pub cpu: Cpu,
|
||||
}
|
||||
impl Emulator {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
cycles: 0,
|
||||
ram: [0x00; 0x10000],
|
||||
cpu: Cpu::default(),
|
||||
}
|
||||
}
|
||||
pub fn step(&mut self) -> Result<(), error::EmulatorError> {
|
||||
println!("Step on {:04X}", self.cpu.PC);
|
||||
let code = self.ram[self.cpu.PC as usize];
|
||||
let code = match opcodes::from_code(code) {
|
||||
None => return Err(error::EmulatorError::UnknownOp(code)),
|
||||
Some(v) => v,
|
||||
};
|
||||
println!(" Opcode {:?}", code.name);
|
||||
let arg: Option<u16> = match code.addr_mode {
|
||||
AddressingMode::IMPL => None,
|
||||
AddressingMode::A => None,
|
||||
AddressingMode::IMM => {
|
||||
let addr = fetch!(self PC+1);
|
||||
Some(addr as u16)
|
||||
}
|
||||
AddressingMode::ABS => {
|
||||
let addr = self.cpu.PC as usize + 1;
|
||||
Some(fetch!(self D addr) as u16)
|
||||
}
|
||||
AddressingMode::ZPG => {
|
||||
let addr = self.cpu.PC as usize + 1;
|
||||
Some(fetch!(self addr) as u16)
|
||||
}
|
||||
_ => {
|
||||
unimplemented!("Unimplemented addressing mode {:?}", code.addr_mode);
|
||||
}
|
||||
};
|
||||
println!(" Argument: {:#04X?}", arg);
|
||||
match code.name {
|
||||
OpcodeType::BRK => {
|
||||
println!("Stepped on break. Ending");
|
||||
println!("{:#?}", self.cpu);
|
||||
return Err(error::EmulatorError::Break);
|
||||
}
|
||||
OpcodeType::LDA => match code.addr_mode {
|
||||
AddressingMode::IMM => {
|
||||
self.cpu.A = arg.unwrap_or_else(|| invalid_mode(code.addr_mode)) as u8
|
||||
}
|
||||
AddressingMode::ABS => {
|
||||
self.cpu.A = fetch!(self arg.unwrap_or_else(||invalid_mode(code.addr_mode)))
|
||||
}
|
||||
AddressingMode::ZPG => {
|
||||
self.cpu.A = fetch!(self arg.unwrap_or_else(||invalid_mode(code.addr_mode)))
|
||||
}
|
||||
_ => panic!("Invalid addressing mode for {:?}", code.name),
|
||||
},
|
||||
OpcodeType::STA => match code.addr_mode {
|
||||
AddressingMode::ABS => {
|
||||
self.ram[arg.unwrap_or_else(|| invalid_mode(code.addr_mode)) as usize] =
|
||||
self.cpu.A
|
||||
}
|
||||
_ => panic!("Invalid addressing mode for {:?}", code.name),
|
||||
},
|
||||
OpcodeType::ADC => match code.addr_mode {
|
||||
AddressingMode::IMM => {
|
||||
self.cpu.A += arg.unwrap_or_else(|| invalid_mode(code.addr_mode)) as u8
|
||||
}
|
||||
_ => panic!("Invalid addressing mode for {:?}", code.name),
|
||||
},
|
||||
OpcodeType::JMP => match code.addr_mode {
|
||||
AddressingMode::ABS => {
|
||||
self.cpu.PC = arg.unwrap_or_else(|| invalid_mode(code.addr_mode)) as u16
|
||||
}
|
||||
_ => panic!("Invalid addressing mode for {:?}", code.name),
|
||||
},
|
||||
_ => {
|
||||
unimplemented!(
|
||||
"Unimplemented opcode {:?} with {:?}",
|
||||
code.name,
|
||||
code.addr_mode
|
||||
);
|
||||
}
|
||||
}
|
||||
if code.name != OpcodeType::JMP {
|
||||
self.cpu.PC += get_size(code.addr_mode) as u16;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn restart(&mut self) {
|
||||
self.cycles = 0;
|
||||
self.ram = [0x00; 0x10000];
|
||||
self.cpu = Cpu::default();
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Cpu {
|
||||
A: u8,
|
||||
X: u8,
|
||||
Y: u8,
|
||||
PC: u16,
|
||||
}
|
||||
impl std::default::Default for Cpu {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
A: 0x00,
|
||||
X: 0x00,
|
||||
Y: 0x00,
|
||||
PC: 0x0600,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::fmt::Debug for Cpu {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
write!(
|
||||
f,
|
||||
"Registers: \n PC: {:04X}\n A: {:02X} X: {:02X} Y: {:02X}\n",
|
||||
self.PC, self.A, self.X, self.Y,
|
||||
)
|
||||
}
|
||||
}
|
25
src/emulator/error.rs
Normal file
25
src/emulator/error.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use std::boxed::Box;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Error as FmtError, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EmulatorError {
|
||||
UnknownOp(u8),
|
||||
Break,
|
||||
Suberror(Box<dyn Error>),
|
||||
}
|
||||
|
||||
impl Display for EmulatorError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
write!(
|
||||
f,
|
||||
"Emulator Error: {}",
|
||||
match self {
|
||||
EmulatorError::Suberror(e) => e.description().to_string(),
|
||||
EmulatorError::Break => "Emulator Terminated".to_string(),
|
||||
EmulatorError::UnknownOp(code) => format!("Unknown OP with code {:02X}", code),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
impl Error for EmulatorError {}
|
8
src/emulator/mod.rs
Normal file
8
src/emulator/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
pub mod error;
|
||||
|
||||
mod addressing_modes;
|
||||
use addressing_modes::AddressingMode;
|
||||
mod opcodes;
|
||||
use opcodes::OpcodeType;
|
||||
mod emulator;
|
||||
pub use emulator::Emulator;
|
883
src/emulator/opcodes.rs
Normal file
883
src/emulator/opcodes.rs
Normal file
@ -0,0 +1,883 @@
|
||||
use super::addressing_modes::AddressingMode;
|
||||
|
||||
pub const OPCODES: [Option<OpcodeData>; 0x100] = [
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BRK,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ASL,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::PHP,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ASL,
|
||||
addr_mode: AddressingMode::A,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ASL,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BPL,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ASL,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CLC,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ORA,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ASL,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::JSR,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BIT,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROL,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::PLP,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROL,
|
||||
addr_mode: AddressingMode::A,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BIT,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROL,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BMI,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROL,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SEC,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::AND,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROL,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::RTI,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LSR,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::PHA,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LSR,
|
||||
addr_mode: AddressingMode::A,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::JMP,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LSR,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BVC,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LSR,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CLI,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::EOR,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LSR,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::RTS,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROR,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::PLA,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROR,
|
||||
addr_mode: AddressingMode::A,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::JMP,
|
||||
addr_mode: AddressingMode::IND,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROR,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BVS,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROR,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SEI,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ADC,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::ROR,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STY,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STX,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::DEY,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::TXA,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STY,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STX,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BCC,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STY,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STX,
|
||||
addr_mode: AddressingMode::ZPGY,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::TYA,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::TXS,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::STA,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDY,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDX,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDY,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDX,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::TAY,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::TAX,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDY,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDX,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BCS,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDY,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDX,
|
||||
addr_mode: AddressingMode::ZPGY,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CLV,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::TSX,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDY,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDA,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::LDX,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CPY,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CPY,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::DEC,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::INY,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::DEX,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CPY,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::DEC,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BNE,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::DEC,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CLD,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CMP,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::DEC,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CPX,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::INDX,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CPX,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::INC,
|
||||
addr_mode: AddressingMode::ZPG,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::INX,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::IMM,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::NOP,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::CPX,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::INC,
|
||||
addr_mode: AddressingMode::ABS,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::BEQ,
|
||||
addr_mode: AddressingMode::REL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::INDY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::INC,
|
||||
addr_mode: AddressingMode::ZPGX,
|
||||
}),
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SED,
|
||||
addr_mode: AddressingMode::IMPL,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::ABSY,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::SBC,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
Some(OpcodeData {
|
||||
name: OpcodeType::INC,
|
||||
addr_mode: AddressingMode::ABSX,
|
||||
}),
|
||||
None,
|
||||
];
|
||||
/* pub fn get_code(name: OpcodeType, addr_mode: AddressingMode) -> Result<u8, Error> {
|
||||
for (i, opcode) in OPCODES.iter().enumerate() {
|
||||
match opcode {
|
||||
None => continue,
|
||||
Some(ref opcode) => {
|
||||
if opcode.name == name && opcode.addr_mode == addr_mode {
|
||||
return Ok((i & 0xFF) as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(Error::UnkownOpcode { name: name.into() })
|
||||
} */
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum OpcodeType {
|
||||
ADC,
|
||||
AND,
|
||||
ASL,
|
||||
BCC, // Branch ops
|
||||
BCS, // Branch ops
|
||||
BEQ, // Branch ops
|
||||
BIT,
|
||||
BMI, // Branch ops
|
||||
BNE, // Branch ops
|
||||
BPL, // Branch ops
|
||||
BRK,
|
||||
BVC, // Branch ops
|
||||
BVS, // Branch ops
|
||||
CLC,
|
||||
CLD,
|
||||
CLI,
|
||||
CLV,
|
||||
CMP,
|
||||
CPX,
|
||||
CPY,
|
||||
DEC,
|
||||
DEX,
|
||||
DEY,
|
||||
EOR,
|
||||
INC,
|
||||
INX,
|
||||
INY,
|
||||
JMP,
|
||||
JSR,
|
||||
LDA,
|
||||
LDX,
|
||||
LDY,
|
||||
LSR,
|
||||
NOP,
|
||||
ORA,
|
||||
PHA,
|
||||
PHP,
|
||||
PLA,
|
||||
PLP,
|
||||
ROL,
|
||||
ROR,
|
||||
RTI,
|
||||
RTS,
|
||||
SBC,
|
||||
SEC,
|
||||
SED,
|
||||
SEI,
|
||||
STA,
|
||||
STX,
|
||||
STY,
|
||||
TAX,
|
||||
TAY,
|
||||
TSX,
|
||||
TXA,
|
||||
TXS,
|
||||
TYA,
|
||||
}
|
||||
impl OpcodeType {
|
||||
pub fn identify<'s, S: std::ops::Deref<Target = &'s str>>(
|
||||
string: &S,
|
||||
) -> Result<OpcodeType, ()> {
|
||||
match **string {
|
||||
"ADC" => Ok(OpcodeType::ADC),
|
||||
"AND" => Ok(OpcodeType::AND),
|
||||
"ASL" => Ok(OpcodeType::ASL),
|
||||
"BCC" => Ok(OpcodeType::BCC),
|
||||
"BCS" => Ok(OpcodeType::BCS),
|
||||
"BEQ" => Ok(OpcodeType::BEQ),
|
||||
"BIT" => Ok(OpcodeType::BIT),
|
||||
"BMI" => Ok(OpcodeType::BMI),
|
||||
"BNE" => Ok(OpcodeType::BNE),
|
||||
"BPL" => Ok(OpcodeType::BPL),
|
||||
"BRK" => Ok(OpcodeType::BRK),
|
||||
"BVC" => Ok(OpcodeType::BVC),
|
||||
"BVS" => Ok(OpcodeType::BVS),
|
||||
"CLC" => Ok(OpcodeType::CLC),
|
||||
"CLD" => Ok(OpcodeType::CLD),
|
||||
"CLI" => Ok(OpcodeType::CLI),
|
||||
"CLV" => Ok(OpcodeType::CLV),
|
||||
"CMP" => Ok(OpcodeType::CMP),
|
||||
"CPX" => Ok(OpcodeType::CPX),
|
||||
"CPY" => Ok(OpcodeType::CPY),
|
||||
"DEC" => Ok(OpcodeType::DEC),
|
||||
"DEX" => Ok(OpcodeType::DEX),
|
||||
"DEY" => Ok(OpcodeType::DEY),
|
||||
"EOR" => Ok(OpcodeType::EOR),
|
||||
"INC" => Ok(OpcodeType::INC),
|
||||
"INX" => Ok(OpcodeType::INX),
|
||||
"INY" => Ok(OpcodeType::INY),
|
||||
"JMP" => Ok(OpcodeType::JMP),
|
||||
"JSR" => Ok(OpcodeType::JSR),
|
||||
"LDA" => Ok(OpcodeType::LDA),
|
||||
"LDX" => Ok(OpcodeType::LDX),
|
||||
"LDY" => Ok(OpcodeType::LDY),
|
||||
"LSR" => Ok(OpcodeType::LSR),
|
||||
"NOP" => Ok(OpcodeType::NOP),
|
||||
"ORA" => Ok(OpcodeType::ORA),
|
||||
"PHA" => Ok(OpcodeType::PHA),
|
||||
"PHP" => Ok(OpcodeType::PHP),
|
||||
"PLA" => Ok(OpcodeType::PLA),
|
||||
"PLP" => Ok(OpcodeType::PLP),
|
||||
"ROL" => Ok(OpcodeType::ROL),
|
||||
"ROR" => Ok(OpcodeType::ROR),
|
||||
"RTI" => Ok(OpcodeType::RTI),
|
||||
"RTS" => Ok(OpcodeType::RTS),
|
||||
"SBC" => Ok(OpcodeType::SBC),
|
||||
"SEC" => Ok(OpcodeType::SEC),
|
||||
"SED" => Ok(OpcodeType::SED),
|
||||
"SEI" => Ok(OpcodeType::SEI),
|
||||
"STA" => Ok(OpcodeType::STA),
|
||||
"STX" => Ok(OpcodeType::STX),
|
||||
"STY" => Ok(OpcodeType::STY),
|
||||
"TAX" => Ok(OpcodeType::TAX),
|
||||
"TAY" => Ok(OpcodeType::TAY),
|
||||
"TSX" => Ok(OpcodeType::TSX),
|
||||
"TXA" => Ok(OpcodeType::TXA),
|
||||
"TXS" => Ok(OpcodeType::TXS),
|
||||
"TYA" => Ok(OpcodeType::TYA),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
pub fn is_branch_op(self) -> bool {
|
||||
use OpcodeType::*;
|
||||
let branch_ops = [BCC, BCS, BEQ, BMI, BNE, BPL, BVC, BVS];
|
||||
branch_ops.contains(&self)
|
||||
}
|
||||
}
|
||||
impl std::convert::Into<String> for OpcodeType {
|
||||
fn into(self) -> String {
|
||||
format!("{:?}", self)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct OpcodeData {
|
||||
pub name: OpcodeType,
|
||||
pub addr_mode: AddressingMode,
|
||||
}
|
||||
|
||||
pub fn from_code(code: u8) -> Option<OpcodeData> {
|
||||
OPCODES[code as usize]
|
||||
}
|
||||
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_opcode_name() {
|
||||
use super::OpcodeType;
|
||||
let strings = vec![("LDA", true), ("STA", true), ("JMP", true), ("xd", false)];
|
||||
for (string, is_ok) in strings.iter() {
|
||||
let res = OpcodeType::identify(&string);
|
||||
println!("{} -> {:?}", string, res);
|
||||
assert_eq!(res.is_ok(), *is_ok);
|
||||
}
|
||||
}
|
||||
}
|
56
src/emulator/ops
Normal file
56
src/emulator/ops
Normal file
@ -0,0 +1,56 @@
|
||||
ADC 011A AA01
|
||||
AND 001A AA01
|
||||
ASL 000A AA10
|
||||
BCC 1001 0000
|
||||
BCS 1011 0000
|
||||
BEQ 1111 0000
|
||||
BIT 0010 A100
|
||||
BMI 0011 0000
|
||||
BNE 1101 0000
|
||||
BPL 0001 0000
|
||||
BRK 0000 0000
|
||||
BVC 0101 0000
|
||||
BVS 0111 0000
|
||||
CLC 0001 1000
|
||||
CLD 1101 1000
|
||||
CLI 0101 1000
|
||||
CLV 1011 1000
|
||||
CMP 110A AA01
|
||||
CPA 1110 AA00
|
||||
CPY 1100 AA00
|
||||
DEC 110A A110
|
||||
DEA 1100 1010
|
||||
DEY 1000 1000
|
||||
EOR 010A AA01
|
||||
INC 111A A110
|
||||
INA 1110 1000
|
||||
INY 1100 1000
|
||||
JMP 01A0 1100
|
||||
JSR 0010 0000
|
||||
LDA 10AA AA01
|
||||
LDA 101A AA10
|
||||
LDY 101A AA00
|
||||
LSR 010A AA10
|
||||
NOP 1110 1010
|
||||
ORA 000A AA01
|
||||
PHA 0100 1000
|
||||
PHP 0000 1000
|
||||
PLA 0110 1000
|
||||
PLP 0010 1000
|
||||
ROL 001A AA10
|
||||
ROR 011A AA10
|
||||
RTI 0100 0000
|
||||
RTS 0110 0000
|
||||
SBC 111A AA01
|
||||
SEC 0011 1000
|
||||
SED 1111 1000
|
||||
SEI 0111 0000
|
||||
STA 100A AA01
|
||||
STA 100A A110
|
||||
STY 100A A100
|
||||
TAA 1010 1010
|
||||
TAY 1010 1000
|
||||
TSA 1011 1010
|
||||
TAA 1000 1010
|
||||
TAS 1001 1010
|
||||
TYA 1001 1000
|
24
src/error.rs
Normal file
24
src/error.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProgErr(Box<dyn Error>);
|
||||
impl std::fmt::Display for ProgErr {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
write!(fmt, "Error:\n\t{}", self.0)
|
||||
}
|
||||
}
|
||||
impl std::error::Error for ProgErr {}
|
||||
|
||||
macro_rules! prog_err {
|
||||
( $( $type: ty ),* ) => {
|
||||
$(
|
||||
impl std::convert::From<$type> for ProgErr {
|
||||
fn from(e: $type) -> Self {
|
||||
Self(Box::from(e))
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
prog_err!(glib::BoolError, crate::emulator::error::EmulatorError);
|
75
src/graphic/mod.rs
Normal file
75
src/graphic/mod.rs
Normal file
@ -0,0 +1,75 @@
|
||||
pub struct Image {
|
||||
pub pixels: std::boxed::Box<[Color]>,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
}
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Color {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
pub b: u8,
|
||||
}
|
||||
impl Image {
|
||||
pub fn new() -> Self {
|
||||
let width: usize = 16;
|
||||
let height: usize = 16;
|
||||
let pixels: Vec<_> = (0..(width * height)).map(|_| Color::from(0i32)).collect();
|
||||
let pixels = pixels.into_boxed_slice();
|
||||
Self {
|
||||
pixels,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
pub fn draw(&self, cr: &cairo::Context) {
|
||||
println!("Started drawing");
|
||||
cr.scale(self.width as f64, self.height as f64);
|
||||
cr.set_source_rgb(0.0, 0.0, 0.0);
|
||||
cr.paint();
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
let (r, g, b): (f64, _, _) = self
|
||||
.pixels
|
||||
.get(y * self.width + x)
|
||||
.expect("Out of bounds")
|
||||
.into();
|
||||
cr.set_source_rgb(r, g, b);
|
||||
cr.rectangle(
|
||||
x as f64 / self.width as f64,
|
||||
y as f64 / self.height as f64,
|
||||
1.,
|
||||
1.,
|
||||
);
|
||||
cr.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::convert::From<(u8, u8, u8)> for Color {
|
||||
fn from(color: (u8, u8, u8)) -> Self {
|
||||
Color {
|
||||
r: color.0,
|
||||
g: color.1,
|
||||
b: color.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::convert::From<i32> for Color {
|
||||
fn from(num: i32) -> Self {
|
||||
let num = num & 0x00_FF_FF_FF; // Remove alpha
|
||||
Color {
|
||||
r: (num >> 16) as u8,
|
||||
g: (num >> 8) as u8,
|
||||
b: (num) as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::convert::Into<(f64, f64, f64)> for &Color {
|
||||
fn into(self) -> (f64, f64, f64) {
|
||||
(
|
||||
(self.r as f64) / 255.0,
|
||||
(self.g as f64) / 255.0,
|
||||
(self.b as f64) / 255.0,
|
||||
)
|
||||
}
|
||||
}
|
169
src/main.rs
Normal file
169
src/main.rs
Normal file
@ -0,0 +1,169 @@
|
||||
mod error;
|
||||
use error::ProgErr;
|
||||
|
||||
use cairo;
|
||||
use gio::prelude::*;
|
||||
use gtk::prelude::*;
|
||||
use gtk::Builder;
|
||||
|
||||
mod emulator;
|
||||
use emulator::Emulator;
|
||||
mod graphic;
|
||||
use graphic::{Color, Image};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
enum Cmd {
|
||||
Step,
|
||||
Run,
|
||||
Stop,
|
||||
Reset,
|
||||
}
|
||||
impl std::convert::From<&str> for Cmd {
|
||||
fn from(text: &str) -> Self {
|
||||
match text {
|
||||
"Step" => Self::Step,
|
||||
"Run" => Self::Run,
|
||||
"Stop" => Self::Stop,
|
||||
"Reset" => Self::Reset,
|
||||
_ => panic!("???"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(app: >k::Application) {
|
||||
let img = Image::new();
|
||||
let (img_width, img_height) = (img.width, img.height);
|
||||
use std::sync::{Arc, Mutex};
|
||||
let img_m = Arc::from(Mutex::from(img));
|
||||
|
||||
let (tcmd, rcmd) = std::sync::mpsc::channel::<Cmd>();
|
||||
let (tdata, rdata) = glib::MainContext::channel(glib::source::Priority::default());
|
||||
let emulator = Arc::from(Mutex::from(Emulator::new()));
|
||||
{
|
||||
let emulator_clone = emulator.clone();
|
||||
std::thread::spawn(move || {
|
||||
let emulator = emulator_clone;
|
||||
loop {
|
||||
if let Ok(cmd) = rcmd.recv() {
|
||||
let mut emulator = match emulator.try_lock() {
|
||||
Err(_) => continue,
|
||||
Ok(v) => v,
|
||||
};
|
||||
match cmd {
|
||||
Cmd::Step => {
|
||||
if let Err(e) = emulator.step() {
|
||||
println!("{:#?}", e);
|
||||
}
|
||||
}
|
||||
Cmd::Reset => {
|
||||
emulator.restart();
|
||||
emulator.ram = *include_bytes!("color.hex");
|
||||
}
|
||||
Cmd::Run => loop {
|
||||
if let Ok(cmd) = rcmd.recv_timeout(std::time::Duration::from_millis(1))
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
emulator.step();
|
||||
println!("Tick {}", emulator.cycles);
|
||||
let page_02 = Vec::from(&emulator.ram[0x200..0x300]);
|
||||
tdata.send(page_02);
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
println!("Tick {}", emulator.cycles);
|
||||
let page_02 = Vec::from(&emulator.ram[0x200..0x300]);
|
||||
tdata.send(page_02);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
let builder: Builder = Builder::new_from_string(include_str!("ui.glade"));
|
||||
let window: gtk::ApplicationWindow = builder.get_object("Window").unwrap();
|
||||
let da: gtk::DrawingArea = builder.get_object("Display").unwrap();
|
||||
|
||||
{
|
||||
da.set_size_request(img_width as i32, img_height as i32);
|
||||
let img_m = img_m.clone();
|
||||
da.connect_draw(move |_: >k::DrawingArea, ctx: &cairo::Context| {
|
||||
let img: Result<_, _> = img_m.try_lock();
|
||||
if let Ok(img) = img {
|
||||
println!("Redrawing!");
|
||||
img.draw(&ctx);
|
||||
}
|
||||
glib::signal::Inhibit(false)
|
||||
});
|
||||
}
|
||||
|
||||
for widget_name in &["Step", "Reset", "Run"] {
|
||||
let tcmd_clone = tcmd.clone();
|
||||
let widget: gtk::Button = builder.get_object(widget_name).expect("Not found");
|
||||
widget.connect_clicked(move |s: >k::Button| {
|
||||
let name = s.get_widget_name().unwrap();
|
||||
let name = name.as_str();
|
||||
println!("Sending from {}", name);
|
||||
let cmd = Cmd::from(name);
|
||||
tcmd_clone.send(cmd).expect("Couldn't send cmd");
|
||||
});
|
||||
}
|
||||
|
||||
let registers: gtk::Label = builder.get_object("Registers").unwrap();
|
||||
let registers = Mutex::from(registers);
|
||||
|
||||
{
|
||||
let emulator = emulator.clone();
|
||||
let img_m = img_m.clone();
|
||||
rdata.attach(None, move |data: Vec<_>| {
|
||||
let img: Result<_, _> = img_m.try_lock();
|
||||
println!("Received page");
|
||||
for line in data.chunks(16) {
|
||||
println!(
|
||||
"{}",
|
||||
line.iter()
|
||||
.map(|h| format!("{:02X}", h))
|
||||
.collect::<String>()
|
||||
)
|
||||
}
|
||||
if let Ok(mut img) = img {
|
||||
println!("Updating image");
|
||||
let (w, h) = (img.width, img.height);
|
||||
let pixels: &mut [Color] = &mut img.pixels;
|
||||
let palette = [
|
||||
Color::from(0x00_00_00),
|
||||
Color::from(0xFF_00_00),
|
||||
Color::from(0x00_FF_00),
|
||||
Color::from(0xFF_FF_00),
|
||||
Color::from(0x00_00_FF),
|
||||
Color::from(0xFF_00_FF),
|
||||
Color::from(0x00_FF_FF),
|
||||
Color::from(0xFF_FF_FF),
|
||||
];
|
||||
for x in 0..w {
|
||||
for y in 0..h {
|
||||
let i = y * w + x;
|
||||
pixels[i] = palette[data[i] as usize & 0b111];
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Ok(registers) = registers.try_lock() {
|
||||
if let Ok(emulator) = emulator.try_lock() {
|
||||
registers.set_text(&format!("{:#?}", emulator.cpu));
|
||||
}
|
||||
}
|
||||
da.queue_draw();
|
||||
glib::Continue(true)
|
||||
});
|
||||
}
|
||||
|
||||
window.set_application(Some(app));
|
||||
window.show_all();
|
||||
}
|
||||
|
||||
fn main() -> Result<(), ProgErr> {
|
||||
let app: gtk::Application =
|
||||
gtk::Application::new(Some("com.ducklings_corp.emulator"), Default::default())?;
|
||||
app.connect_activate(move |app| init(app));
|
||||
app.run(&std::env::args().collect::<Vec<_>>());
|
||||
Ok(())
|
||||
}
|
114
src/ui.glade
Normal file
114
src/ui.glade
Normal file
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkApplicationWindow" id="Window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">600</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="Reset">
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
<property name="name">Reset</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="Run">
|
||||
<property name="label" translatable="yes">Run</property>
|
||||
<property name="name">Run</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="Step">
|
||||
<property name="label" translatable="yes">Step</property>
|
||||
<property name="name">Step</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="Display">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">6502 Emulator</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="Registers">
|
||||
<property name="name">Registers</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">A: 0x00 X: 0x00 Y: 0x00 PC: 0x000</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
114
src/ui.glade~
Normal file
114
src/ui.glade~
Normal file
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkApplicationWindow" id="Window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">600</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="Reset">
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
<property name="name">Reset</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="Run">
|
||||
<property name="label" translatable="yes">Run</property>
|
||||
<property name="name">Run</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="Step">
|
||||
<property name="label" translatable="yes">Step</property>
|
||||
<property name="name">Step</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="Display">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">6502 Emulator</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="Registers">
|
||||
<property name="name">Registers</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">A: 0x00 X: 0x00 Y: 0x00 PC: 0x000</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
Loading…
x
Reference in New Issue
Block a user