done?
This commit is contained in:
parent
61bb14b9e3
commit
ad8728bdf4
19 changed files with 335 additions and 47 deletions
21
ass1/horner.log
Normal file
21
ass1/horner.log
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
***** Section <default> *****
|
||||||
|
Stats: size=61 blocks=61 symbols=10 literals=0 relocations=0
|
||||||
|
Blocks
|
||||||
|
name start size #ins #dir #sto
|
||||||
|
<default> 00000 0003D 16 8 1
|
||||||
|
Symbols
|
||||||
|
name hex dec scope kind type description
|
||||||
|
halt 000025 37 local relative code label
|
||||||
|
poly 000000 0 exported relative code label
|
||||||
|
rez 00003A 58 local relative data label
|
||||||
|
start 000000 0 local relative code label
|
||||||
|
x 000037 55 local relative data label
|
||||||
|
x0 000034 52 local relative data label
|
||||||
|
x1 000031 49 local relative data label
|
||||||
|
x2 00002E 46 local relative data label
|
||||||
|
x3 00002B 43 local relative data label
|
||||||
|
x4 000028 40 local relative data label
|
||||||
|
Literals
|
||||||
|
label definition
|
||||||
|
Relocations
|
||||||
|
address length flag symbol
|
||||||
38
ass1/horner.lst
Normal file
38
ass1/horner.lst
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
00000 poly START 0
|
||||||
|
00000 772025 start LDT x4
|
||||||
|
00003 6F2031 LDS x
|
||||||
|
00006 9845 MULR S,T
|
||||||
|
00008 032020 LDA x3
|
||||||
|
0000B 9050 ADDR T,A . do sedaj izračunano (1x + 2)
|
||||||
|
|
||||||
|
0000D 77201E LDT x2
|
||||||
|
00010 9840 MULR S,A
|
||||||
|
00012 9050 ADDR T,A . do sedaj izračunano ((1x+2)x + 3)
|
||||||
|
|
||||||
|
00014 77201A LDT x1
|
||||||
|
00017 9840 MULR S,A
|
||||||
|
00019 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)
|
||||||
|
|
||||||
|
0001B 772016 LDT x0
|
||||||
|
0001E 9840 MULR S,A
|
||||||
|
00020 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)x + 5
|
||||||
|
|
||||||
|
|
||||||
|
00022 0F2015 STA rez
|
||||||
|
|
||||||
|
00025 3F2FFD halt J halt
|
||||||
|
00028 END start
|
||||||
|
|
||||||
|
|
||||||
|
. polinom
|
||||||
|
00028 000001 x4 WORD 1
|
||||||
|
0002B 000002 x3 WORD 2
|
||||||
|
0002E 000003 x2 WORD 3
|
||||||
|
00031 000004 x1 WORD 4
|
||||||
|
00034 000005 x0 WORD 5
|
||||||
|
|
||||||
|
. tocka
|
||||||
|
00037 000002 x WORD 2
|
||||||
|
|
||||||
|
. rezultat
|
||||||
|
0003A 000000 rez RESW 1
|
||||||
4
ass1/horner.obj
Normal file
4
ass1/horner.obj
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
Hpoly 00000000003D
|
||||||
|
T0000001E7720256F20319845032020905077201E9840905077201A98409050772016
|
||||||
|
T00001E1C984090500F20153F2FFD000001000002000003000004000005000002
|
||||||
|
E000000
|
||||||
21
ass1/poly.log
Normal file
21
ass1/poly.log
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
***** Section <default> *****
|
||||||
|
Stats: size=70 blocks=70 symbols=10 literals=0 relocations=0
|
||||||
|
Blocks
|
||||||
|
name start size #ins #dir #sto
|
||||||
|
<default> 00000 00046 20 8 1
|
||||||
|
Symbols
|
||||||
|
name hex dec scope kind type description
|
||||||
|
halt 00002E 46 local relative code label
|
||||||
|
poly 000000 0 exported relative code label
|
||||||
|
rez 000043 67 local relative data label
|
||||||
|
start 000000 0 local relative code label
|
||||||
|
x 000040 64 local relative data label
|
||||||
|
x0 00003D 61 local relative data label
|
||||||
|
x1 00003A 58 local relative data label
|
||||||
|
x2 000037 55 local relative data label
|
||||||
|
x3 000034 52 local relative data label
|
||||||
|
x4 000031 49 local relative data label
|
||||||
|
Literals
|
||||||
|
label definition
|
||||||
|
Relocations
|
||||||
|
address length flag symbol
|
||||||
42
ass1/poly.lst
Normal file
42
ass1/poly.lst
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
00000 poly START 0
|
||||||
|
00000 03203A start LDA x0 . pristejemo x0 v A
|
||||||
|
|
||||||
|
00003 6B203A LDB x
|
||||||
|
00006 6F2037 LDS x
|
||||||
|
00009 77202E LDT x1
|
||||||
|
0000C 9845 MULR S,T
|
||||||
|
0000E 9050 ADDR T,A . pristejemo x0 * x
|
||||||
|
|
||||||
|
00010 772024 LDT x2
|
||||||
|
00013 9834 MULR B,S . izracunamo x^2
|
||||||
|
00015 9845 MULR S,T
|
||||||
|
00017 9050 ADDR T,A
|
||||||
|
|
||||||
|
00019 772018 LDT x3
|
||||||
|
0001C 9834 MULR B,S . izracunamo x^3
|
||||||
|
0001E 9845 MULR S,T
|
||||||
|
00020 9050 ADDR T,A
|
||||||
|
|
||||||
|
00022 77200C LDT x4
|
||||||
|
00025 9834 MULR B,S . izracunamo x^4
|
||||||
|
00027 9845 MULR S,T
|
||||||
|
00029 9050 ADDR T,A
|
||||||
|
|
||||||
|
0002B 0F2015 STA rez
|
||||||
|
|
||||||
|
0002E 3F2FFD halt J halt
|
||||||
|
00031 END start
|
||||||
|
|
||||||
|
|
||||||
|
. polinom
|
||||||
|
00031 000001 x4 WORD 1
|
||||||
|
00034 000002 x3 WORD 2
|
||||||
|
00037 000003 x2 WORD 3
|
||||||
|
0003A 000004 x1 WORD 4
|
||||||
|
0003D 000005 x0 WORD 5
|
||||||
|
|
||||||
|
. tocka
|
||||||
|
00040 000002 x WORD 2
|
||||||
|
|
||||||
|
. rezultat
|
||||||
|
00043 000000 rez RESW 1
|
||||||
5
ass1/poly.obj
Normal file
5
ass1/poly.obj
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Hpoly 000000000046
|
||||||
|
T0000001E03203A6B203A6F203777202E984590507720249834984590507720189834
|
||||||
|
T00001E1E9845905077200C9834984590500F20153F2FFD0000010000020000030000
|
||||||
|
T00003C0704000005000002
|
||||||
|
E000000
|
||||||
4
ass1/test.asm
Normal file
4
ass1/test.asm
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
poly START 0
|
||||||
|
END poly
|
||||||
|
|
||||||
|
x1 WORD 1
|
||||||
13
ass1/test.log
Normal file
13
ass1/test.log
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
***** Section <default> *****
|
||||||
|
Stats: size=3 blocks=3 symbols=2 literals=0 relocations=0
|
||||||
|
Blocks
|
||||||
|
name start size #ins #dir #sto
|
||||||
|
<default> 00000 00003 0 3 0
|
||||||
|
Symbols
|
||||||
|
name hex dec scope kind type description
|
||||||
|
poly 000000 0 exported relative code label
|
||||||
|
x1 000000 0 local relative data label
|
||||||
|
Literals
|
||||||
|
label definition
|
||||||
|
Relocations
|
||||||
|
address length flag symbol
|
||||||
4
ass1/test.lst
Normal file
4
ass1/test.lst
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
00000 poly START 0
|
||||||
|
00000 END poly
|
||||||
|
|
||||||
|
00000 000001 x1 WORD 1
|
||||||
3
ass1/test.obj
Normal file
3
ass1/test.obj
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Hpoly 000000000003
|
||||||
|
T00000003000001
|
||||||
|
E000000
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,4 +1,10 @@
|
||||||
open OpcodeTable
|
open OpcodeTable
|
||||||
|
open Processor
|
||||||
|
open IzvajalnikF1
|
||||||
|
open IzvajalnikF2
|
||||||
|
open IzvajalnikF3
|
||||||
|
open IzvajalnikF4
|
||||||
|
|
||||||
|
|
||||||
type nixbpe = {
|
type nixbpe = {
|
||||||
n : int;
|
n : int;
|
||||||
|
|
|
||||||
51
ass2/SICocaml/loader.ml
Normal file
51
ass2/SICocaml/loader.ml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
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
|
||||||
|
|
@ -1,37 +1,19 @@
|
||||||
(* test_execute.ml *)
|
(* 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 *)
|
(* Test function *)
|
||||||
let test_execute () =
|
let test_runner () =
|
||||||
(* Create a dummy state *)
|
let khz = 0.001 in
|
||||||
let mem_size = 1024 in
|
Processor.print_memory state 50;
|
||||||
let memory = Bytes.make mem_size '\000' in
|
Loader.load_object_file state "/mnt/c/Programiranje/SPO/ass1/horner.obj";
|
||||||
let regs = {
|
Processor.print_memory state 50;
|
||||||
a = 0; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0;
|
Printf.printf "\n\n---Starting execution!---\n\n";
|
||||||
pc = 0; sw = 0
|
Pogajalnik.run state khz
|
||||||
} 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 *)
|
(* Run the test *)
|
||||||
let () = test_execute ()
|
let () = test_runner ()
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
(library
|
(library
|
||||||
(name sicxeDune)
|
(name sicxeDune)
|
||||||
(wrapped false))
|
(wrapped false)
|
||||||
|
(libraries unix))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
open OpcodeTable
|
open OpcodeTable
|
||||||
|
open Processor
|
||||||
|
|
||||||
type nixbpe = {
|
type nixbpe = {
|
||||||
n : int;
|
n : int;
|
||||||
|
|
@ -12,14 +13,6 @@ type nixbpe = {
|
||||||
let string_of_nixbpe nixbpe =
|
let string_of_nixbpe nixbpe =
|
||||||
Printf.sprintf "n=%d,i=%d,x=%d,b=%d,p=%d,e=%d"
|
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
|
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----*)
|
(*----Funkcije izvajalnika----*)
|
||||||
(*TODO - brali bomo vedno relativno od začetka instrukcije, PC bomo na koncu ukaza povečali za pravo velikost!*)
|
(*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 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
|
||||||
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
|
disp
|
||||||
|
|
||||||
(*dobi address iz tip ukaza 4*)
|
(*dobi address iz tip ukaza 4*)
|
||||||
|
|
@ -72,13 +68,31 @@ let readAddress (state : Processor.state) : int =
|
||||||
address
|
address
|
||||||
|
|
||||||
(*pridobi operand*)
|
(*pridobi operand*)
|
||||||
let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int =
|
let getOperandF3 (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 + 3(*PC relativno, ker PC povečamo šele po klicu te funkcije moramo tu +3*)
|
||||||
else disp (*direktno*)
|
else disp (*direktno*)
|
||||||
in
|
in
|
||||||
let ea = if nixbpe.x = 1 then ea + state.regs.x else ea in (*+ (X) po potrebi*)
|
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*)
|
(*pridobi operand*)
|
||||||
let value =
|
let value =
|
||||||
if nixbpe.n = 1 && nixbpe.i = 1 then Processor.readMemAddr state ea (*direktno*)
|
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*)
|
(*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 = readDisp state in
|
let disp = readDisp state in
|
||||||
let operand = getOperand state nixbpe disp in
|
let operand = getOperandF3 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"
|
||||||
(string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand;
|
(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 executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
|
||||||
let address = readAddress state in
|
let address = readAddress state in
|
||||||
let operand = getOperand state nixbpe address in
|
let operand = getOperandF4 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"
|
||||||
(string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand;
|
(string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand;
|
||||||
|
|
||||||
Processor.pcIncrement state 3;
|
Processor.pcIncrement state 4;
|
||||||
match mnemonic with
|
match mnemonic with
|
||||||
| ADD -> IzvajalnikF4.add state operand
|
| ADD -> IzvajalnikF4.add state operand
|
||||||
| ADDF -> notImplemented "ADDF3"
|
| 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