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

View file

@ -1,21 +1,24 @@
***** 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
name start size #ins #dir #sto
<default> 00000 0003D 16 8 1
<default> 00010 00043 17 9 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
halt 00003E 62 local relative code label
p 000010 16 local relative data label
poly 000010 16 exported relative code label
rez 000050 80 local relative data label
start 000014 20 local relative code label
x 00004D 77 local relative data label
x0 00004A 74 local relative data label
x1 000047 71 local relative data label
x2 000044 68 local relative data label
x3 000041 65 local relative data label
x4 000018 24 local relative data label
Literals
label definition
Relocations
address length flag symbol
00015 5
0001C 5

View file

@ -1,38 +1,42 @@
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)
00010 poly START 16
00010 EF p BYTE X'EF'
00011 190022 ADD #34
00014 77900018 start +LDT x4,X
00018 000001 x4 WORD 1
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
00010 9840 MULR S,A
00012 9050 ADDR T,A . do sedaj izračunano ((1x+2)x + 3)
00026 77201B LDT x2
00029 9840 MULR S,A
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
00017 9840 MULR S,A
00019 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)
00034 772013 LDT x0
00037 9840 MULR S,A
00039 9050 ADDR T,A . do sedaj izračunano (((1x+2)x + 3)x + 4)x + 5
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
. fullline comment
0003B 0F2012 STA rez
0003E 3F2FFD halt J halt
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
00041 000002 x3 WORD 2
00044 000003 x2 WORD 3
00047 000004 x1 WORD 4
0004A 000005 x0 WORD 5
. tocka
00037 000002 x WORD 2
0004D 000002 x WORD 2
. rezultat
0003A 000000 rez RESW 1
00050 000000 rez RESW 1
00053 END start

View file

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

View file

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

View file

@ -74,7 +74,7 @@ let readAddress (state : Processor.state) : int =
address
(*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 =
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*)
@ -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 failwith "Invalid addressing mode"
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 ea =
@ -153,7 +159,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 ea ,operand = getOperandF3 state nixbpe disp in
let ea ,operand, valueMem = 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;
@ -191,15 +197,15 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode
| LDT -> IzvajalnikF3.ldt state operand
| LDX -> IzvajalnikF3.ldx state operand
| LPS -> notImplemented "LPS4"
| STA -> IzvajalnikF3.sta state ea
| STB -> IzvajalnikF3.stb state ea
| STCH -> IzvajalnikF3.stch state ea
| STA -> IzvajalnikF3.sta state valueMem
| STB -> IzvajalnikF3.stb state valueMem
| STCH -> IzvajalnikF3.stch state valueMem
| STF -> notImplemented "STF4"
| STL -> IzvajalnikF3.stl state ea
| STS -> IzvajalnikF3.sts state ea
| STSW -> IzvajalnikF3.stsw state ea
| STT -> IzvajalnikF3.stt state ea
| STX -> IzvajalnikF3.stx state ea
| STL -> IzvajalnikF3.stl state valueMem
| STS -> IzvajalnikF3.sts state valueMem
| STSW -> IzvajalnikF3.stsw state valueMem
| STT -> IzvajalnikF3.stt state valueMem
| STX -> IzvajalnikF3.stx state valueMem
(* Control / IO *)
| 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 byte2 = Char.chr ((value lsr 8) 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 *)
Bytes.set state.memory address byte1;
Bytes.set state.memory (address+1) byte2;

View file

@ -2,6 +2,8 @@ open Zbirnik.Parser
open Zbirnik.SemanticAnalyzer
open Zbirnik.PrehodPrvi
open Zbirnik.Simtab
open Zbirnik.DrugiPrehod
open Zbirnik.OpcodeTable
(* Helper functions to print optional values *)
@ -27,14 +29,17 @@ let print_lineSemantic_list (lines : lineSemantic list) : unit =
) lines
let print_intermediate_file_list (lines : lineSemantic list) : unit =
List.iter (fun l ->
Printf.printf "%s | %8s | %6s | %20s | %s\n"
(print_opt_int l.loc)
(print_opt_string l.label)
(string_of_mnemonic l.opcode)
(string_of_mnemonic_type l.mnem)
(print_opt_string l.comment)
) lines
List.iter (fun l ->
Printf.printf "%s | %8s | %6s | %20s | x=%d | n = %d | i = %d | %s\n"
(print_opt_int l.loc)
(print_opt_string l.label)
(string_of_mnemonic l.opcode)
(string_of_mnemonic_type l.mnem)
(if l.x then 1 else 0)
(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 =
Printf.printf "\nSYMBOL TABLE\n";
@ -46,6 +51,9 @@ let print_symtab (tab : symtab) : unit =
) tab;
Printf.printf "----------------------\n"
let print_object_code (objectCodeList : string list) : unit =
List.iter (fun s -> print_endline s) objectCodeList
let run () =
let lineSemantic = (checkLineSemanticOfCode (parser "../../ass1/horner.asm") ) in
print_lineSemantic_list lineSemantic;
@ -54,6 +62,9 @@ let run () =
Printf.printf "Program Length je: %d\n" prlen;
print_intermediate_file_list prehod1;
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 Encoder
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 =
match ifl with
| [] -> failwith "empty code"
@ -41,29 +42,35 @@ let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : st
| [] -> loop xs objectCodeList newStartAddress []
| _ -> loop xs (newTextLine :: objectCodeList) newStartAddress []
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 simbol na mestu opeanda*)
let isSymbol, symbol = operand_is_symbol x.mnem in
if isSymbol then
begin
let locSimbola = find_symbol tab symbol in
let opcode = create_opcode_symbol x.opcode locSimbola in
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
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
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
match operand_is_symbol x with
| None -> loop xs objectCodeList newStartAddress instructionList (*None -> ta ukaz se ne zapiše, ga skipamo*)
| Some (_, operand, formatLen) ->
let opcode = create_opcode simtab opcodeTab x.opcode operand formatLen x.loc 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)
in loop ostaliUkazi objectCodeList startAddr instructionList
in loop ostaliUkazi objectCodeList start instructionList

View file

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

View file

@ -7,17 +7,17 @@ let getZaglavjeAndStart (prviUkaz : lineSemantic) (lenProg : int) : string list
| 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*)
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*)
let n = int_of_string s in
if n < 0 || n > 0xFFFFFF then
invalid_arg "getZaglavje: zacetni naslov out of range"
else
Printf.sprintf "%06X" n
(Printf.sprintf "%06X" n), n
| _ -> failwith "getZaglavje: invalid mnemonic_type"
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*)

View file

@ -2,31 +2,143 @@
(*sem spada izbira nacina naslavljanja, dolocanje ali je operand simbol itd..*)
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
let _ = int_of_string s in
true, ""
with Failure _ -> false, s
let n = int_of_string s in
false, N n
with Failure _ -> true, S s
(*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
| MnemonicD -> false, ""
| MnemonicDn s -> string_is_symbol s
| MnemonicF1 -> false, ""
| MnemonicF2n _ -> false, ""
| MnemonicF2r _ -> false, ""
| 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, ""
| 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))
| RN (r1, n) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 n)
| 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*)
| N n -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 n) ^ (int_to_hex_width 1 0)
| _ -> failwith "invalid operand type for F2 instruction"
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*)
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*)
opcode : mnemonic;
mnem : mnemonic_type;
x : bool; (*ali imamo X naslavljanje*)
n : bool;
i : bool;
comment : string option;
len : int; (*dolžina, pove za koliko moramo povečati locctr*)
mutable loc : int option; (* assigned in pass1 *)
@ -130,78 +133,30 @@ let getMnem (opcode : string) : mnemonic * bool =
let o =
match opcode with
(* ------------------- Format 1 instructions ------------------- *)
| "FIX" -> FIX
| "FLOAT" -> FLOAT
| "HIO" -> HIO
| "NORM" -> NORM
| "SIO" -> SIO
| "TIO" -> TIO
| "FIX" -> FIX | "FLOAT" -> FLOAT | "HIO" -> HIO
| "NORM" -> NORM | "SIO" -> SIO | "TIO" -> TIO
(* ------------------- Format 2 instructions ------------------- *)
| "ADDR" -> ADDR
| "CLEAR" -> CLEAR
| "COMPR" -> COMPR
| "DIVR" -> DIVR
| "MULR" -> MULR
| "RMO" -> RMO
| "SHIFTL" -> SHIFTL
| "SHIFTR" -> SHIFTR
| "SUBR" -> SUBR
| "SVC" -> SVC
| "TIXR" -> TIXR
| "ADDR" -> ADDR | "CLEAR" -> CLEAR | "COMPR" -> COMPR | "DIVR" -> DIVR
| "MULR" -> MULR | "RMO" -> RMO | "SHIFTL" -> SHIFTL | "SHIFTR" -> SHIFTR
| "SUBR" -> SUBR | "SVC" -> SVC | "TIXR" -> TIXR
(* ------------------- Format 3/4 instructions ------------------- *)
| "ADD" -> ADD
| "ADDF" -> ADDF
| "AND" -> AND
| "COMP" -> COMP
| "COMPF" -> COMPF
| "DIV" -> DIV
| "J" -> J
| "JEQ" -> JEQ
| "JGT" -> JGT
| "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
| "ADD" -> ADD | "ADDF" -> ADDF | "AND" -> AND | "COMP" -> COMP
| "COMPF" -> COMPF | "DIV" -> DIV | "J" -> J | "JEQ" -> JEQ
| "JGT" -> JGT | "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 ------------------- *)
| "START" -> START
| "END" -> END
| "ORG" -> ORG
| "EQU" -> EQU
| "BASE" -> BASE
| "NOBASE" -> NOBASE
| "LTORG" -> LTORG
| "RESW" -> RESW
| "RESB" -> RESB
| "WORD" -> WORD
| "BYTE" -> BYTE
| "START" -> START | "END" -> END | "ORG" -> ORG
| "EQU" -> EQU | "BASE" -> BASE | "NOBASE" -> NOBASE
| "LTORG" -> LTORG | "RESW" -> RESW | "RESB" -> RESB
| "WORD" -> WORD | "BYTE" -> BYTE
(*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"
(string_of_mnemonic opcode) (List.length operand))
(*vrni dolzino ukaza*)
let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int =
match mnemType with
(* ----------- directives with no memory ----------- *)
@ -316,11 +272,48 @@ let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int =
| _ -> failwith "Narobe mnemoic glede na mnemType"
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 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
{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 =
List.map (checkLineSemantic) code

View file

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