forked from BNOECHO/SIC_Assemblers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOn_Site_test_1.py
117 lines (100 loc) · 5.37 KB
/
On_Site_test_1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
SIC_CMD_List = list()
current_Address = 0
start_Address = int()
SYMTAB = dict() # string, int
Opcode = {
"Add": "18","AND": "40","COMP": "28","DIV": "24","J": "3C","JEQ": "30","JGT": "34","JLT": "38","JSUB": "48","LDA": "00","LDCH": "50","LDL": "08","LDX": "04","MUL": "20","OR": "44","RD": "D8","RSUB": "4C","STA": "0C","STCH": "54","STL": "14","STSW": "E8","STX": "10","SUB": "1C","TD": "E0","TIX": "2C","WD": "DC"
}
output = list()
loc = list()
class SIC:
def __init__(self, line: str):
print(line)
self.address_Label, self.mnemonic_Opcode = line.removesuffix('\n').split('\t')[:2] #address_Label, mnemonic_Opcode, operand
self.operands = line.removesuffix('\n').split('\t')[2] if len(line.removesuffix('\n').split('\t')) > 2 else ""
self.object_Code = str()
self.address = 0
self.isDirectives = True; # 是否為組譯器指引(虛指令)
def cal_Size(self): #計算大小同時生成虛指令的物件碼
global start_Address
self.length = 0
match self.mnemonic_Opcode:
case 'START':
start_Address = int(self.operands, 16)
self.address = start_Address
self.object_Code = 'H' + self.address_Label.ljust(6, ' ') + f'{start_Address:x}'.rjust(6, '0')
self.length = int(self.operands, 16)
case 'END':
self.object_Code = 'E' + f'{start_Address:x}'.rjust(6, '0')
self.length = 0
case 'BYTE':
if self.operands.startswith('X'):
self.object_Code = self.operands[2:-1]
if self.operands.startswith('C'):
self.object_Code = self.operands[2:-1].encode().hex()
self.length = len(self.object_Code) // 2
case 'WORD':
self.object_Code = hex(int(self.operands)).lstrip("0x").zfill(6)
self.length = 3
case 'RESB':
self.length = int(self.operands)
case 'RESW':
self.length = int(self.operands) * 3
case _:
#實指令皆為3byte (format 1/2/4指令 只存在於XE)
self.isDirectives = False
return 3
return self.length #回傳長度
def pass_2(self):
if self.isDirectives:
output.append(f"{self.address:04X}\t{self.address_Label}\t{self.mnemonic_Opcode}\t{self.operands}")
if self.mnemonic_Opcode in ["BYTE","WORD"]:
output.append(f"\t{self.object_Code}")
output.append("\n")
return
addressing_Mode = 0
if self.operands != '' and self.operands.endswith(',X'):
addressing_Mode = 0x8000
self.operands = self.operands.removesuffix(',X')
self.object_Code = Opcode[self.mnemonic_Opcode] + hex(SYMTAB[self.operands] + addressing_Mode).removeprefix('0x').rjust(4, '0')
output.append(f"{self.address:04X}\t{self.address_Label}\t{self.mnemonic_Opcode}\t{self.operands}")
# if not self.isDirectives or self.mnemonic_Opcode == "BYTE" or self.mnemonic_Opcode == "WORD":
output.append(f"\t{self.object_Code.upper()}") #hex(int(string))
output.append("\n")
def pass_1(self):
global current_Address
self.address = current_Address
current_Address += self.cal_Size() #下一個指令的起始位置
if self.address_Label != '':
SYMTAB.update({self.address_Label: self.address})
# output to loc
loc.append(f"{self.address:04X}\t{self.address_Label}\t{self.mnemonic_Opcode}\t{self.operands}\n")
if __name__ == "__main__":
with open("input1.txt", "r") as f:
SIC_CMD_List = [SIC(i) for i in f.readlines() if not i.startswith('.')]
for i in SIC_CMD_List:
i.pass_1()
SYMTAB.update({'': 0}) #空字串代表沒有label
for i in SIC_CMD_List:
i.pass_2()
with open("objectcode.txt", "w") as f:
f.write(SIC_CMD_List[0].object_Code + f'{(current_Address - start_Address):x}'.rjust(6, '0').upper() + '\n')
line_Start_Address = -1; line_Object_Code = str()
for i in range(1, len(SIC_CMD_List)-1):
print(SIC_CMD_List[i].object_Code)
if SIC_CMD_List[i].object_Code == '':
continue #如果為空則跳過
if line_Start_Address == -1:
line_Start_Address = SIC_CMD_List[i].address #紀錄該行開頭的位置
line_Object_Code += SIC_CMD_List[i].object_Code
if (len(line_Object_Code) + len(SIC_CMD_List[i+1].object_Code)) > 60 or SIC_CMD_List[i+1].object_Code == '' or SIC_CMD_List[i+1].mnemonic_Opcode == 'END': #若長度達到極限(加上下一筆超過60個字元) 或是下一行並無物件碼/為END則輸出
f.write('T' + hex(line_Start_Address).removeprefix('0x').rjust(6, '0').upper() + hex(len(line_Object_Code)//2).removeprefix('0x').rjust(2, '0').upper() + line_Object_Code.removeprefix('0x').upper() + '\n')
line_Start_Address = -1
line_Object_Code = str()
f.write(SIC_CMD_List[-1].object_Code.upper())
with open("loc.txt", "w") as f:
for line in loc:
f.write(line)
with open("output.txt", "w") as f:
for line in output:
f.write(line.upper())