Initial Commit

This commit is contained in:
Sarah Jamie Lewis 2021-11-08 18:19:34 -08:00
commit 01cc63c7f1
16 changed files with 2240 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/side.iml" filepath="$PROJECT_DIR$/.idea/side.iml" />
</modules>
</component>
</project>

12
.idea/side.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

7
.idea/vcs.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/font8x8" vcs="Git" />
</component>
</project>

903
Cargo.lock generated Normal file
View File

@ -0,0 +1,903 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bindgen"
version = "0.56.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"clap",
"env_logger",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"which",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bumpalo"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "cc"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
[[package]]
name = "cexpr"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [
"nom 5.1.2",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "cmake"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089"
dependencies = [
"cc",
]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "downcast-rs"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "encoding_rs"
version = "0.8.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "env_logger"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "filetime"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"winapi",
]
[[package]]
name = "flate2"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
dependencies = [
"cfg-if 1.0.0",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]]
name = "font8x8"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "js-sys"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
[[package]]
name = "libloading"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0"
dependencies = [
"cfg-if 1.0.0",
"winapi",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "minifb"
version = "0.19.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b6e41119d1667465608d36488fa5dcd228057a26c156e25f17f492f38435124"
dependencies = [
"cc",
"orbclient",
"raw-window-handle",
"tempfile",
"wayland-client",
"wayland-cursor",
"wayland-protocols",
"winapi",
"x11-dl",
"xkb",
"xkbcommon-sys",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "nix"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945"
dependencies = [
"bitflags",
"cc",
"cfg-if 1.0.0",
"libc",
"memoffset",
]
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "nom"
version = "7.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
dependencies = [
"memchr",
"minimal-lexical",
"version_check",
]
[[package]]
name = "once_cell"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "orbclient"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c976c5018e7f1db4359616d8b31ef8ae7d9649b11803c0b38fff67fd2999fc8"
dependencies = [
"libc",
"raw-window-handle",
"redox_syscall",
"sdl2",
"sdl2-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pkg-config"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
[[package]]
name = "ppv-lite86"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "raw-window-handle"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211"
dependencies = [
"libc",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "sdl2"
version = "0.34.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deecbc3fa9460acff5a1e563e05cb5f31bba0aa0c214bb49a43db8159176d54b"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"raw-window-handle",
"sdl2-sys",
]
[[package]]
name = "sdl2-sys"
version = "0.34.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41a29aa21f175b5a41a6e26da572d5e5d1ee5660d35f9f9d0913e8a802098f74"
dependencies = [
"cfg-if 0.1.10",
"cmake",
"flate2",
"libc",
"tar",
"unidiff",
"version-compare",
]
[[package]]
name = "shlex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
name = "side"
version = "0.1.0"
dependencies = [
"font8x8",
"minifb",
]
[[package]]
name = "smallvec"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "tar"
version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c"
dependencies = [
"filetime",
"libc",
"xattr",
]
[[package]]
name = "tempfile"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if 1.0.0",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "unidiff"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a62719acf1933bfdbeb73a657ecd9ecece70b405125267dd549e2e2edc232c"
dependencies = [
"encoding_rs",
"lazy_static",
"regex",
]
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version-compare"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]]
name = "wayland-client"
version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355"
dependencies = [
"bitflags",
"downcast-rs",
"libc",
"nix",
"wayland-commons",
"wayland-scanner",
"wayland-sys",
]
[[package]]
name = "wayland-commons"
version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda"
dependencies = [
"nix",
"once_cell",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-cursor"
version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a"
dependencies = [
"nix",
"wayland-client",
"xcursor",
]
[[package]]
name = "wayland-protocols"
version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f"
dependencies = [
"bitflags",
"wayland-client",
"wayland-commons",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1"
dependencies = [
"proc-macro2",
"quote",
"xml-rs",
]
[[package]]
name = "wayland-sys"
version = "0.28.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8"
dependencies = [
"pkg-config",
]
[[package]]
name = "web-sys"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "x11-dl"
version = "2.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59"
dependencies = [
"lazy_static",
"libc",
"pkg-config",
]
[[package]]
name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
dependencies = [
"libc",
]
[[package]]
name = "xcursor"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
dependencies = [
"nom 7.1.0",
]
[[package]]
name = "xkb"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aec02bc5de902aa579f3d2f2c522edaf40fa42963cbaffe645b058ddcc68fdb2"
dependencies = [
"bitflags",
"libc",
"xkbcommon-sys",
]
[[package]]
name = "xkbcommon-sys"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a001b79d45b0b4541c228a501177f2b35db976bf7ee3f7fce8fa2381554ab5"
dependencies = [
"bindgen",
"libc",
"pkg-config",
]
[[package]]
name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"

10
Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "side"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
minifb = "0.19.3"
font8x8 = "0.3.1"

178
README.md Normal file
View File

@ -0,0 +1,178 @@
# Philosophy of Boo OS
> Operating System: An operating system is a collection of things that don't fit into a language. There shouldn't be one. - [Design Principles Behind Smalltalk](https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html)
Boo OS is a meditation on recursive complexity and the curse of simplicity. In an age where computers are so powerful, it is sometimes healing to start again.
I have often been stuck between my desire to build either an operating system, a shell, a language or an ide. None
of those categories ever quite fit the hole I was intending them to fill.
After much introspection and research I finally decided that what I really needed was something different.
Inspired by smalltalk, Boo OS is "image" based, the entire system can be dumped and reloaded to the same state.
Eventually my plan is that Boo OS contain all the essentials necessary for **self modification**. It should be possible to (safely) modify the operating system from within the operating system and have the changes take effect.
How that will look is undecided. For now, Boo OS is coded entirely in Boo Bytecode Assembly Language and assembled
using a Rust based assembler. One of my first targets for a real application is an Assembler written in Boo Bytecode,
run on BooOS and outputting a Boo Bytecode image.
## BooVM
Boo OS is written in Boo Bytecode which is run by the Boo Virtual Machine (BooVM). BooVM and Boo Bytecode is inspired
by various retro computing architectures with minimal instructions, but a focus on integrating with the core
systems.
As such. the BooVM offers minimal integration with the outside world. Interaction is limited to:
- Reading and Writing BooVM images to/from the Host OS
- Exposing The State of the Keyboard and Mouse
- Offering a Framebuffer for Display Output
- (Provisional) Reading and Writing "Files" from the Host OS OR Loading and Interacting with a generalized
File System that can be loaded by both operating systems (i.e. some kind of virtual disk image)
### Why Write a Custom VM?
Why Not? This is a meditation on recursive complexity. I was already set on writing a new language and building one from the ground up on a custom instruction set seemed like a great idea.
The longer version is that I looked into many options for the base of this project. They fell into
two main categories:
The first featured existing ISA emulations (e.g. QEMU) and existing production ready language virtual machines (e.g. JVM, Lua) - I decided that using an existing architecture wasn't in the spirit of the project. Further, both of these options
would require extra work to integrate a framebuffer display and input up to the extent where I would be writing an OS
for an existing architecture. I wanted to keep the wrapping interface to the host OS as simple as possible.
The second category featured older reto architectures, emulators and the like. I rejected this approach because
there are some details I don't want to care about, like scanlines and cartridge layouts. This approach would also
make interaction with the Host OS a project in itself likely requiring forking and significant rework resulting in
a custom emulator any way.
After research, designing and implementing an assembler for some custom bytecode and building a small VM to run
it seemed to be the simplest option and provides me with a lot of freedom moving forward, and lends itself to
infinite experimentation.
## TODO List
The below represents some ideas for projects to tackle within Boo OS.
- [x] Print Strings to the FrameBuffer
- [x] Set Framebuffer Position Helper Function
- [x] `put_char` Helper Function
- [ ] Memory Management
- [ ] Heap Design
- [ ] Implement Helper Functions `alloc` and `free`
- [ ] Memory Safety
- [ ] Keyboard Input
- [ ] Designing Input Interaction (poll v.s. interrupts)
- [ ] Create a Console Shell to Interact with the System
- [ ] At first this shell will be limited to pre-programmed commands
- [ ] But, it should quickly all the construction of new commands from old ones
- [ ] Finally, the shell should facilitate saving and loading of images
- [ ] Write a Bootstrapped Assembler Application in Boo Bytecode Assembly
# Formal Reqs
Run time:
- Memory needs R/W/E flags - 3 bits
- Mapping Memory before handing off to lesser privileged processes
- Needs some understanding off operating mode
- Never attempt to pop an empty stack
Memory
We treat each 64 chunks of memory as a single page:
0x0000 4800 Pages of Write only Display Memory
0x4B000 1 Page of Registers [rip, mode, display, rax, r2, r3, r4, r5, r6, r7, r8]
0x4B040 1 Page of Call Stack
0x4B080 1 Page of Input Flags (Keys Down etc)
0x4B0C0 Dynamic Memory Begins
## Instructions
All instructions are fixed length.
## Meta Instructions
0x00 - Nop
0x01 - Update Display
0x0F - HLT
## Dynamic Instructions
Prefix 0x1#,0x2#,0x3# are given to dynamin register based commands
- 0x1n STORE(n) $Addr (R(n)) -> Addr)
- 0x2n LOAD(n) $Addr (Addr -> R(n))
- 0x3n LOADI(n) IMM (Immediate -> R(n))
- 0x4n INC(n)
- 0x5n DEC(n)
- 0x6n ISTORE(n)
- 0x7n x LDSTORE Load the Address Stored in n into reg(x)
- 0x8n x Transfer R(n) to R(x)
- 0x9n Shift
## Arithmetic
Prefix 0xa# is given to arithmetic functions
- 0xa1 ADD (R2 + R3 -> RAX)
- 0xa2 SUB (R2 - R3 -> RAX)
- 0xa3 MUL (R2 * R3 -> RAX)
- 0xa4 DIV (R2 / R3 -> RAX)
- 0xa5 SHIFT (R2 >> R3 -> RAX)
- 0xa6 AND (R2 & R3 -> RAX)
# Stack
Prefix 0xc# allows call stack manipulation. The machine denotes 64 memory addresses at memoo
- 0xc0 RET
- 0xc1 PUSH Call Stack
# Jumps and Branches (0x5#)
- 0xE0 JMP $Addr - Unconditional jump to $Addr
- 0xE1 JMPEQ $Addr (if R1 == R2 jmp $Addr else )
- 0xE2 JMPNEQ $Addr (if R1 != R2 jmp $Addr else )
- 0xE3 JMPGT $Addr (if R1 > R2 jmp $Addr else )
- 0xE4 JMPLT $Addr (if R1 < R2 jmp $Addr else )
- 0xE5 JMPGEQ $Addr (if R1 >= R2 jmp $Addr else )
- 0xE6 JMPLEQ $Addr (if R1 <= R2 jmp $Addr else )
## Admin Mode Instructions
Instructions prefixed with 0xF are admin instructions
- 0xF0 UNSET_R $Addr (Sets the 64 addresses after $Addr as Not Readable)
- 0xF1 SET_R $Addr (Sets the 64 addresses after $Addr as Readable)
- 0xF2 UNSET_W $Addr (Sets the 64 addresses after $Addr as Not Writable)
- 0xF3 SET_W $Addr (Sets the 64 addresses after $Addr as Writable)
- 0xF4 UNSET_X $Addr (Sets the 64 addresses after $Addr as Not Executable)
- 0xF5 SET_X $Addr (Sets the 64 addresses after $Addr as Executable)
- 0xFF DROP_MODE $Addr - Drops from Admin Mode into User Mode (No access to Admin mode instructions)
0: LOAD_IMM 10
1: NOP
2: DEC(1)
3: JNEQ
##

290
charset.asm Normal file
View File

@ -0,0 +1,290 @@
label char_space:
$00000000
$00000000
label char_!:
$183c3c18
$18001800
label char_":
$36360000
$00000000
label char_#:
$36367f36
$7f363600
label char_$:
$0c3e031e
$301f0c00
label char_%:
$00633318
$0c666300
label char_&:
$1c361c6e
$3b336e00
label char_':
$06060300
$00000000
label char_(:
$180c0606
$060c1800
label char_):
$060c1818
$180c0600
label char_*:
$00663cff
$3c660000
label char_+:
$000c0c3f
$0c0c0000
label char_,:
$00000000
$000c0c06
label char_-:
$0000003f
$00000000
label char_.:
$00000000
$000c0c00
label char_/:
$6030180c
$06030100
label char_0:
$3e63737b
$6f673e00
label char_1:
$0c0e0c0c
$0c0c3f00
label char_2:
$1e33301c
$06333f00
label char_3:
$1e33301c
$30331e00
label char_4:
$383c3633
$7f307800
label char_5:
$3f031f30
$30331e00
label char_6:
$1c06031f
$33331e00
label char_7:
$3f333018
$0c0c0c00
label char_8:
$1e33331e
$33331e00
label char_9:
$1e33333e
$30180e00
label char_::
$000c0c00
$000c0c00
label char_;:
$000c0c00
$000c0c06
label char_<:
$180c0603
$060c1800
label char_=:
$00003f00
$003f0000
label char_>:
$060c1830
$180c0600
label char_?:
$1e333018
$0c000c00
label char_@:
$3e637b7b
$7b031e00
label char_A:
$0c1e3333
$3f333300
label char_B:
$3f66663e
$66663f00
label char_C:
$3c660303
$03663c00
label char_D:
$1f366666
$66361f00
label char_E:
$7f46161e
$16467f00
label char_F:
$7f46161e
$16060f00
label char_G:
$3c660303
$73667c00
label char_H:
$3333333f
$33333300
label char_I:
$1e0c0c0c
$0c0c1e00
label char_J:
$78303030
$33331e00
label char_K:
$6766361e
$36666700
label char_L:
$0f060606
$46667f00
label char_M:
$63777f7f
$6b636300
label char_N:
$63676f7b
$73636300
label char_O:
$1c366363
$63361c00
label char_P:
$3f66663e
$06060f00
label char_Q:
$1e333333
$3b1e3800
label char_R:
$3f66663e
$36666700
label char_S:
$1e33070e
$38331e00
label char_T:
$3f2d0c0c
$0c0c1e00
label char_U:
$33333333
$33333f00
label char_V:
$33333333
$331e0c00
label char_W:
$6363636b
$7f776300
label char_X:
$6363361c
$1c366300
label char_Y:
$3333331e
$0c0c1e00
label char_Z:
$7f633118
$4c667f00
label char_[:
$1e060606
$06061e00
label char_\:
$03060c18
$30604000
label char_]:
$1e181818
$18181e00
label char_^:
$081c3663
$00000000
label char__:
$00000000
$000000ff
label char_`:
$0c0c1800
$00000000
label char_a:
$00001e30
$3e336e00
label char_b:
$0706063e
$66663b00
label char_c:
$00001e33
$03331e00
label char_d:
$3830303e
$33336e00
label char_e:
$00001e33
$3f031e00
label char_f:
$1c36060f
$06060f00
label char_g:
$00006e33
$333e301f
label char_h:
$0706366e
$66666700
label char_i:
$0c000e0c
$0c0c1e00
label char_j:
$30003030
$3033331e
label char_k:
$07066636
$1e366700
label char_l:
$0e0c0c0c
$0c0c1e00
label char_m:
$0000337f
$7f6b6300
label char_n:
$00001f33
$33333300
label char_o:
$00001e33
$33331e00
label char_p:
$00003b66
$663e060f
label char_q:
$00006e33
$333e3078
label char_r:
$00003b6e
$66060f00
label char_s:
$00003e03
$1e301f00
label char_t:
$080c3e0c
$0c2c1800
label char_u:
$00003333
$33336e00
label char_v:
$00003333
$331e0c00
label char_w:
$0000636b
$7f7f3600
label char_x:
$00006336
$1c366300
label char_y:
$00003333
$333e301f
label char_z:
$00003f19
$0c263f00
label char_{:
$380c0c07
$0c0c3800
label char_|:
$18181800
$18181800
label char_}:
$070c0c38
$0c0c0700
label char_~:
$6e3b0000
$00000000
label char_delete:
$00000000
$00000000
data ascii HEX_TABLE 0123456789ABCDEF

5
display.asm Normal file
View File

@ -0,0 +1,5 @@
label set_pos:
loadi 2 $280
mul $2 $A $2 ; Mul Y * 640
add $2 $9 $B ; + X = VBUF POS
ret

71
example.asm Normal file
View File

@ -0,0 +1,71 @@
@ $00000:
label vbuf:
@ $4B000:
$5B000 ; Set Instruction Pointer to $5B000
label RAX:
$0000000 ; RAX
$0000000 ; R2 - Temp Scratch
$0000000 ; R3 - Temp Scratch
$0000000 ; R4 - ARG 1
$0000000 ; R5 - ARG 2
$0000000 ; R6 - ARG 3
$0000000 ; R7 - ARG 4
$0000000 ; R8 - ARG 5
$0000000 ; RX
$0000000 ; RY
$0000000 ; RVBUF (RY * 640) + RX
@ $4B0C0:
import display.asm
import charset.asm
import strings.asm
import util.asm
; Common Strings
data ascii HelloWorld Welcome to Boo OS Running on Boo Byte Code!
data ascii Welcome !@#$%^&*()_+=-0987654321
data ascii Introspection We Can Now Do Introspection:
data ascii label_rax RAX:
data ascii label_rip RIP:
data ascii label_cycles Instruction Count:
; Kernel Begins
@ $5B000:
loadi $9 1;
loadi $A 1;
call set_pos
loadi $4 HelloWorld
call draw_string;
loadi $9 1;
loadi $A 10;
call set_pos
loadi $4 Welcome
call draw_string;
; OK! Time for some self referencing!!
loadi $9 1;
loadi $A 20;
call set_pos
loadi $4 Introspection
call draw_string;
loadi $9 1;
loadi $A 30;
call set_pos
loadi $4 label_cycles
call draw_string;
loadi $4 $4B000
loadi $2 $40
add $2 $4 $4
call print_addr
updsp
jmp $5B000;

280
src/assembler.rs Normal file
View File

@ -0,0 +1,280 @@
use crate::{Machine, MEMORY};
use std::collections::HashMap;
use std::fs::read_to_string;
pub struct ImageAssembler {
memory: [u32; MEMORY],
ptr: usize,
labels: HashMap<String, usize>,
}
impl ImageAssembler {
pub fn new() -> ImageAssembler {
ImageAssembler {
memory: [0; MEMORY],
ptr: 0,
labels: HashMap::new(),
}
}
pub fn extract(self) -> Machine {
let mut machine = Machine::new();
machine.memory = self.memory;
return machine;
}
pub fn assemble(&mut self, filename: &str) {
let asm = read_to_string(filename).unwrap_or_default();
let lines = asm.split('\n');
for line in lines {
let parts = line.split_once(';');
let command = match parts {
Some((command, _comment)) => command.trim(),
_ => line.trim(),
};
let command_parts = command.split_whitespace().collect::<Vec<&str>>();
if command_parts.is_empty() {
continue;
}
if command_parts.len() == 1 {
match command_parts[0] {
"nop" => {
self.memory[self.ptr] = 0x00000000;
self.ptr += 1;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
}
"ret" => {
self.memory[self.ptr] = 0xC0000000;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"hlt" => {
self.memory[self.ptr] = 0x0F000000;
self.ptr += 1;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
}
"inc1" => {
self.memory[self.ptr] = 0x41000000;
self.ptr += 1;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
}
"inc2" => {
self.memory[self.ptr] = 0x42000000;
self.ptr += 1;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
}
"inc3" => {
self.memory[self.ptr] = 0x43000000;
self.ptr += 1;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
}
"updsp" => {
self.memory[self.ptr] = 0x01000000;
self.ptr += 1;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
}
_ => {
let data = self.parse_addr(command_parts[0]);
self.memory[self.ptr] = data;
self.ptr += 1;
}
}
} else if command_parts.len() == 2 && command_parts[0] != "data" {
match command_parts[0] {
"label" => {
self.labels
.insert(command_parts[1].replace(":", ""), self.ptr);
}
"@" => {
self.ptr = self.parse_addr(command_parts[1]) as usize;
println!("Setting addr to ${:X}", self.ptr);
}
"inc" => {
let num = self.parse_addr(command_parts[1]);
let inst = 0x40 + num;
self.memory[self.ptr] = inst << 24;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"dec" => {
let num = self.parse_addr(command_parts[1]);
let inst = 0x50 + num;
self.memory[self.ptr] = inst << 24;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"jmp" => {
let addr = self.parse_addr(command_parts[1]);
self.memory[self.ptr] = 0xE0000000 + addr;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"jneq" => {
let addr = self.parse_addr(command_parts[1]);
self.memory[self.ptr] = 0xE2000000 + addr;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"call" => {
let addr = self.parse_addr(command_parts[1]);
self.memory[self.ptr] = 0xC1000000 + addr;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"import" => {
self.assemble(command_parts[1]);
}
_ => {
panic!("Unknown Instruction: {:?}", command_parts)
}
}
} else if command_parts.len() == 3 && command_parts[0] != "data" {
match command_parts[0] {
"ldstore" => {
// Load Immediate
let target_reg = self.parse_addr(command_parts[1]);
let inst = (0x70 + target_reg) << 24;
let imm = self.parse_addr(command_parts[2]);
self.memory[self.ptr] = inst + imm;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"loadi" => {
// Load Immediate
let target_reg = self.parse_addr(command_parts[1]);
let inst = (0x30 + target_reg) << 24;
let imm = self.parse_addr(command_parts[2]);
self.memory[self.ptr] = inst + imm;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"load" => {
// Load Immediate
let target_reg = self.parse_addr(command_parts[1]);
let inst = (0x20 + target_reg) << 24;
let reg = self.parse_addr(command_parts[2]);
self.memory[self.ptr] = inst + reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"store" => {
// Load Immediate
let target_reg = self.parse_addr(command_parts[1]);
let inst = (0x10 + target_reg) << 24;
let reg = self.parse_addr(command_parts[2]);
self.memory[self.ptr] = inst + reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"rstore" => {
// Load Immediate
let target_reg = self.parse_addr(command_parts[1]);
let inst = (0x60 + target_reg) << 24;
let reg = self.parse_addr(command_parts[2]);
self.memory[self.ptr] = inst + reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"tx" => {
let target_reg = self.parse_addr(command_parts[1]);
let inst = (0x80 + target_reg) << 24;
let reg = self.parse_addr(command_parts[2]);
self.memory[self.ptr] = inst + reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
_ => {
panic!("unknown opcpde {}", command_parts[0])
}
}
} else if command_parts.len() == 4 && command_parts[0] != "data" {
// Every Instruction with 3 is [INST] [Source Reg] [Target Addr / Reg]
let a_reg = self.parse_addr(command_parts[1]);
let b_reg = self.parse_addr(command_parts[2]);
let result_reg = self.parse_addr(command_parts[3]);
match command_parts[0] {
"add" => {
self.memory[self.ptr] =
(0xa1 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"sub" => {
self.memory[self.ptr] =
(0xa2 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"mul" => {
self.memory[self.ptr] =
(0xa3 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"shift" => {
self.memory[self.ptr] =
(0xa5 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
"and" => {
self.memory[self.ptr] =
(0xa6 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg;
println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]);
self.ptr += 1;
}
_ => {
panic!("Unknown Instruction: {:?}", command_parts)
}
}
} else {
match command_parts[0] {
"data" => match command_parts[1] {
"ascii" => {
self.labels
.insert(command_parts[2].replace(":", ""), self.ptr);
let data = command_parts
.iter()
.skip(3)
.map(|x| String::from(*x))
.collect::<Vec<String>>()
.join(" ");
for char in data.chars() {
self.memory[self.ptr] = char as u32;
self.ptr += 1;
}
self.memory[self.ptr] = 0x00;
self.ptr += 1;
}
_ => {
panic!("unknown type {}", command_parts[1])
}
},
_ => {
panic!("unknown command {}", command_parts[0])
}
}
}
}
}
fn parse_addr(&self, input: &str) -> u32 {
match u32::from_str_radix(input.replace("$", "").replace(":", "").as_str(), 16) {
Ok(addr) => {
return addr;
}
_ => match self.labels.get(input) {
Some(addr) => {
return addr.clone() as u32;
}
_ => {
panic!("Not a Hex Encoded Address {:?}", input)
}
},
}
}
}

230
src/lib.rs Normal file
View File

@ -0,0 +1,230 @@
pub mod assembler;
pub const VRAM: usize = 640 * 480;
pub const REGISTER_PAGE: usize = VRAM;
pub const INPUT_PAGE: usize = VRAM + 64;
pub const OFFSET: usize = INPUT_PAGE;
pub const MEM_SIZE: usize = 65535;
pub const MEMORY: usize = OFFSET + MEM_SIZE;
pub struct Machine {
pub memory: [u32; MEMORY],
}
impl Machine {
pub fn new() -> Machine {
let mut memory = [0; MEMORY];
memory[REGISTER_PAGE] = 0x00;
Machine { memory }
}
pub fn load(&mut self, memory: [u32; MEMORY]) {
self.memory = memory;
self.memory[INPUT_PAGE] = 0x00;
}
pub fn dump(&self) -> [u32; MEMORY] {
return self.memory;
}
pub fn cycle(&mut self) {
let ip = self.memory[REGISTER_PAGE] as usize;
let instruction = self.memory[ip];
self.memory[INPUT_PAGE] += 1;
match instruction >> 28 {
0x0 => {
match instruction >> 24 {
0x00 => {
// NOP
}
0x01 => {
self.memory[REGISTER_PAGE + 63] = 0x01;
}
0x0F => {
println!("---");
println!(
"REG 1:{:X} 2:{:X} 3:{:X} 4:{:X}",
self.memory[REGISTER_PAGE + 1],
self.memory[REGISTER_PAGE + 2],
self.memory[REGISTER_PAGE + 3],
self.memory[REGISTER_PAGE + 4]
);
println!(
"REG 5:{:X} 6:{:X} 7:{:X} 8:{:X}",
self.memory[REGISTER_PAGE + 5],
self.memory[REGISTER_PAGE + 6],
self.memory[REGISTER_PAGE + 7],
self.memory[REGISTER_PAGE + 8],
);
println!(
"REG 9:{:X} A:{:X} B:{:X} C:{:X}",
self.memory[REGISTER_PAGE + 9],
self.memory[REGISTER_PAGE + 10],
self.memory[REGISTER_PAGE + 11],
self.memory[REGISTER_PAGE + 12],
);
panic!("HLT");
}
op => {
unimplemented!("0x0 Meta Instruction {}", op)
}
}
}
0x1 => {
// STORE R(X) => ADDR
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
let mem = instruction & 0x00FFFFFF;
self.memory[mem as usize] = self.memory[REGISTER_PAGE + input_reg];
}
0x2 => {
// LOAD ADDR => R(X)
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
let mem = instruction & 0x00FFFFFF;
self.memory[REGISTER_PAGE + input_reg] = self.memory[mem as usize];
}
0x3 => {
// LOAD IMMEDIATE => R(X)
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
let imm = instruction & 0x00FFFFFF;
self.memory[REGISTER_PAGE + input_reg] = imm;
}
0x04 => {
// INC R(X)
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
self.memory[REGISTER_PAGE + input_reg] += 1;
}
0x05 => {
// DEC R(X)
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
self.memory[REGISTER_PAGE + input_reg] -= 1;
}
0x06 => {
// STORE Mem[R(In)] = R(X)
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
let reg = (instruction & 0x000000FF) as usize;
let addr = self.memory[REGISTER_PAGE + reg] as usize;
self.memory[addr] = self.memory[REGISTER_PAGE + input_reg];
}
0x07 => {
// LOAD R(X) = MEM(R(In))
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
let reg = (instruction & 0x000000FF) as usize;
self.memory[REGISTER_PAGE + reg] =
self.memory[self.memory[REGISTER_PAGE + input_reg] as usize];
}
0x08 => {
// TX R(In) => R(X)
let input_reg = ((instruction) >> 24 & 0x0F) as usize;
let reg = (instruction & 0x000000FF) as usize;
self.memory[REGISTER_PAGE + input_reg] = self.memory[REGISTER_PAGE + reg];
}
0x0A => {
match instruction >> 24 {
// ADD A B => C
0xA1 => {
let a_reg = ((instruction & 0x00FF0000) >> 16) as usize;
let b_reg = ((instruction & 0x0000FF00) >> 8) as usize;
let dest_reg = (instruction & 0xFF) as usize;
let a = self.memory[REGISTER_PAGE + a_reg];
let b = self.memory[REGISTER_PAGE + b_reg];
let result = a + b;
self.memory[REGISTER_PAGE + dest_reg] = result;
}
// SUB A B => C
0xA2 => {
let a_reg = ((instruction & 0x00FF0000) >> 16) as usize;
let b_reg = ((instruction & 0x0000FF00) >> 8) as usize;
let dest_reg = (instruction & 0xFF) as usize;
let a = self.memory[REGISTER_PAGE + a_reg];
let b = self.memory[REGISTER_PAGE + b_reg];
let result = a - b;
self.memory[REGISTER_PAGE + dest_reg] = result;
}
// MUL A B => C
0xA3 => {
let a_reg = ((instruction & 0x00FF0000) >> 16) as usize;
let b_reg = ((instruction & 0x0000FF00) >> 8) as usize;
let dest_reg = (instruction & 0xFF) as usize;
let a = self.memory[REGISTER_PAGE + a_reg];
let b = self.memory[REGISTER_PAGE + b_reg];
let result = a * b;
self.memory[REGISTER_PAGE + dest_reg] = result;
}
// RSHIFT A >> B => C
0xA5 => {
let source_reg = ((instruction & 0x00FF0000) >> 16) as usize;
let bit_reg = ((instruction & 0x0000FF00) >> 8) as usize;
let dest_reg = (instruction & 0xFF) as usize;
let source = self.memory[REGISTER_PAGE + source_reg];
let bits = self.memory[REGISTER_PAGE + bit_reg];
let result = source >> bits;
self.memory[REGISTER_PAGE + dest_reg] = result;
}
// AND A & B => C
0xA6 => {
let source_reg = ((instruction & 0x00FF0000) >> 16) as usize;
let mask_reg = ((instruction & 0x0000FF00) >> 8) as usize;
let dest_reg = (instruction & 0xFF) as usize;
let source = self.memory[REGISTER_PAGE + source_reg];
let bits = self.memory[REGISTER_PAGE + mask_reg];
let result = source & bits;
self.memory[REGISTER_PAGE + dest_reg] = result;
}
op => {
unimplemented!("0x0 Addition Instruction {}", op)
}
}
}
0x0C => {
match instruction >> 24 {
// RET (Pops call stack and JMPs)
0xC0 => {
let sp = self.memory[REGISTER_PAGE + 62] as usize;
self.memory[REGISTER_PAGE] = self.memory[REGISTER_PAGE + 62 - sp];
self.memory[REGISTER_PAGE + 62] -= 1;
}
// CALL Addr (Pushed Addr and JMPS)
0xC1 => {
self.memory[REGISTER_PAGE + 62] += 1;
let sp = self.memory[REGISTER_PAGE + 62] as usize;
self.memory[REGISTER_PAGE + 62 - sp] = self.memory[REGISTER_PAGE];
let mem = instruction & 0x00FFFFFF;
self.memory[REGISTER_PAGE] = mem - 1;
}
op => {
unimplemented!("0x0 Call Strack Instruction {}", op)
}
}
}
0x0E => {
match instruction >> 24 {
0xE0 => {
// Unconditional JMP
let mem = instruction & 0x00FFFFFF;
self.memory[REGISTER_PAGE] = mem - 1;
}
0xE2 => {
// JEQ ADDR if R(1) != R(2)
if self.memory[REGISTER_PAGE + 1] != self.memory[REGISTER_PAGE + 2] {
let mem = instruction & 0x00FFFFFF;
self.memory[REGISTER_PAGE] = mem - 1;
}
}
op => {
unimplemented!("0x0 JMP Instruction {}", op)
}
}
}
x => {
panic!("unknown bytecode opcode {:X} {:X} {:X}", x, ip, instruction)
}
}
self.memory[REGISTER_PAGE] += 1;
//
}
}

54
src/main.rs Normal file
View File

@ -0,0 +1,54 @@
extern crate minifb;
use minifb::{Key, Scale, Window, WindowOptions};
use side::assembler::ImageAssembler;
use side::{Machine, REGISTER_PAGE};
use std::env;
//use font8x8::{BASIC_FONTS, UnicodeFonts};
const WIDTH: usize = 640;
const HEIGHT: usize = 360;
fn main() {
// for font in BASIC_FONTS.iter().skip(0x20) {
// println!("label char_{}:", font.0);
// println!("\t${:02x}{:02x}{:02x}{:02x}", font.1[0],font.1[1],font.1[2],font.1[3]);
// println!("\t${:02x}{:02x}{:02x}{:02x}", font.1[4],font.1[5],font.1[6],font.1[7]);
// }
// return;
let args: Vec<String> = env::args().collect();
let mut machine = Machine::new();
if args.len() == 3 {
match args[1].as_str() {
"assemble" => {
let mut ia = ImageAssembler::new();
ia.assemble(&args[2]);
machine = ia.extract();
}
_ => {
panic!("unknown command {}", args[1])
}
}
}
let mut opts = WindowOptions::default();
opts.scale = Scale::X1;
let mut window = Window::new("Test - ESC to exit", WIDTH, HEIGHT, opts).unwrap_or_else(|e| {
panic!("{}", e);
});
while window.is_open() && !window.is_key_down(Key::Escape) {
machine.cycle();
if machine.memory[REGISTER_PAGE + 63] == 0x01 {
// We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way
window
.update_with_buffer(&machine.memory, WIDTH, HEIGHT)
.unwrap();
machine.memory[REGISTER_PAGE + 63] = 0x00;
}
}
}

144
strings.asm Normal file
View File

@ -0,0 +1,144 @@
label draw_char_pixels:
shift 5 2 1; Shift 5 by count in R(2)
loadi 6 1;
and 1 6 1; Mask with 0x01
loadi 6 $FFFFFF
mul 1 6 1;
rstore 1 $B; Transfer RAX to the Address Stored in R11
inc $B; Increment VBuf Pointer
inc 2; INC Scratch Pixel
loadi 1 8; For Every Pixel in this Row of 8
jneq draw_char_pixels
ret
label draw_char:
ldstore 4 3; Load Arg 1 in 3
loadi 6 $18;
shift 3 6 5; Shift To First Byte
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
loadi 6 $10;
shift 3 6 5; Shift To Second Byte
loadi 6 $0000FF;
and 6 5 5; Mask Off
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
loadi 6 $8;
shift 3 6 5; Shift To Third Byte
loadi 6 $0000FF;
and 6 5 5;
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
loadi 6 $0;
shift 3 6 5; Shift To 4th Byte
loadi 6 $0000FF;
and 6 5 5; MASK off last Byte
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
inc 4; Move to Second Part
ldstore 4 3; Load Arg 1 in 3
loadi 6 $18;
shift 3 6 5; Shift To First Byte
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
loadi 6 $10;
shift 3 6 5; Shift To Second Byte
loadi 6 $0000FF;
and 6 5 5; Mask Off
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
loadi 6 $8;
shift 3 6 5; Shift To Third Byte
loadi 6 $0000FF;
and 6 5 5;
loadi 2 0; Set Pixel to 8
call draw_char_pixels
loadi 6 $278
add $6 $B $B ; Move VBUF
loadi 6 $0;
shift 3 6 5; Shift To 4th Byte
loadi 6 $0000FF;
and 6 5 5; MASK off last Byte
loadi 2 0; Set Pixel to 8
call draw_char_pixels
ret
label _scratch_draw_string:
nop
label draw_string:
label draw_next_char:
ldstore 4 3; Load Arg 1 in 3
store 4 _scratch_draw_string
loadi $2 $20 ; Load Addr of [SPACE] in $2
sub $3 $2 $1 ; Sub the Character From Space
loadi $2 2
mul $1 $2 $1 ; Mull By 2
loadi $2 char_space
add $2 $1 $1 ; Add to Char Space
tx $4 $1
call draw_char; Call draw_char
loadi $2 8
add $2 $9 $9; // X = X + 9
call set_pos
load $4 _scratch_draw_string
inc $4;
ldstore 4 3; Load Arg 1 in 3
tx $2 $3
loadi $1 0
jneq draw_next_char
ret
label num_to_char:
loadi $2 HEX_TABLE
add $2 $4 $4
ldstore 4 3; Load Arg 1 in 3
loadi $2 $20 ; Load Addr of [SPACE] in $2
sub $3 $2 $1 ; Sub the Character From Space
loadi $2 2
mul $1 $2 $1 ; Mull By 2
loadi $2 char_space
add $2 $1 $1 ; Add to Char Space
tx $4 $1
ret

39
util.asm Normal file
View File

@ -0,0 +1,39 @@
label _scratch_print_var:
nop
label print_addr:
ldstore 4 3; Load Arg 1 in 3
store $3 _scratch_print_var ; preserve rax
loadi $7 $1C
label print_rax_digit:
loadi $2 8
add $2 $9 $9; // X = X + 9
call set_pos
load $3 _scratch_print_var
shift $3 $7 $4
loadi $2 $00000F
and $2 $4 $4
call num_to_char;
call draw_char;
loadi $2 4
sub $7 $2 $7
tx $2 $7
loadi $1 0
jneq print_rax_digit
loadi $2 8
add $2 $9 $9; // X = X + 9
call set_pos
load $3 _scratch_print_var
shift $3 $7 $4
loadi $2 $00000F
and $2 $4 $4
call num_to_char;
call draw_char;
ret