-
Notifications
You must be signed in to change notification settings - Fork 0
/
simpleh8simulator.py
165 lines (141 loc) · 4.59 KB
/
simpleh8simulator.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# -*- coding: utf-8 -*-
import h8simulator
class SFormat() :
def __init__(self, filename=None) :
# プログラム名
self.programName = ""
# エントリアドレス
self.entryAddress = 0
# メモリデータ
self.memoryData = {}
if filename :
self.loadFromString(filename)
def setProgramName(self, value) :
self.programName = value
def getProgramName(self) :
return self.programName
def setEntryAddress(self, value) :
self.entryAddress = value
def getEntryAddress(self) :
return self.entryAddress
def setMemoryData(self, address, data) :
'''
メモリにバイトデータをセットするメソッド
address:開始アドレス
data:バイトデータ(整数のリスト,要素は8ビットとみなした整数値)
'''
for byte in data :
self.memoryData[address] = byte
address += 1
def getMemoryData(self) :
return self.memoryData
def loadFromFile(self, filename) :
'''
S-Format 解析用メソッド(引数がファイル名版)
filename:Sフォーマットのファイル名またはファイルへのパス
'''
self.loadFromString(open(filename, 'r').read())
def loadFromString(self, string) :
'''
S-Format 解析用メソッド
string:Sフォーマットの文字列(open(filename,'r').read()などを直接渡せばいい)
'''
for line in string.split() :
if line[:2] == "S0" :
self.setProgramName(''.join(map(chr, hexStrToNbyteList(line[8:-2], 1))))
elif line[:2] == "S1" :
address = hexStrToNbyteList(line[4:8], 2)[0]
data = hexStrToNbyteList(line[8:-2], 1)
self.setMemoryData(address, data)
elif line[:2] == "S2" :
address = hexStrToNbyteList(line[4:10], 3)[0]
data = hexStrToNbyteList(line[10:-2], 1)
self.setMemoryData(address, data)
elif line[:2] == "S3" :
address = hexStrToNbyteList(line[4:12], 4)[0]
data = hexStrToNbyteList(line[12:-2], 1)
self.setMemoryData(address, data)
elif line[:2] == "S4" :
pass
elif line[:2] == "S5" :
pass
elif line[:2] == "S6" :
pass
elif line[:2] == "S7" :
address = hexStrToNbyteList(line[4:12], 4)[0]
self.setEntryAddress(address)
elif line[:2] == "S8" :
address = hexStrToNbyteList(line[4:10], 3)[0]
self.setEntryAddress(address)
elif line[:2] == "S9" :
address = hexStrToNbyteList(line[4:8], 2)[0]
self.setEntryAddress(address)
else :
raise Exception("invalid format")
def hexStrToNbyteList(s, n) :
return [ int(s[2*n*x:2*n*(x+1)], 16) for x in range(len(s)/(2*n))]
class SimpleH8simulator(h8simulator.H8simulator) :
def __init__(self) :
h8simulator.H8simulator.__init__(self)
# SFormatファイル
self.sformat = SFormat()
# IOアドレス
self.outputAddress = 0x100002
def load(self, filename) :
self.sformat.loadFromFile(filename)
def reset(self) :
self.loadMemory(self.sformat.getMemoryData())
self.setProgramCounter(self.sformat.getEntryAddress())
for x in range(8) :
self.set32bitRegistor(x, 0)
self.setConditionCode(0)
self.outputBuf = []
self.set8bitMemory(self.outputAddress, 0)
def runStep(self) :
h8simulator.H8simulator.runStep(self)
self.runIO()
def runIO(self) :
if self.get8bitMemory(self.outputAddress) != 0 :
self.outputBuf.insert(0, "%c" % self.get8bitMemory(self.outputAddress))
self.set8bitMemory(self.outputAddress, 0)
def getDisAssembly(self, address=None, disasm={}) :
if address == None :
self.reset()
else :
self.setProgramCounter(address)
jump_operation_list = [
'BHI',
'BLS',
'BCC',
'BCS',
'BNE',
'BEQ',
'BVC',
'BVS',
'BPL',
'BMI',
'BGE',
'BLT',
'BGT',
'BLE',
'BSR',
'JSR',
]
while True :
old_program_counter = self.getProgramCounter()
try :
self.runStep()
except :
pass
disasm[old_program_counter] = self.getMnemonic()
if self.operation_mnemonic == "RTS" :
break
if any([self.operation_mnemonic == x for x in jump_operation_list]) :
jump1 = old_program_counter + self.opecode_size
jump2 = self.operands['src']['effective_address']
if jump1 not in disasm :
self.getDisAssembly(jump1, disasm)
if jump2 not in disasm :
self.getDisAssembly(jump2, disasm)
break
return disasm