working...
This commit is contained in:
parent
d836b3955d
commit
0332001ef8
75 changed files with 427 additions and 1081 deletions
16
ass2/.gitignore
vendored
Normal file
16
ass2/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Dune build artifacts
|
||||
**/_build/
|
||||
**/_install/
|
||||
|
||||
# OCaml compiled files
|
||||
*.cm[iox]
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.exe
|
||||
*.cmi
|
||||
*.cmo
|
||||
*.cmx
|
||||
|
||||
# OCaml package manager / opam
|
||||
*.opam.locked
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
synopsis: "A short synopsis"
|
||||
description: "A longer description"
|
||||
maintainer: ["Maintainer Name <maintainer@example.com>"]
|
||||
authors: ["Author Name <author@example.com>"]
|
||||
license: "LICENSE"
|
||||
tags: ["add topics" "to describe" "your" "project"]
|
||||
homepage: "https://github.com/username/reponame"
|
||||
doc: "https://url/to/documentation"
|
||||
bug-reports: "https://github.com/username/reponame/issues"
|
||||
depends: [
|
||||
"dune" {>= "3.20"}
|
||||
"ocaml"
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
]
|
||||
dev-repo: "git+https://github.com/username/reponame.git"
|
||||
x-maintenance-intent: ["(latest)"]
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
<dummy>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(ocamlc /usr/bin/ocamlc.opt)
|
||||
(ocaml_config_vars (afl_instrument false) (architecture amd64) (asm x86_64-linux-gnu-as) (asm_cfi_supported true) (ast_impl_magic_number Caml1999M030) (ast_intf_magic_number Caml1999N030) (bytecomp_c_compiler "x86_64-linux-gnu-gcc -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security -D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2") (bytecomp_c_libraries "-lm -lpthread") (c_compiler x86_64-linux-gnu-gcc) (ccomp_type cc) (cma_magic_number Caml1999A030) (cmi_magic_number Caml1999I030) (cmo_magic_number Caml1999O030) (cmt_magic_number Caml1999T030) (cmx_magic_number Caml1999Y030) (cmxa_magic_number Caml1999Z030) (cmxs_magic_number Caml1999D030) (default_executable_name a.out) (default_safe_string true) (exec_magic_number Caml1999X030) (ext_asm .s) (ext_dll .so) (ext_exe "") (ext_lib .a) (ext_obj .o) (flambda false) (flat_float_array true) (function_sections true) (host x86_64-pc-linux-gnu) (int_size 63) (linear_magic_number Caml1999L030) (model default) (native_c_compiler "x86_64-linux-gnu-gcc -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security -D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2") (native_c_libraries "-lm ") (native_pack_linker "x86_64-linux-gnu-ld -r -o ") (ocamlc_cflags "-O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security") (ocamlc_cppflags "-D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2") (ocamlopt_cflags "-O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security") (ocamlopt_cppflags "-D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2") (os_type Unix) (ranlib x86_64-linux-gnu-ranlib) (safe_string true) (standard_library /usr/lib/ocaml) (standard_library_default /usr/lib/ocaml) (supports_shared_libraries true) (system linux) (systhread_supported true) (target x86_64-pc-linux-gnu) (version 4.13.1) (windows_unicode false) (with_frame_pointers false) (word_size 64))
|
||||
|
|
@ -1 +0,0 @@
|
|||
((6:ocamlc19:/usr/bin/ocamlc.opt)(17:ocaml_config_vars((14:afl_instrument5:false)(12:architecture5:amd64)(3:asm19:x86_64-linux-gnu-as)(17:asm_cfi_supported4:true)(21:ast_impl_magic_number12:Caml1999M030)(21:ast_intf_magic_number12:Caml1999N030)(19:bytecomp_c_compiler241:x86_64-linux-gnu-gcc -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security -D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2)(20:bytecomp_c_libraries14:-lm -lpthread)(10:c_compiler20:x86_64-linux-gnu-gcc)(10:ccomp_type2:cc)(16:cma_magic_number12:Caml1999A030)(16:cmi_magic_number12:Caml1999I030)(16:cmo_magic_number12:Caml1999O030)(16:cmt_magic_number12:Caml1999T030)(16:cmx_magic_number12:Caml1999Y030)(17:cmxa_magic_number12:Caml1999Z030)(17:cmxs_magic_number12:Caml1999D030)(23:default_executable_name5:a.out)(19:default_safe_string4:true)(17:exec_magic_number12:Caml1999X030)(7:ext_asm2:.s)(7:ext_dll3:.so)(7:ext_exe0:)(7:ext_lib2:.a)(7:ext_obj2:.o)(7:flambda5:false)(16:flat_float_array4:true)(17:function_sections4:true)(4:host19:x86_64-pc-linux-gnu)(8:int_size2:63)(19:linear_magic_number12:Caml1999L030)(5:model7:default)(17:native_c_compiler241:x86_64-linux-gnu-gcc -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security -D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2)(18:native_c_libraries4:-lm )(18:native_pack_linker26:x86_64-linux-gnu-ld -r -o )(13:ocamlc_cflags165:-O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security)(15:ocamlc_cppflags54:-D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2)(15:ocamlopt_cflags165:-O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -g -O2 -ffile-prefix-map=/build/ocaml-SC7b9w/ocaml-4.13.1=. -fstack-protector-strong -Wformat -Werror=format-security)(17:ocamlopt_cppflags54:-D_FILE_OFFSET_BITS=64 -Wdate-time -D_FORTIFY_SOURCE=2)(7:os_type4:Unix)(6:ranlib23:x86_64-linux-gnu-ranlib)(11:safe_string4:true)(16:standard_library14:/usr/lib/ocaml)(24:standard_library_default14:/usr/lib/ocaml)(25:supports_shared_libraries4:true)(6:system5:linux)(19:systhread_supported4:true)(6:target19:x86_64-pc-linux-gnu)(7:version6:4.13.1)(15:windows_unicode5:false)(19:with_frame_pointers5:false)(9:word_size2:64))))
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
(lang dune 3.20)
|
||||
(name SICXE)
|
||||
(sections (lib .) (bin ../../bin))
|
||||
(files (lib (META dune-package opam)) (bin (SICXE)))
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
synopsis: "A short synopsis"
|
||||
description: "A longer description"
|
||||
maintainer: ["Maintainer Name <maintainer@example.com>"]
|
||||
authors: ["Author Name <author@example.com>"]
|
||||
license: "LICENSE"
|
||||
tags: ["add topics" "to describe" "your" "project"]
|
||||
homepage: "https://github.com/username/reponame"
|
||||
doc: "https://url/to/documentation"
|
||||
bug-reports: "https://github.com/username/reponame/issues"
|
||||
depends: [
|
||||
"dune" {>= "3.20"}
|
||||
"ocaml"
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
]
|
||||
dev-repo: "git+https://github.com/username/reponame.git"
|
||||
x-maintenance-intent: ["(latest)"]
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
let () = print_endline "Hello, World!"
|
||||
|
|
@ -1 +0,0 @@
|
|||
(* Auto-generated by Dune *)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
sICXE__OpcodeTable
|
||||
|
|
@ -1 +0,0 @@
|
|||
lib/decoder.ml: Char Hashtbl OpcodeTable
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
sICXE__Decoder
|
||||
sICXE__OpcodeTable
|
||||
|
|
@ -1 +0,0 @@
|
|||
lib/izvajalnik.ml: Bytes Char Decoder OpcodeTable Printf
|
||||
|
|
@ -1 +0,0 @@
|
|||
lib/opcodeTable.ml: Hashtbl
|
||||
Binary file not shown.
|
|
@ -1,10 +0,0 @@
|
|||
(*decoderjeva naloga je pridobiti mnemonic in tip ukaza iz prvega byta z pogledom v hash-table*)
|
||||
let table = OpcodeTable.table
|
||||
|
||||
let decoder (byte1 : char) : OpcodeTable.info =
|
||||
let opcode = (Char.code byte1) land 0xFC in
|
||||
try
|
||||
Hashtbl.find OpcodeTable.table opcode
|
||||
with
|
||||
| Not_found -> failwith "invalid opcode"
|
||||
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
type registers = {
|
||||
mutable a : int;
|
||||
mutable x : int;
|
||||
mutable l : int;
|
||||
mutable b : int;
|
||||
mutable s : int;
|
||||
mutable t : int;
|
||||
mutable f : int;
|
||||
mutable pc : int;
|
||||
mutable sw : int
|
||||
}
|
||||
(*tip state predstavlja stanje SIC/XE, z pomnilnikom in registri*)
|
||||
type state = {
|
||||
regs : registers;
|
||||
memory : Bytes.t
|
||||
}
|
||||
|
||||
type nixbpe = {
|
||||
n : int;
|
||||
i : int;
|
||||
x : int;
|
||||
b : int;
|
||||
p : int;
|
||||
e : int
|
||||
}
|
||||
|
||||
(*kreiramo začetno stanje*)
|
||||
let regs = {a = 0; x = 0; l = 0; b = 0; s = 0; t = 0; f = 0; pc = 0; sw = 0}
|
||||
let memSize = 1 lsl 20 (*2^20*)
|
||||
let memory = Bytes.make memSize '\x00' (*mutbale kos pomnilnika velikosti memSize*)
|
||||
let state = {regs; memory}
|
||||
|
||||
|
||||
(*----Funkcije izvajalnika----*)
|
||||
(*TODO - brali bomo vedno relativno od začetka instrukcije, PC bomo na koncu ukaza povečali za pravo velikost!*)
|
||||
|
||||
(*funkcije za javljanje napak*)
|
||||
let notImplemented (mnemonic : string) = Printf.printf "mnemonic %s is not implemented!\n" mnemonic
|
||||
let invalidOpcode (opcode : int) = Printf.printf "opcode %d is invalid!\n" opcode
|
||||
let invalidAdressing () = Printf.printf "invalid adressing!\n"
|
||||
|
||||
(*beri in povisaj PC*)
|
||||
let fetch (state : state) : char =
|
||||
let byte = Bytes.get state.memory state.regs.pc in
|
||||
state.regs.pc <- state.regs.pc + 1;
|
||||
byte
|
||||
|
||||
(*beri za offset in ne povecaj PC*)
|
||||
let readMem (state : state) (offset : int) : char =
|
||||
Bytes.get state.memory (state.regs.pc + offset)
|
||||
|
||||
|
||||
(*beri drugi byte ukaza formata 2 in vrni r1 in r2, kot int njunih vrednosti (reg a -> 1, reg x -> 2 ...)*)
|
||||
let readR1R2 (state : state) : (int * int) =
|
||||
let byte2 = Char.code (readMem state 1) in
|
||||
let highNibble = (byte2 land 0xF0) lsr 4 in (*pridobi prvi nibble*)
|
||||
let lowNibble = byte2 land 0x0F in (*pridobi drugi nibble*)
|
||||
(highNibble, lowNibble)
|
||||
|
||||
(*preberi byta 1 in 2 in dobi nixbpe bite*)
|
||||
let getNIXBPE (state : state) : nixbpe =
|
||||
let byte1 = Char.code (readMem state 0) in
|
||||
let byte2 = Char.code (readMem state 1) in
|
||||
{n = (byte1 lsr 1) land 1;
|
||||
i = byte1 land 1;
|
||||
x = (byte2 lsr 7) land 1;
|
||||
b = (byte2 lsr 6) land 1;
|
||||
p = (byte2 lsr 5) land 1;
|
||||
e = (byte2 lsr 4) land 1;}
|
||||
|
||||
|
||||
let getAddress (state : state) : int =
|
||||
42
|
||||
|
||||
|
||||
(*execute format 1*)
|
||||
let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
match mnemonic with
|
||||
| FIX -> notImplemented "FIX"
|
||||
| FLOAT -> notImplemented "FLOAT"
|
||||
| HIO -> notImplemented "HIO"
|
||||
| NORM -> notImplemented "NORM"
|
||||
| SIO -> notImplemented "SIO"
|
||||
| TIO -> notImplemented "TIO"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 1")
|
||||
|
||||
|
||||
|
||||
(*execute format 2*)
|
||||
let executeFormat2 (state: state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let (r1, r2) = readR1R2 state in
|
||||
match mnemonic with
|
||||
| ADDR -> notImplemented "ADD" (*when implemented: -> add state r1 r2*)
|
||||
| CLEAR -> notImplemented "CLEAR"
|
||||
| COMPR -> notImplemented "F2"
|
||||
| DIVR -> notImplemented "F2"
|
||||
| MULR -> notImplemented "F2"
|
||||
| RMO -> notImplemented "F2"
|
||||
| SHIFTL -> notImplemented "F2"
|
||||
| SHIFTR -> notImplemented "F2"
|
||||
| SUBR -> notImplemented "F2"
|
||||
| SVC -> notImplemented "F2"
|
||||
| TIXR -> notImplemented "F2"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 2")
|
||||
|
||||
|
||||
(*execute Format 3*)
|
||||
let executeFormat3 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = getAddress state in
|
||||
match mnemonic with
|
||||
| ADD -> notImplemented "ADD3"
|
||||
| ADDF -> notImplemented "ADDF4"
|
||||
| AND -> notImplemented "AND4"
|
||||
| COMP -> notImplemented "COMP4"
|
||||
| COMPF -> notImplemented "COMPF4"
|
||||
| DIV -> notImplemented "DIV4"
|
||||
| MUL -> notImplemented "MUL4"
|
||||
| OR -> notImplemented "OR4"
|
||||
| SUB -> notImplemented "SUB4"
|
||||
| SUBF -> notImplemented "SUBF4"
|
||||
| TD -> notImplemented "TD4"
|
||||
| WD -> notImplemented "WD4"
|
||||
|
||||
(* Jump / subroutine *)
|
||||
| J -> notImplemented "J4"
|
||||
| JEQ -> notImplemented "JEQ4"
|
||||
| JGT -> notImplemented "JGT4"
|
||||
| JLT -> notImplemented "JLT4"
|
||||
| JSUB -> notImplemented "JSUB4"
|
||||
| RSUB -> notImplemented "RSUB4"
|
||||
|
||||
(* Load/store *)
|
||||
| LDA -> notImplemented "LDA4"
|
||||
| LDB -> notImplemented "LDB4"
|
||||
| LDCH -> notImplemented "LDCH4"
|
||||
| LDF -> notImplemented "LDF4"
|
||||
| LDL -> notImplemented "LDL4"
|
||||
| LDS -> notImplemented "LDS4"
|
||||
| LDT -> notImplemented "LDT4"
|
||||
| LDX -> notImplemented "LDX4"
|
||||
| LPS -> notImplemented "LPS4"
|
||||
| STA -> notImplemented "STA4"
|
||||
| STB -> notImplemented "STB4"
|
||||
| STCH -> notImplemented "STCH4"
|
||||
| STF -> notImplemented "STF4"
|
||||
| STL -> notImplemented "STL4"
|
||||
| STS -> notImplemented "STS4"
|
||||
| STSW -> notImplemented "STSW4"
|
||||
| STT -> notImplemented "STT4"
|
||||
| STX -> notImplemented "STX4"
|
||||
|
||||
(* Control / IO *)
|
||||
| TIX -> notImplemented "TIX4"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
|
||||
|
||||
|
||||
let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = getAddress state in
|
||||
match mnemonic with
|
||||
(*aritmetika*)
|
||||
| ADD -> notImplemented "ADD4"
|
||||
| ADDF -> notImplemented "ADDF4"
|
||||
| AND -> notImplemented "AND4"
|
||||
| COMP -> notImplemented "COMP4"
|
||||
| COMPF -> notImplemented "COMPF4"
|
||||
| DIV -> notImplemented "DIV4"
|
||||
| MUL -> notImplemented "MUL4"
|
||||
| OR -> notImplemented "OR4"
|
||||
| SUB -> notImplemented "SUB4"
|
||||
| SUBF -> notImplemented "SUBF4"
|
||||
| TD -> notImplemented "TD4"
|
||||
| WD -> notImplemented "WD4"
|
||||
|
||||
(* Jump / subroutine *)
|
||||
| J -> notImplemented "J4"
|
||||
| JEQ -> notImplemented "JEQ4"
|
||||
| JGT -> notImplemented "JGT4"
|
||||
| JLT -> notImplemented "JLT4"
|
||||
| JSUB -> notImplemented "JSUB4"
|
||||
| RSUB -> notImplemented "RSUB4"
|
||||
|
||||
(* Load/store *)
|
||||
| LDA -> notImplemented "LDA4"
|
||||
| LDB -> notImplemented "LDB4"
|
||||
| LDCH -> notImplemented "LDCH4"
|
||||
| LDF -> notImplemented "LDF4"
|
||||
| LDL -> notImplemented "LDL4"
|
||||
| LDS -> notImplemented "LDS4"
|
||||
| LDT -> notImplemented "LDT4"
|
||||
| LDX -> notImplemented "LDX4"
|
||||
| LPS -> notImplemented "LPS4"
|
||||
| STA -> notImplemented "STA4"
|
||||
| STB -> notImplemented "STB4"
|
||||
| STCH -> notImplemented "STCH4"
|
||||
| STF -> notImplemented "STF4"
|
||||
| STL -> notImplemented "STL4"
|
||||
| STS -> notImplemented "STS4"
|
||||
| STSW -> notImplemented "STSW4"
|
||||
| STT -> notImplemented "STT4"
|
||||
| STX -> notImplemented "STX4"
|
||||
|
||||
(* Control / IO *)
|
||||
| TIX -> notImplemented "TIX4"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 4")
|
||||
|
||||
|
||||
|
||||
|
||||
(*execute format 3_4*)
|
||||
let executeFormat3_4 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let nixbpe = getNIXBPE state in
|
||||
match nixbpe.e with
|
||||
| 0 -> executeFormat3 state nixbpe mnemonic
|
||||
| 1 -> executeFormat4 state nixbpe mnemonic
|
||||
| _ -> failwith "invalid computation of nxbpe"
|
||||
|
||||
|
||||
(*execute ukaza*)
|
||||
let execute (state : state) : unit =
|
||||
let byte1 = readMem state 0 in (*read the 1st byte of the instruction*)
|
||||
try
|
||||
let {OpcodeTable.mnemonic; OpcodeTable.format} = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*)
|
||||
match format with
|
||||
| F1 -> executeFormat1 state mnemonic
|
||||
| F2 -> executeFormat2 state mnemonic
|
||||
| F3_4 -> executeFormat3_4 state mnemonic
|
||||
with
|
||||
| Failure msg -> byte1 |> Char.code |> invalidOpcode
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
(*opcode hash table, formati ukazov in mnemoniki*)
|
||||
type mnemonic =
|
||||
(* Format 1 *)
|
||||
| FIX | FLOAT | HIO | NORM | SIO | TIO
|
||||
|
||||
(* Format 2 *)
|
||||
| ADDR | CLEAR | COMPR | DIVR | MULR | RMO
|
||||
| SHIFTL | SHIFTR | SUBR | SVC | TIXR
|
||||
|
||||
(* Format 3/4 *)
|
||||
| ADD | ADDF | AND | COMP | COMPF | DIV
|
||||
| J | JEQ | JGT | JLT | JSUB | LDA | LDB | LDCH | LDF
|
||||
| LDL | LDS | LDT | LDX | LPS | MUL | OR | RD
|
||||
| RSUB | STA | STB | STCH | STF | STL | STS | STSW
|
||||
| STT | STX | SUB | SUBF | TD | TIX | WD
|
||||
|
||||
type format =
|
||||
| F1
|
||||
| F2
|
||||
| F3_4
|
||||
|
||||
type info = {
|
||||
mnemonic : mnemonic;
|
||||
format : format;
|
||||
}
|
||||
|
||||
(* Opcode table *)
|
||||
|
||||
let table : (int, info) Hashtbl.t = Hashtbl.create 128
|
||||
|
||||
let () =
|
||||
let add op mnemonic format =
|
||||
Hashtbl.add table op { mnemonic; format }
|
||||
in
|
||||
|
||||
(*Format 1 Instructions*)
|
||||
add 0xC4 FIX F1;
|
||||
add 0xC0 FLOAT F1;
|
||||
add 0xC8 HIO F1;
|
||||
add 0xC1 NORM F1;
|
||||
add 0xF0 SIO F1;
|
||||
add 0xF8 TIO F1;
|
||||
|
||||
(*Format 2 Instructions*)
|
||||
add 0x90 ADDR F2;
|
||||
add 0xB4 CLEAR F2;
|
||||
add 0xA0 COMPR F2;
|
||||
add 0x9C DIVR F2;
|
||||
add 0x98 MULR F2;
|
||||
add 0xAC RMO F2;
|
||||
add 0xA4 SHIFTL F2;
|
||||
add 0xA8 SHIFTR F2;
|
||||
add 0x94 SUBR F2;
|
||||
add 0xB0 SVC F2;
|
||||
add 0xB8 TIXR F2;
|
||||
|
||||
(*Format 3/4 Instructions*)
|
||||
add 0x18 ADD F3_4;
|
||||
add 0x58 ADDF F3_4;
|
||||
add 0x40 AND F3_4;
|
||||
add 0x28 COMP F3_4;
|
||||
add 0x88 COMPF F3_4;
|
||||
add 0x24 DIV F3_4;
|
||||
add 0x3C J F3_4;
|
||||
add 0x30 JEQ F3_4;
|
||||
add 0x34 JGT F3_4;
|
||||
add 0x38 JLT F3_4;
|
||||
add 0x48 JSUB F3_4;
|
||||
add 0x00 LDA F3_4;
|
||||
add 0x68 LDB F3_4;
|
||||
add 0x50 LDCH F3_4;
|
||||
add 0x70 LDF F3_4;
|
||||
add 0x08 LDL F3_4;
|
||||
add 0x6C LDS F3_4;
|
||||
add 0x74 LDT F3_4;
|
||||
add 0x04 LDX F3_4;
|
||||
add 0xD0 LPS F3_4;
|
||||
add 0x20 MUL F3_4;
|
||||
add 0x44 OR F3_4;
|
||||
add 0xD8 RD F3_4;
|
||||
add 0x4C RSUB F3_4;
|
||||
add 0x0C STA F3_4;
|
||||
add 0x78 STB F3_4;
|
||||
add 0x54 STCH F3_4;
|
||||
add 0x80 STF F3_4;
|
||||
add 0x14 STL F3_4;
|
||||
add 0x7C STS F3_4;
|
||||
add 0xE8 STSW F3_4;
|
||||
add 0x84 STT F3_4;
|
||||
add 0x10 STX F3_4;
|
||||
add 0x1C SUB F3_4;
|
||||
add 0x5C SUBF F3_4;
|
||||
add 0xE0 TD F3_4;
|
||||
add 0x2C TIX F3_4;
|
||||
add 0xDC WD F3_4;
|
||||
()
|
||||
|
||||
(*mnemonic to string*)
|
||||
let string_of_mnemonic = function
|
||||
(* Format 1 *)
|
||||
| FIX -> "FIX"
|
||||
| FLOAT -> "FLOAT"
|
||||
| HIO -> "HIO"
|
||||
| NORM -> "NORM"
|
||||
| SIO -> "SIO"
|
||||
| TIO -> "TIO"
|
||||
|
||||
(* Format 2 *)
|
||||
| ADDR -> "ADDR"
|
||||
| CLEAR -> "CLEAR"
|
||||
| COMPR -> "COMPR"
|
||||
| DIVR -> "DIVR"
|
||||
| MULR -> "MULR"
|
||||
| RMO -> "RMO"
|
||||
| SHIFTL -> "SHIFTL"
|
||||
| SHIFTR -> "SHIFTR"
|
||||
| SUBR -> "SUBR"
|
||||
| SVC -> "SVC"
|
||||
| TIXR -> "TIXR"
|
||||
|
||||
(* Format 3/4 *)
|
||||
| ADD -> "ADD"
|
||||
| ADDF -> "ADDF"
|
||||
| AND -> "AND"
|
||||
| COMP -> "COMP"
|
||||
| COMPF -> "COMPF"
|
||||
| DIV -> "DIV"
|
||||
| J -> "J"
|
||||
| JEQ -> "JEQ"
|
||||
| JGT -> "JGT"
|
||||
| JLT -> "JLT"
|
||||
| JSUB -> "JSUB"
|
||||
| LDA -> "LDA"
|
||||
| LDB -> "LDB"
|
||||
| LDCH -> "LDCH"
|
||||
| LDF -> "LDF"
|
||||
| LDL -> "LDL"
|
||||
| LDS -> "LDS"
|
||||
| LDT -> "LDT"
|
||||
| LDX -> "LDX"
|
||||
| LPS -> "LPS"
|
||||
| MUL -> "MUL"
|
||||
| OR -> "OR"
|
||||
| RD -> "RD"
|
||||
| RSUB -> "RSUB"
|
||||
| STA -> "STA"
|
||||
| STB -> "STB"
|
||||
| STCH -> "STCH"
|
||||
| STF -> "STF"
|
||||
| STL -> "STL"
|
||||
| STS -> "STS"
|
||||
| STSW -> "STSW"
|
||||
| STT -> "STT"
|
||||
| STX -> "STX"
|
||||
| SUB -> "SUB"
|
||||
| SUBF -> "SUBF"
|
||||
| TD -> "TD"
|
||||
| TIX -> "TIX"
|
||||
| WD -> "WD"
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
(* generated by dune *)
|
||||
|
||||
(** @canonical SICXE.Decoder *)
|
||||
module Decoder = SICXE__Decoder
|
||||
|
||||
(** @canonical SICXE.Izvajalnik *)
|
||||
module Izvajalnik = SICXE__Izvajalnik
|
||||
|
||||
(** @canonical SICXE.OpcodeTable *)
|
||||
module OpcodeTable = SICXE__OpcodeTable
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
(* Auto-generated by Dune *)
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../default/META.SICXE
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../default/SICXE.dune-package
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../../../default/SICXE.opam
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
# dune build
|
||||
# OCAMLPARAM: unset
|
||||
# Shared cache: enabled-except-user-rules
|
||||
# Shared cache location: /home/jaka/.cache/dune/db
|
||||
# Workspace root: /mnt/c/Programiranje/SPO/ass2/SICocaml/SICXE
|
||||
# Auto-detected concurrency: 16
|
||||
# Dune context:
|
||||
# { name = "default"
|
||||
# ; kind = "default"
|
||||
# ; profile = Dev
|
||||
# ; merlin = true
|
||||
# ; fdo_target_exe = None
|
||||
# ; build_dir = In_build_dir "default"
|
||||
# ; instrument_with = []
|
||||
# }
|
||||
$ /usr/bin/ocamlc.opt -config > /tmp/dune_71502d_output
|
||||
# Promoting "_build/default/SICXE.opam" to "SICXE.opam"
|
||||
$ (cd _build/default && /usr/bin/ocamlc.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -w -49 -nopervasives -nostdlib -g -bin-annot -I lib/.SICXE.objs/byte -no-alias-deps -opaque -o lib/.SICXE.objs/byte/sICXE.cmo -c -impl lib/sICXE.ml-gen)
|
||||
$ (cd _build/default && /usr/bin/ocamldep.opt -modules -impl lib/opcodeTable.ml) > _build/default/lib/.SICXE.objs/sICXE__OpcodeTable.impl.d
|
||||
$ (cd _build/default && /usr/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -w -49 -nopervasives -nostdlib -g -I lib/.SICXE.objs/byte -I lib/.SICXE.objs/native -intf-suffix .ml-gen -no-alias-deps -opaque -o lib/.SICXE.objs/native/sICXE.cmx -c -impl lib/sICXE.ml-gen)
|
||||
$ (cd _build/default && /usr/bin/ocamldep.opt -modules -impl lib/decoder.ml) > _build/default/lib/.SICXE.objs/sICXE__Decoder.impl.d
|
||||
$ (cd _build/default && /usr/bin/ocamldep.opt -modules -impl lib/izvajalnik.ml) > _build/default/lib/.SICXE.objs/sICXE__Izvajalnik.impl.d
|
||||
$ (cd _build/default && /usr/bin/ocamlc.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I lib/.SICXE.objs/byte -no-alias-deps -opaque -open SICXE -o lib/.SICXE.objs/byte/sICXE__OpcodeTable.cmo -c -impl lib/opcodeTable.ml)
|
||||
$ (cd _build/default && /usr/bin/ocamlc.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I test/.test_SICXE.eobjs/byte -no-alias-deps -opaque -o test/.test_SICXE.eobjs/byte/dune__exe__Test_SICXE.cmi -c -intf test/test_SICXE.mli)
|
||||
$ (cd _build/default && /usr/bin/ocamlc.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I lib/.SICXE.objs/byte -no-alias-deps -opaque -open SICXE -o lib/.SICXE.objs/byte/sICXE__Decoder.cmo -c -impl lib/decoder.ml)
|
||||
$ (cd _build/default && /usr/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -I lib/.SICXE.objs/byte -I lib/.SICXE.objs/native -intf-suffix .ml -no-alias-deps -opaque -open SICXE -o lib/.SICXE.objs/native/sICXE__OpcodeTable.cmx -c -impl lib/opcodeTable.ml)
|
||||
$ (cd _build/default && /usr/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -I test/.test_SICXE.eobjs/byte -I test/.test_SICXE.eobjs/native -intf-suffix .ml -no-alias-deps -opaque -o test/.test_SICXE.eobjs/native/dune__exe__Test_SICXE.cmx -c -impl test/test_SICXE.ml)
|
||||
$ (cd _build/default && /usr/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -I lib/.SICXE.objs/byte -I lib/.SICXE.objs/native -intf-suffix .ml -no-alias-deps -opaque -open SICXE -o lib/.SICXE.objs/native/sICXE__Decoder.cmx -c -impl lib/decoder.ml)
|
||||
$ (cd _build/default && /usr/bin/ocamlc.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I lib/.SICXE.objs/byte -no-alias-deps -opaque -open SICXE -o lib/.SICXE.objs/byte/sICXE__Izvajalnik.cmo -c -impl lib/izvajalnik.ml)
|
||||
> File "lib/izvajalnik.ml", line 72, characters 16-21:
|
||||
> 72 | let getAddress (state : state) : int =
|
||||
> ^^^^^
|
||||
> Error (warning 27 [unused-var-strict]): unused variable state.
|
||||
> File "lib/izvajalnik.ml", line 77, characters 20-25:
|
||||
> 77 | let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
> ^^^^^
|
||||
> Error (warning 27 [unused-var-strict]): unused variable state.
|
||||
> File "lib/izvajalnik.ml", line 91, characters 7-9:
|
||||
> 91 | let (r1, r2) = readR1R2 state in
|
||||
> ^^
|
||||
> Error (warning 26 [unused-var]): unused variable r1.
|
||||
> File "lib/izvajalnik.ml", line 91, characters 11-13:
|
||||
> 91 | let (r1, r2) = readR1R2 state in
|
||||
> ^^
|
||||
> Error (warning 26 [unused-var]): unused variable r2.
|
||||
> File "lib/izvajalnik.ml", line 108, characters 36-42:
|
||||
> 108 | let executeFormat3 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
> ^^^^^^
|
||||
> Error (warning 27 [unused-var-strict]): unused variable nixbpe.
|
||||
> File "lib/izvajalnik.ml", line 109, characters 6-13:
|
||||
> 109 | let address = getAddress state in
|
||||
> ^^^^^^^
|
||||
> Error (warning 26 [unused-var]): unused variable address.
|
||||
> File "lib/izvajalnik.ml", line 157, characters 36-42:
|
||||
> 157 | let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
> ^^^^^^
|
||||
> Error (warning 27 [unused-var-strict]): unused variable nixbpe.
|
||||
> File "lib/izvajalnik.ml", line 158, characters 6-13:
|
||||
> 158 | let address = getAddress state in
|
||||
> ^^^^^^^
|
||||
> Error (warning 26 [unused-var]): unused variable address.
|
||||
> File "lib/izvajalnik.ml", line 228, characters 14-17:
|
||||
> 228 | | Failure msg -> byte1 |> Char.code |> invalidOpcode
|
||||
> ^^^
|
||||
> Error (warning 27 [unused-var-strict]): unused variable msg.
|
||||
[2]
|
||||
$ (cd _build/default && /usr/bin/ocamlopt.opt -w @1..3@5..28@31..39@43@46..47@49..57@61..62@67@69-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -o test/test_SICXE.exe test/.test_SICXE.eobjs/native/dune__exe__Test_SICXE.cmx)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
(executable
|
||||
(public_name SICXE)
|
||||
(name main)
|
||||
(libraries SICXE))
|
||||
|
|
@ -1 +0,0 @@
|
|||
let () = print_endline "Hello, World!"
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
(lang dune 3.20)
|
||||
|
||||
(name SICXE)
|
||||
|
||||
(generate_opam_files true)
|
||||
|
||||
(source
|
||||
(github username/reponame))
|
||||
|
||||
(authors "Author Name <author@example.com>")
|
||||
|
||||
(maintainers "Maintainer Name <maintainer@example.com>")
|
||||
|
||||
(license LICENSE)
|
||||
|
||||
(documentation https://url/to/documentation)
|
||||
|
||||
(package
|
||||
(name SICXE)
|
||||
(synopsis "A short synopsis")
|
||||
(description "A longer description")
|
||||
(depends ocaml)
|
||||
(tags
|
||||
("add topics" "to describe" your project)))
|
||||
|
||||
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
(*decoderjeva naloga je pridobiti mnemonic in tip ukaza iz prvega byta z pogledom v hash-table*)
|
||||
let table = OpcodeTable.table
|
||||
|
||||
let decoder (byte1 : char) : OpcodeTable.info =
|
||||
let opcode = (Char.code byte1) land 0xFC in
|
||||
try
|
||||
Hashtbl.find OpcodeTable.table opcode
|
||||
with
|
||||
| Not_found -> failwith "invalid opcode"
|
||||
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(library
|
||||
(name SICXE))
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
type registers = {
|
||||
mutable a : int;
|
||||
mutable x : int;
|
||||
mutable l : int;
|
||||
mutable b : int;
|
||||
mutable s : int;
|
||||
mutable t : int;
|
||||
mutable f : int;
|
||||
mutable pc : int;
|
||||
mutable sw : int
|
||||
}
|
||||
(*tip state predstavlja stanje SIC/XE, z pomnilnikom in registri*)
|
||||
type state = {
|
||||
regs : registers;
|
||||
memory : Bytes.t
|
||||
}
|
||||
|
||||
type nixbpe = {
|
||||
n : int;
|
||||
i : int;
|
||||
x : int;
|
||||
b : int;
|
||||
p : int;
|
||||
e : int
|
||||
}
|
||||
|
||||
(*kreiramo začetno stanje*)
|
||||
let regs = {a = 0; x = 0; l = 0; b = 0; s = 0; t = 0; f = 0; pc = 0; sw = 0}
|
||||
let memSize = 1 lsl 20 (*2^20*)
|
||||
let memory = Bytes.make memSize '\x00' (*mutbale kos pomnilnika velikosti memSize*)
|
||||
let state = {regs; memory}
|
||||
|
||||
|
||||
(*----Funkcije izvajalnika----*)
|
||||
(*TODO - brali bomo vedno relativno od začetka instrukcije, PC bomo na koncu ukaza povečali za pravo velikost!*)
|
||||
|
||||
(*funkcije za javljanje napak*)
|
||||
let notImplemented (mnemonic : string) = Printf.printf "mnemonic %s is not implemented!\n" mnemonic
|
||||
let invalidOpcode (opcode : int) = Printf.printf "opcode %d is invalid!\n" opcode
|
||||
let invalidAdressing () = Printf.printf "invalid adressing!\n"
|
||||
|
||||
(*beri in povisaj PC*)
|
||||
let fetch (state : state) : char =
|
||||
let byte = Bytes.get state.memory state.regs.pc in
|
||||
state.regs.pc <- state.regs.pc + 1;
|
||||
byte
|
||||
|
||||
(*beri za offset in ne povecaj PC*)
|
||||
let readMem (state : state) (offset : int) : char =
|
||||
Bytes.get state.memory (state.regs.pc + offset)
|
||||
|
||||
|
||||
(*beri drugi byte ukaza formata 2 in vrni r1 in r2, kot int njunih vrednosti (reg a -> 1, reg x -> 2 ...)*)
|
||||
let readR1R2 (state : state) : (int * int) =
|
||||
let byte2 = Char.code (readMem state 1) in
|
||||
let highNibble = (byte2 land 0xF0) lsr 4 in (*pridobi prvi nibble*)
|
||||
let lowNibble = byte2 land 0x0F in (*pridobi drugi nibble*)
|
||||
(highNibble, lowNibble)
|
||||
|
||||
(*preberi byta 1 in 2 in dobi nixbpe bite*)
|
||||
let getNIXBPE (state : state) : nixbpe =
|
||||
let byte1 = Char.code (readMem state 0) in
|
||||
let byte2 = Char.code (readMem state 1) in
|
||||
{n = (byte1 lsr 1) land 1;
|
||||
i = byte1 land 1;
|
||||
x = (byte2 lsr 7) land 1;
|
||||
b = (byte2 lsr 6) land 1;
|
||||
p = (byte2 lsr 5) land 1;
|
||||
e = (byte2 lsr 4) land 1;}
|
||||
|
||||
|
||||
let getAddress (state : state) : int =
|
||||
42
|
||||
|
||||
|
||||
(*execute format 1*)
|
||||
let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
match mnemonic with
|
||||
| FIX -> notImplemented "FIX"
|
||||
| FLOAT -> notImplemented "FLOAT"
|
||||
| HIO -> notImplemented "HIO"
|
||||
| NORM -> notImplemented "NORM"
|
||||
| SIO -> notImplemented "SIO"
|
||||
| TIO -> notImplemented "TIO"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 1")
|
||||
|
||||
|
||||
|
||||
(*execute format 2*)
|
||||
let executeFormat2 (state: state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let (r1, r2) = readR1R2 state in
|
||||
match mnemonic with
|
||||
| ADDR -> notImplemented "ADD" (*when implemented: -> add state r1 r2*)
|
||||
| CLEAR -> notImplemented "CLEAR"
|
||||
| COMPR -> notImplemented "F2"
|
||||
| DIVR -> notImplemented "F2"
|
||||
| MULR -> notImplemented "F2"
|
||||
| RMO -> notImplemented "F2"
|
||||
| SHIFTL -> notImplemented "F2"
|
||||
| SHIFTR -> notImplemented "F2"
|
||||
| SUBR -> notImplemented "F2"
|
||||
| SVC -> notImplemented "F2"
|
||||
| TIXR -> notImplemented "F2"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 2")
|
||||
|
||||
|
||||
(*execute Format 3*)
|
||||
let executeFormat3 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = getAddress state in
|
||||
match mnemonic with
|
||||
| ADD -> notImplemented "ADD3"
|
||||
| ADDF -> notImplemented "ADDF4"
|
||||
| AND -> notImplemented "AND4"
|
||||
| COMP -> notImplemented "COMP4"
|
||||
| COMPF -> notImplemented "COMPF4"
|
||||
| DIV -> notImplemented "DIV4"
|
||||
| MUL -> notImplemented "MUL4"
|
||||
| OR -> notImplemented "OR4"
|
||||
| SUB -> notImplemented "SUB4"
|
||||
| SUBF -> notImplemented "SUBF4"
|
||||
| TD -> notImplemented "TD4"
|
||||
| WD -> notImplemented "WD4"
|
||||
|
||||
(* Jump / subroutine *)
|
||||
| J -> notImplemented "J4"
|
||||
| JEQ -> notImplemented "JEQ4"
|
||||
| JGT -> notImplemented "JGT4"
|
||||
| JLT -> notImplemented "JLT4"
|
||||
| JSUB -> notImplemented "JSUB4"
|
||||
| RSUB -> notImplemented "RSUB4"
|
||||
|
||||
(* Load/store *)
|
||||
| LDA -> notImplemented "LDA4"
|
||||
| LDB -> notImplemented "LDB4"
|
||||
| LDCH -> notImplemented "LDCH4"
|
||||
| LDF -> notImplemented "LDF4"
|
||||
| LDL -> notImplemented "LDL4"
|
||||
| LDS -> notImplemented "LDS4"
|
||||
| LDT -> notImplemented "LDT4"
|
||||
| LDX -> notImplemented "LDX4"
|
||||
| LPS -> notImplemented "LPS4"
|
||||
| STA -> notImplemented "STA4"
|
||||
| STB -> notImplemented "STB4"
|
||||
| STCH -> notImplemented "STCH4"
|
||||
| STF -> notImplemented "STF4"
|
||||
| STL -> notImplemented "STL4"
|
||||
| STS -> notImplemented "STS4"
|
||||
| STSW -> notImplemented "STSW4"
|
||||
| STT -> notImplemented "STT4"
|
||||
| STX -> notImplemented "STX4"
|
||||
|
||||
(* Control / IO *)
|
||||
| TIX -> notImplemented "TIX4"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
|
||||
|
||||
|
||||
let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = getAddress state in
|
||||
match mnemonic with
|
||||
(*aritmetika*)
|
||||
| ADD -> notImplemented "ADD4"
|
||||
| ADDF -> notImplemented "ADDF4"
|
||||
| AND -> notImplemented "AND4"
|
||||
| COMP -> notImplemented "COMP4"
|
||||
| COMPF -> notImplemented "COMPF4"
|
||||
| DIV -> notImplemented "DIV4"
|
||||
| MUL -> notImplemented "MUL4"
|
||||
| OR -> notImplemented "OR4"
|
||||
| SUB -> notImplemented "SUB4"
|
||||
| SUBF -> notImplemented "SUBF4"
|
||||
| TD -> notImplemented "TD4"
|
||||
| WD -> notImplemented "WD4"
|
||||
|
||||
(* Jump / subroutine *)
|
||||
| J -> notImplemented "J4"
|
||||
| JEQ -> notImplemented "JEQ4"
|
||||
| JGT -> notImplemented "JGT4"
|
||||
| JLT -> notImplemented "JLT4"
|
||||
| JSUB -> notImplemented "JSUB4"
|
||||
| RSUB -> notImplemented "RSUB4"
|
||||
|
||||
(* Load/store *)
|
||||
| LDA -> notImplemented "LDA4"
|
||||
| LDB -> notImplemented "LDB4"
|
||||
| LDCH -> notImplemented "LDCH4"
|
||||
| LDF -> notImplemented "LDF4"
|
||||
| LDL -> notImplemented "LDL4"
|
||||
| LDS -> notImplemented "LDS4"
|
||||
| LDT -> notImplemented "LDT4"
|
||||
| LDX -> notImplemented "LDX4"
|
||||
| LPS -> notImplemented "LPS4"
|
||||
| STA -> notImplemented "STA4"
|
||||
| STB -> notImplemented "STB4"
|
||||
| STCH -> notImplemented "STCH4"
|
||||
| STF -> notImplemented "STF4"
|
||||
| STL -> notImplemented "STL4"
|
||||
| STS -> notImplemented "STS4"
|
||||
| STSW -> notImplemented "STSW4"
|
||||
| STT -> notImplemented "STT4"
|
||||
| STX -> notImplemented "STX4"
|
||||
|
||||
(* Control / IO *)
|
||||
| TIX -> notImplemented "TIX4"
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 4")
|
||||
|
||||
|
||||
|
||||
|
||||
(*execute format 3_4*)
|
||||
let executeFormat3_4 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let nixbpe = getNIXBPE state in
|
||||
match nixbpe.e with
|
||||
| 0 -> executeFormat3 state nixbpe mnemonic
|
||||
| 1 -> executeFormat4 state nixbpe mnemonic
|
||||
| _ -> failwith "invalid computation of nxbpe"
|
||||
|
||||
|
||||
(*execute ukaza*)
|
||||
let execute (state : state) : unit =
|
||||
let byte1 = readMem state 0 in (*read the 1st byte of the instruction*)
|
||||
try
|
||||
let {OpcodeTable.mnemonic; OpcodeTable.format} = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*)
|
||||
match format with
|
||||
| F1 -> executeFormat1 state mnemonic
|
||||
| F2 -> executeFormat2 state mnemonic
|
||||
| F3_4 -> executeFormat3_4 state mnemonic
|
||||
with
|
||||
| Failure msg -> byte1 |> Char.code |> invalidOpcode
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
(*opcode hash table, formati ukazov in mnemoniki*)
|
||||
type mnemonic =
|
||||
(* Format 1 *)
|
||||
| FIX | FLOAT | HIO | NORM | SIO | TIO
|
||||
|
||||
(* Format 2 *)
|
||||
| ADDR | CLEAR | COMPR | DIVR | MULR | RMO
|
||||
| SHIFTL | SHIFTR | SUBR | SVC | TIXR
|
||||
|
||||
(* Format 3/4 *)
|
||||
| ADD | ADDF | AND | COMP | COMPF | DIV
|
||||
| J | JEQ | JGT | JLT | JSUB | LDA | LDB | LDCH | LDF
|
||||
| LDL | LDS | LDT | LDX | LPS | MUL | OR | RD
|
||||
| RSUB | STA | STB | STCH | STF | STL | STS | STSW
|
||||
| STT | STX | SUB | SUBF | TD | TIX | WD
|
||||
|
||||
type format =
|
||||
| F1
|
||||
| F2
|
||||
| F3_4
|
||||
|
||||
type info = {
|
||||
mnemonic : mnemonic;
|
||||
format : format;
|
||||
}
|
||||
|
||||
(* Opcode table *)
|
||||
|
||||
let table : (int, info) Hashtbl.t = Hashtbl.create 128
|
||||
|
||||
let () =
|
||||
let add op mnemonic format =
|
||||
Hashtbl.add table op { mnemonic; format }
|
||||
in
|
||||
|
||||
(*Format 1 Instructions*)
|
||||
add 0xC4 FIX F1;
|
||||
add 0xC0 FLOAT F1;
|
||||
add 0xC8 HIO F1;
|
||||
add 0xC1 NORM F1;
|
||||
add 0xF0 SIO F1;
|
||||
add 0xF8 TIO F1;
|
||||
|
||||
(*Format 2 Instructions*)
|
||||
add 0x90 ADDR F2;
|
||||
add 0xB4 CLEAR F2;
|
||||
add 0xA0 COMPR F2;
|
||||
add 0x9C DIVR F2;
|
||||
add 0x98 MULR F2;
|
||||
add 0xAC RMO F2;
|
||||
add 0xA4 SHIFTL F2;
|
||||
add 0xA8 SHIFTR F2;
|
||||
add 0x94 SUBR F2;
|
||||
add 0xB0 SVC F2;
|
||||
add 0xB8 TIXR F2;
|
||||
|
||||
(*Format 3/4 Instructions*)
|
||||
add 0x18 ADD F3_4;
|
||||
add 0x58 ADDF F3_4;
|
||||
add 0x40 AND F3_4;
|
||||
add 0x28 COMP F3_4;
|
||||
add 0x88 COMPF F3_4;
|
||||
add 0x24 DIV F3_4;
|
||||
add 0x3C J F3_4;
|
||||
add 0x30 JEQ F3_4;
|
||||
add 0x34 JGT F3_4;
|
||||
add 0x38 JLT F3_4;
|
||||
add 0x48 JSUB F3_4;
|
||||
add 0x00 LDA F3_4;
|
||||
add 0x68 LDB F3_4;
|
||||
add 0x50 LDCH F3_4;
|
||||
add 0x70 LDF F3_4;
|
||||
add 0x08 LDL F3_4;
|
||||
add 0x6C LDS F3_4;
|
||||
add 0x74 LDT F3_4;
|
||||
add 0x04 LDX F3_4;
|
||||
add 0xD0 LPS F3_4;
|
||||
add 0x20 MUL F3_4;
|
||||
add 0x44 OR F3_4;
|
||||
add 0xD8 RD F3_4;
|
||||
add 0x4C RSUB F3_4;
|
||||
add 0x0C STA F3_4;
|
||||
add 0x78 STB F3_4;
|
||||
add 0x54 STCH F3_4;
|
||||
add 0x80 STF F3_4;
|
||||
add 0x14 STL F3_4;
|
||||
add 0x7C STS F3_4;
|
||||
add 0xE8 STSW F3_4;
|
||||
add 0x84 STT F3_4;
|
||||
add 0x10 STX F3_4;
|
||||
add 0x1C SUB F3_4;
|
||||
add 0x5C SUBF F3_4;
|
||||
add 0xE0 TD F3_4;
|
||||
add 0x2C TIX F3_4;
|
||||
add 0xDC WD F3_4;
|
||||
()
|
||||
|
||||
(*mnemonic to string*)
|
||||
let string_of_mnemonic = function
|
||||
(* Format 1 *)
|
||||
| FIX -> "FIX"
|
||||
| FLOAT -> "FLOAT"
|
||||
| HIO -> "HIO"
|
||||
| NORM -> "NORM"
|
||||
| SIO -> "SIO"
|
||||
| TIO -> "TIO"
|
||||
|
||||
(* Format 2 *)
|
||||
| ADDR -> "ADDR"
|
||||
| CLEAR -> "CLEAR"
|
||||
| COMPR -> "COMPR"
|
||||
| DIVR -> "DIVR"
|
||||
| MULR -> "MULR"
|
||||
| RMO -> "RMO"
|
||||
| SHIFTL -> "SHIFTL"
|
||||
| SHIFTR -> "SHIFTR"
|
||||
| SUBR -> "SUBR"
|
||||
| SVC -> "SVC"
|
||||
| TIXR -> "TIXR"
|
||||
|
||||
(* Format 3/4 *)
|
||||
| ADD -> "ADD"
|
||||
| ADDF -> "ADDF"
|
||||
| AND -> "AND"
|
||||
| COMP -> "COMP"
|
||||
| COMPF -> "COMPF"
|
||||
| DIV -> "DIV"
|
||||
| J -> "J"
|
||||
| JEQ -> "JEQ"
|
||||
| JGT -> "JGT"
|
||||
| JLT -> "JLT"
|
||||
| JSUB -> "JSUB"
|
||||
| LDA -> "LDA"
|
||||
| LDB -> "LDB"
|
||||
| LDCH -> "LDCH"
|
||||
| LDF -> "LDF"
|
||||
| LDL -> "LDL"
|
||||
| LDS -> "LDS"
|
||||
| LDT -> "LDT"
|
||||
| LDX -> "LDX"
|
||||
| LPS -> "LPS"
|
||||
| MUL -> "MUL"
|
||||
| OR -> "OR"
|
||||
| RD -> "RD"
|
||||
| RSUB -> "RSUB"
|
||||
| STA -> "STA"
|
||||
| STB -> "STB"
|
||||
| STCH -> "STCH"
|
||||
| STF -> "STF"
|
||||
| STL -> "STL"
|
||||
| STS -> "STS"
|
||||
| STSW -> "STSW"
|
||||
| STT -> "STT"
|
||||
| STX -> "STX"
|
||||
| SUB -> "SUB"
|
||||
| SUBF -> "SUBF"
|
||||
| TD -> "TD"
|
||||
| TIX -> "TIX"
|
||||
| WD -> "WD"
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(test
|
||||
(name test_SICXE))
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,20 +1,3 @@
|
|||
type registers = {
|
||||
mutable a : int;
|
||||
mutable x : int;
|
||||
mutable l : int;
|
||||
mutable b : int;
|
||||
mutable s : int;
|
||||
mutable t : int;
|
||||
mutable f : int;
|
||||
mutable pc : int;
|
||||
mutable sw : int
|
||||
}
|
||||
(*tip state predstavlja stanje SIC/XE, z pomnilnikom in registri*)
|
||||
type state = {
|
||||
regs : registers;
|
||||
memory : Bytes.t
|
||||
}
|
||||
|
||||
type nixbpe = {
|
||||
n : int;
|
||||
i : int;
|
||||
|
|
@ -24,11 +7,11 @@ type nixbpe = {
|
|||
e : int
|
||||
}
|
||||
|
||||
(*kreiramo začetno stanje*)
|
||||
let regs = {a = 0; x = 0; l = 0; b = 0; s = 0; t = 0; f = 0; pc = 0; sw = 0}
|
||||
(*kreiramo začetno stanje -> TODO prestavi v main*)
|
||||
let regs = Processor.{a = 0; x = 0; l = 0; b = 0; s = 0; t = 0; f = 0.0; pc = 0; sw = 0}
|
||||
let memSize = 1 lsl 20 (*2^20*)
|
||||
let memory = Bytes.make memSize '\x00' (*mutbale kos pomnilnika velikosti memSize*)
|
||||
let state = {regs; memory}
|
||||
let state = Processor.{regs; memory}
|
||||
|
||||
|
||||
(*----Funkcije izvajalnika----*)
|
||||
|
|
@ -39,28 +22,20 @@ let notImplemented (mnemonic : string) = Printf.printf "mnemonic %s is not imple
|
|||
let invalidOpcode (opcode : int) = Printf.printf "opcode %d is invalid!\n" opcode
|
||||
let invalidAdressing () = Printf.printf "invalid adressing!\n"
|
||||
|
||||
(*beri in povisaj PC*)
|
||||
let fetch (state : state) : char =
|
||||
let byte = Bytes.get state.memory state.regs.pc in
|
||||
state.regs.pc <- state.regs.pc + 1;
|
||||
byte
|
||||
|
||||
(*beri za offset in ne povecaj PC*)
|
||||
let readMem (state : state) (offset : int) : char =
|
||||
Bytes.get state.memory (state.regs.pc + offset)
|
||||
|
||||
|
||||
|
||||
(*beri drugi byte ukaza formata 2 in vrni r1 in r2, kot int njunih vrednosti (reg a -> 1, reg x -> 2 ...)*)
|
||||
let readR1R2 (state : state) : (int * int) =
|
||||
let byte2 = Char.code (readMem state 1) in
|
||||
let readR1R2 (state : Processor.state) : (int * int) =
|
||||
let byte2 = Char.code (Processor.readMem state 1) in
|
||||
let highNibble = (byte2 land 0xF0) lsr 4 in (*pridobi prvi nibble*)
|
||||
let lowNibble = byte2 land 0x0F in (*pridobi drugi nibble*)
|
||||
(highNibble, lowNibble)
|
||||
|
||||
(*preberi byta 1 in 2 in dobi nixbpe bite*)
|
||||
let getNIXBPE (state : state) : nixbpe =
|
||||
let byte1 = Char.code (readMem state 0) in
|
||||
let byte2 = Char.code (readMem state 1) in
|
||||
let getNIXBPE (state : Processor.state) : nixbpe =
|
||||
let byte1 = Char.code (Processor.readMem state 0) in
|
||||
let byte2 = Char.code (Processor.readMem state 1) in
|
||||
{n = (byte1 lsr 1) land 1;
|
||||
i = byte1 land 1;
|
||||
x = (byte2 lsr 7) land 1;
|
||||
|
|
@ -69,15 +44,49 @@ let getNIXBPE (state : state) : nixbpe =
|
|||
e = (byte2 lsr 4) land 1;}
|
||||
|
||||
|
||||
let getAddress (state : state) : int =
|
||||
42
|
||||
(*dobi disp iz tipa ukaza 3*)
|
||||
(*TODO pretvori v negativno število glede na nxibpe*)
|
||||
let getDisp (state : Processor.state) : int =
|
||||
let byte2 = Char.code (Processor.readMem state 1) in
|
||||
let byte3 = Char.code (Processor.readMem state 2) in
|
||||
let disp_high = byte2 land 0x0F in
|
||||
let disp = (disp_high lsl 8) lor byte3 in
|
||||
disp
|
||||
|
||||
(*dobi address iz tip ukaza 4*)
|
||||
(*TODO preveri ali mores paziti negativnost*)
|
||||
let getAddress (state : Processor.state) : int =
|
||||
let byte2 = Char.code (Processor.readMem state 1) in
|
||||
let byte3 = Char.code (Processor.readMem state 2) in
|
||||
let byte4 = Char.code (Processor.readMem state 3) in
|
||||
|
||||
let addr_highest = byte2 land 0x0F in
|
||||
let addr_high = (addr_highest lsl 8) lor byte3 in
|
||||
let address = (addr_high lsl 8) lor byte4 in
|
||||
address
|
||||
|
||||
let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int =
|
||||
let ea =
|
||||
if nixbpe.b = 1 && nixbpe.p = 0 then state.regs.b + disp (*B relativno*)
|
||||
else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + disp (*PC relativno*)
|
||||
else disp (*direktno*)
|
||||
in
|
||||
let ea = if nixbpe.x = 1 then ea + state.regs.x else ea in (*+ (X) po potrebi*)
|
||||
(*pridobi operand*)
|
||||
let value =
|
||||
if nixbpe.n = 1 && nixbpe.i = 1 then Processor.readMemAddr state ea (*direktno*)
|
||||
else if nixbpe.n = 0 && nixbpe.i = 1 then disp (* immediate value *)
|
||||
else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state (Processor.readMemAddr state ea) (* indirect *)
|
||||
else failwith "Invalid addressing mode"
|
||||
in
|
||||
value
|
||||
|
||||
(*execute format 1*)
|
||||
let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
Processor.pcIncrement state 1;
|
||||
match mnemonic with
|
||||
| FIX -> notImplemented "FIX"
|
||||
| FLOAT -> notImplemented "FLOAT"
|
||||
| FIX -> IzvajalnikF1.fix state
|
||||
| FLOAT -> IzvajalnikF1.floatF state
|
||||
| HIO -> notImplemented "HIO"
|
||||
| NORM -> notImplemented "NORM"
|
||||
| SIO -> notImplemented "SIO"
|
||||
|
|
@ -87,75 +96,80 @@ let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
|||
|
||||
|
||||
(*execute format 2*)
|
||||
let executeFormat2 (state: state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let (r1, r2) = readR1R2 state in
|
||||
Processor.pcIncrement state 2;
|
||||
match mnemonic with
|
||||
| ADDR -> notImplemented "ADD" (*when implemented: -> add state r1 r2*)
|
||||
| CLEAR -> notImplemented "CLEAR"
|
||||
| COMPR -> notImplemented "F2"
|
||||
| DIVR -> notImplemented "F2"
|
||||
| MULR -> notImplemented "F2"
|
||||
| RMO -> notImplemented "F2"
|
||||
| SHIFTL -> notImplemented "F2"
|
||||
| SHIFTR -> notImplemented "F2"
|
||||
| SUBR -> notImplemented "F2"
|
||||
| ADDR -> IzvajalnikF2.addr state r1 r2
|
||||
| CLEAR -> IzvajalnikF2.clear state r1
|
||||
| COMPR -> IzvajalnikF2.compr state r1 r2
|
||||
| DIVR -> IzvajalnikF2.divr state r1 r2
|
||||
| MULR -> IzvajalnikF2.mulr state r1 r2
|
||||
| RMO -> IzvajalnikF2.rmo state r1 r2
|
||||
| SHIFTL -> IzvajalnikF2.shiftl state r1 r2
|
||||
| SHIFTR -> IzvajalnikF2.shiftr state r1 r2
|
||||
| SUBR -> IzvajalnikF2.subr state r1 r2
|
||||
| SVC -> notImplemented "F2"
|
||||
| TIXR -> notImplemented "F2"
|
||||
| TIXR -> IzvajalnikF2.tixr state r1
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 2")
|
||||
|
||||
|
||||
|
||||
(*execute Format 3*)
|
||||
let executeFormat3 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = getAddress state in
|
||||
let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let disp = getDisp state in
|
||||
let operand = getOperand state nixbpe disp in
|
||||
Processor.pcIncrement state 3; (*povecamo pc pred izvedbo ukaza*)
|
||||
match mnemonic with
|
||||
| ADD -> notImplemented "ADD3"
|
||||
| ADDF -> notImplemented "ADDF4"
|
||||
| AND -> notImplemented "AND4"
|
||||
| COMP -> notImplemented "COMP4"
|
||||
| COMPF -> notImplemented "COMPF4"
|
||||
| DIV -> notImplemented "DIV4"
|
||||
| MUL -> notImplemented "MUL4"
|
||||
| OR -> notImplemented "OR4"
|
||||
| SUB -> notImplemented "SUB4"
|
||||
| SUBF -> notImplemented "SUBF4"
|
||||
| TD -> notImplemented "TD4"
|
||||
| WD -> notImplemented "WD4"
|
||||
| ADD -> IzvajalnikF3.add state operand
|
||||
| ADDF -> notImplemented "ADDF3"
|
||||
| AND -> IzvajalnikF3.andF state operand
|
||||
| COMP -> IzvajalnikF3.comp state operand
|
||||
| COMPF -> notImplemented "COMPF3"
|
||||
| DIV -> IzvajalnikF3.div state operand
|
||||
| MUL -> IzvajalnikF3.mul state operand
|
||||
| OR -> IzvajalnikF3.orF state operand
|
||||
| SUB -> IzvajalnikF3.sub state operand
|
||||
| SUBF -> notImplemented "SUBF3"
|
||||
| TD -> notImplemented "TD3"
|
||||
| WD -> notImplemented "WD3"
|
||||
|
||||
(* Jump / subroutine *)
|
||||
| J -> notImplemented "J4"
|
||||
| JEQ -> notImplemented "JEQ4"
|
||||
| JGT -> notImplemented "JGT4"
|
||||
| JLT -> notImplemented "JLT4"
|
||||
| JSUB -> notImplemented "JSUB4"
|
||||
| RSUB -> notImplemented "RSUB4"
|
||||
| J -> IzvajalnikF3.j state operand
|
||||
| JEQ -> IzvajalnikF3.jeq state operand
|
||||
| JGT -> IzvajalnikF3.jgt state operand
|
||||
| JLT -> IzvajalnikF3.jlt state operand
|
||||
| JSUB -> IzvajalnikF3.jsub state operand
|
||||
| RSUB -> IzvajalnikF3.rsub state operand
|
||||
|
||||
(* Load/store *)
|
||||
| LDA -> notImplemented "LDA4"
|
||||
| LDB -> notImplemented "LDB4"
|
||||
| LDCH -> notImplemented "LDCH4"
|
||||
| LDF -> notImplemented "LDF4"
|
||||
| LDL -> notImplemented "LDL4"
|
||||
| LDS -> notImplemented "LDS4"
|
||||
| LDT -> notImplemented "LDT4"
|
||||
| LDX -> notImplemented "LDX4"
|
||||
| LDA -> IzvajalnikF3.lda state operand
|
||||
| LDB -> IzvajalnikF3.ldb state operand
|
||||
| LDCH -> notImplemented "LDCH3"
|
||||
| LDF -> notImplemented "LDF3"
|
||||
| LDL -> IzvajalnikF3.ldl state operand
|
||||
| LDS -> IzvajalnikF3.lds state operand
|
||||
| LDT -> IzvajalnikF3.ldt state operand
|
||||
| LDX -> IzvajalnikF3.ldx state operand
|
||||
| LPS -> notImplemented "LPS4"
|
||||
| STA -> notImplemented "STA4"
|
||||
| STB -> notImplemented "STB4"
|
||||
| STA -> IzvajalnikF3.sta state operand
|
||||
| STB -> IzvajalnikF3.stb state operand
|
||||
| STCH -> notImplemented "STCH4"
|
||||
| STF -> notImplemented "STF4"
|
||||
| STL -> notImplemented "STL4"
|
||||
| STS -> notImplemented "STS4"
|
||||
| STSW -> notImplemented "STSW4"
|
||||
| STT -> notImplemented "STT4"
|
||||
| STX -> notImplemented "STX4"
|
||||
| STL -> IzvajalnikF3.stl state operand
|
||||
| STS -> IzvajalnikF3.sts state operand
|
||||
| STSW -> IzvajalnikF3.stsw state operand
|
||||
| STT -> IzvajalnikF3.stt state operand
|
||||
| STX -> IzvajalnikF3.stx state operand
|
||||
|
||||
(* Control / IO *)
|
||||
| TIX -> notImplemented "TIX4"
|
||||
| TIX -> IzvajalnikF3.tix state operand
|
||||
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
|
||||
|
||||
|
||||
let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = getAddress state in
|
||||
Processor.pcIncrement state 3;
|
||||
match mnemonic with
|
||||
(*aritmetika*)
|
||||
| ADD -> notImplemented "ADD4"
|
||||
|
|
@ -205,9 +219,8 @@ let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnem
|
|||
|
||||
|
||||
|
||||
|
||||
(*execute format 3_4*)
|
||||
let executeFormat3_4 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||
let nixbpe = getNIXBPE state in
|
||||
match nixbpe.e with
|
||||
| 0 -> executeFormat3 state nixbpe mnemonic
|
||||
|
|
@ -216,8 +229,8 @@ let executeFormat3_4 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
|||
|
||||
|
||||
(*execute ukaza*)
|
||||
let execute (state : state) : unit =
|
||||
let byte1 = readMem state 0 in (*read the 1st byte of the instruction*)
|
||||
let execute (state : Processor.state) : unit =
|
||||
let byte1 = Processor.readMem state 0 in (*read the 1st byte of the instruction*)
|
||||
try
|
||||
let {OpcodeTable.mnemonic; OpcodeTable.format} = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*)
|
||||
match format with
|
||||
|
|
|
|||
12
ass2/SICocaml/izvajalnikF1.ml
Normal file
12
ass2/SICocaml/izvajalnikF1.ml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
(*A <- (F) [convert to integer]*)
|
||||
let fix (state : Processor.state) : unit =
|
||||
state.regs.a <- int_of_float state.regs.f;
|
||||
()
|
||||
|
||||
(*F <- (A) [convert to floating]*)
|
||||
let floatF (state : Processor.state) : unit = (*poimenovana floatF zaradi tipa float*)
|
||||
state.regs.f <- float_of_int state.regs.a;
|
||||
()
|
||||
|
||||
(*TODO implement the rest*)
|
||||
|
||||
59
ass2/SICocaml/izvajalnikF2.ml
Normal file
59
ass2/SICocaml/izvajalnikF2.ml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
(*r2 <- (r2) + (r1)*)
|
||||
let addr (state : Processor.state) (r1 : int) (r2 : int) : unit =
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
let valR2 = Processor.read_register_int state r2 in
|
||||
Processor.write_register_int state r2 (valR1 + valR2)
|
||||
|
||||
(*r1 <- 0*)
|
||||
let clear (state : Processor.state) (r1 : int) : unit =
|
||||
Processor.write_register_int state r1 0
|
||||
|
||||
(*(r1):(r2)*)
|
||||
let compr (state : Processor.state) (r1 : int) (r2 : int) : unit =
|
||||
let sw = 9 in
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
let valR2 = Processor.read_register_int state r2 in
|
||||
Processor.write_register_int state sw (if valR1 < valR2 then 0 else if valR1 = valR2 then 1 else 2)
|
||||
|
||||
(*r2 <- (r2) / (r1)*)
|
||||
let divr (state : Processor.state) (r1 : int) (r2 : int) : unit =
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
let valR2 = Processor.read_register_int state r2 in
|
||||
Processor.write_register_int state r2 (valR2 / valR1)
|
||||
|
||||
(*r2 <- (r2) * (r1)*)
|
||||
let mulr (state : Processor.state) (r1 : int) (r2 : int) : unit =
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
let valR2 = Processor.read_register_int state r2 in
|
||||
Processor.write_register_int state r2 (valR2 * valR1)
|
||||
|
||||
(*r2 <- (r1)*)
|
||||
let rmo (state : Processor.state) (r1 : int) (r2 : int) : unit =
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
Processor.write_register_int state r2 (valR1)
|
||||
|
||||
(*r1 <- (r1); left shift n bits. {In assembled instruction, r2 = n-1}*)
|
||||
let shiftl(state : Processor.state) (r1 : int) (r2 : int) =
|
||||
let n = r2 + 1 in
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
Processor.write_register_int state r1 (valR1 lsl n)
|
||||
|
||||
(*r1 <- (r1); right shift logical n bits. {In assembled instruction, r2 = n-1}*)
|
||||
let shiftr(state : Processor.state) (r1 : int) (r2 : int) =
|
||||
let n = r2 + 1 in
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
Processor.write_register_int state r1 (valR1 lsr n)
|
||||
|
||||
(*r2 <- (r2) - (r1)*)
|
||||
let subr (state : Processor.state) (r1 : int) (r2 : int) : unit =
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
let valR2 = Processor.read_register_int state r2 in
|
||||
Processor.write_register_int state r2 (valR2 - valR1)
|
||||
|
||||
(*X <- (X) + 1; (X):(r1)*)
|
||||
let tixr (state : Processor.state) (r1 : int) : unit =
|
||||
state.regs.x <- state.regs.x + 1;
|
||||
let sw = 9 in
|
||||
let valR1 = Processor.read_register_int state r1 in
|
||||
let valX = state.regs.x in
|
||||
Processor.write_register_int state sw (if valX < valR1 then 0 else if valX = valR1 then 1 else 2)
|
||||
155
ass2/SICocaml/izvajalnikF3.ml
Normal file
155
ass2/SICocaml/izvajalnikF3.ml
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
(*A <- (A)+ (m..m+2)*)
|
||||
let add (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.a <- valA + operand
|
||||
|
||||
(*F (F) + (m..m+5)*)
|
||||
(*TODO check!*)
|
||||
let addf (state : Processor.state) (operand : int) : unit =
|
||||
let valF = state.regs.f in
|
||||
state.regs.f <- valF +. (float_of_int operand)
|
||||
|
||||
(*A <- (A) & (m..m+2)*)
|
||||
let andF (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.a <- valA land operand
|
||||
|
||||
(*(A):(m..m+2)*)
|
||||
let comp (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.sw <- (if valA < operand then 0 else if valA = operand then 1 else 2)
|
||||
|
||||
(*A <- (A) / (m..m+2)*)
|
||||
let div (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.a <- valA / operand
|
||||
|
||||
(*A <- (A) * (m..m+2)*)
|
||||
let mul (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.a <- valA * operand
|
||||
|
||||
(*A <- (A) | (m..m+2)*)
|
||||
let orF (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.a <- valA lor operand
|
||||
|
||||
(*A <- (A) - (m..m+2)*)
|
||||
let sub (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
state.regs.a <- valA - operand
|
||||
|
||||
(*PC <- m*)
|
||||
let j (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.pc <- operand
|
||||
|
||||
(*PC <- m if CC set to =*)
|
||||
let jeq (state : Processor.state) (operand : int) : unit =
|
||||
let cc = state.regs.sw in
|
||||
match cc with
|
||||
| 1 -> state.regs.pc <- operand
|
||||
| _ -> ()
|
||||
|
||||
(*PC <- m if CC set to >*)
|
||||
let jgt (state : Processor.state) (operand : int) : unit =
|
||||
let cc = state.regs.sw in
|
||||
match cc with
|
||||
| 2 -> state.regs.pc <- operand
|
||||
| _ -> ()
|
||||
|
||||
(*PC <- m if CC set to <*)
|
||||
let jlt (state : Processor.state) (operand : int) : unit =
|
||||
let cc = state.regs.sw in
|
||||
match cc with
|
||||
| 0 -> state.regs.pc <- operand
|
||||
| _ -> ()
|
||||
|
||||
(*L <- (PC); PC <- m*)
|
||||
let jsub (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.l <- state.regs.pc;
|
||||
state.regs.pc <- operand
|
||||
|
||||
(*PC <- (L)*)
|
||||
let rsub (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.pc <- state.regs.l
|
||||
|
||||
(*A <- (m..m+2)*)
|
||||
let lda (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.a <- operand
|
||||
|
||||
(* LDB: B <- (m..m+2) *)
|
||||
let ldb (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.b <- operand
|
||||
|
||||
(*A [rightmost byte] ← (m)*)
|
||||
(*TODO*)
|
||||
let ldch (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.a <- operand
|
||||
|
||||
(* LDX: X <- (m..m+2) *)
|
||||
let ldx (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.x <- operand
|
||||
|
||||
(* LDL: L <- (m..m+2) *)
|
||||
let ldl (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.l <- operand
|
||||
|
||||
(* LDS: S <- (m..m+2) *)
|
||||
let lds (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.s <- operand
|
||||
|
||||
(* LDT: T <- (m..m+2) *)
|
||||
let ldt (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.t <- operand
|
||||
|
||||
(* LDF: F <- (m..m+5) *)
|
||||
(*TODO*)
|
||||
let ldf (state : Processor.state) (operand : float) : unit =
|
||||
state.regs.f <- operand
|
||||
|
||||
(*m..m+2 <- (A)*)
|
||||
let sta (state : Processor.state) (operand : int) : unit =
|
||||
let valA = state.regs.a in
|
||||
Processor.writeMemAddr state operand valA
|
||||
|
||||
(* m..m+2 <- (B) *)
|
||||
let stb (state : Processor.state) (operand : int) : unit =
|
||||
let valB = state.regs.b in
|
||||
Processor.writeMemAddr state operand valB
|
||||
|
||||
(* m..m+2 <- (X) *)
|
||||
let stx (state : Processor.state) (operand : int) : unit =
|
||||
let valX = state.regs.x in
|
||||
Processor.writeMemAddr state operand valX
|
||||
|
||||
(* m..m+2 <- (L) *)
|
||||
let stl (state : Processor.state) (operand : int) : unit =
|
||||
let valL = state.regs.l in
|
||||
Processor.writeMemAddr state operand valL
|
||||
|
||||
(* m..m+2 <- (S) *)
|
||||
let sts (state : Processor.state) (operand : int) : unit =
|
||||
let valS = state.regs.s in
|
||||
Processor.writeMemAddr state operand valS
|
||||
|
||||
(* m..m+2 <- (SW) *)
|
||||
let stsw (state : Processor.state) (operand : int) : unit =
|
||||
let valSW = state.regs.s in
|
||||
Processor.writeMemAddr state operand valSW
|
||||
|
||||
(* m..m+2 <- T register *)
|
||||
let stt (state : Processor.state) (operand : int) : unit =
|
||||
let valT = state.regs.t in
|
||||
Processor.writeMemAddr state operand valT
|
||||
|
||||
(* m..m+5 <- (F)*)
|
||||
(*TODO change*)
|
||||
let stf (state : Processor.state) (operand : int) : unit =
|
||||
let valF = state.regs.f in
|
||||
Processor.writeMemAddr state operand (int_of_float valF)
|
||||
|
||||
(*X <- (X) + 1; (X):(m..m+2)*)
|
||||
let tix (state : Processor.state) (operand : int) : unit =
|
||||
state.regs.x <- state.regs.x + 1;
|
||||
let valX = state.regs.x in
|
||||
state.regs.sw <- (if valX < operand then 0 else if valX = operand then 1 else 2)
|
||||
Binary file not shown.
Binary file not shown.
81
ass2/SICocaml/processor.ml
Normal file
81
ass2/SICocaml/processor.ml
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
type registers = {
|
||||
mutable a : int;
|
||||
mutable x : int;
|
||||
mutable l : int;
|
||||
mutable b : int;
|
||||
mutable s : int;
|
||||
mutable t : int;
|
||||
mutable f : float;
|
||||
mutable pc : int;
|
||||
mutable sw : int
|
||||
}
|
||||
(*tip state predstavlja stanje SIC/XE, z pomnilnikom in registri*)
|
||||
type state = {
|
||||
regs : registers;
|
||||
memory : Bytes.t
|
||||
}
|
||||
|
||||
(*beri 1 byte in povisaj PC*)
|
||||
let fetch (state : state) : char =
|
||||
let byte = Bytes.get state.memory state.regs.pc in
|
||||
state.regs.pc <- state.regs.pc + 1;
|
||||
byte
|
||||
|
||||
(*beri 1 byte za offset in ne povecaj PC*)
|
||||
let readMem (state : state) (offset : int) : char =
|
||||
Bytes.get state.memory (state.regs.pc + offset)
|
||||
|
||||
|
||||
(*beri 3 byte iz address*)
|
||||
let readMemAddr (state : state) (address : int) : int =
|
||||
let byte1 = Char.code (Bytes.get state.memory address) in
|
||||
let byte2 = Char.code (Bytes.get state.memory (address + 1)) in
|
||||
let byte3 = Char.code (Bytes.get state.memory (address + 2)) in
|
||||
let value = (byte1 lsl 16) lor (byte2 lsl 8) lor byte3 in
|
||||
value
|
||||
|
||||
|
||||
(*napiši 3 byte inta na address*)
|
||||
let writeMemAddr (state : state) (address : int) (value : int) : unit =
|
||||
(* Mask and shift each byte *)
|
||||
let byte1 = Char.chr ((value lsr 16) land 0xFF) in
|
||||
let byte2 = Char.chr ((value lsr 8) land 0xFF) in
|
||||
let byte3 = Char.chr (value land 0xFF) in
|
||||
|
||||
(* Write bytes into memory *)
|
||||
Bytes.set state.memory address byte1;
|
||||
Bytes.set state.memory (address+1) byte2;
|
||||
Bytes.set state.memory (address+2) byte3
|
||||
|
||||
(*povečaj pc za i*)
|
||||
let pcIncrement (state : state) (i : int) : unit =
|
||||
state.regs.pc <- state.regs.pc + i;
|
||||
()
|
||||
|
||||
(*beri register glede na reg_code*)
|
||||
|
||||
let read_register_int (state: state) (reg_code : int) : int =
|
||||
match reg_code with
|
||||
| 0 -> state.regs.a
|
||||
| 1 -> state.regs.x
|
||||
| 2 -> state.regs.l
|
||||
| 3 -> state.regs.b
|
||||
| 4 -> state.regs.s
|
||||
| 5 -> state.regs.t
|
||||
| 6 -> int_of_float state.regs.f
|
||||
| 8 -> state.regs.pc
|
||||
| 9 -> state.regs.sw
|
||||
| _ -> failwith "Invalid register code"
|
||||
|
||||
let write_register_int (state : state) (reg_code : int) (value : int) : unit=
|
||||
match reg_code with
|
||||
| 0 -> state.regs.a <- value
|
||||
| 1 -> state.regs.x <- value
|
||||
| 2 -> state.regs.l <- value
|
||||
| 3 -> state.regs.b <- value
|
||||
| 4 -> state.regs.s <- value
|
||||
| 5 -> state.regs.t <- value
|
||||
| 6 -> state.regs.f <- float_of_int value
|
||||
| 8 -> state.regs.pc <- value
|
||||
| 9 -> state.regs.sw <- value
|
||||
| _ -> failwith "Invalid register code"
|
||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue