working on ass3, todo pc, nixbpe

This commit is contained in:
Jaka Furlan 2025-12-14 23:31:52 +01:00
parent 6261d9fe37
commit beabcde7db
15 changed files with 412 additions and 194 deletions

View file

@ -1,6 +1,9 @@
poly START 0 poly START 16
start LDT x4 p BYTE X'EF'
LDS x ADD #34
start +LDT x4, X
x4 WORD 1
+LDS @x
MULR S, T MULR S, T
LDA x3 LDA x3
ADDR T, A . do sedaj izračunano (1x + 2) ADDR T, A . do sedaj izračunano (1x + 2)
@ -8,7 +11,6 @@ start LDT x4
LDT x2 LDT x2
MULR S, A MULR S, A
ADDR T, A .do sedaj izračunano ((1x+2)x + 3) ADDR T, A .do sedaj izračunano ((1x+2)x + 3)
LDT x1 LDT x1
MULR S, A MULR S, A
ADDR T, A .do sedaj izračunano (((1x+2)x + 3)x + 4) ADDR T, A .do sedaj izračunano (((1x+2)x + 3)x + 4)
@ -21,11 +23,11 @@ start LDT x4
STA rez STA rez
halt J halt halt J halt
END start
.polinom .polinom
x4 WORD 1
x3 WORD 2 x3 WORD 2
x2 WORD 3 x2 WORD 3
x1 WORD 4 x1 WORD 4
@ -36,3 +38,5 @@ x WORD 2
.rezultat .rezultat
rez RESW 1 rez RESW 1
END start

View file

@ -1,21 +1,24 @@
***** Section <default> ***** ***** Section <default> *****
Stats: size=61 blocks=61 symbols=10 literals=0 relocations=0 Stats: size=67 blocks=67 symbols=11 literals=0 relocations=2
Blocks Blocks
name start size #ins #dir #sto name start size #ins #dir #sto
<default> 00000 0003D 16 8 1 <default> 00010 00043 17 9 1
Symbols Symbols
name hex dec scope kind type description name hex dec scope kind type description
halt 000025 37 local relative code label halt 00003E 62 local relative code label
poly 000000 0 exported relative code label p 000010 16 local relative data label
rez 00003A 58 local relative data label poly 000010 16 exported relative code label
start 000000 0 local relative code label rez 000050 80 local relative data label
x 000037 55 local relative data label start 000014 20 local relative code label
x0 000034 52 local relative data label x 00004D 77 local relative data label
x1 000031 49 local relative data label x0 00004A 74 local relative data label
x2 00002E 46 local relative data label x1 000047 71 local relative data label
x3 00002B 43 local relative data label x2 000044 68 local relative data label
x4 000028 40 local relative data label x3 000041 65 local relative data label
x4 000018 24 local relative data label
Literals Literals
label definition label definition
Relocations Relocations
address length flag symbol address length flag symbol
00015 5
0001C 5

View file

@ -1,38 +1,42 @@
00000 poly START 0 00010 poly START 16
00000 772025 start LDT x4 00010 EF p BYTE X'EF'
00003 6F2031 LDS x 00011 190022 ADD #34
00006 9845 MULR S,T 00014 77900018 start +LDT x4,X
00008 032020 LDA x3 00018 000001 x4 WORD 1
0000B 9050 ADDR T,A . do sedaj izračunano (1x + 2) 0001B 6E10004D +LDS @x
0001F 9845 MULR S,T
00021 03201D LDA x3
00024 9050 ADDR T,A . do sedaj izračunano (1x + 2)
0000D 77201E LDT x2 00026 77201B LDT x2
00010 9840 MULR S,A 00029 9840 MULR S,A
00012 9050 ADDR T,A . do sedaj izračunano ((1x+2)x + 3) 0002B 9050 ADDR T,A . do sedaj izračunano ((1x+2)x + 3)
0002D 772017 LDT x1
00030 9840 MULR S,A
00032 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)
00014 77201A LDT x1 00034 772013 LDT x0
00017 9840 MULR S,A 00037 9840 MULR S,A
00019 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4) 00039 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)x + 5
0001B 772016 LDT x0 . fullline comment
0001E 9840 MULR S,A 0003B 0F2012 STA rez
00020 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)x + 5
0003E 3F2FFD halt J halt
00022 0F2015 STA rez
00025 3F2FFD halt J halt
00028 END start
. polinom . polinom
00028 000001 x4 WORD 1
0002B 000002 x3 WORD 2 00041 000002 x3 WORD 2
0002E 000003 x2 WORD 3 00044 000003 x2 WORD 3
00031 000004 x1 WORD 4 00047 000004 x1 WORD 4
00034 000005 x0 WORD 5 0004A 000005 x0 WORD 5
. tocka . tocka
00037 000002 x WORD 2 0004D 000002 x WORD 2
. rezultat . rezultat
0003A 000000 rez RESW 1 00050 000000 rez RESW 1
00053 END start

View file

@ -1,4 +1,7 @@
Hpoly 00000000003D Hpoly 000010000043
T0000001E7720256F20319845032020905077201E9840905077201A98409050772016 T0000101EEF190022779000180000016E10004D984503201D905077201B9840905077
T00001E1C984090500F20153F2FFD000001000002000003000004000005000002 T00002E1E201798409050772013984090500F20123F2FFD0000020000030000040000
E000000 T00004C0405000002
M00001505
M00001C05
E000014

View file

@ -1,4 +1,5 @@
poly START 0 poly START 0
RSUB
LDB x1 LDB x1
END poly END poly

View file

@ -74,7 +74,7 @@ let readAddress (state : Processor.state) : int =
address address
(*pridobi effective address in operand*) (*pridobi effective address in operand*)
let getOperandF3 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * int= let getOperandF3 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * 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 + to_signed disp + 3(*PC relativno, ker PC povečamo šele po klicu te funkcije moramo tu +3*) else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + to_signed disp + 3(*PC relativno, ker PC povečamo šele po klicu te funkcije moramo tu +3*)
@ -89,7 +89,13 @@ let getOperandF3 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int
else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state (Processor.readMemAddr state ea) (* indirect *) else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state (Processor.readMemAddr state ea) (* indirect *)
else failwith "Invalid addressing mode" else failwith "Invalid addressing mode"
in in
ea ,value let valueMem =
if nixbpe.n = 1 && nixbpe.i = 1 then ea
else if nixbpe.n = 0 && nixbpe.i = 1 then ea (* immediate value *)
else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state ea (* indirect *)
else failwith "Invalid addressing mode"
in
ea ,value, valueMem
let getOperandF4 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * int = let getOperandF4 (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int * int =
let ea = let ea =
@ -153,7 +159,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 ea ,operand = getOperandF3 state nixbpe disp in let ea ,operand, valueMem = 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;
@ -191,15 +197,15 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
| LDT -> IzvajalnikF3.ldt state operand | LDT -> IzvajalnikF3.ldt state operand
| LDX -> IzvajalnikF3.ldx state operand | LDX -> IzvajalnikF3.ldx state operand
| LPS -> notImplemented "LPS4" | LPS -> notImplemented "LPS4"
| STA -> IzvajalnikF3.sta state ea | STA -> IzvajalnikF3.sta state valueMem
| STB -> IzvajalnikF3.stb state ea | STB -> IzvajalnikF3.stb state valueMem
| STCH -> IzvajalnikF3.stch state ea | STCH -> IzvajalnikF3.stch state valueMem
| STF -> notImplemented "STF4" | STF -> notImplemented "STF4"
| STL -> IzvajalnikF3.stl state ea | STL -> IzvajalnikF3.stl state valueMem
| STS -> IzvajalnikF3.sts state ea | STS -> IzvajalnikF3.sts state valueMem
| STSW -> IzvajalnikF3.stsw state ea | STSW -> IzvajalnikF3.stsw state valueMem
| STT -> IzvajalnikF3.stt state ea | STT -> IzvajalnikF3.stt state valueMem
| STX -> IzvajalnikF3.stx state ea | STX -> IzvajalnikF3.stx state valueMem
(* Control / IO *) (* Control / IO *)
| TIX -> IzvajalnikF3.tix state operand | TIX -> IzvajalnikF3.tix state operand

View file

@ -41,7 +41,8 @@ let writeMemAddr (state : state) (address : int) (value : int) : unit =
let byte1 = Char.chr ((value lsr 16) land 0xFF) in let byte1 = Char.chr ((value lsr 16) land 0xFF) in
let byte2 = Char.chr ((value lsr 8) land 0xFF) in let byte2 = Char.chr ((value lsr 8) land 0xFF) in
let byte3 = Char.chr (value land 0xFF) in let byte3 = Char.chr (value land 0xFF) in
Printf.printf "[Procesor/writeMemAddr]Napisal byte %02X %02X %02X na %06X\n"
(int_of_char byte1) (int_of_char byte2) (int_of_char byte3) address;
(* Write bytes into memory *) (* Write bytes into memory *)
Bytes.set state.memory address byte1; Bytes.set state.memory address byte1;
Bytes.set state.memory (address+1) byte2; Bytes.set state.memory (address+1) byte2;

View file

@ -2,6 +2,8 @@ open Zbirnik.Parser
open Zbirnik.SemanticAnalyzer open Zbirnik.SemanticAnalyzer
open Zbirnik.PrehodPrvi open Zbirnik.PrehodPrvi
open Zbirnik.Simtab open Zbirnik.Simtab
open Zbirnik.DrugiPrehod
open Zbirnik.OpcodeTable
(* Helper functions to print optional values *) (* Helper functions to print optional values *)
@ -27,14 +29,17 @@ let print_lineSemantic_list (lines : lineSemantic list) : unit =
) lines ) lines
let print_intermediate_file_list (lines : lineSemantic list) : unit = let print_intermediate_file_list (lines : lineSemantic list) : unit =
List.iter (fun l -> List.iter (fun l ->
Printf.printf "%s | %8s | %6s | %20s | %s\n" Printf.printf "%s | %8s | %6s | %20s | x=%d | n = %d | i = %d | %s\n"
(print_opt_int l.loc) (print_opt_int l.loc)
(print_opt_string l.label) (print_opt_string l.label)
(string_of_mnemonic l.opcode) (string_of_mnemonic l.opcode)
(string_of_mnemonic_type l.mnem) (string_of_mnemonic_type l.mnem)
(print_opt_string l.comment) (if l.x then 1 else 0)
) lines (if l.n then 1 else 0)
(if l.i then 1 else 0)
(print_opt_string l.comment)
) lines
let print_symtab (tab : symtab) : unit = let print_symtab (tab : symtab) : unit =
Printf.printf "\nSYMBOL TABLE\n"; Printf.printf "\nSYMBOL TABLE\n";
@ -46,6 +51,9 @@ let print_symtab (tab : symtab) : unit =
) tab; ) tab;
Printf.printf "----------------------\n" Printf.printf "----------------------\n"
let print_object_code (objectCodeList : string list) : unit =
List.iter (fun s -> print_endline s) objectCodeList
let run () = let run () =
let lineSemantic = (checkLineSemanticOfCode (parser "../../ass1/horner.asm") ) in let lineSemantic = (checkLineSemanticOfCode (parser "../../ass1/horner.asm") ) in
print_lineSemantic_list lineSemantic; print_lineSemantic_list lineSemantic;
@ -54,6 +62,9 @@ let run () =
Printf.printf "Program Length je: %d\n" prlen; Printf.printf "Program Length je: %d\n" prlen;
print_intermediate_file_list prehod1; print_intermediate_file_list prehod1;
print_symtab simtab; print_symtab simtab;
let opcodeTab = get_opcode_table () in
let objectCodeList = drugiPrehod lineSemantic simtab opcodeTab prlen in
print_object_code objectCodeList;
() ()

View file

@ -3,8 +3,9 @@ open Simtab
open SemanticAnalyzer open SemanticAnalyzer
open Encoder open Encoder
open Instruction open Instruction
open OpcodeTable
let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : string list = let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (opcodeTab : opcodeTab) (lenProg : int) : string list =
let prviUkaz, ostaliUkazi = let prviUkaz, ostaliUkazi =
match ifl with match ifl with
| [] -> failwith "empty code" | [] -> failwith "empty code"
@ -41,29 +42,35 @@ let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : st
| [] -> loop xs objectCodeList newStartAddress [] | [] -> loop xs objectCodeList newStartAddress []
| _ -> loop xs (newTextLine :: objectCodeList) newStartAddress [] | _ -> loop xs (newTextLine :: objectCodeList) newStartAddress []
end end
| BYTE ->
let operand = match x.mnem with | MnemonicSd s -> s | _ -> failwith "narobe mnemType za BYTE" in
let opcode = create_opcode_byte operand in
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*)
loop xs (newTextLine :: objectCodeList) newStartAddress []
else
loop xs objectCodeList newStartAddress (opcode :: instructionList)
| WORD ->
let operand = match x.mnem with | MnemonicSd s -> s | _ -> failwith "narobe mnemType za WORD" in
let opcode = create_opcode_word operand in
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*)
loop xs (newTextLine :: objectCodeList) newStartAddress []
else
loop xs objectCodeList newStartAddress (opcode :: instructionList)
| _ -> (*if not comment or reserve*) | _ -> (*if not comment or reserve*)
(*if simbol na mestu opeanda*) (*if simbol na mestu opeanda*)
let isSymbol, symbol = operand_is_symbol x.mnem in match operand_is_symbol x with
if isSymbol then | None -> loop xs objectCodeList newStartAddress instructionList (*None -> ta ukaz se ne zapiše, ga skipamo*)
begin | Some (_, operand, formatLen) ->
let locSimbola = find_symbol tab symbol in let opcode = create_opcode simtab opcodeTab x.opcode operand formatLen x.loc in
let opcode = create_opcode_symbol x.opcode locSimbola in (*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
if String.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*) let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*)
let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*) loop xs (newTextLine :: objectCodeList) newStartAddress []
loop xs (newTextLine :: objectCodeList) newStartAddress [] else
else loop xs objectCodeList newStartAddress (opcode :: instructionList)
loop xs objectCodeList newStartAddress (opcode :: instructionList)
end
else
let opcode = create_opcode x.opcode x.mnem in (*symbol je tukaj kar stevilska vrednost/register*)
(*TODO dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
begin
if String.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*)
loop xs (newTextLine :: objectCodeList) newStartAddress []
else
loop xs objectCodeList newStartAddress (opcode :: instructionList)
end
in loop ostaliUkazi objectCodeList startAddr instructionList in loop ostaliUkazi objectCodeList start instructionList

View file

@ -1,10 +1,3 @@
(library (library
(name zbirnik) (name zbirnik)
(libraries str) (libraries str))
(modules parser
simtab
semanticAnalyzer
prehodPrvi
encoder
drugiPrehod
instruction))

View file

@ -7,17 +7,17 @@ let getZaglavjeAndStart (prviUkaz : lineSemantic) (lenProg : int) : string list
| None -> "MOJPROG" (*default ime*) | None -> "MOJPROG" (*default ime*)
| Some s -> if String.length s > 6 then "MOJPROG" else String.make (6 - String.length s) '0' ^ s (*paddamo z 0 če je < 6*) | Some s -> if String.length s > 6 then "MOJPROG" else String.make (6 - String.length s) '0' ^ s (*paddamo z 0 če je < 6*)
in in
let startAddr = match prviUkaz.mnem with let startAddrString, startAddrInt = match prviUkaz.mnem with
| MnemonicDn s -> (*preverimo ali je pravilne dolzine in naredimo string dolzine 6*) | MnemonicDn s -> (*preverimo ali je pravilne dolzine in naredimo string dolzine 6*)
let n = int_of_string s in let n = int_of_string s in
if n < 0 || n > 0xFFFFFF then if n < 0 || n > 0xFFFFFF then
invalid_arg "getZaglavje: zacetni naslov out of range" invalid_arg "getZaglavje: zacetni naslov out of range"
else else
Printf.sprintf "%06X" n (Printf.sprintf "%06X" n), n
| _ -> failwith "getZaglavje: invalid mnemonic_type" | _ -> failwith "getZaglavje: invalid mnemonic_type"
in in
let lenObjectCode = Printf.sprintf "%06X" lenProg in let lenObjectCode = Printf.sprintf "%06X" lenProg in
["H" ^ name ^ startAddr ^ lenObjectCode], int_of_string startAddr (*vrnemo concatiniran string in startAddr*) ["H" ^ name ^ startAddrString ^ lenObjectCode], startAddrInt(*vrnemo concatiniran string in startAddr*)
(*vrne T vrstico*) (*vrne T vrstico*)

View file

@ -2,31 +2,143 @@
(*sem spada izbira nacina naslavljanja, dolocanje ali je operand simbol itd..*) (*sem spada izbira nacina naslavljanja, dolocanje ali je operand simbol itd..*)
open SemanticAnalyzer open SemanticAnalyzer
open Simtab
open OpcodeTable
type operand =
| R of register
| RR of register * register
| RN of register * int (*register in število*)
| N of int (*številski operand*)
| S of string (*simbol*)
| None
let string_is_symbol (s : string) : bool * string = let string_is_symbol (s : string) : bool * operand =
try try
let _ = int_of_string s in let n = int_of_string s in
true, "" false, N n
with Failure _ -> false, s with Failure _ -> true, S s
(*preveri ali je operand iz mnemonic_type simbol ali stevilo*) (*preveri ali je operand iz mnemonic_type simbol ali stevilo*)
let operand_is_symbol (operand : mnemonic_type) : bool * string = (*vrne isSymbol in symbol*) let operand_is_symbol (x : lineSemantic) : (bool * operand * int) option = (*vrne isSymbol, operand in dolzino ukaza, ali none, če ukaza/direktive ne bomo zapisali v T file*)
match x.mnem with
| MnemonicD -> None
| MnemonicDn s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
| MnemonicF1 -> Some (false, None, x.len)
| MnemonicF2n n -> Some (false, N n, x.len)
| MnemonicF2r r1 -> Some (false, R r1, x.len)
| MnemonicF2rn (r1, n) -> Some (false, RN (r1, n), x.len)
| MnemonicF2rr (r1, r2) -> Some (false, RR (r1, r2), x.len)
| MnemonicF3 -> Some (false, None, x.len)
| MnemonicF3m s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
| MnemonicF4m s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
| MnemonicSd s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
| MnemonicSn _ -> None(*RESW in RESB že drugje obdelamo*)
| COMMENT -> None (*Comment ze obdelamo drugje*)
(*helper funkcija za registre*)
let int_of_reg (reg : register) : int =
match reg with
| A -> 0
| X -> 1
| L -> 2
| B -> 3
| S -> 4
| T -> 5
| F -> 6
| PC -> 8
| SW -> 9
(*helper funkcija*)
let int_to_hex_width (width : int) (n : int) : string =
let s = Printf.sprintf "%X" n in
let len = String.length s in
if len >= width then s
else String.make (width - len) '0' ^ s
let char_to_hex c =
Printf.sprintf "%02X" (Char.code c)
(*naredi binaren zapis F1 oz string nibblov celotnega ukaza*)
let get_bin_instruction_F1 (opcode : int) : string =
int_to_hex_width 2 opcode
(*naredi binaren zapis F2 oz string nibblov celotnega ukaza*)
let get_bin_instruction_F2 (opcode : int) (operand : operand) : string =
match operand with match operand with
| MnemonicD -> false, "" | RR (r1, r2) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 (int_of_reg r2))
| MnemonicDn s -> string_is_symbol s | RN (r1, n) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 n)
| MnemonicF1 -> false, "" | R r1 -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 0) (*r2 -> 0*)
| MnemonicF2n _ -> false, "" | N n -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 n) ^ (int_to_hex_width 1 0)
| MnemonicF2r _ -> false, "" | _ -> failwith "invalid operand type for F2 instruction"
| MnemonicF2rn (_, _) -> false, ""
| MnemonicF2rr (_, _) -> false, ""
| MnemonicF3 -> false, ""
| MnemonicF3m s -> string_is_symbol s
| MnemonicF4m s -> string_is_symbol s
| MnemonicSd s -> string_is_symbol s
| MnemonicSn _ -> false, ""
| COMMENT -> false, ""
let get_bin_instruction_F3 (opcode : int) (simtab : symtab) (operand : operand) (_ : int option) : string =
match operand with
| None -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 4 0) (*RSUB damo z disp = 0*)
| N n -> (*todo dodaj n_i*) (int_to_hex_width 2 opcode) ^ (*todo add xbpe*) (int_to_hex_width 1 0) ^ (int_to_hex_width 3 n)
| S s -> let operand = Hashtbl.find simtab s in (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 0) ^ (int_to_hex_width 3 operand)
| _ -> ""
let create_opcode_symbol (opcode : mnemonic) (locSimbola : int) : string = let get_bin_instruction_F4 (opcode : int) (simtab : symtab) (operand : operand) (_ : int option) : string =
match operand with
| None -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 6 0) (*RSUB damo z disp = 0*)
| N n -> (*todo dodaj n_i*) (int_to_hex_width 2 opcode) ^ (*todo add xbpe*) (int_to_hex_width 1 0) ^ (int_to_hex_width 5 n)
| S s -> let operand = Hashtbl.find simtab s in (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 0) ^ (int_to_hex_width 5 operand)
| _ -> ""
let create_opcode (simtab : symtab) (opcodeTab : opcodeTab) (opcode : mnemonic) (operand : operand) (formatLen : int) (loc : int option) : string =
(*izberi nacin naslavljanja in naredi string ukaza*) (*izberi nacin naslavljanja in naredi string ukaza*)
match formatLen with
| 1 -> get_bin_instruction_F1 (find_opcode opcodeTab opcode)
| 2 -> get_bin_instruction_F2 (find_opcode opcodeTab opcode) operand
| 3 -> get_bin_instruction_F3 (find_opcode opcodeTab opcode) simtab operand loc
| 4 -> get_bin_instruction_F4 (find_opcode opcodeTab opcode) simtab operand loc
| _ -> failwith "invalid formatLen"
(*opcode BYTE direktive*)
let create_opcode_byte (operand : string) : string =
if String.length operand < 3 then
failwith "Invalid BYTE operand, use X'...' or C'...'!"
else
match operand.[0] with
| 'C' ->
(* e.g., C'EOF' *)
let content = String.sub operand 2 (String.length operand - 3) in
let len = String.length content in
if len <> 1 then failwith "BYTE C'...' has to have a operand of length 1 inside hte '...' brackets!" else
String.concat "" (List.init (String.length content) (fun i -> char_to_hex content.[i]))
| 'X' ->
(* e.g., X'F1' *)
let hex = String.sub operand 2 (String.length operand - 3) in
if String.length hex >= 6 then
failwith "WORD X'...' has to have a operand of length <= 6 inside hte '...' brackets!"
else String.make (2 - String.length hex) '0' ^ hex
| _ ->
let n = int_of_string operand in
Printf.sprintf "%02X" n
let create_opcode_word (operand : string) : string =
if String.length operand = 0 then
failwith "Invalid WORD operand use X'...' or C'...'!"
else
match operand.[0] with
| 'C' ->
(* WORD as C'...' *)
let content = String.sub operand 2 (String.length operand - 3) in
let len = String.length content in
if len <> 3 then failwith "WORD C'...' has to have a operand of length 3 inside hte '...' brackets!" else
let hex = String.concat "" (List.init len (fun i -> char_to_hex content.[i])) in
(* pad to 6 hex digits for WORD *)
if String.length hex >= 6 then hex else String.make (6 - String.length hex) '0' ^ hex
| 'X' ->
(* WORD as X'...' *)
let hex = String.sub operand 2 (String.length operand - 3) in
if String.length hex >= 6 then
failwith "WORD X'...' has to have a operand of length <= 6 inside hte '...' brackets!"
else String.make (6 - String.length hex) '0' ^ hex
| _ ->
(* numeric constant *)
let n = int_of_string operand in
Printf.sprintf "%06X" n

View file

@ -0,0 +1,77 @@
open SemanticAnalyzer
type opcodeTab = (mnemonic, int) Hashtbl.t
let find_opcode (tab : opcodeTab) (mnemonic : mnemonic) : int =
try
Hashtbl.find tab mnemonic
with
| Not_found -> failwith (Printf.sprintf "[OpcodeTable] Mnemonic not found: '%s'." (string_of_mnemonic mnemonic) )
let get_opcode_table () : opcodeTab=
let opcode_table : (mnemonic, int) Hashtbl.t = Hashtbl.create 128 in
let add mnemonic opcode =
Hashtbl.add opcode_table mnemonic opcode
in
(* Format 1 *)
add FIX 0xC4;
add FLOAT 0xC0;
add HIO 0xC8;
add NORM 0xC1;
add SIO 0xF0;
add TIO 0xF8;
(* Format 2 *)
add ADDR 0x90;
add CLEAR 0xB4;
add COMPR 0xA0;
add DIVR 0x9C;
add MULR 0x98;
add RMO 0xAC;
add SHIFTL 0xA4;
add SHIFTR 0xA8;
add SUBR 0x94;
add SVC 0xB0;
add TIXR 0xB8;
(* Format 3 / 4 *)
add ADD 0x18;
add ADDF 0x58;
add AND 0x40;
add COMP 0x28;
add COMPF 0x88;
add DIV 0x24;
add J 0x3C;
add JEQ 0x30;
add JGT 0x34;
add JLT 0x38;
add JSUB 0x48;
add LDA 0x00;
add LDB 0x68;
add LDCH 0x50;
add LDF 0x70;
add LDL 0x08;
add LDS 0x6C;
add LDT 0x74;
add LDX 0x04;
add LPS 0xD0;
add MUL 0x20;
add OR 0x44;
add RD 0xD8;
add RSUB 0x4C;
add STA 0x0C;
add STB 0x78;
add STCH 0x54;
add STF 0x80;
add STL 0x14;
add STS 0x7C;
add STSW 0xE8;
add STT 0x84;
add STX 0x10;
add SUB 0x1C;
add SUBF 0x5C;
add TD 0xE0;
add TIX 0x2C;
add WD 0xDC;
opcode_table

View file

@ -117,6 +117,9 @@ type lineSemantic = {
ext : bool; (*za razlikovanje med F3 in F4*) ext : bool; (*za razlikovanje med F3 in F4*)
opcode : mnemonic; opcode : mnemonic;
mnem : mnemonic_type; mnem : mnemonic_type;
x : bool; (*ali imamo X naslavljanje*)
n : bool;
i : bool;
comment : string option; comment : string option;
len : int; (*dolžina, pove za koliko moramo povečati locctr*) len : int; (*dolžina, pove za koliko moramo povečati locctr*)
mutable loc : int option; (* assigned in pass1 *) mutable loc : int option; (* assigned in pass1 *)
@ -130,78 +133,30 @@ let getMnem (opcode : string) : mnemonic * bool =
let o = let o =
match opcode with match opcode with
(* ------------------- Format 1 instructions ------------------- *) (* ------------------- Format 1 instructions ------------------- *)
| "FIX" -> FIX | "FIX" -> FIX | "FLOAT" -> FLOAT | "HIO" -> HIO
| "FLOAT" -> FLOAT | "NORM" -> NORM | "SIO" -> SIO | "TIO" -> TIO
| "HIO" -> HIO
| "NORM" -> NORM
| "SIO" -> SIO
| "TIO" -> TIO
(* ------------------- Format 2 instructions ------------------- *) (* ------------------- Format 2 instructions ------------------- *)
| "ADDR" -> ADDR | "ADDR" -> ADDR | "CLEAR" -> CLEAR | "COMPR" -> COMPR | "DIVR" -> DIVR
| "CLEAR" -> CLEAR | "MULR" -> MULR | "RMO" -> RMO | "SHIFTL" -> SHIFTL | "SHIFTR" -> SHIFTR
| "COMPR" -> COMPR | "SUBR" -> SUBR | "SVC" -> SVC | "TIXR" -> TIXR
| "DIVR" -> DIVR
| "MULR" -> MULR
| "RMO" -> RMO
| "SHIFTL" -> SHIFTL
| "SHIFTR" -> SHIFTR
| "SUBR" -> SUBR
| "SVC" -> SVC
| "TIXR" -> TIXR
(* ------------------- Format 3/4 instructions ------------------- *) (* ------------------- Format 3/4 instructions ------------------- *)
| "ADD" -> ADD | "ADD" -> ADD | "ADDF" -> ADDF | "AND" -> AND | "COMP" -> COMP
| "ADDF" -> ADDF | "COMPF" -> COMPF | "DIV" -> DIV | "J" -> J | "JEQ" -> JEQ
| "AND" -> AND | "JGT" -> JGT | "JLT" -> JLT | "JSUB" -> JSUB | "LDA" -> LDA
| "COMP" -> COMP | "LDB" -> LDB | "LDCH" -> LDCH | "LDF" -> LDF | "LDL" -> LDL
| "COMPF" -> COMPF | "LDS" -> LDS | "LDT" -> LDT | "LDX" -> LDX | "LPS" -> LPS
| "DIV" -> DIV | "MUL" -> MUL | "OR" -> OR | "RD" -> RD | "RSUB" -> RSUB | "STA" -> STA
| "J" -> J | "STB" -> STB | "STCH" -> STCH | "STF" -> STF | "STL" -> STL | "STS" -> STS
| "JEQ" -> JEQ | "STSW" -> STSW | "STT" -> STT | "STX" -> STX | "SUB" -> SUB
| "JGT" -> JGT | "SUBF" -> SUBF | "TD" -> TD | "TIX" -> TIX | "WD" -> WD
| "JLT" -> JLT
| "JSUB" -> JSUB
| "LDA" -> LDA
| "LDB" -> LDB
| "LDCH" -> LDCH
| "LDF" -> LDF
| "LDL" -> LDL
| "LDS" -> LDS
| "LDT" -> LDT
| "LDX" -> LDX
| "LPS" -> LPS
| "MUL" -> MUL
| "OR" -> OR
| "RD" -> RD
| "RSUB" -> RSUB
| "STA" -> STA
| "STB" -> STB
| "STCH" -> STCH
| "STF" -> STF
| "STL" -> STL
| "STS" -> STS
| "STSW" -> STSW
| "STT" -> STT
| "STX" -> STX
| "SUB" -> SUB
| "SUBF" -> SUBF
| "TD" -> TD
| "TIX" -> TIX
| "WD" -> WD
(* ------------------- SIC/XE Directives ------------------- *) (* ------------------- SIC/XE Directives ------------------- *)
| "START" -> START | "START" -> START | "END" -> END | "ORG" -> ORG
| "END" -> END | "EQU" -> EQU | "BASE" -> BASE | "NOBASE" -> NOBASE
| "ORG" -> ORG | "LTORG" -> LTORG | "RESW" -> RESW | "RESB" -> RESB
| "EQU" -> EQU | "WORD" -> WORD | "BYTE" -> BYTE
| "BASE" -> BASE
| "NOBASE" -> NOBASE
| "LTORG" -> LTORG
| "RESW" -> RESW
| "RESB" -> RESB
| "WORD" -> WORD
| "BYTE" -> BYTE
(*comment*) (*comment*)
| "COMMENT" -> COMMENT | "COMMENT" -> COMMENT
@ -281,6 +236,7 @@ let getMnemType (opcode : mnemonic) (ext : bool) (operand : string list) : mnemo
| _, _ -> failwith (Printf.sprintf "Invalid operands for opcode %s: %d operands" | _, _ -> failwith (Printf.sprintf "Invalid operands for opcode %s: %d operands"
(string_of_mnemonic opcode) (List.length operand)) (string_of_mnemonic opcode) (List.length operand))
(*vrni dolzino ukaza*)
let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int = let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int =
match mnemType with match mnemType with
(* ----------- directives with no memory ----------- *) (* ----------- directives with no memory ----------- *)
@ -316,11 +272,48 @@ let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int =
| _ -> failwith "Narobe mnemoic glede na mnemType" | _ -> failwith "Narobe mnemoic glede na mnemType"
end end
(*preveri ali imaš X naslavljanje*)
let has_index (ops : string list) : bool * string list = (*vrne bool x in operande brez X*)
match ops with
| [lst; x] when String.uppercase_ascii x = "X" -> true, [lst] (*predpostavimo da se X pojavi na drugem mestu in nikoli na tretjem*)
| _ -> false, ops
(*dobi n in i bita in operande brez # ali @*)
let get_ni_bits (operands : string list) : bool * bool * string list =
match operands with
| [] ->
(true, true, [])
| op :: rest ->
if String.length op = 0 then
(true, true, operands)
else
match op.[0] with
| '#' ->
let stripped =String.sub op 1 (String.length op - 1) in
(false, true, stripped :: rest)
| '@' ->
let stripped = String.sub op 1 (String.length op - 1) in
(true, false, stripped :: rest)
| _ ->
(true, true, operands)
let checkLineSemantic (line : line) : lineSemantic = let checkLineSemantic (line : line) : lineSemantic =
let mnem, ext = getMnem line.opcode in let mnem, ext = getMnem line.opcode in
let mnemType = getMnemType mnem ext line.operand in let x, ops = has_index line.operand in
let n, i, ops = get_ni_bits ops in
let mnemType = getMnemType mnem ext ops in
let dolzina = getLen mnemType mnem in let dolzina = getLen mnemType mnem in
{line_no = line.line_no; label = line.label; ext = ext; opcode = mnem; mnem = mnemType; comment = line.comment; len = dolzina; loc = line.loc} { line_no = line.line_no;
label = line.label;
ext = ext;
opcode = mnem;
mnem = mnemType;
x = x;
n = n;
i = i;
comment = line.comment;
len = dolzina;
loc = line.loc}
let checkLineSemanticOfCode (code : line list) : lineSemantic list = let checkLineSemanticOfCode (code : line list) : lineSemantic list =
List.map (checkLineSemantic) code List.map (checkLineSemantic) code

View file

@ -11,5 +11,8 @@ let add_symbol (tab : symtab) (label : string) (addr : int) =
else else
Hashtbl.add tab label addr Hashtbl.add tab label addr
let find_symbol (tab : symtab) (label : string) : int = let find_symbol (tab : symtab) (label : string) : int =
Hashtbl.find tab label try
Hashtbl.find tab label
with
| Not_found -> failwith (Printf.sprintf "[SimTab] Symbol not found: '%s'." label)