+10000 lines changed: First commit

This commit is contained in:
PeronTheDuck 2020-01-13 00:44:09 -03:00
commit e66085eb25
16 changed files with 2113 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
**/*.rs.bk

429
Cargo.lock generated Normal file
View 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
View 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

Binary file not shown.

32
src/emulator/addr Normal file
View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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: &gtk::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 |_: &gtk::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: &gtk::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
View 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
View 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>