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 = {
|
||||
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 *)
|
||||
|
||||
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