working...

This commit is contained in:
Jaka Furlan 2025-11-29 18:00:02 +01:00
parent d836b3955d
commit 0332001ef8
75 changed files with 427 additions and 1081 deletions

View file

@ -1,20 +1,3 @@
type registers = {
mutable a : int;
mutable x : int;
mutable l : int;
mutable b : int;
mutable s : int;
mutable t : int;
mutable f : int;
mutable pc : int;
mutable sw : int
}
(*tip state predstavlja stanje SIC/XE, z pomnilnikom in registri*)
type state = {
regs : registers;
memory : Bytes.t
}
type nixbpe = {
n : int;
i : int;
@ -24,11 +7,11 @@ type nixbpe = {
e : int
}
(*kreiramo začetno stanje*)
let regs = {a = 0; x = 0; l = 0; b = 0; s = 0; t = 0; f = 0; pc = 0; sw = 0}
(*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 = {regs; memory}
let state = Processor.{regs; memory}
(*----Funkcije izvajalnika----*)
@ -39,28 +22,20 @@ let notImplemented (mnemonic : string) = Printf.printf "mnemonic %s is not imple
let invalidOpcode (opcode : int) = Printf.printf "opcode %d is invalid!\n" opcode
let invalidAdressing () = Printf.printf "invalid adressing!\n"
(*beri in povisaj PC*)
let fetch (state : state) : char =
let byte = Bytes.get state.memory state.regs.pc in
state.regs.pc <- state.regs.pc + 1;
byte
(*beri za offset in ne povecaj PC*)
let readMem (state : state) (offset : int) : char =
Bytes.get state.memory (state.regs.pc + offset)
(*beri drugi byte ukaza formata 2 in vrni r1 in r2, kot int njunih vrednosti (reg a -> 1, reg x -> 2 ...)*)
let readR1R2 (state : state) : (int * int) =
let byte2 = Char.code (readMem state 1) in
let readR1R2 (state : Processor.state) : (int * int) =
let byte2 = Char.code (Processor.readMem state 1) in
let highNibble = (byte2 land 0xF0) lsr 4 in (*pridobi prvi nibble*)
let lowNibble = byte2 land 0x0F in (*pridobi drugi nibble*)
(highNibble, lowNibble)
(*preberi byta 1 in 2 in dobi nixbpe bite*)
let getNIXBPE (state : state) : nixbpe =
let byte1 = Char.code (readMem state 0) in
let byte2 = Char.code (readMem state 1) in
let getNIXBPE (state : Processor.state) : nixbpe =
let byte1 = Char.code (Processor.readMem state 0) in
let byte2 = Char.code (Processor.readMem state 1) in
{n = (byte1 lsr 1) land 1;
i = byte1 land 1;
x = (byte2 lsr 7) land 1;
@ -69,15 +44,49 @@ let getNIXBPE (state : state) : nixbpe =
e = (byte2 lsr 4) land 1;}
let getAddress (state : state) : int =
42
(*dobi disp iz tipa ukaza 3*)
(*TODO pretvori v negativno število glede na nxibpe*)
let getDisp (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
disp
(*dobi address iz tip ukaza 4*)
(*TODO preveri ali mores paziti negativnost*)
let getAddress (state : Processor.state) : int =
let byte2 = Char.code (Processor.readMem state 1) in
let byte3 = Char.code (Processor.readMem state 2) in
let byte4 = Char.code (Processor.readMem state 3) in
let addr_highest = byte2 land 0x0F in
let addr_high = (addr_highest lsl 8) lor byte3 in
let address = (addr_high lsl 8) lor byte4 in
address
let getOperand (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 disp (*direktno*)
in
let ea = if nixbpe.x = 1 then ea + state.regs.x else ea in (*+ (X) po potrebi*)
(*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
(*execute format 1*)
let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
Processor.pcIncrement state 1;
match mnemonic with
| FIX -> notImplemented "FIX"
| FLOAT -> notImplemented "FLOAT"
| FIX -> IzvajalnikF1.fix state
| FLOAT -> IzvajalnikF1.floatF state
| HIO -> notImplemented "HIO"
| NORM -> notImplemented "NORM"
| SIO -> notImplemented "SIO"
@ -87,75 +96,80 @@ let executeFormat1 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
(*execute format 2*)
let executeFormat2 (state: state) (mnemonic : OpcodeTable.mnemonic) : unit =
let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
let (r1, r2) = readR1R2 state in
Processor.pcIncrement state 2;
match mnemonic with
| ADDR -> notImplemented "ADD" (*when implemented: -> add state r1 r2*)
| CLEAR -> notImplemented "CLEAR"
| COMPR -> notImplemented "F2"
| DIVR -> notImplemented "F2"
| MULR -> notImplemented "F2"
| RMO -> notImplemented "F2"
| SHIFTL -> notImplemented "F2"
| SHIFTR -> notImplemented "F2"
| SUBR -> notImplemented "F2"
| ADDR -> IzvajalnikF2.addr state r1 r2
| CLEAR -> IzvajalnikF2.clear state r1
| COMPR -> IzvajalnikF2.compr state r1 r2
| DIVR -> IzvajalnikF2.divr state r1 r2
| MULR -> IzvajalnikF2.mulr state r1 r2
| RMO -> IzvajalnikF2.rmo state r1 r2
| SHIFTL -> IzvajalnikF2.shiftl state r1 r2
| SHIFTR -> IzvajalnikF2.shiftr state r1 r2
| SUBR -> IzvajalnikF2.subr state r1 r2
| SVC -> notImplemented "F2"
| TIXR -> notImplemented "F2"
| TIXR -> IzvajalnikF2.tixr state r1
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 2")
(*execute Format 3*)
let executeFormat3 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
let address = getAddress state in
let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
let disp = getDisp state in
let operand = getOperand state nixbpe disp in
Processor.pcIncrement state 3; (*povecamo pc pred izvedbo ukaza*)
match mnemonic with
| ADD -> notImplemented "ADD3"
| 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 -> IzvajalnikF3.add state operand
| ADDF -> notImplemented "ADDF3"
| AND -> IzvajalnikF3.andF state operand
| COMP -> IzvajalnikF3.comp state operand
| COMPF -> notImplemented "COMPF3"
| DIV -> IzvajalnikF3.div state operand
| MUL -> IzvajalnikF3.mul state operand
| OR -> IzvajalnikF3.orF state operand
| SUB -> IzvajalnikF3.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 -> IzvajalnikF3.j state operand
| JEQ -> IzvajalnikF3.jeq state operand
| JGT -> IzvajalnikF3.jgt state operand
| JLT -> IzvajalnikF3.jlt state operand
| JSUB -> IzvajalnikF3.jsub state operand
| RSUB -> IzvajalnikF3.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 -> IzvajalnikF3.lda state operand
| LDB -> IzvajalnikF3.ldb state operand
| LDCH -> notImplemented "LDCH3"
| LDF -> notImplemented "LDF3"
| LDL -> IzvajalnikF3.ldl state operand
| LDS -> IzvajalnikF3.lds state operand
| LDT -> IzvajalnikF3.ldt state operand
| LDX -> IzvajalnikF3.ldx state operand
| LPS -> notImplemented "LPS4"
| STA -> notImplemented "STA4"
| STB -> notImplemented "STB4"
| STA -> IzvajalnikF3.sta state operand
| STB -> IzvajalnikF3.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 -> IzvajalnikF3.stl state operand
| STS -> IzvajalnikF3.sts state operand
| STSW -> IzvajalnikF3.stsw state operand
| STT -> IzvajalnikF3.stt state operand
| STX -> IzvajalnikF3.stx state operand
(* Control / IO *)
| TIX -> notImplemented "TIX4"
| TIX -> IzvajalnikF3.tix state operand
|_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3")
let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit =
let address = getAddress state in
Processor.pcIncrement state 3;
match mnemonic with
(*aritmetika*)
| ADD -> notImplemented "ADD4"
@ -205,9 +219,8 @@ let executeFormat4 (state : state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnem
(*execute format 3_4*)
let executeFormat3_4 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit =
let nixbpe = getNIXBPE state in
match nixbpe.e with
| 0 -> executeFormat3 state nixbpe mnemonic
@ -216,8 +229,8 @@ let executeFormat3_4 (state : state) (mnemonic : OpcodeTable.mnemonic) : unit =
(*execute ukaza*)
let execute (state : state) : unit =
let byte1 = readMem state 0 in (*read the 1st byte of the instruction*)
let execute (state : Processor.state) : unit =
let byte1 = Processor.readMem state 0 in (*read the 1st byte of the instruction*)
try
let {OpcodeTable.mnemonic; OpcodeTable.format} = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*)
match format with