working...1
This commit is contained in:
parent
bc78a83838
commit
61bb14b9e3
21 changed files with 1054 additions and 12 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -39,7 +39,7 @@ let readR1R2 (state : Processor.state) : (int * int) =
|
||||||
(highNibble, lowNibble)
|
(highNibble, lowNibble)
|
||||||
|
|
||||||
(*preberi byta 1 in 2 in dobi nixbpe bite*)
|
(*preberi byta 1 in 2 in dobi nixbpe bite*)
|
||||||
let getNIXBPE (state : Processor.state) : nixbpe =
|
let readNIXBPE (state : Processor.state) : nixbpe =
|
||||||
let byte1 = Char.code (Processor.readMem state 0) in
|
let byte1 = Char.code (Processor.readMem state 0) in
|
||||||
let byte2 = Char.code (Processor.readMem state 1) in
|
let byte2 = Char.code (Processor.readMem state 1) in
|
||||||
{n = (byte1 lsr 1) land 1;
|
{n = (byte1 lsr 1) land 1;
|
||||||
|
|
@ -52,7 +52,7 @@ let getNIXBPE (state : Processor.state) : nixbpe =
|
||||||
|
|
||||||
(*dobi disp iz tipa ukaza 3*)
|
(*dobi disp iz tipa ukaza 3*)
|
||||||
(*TODO pretvori v negativno število glede na nxibpe*)
|
(*TODO pretvori v negativno število glede na nxibpe*)
|
||||||
let getDisp (state : Processor.state) : int =
|
let readDisp (state : Processor.state) : int =
|
||||||
let byte2 = Char.code (Processor.readMem state 1) in
|
let byte2 = Char.code (Processor.readMem state 1) in
|
||||||
let byte3 = Char.code (Processor.readMem state 2) in
|
let byte3 = Char.code (Processor.readMem state 2) in
|
||||||
let disp_high = byte2 land 0x0F in
|
let disp_high = byte2 land 0x0F in
|
||||||
|
|
@ -61,7 +61,7 @@ let getDisp (state : Processor.state) : int =
|
||||||
|
|
||||||
(*dobi address iz tip ukaza 4*)
|
(*dobi address iz tip ukaza 4*)
|
||||||
(*TODO preveri ali mores paziti negativnost*)
|
(*TODO preveri ali mores paziti negativnost*)
|
||||||
let getAddress (state : Processor.state) : int =
|
let readAddress (state : Processor.state) : int =
|
||||||
let byte2 = Char.code (Processor.readMem state 1) in
|
let byte2 = Char.code (Processor.readMem state 1) in
|
||||||
let byte3 = Char.code (Processor.readMem state 2) in
|
let byte3 = Char.code (Processor.readMem state 2) in
|
||||||
let byte4 = Char.code (Processor.readMem state 3) in
|
let byte4 = Char.code (Processor.readMem state 3) in
|
||||||
|
|
@ -71,6 +71,7 @@ let getAddress (state : Processor.state) : int =
|
||||||
let address = (addr_high lsl 8) lor byte4 in
|
let address = (addr_high lsl 8) lor byte4 in
|
||||||
address
|
address
|
||||||
|
|
||||||
|
(*pridobi operand*)
|
||||||
let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int =
|
let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int =
|
||||||
let ea =
|
let ea =
|
||||||
if nixbpe.b = 1 && nixbpe.p = 0 then state.regs.b + disp (*B relativno*)
|
if nixbpe.b = 1 && nixbpe.p = 0 then state.regs.b + disp (*B relativno*)
|
||||||
|
|
@ -131,7 +132,7 @@ let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) :
|
||||||
|
|
||||||
(*execute Format 3*)
|
(*execute Format 3*)
|
||||||
let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||||
let disp = getDisp state in
|
let disp = readDisp state in
|
||||||
let operand = getOperand state nixbpe disp in
|
let operand = getOperand state nixbpe disp in
|
||||||
(*debugging*)
|
(*debugging*)
|
||||||
Printf.printf "[Izvajalnik/executeFormat3] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n"
|
Printf.printf "[Izvajalnik/executeFormat3] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n"
|
||||||
|
|
@ -158,7 +159,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
|
||||||
| JGT -> IzvajalnikF3.jgt state operand
|
| JGT -> IzvajalnikF3.jgt state operand
|
||||||
| JLT -> IzvajalnikF3.jlt state operand
|
| JLT -> IzvajalnikF3.jlt state operand
|
||||||
| JSUB -> IzvajalnikF3.jsub state operand
|
| JSUB -> IzvajalnikF3.jsub state operand
|
||||||
| RSUB -> IzvajalnikF3.rsub state operand
|
| RSUB -> IzvajalnikF3.rsub state
|
||||||
|
|
||||||
(* Load/store *)
|
(* Load/store *)
|
||||||
| LDA -> IzvajalnikF3.lda state operand
|
| LDA -> IzvajalnikF3.lda state operand
|
||||||
|
|
@ -186,7 +187,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
|
||||||
|
|
||||||
|
|
||||||
let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||||
let address = getAddress state in
|
let address = readAddress state in
|
||||||
let operand = getOperand state nixbpe address in
|
let operand = getOperand state nixbpe address in
|
||||||
(*debugging*)
|
(*debugging*)
|
||||||
Printf.printf "[Izvajalnik/executeFormat4] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n"
|
Printf.printf "[Izvajalnik/executeFormat4] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n"
|
||||||
|
|
@ -213,7 +214,7 @@ let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
|
||||||
| JGT -> IzvajalnikF4.jgt state operand
|
| JGT -> IzvajalnikF4.jgt state operand
|
||||||
| JLT -> IzvajalnikF4.jlt state operand
|
| JLT -> IzvajalnikF4.jlt state operand
|
||||||
| JSUB -> IzvajalnikF4.jsub state operand
|
| JSUB -> IzvajalnikF4.jsub state operand
|
||||||
| RSUB -> IzvajalnikF4.rsub state operand
|
| RSUB -> IzvajalnikF4.rsub state
|
||||||
|
|
||||||
(* Load/store *)
|
(* Load/store *)
|
||||||
| LDA -> IzvajalnikF4.lda state operand
|
| LDA -> IzvajalnikF4.lda state operand
|
||||||
|
|
@ -243,7 +244,7 @@ let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
|
||||||
|
|
||||||
(*execute format 3_4*)
|
(*execute format 3_4*)
|
||||||
let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||||
let nixbpe = getNIXBPE state in
|
let nixbpe = readNIXBPE state in
|
||||||
(*debugging*)
|
(*debugging*)
|
||||||
Printf.printf "[Izvajalnik/executeFormat3_4]n=%d,i=%d,x=%d,b=%d,p=%d,e=%d\n" nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e;
|
Printf.printf "[Izvajalnik/executeFormat3_4]n=%d,i=%d,x=%d,b=%d,p=%d,e=%d\n" nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ let jsub (state : Processor.state) (operand : int) : unit =
|
||||||
state.regs.pc <- operand
|
state.regs.pc <- operand
|
||||||
|
|
||||||
(*PC <- (L)*)
|
(*PC <- (L)*)
|
||||||
let rsub (state : Processor.state) (operand : int) : unit =
|
let rsub (state : Processor.state) : unit =
|
||||||
state.regs.pc <- state.regs.l
|
state.regs.pc <- state.regs.l
|
||||||
|
|
||||||
(*A <- (m..m+2)*)
|
(*A <- (m..m+2)*)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ let jsub (state : Processor.state) (operand : int) : unit =
|
||||||
state.regs.pc <- operand
|
state.regs.pc <- operand
|
||||||
|
|
||||||
(*PC <- (L)*)
|
(*PC <- (L)*)
|
||||||
let rsub (state : Processor.state) (operand : int) : unit =
|
let rsub (state : Processor.state) : unit =
|
||||||
state.regs.pc <- state.regs.l
|
state.regs.pc <- state.regs.l
|
||||||
|
|
||||||
(*A <- (m..m+2)*)
|
(*A <- (m..m+2)*)
|
||||||
|
|
|
||||||
4
ass2/SICocaml/sicxeDune/bin/dune
Normal file
4
ass2/SICocaml/sicxeDune/bin/dune
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
(executable
|
||||||
|
(public_name sicxeDune)
|
||||||
|
(name main)
|
||||||
|
(libraries sicxeDune))
|
||||||
37
ass2/SICocaml/sicxeDune/bin/main.ml
Normal file
37
ass2/SICocaml/sicxeDune/bin/main.ml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
(* test_execute.ml *)
|
||||||
|
|
||||||
|
open Processor (* assuming your state, regs, and execute are defined here *)
|
||||||
|
|
||||||
|
(* Test function *)
|
||||||
|
let test_execute () =
|
||||||
|
(* Create a dummy state *)
|
||||||
|
let mem_size = 1024 in
|
||||||
|
let memory = Bytes.make mem_size '\000' in
|
||||||
|
let regs = {
|
||||||
|
a = 0; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0;
|
||||||
|
pc = 0; sw = 0
|
||||||
|
} in
|
||||||
|
let state = { memory; regs } in
|
||||||
|
|
||||||
|
(* Example: Write a LDA instruction at address 0*)
|
||||||
|
Processor.write_instruction3 state 0 '\x01' '\x00' '\x23';
|
||||||
|
|
||||||
|
(* Write the operand value at 0x010 *)
|
||||||
|
Processor.writeMemAddr state 0x010 0x123456;
|
||||||
|
|
||||||
|
(* Set PC to 0 *)
|
||||||
|
state.regs.pc <- 0;
|
||||||
|
|
||||||
|
Printf.printf "Before execution:\n";
|
||||||
|
Processor.print_regs state;
|
||||||
|
Processor.print_memory state 15;
|
||||||
|
|
||||||
|
(* Execute instruction *)
|
||||||
|
Izvajalnik.execute state;
|
||||||
|
|
||||||
|
Printf.printf "After execution:\n";
|
||||||
|
Processor.print_regs state;
|
||||||
|
Processor.print_memory state 15
|
||||||
|
|
||||||
|
(* Run the test *)
|
||||||
|
let () = test_execute ()
|
||||||
26
ass2/SICocaml/sicxeDune/dune-project
Normal file
26
ass2/SICocaml/sicxeDune/dune-project
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
(lang dune 3.20)
|
||||||
|
|
||||||
|
(name sicxeDune)
|
||||||
|
|
||||||
|
(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 sicxeDune)
|
||||||
|
(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
|
||||||
10
ass2/SICocaml/sicxeDune/lib/decoder.ml
Normal file
10
ass2/SICocaml/sicxeDune/lib/decoder.ml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
(*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"
|
||||||
|
|
||||||
3
ass2/SICocaml/sicxeDune/lib/dune
Normal file
3
ass2/SICocaml/sicxeDune/lib/dune
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
(library
|
||||||
|
(name sicxeDune)
|
||||||
|
(wrapped false))
|
||||||
272
ass2/SICocaml/sicxeDune/lib/izvajalnik.ml
Normal file
272
ass2/SICocaml/sicxeDune/lib/izvajalnik.ml
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
open OpcodeTable
|
||||||
|
|
||||||
|
type nixbpe = {
|
||||||
|
n : int;
|
||||||
|
i : int;
|
||||||
|
x : int;
|
||||||
|
b : int;
|
||||||
|
p : int;
|
||||||
|
e : int
|
||||||
|
}
|
||||||
|
|
||||||
|
let string_of_nixbpe nixbpe =
|
||||||
|
Printf.sprintf "n=%d,i=%d,x=%d,b=%d,p=%d,e=%d"
|
||||||
|
nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e
|
||||||
|
|
||||||
|
(*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 = Processor.{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 drugi byte ukaza formata 2 in vrni r1 in r2, kot int njunih vrednosti (reg a -> 1, reg x -> 2 ...)*)
|
||||||
|
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 readNIXBPE (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;
|
||||||
|
b = (byte2 lsr 6) land 1;
|
||||||
|
p = (byte2 lsr 5) land 1;
|
||||||
|
e = (byte2 lsr 4) land 1;}
|
||||||
|
|
||||||
|
|
||||||
|
(*dobi disp iz tipa ukaza 3*)
|
||||||
|
(*TODO pretvori v negativno število glede na nxibpe*)
|
||||||
|
let readDisp (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 readAddress (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
|
||||||
|
|
||||||
|
(*pridobi operand*)
|
||||||
|
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 : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||||
|
Processor.pcIncrement state 1;
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/executeFormat1] Mnemonic: %s\n"
|
||||||
|
(string_of_mnemonic mnemonic);
|
||||||
|
|
||||||
|
match mnemonic with
|
||||||
|
| FIX -> IzvajalnikF1.fix state
|
||||||
|
| FLOAT -> IzvajalnikF1.floatF state
|
||||||
|
| 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: Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||||
|
let (r1, r2) = readR1R2 state in
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/executeFormat2] Mnemonic: %s, r1: %d, r2: %d\n"
|
||||||
|
(string_of_mnemonic mnemonic) r1 r2;
|
||||||
|
|
||||||
|
Processor.pcIncrement state 2;
|
||||||
|
match mnemonic with
|
||||||
|
| 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 -> IzvajalnikF2.tixr state r1
|
||||||
|
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 2")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(*execute Format 3*)
|
||||||
|
let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||||
|
let disp = readDisp state in
|
||||||
|
let operand = getOperand state nixbpe disp in
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/executeFormat3] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n"
|
||||||
|
(string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand;
|
||||||
|
|
||||||
|
Processor.pcIncrement state 3; (*povecamo pc pred izvedbo ukaza*)
|
||||||
|
match mnemonic with
|
||||||
|
| 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 -> 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
|
||||||
|
|
||||||
|
(* Load/store *)
|
||||||
|
| 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 -> IzvajalnikF3.sta state operand
|
||||||
|
| STB -> IzvajalnikF3.stb state operand
|
||||||
|
| STCH -> notImplemented "STCH4"
|
||||||
|
| STF -> notImplemented "STF4"
|
||||||
|
| 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 -> IzvajalnikF3.tix state operand
|
||||||
|
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
|
||||||
|
|
||||||
|
|
||||||
|
let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||||
|
let address = readAddress state in
|
||||||
|
let operand = getOperand state nixbpe address in
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/executeFormat4] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n"
|
||||||
|
(string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand;
|
||||||
|
|
||||||
|
Processor.pcIncrement state 3;
|
||||||
|
match mnemonic with
|
||||||
|
| ADD -> IzvajalnikF4.add state operand
|
||||||
|
| ADDF -> notImplemented "ADDF3"
|
||||||
|
| AND -> IzvajalnikF4.andF state operand
|
||||||
|
| COMP -> IzvajalnikF4.comp state operand
|
||||||
|
| COMPF -> notImplemented "COMPF3"
|
||||||
|
| DIV -> IzvajalnikF4.div state operand
|
||||||
|
| MUL -> IzvajalnikF4.mul state operand
|
||||||
|
| OR -> IzvajalnikF4.orF state operand
|
||||||
|
| SUB -> IzvajalnikF4.sub state operand
|
||||||
|
| SUBF -> notImplemented "SUBF3"
|
||||||
|
| TD -> notImplemented "TD3"
|
||||||
|
| WD -> notImplemented "WD3"
|
||||||
|
|
||||||
|
(* Jump / subroutine *)
|
||||||
|
| J -> IzvajalnikF4.j state operand
|
||||||
|
| JEQ -> IzvajalnikF4.jeq state operand
|
||||||
|
| JGT -> IzvajalnikF4.jgt state operand
|
||||||
|
| JLT -> IzvajalnikF4.jlt state operand
|
||||||
|
| JSUB -> IzvajalnikF4.jsub state operand
|
||||||
|
| RSUB -> IzvajalnikF4.rsub state
|
||||||
|
|
||||||
|
(* Load/store *)
|
||||||
|
| LDA -> IzvajalnikF4.lda state operand
|
||||||
|
| LDB -> IzvajalnikF4.ldb state operand
|
||||||
|
| LDCH -> notImplemented "LDCH3"
|
||||||
|
| LDF -> notImplemented "LDF3"
|
||||||
|
| LDL -> IzvajalnikF4.ldl state operand
|
||||||
|
| LDS -> IzvajalnikF4.lds state operand
|
||||||
|
| LDT -> IzvajalnikF4.ldt state operand
|
||||||
|
| LDX -> IzvajalnikF4.ldx state operand
|
||||||
|
| LPS -> notImplemented "LPS4"
|
||||||
|
| STA -> IzvajalnikF4.sta state operand
|
||||||
|
| STB -> IzvajalnikF4.stb state operand
|
||||||
|
| STCH -> notImplemented "STCH4"
|
||||||
|
| STF -> notImplemented "STF4"
|
||||||
|
| STL -> IzvajalnikF4.stl state operand
|
||||||
|
| STS -> IzvajalnikF4.sts state operand
|
||||||
|
| STSW -> IzvajalnikF4.stsw state operand
|
||||||
|
| STT -> IzvajalnikF4.stt state operand
|
||||||
|
| STX -> IzvajalnikF4.stx state operand
|
||||||
|
|
||||||
|
(* Control / IO *)
|
||||||
|
| TIX -> IzvajalnikF3.tix state operand
|
||||||
|
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(*execute format 3_4*)
|
||||||
|
let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
|
||||||
|
let nixbpe = readNIXBPE state in
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/executeFormat3_4]n=%d,i=%d,x=%d,b=%d,p=%d,e=%d\n" nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e;
|
||||||
|
|
||||||
|
match nixbpe.e with
|
||||||
|
| 0 -> executeFormat3 state nixbpe mnemonic
|
||||||
|
| 1 -> executeFormat4 state nixbpe mnemonic
|
||||||
|
| _ -> failwith "invalid computation of nxbpe"
|
||||||
|
|
||||||
|
(*execute ukaza*)
|
||||||
|
let execute (state : Processor.state) : unit =
|
||||||
|
let byte1 = Processor.readMem state 0 in (*read the 1st byte of the instruction*)
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/execute]Prebral byte1 %c = 0x%02X\n" byte1 (Char.code byte1);
|
||||||
|
|
||||||
|
try
|
||||||
|
let info = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*)
|
||||||
|
(*debugging*)
|
||||||
|
Printf.printf "[Izvajalnik/execute]Opcode %s, format %s\n" (string_of_mnemonic info.mnemonic) (format_str info.format);
|
||||||
|
|
||||||
|
match info.format with
|
||||||
|
| F1 -> executeFormat1 state info.mnemonic
|
||||||
|
| F2 -> executeFormat2 state info.mnemonic
|
||||||
|
| F3_4 -> executeFormat3_4 state info.mnemonic
|
||||||
|
with
|
||||||
|
| Failure msg -> Printf.printf "Cought faliure %s \n" msg;
|
||||||
12
ass2/SICocaml/sicxeDune/lib/izvajalnikF1.ml
Normal file
12
ass2/SICocaml/sicxeDune/lib/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/sicxeDune/lib/izvajalnikF2.ml
Normal file
59
ass2/SICocaml/sicxeDune/lib/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/sicxeDune/lib/izvajalnikF3.ml
Normal file
155
ass2/SICocaml/sicxeDune/lib/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) : 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)
|
||||||
155
ass2/SICocaml/sicxeDune/lib/izvajalnikF4.ml
Normal file
155
ass2/SICocaml/sicxeDune/lib/izvajalnikF4.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) : 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)
|
||||||
163
ass2/SICocaml/sicxeDune/lib/opcodeTable.ml
Normal file
163
ass2/SICocaml/sicxeDune/lib/opcodeTable.ml
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
(*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"
|
||||||
|
|
||||||
|
|
||||||
|
let format_str format = match format with
|
||||||
|
| F1 -> "F1" | F2 -> "F2" | F3_4 -> "F3/4"
|
||||||
111
ass2/SICocaml/sicxeDune/lib/processor.ml
Normal file
111
ass2/SICocaml/sicxeDune/lib/processor.ml
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
(*popoč za pisanje instrukcij*)
|
||||||
|
let write_instruction3 (state : state) (address : int) (byte1 : char) (byte2 : char) (byte3 : char) : unit =
|
||||||
|
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"
|
||||||
|
|
||||||
|
let print_memory (state : state) (n : int) : unit =
|
||||||
|
let mem = state.memory in
|
||||||
|
let len = Bytes.length mem in
|
||||||
|
let limit = min n len in
|
||||||
|
Printf.printf "Memory dump (first %d bytes):\n" limit;
|
||||||
|
for i = 0 to limit - 1 do
|
||||||
|
let byte = Char.code (Bytes.get mem i) in
|
||||||
|
Printf.printf "%02X " byte;
|
||||||
|
if (i + 1) mod 16 = 0 then Printf.printf "\n";
|
||||||
|
done;
|
||||||
|
Printf.printf "\n"
|
||||||
|
|
||||||
|
let print_regs state : unit =
|
||||||
|
let regs = state.regs in
|
||||||
|
Printf.printf "A: %06X\n" regs.a;
|
||||||
|
Printf.printf "B: %06X\n" regs.b;
|
||||||
|
Printf.printf "X: %06X\n" regs.x;
|
||||||
|
Printf.printf "L: %06X\n" regs.l;
|
||||||
|
Printf.printf "S: %06X\n" regs.s;
|
||||||
|
Printf.printf "T: %06X\n" regs.t;
|
||||||
|
Printf.printf "PC: %06X\n" regs.pc;
|
||||||
|
Printf.printf "SW: %06X\n" regs.sw;
|
||||||
|
Printf.printf "\n"
|
||||||
32
ass2/SICocaml/sicxeDune/sicxeDune.opam
Normal file
32
ass2/SICocaml/sicxeDune/sicxeDune.opam
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# 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)"]
|
||||||
2
ass2/SICocaml/sicxeDune/test/dune
Normal file
2
ass2/SICocaml/sicxeDune/test/dune
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
(test
|
||||||
|
(name test_sicxeDune))
|
||||||
0
ass2/SICocaml/sicxeDune/test/test_sicxeDune.ml
Normal file
0
ass2/SICocaml/sicxeDune/test/test_sicxeDune.ml
Normal file
|
|
@ -14,7 +14,7 @@ let test_execute () =
|
||||||
let mem_size = 1024 in
|
let mem_size = 1024 in
|
||||||
let memory = Bytes.make mem_size '\000' in
|
let memory = Bytes.make mem_size '\000' in
|
||||||
let regs = {
|
let regs = {
|
||||||
a = 4; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0;
|
a = 0; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0;
|
||||||
pc = 0; sw = 0
|
pc = 0; sw = 0
|
||||||
} in
|
} in
|
||||||
let state = { memory; regs } in
|
let state = { memory; regs } in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue