done?
This commit is contained in:
parent
61bb14b9e3
commit
ad8728bdf4
19 changed files with 335 additions and 47 deletions
|
|
@ -1,37 +1,19 @@
|
|||
(* test_execute.ml *)
|
||||
|
||||
open Processor (* assuming your state, regs, and execute are defined here *)
|
||||
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}
|
||||
|
||||
(* 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
|
||||
let test_runner () =
|
||||
let khz = 0.001 in
|
||||
Processor.print_memory state 50;
|
||||
Loader.load_object_file state "/mnt/c/Programiranje/SPO/ass1/horner.obj";
|
||||
Processor.print_memory state 50;
|
||||
Printf.printf "\n\n---Starting execution!---\n\n";
|
||||
Pogajalnik.run state khz
|
||||
|
||||
(* 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 ()
|
||||
let () = test_runner ()
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
(library
|
||||
(name sicxeDune)
|
||||
(wrapped false))
|
||||
(wrapped false)
|
||||
(libraries unix))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
open OpcodeTable
|
||||
open OpcodeTable
|
||||
open Processor
|
||||
|
||||
type nixbpe = {
|
||||
n : int;
|
||||
|
|
@ -12,14 +13,6 @@ type nixbpe = {
|
|||
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!*)
|
||||
|
||||
|
|
@ -56,7 +49,10 @@ 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
|
||||
let disp_low = byte3 in
|
||||
let disp = (disp_high lsl 8) lor disp_low in
|
||||
let hex_string = Printf.sprintf "%02X%02X" disp_high disp_low in
|
||||
Printf.printf "[Izvajalnik/readDisp]prebral disp: 0x%s = 0x%04X = %d\n" hex_string disp disp;
|
||||
disp
|
||||
|
||||
(*dobi address iz tip ukaza 4*)
|
||||
|
|
@ -72,13 +68,31 @@ let readAddress (state : Processor.state) : int =
|
|||
address
|
||||
|
||||
(*pridobi operand*)
|
||||
let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int =
|
||||
let getOperandF3 (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 if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + disp + 3(*PC relativno, ker PC povečamo šele po klicu te funkcije moramo tu +3*)
|
||||
else disp (*direktno*)
|
||||
in
|
||||
let ea = if nixbpe.x = 1 then ea + state.regs.x else ea in (*+ (X) po potrebi*)
|
||||
Printf.printf "[Izvajalnik/getOperand]effective address: 0x%06X = %d\n" ea ea;
|
||||
(*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
|
||||
|
||||
let getOperandF4 (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 + 4(*PC relativno, ker PC povečamo šele po klicu te funkcije moramo tu +4*)
|
||||
else disp (*direktno*)
|
||||
in
|
||||
let ea = if nixbpe.x = 1 then ea + state.regs.x else ea in (*+ (X) po potrebi*)
|
||||
Printf.printf "[Izvajalnik/getOperand]effective address: 0x%06X = %d\n" ea ea;
|
||||
(*pridobi operand*)
|
||||
let value =
|
||||
if nixbpe.n = 1 && nixbpe.i = 1 then Processor.readMemAddr state ea (*direktno*)
|
||||
|
|
@ -133,7 +147,7 @@ let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) :
|
|||
(*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
|
||||
let operand = getOperandF3 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;
|
||||
|
|
@ -188,12 +202,12 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
|
|||
|
||||
let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||
let address = readAddress state in
|
||||
let operand = getOperand state nixbpe address in
|
||||
let operand = getOperandF4 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 4;
|
||||
match mnemonic with
|
||||
| ADD -> IzvajalnikF4.add state operand
|
||||
| ADDF -> notImplemented "ADDF3"
|
||||
|
|
|
|||
49
ass2/SICocaml/sicxeDune/lib/loader.ml
Normal file
49
ass2/SICocaml/sicxeDune/lib/loader.ml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
open Processor
|
||||
(* 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
|
||||
30
ass2/SICocaml/sicxeDune/lib/pogajalnik.ml
Normal file
30
ass2/SICocaml/sicxeDune/lib/pogajalnik.ml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
(*pogajalnik bo izvajal exekucijo eno za drugo*)
|
||||
|
||||
let run (state : Processor.state) (khz : float) : unit =
|
||||
let perioda_sekunde = 1.0 /. (khz *. 1000.0) in
|
||||
let rec loop state last_pc count=
|
||||
|
||||
(*izvedi ukaz*)
|
||||
Izvajalnik.execute state;
|
||||
|
||||
(*printni stanje*)
|
||||
Printf.printf "After execution:\n";
|
||||
Processor.print_regs state;
|
||||
Processor.print_memory state 50;
|
||||
flush stdout;
|
||||
|
||||
(*spi*)
|
||||
Unix.sleepf perioda_sekunde;(*mogoče spremeni na time of day approach , da se izogneš driftu*)
|
||||
|
||||
(*preveri ali je PC obtičan na istem mestu*)
|
||||
let current_pc = state.regs.pc in
|
||||
let count, last_pc =
|
||||
if current_pc = last_pc then (count + 1, last_pc)
|
||||
else (1, current_pc)
|
||||
in
|
||||
(*Nehaj rekurzijo če je PC 5x na istem mestu*)
|
||||
if count >= 5 then
|
||||
Printf.printf "PC stuck at 0x%X 5 times. Ending loop.\n" current_pc
|
||||
else
|
||||
loop state last_pc count
|
||||
in loop state state.regs.pc 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue