completed assignment 2

This commit is contained in:
Jaka Furlan 2025-12-06 19:03:23 +01:00
parent 7106f34a4e
commit 909ef0f639
18 changed files with 25 additions and 1041 deletions

Binary file not shown.

Binary file not shown.

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"

Binary file not shown.

Binary file not shown.

View file

@ -1,278 +0,0 @@
open OpcodeTable
open Processor
open IzvajalnikF1
open IzvajalnikF2
open IzvajalnikF3
open IzvajalnikF4
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

@ -1,12 +0,0 @@
(*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

@ -1,59 +0,0 @@
(*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

@ -1,155 +0,0 @@
(*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

@ -1,155 +0,0 @@
(*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

@ -1,51 +0,0 @@
open Processor
open Printf
(* Convert hex string to int *)
let int_of_hex s = int_of_string ("0x" ^ s)
(* Convert two hex digits to a char *)
let char_of_hex s = Char.chr (int_of_hex s)
(* Write a list of bytes (chars) to memory at a given start address *)
let write_bytes state start bytes =
List.iteri (fun i byte -> Bytes.set state.memory (start + i) byte) bytes
(* Parse a T record line like: TAAAAAALL[BYTECODES...] *)
let parse_text_record line =
(* Skip leading 'T' *)
let line = String.sub line 1 (String.length line - 1) in
if String.length line < 8 then failwith "T record too short";
let start_str = String.sub line 0 6 in (*pridobi stolpce 2-7*)
let len_str = String.sub line 6 2 in (*pridobi stolpce 8-9*)
let start_addr = int_of_hex start_str in (*izračunaj star addr*)
let _ = int_of_hex len_str in (*izračunaj dolžino -> v bistvu je nikjer ne rabimo*)
let byte_str = String.sub line 8 (String.length line - 8) in (*pridobi stolpce 10-*)
(* Split the string into pairs of hex digits *)
let bytes =
let rec aux i acc =
if i >= String.length byte_str then List.rev acc (*ko si na koncu še obrni listo, ker si dodajal na začetek *)
else
let hex_pair = String.sub byte_str i 2 in (*pridobi par črk*)
aux (i + 2) (char_of_hex hex_pair :: acc) (*dodaj na začetek nov par*)
in
aux 0 []
in
(start_addr, bytes)
(* Load a SIC/XE object file into memory *)
let load_object_file (state : Processor.state) (filename : string) : unit =
let ic = open_in filename in
try
while true do
let line = input_line ic in
match line.[0] with
| 'T' ->
let addr, bytes = parse_text_record line in
write_bytes state addr bytes
| 'H' -> () (* header: can parse start addr/length if needed *)
| 'E' -> () (* end: can parse entry point if needed *)
| _ -> ()
done
with
| End_of_file -> close_in ic

Binary file not shown.

Binary file not shown.

View file

@ -1,163 +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"
let format_str format = match format with
| F1 -> "F1" | F2 -> "F2" | F3_4 -> "F3/4"

View file

@ -1,111 +0,0 @@
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

@ -171,7 +171,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
| SUB -> IzvajalnikF3.sub state operand | SUB -> IzvajalnikF3.sub state operand
| SUBF -> notImplemented "SUBF3" | SUBF -> notImplemented "SUBF3"
| TD -> notImplemented "TD3" | TD -> notImplemented "TD3"
| WD -> notImplemented "WD3" | WD -> IzvajalnikF3.wd state operand
(* Jump / subroutine *) (* Jump / subroutine *)
| J -> IzvajalnikF3.j state ea | J -> IzvajalnikF3.j state ea
@ -184,7 +184,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
(* Load/store *) (* Load/store *)
| LDA -> IzvajalnikF3.lda state operand | LDA -> IzvajalnikF3.lda state operand
| LDB -> IzvajalnikF3.ldb state operand | LDB -> IzvajalnikF3.ldb state operand
| LDCH -> notImplemented "LDCH3" | LDCH -> IzvajalnikF3.ldch state operand
| LDF -> notImplemented "LDF3" | LDF -> notImplemented "LDF3"
| LDL -> IzvajalnikF3.ldl state operand | LDL -> IzvajalnikF3.ldl state operand
| LDS -> IzvajalnikF3.lds state operand | LDS -> IzvajalnikF3.lds state operand
@ -193,7 +193,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
| LPS -> notImplemented "LPS4" | LPS -> notImplemented "LPS4"
| STA -> IzvajalnikF3.sta state operand | STA -> IzvajalnikF3.sta state operand
| STB -> IzvajalnikF3.stb state operand | STB -> IzvajalnikF3.stb state operand
| STCH -> notImplemented "STCH4" | STCH -> IzvajalnikF3.stch state operand
| STF -> notImplemented "STF4" | STF -> notImplemented "STF4"
| STL -> IzvajalnikF3.stl state ea | STL -> IzvajalnikF3.stl state ea
| STS -> IzvajalnikF3.sts state ea | STS -> IzvajalnikF3.sts state ea

View file

@ -39,6 +39,23 @@ let sub (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in let valA = state.regs.a in
state.regs.a <- valA - operand state.regs.a <- valA - operand
(*Device specified by (m) <- (A)[rightmost byte]*)
let wd (state : Processor.state) (operand : int) : unit =
let charA = char_of_int (state.regs.a land 0xFF) in
match operand with
| 0 -> failwith "not implemented"
| 1 -> Printf.printf "[STDOUT]: %c\n" charA
| 2 -> failwith "not implemented"
| _ -> failwith "unsupporterd operand"
(*(A)[rightmost byte] <- Device specified by (m)*)
let rd (state : Processor.state) (operand : int) : unit =
match operand with
| 0 -> let charIn = input_char stdin in state.regs.a <- Char.code charIn
| 1 -> failwith "not implemented"
| 2 -> failwith "not implemented"
| _ -> failwith "unsupporterd operand"
(*PC <- m*) (*PC <- m*)
let j (state : Processor.state) (operand : int) : unit = let j (state : Processor.state) (operand : int) : unit =
state.regs.pc <- operand state.regs.pc <- operand
@ -84,7 +101,7 @@ let ldb (state : Processor.state) (operand : int) : unit =
(*A [rightmost byte] ← (m)*) (*A [rightmost byte] ← (m)*)
(*TODO*) (*TODO*)
let ldch (state : Processor.state) (operand : int) : unit = let ldch (state : Processor.state) (operand : int) : unit =
state.regs.a <- operand state.regs.a <- (0xFF land operand)
(* LDX: X <- (m..m+2) *) (* LDX: X <- (m..m+2) *)
let ldx (state : Processor.state) (operand : int) : unit = let ldx (state : Processor.state) (operand : int) : unit =
@ -137,6 +154,10 @@ let stsw (state : Processor.state) (operand : int) : unit =
let valSW = state.regs.s in let valSW = state.regs.s in
Processor.writeMemAddr state operand valSW Processor.writeMemAddr state operand valSW
let stch (state : Processor.state) (operand : int) : unit =
let byte = state.regs.a land 0xFF in
Bytes.set state.memory operand (char_of_int byte)
(* m..m+2 <- T register *) (* m..m+2 <- T register *)
let stt (state : Processor.state) (operand : int) : unit = let stt (state : Processor.state) (operand : int) : unit =
let valT = state.regs.t in let valT = state.regs.t in

View file

@ -1,43 +0,0 @@
(* test_execute.ml *)
open Processor (* assuming your state, regs, and execute are defined here *)
(* Helper to write 3-byte instruction to memory *)
let write_instruction3 state addr byte1 byte2 byte3 =
Bytes.set state.memory addr (Char.chr byte1);
Bytes.set state.memory (addr+1) (Char.chr byte2);
Bytes.set state.memory (addr+2) (Char.chr byte3)
(* 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 ()