first instructiom
This commit is contained in:
parent
3181d2c80d
commit
f74be7dbbf
245
Cargo.lock
generated
245
Cargo.lock
generated
@ -1,16 +1,251 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "um"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ux",
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ux"
|
||||
version = "0.1.6"
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b59fc5417e036e53226bbebd90196825d358624fd5577432c4e486c95b1b096"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
@ -4,4 +4,4 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ux = "0.1.6"
|
||||
clap = { version = "4.5.45", features = [ "derive" ] }
|
||||
|
256
data/um.asm
Normal file
256
data/um.asm
Normal file
@ -0,0 +1,256 @@
|
||||
ORT r5=0x12
|
||||
CMV r0=r0 if r0
|
||||
CMV r0=r0 if r0
|
||||
CMV r0=r0 if r0
|
||||
CMV r0=r0 if r0
|
||||
CMV r0=r0 if r0
|
||||
CMV r0=r0 if r0
|
||||
CMV r0=r0 if r0
|
||||
ORT r0=0x100
|
||||
ORT r2=0x7
|
||||
ORT r3=0x1ffffff
|
||||
ADD r4=r3+r7
|
||||
NAD r3=r1 nand r3
|
||||
NAD r3=r3 nand r3
|
||||
DIV r1=r1/r4
|
||||
NAD r1=r2 nand r1
|
||||
NAD r1=r1 nand r1
|
||||
AMD r6[r1]=r3
|
||||
IDX r1=r6[r0]
|
||||
ORT r7=0x1
|
||||
ADD r0=r7+r0
|
||||
ORT r3=0xff
|
||||
IDX r3=r6[r3]
|
||||
DIV r3=r1/r3
|
||||
ORT r4=0x1c
|
||||
ADD r4=r4+r3
|
||||
IDX r4=r6[r4]
|
||||
LOD r6@r4
|
||||
CMV r0=r5 if r2
|
||||
CMV r0=r7 if r1
|
||||
CMV r1=r3 if r2
|
||||
CMV r1=r7 if r3
|
||||
CMV r2=r1 if r1
|
||||
CMV r2=r2 if r7
|
||||
CMV r2=r4 if r5
|
||||
CMV r2=r6 if r3
|
||||
CMV r2=r6 if r4
|
||||
CMV r3=r0 if r0
|
||||
CMV r3=r0 if r5
|
||||
CMV r3=r1 if r2
|
||||
CMV r3=r1 if r7
|
||||
CMV r0=r1 if r2
|
||||
ORT r7=0x8
|
||||
DIV r4=r1/r7
|
||||
DIV r3=r4/r7
|
||||
NAD r4=r4 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
NAD r3=r3 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
NAD r7=r1 nand r2
|
||||
NAD r7=r7 nand r7
|
||||
IDX r7=r6[r7]
|
||||
IDX r1=r6[r3]
|
||||
IDX r4=r6[r4]
|
||||
CMV r1=r4 if r7
|
||||
AMD r6[r3]=r1
|
||||
LOD r6@r5
|
||||
ORT r3=0x8
|
||||
DIV r3=r1/r3
|
||||
NAD r3=r2 nand r3
|
||||
NAD r3=r3 nand r3
|
||||
IDX r3=r6[r3]
|
||||
ORT r4=0x4e
|
||||
ORT r7=0x42
|
||||
CMV r7=r4 if r3
|
||||
LOD r6@r7
|
||||
NAD r3=r1 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r3=r6[r3]
|
||||
ORT r7=0x100
|
||||
ADD r3=r7+r3
|
||||
IDX r3=r6[r3]
|
||||
ORT r4=0x40
|
||||
DIV r4=r1/r4
|
||||
NAD r4=r2 nand r4
|
||||
NAD r4=r4 nand r4
|
||||
AMD r6[r4]=r3
|
||||
LOD r6@r5
|
||||
NAD r4=r1 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
IDX r4=r6[r4]
|
||||
ORT r7=0x1
|
||||
ADD r4=r7+r4
|
||||
IDX r3=r3[r4]
|
||||
ORT r4=0x40
|
||||
DIV r4=r1/r4
|
||||
NAD r4=r2 nand r4
|
||||
NAD r4=r4 nand r4
|
||||
AMD r6[r4]=r3
|
||||
LOD r6@r5
|
||||
ORT r3=0x40
|
||||
DIV r3=r1/r3
|
||||
NAD r3=r2 nand r3
|
||||
NAD r3=r3 nand r3
|
||||
IDX r3=r6[r3]
|
||||
ORT r4=0x6f
|
||||
ORT r7=0x63
|
||||
CMV r7=r4 if r3
|
||||
LOD r6@r7
|
||||
NAD r3=r1 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r3=r6[r3]
|
||||
ORT r4=0x8
|
||||
DIV r4=r1/r4
|
||||
NAD r4=r2 nand r4
|
||||
NAD r4=r4 nand r4
|
||||
IDX r4=r6[r4]
|
||||
ORT r7=0x100
|
||||
ADD r4=r7+r4
|
||||
AMD r6[r4]=r3
|
||||
LOD r6@r5
|
||||
ORT r4=0x8
|
||||
DIV r4=r1/r4
|
||||
NAD r4=r2 nand r4
|
||||
NAD r4=r4 nand r4
|
||||
IDX r4=r6[r4]
|
||||
ORT r7=0x1
|
||||
ADD r4=r7+r4
|
||||
NAD r7=r1 nand r2
|
||||
NAD r7=r7 nand r7
|
||||
IDX r7=r6[r7]
|
||||
AMD r3[r4]=r7
|
||||
LOD r6@r5
|
||||
ORT r7=0x8
|
||||
DIV r4=r1/r7
|
||||
DIV r3=r4/r7
|
||||
NAD r4=r4 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
NAD r3=r3 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r4=r6[r4]
|
||||
NAD r7=r1 nand r2
|
||||
NAD r7=r7 nand r7
|
||||
IDX r7=r6[r7]
|
||||
ADD r4=r4+r7
|
||||
AMD r6[r3]=r4
|
||||
LOD r6@r5
|
||||
ORT r7=0x8
|
||||
DIV r4=r1/r7
|
||||
DIV r3=r4/r7
|
||||
NAD r4=r4 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
NAD r3=r3 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r4=r6[r4]
|
||||
NAD r7=r1 nand r2
|
||||
NAD r7=r7 nand r7
|
||||
IDX r7=r6[r7]
|
||||
MUL r4=r4*r7
|
||||
AMD r6[r3]=r4
|
||||
LOD r6@r5
|
||||
ORT r7=0x8
|
||||
DIV r4=r1/r7
|
||||
DIV r3=r4/r7
|
||||
NAD r4=r4 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
NAD r3=r3 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r4=r6[r4]
|
||||
NAD r7=r1 nand r2
|
||||
NAD r7=r7 nand r7
|
||||
IDX r7=r6[r7]
|
||||
DIV r4=r4/r7
|
||||
AMD r6[r3]=r4
|
||||
LOD r6@r5
|
||||
ORT r7=0x8
|
||||
DIV r4=r1/r7
|
||||
DIV r3=r4/r7
|
||||
NAD r4=r4 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
NAD r3=r3 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r4=r6[r4]
|
||||
NAD r7=r1 nand r2
|
||||
NAD r7=r7 nand r7
|
||||
IDX r7=r6[r7]
|
||||
NAD r4=r4 nand r7
|
||||
AMD r6[r3]=r4
|
||||
LOD r6@r5
|
||||
HLT
|
||||
NAD r3=r1 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r3=r6[r3]
|
||||
ADD r7=r7+r3
|
||||
ALC r4 r7
|
||||
AMD r4[r6]=r3
|
||||
ORT r3=0x8
|
||||
DIV r3=r1/r3
|
||||
NAD r3=r2 nand r3
|
||||
NAD r3=r3 nand r3
|
||||
AMD r6[r3]=r4
|
||||
LOD r6@r5
|
||||
NAD r3=r1 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
IDX r3=r6[r3]
|
||||
ABN r3
|
||||
LOD r6@r5
|
||||
NAD r4=r1 nand r2
|
||||
NAD r4=r4 nand r4
|
||||
IDX r4=r6[r4]
|
||||
OUT r4
|
||||
LOD r6@r5
|
||||
INP r4
|
||||
NAD r3=r1 nand r2
|
||||
NAD r3=r3 nand r3
|
||||
AMD r6[r3]=r4
|
||||
LOD r6@r5
|
||||
ORT r4=0x8
|
||||
DIV r4=r1/r4
|
||||
NAD r4=r2 nand r4
|
||||
NAD r4=r4 nand r4
|
||||
IDX r4=r6[r4]
|
||||
ORT r0=0xde
|
||||
ORT r3=0xd8
|
||||
CMV r3=r0 if r4
|
||||
LOD r6@r3
|
||||
NAD r0=r1 nand r2
|
||||
NAD r0=r0 nand r0
|
||||
IDX r0=r6[r0]
|
||||
ORT r7=0x100
|
||||
ADD r0=r0+r7
|
||||
LOD r6@r5
|
||||
ORT r2=0x100
|
||||
IDX r5=r4[r6]
|
||||
ADD r3=r5+r2
|
||||
ALC r3 r3
|
||||
ORT r0=0xec
|
||||
ORT r7=0xe6
|
||||
CMV r0=r7 if r2
|
||||
LOD r6@r0
|
||||
NAD r7=r6 nand r6
|
||||
ADD r2=r7+r2
|
||||
IDX r0=r6[r2]
|
||||
AMD r3[r2]=r0
|
||||
ORT r0=0xe2
|
||||
LOD r6@r0
|
||||
ORT r0=0xf8
|
||||
ORT r2=0xf0
|
||||
CMV r0=r2 if r5
|
||||
LOD r6@r0
|
||||
IDX r0=r4[r5]
|
||||
NAD r7=r6 nand r6
|
||||
ADD r5=r7+r5
|
||||
ORT r7=0x100
|
||||
ADD r7=r5+r7
|
||||
AMD r3[r7]=r0
|
||||
ORT r0=0xec
|
||||
LOD r6@r0
|
||||
ORT r2=0x7
|
||||
NAD r0=r1 nand r2
|
||||
NAD r0=r0 nand r0
|
||||
IDX r0=r6[r0]
|
||||
ADD r0=r0+r7
|
||||
ORT r5=0x12
|
||||
LOD r3@r5
|
||||
IDX r0=r0[r0]
|
56
src/bin/um.rs
Normal file
56
src/bin/um.rs
Normal file
@ -0,0 +1,56 @@
|
||||
extern crate um;
|
||||
use um::cpu::{Cpu};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::fs::File;
|
||||
use std::vec::Vec;
|
||||
use clap::Parser;
|
||||
|
||||
/// Run a um program
|
||||
#[derive(Parser)]
|
||||
struct Cli {
|
||||
/// The path to the program to load
|
||||
program: std::path::PathBuf,
|
||||
}
|
||||
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let args = Cli::parse();
|
||||
|
||||
let mut pgm = Vec::new();
|
||||
|
||||
let mut f = File::open(args.program)?;
|
||||
let mut cont = true;
|
||||
while cont {
|
||||
let mut buffer = [0u8; 4];
|
||||
cont = match f.read(&mut buffer) {
|
||||
Ok(4) => {
|
||||
let num = u32::from_be_bytes(
|
||||
buffer.try_into().unwrap());
|
||||
pgm.push(num);
|
||||
true
|
||||
},
|
||||
Ok(_) => false,
|
||||
Err(_) => false,
|
||||
};
|
||||
}
|
||||
|
||||
let mut c = Cpu::new(pgm);
|
||||
cont = true;
|
||||
println!("start\n{}", c.state());
|
||||
while cont {
|
||||
let r = c.step();
|
||||
cont = match r {
|
||||
Ok(_) => {
|
||||
println!("ok\n{}", c.state());
|
||||
true
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error {:?}", e);
|
||||
false
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
|
||||
}
|
124
src/cpu.rs
Normal file
124
src/cpu.rs
Normal file
@ -0,0 +1,124 @@
|
||||
use std::collections::HashMap;
|
||||
use std::vec::Vec;
|
||||
use crate::instruction::{Instruction, NormalInstruction, SpecialInstruction};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CpuError {
|
||||
ProgramEnd,
|
||||
InvalidInstruction,
|
||||
UnexpectedInput
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cpu {
|
||||
reg: [u32; 8],
|
||||
arr: HashMap<u32, Vec<u32>>,
|
||||
finger: u32,
|
||||
out: Option<u8>,
|
||||
in_reg: Option<u8>
|
||||
}
|
||||
|
||||
|
||||
impl Cpu {
|
||||
pub fn new(pgm: Vec<u32>) -> Cpu {
|
||||
let mut arrays = HashMap::new();
|
||||
arrays.insert(0, pgm);
|
||||
Cpu {
|
||||
reg: [0;8],
|
||||
arr: arrays,
|
||||
finger: 0,
|
||||
in_reg: None,
|
||||
out: None
|
||||
}
|
||||
}
|
||||
|
||||
fn ins(&self) -> Result<Instruction,CpuError> {
|
||||
if self.finger as usize >= self.arr[&0].len() {
|
||||
return Err(CpuError::ProgramEnd);
|
||||
}
|
||||
let d = self.arr[&0][self.finger as usize];
|
||||
if let Ok(i) = Instruction::parse(d) {
|
||||
Ok(i)
|
||||
} else {
|
||||
Err(CpuError::InvalidInstruction)
|
||||
}
|
||||
|
||||
}
|
||||
pub fn output(&self) -> Option<u8> {
|
||||
self.out
|
||||
}
|
||||
|
||||
pub fn expecting_input(&self) -> bool {
|
||||
match self.in_reg {
|
||||
None => false,
|
||||
Some(_) => true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_in(&mut self, value: u8) -> Result<(), CpuError> {
|
||||
match self.in_reg {
|
||||
None => Err(CpuError::UnexpectedInput),
|
||||
Some(i) => {
|
||||
self.reg[i as usize] = value as u32;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn state(&self) -> String {
|
||||
let istr = match self.ins() {
|
||||
Ok(i) => i.fmt(),
|
||||
Err(e) => format!("{:?}", e)
|
||||
};
|
||||
format!("CPU Reg {:?}\nCPU Finger {}\nCPU Ins {}", self.reg, self.finger, istr)
|
||||
}
|
||||
|
||||
fn handle_ortho(&mut self, i:SpecialInstruction) -> Result<(), CpuError>{
|
||||
self.reg[i.a as usize] = i.v as u32;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exec(&mut self, instruction: Instruction)-> Result<(), CpuError>{
|
||||
println!("{:?}", instruction);
|
||||
match instruction {
|
||||
Instruction::Ortho(i) => self.handle_ortho(i),
|
||||
_ => Err(CpuError::InvalidInstruction)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(&mut self) -> Result<(), CpuError>{
|
||||
self.out = None;
|
||||
self.in_reg = None;
|
||||
let i = self.ins()?;
|
||||
self.exec(i)?;
|
||||
self.finger += 1;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests{
|
||||
use super::*;
|
||||
|
||||
fn ezop(op:u32, a:u32, b:u32, c:u32) -> u32 {
|
||||
match op {
|
||||
13 => (op & 0xf) << 28 | (a & 7) << 25 | (b & 0x1ffffff),
|
||||
_ => (op & 0xf) << 28 | (a & 7) << 6 | (b & 7) << 3 | (c & 7)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_ortho() -> Result<(), String> {
|
||||
let pgm = vec!(ezop(13, 3, 1337, 0));
|
||||
let mut c = Cpu::new(pgm);
|
||||
let result = c.step();
|
||||
assert!(matches!(result, Ok(_)));
|
||||
assert_eq!(c.reg[0], 0);
|
||||
assert_eq!(c.reg[3], 1337);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +1,16 @@
|
||||
|
||||
use ux::{u3, u25};
|
||||
|
||||
pub struct ParsingError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NormalInstruction {
|
||||
pub a: u3,
|
||||
pub b: u3,
|
||||
pub c: u3
|
||||
pub a: u8,
|
||||
pub b: u8,
|
||||
pub c: u8
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SpecialInstruction {
|
||||
pub a: u3,
|
||||
pub v: u25
|
||||
pub a: u8,
|
||||
pub v: u32
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -34,8 +31,8 @@ pub enum Instruction {
|
||||
Ortho(SpecialInstruction)
|
||||
}
|
||||
|
||||
const fn u3at(d: u32, pos: u8) -> u3 {
|
||||
u3::new(((d >> pos) & 7) as u8)
|
||||
const fn u3at(d: u32, pos: u8) -> u8 {
|
||||
((d >> pos) & 7) as u8
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
@ -49,21 +46,21 @@ a, i.b, i.c),
|
||||
Instruction::Multiply(i) => format!("MUL r{}=r{}*r{}", i.a, i.b, i.c),
|
||||
Instruction::Divide(i) => format!("DIV r{}=r{}/r{}", i.a, i.b, i.c),
|
||||
Instruction::NotAnd(i) => format!("NAD r{}=r{} nand r{}", i.a, i.b, i.c),
|
||||
Instruction::Halt(i) => format!("HLT"),
|
||||
Instruction::Halt(_i) => format!("HLT"),
|
||||
Instruction::Allocate(i) => format!("ALC r{} r{}", i.b, i.c),
|
||||
Instruction::Abandon(i) => format!("ABN r{}", i.c),
|
||||
Instruction::Output(i) => format!("OUT r{}", i.c),
|
||||
Instruction::Input(i) => format!("INP r{}", i.c),
|
||||
Instruction::Load(i) => format!("LOD r{}@r{}", i.b, i.c),
|
||||
Instruction::Ortho(i) => format!("ORT r{}={}", i.a, i.v)
|
||||
Instruction::Ortho(i) => format!("ORT r{}=0x{:x}", i.a, i.v)
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn parse(d: u32) -> Result<Instruction, ParsingError> {
|
||||
let itype = d >> 28;
|
||||
let (a, b, c, v) = match itype {
|
||||
13 => (u3at(d, 25), u3::new(0), u3::new(0), u25::new(d & 0x1ffffff)),
|
||||
_ => (u3at(d, 6), u3at(d, 3), u3at(d, 0), u25::new(0))
|
||||
13 => (u3at(d, 25), 0, 0, d & 0x1ffffff),
|
||||
_ => (u3at(d, 6), u3at(d, 3), u3at(d, 0), 0)
|
||||
};
|
||||
match itype {
|
||||
0 => Ok(Instruction::ConditionalMove(NormalInstruction{a: a, b: b, c: c})),
|
||||
|
@ -1 +1,2 @@
|
||||
pub mod instruction;
|
||||
pub mod cpu;
|
Loading…
Reference in New Issue
Block a user