working...

This commit is contained in:
Jaka Furlan 2025-11-29 18:00:02 +01:00
parent d836b3955d
commit 0332001ef8
75 changed files with 427 additions and 1081 deletions

16
ass2/.gitignore vendored Normal file
View 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

View file

@ -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.

View file

@ -1 +0,0 @@
<dummy>

View file

@ -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))

View file

@ -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))))

View file

@ -1,4 +0,0 @@
(lang dune 3.20)
(name SICXE)
(sections (lib .) (bin ../../bin))
(files (lib (META dune-package opam)) (bin (SICXE)))

View file

@ -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)"]

View file

@ -1 +0,0 @@
let () = print_endline "Hello, World!"

View file

@ -1 +0,0 @@
(* Auto-generated by Dune *)

View file

@ -1 +0,0 @@
lib/decoder.ml: Char Hashtbl OpcodeTable

View file

@ -1,2 +0,0 @@
sICXE__Decoder
sICXE__OpcodeTable

View file

@ -1 +0,0 @@
lib/izvajalnik.ml: Bytes Char Decoder OpcodeTable Printf

View file

@ -1 +0,0 @@
lib/opcodeTable.ml: Hashtbl

View file

@ -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"

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -1 +0,0 @@
(* Auto-generated by Dune *)

View file

@ -1 +0,0 @@
../../../../default/META.SICXE

View file

@ -1 +0,0 @@
../../../../default/SICXE.dune-package

View file

@ -1 +0,0 @@
../../../../default/SICXE.opam

View file

@ -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)

View file

@ -1,4 +0,0 @@
(executable
(public_name SICXE)
(name main)
(libraries SICXE))

View file

@ -1 +0,0 @@
let () = print_endline "Hello, World!"

View file

@ -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

View file

@ -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"

View file

@ -1,2 +0,0 @@
(library
(name SICXE))

View file

@ -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

View file

@ -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"

View file

@ -1,2 +0,0 @@
(test
(name test_SICXE))

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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

View 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*)

View 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)

View 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.

View 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.