diff --git a/ass2/SICocaml/decoder.cmi b/ass2/SICocaml/decoder.cmi index 86f3866..455628f 100644 Binary files a/ass2/SICocaml/decoder.cmi and b/ass2/SICocaml/decoder.cmi differ diff --git a/ass2/SICocaml/decoder.cmo b/ass2/SICocaml/decoder.cmo index df363d3..23b814f 100644 Binary files a/ass2/SICocaml/decoder.cmo and b/ass2/SICocaml/decoder.cmo differ diff --git a/ass2/SICocaml/izvajalnik.cmi b/ass2/SICocaml/izvajalnik.cmi index d80c246..b1c4bff 100644 Binary files a/ass2/SICocaml/izvajalnik.cmi and b/ass2/SICocaml/izvajalnik.cmi differ diff --git a/ass2/SICocaml/izvajalnik.cmo b/ass2/SICocaml/izvajalnik.cmo index 02e0d8a..7038042 100644 Binary files a/ass2/SICocaml/izvajalnik.cmo and b/ass2/SICocaml/izvajalnik.cmo differ diff --git a/ass2/SICocaml/izvajalnik.ml b/ass2/SICocaml/izvajalnik.ml index f4d4c38..065624d 100644 --- a/ass2/SICocaml/izvajalnik.ml +++ b/ass2/SICocaml/izvajalnik.ml @@ -1,3 +1,5 @@ +open OpcodeTable + type nixbpe = { n : int; i : int; @@ -7,6 +9,10 @@ type nixbpe = { 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*) @@ -84,6 +90,10 @@ let getAddress (state : Processor.state) : int = (*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 @@ -98,6 +108,10 @@ let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : (*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 @@ -119,6 +133,10 @@ let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit = let disp = getDisp 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 @@ -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 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; match mnemonic with - (*aritmetika*) - | ADD -> notImplemented "ADD4" - | ADDF -> notImplemented "ADDF4" - | AND -> notImplemented "AND4" - | COMP -> notImplemented "COMP4" - | COMPF -> notImplemented "COMPF4" - | DIV -> notImplemented "DIV4" - | MUL -> notImplemented "MUL4" - | OR -> notImplemented "OR4" - | SUB -> notImplemented "SUB4" - | SUBF -> notImplemented "SUBF4" - | TD -> notImplemented "TD4" - | WD -> notImplemented "WD4" + | 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 -> notImplemented "J4" - | JEQ -> notImplemented "JEQ4" - | JGT -> notImplemented "JGT4" - | JLT -> notImplemented "JLT4" - | JSUB -> notImplemented "JSUB4" - | RSUB -> notImplemented "RSUB4" + | 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 operand (* Load/store *) - | LDA -> notImplemented "LDA4" - | LDB -> notImplemented "LDB4" - | LDCH -> notImplemented "LDCH4" - | LDF -> notImplemented "LDF4" - | LDL -> notImplemented "LDL4" - | LDS -> notImplemented "LDS4" - | LDT -> notImplemented "LDT4" - | LDX -> notImplemented "LDX4" + | LDA -> 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 -> notImplemented "STA4" - | STB -> notImplemented "STB4" + | STA -> IzvajalnikF4.sta state operand + | STB -> IzvajalnikF4.stb state operand | STCH -> notImplemented "STCH4" | STF -> notImplemented "STF4" - | STL -> notImplemented "STL4" - | STS -> notImplemented "STS4" - | STSW -> notImplemented "STSW4" - | STT -> notImplemented "STT4" - | STX -> notImplemented "STX4" + | STL -> 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 -> notImplemented "TIX4" - |_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 4") + | 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 = 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 | 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 {OpcodeTable.mnemonic; OpcodeTable.format} = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*) - match format with - | F1 -> executeFormat1 state mnemonic - | F2 -> executeFormat2 state mnemonic - | F3_4 -> executeFormat3_4 state mnemonic + 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 -> byte1 |> Char.code |> invalidOpcode \ No newline at end of file + | Failure msg -> Printf.printf "Cought faliure %s \n" msg; \ No newline at end of file diff --git a/ass2/SICocaml/izvajalnikF4.ml b/ass2/SICocaml/izvajalnikF4.ml new file mode 100644 index 0000000..80db3e8 --- /dev/null +++ b/ass2/SICocaml/izvajalnikF4.ml @@ -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) \ No newline at end of file diff --git a/ass2/SICocaml/opcodeTable.cmi b/ass2/SICocaml/opcodeTable.cmi index c7ab3a0..5d89792 100644 Binary files a/ass2/SICocaml/opcodeTable.cmi and b/ass2/SICocaml/opcodeTable.cmi differ diff --git a/ass2/SICocaml/opcodeTable.cmo b/ass2/SICocaml/opcodeTable.cmo index 83783ff..86c245f 100644 Binary files a/ass2/SICocaml/opcodeTable.cmo and b/ass2/SICocaml/opcodeTable.cmo differ diff --git a/ass2/SICocaml/opcodeTable.ml b/ass2/SICocaml/opcodeTable.ml index 4c4544c..03dc20e 100644 --- a/ass2/SICocaml/opcodeTable.ml +++ b/ass2/SICocaml/opcodeTable.ml @@ -157,3 +157,7 @@ let string_of_mnemonic = function | TD -> "TD" | TIX -> "TIX" | WD -> "WD" + + +let format_str format = match format with + | F1 -> "F1" | F2 -> "F2" | F3_4 -> "F3/4" \ No newline at end of file diff --git a/ass2/SICocaml/processor.ml b/ass2/SICocaml/processor.ml index c28b621..2499448 100644 --- a/ass2/SICocaml/processor.ml +++ b/ass2/SICocaml/processor.ml @@ -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+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; @@ -78,4 +84,28 @@ let write_register_int (state : state) (reg_code : int) (value : int) : unit= | 6 -> state.regs.f <- float_of_int value | 8 -> state.regs.pc <- value | 9 -> state.regs.sw <- value - | _ -> failwith "Invalid register code" \ No newline at end of file + | _ -> 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" \ No newline at end of file diff --git a/ass2/SICocaml/test.ml b/ass2/SICocaml/test.ml new file mode 100644 index 0000000..bec4bd9 --- /dev/null +++ b/ass2/SICocaml/test.ml @@ -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 ()