completed phase 1?

This commit is contained in:
Jaka Furlan 2025-11-29 20:28:00 +01:00
parent 0332001ef8
commit bc78a83838
11 changed files with 306 additions and 44 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,3 +1,5 @@
open OpcodeTable
type nixbpe = { type nixbpe = {
n : int; n : int;
i : int; i : int;
@ -7,6 +9,10 @@ type nixbpe = {
e : 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*) (*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 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 memSize = 1 lsl 20 (*2^20*)
@ -84,6 +90,10 @@ let getAddress (state : Processor.state) : int =
(*execute format 1*) (*execute format 1*)
let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit = let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
Processor.pcIncrement state 1; Processor.pcIncrement state 1;
(*debugging*)
Printf.printf "[Izvajalnik/executeFormat1] Mnemonic: %s\n"
(string_of_mnemonic mnemonic);
match mnemonic with match mnemonic with
| FIX -> IzvajalnikF1.fix state | FIX -> IzvajalnikF1.fix state
| FLOAT -> IzvajalnikF1.floatF state | FLOAT -> IzvajalnikF1.floatF state
@ -98,6 +108,10 @@ let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) :
(*execute format 2*) (*execute format 2*)
let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit = let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
let (r1, r2) = readR1R2 state in 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; Processor.pcIncrement state 2;
match mnemonic with match mnemonic with
| ADDR -> IzvajalnikF2.addr state r1 r2 | ADDR -> IzvajalnikF2.addr state r1 r2
@ -119,6 +133,10 @@ let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) :
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 = getDisp state in
let operand = getOperand state nixbpe disp 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*) Processor.pcIncrement state 3; (*povecamo pc pred izvedbo ukaza*)
match mnemonic with match mnemonic with
| ADD -> IzvajalnikF3.add state operand | ADD -> IzvajalnikF3.add state operand
@ -169,73 +187,85 @@ 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 = getAddress 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; Processor.pcIncrement state 3;
match mnemonic with match mnemonic with
(*aritmetika*) | ADD -> IzvajalnikF4.add state operand
| ADD -> notImplemented "ADD4" | ADDF -> notImplemented "ADDF3"
| ADDF -> notImplemented "ADDF4" | AND -> IzvajalnikF4.andF state operand
| AND -> notImplemented "AND4" | COMP -> IzvajalnikF4.comp state operand
| COMP -> notImplemented "COMP4" | COMPF -> notImplemented "COMPF3"
| COMPF -> notImplemented "COMPF4" | DIV -> IzvajalnikF4.div state operand
| DIV -> notImplemented "DIV4" | MUL -> IzvajalnikF4.mul state operand
| MUL -> notImplemented "MUL4" | OR -> IzvajalnikF4.orF state operand
| OR -> notImplemented "OR4" | SUB -> IzvajalnikF4.sub state operand
| SUB -> notImplemented "SUB4" | SUBF -> notImplemented "SUBF3"
| SUBF -> notImplemented "SUBF4" | TD -> notImplemented "TD3"
| TD -> notImplemented "TD4" | WD -> notImplemented "WD3"
| WD -> notImplemented "WD4"
(* Jump / subroutine *) (* Jump / subroutine *)
| J -> notImplemented "J4" | J -> IzvajalnikF4.j state operand
| JEQ -> notImplemented "JEQ4" | JEQ -> IzvajalnikF4.jeq state operand
| JGT -> notImplemented "JGT4" | JGT -> IzvajalnikF4.jgt state operand
| JLT -> notImplemented "JLT4" | JLT -> IzvajalnikF4.jlt state operand
| JSUB -> notImplemented "JSUB4" | JSUB -> IzvajalnikF4.jsub state operand
| RSUB -> notImplemented "RSUB4" | RSUB -> IzvajalnikF4.rsub state operand
(* Load/store *) (* Load/store *)
| LDA -> notImplemented "LDA4" | LDA -> IzvajalnikF4.lda state operand
| LDB -> notImplemented "LDB4" | LDB -> IzvajalnikF4.ldb state operand
| LDCH -> notImplemented "LDCH4" | LDCH -> notImplemented "LDCH3"
| LDF -> notImplemented "LDF4" | LDF -> notImplemented "LDF3"
| LDL -> notImplemented "LDL4" | LDL -> IzvajalnikF4.ldl state operand
| LDS -> notImplemented "LDS4" | LDS -> IzvajalnikF4.lds state operand
| LDT -> notImplemented "LDT4" | LDT -> IzvajalnikF4.ldt state operand
| LDX -> notImplemented "LDX4" | LDX -> IzvajalnikF4.ldx state operand
| LPS -> notImplemented "LPS4" | LPS -> notImplemented "LPS4"
| STA -> notImplemented "STA4" | STA -> IzvajalnikF4.sta state operand
| STB -> notImplemented "STB4" | STB -> IzvajalnikF4.stb state operand
| STCH -> notImplemented "STCH4" | STCH -> notImplemented "STCH4"
| STF -> notImplemented "STF4" | STF -> notImplemented "STF4"
| STL -> notImplemented "STL4" | STL -> IzvajalnikF4.stl state operand
| STS -> notImplemented "STS4" | STS -> IzvajalnikF4.sts state operand
| STSW -> notImplemented "STSW4" | STSW -> IzvajalnikF4.stsw state operand
| STT -> notImplemented "STT4" | STT -> IzvajalnikF4.stt state operand
| STX -> notImplemented "STX4" | STX -> IzvajalnikF4.stx state operand
(* Control / IO *) (* Control / IO *)
| TIX -> notImplemented "TIX4" | TIX -> IzvajalnikF3.tix state operand
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 4") |_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
(*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 = getNIXBPE 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 match nixbpe.e with
| 0 -> executeFormat3 state nixbpe mnemonic | 0 -> executeFormat3 state nixbpe mnemonic
| 1 -> executeFormat4 state nixbpe mnemonic | 1 -> executeFormat4 state nixbpe mnemonic
| _ -> failwith "invalid computation of nxbpe" | _ -> failwith "invalid computation of nxbpe"
(*execute ukaza*) (*execute ukaza*)
let execute (state : Processor.state) : unit = let execute (state : Processor.state) : unit =
let byte1 = Processor.readMem state 0 in (*read the 1st byte of the instruction*) 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 try
let {OpcodeTable.mnemonic; OpcodeTable.format} = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*) let info = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*)
match format with (*debugging*)
| F1 -> executeFormat1 state mnemonic Printf.printf "[Izvajalnik/execute]Opcode %s, format %s\n" (string_of_mnemonic info.mnemonic) (format_str info.format);
| F2 -> executeFormat2 state mnemonic
| F3_4 -> executeFormat3_4 state mnemonic match info.format with
| F1 -> executeFormat1 state info.mnemonic
| F2 -> executeFormat2 state info.mnemonic
| F3_4 -> executeFormat3_4 state info.mnemonic
with with
| Failure msg -> byte1 |> Char.code |> invalidOpcode | Failure msg -> Printf.printf "Cought faliure %s \n" msg;

View file

@ -0,0 +1,155 @@
(*A <- (A)+ (m..m+2)*)
let add (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.a <- valA + operand
(*F (F) + (m..m+5)*)
(*TODO check!*)
let addf (state : Processor.state) (operand : int) : unit =
let valF = state.regs.f in
state.regs.f <- valF +. (float_of_int operand)
(*A <- (A) & (m..m+2)*)
let andF (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.a <- valA land operand
(*(A):(m..m+2)*)
let comp (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.sw <- (if valA < operand then 0 else if valA = operand then 1 else 2)
(*A <- (A) / (m..m+2)*)
let div (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.a <- valA / operand
(*A <- (A) * (m..m+2)*)
let mul (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.a <- valA * operand
(*A <- (A) | (m..m+2)*)
let orF (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.a <- valA lor operand
(*A <- (A) - (m..m+2)*)
let sub (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
state.regs.a <- valA - operand
(*PC <- m*)
let j (state : Processor.state) (operand : int) : unit =
state.regs.pc <- operand
(*PC <- m if CC set to =*)
let jeq (state : Processor.state) (operand : int) : unit =
let cc = state.regs.sw in
match cc with
| 1 -> state.regs.pc <- operand
| _ -> ()
(*PC <- m if CC set to >*)
let jgt (state : Processor.state) (operand : int) : unit =
let cc = state.regs.sw in
match cc with
| 2 -> state.regs.pc <- operand
| _ -> ()
(*PC <- m if CC set to <*)
let jlt (state : Processor.state) (operand : int) : unit =
let cc = state.regs.sw in
match cc with
| 0 -> state.regs.pc <- operand
| _ -> ()
(*L <- (PC); PC <- m*)
let jsub (state : Processor.state) (operand : int) : unit =
state.regs.l <- state.regs.pc;
state.regs.pc <- operand
(*PC <- (L)*)
let rsub (state : Processor.state) (operand : int) : unit =
state.regs.pc <- state.regs.l
(*A <- (m..m+2)*)
let lda (state : Processor.state) (operand : int) : unit =
state.regs.a <- operand
(* LDB: B <- (m..m+2) *)
let ldb (state : Processor.state) (operand : int) : unit =
state.regs.b <- operand
(*A [rightmost byte] ← (m)*)
(*TODO*)
let ldch (state : Processor.state) (operand : int) : unit =
state.regs.a <- operand
(* LDX: X <- (m..m+2) *)
let ldx (state : Processor.state) (operand : int) : unit =
state.regs.x <- operand
(* LDL: L <- (m..m+2) *)
let ldl (state : Processor.state) (operand : int) : unit =
state.regs.l <- operand
(* LDS: S <- (m..m+2) *)
let lds (state : Processor.state) (operand : int) : unit =
state.regs.s <- operand
(* LDT: T <- (m..m+2) *)
let ldt (state : Processor.state) (operand : int) : unit =
state.regs.t <- operand
(* LDF: F <- (m..m+5) *)
(*TODO*)
let ldf (state : Processor.state) (operand : float) : unit =
state.regs.f <- operand
(*m..m+2 <- (A)*)
let sta (state : Processor.state) (operand : int) : unit =
let valA = state.regs.a in
Processor.writeMemAddr state operand valA
(* m..m+2 <- (B) *)
let stb (state : Processor.state) (operand : int) : unit =
let valB = state.regs.b in
Processor.writeMemAddr state operand valB
(* m..m+2 <- (X) *)
let stx (state : Processor.state) (operand : int) : unit =
let valX = state.regs.x in
Processor.writeMemAddr state operand valX
(* m..m+2 <- (L) *)
let stl (state : Processor.state) (operand : int) : unit =
let valL = state.regs.l in
Processor.writeMemAddr state operand valL
(* m..m+2 <- (S) *)
let sts (state : Processor.state) (operand : int) : unit =
let valS = state.regs.s in
Processor.writeMemAddr state operand valS
(* m..m+2 <- (SW) *)
let stsw (state : Processor.state) (operand : int) : unit =
let valSW = state.regs.s in
Processor.writeMemAddr state operand valSW
(* m..m+2 <- T register *)
let stt (state : Processor.state) (operand : int) : unit =
let valT = state.regs.t in
Processor.writeMemAddr state operand valT
(* m..m+5 <- (F)*)
(*TODO change*)
let stf (state : Processor.state) (operand : int) : unit =
let valF = state.regs.f in
Processor.writeMemAddr state operand (int_of_float valF)
(*X <- (X) + 1; (X):(m..m+2)*)
let tix (state : Processor.state) (operand : int) : unit =
state.regs.x <- state.regs.x + 1;
let valX = state.regs.x in
state.regs.sw <- (if valX < operand then 0 else if valX = operand then 1 else 2)

Binary file not shown.

Binary file not shown.

View file

@ -157,3 +157,7 @@ let string_of_mnemonic = function
| TD -> "TD" | TD -> "TD"
| TIX -> "TIX" | TIX -> "TIX"
| WD -> "WD" | WD -> "WD"
let format_str format = match format with
| F1 -> "F1" | F2 -> "F2" | F3_4 -> "F3/4"

View file

@ -47,6 +47,12 @@ let writeMemAddr (state : state) (address : int) (value : int) : unit =
Bytes.set state.memory (address+1) byte2; Bytes.set state.memory (address+1) byte2;
Bytes.set state.memory (address+2) byte3 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*) (*povečaj pc za i*)
let pcIncrement (state : state) (i : int) : unit = let pcIncrement (state : state) (i : int) : unit =
state.regs.pc <- state.regs.pc + i; state.regs.pc <- state.regs.pc + i;
@ -79,3 +85,27 @@ let write_register_int (state : state) (reg_code : int) (value : int) : unit=
| 8 -> state.regs.pc <- value | 8 -> state.regs.pc <- value
| 9 -> state.regs.sw <- value | 9 -> state.regs.sw <- value
| _ -> failwith "Invalid register code" | _ -> 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"

43
ass2/SICocaml/test.ml Normal file
View file

@ -0,0 +1,43 @@
(* 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 = 4; 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 ()