working...1

This commit is contained in:
Jaka Furlan 2025-11-29 21:17:09 +01:00
parent bc78a83838
commit 61bb14b9e3
21 changed files with 1054 additions and 12 deletions

Binary file not shown.

Binary file not shown.

View file

@ -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,7 +71,8 @@ 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
let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int = (*pridobi operand*)
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*)
else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + disp (*PC relativno*) else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + disp (*PC 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;

View file

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

View file

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

View file

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

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

View 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

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

View file

@ -0,0 +1,3 @@
(library
(name sicxeDune)
(wrapped false))

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

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

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

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

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

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

View file

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

View 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