forked from redcode/SpecEmu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPCLogging.asm
294 lines (224 loc) · 12.6 KB
/
PCLogging.asm
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
Get_PC_Log_Parent PROTO
Log_Base16 PROTO :DWORD,:WORD
Log_Newline PROTO
WARN_SIZE_STEP equ 20 * 1024 * 1024
align 16
Get_PC_Log_Parent proc
.if DebuggerActive == TRUE
mov eax, Debugger_hWnd ; debugger main window
.else
mov eax, hWnd ; specemu main window
.endif
ret
Get_PC_Log_Parent endp
; brings up a file requester if lpFilename = NULL
align 16
Start_PC_Logging proc uses ebx,
lpFilename: PTR
local hParent: HWND,
ofn: OPENFILENAME
ifc DoLogging eq TRUE then ret ; exit immediately if already logging
mov InitialLogOpcode, FALSE
mov ebx, FALSE
.if lpFilename == NULL
mov hParent, $fnc (Get_PC_Log_Parent)
.if $fnc (SaveFileName, hParent, SADD ("Save PC Log"), addr szLOGFilter, addr ofn, addr PCLog_Filename, addr LOGExt, 0) != 0
.if $fnc (AskOverwriteFile, addr PCLog_Filename, hParent, addr szWindowName) == TRUE
mov ebx, TRUE
.endif
.endif
.else
strncpy lpFilename, addr PCLog_Filename, sizeof PCLog_Filename
mov ebx, TRUE
.endif
.if ebx
mov PCLogFileStream, $fnc (CreateFileStream, addr PCLog_Filename, FSA_WRITE, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 16384)
.if eax != -1
mov DoLogging, TRUE
mov PCLog_Filesize, 0
mov PCLog_Warnsize, WARN_SIZE_STEP
mov ax, zPC
inc ax
mov PrevzPC, ax ; ensure logging of first opcode. previous PC != PC
mov InitialLogOpcode, TRUE ; initial log opcode has initial register values dumped
.endif
.endif
invoke SetDebuggerLogButtonState
ret
Start_PC_Logging endp
align 16
Stop_PC_Logging proc
ifc DoLogging eq FALSE then ret
invoke Log_Newline
invoke Log_Registers
invoke CloseFileStream, PCLogFileStream
mov DoLogging, FALSE
invoke SetDebuggerLogButtonState
ret
Stop_PC_Logging endp
align 16
SetDebuggerLogButtonState proc uses ebx
ifc DebuggerActive eq FALSE then ret
invoke CheckDlgButton, Debugger_hWnd, IDC_START_STOP_LOGGING_CHK, ZeroExt (DoLogging)
.if DoLogging == TRUE
mov ebx, CTXT ("Stop PC Trace")
.else
mov ebx, CTXT ("Start PC Trace")
.endif
invoke SetDlgItemText, Debugger_hWnd, IDC_START_STOP_LOGGING_CHK, ebx
ret
SetDebuggerLogButtonState endp
align 16
Log_PC proc uses ebx
local textstring: TEXTSTRING,
pTEXTSTRING:DWORD
.if DoLogging == TRUE
; start PC logging code
mov ax, zPC
.if ax != PrevzPC
.if InitialLogOpcode ; initial log opcode has initial register values dumped (this gets set back to TRUE at the start of each frame)
invoke Log_Newline
invoke Log_Registers
invoke Log_Newline
mov InitialLogOpcode, FALSE
.endif
invoke INITTEXTSTRING, addr textstring, addr pTEXTSTRING
invoke Log_Base16, pTEXTSTRING, zPC
; push ebx
; mov bx, zPC
; call MemGetByte
; ADDTEXTHEX pTEXTSTRING, al
; pop ebx
; ADDCHAR pTEXTSTRING, 32
; log current tstate count
ADDTEXTDECIMAL pTEXTSTRING, totaltstates, ATD_SPACES
ifdef LOGOPCODES
ADDCHAR pTEXTSTRING, 9
mov ax, zPC
mov Z80PC, ax
invoke DisassembleLine, pTEXTSTRING
endif
ADDCHAR pTEXTSTRING, 13, 10
; mov ecx, len (addr textstring)
mov ecx, $fnc (GETTEXTLEN, pTEXTSTRING)
add PCLog_Filesize, ecx
invoke WriteFileStream, PCLogFileStream, addr textstring, ecx
; warn on filesize of PC log file
mov eax, PCLog_Filesize
.if eax >= PCLog_Warnsize
add PCLog_Warnsize, WARN_SIZE_STEP
pushad
invoke INITTEXTSTRING, addr textstring, addr pTEXTSTRING
ADDDIRECTTEXTSTRING pTEXTSTRING, "Your PC log file size is now "
invoke IntDiv, PCLog_Filesize, 1024 * 1024
ADDTEXTDECIMAL pTEXTSTRING, eax
ADDDIRECTTEXTSTRING pTEXTSTRING, " MB."
ADDCHAR pTEXTSTRING, 13
ADDDIRECTTEXTSTRING pTEXTSTRING, " Do you want to continue logging?"
MouseOn
mov ebx, $fnc (Get_PC_Log_Parent)
invoke ShowMessageBox, ebx, addr textstring, addr szWindowName, MB_YESNO or MB_ICONWARNING or MB_DEFBUTTON1
.if eax == IDNO
invoke Stop_PC_Logging
invoke ShowMessageBox, $fnc (Get_PC_Log_Parent), SADD ("PC logging has stopped."), addr szWindowName, MB_OK or MB_ICONINFORMATION
.endif
MouseOff
popad
.endif
.endif
; end PC logging code
.endif
ret
Log_PC endp
align 16
Log_Registers proc
local textstring: TEXTSTRING,
pTEXTSTRING:DWORD
.if DoLogging == TRUE
; log all registers
invoke INITTEXTSTRING, addr textstring, addr pTEXTSTRING
ADDDIRECTTEXTSTRING pTEXTSTRING, "PC: #"
mov ax, zPC
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "SP: #"
mov ax, z80registers._sp
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 13, 10
ADDDIRECTTEXTSTRING pTEXTSTRING, "IX: #"
mov ax, z80registers.ix.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "IY: #"
mov ax, z80registers.iy.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 13, 10
ADDDIRECTTEXTSTRING pTEXTSTRING, "HL: #"
mov ax, z80registers.hl.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "HL': #"
mov ax, z80registers.hl_.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 13, 10
ADDDIRECTTEXTSTRING pTEXTSTRING, "DE: #"
mov ax, z80registers.de.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "DE': #"
mov ax, z80registers.de_.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 13, 10
ADDDIRECTTEXTSTRING pTEXTSTRING, "BC: #"
mov ax, z80registers.bc.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "BC': #"
mov ax, z80registers.bc_.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 13, 10
ADDDIRECTTEXTSTRING pTEXTSTRING, "AF: #"
mov ax, z80registers.af.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "AF': #"
mov ax, z80registers.af_.w
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 13, 10
ADDDIRECTTEXTSTRING pTEXTSTRING, "IR: #"
mov ah, z80registers.i
mov al, z80registers.r
and al, 127
or al, z80registers.r_msb
ADDTEXTHEX pTEXTSTRING, ax
ADDCHAR pTEXTSTRING, 9
ADDDIRECTTEXTSTRING pTEXTSTRING, "IM: #"
mov al, z80registers.intmode
ADDTEXTHEX pTEXTSTRING, al
ADDCHAR pTEXTSTRING, 13, 10
mov ecx, len (addr textstring)
add PCLog_Filesize, ecx
invoke WriteFileStream, PCLogFileStream, addr textstring, ecx; len (addr textstring)
; end log all registers
.endif
ret
Log_Registers endp
align 16
Log_Base16 proc lptextstring: DWORD,
val16: WORD
.if ShowHex == TRUE
ADDTEXTHEX lptextstring, val16
.else
ADDTEXTDECIMAL lptextstring, val16, ATD_SPACES
.endif
ret
Log_Base16 endp
.const
Log_Newline_txt db 13, 10
.code
align 16
Log_Newline proc
invoke WriteFileStream, PCLogFileStream, addr Log_Newline_txt, sizeof Log_Newline_txt
add PCLog_Filesize, sizeof Log_Newline_txt
ret
Log_Newline endp