~random-stuff/random-stuff/snes9x-OLD

1 by OV2
Initial 1.52 import
1
/***********************************************************************************
2
  Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3
4
  (c) Copyright 1996 - 2002  Gary Henderson (gary.henderson@ntlworld.com),
5
                             Jerremy Koot (jkoot@snes9x.com)
6
7
  (c) Copyright 2002 - 2004  Matthew Kendora
8
9
  (c) Copyright 2002 - 2005  Peter Bortas (peter@bortas.org)
10
11
  (c) Copyright 2004 - 2005  Joel Yliluoma (http://iki.fi/bisqwit/)
12
13
  (c) Copyright 2001 - 2006  John Weidman (jweidman@slip.net)
14
15
  (c) Copyright 2002 - 2006  funkyass (funkyass@spam.shaw.ca),
16
                             Kris Bleakley (codeviolation@hotmail.com)
17
18
  (c) Copyright 2002 - 2010  Brad Jorsch (anomie@users.sourceforge.net),
19
                             Nach (n-a-c-h@users.sourceforge.net),
87 by OV2
Update copyright in all files
20
21
  (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
1 by OV2
Initial 1.52 import
22
23
  (c) Copyright 2006 - 2007  nitsuja
24
290 by Brandon Wright
Update some copyrights, bump version number.
25
  (c) Copyright 2009 - 2016  BearOso,
1 by OV2
Initial 1.52 import
26
                             OV2
27
28
29
  BS-X C emulator code
30
  (c) Copyright 2005 - 2006  Dreamer Nom,
31
                             zones
32
33
  C4 x86 assembler and some C emulation code
34
  (c) Copyright 2000 - 2003  _Demo_ (_demo_@zsnes.com),
35
                             Nach,
36
                             zsKnight (zsknight@zsnes.com)
37
38
  C4 C++ code
39
  (c) Copyright 2003 - 2006  Brad Jorsch,
40
                             Nach
41
42
  DSP-1 emulator code
43
  (c) Copyright 1998 - 2006  _Demo_,
44
                             Andreas Naive (andreasnaive@gmail.com),
45
                             Gary Henderson,
46
                             Ivar (ivar@snes9x.com),
47
                             John Weidman,
48
                             Kris Bleakley,
49
                             Matthew Kendora,
50
                             Nach,
51
                             neviksti (neviksti@hotmail.com)
52
53
  DSP-2 emulator code
54
  (c) Copyright 2003         John Weidman,
55
                             Kris Bleakley,
56
                             Lord Nightmare (lord_nightmare@users.sourceforge.net),
57
                             Matthew Kendora,
58
                             neviksti
59
60
  DSP-3 emulator code
61
  (c) Copyright 2003 - 2006  John Weidman,
62
                             Kris Bleakley,
63
                             Lancer,
64
                             z80 gaiden
65
66
  DSP-4 emulator code
67
  (c) Copyright 2004 - 2006  Dreamer Nom,
68
                             John Weidman,
69
                             Kris Bleakley,
70
                             Nach,
71
                             z80 gaiden
72
73
  OBC1 emulator code
74
  (c) Copyright 2001 - 2004  zsKnight,
75
                             pagefault (pagefault@zsnes.com),
76
                             Kris Bleakley
77
                             Ported from x86 assembler to C by sanmaiwashi
78
79
  SPC7110 and RTC C++ emulator code used in 1.39-1.51
80
  (c) Copyright 2002         Matthew Kendora with research by
81
                             zsKnight,
82
                             John Weidman,
83
                             Dark Force
84
85
  SPC7110 and RTC C++ emulator code used in 1.52+
86
  (c) Copyright 2009         byuu,
87
                             neviksti
88
89
  S-DD1 C emulator code
90
  (c) Copyright 2003         Brad Jorsch with research by
91
                             Andreas Naive,
92
                             John Weidman
93
94
  S-RTC C emulator code
95
  (c) Copyright 2001 - 2006  byuu,
96
                             John Weidman
97
98
  ST010 C++ emulator code
99
  (c) Copyright 2003         Feather,
100
                             John Weidman,
101
                             Kris Bleakley,
102
                             Matthew Kendora
103
104
  Super FX x86 assembler emulator code
105
  (c) Copyright 1998 - 2003  _Demo_,
106
                             pagefault,
107
                             zsKnight
108
109
  Super FX C emulator code
110
  (c) Copyright 1997 - 1999  Ivar,
111
                             Gary Henderson,
112
                             John Weidman
113
114
  Sound emulator code used in 1.5-1.51
115
  (c) Copyright 1998 - 2003  Brad Martin
116
  (c) Copyright 1998 - 2006  Charles Bilyue'
117
118
  Sound emulator code used in 1.52+
119
  (c) Copyright 2004 - 2007  Shay Green (gblargg@gmail.com)
120
295 by Brandon Wright
Add byuu copyright for his S-SMP
121
  S-SMP emulator code used in 1.54+
122
  (c) Copyright 2016         byuu
123
1 by OV2
Initial 1.52 import
124
  SH assembler code partly based on x86 assembler code
125
  (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
126
127
  2xSaI filter
128
  (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
129
130
  HQ2x, HQ3x, HQ4x filters
131
  (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
132
133
  NTSC filter
134
  (c) Copyright 2006 - 2007  Shay Green
135
136
  GTK+ GUI code
290 by Brandon Wright
Update some copyrights, bump version number.
137
  (c) Copyright 2004 - 2016  BearOso
1 by OV2
Initial 1.52 import
138
139
  Win32 GUI code
140
  (c) Copyright 2003 - 2006  blip,
141
                             funkyass,
142
                             Matthew Kendora,
143
                             Nach,
144
                             nitsuja
298 by Brandon Wright
Bump OV2 Windows port copyright.
145
  (c) Copyright 2009 - 2016  OV2
1 by OV2
Initial 1.52 import
146
147
  Mac OS GUI code
148
  (c) Copyright 1998 - 2001  John Stiles
87 by OV2
Update copyright in all files
149
  (c) Copyright 2001 - 2011  zones
1 by OV2
Initial 1.52 import
150
151
152
  Specific ports contains the works of other authors. See headers in
153
  individual files.
154
155
156
  Snes9x homepage: http://www.snes9x.com/
157
158
  Permission to use, copy, modify and/or distribute Snes9x in both binary
159
  and source form, for non-commercial purposes, is hereby granted without
160
  fee, providing that this license information and copyright notice appear
161
  with all copies and any derived work.
162
163
  This software is provided 'as-is', without any express or implied
164
  warranty. In no event shall the authors be held liable for any damages
165
  arising from the use of this software or it's derivatives.
166
167
  Snes9x is freeware for PERSONAL USE only. Commercial users should
168
  seek permission of the copyright holders first. Commercial use includes,
169
  but is not limited to, charging money for Snes9x or software derived from
170
  Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
171
  using Snes9x as a promotion for your commercial product.
172
173
  The copyright holders request that bug fixes and improvements to the code
174
  should be forwarded to them so everyone can benefit from the modifications
175
  in future versions.
176
177
  Super NES and Super Nintendo Entertainment System are trademarks of
178
  Nintendo Co., Limited and its subsidiary companies.
179
 ***********************************************************************************/
180
181
182
#ifdef DEBUGGER
183
184
#include <stdarg.h>
185
#include "snes9x.h"
186
#include "memmap.h"
187
#include "cpuops.h"
188
#include "dma.h"
189
#include "apu/apu.h"
190
#include "display.h"
191
#include "debug.h"
192
#include "missing.h"
193
194
extern SDMA	DMA[8];
195
extern FILE	*apu_trace;
196
FILE		*trace = NULL, *trace2 = NULL;
197
198
struct SBreakPoint	S9xBreakpoint[6];
199
200
struct SDebug
201
{
202
	struct
203
	{
204
		uint8	Bank;
205
		uint16	Address;
206
	}	Dump;
207
208
	struct
209
	{
210
		uint8	Bank;
211
		uint16	Address;
212
	}	Unassemble;
213
};
214
215
static struct SDebug	Debug = { { 0, 0 }, { 0, 0 } };
216
217
static const char	*HelpMessage[] =
218
{
219
	"Command Help:",
220
	"?, help                - Shows this command help",
221
	"r                      - Shows the registers",
222
	"i                      - Shows the interrupt vectors",
223
	"t                      - Trace current instruction   [step-into]",
224
	"p                      - Proceed to next instruction [step-over]",
225
	"s                      - Skip to next instruction    [skip]",
226
	"T                      - Toggle CPU instruction tracing to trace.log",
227
	"TS                     - Toggle SA-1 instruction tracing to trace_sa1.log",
228
	"E                      - Toggle HC-based event tracing to trace.log",
229
	"V                      - Toggle non-DMA V-RAM read/write tracing to stdout",
230
	"D                      - Toggle on-screen DMA tracing",
231
	"H                      - Toggle on-screen HDMA tracing",
232
	"U                      - Toggle on-screen unknown register read/write tracing",
233
	"P                      - Toggle on-screen DSP tracing",
234
	"S                      - Dump sprite (OBJ) status",
235
	"g [Address]            - Go or go to [Address]",
236
	"u [Address]            - Disassemble from PC or [Address]",
237
	"d [Address]            - Dump from PC or [Address]",
238
	"bv [Number]            - View breakpoints or view breakpoint [Number]",
239
	"bs [Number] [Address]  - Enable/disable breakpoint",
240
	"                         [enable example: bs #2 $02:8002]",
241
	"                         [disable example: bs #2]",
242
	"c                      - Dump SNES colour palette",
243
	"W                      - Show what SNES hardware features the ROM is using",
244
	"                         which might not be implemented yet",
245
	"w                      - Show some SNES hardware features used so far in this frame",
246
	"R                      - Reset SNES",
247
	"q                      - Quit emulation",
248
//	"ai                     - Shou APU vectors",
249
//	"a                      - Show APU status",
250
//	"x                      - Show Sound DSP status",
251
//	"A                      - Toggle APU instruction tracing to aputrace.log",
252
//	"B                      - Toggle sound DSP register tracing to aputrace.log",
253
//	"C                      - Dump sound sample addresses",
254
//	"ad [Address]           - Dump APU RAM from PC or [Address]",
255
	"",
256
	"[Address]              - $Bank:Address or $Address",
257
	"                         [for example: $01:8123]",
258
	"[Number]               - #Number",
259
	"                         [for example: #1]",
260
	"z                      - ",
261
	"f                      - ",
262
	"dump                   - ",
263
	"",
264
	NULL
265
};
266
267
static const char	*S9xMnemonics[256] =
268
{
269
	"BRK", "ORA", "COP", "ORA", "TSB", "ORA", "ASL", "ORA",
270
	"PHP", "ORA", "ASL", "PHD", "TSB", "ORA", "ASL", "ORA",
271
	"BPL", "ORA", "ORA", "ORA", "TRB", "ORA", "ASL", "ORA",
272
	"CLC", "ORA", "INC", "TCS", "TRB", "ORA", "ASL", "ORA",
273
	"JSR", "AND", "JSL", "AND", "BIT", "AND", "ROL", "AND",
274
	"PLP", "AND", "ROL", "PLD", "BIT", "AND", "ROL", "AND",
275
	"BMI", "AND", "AND", "AND", "BIT", "AND", "ROL", "AND",
276
	"SEC", "AND", "DEC", "TSC", "BIT", "AND", "ROL", "AND",
277
	"RTI", "EOR", "WDM", "EOR", "MVP", "EOR", "LSR", "EOR",
278
	"PHA", "EOR", "LSR", "PHK", "JMP", "EOR", "LSR", "EOR",
279
	"BVC", "EOR", "EOR", "EOR", "MVN", "EOR", "LSR", "EOR",
280
	"CLI", "EOR", "PHY", "TCD", "JMP", "EOR", "LSR", "EOR",
281
	"RTS", "ADC", "PER", "ADC", "STZ", "ADC", "ROR", "ADC",
282
	"PLA", "ADC", "ROR", "RTL", "JMP", "ADC", "ROR", "ADC",
283
	"BVS", "ADC", "ADC", "ADC", "STZ", "ADC", "ROR", "ADC",
284
	"SEI", "ADC", "PLY", "TDC", "JMP", "ADC", "ROR", "ADC",
285
	"BRA", "STA", "BRL", "STA", "STY", "STA", "STX", "STA",
286
	"DEY", "BIT", "TXA", "PHB", "STY", "STA", "STX", "STA",
287
	"BCC", "STA", "STA", "STA", "STY", "STA", "STX", "STA",
288
	"TYA", "STA", "TXS", "TXY", "STZ", "STA", "STZ", "STA",
289
	"LDY", "LDA", "LDX", "LDA", "LDY", "LDA", "LDX", "LDA",
290
	"TAY", "LDA", "TAX", "PLB", "LDY", "LDA", "LDX", "LDA",
291
	"BCS", "LDA", "LDA", "LDA", "LDY", "LDA", "LDX", "LDA",
292
	"CLV", "LDA", "TSX", "TYX", "LDY", "LDA", "LDX", "LDA",
293
	"CPY", "CMP", "REP", "CMP", "CPY", "CMP", "DEC", "CMP",
294
	"INY", "CMP", "DEX", "WAI", "CPY", "CMP", "DEC", "CMP",
295
	"BNE", "CMP", "CMP", "CMP", "PEI", "CMP", "DEC", "CMP",
296
	"CLD", "CMP", "PHX", "STP", "JML", "CMP", "DEC", "CMP",
297
	"CPX", "SBC", "SEP", "SBC", "CPX", "SBC", "INC", "SBC",
298
	"INX", "SBC", "NOP", "XBA", "CPX", "SBC", "INC", "SBC",
299
	"BEQ", "SBC", "SBC", "SBC", "PEA", "SBC", "INC", "SBC",
300
	"SED", "SBC", "PLX", "XCE", "JSR", "SBC", "INC", "SBC"
301
};
302
303
static int	AddrModes[256] =
304
{
305
  // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
306
	 3, 10,  3, 19,  6,  6,  6, 12,  0,  1, 24,  0, 14, 14, 14, 17, // 0
307
	 4, 11,  9, 20,  6,  7,  7, 13,  0, 16, 24,  0, 14, 15, 15, 18, // 1
308
	14, 10, 17, 19,  6,  6,  6, 12,  0,  1, 24,  0, 14, 14, 14, 17, // 2
309
	 4, 11,  9, 20,  7,  7,  7, 13,  0, 16, 24,  0, 15, 15, 15, 18, // 3
310
	 0, 10,  3, 19, 25,  6,  6, 12,  0,  1, 24,  0, 14, 14, 14, 17, // 4
311
	 4, 11,  9, 20, 25,  7,  7, 13,  0, 16,  0,  0, 17, 15, 15, 18, // 5
312
	 0, 10,  5, 19,  6,  6,  6, 12,  0,  1, 24,  0, 21, 14, 14, 17, // 6
313
	 4, 11,  9, 20,  7,  7,  7, 13,  0, 16,  0,  0, 23, 15, 15, 18, // 7
314
	 4, 10,  5, 19,  6,  6,  6, 12,  0,  1,  0,  0, 14, 14, 14, 17, // 8
315
	 4, 11,  9, 20,  7,  7,  8, 13,  0, 16,  0,  0, 14, 15, 15, 18, // 9
316
	 2, 10,  2, 19,  6,  6,  6, 12,  0,  1,  0,  0, 14, 14, 14, 17, // A
317
	 4, 11,  9, 20,  7,  7,  8, 13,  0, 16,  0,  0, 15, 15, 16, 18, // B
318
	 2, 10,  3, 19,  6,  6,  6, 12,  0,  1,  0,  0, 14, 14, 14, 17, // C
319
	 4, 11,  9,  9, 27,  7,  7, 13,  0, 16,  0,  0, 22, 15, 15, 18, // D
320
	 2, 10,  3, 19,  6,  6,  6, 12,  0,  1,  0,  0, 14, 14, 14, 17, // E
321
	 4, 11,  9, 20, 26,  7,  7, 13,  0, 16,  0,  0, 23, 15, 15, 18  // F
322
};
323
2 by OV2
Update to latest WIP
324
static uint8 S9xDebugGetByte (uint32);
325
static uint16 S9xDebugGetWord (uint32);
326
static uint8 S9xDebugSA1GetByte (uint32);
327
static uint16 S9xDebugSA1GetWord (uint32);
1 by OV2
Initial 1.52 import
328
static uint8 debug_cpu_op_print (char *, uint8, uint16);
329
static uint8 debug_sa1_op_print (char *, uint8, uint16);
330
static void debug_line_print (const char *);
331
static int debug_get_number (char *, uint16 *);
332
static short debug_get_start_address (char *, uint8 *, uint32 *);
333
static void debug_process_command (char *);
334
static void debug_print_window (uint8 *);
335
static const char * debug_clip_fn (int);
336
static void debug_whats_used (void);
337
static void debug_whats_missing (void);
338
339
2 by OV2
Update to latest WIP
340
static uint8 S9xDebugGetByte (uint32 Address)
341
{
342
	int		block = (Address & 0xffffff) >> MEMMAP_SHIFT;
343
	uint8	*GetAddress = Memory.Map[block];
344
	uint8	byte = 0;
345
346
	if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
347
	{
348
		byte = *(GetAddress + (Address & 0xffff));
349
		return (byte);
350
	}
351
352
	switch ((pint) GetAddress)
353
	{
354
		case CMemory::MAP_LOROM_SRAM:
355
		case CMemory::MAP_SA1RAM:
356
			byte = *(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask));
357
			return (byte);
358
359
		case CMemory::MAP_LOROM_SRAM_B:
360
			byte = *(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB));
361
			return (byte);
362
363
		case CMemory::MAP_HIROM_SRAM:
364
		case CMemory::MAP_RONLY_SRAM:
365
			byte = *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask));
366
			return (byte);
367
368
		case CMemory::MAP_BWRAM:
369
			byte = *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000));
370
			return (byte);
371
372
		default:
373
			return (byte);
374
	}
375
}
376
377
static uint16 S9xDebugGetWord (uint32 Address)
378
{
379
	uint16	word;
380
381
	word  = S9xDebugGetByte(Address);
382
	word |= S9xDebugGetByte(Address + 1) << 8;
383
384
	return (word);
385
}
386
387
static uint8 S9xDebugSA1GetByte (uint32 Address)
388
{
389
	int		block = (Address & 0xffffff) >> MEMMAP_SHIFT;
390
	uint8	*GetAddress = SA1.Map[block];
391
	uint8	byte = 0;
392
393
	if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
394
	{
395
		byte = *(GetAddress + (Address & 0xffff));
396
		return (byte);
397
	}
398
399
	switch ((pint) GetAddress)
400
	{
401
		case CMemory::MAP_LOROM_SRAM:
402
		case CMemory::MAP_SA1RAM:
403
			byte = *(Memory.SRAM + (Address & 0xffff));
404
			return (byte);
405
406
		case CMemory::MAP_BWRAM:
407
			byte = *(SA1.BWRAM + ((Address & 0x7fff) - 0x6000));
408
			return (byte);
409
410
		case CMemory::MAP_BWRAM_BITMAP:
411
			Address -= 0x600000;
412
			if (SA1.VirtualBitmapFormat == 2)
413
				byte = (Memory.SRAM[(Address >> 2) & 0xffff] >> ((Address & 3) << 1)) &  3;
414
			else
415
				byte = (Memory.SRAM[(Address >> 1) & 0xffff] >> ((Address & 1) << 2)) & 15;
416
			return (byte);
417
418
		case CMemory::MAP_BWRAM_BITMAP2:
419
			Address = (Address & 0xffff) - 0x6000;
420
			if (SA1.VirtualBitmapFormat == 2)
421
				byte = (SA1.BWRAM[(Address >> 2) & 0xffff] >> ((Address & 3) << 1)) &  3;
422
			else
423
				byte = (SA1.BWRAM[(Address >> 1) & 0xffff] >> ((Address & 1) << 2)) & 15;
424
			return (byte);
425
426
		default:
427
			return (byte);
428
	}
429
}
430
431
static uint16 S9xDebugSA1GetWord (uint32 Address)
432
{
433
	uint16	word;
434
435
	word  = S9xDebugSA1GetByte(Address);
436
	word |= S9xDebugSA1GetByte(Address + 1) << 8;
437
438
	return (word);
439
}
440
1 by OV2
Initial 1.52 import
441
static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
442
{
443
	uint8	S9xOpcode;
444
	uint8	Operant[3];
445
	uint16	Word;
446
	uint8	Byte;
447
	int16	SWord;
448
	int8	SByte;
449
	uint8	Size = 0;
450
2 by OV2
Update to latest WIP
451
	S9xOpcode = S9xDebugGetByte((Bank << 16) + Address);
1 by OV2
Initial 1.52 import
452
	sprintf(Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
453
2 by OV2
Update to latest WIP
454
	Operant[0] = S9xDebugGetByte((Bank << 16) + Address + 1);
455
	Operant[1] = S9xDebugGetByte((Bank << 16) + Address + 2);
456
	Operant[2] = S9xDebugGetByte((Bank << 16) + Address + 3);
1 by OV2
Initial 1.52 import
457
458
	switch (AddrModes[S9xOpcode])
459
	{
460
		case 0:
461
			// Implied
462
			sprintf(Line, "%s         %s",
463
					Line,
464
					S9xMnemonics[S9xOpcode]);
465
			Size = 1;
466
			break;
467
468
		case 1:
469
			// Immediate[MemoryFlag]
470
			if (!CheckFlag(MemoryFlag))
471
			{
472
				// Accumulator 16 - Bit
473
				sprintf(Line, "%s%02X %02X    %s #$%02X%02X",
474
						Line,
475
						Operant[0],
476
						Operant[1],
477
						S9xMnemonics[S9xOpcode],
478
						Operant[1],
479
						Operant[0]);
480
				Size = 3;
481
			}
482
			else
483
			{
484
				// Accumulator 8 - Bit
485
				sprintf(Line, "%s%02X       %s #$%02X",
486
						Line,
487
						Operant[0],
488
						S9xMnemonics[S9xOpcode],
489
						Operant[0]);
490
				Size = 2;
491
			}
492
493
			break;
494
495
		case 2:
496
			// Immediate[IndexFlag]
497
			if (!CheckFlag(IndexFlag))
498
			{
499
				// X / Y 16 - Bit
500
				sprintf(Line, "%s%02X %02X    %s #$%02X%02X",
501
				        Line,
502
				        Operant[0],
503
				        Operant[1],
504
				        S9xMnemonics[S9xOpcode],
505
				        Operant[1],
506
				        Operant[0]);
507
				Size = 3;
508
			}
509
			else
510
			{
511
				// X / Y 8 - Bit
512
				sprintf(Line, "%s%02X       %s #$%02X",
513
				        Line,
514
				        Operant[0],
515
				        S9xMnemonics[S9xOpcode],
516
				        Operant[0]);
517
				Size = 2;
518
			}
519
520
			break;
521
522
		case 3:
523
			// Immediate[Always 8 - Bit]
524
			sprintf(Line, "%s%02X       %s #$%02X",
525
					Line,
526
					Operant[0],
527
					S9xMnemonics[S9xOpcode],
528
					Operant[0]);
529
			Size = 2;
530
			break;
531
532
		case 4:
533
			// Relative
534
			sprintf(Line, "%s%02X       %s $%02X",
535
					Line,
536
					Operant[0],
537
					S9xMnemonics[S9xOpcode],
538
					Operant[0]);
539
			SByte = Operant[0];
540
			Word = Address;
541
			Word += SByte;
542
			Word += 2;
543
			sprintf(Line, "%-32s[$%04X]", Line, Word);
544
			Size = 2;
545
			break;
546
547
		case 5:
548
			// Relative Long
549
			sprintf(Line, "%s%02X %02X    %s $%02X%02X",
550
					Line,
551
					Operant[0],
552
					Operant[1],
553
					S9xMnemonics[S9xOpcode],
554
					Operant[1],
555
					Operant[0]);
556
			SWord = (Operant[1] << 8) | Operant[0];
557
			Word = Address;
558
			Word += SWord;
559
			Word += 3;
560
			sprintf(Line, "%-32s[$%04X]", Line, Word);
561
			Size = 3;
562
			break;
563
564
		case 6:
565
			// Direct
566
			sprintf(Line, "%s%02X       %s $%02X",
567
					Line,
568
					Operant[0],
569
					S9xMnemonics[S9xOpcode],
570
					Operant[0]);
571
			Word = Operant[0];
572
			Word += Registers.D.W;
573
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
574
			Size = 2;
575
			break;
576
577
		case 7:
578
			// Direct Indexed (with X)
579
			sprintf(Line, "%s%02X       %s $%02X,x",
580
					Line,
581
					Operant[0],
582
					S9xMnemonics[S9xOpcode],
583
					Operant[0]);
584
			Word = Operant[0];
585
			Word += Registers.D.W;
586
			Word += Registers.X.W;
587
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
588
			Size = 2;
589
			break;
590
591
		case 8:
592
			// Direct Indexed (with Y)
593
			sprintf(Line, "%s%02X       %s $%02X,y",
594
			        Line,
595
			        Operant[0],
596
			        S9xMnemonics[S9xOpcode],
597
			        Operant[0]);
598
			Word = Operant[0];
599
			Word += Registers.D.W;
600
			Word += Registers.Y.W;
601
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
602
			Size = 2;
603
			break;
604
605
		case 9:
606
			// Direct Indirect
607
			sprintf(Line, "%s%02X       %s ($%02X)",
608
			        Line,
609
			        Operant[0],
610
			        S9xMnemonics[S9xOpcode],
611
			        Operant[0]);
612
			Word = Operant[0];
613
			Word += Registers.D.W;
2 by OV2
Update to latest WIP
614
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
615
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
616
			Size = 2;
617
			break;
618
619
		case 10:
620
			// Direct Indexed Indirect
621
			sprintf(Line, "%s%02X       %s ($%02X,x)",
622
			        Line,
623
			        Operant[0],
624
			        S9xMnemonics[S9xOpcode],
625
			        Operant[0]);
626
			Word = Operant[0];
627
			Word += Registers.D.W;
628
			Word += Registers.X.W;
2 by OV2
Update to latest WIP
629
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
630
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
631
			Size = 2;
632
			break;
633
634
		case 11:
635
			// Direct Indirect Indexed
636
			sprintf(Line, "%s%02X       %s ($%02X),y",
637
			        Line,
638
			        Operant[0],
639
			        S9xMnemonics[S9xOpcode],
640
			        Operant[0]);
641
			Word = Operant[0];
642
			Word += Registers.D.W;
2 by OV2
Update to latest WIP
643
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
644
			Word += Registers.Y.W;
645
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
646
			Size = 2;
647
			break;
648
649
		case 12:
650
			// Direct Indirect Long
651
			sprintf(Line, "%s%02X       %s [$%02X]",
652
			        Line,
653
			        Operant[0],
654
			        S9xMnemonics[S9xOpcode],
655
			        Operant[0]);
656
			Word = Operant[0];
657
			Word += Registers.D.W;
2 by OV2
Update to latest WIP
658
			Byte = S9xDebugGetByte(Word + 2);
659
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
660
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
661
			Size = 2;
662
			break;
663
664
		case 13:
665
			// Direct Indirect Indexed Long
666
			sprintf(Line, "%s%02X       %s [$%02X],y",
667
			        Line,
668
			        Operant[0],
669
			        S9xMnemonics[S9xOpcode],
670
			        Operant[0]);
671
			Word = Operant[0];
672
			Word += Registers.D.W;
2 by OV2
Update to latest WIP
673
			Byte = S9xDebugGetByte(Word + 2);
674
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
675
			Word += Registers.Y.W;
676
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
677
			Size = 2;
678
			break;
679
680
		case 14:
681
			// Absolute
682
			sprintf(Line, "%s%02X %02X    %s $%02X%02X",
683
			        Line,
684
			        Operant[0],
685
			        Operant[1],
686
			        S9xMnemonics[S9xOpcode],
687
			        Operant[1],
688
			        Operant[0]);
689
			Word = (Operant[1] << 8) | Operant[0];
690
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
691
			Size = 3;
692
			break;
693
694
		case 15:
695
			// Absolute Indexed (with X)
696
			sprintf(Line, "%s%02X %02X    %s $%02X%02X,x",
697
			        Line,
698
			        Operant[0],
699
			        Operant[1],
700
			        S9xMnemonics[S9xOpcode],
701
			        Operant[1],
702
			        Operant[0]);
703
			Word = (Operant[1] << 8) | Operant[0];
704
			Word += Registers.X.W;
705
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
706
			Size = 3;
707
			break;
708
709
		case 16:
710
			// Absolute Indexed (with Y)
711
			sprintf(Line, "%s%02X %02X    %s $%02X%02X,y",
712
			        Line,
713
			        Operant[0],
714
			        Operant[1],
715
			        S9xMnemonics[S9xOpcode],
716
			        Operant[1],
717
			        Operant[0]);
718
			Word = (Operant[1] << 8) | Operant[0];
719
			Word += Registers.Y.W;
720
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
721
			Size = 3;
722
			break;
723
724
		case 17:
725
			// Absolute Long
726
			sprintf(Line, "%s%02X %02X %02X %s $%02X%02X%02X",
727
			        Line,
728
			        Operant[0],
729
			        Operant[1],
730
			        Operant[2],
731
			        S9xMnemonics[S9xOpcode],
732
			        Operant[2],
733
			        Operant[1],
734
			        Operant[0]);
735
			Word = (Operant[1] << 8) | Operant[0];
736
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
737
			Size = 4;
738
			break;
739
740
		case 18:
741
			// Absolute Indexed Long
742
			sprintf(Line, "%s%02X %02X %02X %s $%02X%02X%02X,x",
743
			        Line,
744
			        Operant[0],
745
			        Operant[1],
746
			        Operant[2],
747
			        S9xMnemonics[S9xOpcode],
748
			        Operant[2],
749
			        Operant[1],
750
			        Operant[0]);
751
			Word = (Operant[1] << 8) | Operant[0];
752
			Word += Registers.X.W;
753
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
754
			Size = 4;
755
			break;
756
757
		case 19:
758
			// Stack Relative
759
			sprintf(Line, "%s%02X       %s $%02X,s",
760
			        Line,
761
			        Operant[0],
762
			        S9xMnemonics[S9xOpcode],
763
			        Operant[0]);
764
			Word = Registers.S.W;
765
			Word += Operant[0];
766
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
767
			Size = 2;
768
			break;
769
770
		case 20:
771
			// Stack Relative Indirect Indexed
772
			sprintf(Line, "%s%02X       %s ($%02X,s),y",
773
			        Line,
774
			        Operant[0],
775
			        S9xMnemonics[S9xOpcode],
776
			        Operant[0]);
777
			Word = Registers.S.W;
778
			Word += Operant[0];
2 by OV2
Update to latest WIP
779
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
780
			Word += Registers.Y.W;
781
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
782
			Size = 2;
783
			break;
784
785
		case 21:
786
			// Absolute Indirect
787
			sprintf(Line, "%s%02X %02X    %s ($%02X%02X)",
788
			        Line,
789
			        Operant[0],
790
			        Operant[1],
791
			        S9xMnemonics[S9xOpcode],
792
			        Operant[1],
793
			        Operant[0]);
794
			Word = (Operant[1] << 8) | Operant[0];
2 by OV2
Update to latest WIP
795
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
796
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
797
			Size = 3;
798
			break;
799
800
		case 22:
801
			// Absolute Indirect Long
802
			sprintf(Line, "%s%02X %02X    %s [$%02X%02X]",
803
			        Line,
804
			        Operant[0],
805
			        Operant[1],
806
			        S9xMnemonics[S9xOpcode],
807
			        Operant[1],
808
			        Operant[0]);
809
			Word = (Operant[1] << 8) | Operant[0];
2 by OV2
Update to latest WIP
810
			Byte = S9xDebugGetByte(Word + 2);
811
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
812
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
813
			Size = 3;
814
			break;
815
816
		case 23:
817
			// Absolute Indexed Indirect
818
			sprintf(Line, "%s%02X %02X    %s ($%02X%02X,x)",
819
			        Line,
820
			        Operant[0],
821
			        Operant[1],
822
			        S9xMnemonics[S9xOpcode],
823
			        Operant[1],
824
			        Operant[0]);
825
			Word = (Operant[1] << 8) | Operant[0];
826
			Word += Registers.X.W;
2 by OV2
Update to latest WIP
827
			Word = S9xDebugGetWord(ICPU.ShiftedPB + Word);
1 by OV2
Initial 1.52 import
828
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
829
			Size = 3;
830
			break;
831
832
		case 24:
833
			// Implied Accumulator
834
			sprintf(Line, "%s         %s A",
835
			        Line,
836
			        S9xMnemonics[S9xOpcode]);
837
			Size = 1;
838
			break;
839
840
		case 25:
841
			// MVN/MVP SRC DST
842
			sprintf(Line, "%s%02X %02X    %s %02X %02X",
843
			        Line,
844
			        Operant[0],
845
			        Operant[1],
846
			        S9xMnemonics[S9xOpcode],
847
			        Operant[1],
848
			        Operant[0]);
849
			Size = 3;
850
			break;
851
852
		case 26:
853
			// PEA
854
			sprintf(Line, "%s%02X %02X    %s $%02X%02X",
855
			        Line,
856
			        Operant[0],
857
			        Operant[1],
858
			        S9xMnemonics[S9xOpcode],
859
			        Operant[1],
860
			        Operant[0]);
861
			Size = 3;
862
			break;
863
864
		case 27:
865
			// PEI Direct Indirect
866
			sprintf(Line, "%s%02X       %s ($%02X)",
867
			        Line,
868
			        Operant[0],
869
			        S9xMnemonics[S9xOpcode],
870
			        Operant[0]);
871
			Word = Operant[0];
872
			Word += Registers.D.W;
2 by OV2
Update to latest WIP
873
			Word = S9xDebugGetWord(Word);
1 by OV2
Initial 1.52 import
874
			sprintf(Line, "%-32s[$%04X]", Line, Word);
875
			Size = 2;
876
			break;
877
	}
878
26.1.9 by zones
Fix HIRQ
879
	sprintf(Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%04ld VC:%03ld FC:%02d %03x",
1 by OV2
Initial 1.52 import
880
	        Line, Registers.A.W, Registers.X.W, Registers.Y.W,
881
	        Registers.D.W, Registers.DB, Registers.S.W,
882
	        CheckEmulation() ? 'E' : 'e',
883
	        CheckNegative() ? 'N' : 'n',
884
	        CheckOverflow() ? 'V' : 'v',
885
	        CheckMemory() ? 'M' : 'm',
886
	        CheckIndex() ? 'X' : 'x',
887
	        CheckDecimal() ? 'D' : 'd',
888
	        CheckIRQ() ? 'I' : 'i',
889
	        CheckZero() ? 'Z' : 'z',
890
	        CheckCarry() ? 'C' : 'c',
2 by OV2
Update to latest WIP
891
	        (long) CPU.Cycles,
1 by OV2
Initial 1.52 import
892
	        (long) CPU.V_Counter,
893
	        IPPU.FrameCount,
26.1.9 by zones
Fix HIRQ
894
	        (CPU.IRQExternal ? 0x100 : 0) | (PPU.HTimerEnabled ? 0x10 : 0) | (PPU.VTimerEnabled ? 0x01 : 0));
1 by OV2
Initial 1.52 import
895
896
	return (Size);
897
}
898
899
static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
900
{
901
	uint8	S9xOpcode;
902
	uint8	Operant[3];
903
	uint16	Word;
904
	uint8	Byte;
905
	int16	SWord;
906
	int8	SByte;
907
	uint8	Size = 0;
908
2 by OV2
Update to latest WIP
909
	S9xOpcode = S9xDebugSA1GetByte((Bank << 16) + Address);
1 by OV2
Initial 1.52 import
910
	sprintf(Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
911
2 by OV2
Update to latest WIP
912
	Operant[0] = S9xDebugSA1GetByte((Bank << 16) + Address + 1);
913
	Operant[1] = S9xDebugSA1GetByte((Bank << 16) + Address + 2);
914
	Operant[2] = S9xDebugSA1GetByte((Bank << 16) + Address + 3);
1 by OV2
Initial 1.52 import
915
916
	switch (AddrModes[S9xOpcode])
917
	{
918
		case 0:
919
			// Implied
920
			sprintf(Line, "%s         %s",
921
			        Line,
922
			        S9xMnemonics[S9xOpcode]);
923
			Size = 1;
924
			break;
925
926
		case 1:
927
			// Immediate[MemoryFlag]
928
			if (!SA1CheckFlag(MemoryFlag))
929
			{
930
				// Accumulator 16 - Bit
931
				sprintf(Line, "%s%02X %02X    %s #$%02X%02X",
932
				        Line,
933
				        Operant[0],
934
				        Operant[1],
935
				        S9xMnemonics[S9xOpcode],
936
				        Operant[1],
937
				        Operant[0]);
938
				Size = 3;
939
			}
940
			else
941
			{
942
				// Accumulator 8 - Bit
943
				sprintf(Line, "%s%02X       %s #$%02X",
944
				        Line,
945
				        Operant[0],
946
				        S9xMnemonics[S9xOpcode],
947
				        Operant[0]);
948
				Size = 2;
949
			}
950
951
			break;
952
953
		case 2:
954
			// Immediate[IndexFlag]
955
			if (!SA1CheckFlag(IndexFlag))
956
			{
957
				// X / Y 16 - Bit
958
				sprintf(Line, "%s%02X %02X    %s #$%02X%02X",
959
				        Line,
960
				        Operant[0],
961
				        Operant[1],
962
				        S9xMnemonics[S9xOpcode],
963
				        Operant[1],
964
				        Operant[0]);
965
				Size = 3;
966
			}
967
			else
968
			{
969
				// X / Y 8 - Bit
970
				sprintf(Line, "%s%02X       %s #$%02X",
971
				        Line,
972
				        Operant[0],
973
				        S9xMnemonics[S9xOpcode],
974
				        Operant[0]);
975
				Size = 2;
976
			}
977
978
			break;
979
980
		case 3:
981
			// Immediate[Always 8 - Bit]
982
			sprintf(Line, "%s%02X       %s #$%02X",
983
			        Line,
984
			        Operant[0],
985
			        S9xMnemonics[S9xOpcode],
986
			        Operant[0]);
987
			Size = 2;
988
			break;
989
990
		case 4:
991
			// Relative
992
			sprintf(Line, "%s%02X       %s $%02X",
993
			        Line,
994
			        Operant[0],
995
			        S9xMnemonics[S9xOpcode],
996
			        Operant[0]);
997
			SByte = Operant[0];
998
			Word = Address;
999
			Word += SByte;
1000
			Word += 2;
1001
			sprintf(Line, "%-32s[$%04X]", Line, Word);
1002
			Size = 2;
1003
			break;
1004
1005
		case 5:
1006
			// Relative Long
1007
			sprintf(Line, "%s%02X %02X    %s $%02X%02X",
1008
			        Line,
1009
			        Operant[0],
1010
			        Operant[1],
1011
			        S9xMnemonics[S9xOpcode],
1012
			        Operant[1],
1013
			        Operant[0]);
1014
			SWord = (Operant[1] << 8) | Operant[0];
1015
			Word = Address;
1016
			Word += SWord;
1017
			Word += 3;
1018
			sprintf(Line, "%-32s[$%04X]", Line, Word);
1019
			Size = 3;
1020
			break;
1021
1022
		case 6:
1023
			// Direct
1024
			sprintf(Line, "%s%02X       %s $%02X",
1025
			        Line,
1026
			        Operant[0],
1027
			        S9xMnemonics[S9xOpcode],
1028
			        Operant[0]);
1029
			Word = Operant[0];
1030
			Word += SA1Registers.D.W;
1031
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
1032
			Size = 2;
1033
			break;
1034
1035
		case 7:
1036
			// Direct Indexed (with X)
1037
			sprintf(Line, "%s%02X       %s $%02X,x",
1038
			        Line,
1039
			        Operant[0],
1040
			        S9xMnemonics[S9xOpcode],
1041
			        Operant[0]);
1042
			Word = Operant[0];
1043
			Word += SA1Registers.D.W;
1044
			Word += SA1Registers.X.W;
1045
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
1046
			Size = 2;
1047
			break;
1048
1049
		case 8:
1050
			// Direct Indexed (with Y)
1051
			sprintf(Line, "%s%02X       %s $%02X,y",
1052
			        Line,
1053
			        Operant[0],
1054
			        S9xMnemonics[S9xOpcode],
1055
			        Operant[0]);
1056
			Word = Operant[0];
1057
			Word += SA1Registers.D.W;
1058
			Word += SA1Registers.Y.W;
1059
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
1060
			Size = 2;
1061
			break;
1062
1063
		case 9:
1064
			// Direct Indirect
1065
			sprintf(Line, "%s%02X       %s ($%02X)",
1066
			        Line,
1067
			        Operant[0],
1068
			        S9xMnemonics[S9xOpcode],
1069
			        Operant[0]);
1070
			Word = Operant[0];
1071
			Word += SA1Registers.D.W;
2 by OV2
Update to latest WIP
1072
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1073
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1074
			Size = 2;
1075
			break;
1076
1077
		case 10:
1078
			// Direct Indexed Indirect
1079
			sprintf(Line, "%s%02X       %s ($%02X,x)",
1080
			        Line,
1081
			        Operant[0],
1082
			        S9xMnemonics[S9xOpcode],
1083
			        Operant[0]);
1084
			Word = Operant[0];
1085
			Word += SA1Registers.D.W;
1086
			Word += SA1Registers.X.W;
2 by OV2
Update to latest WIP
1087
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1088
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1089
			Size = 2;
1090
			break;
1091
1092
		case 11:
1093
			// Direct Indirect Indexed
1094
			sprintf(Line, "%s%02X       %s ($%02X),y",
1095
			        Line,
1096
			        Operant[0],
1097
			        S9xMnemonics[S9xOpcode],
1098
			        Operant[0]);
1099
			Word = Operant[0];
1100
			Word += SA1Registers.D.W;
2 by OV2
Update to latest WIP
1101
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1102
			Word += SA1Registers.Y.W;
1103
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1104
			Size = 2;
1105
			break;
1106
1107
		case 12:
1108
			// Direct Indirect Long
1109
			sprintf(Line, "%s%02X       %s [$%02X]",
1110
			        Line,
1111
			        Operant[0],
1112
			        S9xMnemonics[S9xOpcode],
1113
			        Operant[0]);
1114
			Word = Operant[0];
1115
			Word += SA1Registers.D.W;
2 by OV2
Update to latest WIP
1116
			Byte = S9xDebugSA1GetByte(Word + 2);
1117
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1118
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
1119
			Size = 2;
1120
			break;
1121
1122
		case 13:
1123
			// Direct Indirect Indexed Long
1124
			sprintf(Line, "%s%02X       %s [$%02X],y",
1125
			        Line,
1126
			        Operant[0],
1127
			        S9xMnemonics[S9xOpcode],
1128
			        Operant[0]);
1129
			Word = Operant[0];
1130
			Word += SA1Registers.D.W;
2 by OV2
Update to latest WIP
1131
			Byte = S9xDebugSA1GetByte(Word + 2);
1132
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1133
			Word += SA1Registers.Y.W;
1134
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
1135
			Size = 2;
1136
			break;
1137
1138
		case 14:
1139
			// Absolute
1140
			sprintf(Line, "%s%02X %02X    %s $%02X%02X",
1141
			        Line,
1142
			        Operant[0],
1143
			        Operant[1],
1144
			        S9xMnemonics[S9xOpcode],
1145
			        Operant[1],
1146
			        Operant[0]);
1147
			Word = (Operant[1] << 8) | Operant[0];
1148
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1149
			Size = 3;
1150
			break;
1151
1152
		case 15:
1153
			// Absolute Indexed (with X)
1154
			sprintf(Line, "%s%02X %02X    %s $%02X%02X,x",
1155
			        Line,
1156
			        Operant[0],
1157
			        Operant[1],
1158
			        S9xMnemonics[S9xOpcode],
1159
			        Operant[1],
1160
			        Operant[0]);
1161
			Word = (Operant[1] << 8) | Operant[0];
1162
			Word += SA1Registers.X.W;
1163
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1164
			Size = 3;
1165
			break;
1166
1167
		case 16:
1168
			// Absolute Indexed (with Y)
1169
			sprintf(Line, "%s%02X %02X    %s $%02X%02X,y",
1170
			        Line,
1171
			        Operant[0],
1172
			        Operant[1],
1173
			        S9xMnemonics[S9xOpcode],
1174
			        Operant[1],
1175
			        Operant[0]);
1176
			Word = (Operant[1] << 8) | Operant[0];
1177
			Word += SA1Registers.Y.W;
1178
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1179
			Size = 3;
1180
			break;
1181
1182
		case 17:
1183
			// Absolute Long
1184
			sprintf(Line, "%s%02X %02X %02X %s $%02X%02X%02X",
1185
			        Line,
1186
			        Operant[0],
1187
			        Operant[1],
1188
			        Operant[2],
1189
			        S9xMnemonics[S9xOpcode],
1190
			        Operant[2],
1191
			        Operant[1],
1192
			        Operant[0]);
1193
			Word = (Operant[1] << 8) | Operant[0];
1194
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
1195
			Size = 4;
1196
			break;
1197
1198
		case 18:
1199
			// Absolute Indexed Long
1200
			sprintf(Line, "%s%02X %02X %02X %s $%02X%02X%02X,x",
1201
			        Line,
1202
			        Operant[0],
1203
			        Operant[1],
1204
			        Operant[2],
1205
			        S9xMnemonics[S9xOpcode],
1206
			        Operant[2],
1207
			        Operant[1],
1208
			        Operant[0]);
1209
			Word = (Operant[1] << 8) | Operant[0];
1210
			Word += SA1Registers.X.W;
1211
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Operant[2], Word);
1212
			Size = 4;
1213
			break;
1214
1215
		case 19:
1216
			// Stack Relative
1217
			sprintf(Line, "%s%02X       %s $%02X,s",
1218
			        Line,
1219
			        Operant[0],
1220
			        S9xMnemonics[S9xOpcode],
1221
			        Operant[0]);
1222
			Word = SA1Registers.S.W;
1223
			Word += Operant[0];
1224
			sprintf(Line, "%-32s[$00:%04X]", Line, Word);
1225
			Size = 2;
1226
			break;
1227
1228
		case 20:
1229
			// Stack Relative Indirect Indexed
1230
			sprintf(Line, "%s%02X       %s ($%02X,s),y",
1231
			        Line,
1232
			        Operant[0],
1233
			        S9xMnemonics[S9xOpcode],
1234
			        Operant[0]);
1235
			Word = SA1Registers.S.W;
1236
			Word += Operant[0];
2 by OV2
Update to latest WIP
1237
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1238
			Word += SA1Registers.Y.W;
1239
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
1240
			Size = 2;
1241
			break;
1242
1243
		case 21:
1244
			// Absolute Indirect
1245
			sprintf(Line, "%s%02X %02X    %s ($%02X%02X)",
1246
			        Line,
1247
			        Operant[0],
1248
			        Operant[1],
1249
			        S9xMnemonics[S9xOpcode],
1250
			        Operant[1],
1251
			        Operant[0]);
1252
			Word = (Operant[1] << 8) | Operant[0];
2 by OV2
Update to latest WIP
1253
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1254
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
1255
			Size = 3;
1256
			break;
1257
1258
		case 22:
1259
			// Absolute Indirect Long
1260
			sprintf(Line, "%s%02X %02X    %s [$%02X%02X]",
1261
			        Line,
1262
			        Operant[0],
1263
			        Operant[1],
1264
			        S9xMnemonics[S9xOpcode],
1265
			        Operant[1],
1266
			        Operant[0]);
1267
			Word = (Operant[1] << 8) | Operant[0];
2 by OV2
Update to latest WIP
1268
			Byte = S9xDebugSA1GetByte(Word + 2);
1269
			Word = S9xDebugSA1GetWord(Word);
1 by OV2
Initial 1.52 import
1270
			sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
1271
			Size = 3;
1272
			break;
1273
1274
		case 23:
1275
			// Absolute Indexed Indirect
1276
			sprintf(Line, "%s%02X %02X    %s ($%02X%02X,x)",
1277
			        Line,
1278
			        Operant[0],
1279
			        Operant[1],
1280
			        S9xMnemonics[S9xOpcode],
1281
			        Operant[1],
1282
			        Operant[0]);
1283
			Word = (Operant[1] << 8) | Operant[0];
1284
			Word += SA1Registers.X.W;
2 by OV2
Update to latest WIP
1285
			Word = S9xDebugSA1GetWord(SA1.ShiftedPB + Word);
1 by OV2
Initial 1.52 import
1286
			sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
1287
			Size = 3;
1288
			break;
1289
1290
		case 24:
1291
			// Implied Accumulator
1292
			sprintf(Line, "%s         %s A",
1293
			        Line,
1294
			        S9xMnemonics[S9xOpcode]);
1295
			Size = 1;
1296
			break;
1297
1298
		case 25:
1299
			// MVN/MVP SRC DST
1300
			sprintf(Line, "%s         %s %02X %02X",
1301
			        Line,
1302
			        S9xMnemonics[S9xOpcode],
1303
			        Operant[0],
1304
			        Operant[1]);
1305
			Size = 3;
1306
			break;
1307
	}
1308
1309
	sprintf(Line, "%-44s A:%04X X:%04X Y:%04X D:%04X DB:%02X S:%04X P:%c%c%c%c%c%c%c%c%c HC:%04ld VC:%03ld FC:%02d",
1310
	        Line, SA1Registers.A.W, SA1Registers.X.W, SA1Registers.Y.W,
1311
	        SA1Registers.D.W, SA1Registers.DB, SA1Registers.S.W,
1312
	        SA1CheckEmulation() ? 'E' : 'e',
1313
	        SA1CheckNegative() ? 'N' : 'n',
1314
	        SA1CheckOverflow() ? 'V' : 'v',
1315
	        SA1CheckMemory() ? 'M' : 'm',
1316
	        SA1CheckIndex() ? 'X' : 'x',
1317
	        SA1CheckDecimal() ? 'D' : 'd',
1318
	        SA1CheckIRQ() ? 'I' : 'i',
1319
	        SA1CheckZero() ? 'Z' : 'z',
1320
	        SA1CheckCarry() ? 'C' : 'c',
1321
	        (long) CPU.Cycles,
1322
	        (long) CPU.V_Counter,
1323
	        IPPU.FrameCount);
1324
1325
	return (Size);
1326
}
1327
1328
static void debug_line_print (const char *Line)
1329
{
1330
	printf("%s\n", Line);
1331
}
1332
1333
static int debug_get_number (char *Line, uint16 *Number)
1334
{
1335
	int	i;
1336
1337
	if (sscanf(Line, " #%d", &i) == 1)
1338
	{
1339
		*Number = i;
1340
		return (1);
1341
	}
1342
1343
	return (-1);
1344
}
1345
1346
static short debug_get_start_address (char *Line, uint8 *Bank, uint32 *Address)
1347
{
1348
	uint32	a, b;
1349
1350
	if (sscanf(Line + 1, " $%x:%x", &b, &a) != 2)
1351
		return (-1);
1352
1353
	*Bank = b;
1354
	*Address = a;
1355
1356
	return (1);
1357
}
1358
1359
static void debug_process_command (char *Line)
1360
{
1361
	uint8	Bank = Registers.PB;
1362
	uint32	Address = Registers.PCw;
1363
	uint16	Hold = 0;
1364
	uint16	Number;
1365
	short	ErrorCode;
1366
	char	string[512];
1367
1368
	if (strncasecmp(Line, "dump", 4) == 0)
1369
	{
1370
		int	Count;
1371
1372
		if (sscanf(&Line[4], "%x %d", &Address, &Count) == 2)
1373
		{
1374
			FILE	*fs;
1375
1376
			sprintf(string, "%06x%05d.sd2", Address, Count);
1377
			fs = fopen(string, "wb");
1378
			if (fs)
1379
			{
1380
				for (int i = 0; i < Count; i++)
2 by OV2
Update to latest WIP
1381
					putc(S9xDebugGetByte(Address + i), fs);
1 by OV2
Initial 1.52 import
1382
				fclose(fs);
1383
			}
1384
			else
1385
				printf("Can't open %s for writing\n", string);
1386
		}
1387
		else
1388
			printf("Usage: dump start_address_in_hex count_in_decimal\n");
1389
1390
		return;
1391
	}
1392
1393
	if (*Line == 'i')
1394
	{
1395
		printf("Vectors:\n");
1396
		sprintf(string, "      8 Bit   16 Bit ");
1397
		debug_line_print(string);
2 by OV2
Update to latest WIP
1398
		sprintf(string, "ABT $00:%04X|$00:%04X", S9xDebugGetWord(0xFFF8), S9xDebugGetWord(0xFFE8));
1399
		debug_line_print(string);
1400
		sprintf(string, "BRK $00:%04X|$00:%04X", S9xDebugGetWord(0xFFFE), S9xDebugGetWord(0xFFE6));
1401
		debug_line_print(string);
1402
		sprintf(string, "COP $00:%04X|$00:%04X", S9xDebugGetWord(0xFFF4), S9xDebugGetWord(0xFFE4));
1403
		debug_line_print(string);
1404
		sprintf(string, "IRQ $00:%04X|$00:%04X", S9xDebugGetWord(0xFFFE), S9xDebugGetWord(0xFFEE));
1405
		debug_line_print(string);
1406
		sprintf(string, "NMI $00:%04X|$00:%04X", S9xDebugGetWord(0xFFFA), S9xDebugGetWord(0xFFEA));
1407
		debug_line_print(string);
1408
		sprintf(string, "RES     $00:%04X", S9xDebugGetWord(0xFFFC));
1 by OV2
Initial 1.52 import
1409
		debug_line_print(string);
1410
	}
1411
1412
/*
1413
	if (strncmp(Line, "ai", 2) == 0)
1414
	{
1415
		printf("APU vectors:");
1416
1417
		for (int i = 0; i < 0x40; i += 2)
1418
		{
1419
			if (i % 16 == 0)
1420
				printf("\n%04x ", 0xffc0 + i);
1421
1422
			printf("%04x ", APU.ExtraRAM[i]);
1423
		}
1424
1425
		printf("\n");
1426
	}
1427
*/
1428
1429
	if (*Line == 's')
1430
	{
1431
		Registers.PCw += debug_cpu_op_print(string, Bank, Address);
1432
		Bank = Registers.PB;
1433
		Address = Registers.PCw;
1434
		*Line = 'r';
1435
	}
1436
1437
	if (*Line == 'z')
1438
	{
1439
		uint16	*p = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1];
1440
1441
		for (int l = 0; l < 32; l++)
1442
		{
1443
			for (int c = 0; c < 32; c++, p++)
1444
				printf("%04x,", *p++);
1445
1446
			printf("\n");
1447
		}
1448
	}
1449
1450
	if (*Line == 'c')
1451
	{
1452
		printf("Colours:\n");
1453
1454
		for (int i = 0; i < 256; i++)
1455
			printf("%02x%02x%02x  ", PPU.CGDATA[i] & 0x1f, (PPU.CGDATA[i] >> 5) & 0x1f, (PPU.CGDATA[i] >> 10) & 0x1f);
1456
1457
		printf("\n");
1458
	}
1459
1460
	if (*Line == 'S')
1461
	{
1462
		int	SmallWidth, LargeWidth, SmallHeight, LargeHeight;
1463
1464
		switch ((Memory.FillRAM[0x2101] >> 5) & 7)
1465
		{
1466
1467
			case 0:
1468
				SmallWidth = SmallHeight = 8;
1469
				LargeWidth = LargeHeight = 16;
1470
				break;
1471
1472
			case 1:
1473
				SmallWidth = SmallHeight = 8;
1474
				LargeWidth = LargeHeight = 32;
1475
				break;
1476
1477
			case 2:
1478
				SmallWidth = SmallHeight = 8;
1479
				LargeWidth = LargeHeight = 64;
1480
				break;
1481
1482
			case 3:
1483
				SmallWidth = SmallHeight = 16;
1484
				LargeWidth = LargeHeight = 32;
1485
				break;
1486
1487
			case 4:
1488
				SmallWidth = SmallHeight = 16;
1489
				LargeWidth = LargeHeight = 64;
1490
				break;
1491
1492
			default:
1493
			case 5:
1494
				SmallWidth = SmallHeight = 32;
1495
				LargeWidth = LargeHeight = 64;
1496
				break;
1497
1498
			case 6:
1499
				SmallWidth = 16;
1500
				SmallHeight = 32;
1501
				LargeWidth = 32;
1502
				LargeHeight = 64;
1503
				break;
1504
1505
			case 7:
1506
				SmallWidth = 16;
1507
				SmallHeight = 32;
1508
				LargeWidth = LargeHeight = 32;
1509
				break;
1510
		}
1511
1512
		printf("Sprites: Small: %dx%d, Large: %dx%d, OAMAddr: 0x%04x, OBJNameBase: 0x%04x, OBJNameSelect: 0x%04x, First: %d\n",
1513
		       SmallWidth, SmallHeight, LargeWidth, LargeHeight, PPU.OAMAddr, PPU.OBJNameBase, PPU.OBJNameSelect, PPU.FirstSprite);
1514
1515
		for (int i = 0; i < 128; i++)
1516
		{
1517
			printf("X:%3d Y:%3d %c%c%d%c ",
1518
			       PPU.OBJ[i].HPos,
1519
			       PPU.OBJ[i].VPos,
1520
			       PPU.OBJ[i].VFlip ? 'V' : 'v',
1521
			       PPU.OBJ[i].HFlip ? 'H' : 'h',
1522
			       PPU.OBJ[i].Priority,
1523
			       PPU.OBJ[i].Size ? 'S' : 's');
1524
1525
			if (i % 4 == 3)
1526
				printf("\n");
1527
		}
1528
	}
1529
1530
	if (*Line == 'T')
1531
	{
1532
		if (Line[1] == 'S')
1533
		{
1534
			SA1.Flags ^= TRACE_FLAG;
1535
1536
			if (SA1.Flags & TRACE_FLAG)
1537
			{
1538
				printf("SA1 CPU instruction tracing enabled.\n");
58 by zones
Change debugger's log folder to LOG_DIR. / Mac: Add frame advance, change the timing of .srm save.
1539
				ENSURE_TRACE_OPEN(trace2, "trace_sa1.log", "wb")
1 by OV2
Initial 1.52 import
1540
			}
1541
			else
1542
			{
1543
				printf("SA1 CPU instruction tracing disabled.\n");
1544
				fclose(trace2);
1545
				trace2 = NULL;
1546
			}
1547
		}
1548
		else
1549
		{
1550
			CPU.Flags ^= TRACE_FLAG;
1551
1552
			if (CPU.Flags & TRACE_FLAG)
1553
			{
1554
				printf("CPU instruction tracing enabled.\n");
58 by zones
Change debugger's log folder to LOG_DIR. / Mac: Add frame advance, change the timing of .srm save.
1555
				ENSURE_TRACE_OPEN(trace, "trace.log", "wb")
1 by OV2
Initial 1.52 import
1556
			}
1557
			else
1558
			{
1559
				printf("CPU instruction tracing disabled.\n");
1560
				fclose(trace);
1561
				trace = NULL;
1562
			}
1563
		}
1564
	}
1565
1566
	if (*Line == 'E')
1567
	{
1568
		Settings.TraceHCEvent = !Settings.TraceHCEvent;
1569
		printf("HC event tracing %s.\n", Settings.TraceHCEvent ? "enabled" : "disabled");
1570
	}
1571
1572
	if (*Line == 'A')
91 by zones
Add ports list doc (adventure_of_link) / Add APU debugger / Fix the issue that echo breaks the boot ROM
1573
		spc_core->debug_toggle_trace();
1574
1575
/*
1 by OV2
Initial 1.52 import
1576
	if (*Line == 'B')
1577
	{
1578
		Settings.TraceSoundDSP = !Settings.TraceSoundDSP;
1579
		printf("Sound DSP register tracing %s.\n", Settings.TraceSoundDSP ? "enabled" : "disabled");
1580
	}
1581
1582
	if (*Line == 'x')
1583
		S9xPrintSoundDSPState();
1584
1585
	if (*Line == 'C')
1586
	{
1587
		printf("SPC700 sample addresses at 0x%04x:\n", APU.DSP[APU_DIR] << 8);
1588
1589
		for (int i = 0; i < 256; i++)
1590
		{
1591
			uint8	*dir = IAPU.RAM + (((APU.DSP[APU_DIR] << 8) + i * 4) & 0xffff);
1592
			int		addr = *dir + (*(dir + 1) << 8);
1593
			int		addr2 = *(dir + 2) + (*(dir + 3) << 8);
1594
			printf("%04X %04X;", addr, addr2);
1595
1596
			if (i % 8 == 7)
1597
				printf("\n");
1598
		}
1599
	}
1600
*/
1601
1602
	if (*Line == 'R')
1603
	{
1604
		S9xReset();
1605
		printf("SNES reset.\n");
1606
		CPU.Flags |= DEBUG_MODE_FLAG;
1607
	}
1608
1609
/*
1610
	if (strncmp(Line, "ad", 2) == 0)
1611
	{
1612
		uint32	Count = 16;
1613
		Address = 0;
1614
1615
		if (sscanf(Line + 2, "%x,%x", &Address, &Count) != 2)
1616
		{
1617
			if (sscanf(Line + 2, "%x", &Address) == 1)
1618
				Count = 16;
1619
		}
1620
1621
		printf("APU RAM dump:\n");
1622
1623
		for (uint32 l = 0; l < Count; l += 16)
1624
		{
1625
			printf("%04X ", Address);
1626
1627
			for (int i = 0; i < 16; i++)
1628
				printf("%02X ", IAPU.RAM[Address++]);
1629
1630
			printf("\n");
1631
		}
1632
1633
		*Line = 0;
1634
	}
1635
1636
	if (*Line == 'a')
1637
	{
1638
		printf("APU in-ports : %02X %02X %02X %02X\n", IAPU.RAM[0xF4], IAPU.RAM[0xF5], IAPU.RAM[0xF6], IAPU.RAM[0xF7]);
1639
		printf("APU out-ports: %02X %02X %02X %02X\n", APU.OutPorts[0], APU.OutPorts[1], APU.OutPorts[2], APU.OutPorts[3]);
1640
		printf("ROM/RAM switch: %s\n", (IAPU.RAM[0xf1] & 0x80) ? "ROM" : "RAM");
1641
1642
		for (int i = 0; i < 3; i++)
1643
			if (APU.TimerEnabled[i])
1644
				printf("Timer%d enabled, Value: 0x%03X, 4-bit: 0x%02X, Target: 0x%03X\n",
1645
				       i, APU.Timer[i], IAPU.RAM[0xfd + i], APU.TimerTarget[i]);
1646
	}
1647
1648
	if (*Line == 'P')
1649
	{
1650
		Settings.TraceDSP = !Settings.TraceDSP;
1651
		printf("DSP tracing %s.\n", Settings.TraceDSP ? "enabled" : "disabled");
1652
	}
1653
*/
1654
1655
	if (*Line == 'p')
1656
	{
1657
		S9xBreakpoint[5].Enabled = FALSE;
1658
		Address += debug_cpu_op_print(string, Bank, Address);
1659
1660
		if (strncmp(&string[18], "JMP", 3) != 0 &&
1661
		    strncmp(&string[18], "JML", 3) != 0 &&
1662
		    strncmp(&string[18], "RT" , 2) != 0 &&
1663
		    strncmp(&string[18], "BRA", 3))
1664
		{
1665
			S9xBreakpoint[5].Enabled = TRUE;
1666
			S9xBreakpoint[5].Bank = Bank;
1667
			S9xBreakpoint[5].Address = Address;
1668
		}
1669
		else
1670
		{
1671
			CPU.Flags |= SINGLE_STEP_FLAG;
1672
			CPU.Flags &= ~DEBUG_MODE_FLAG;
1673
		}
1674
	}
1675
1676
	if (*Line == 'b')
1677
	{
1678
		if (Line[1] == 's')
1679
		{
1680
			debug_get_number(Line + 2, &Hold);
1681
1682
			if (Hold > 4)
1683
				Hold = 0;
1684
1685
			if (Hold < 5)
1686
			{
1687
				if (debug_get_start_address(Line + 5, &Bank, &Address) == -1)
1688
					S9xBreakpoint[Hold].Enabled = FALSE;
1689
				else
1690
				{
1691
					S9xBreakpoint[Hold].Enabled = TRUE;
1692
					S9xBreakpoint[Hold].Bank = Bank;
1693
					S9xBreakpoint[Hold].Address = Address;
1694
					CPU.Flags |= BREAK_FLAG;
1695
				}
1696
			}
1697
1698
			Line[1] = 'v';
1699
		}
1700
1701
		if (Line[1] == 'v')
1702
		{
1703
			Number = 0;
1704
1705
			if (debug_get_number(Line + 2, &Number) == -1 && Number < 5)
1706
			{
1707
				debug_line_print("Breakpoints:");
1708
1709
				for (Number = 0; Number != 5; Number++)
1710
				{
1711
					if (S9xBreakpoint[Number].Enabled)
1712
						sprintf(string, "%i @ $%02X:%04X", Number, S9xBreakpoint[Number].Bank, S9xBreakpoint[Number].Address);
1713
					else
1714
						sprintf(string, "%i @ Disabled", Number);
1715
1716
					debug_line_print(string);
1717
				}
1718
			}
1719
			else
1720
			{
1721
				debug_line_print("Breakpoint:");
1722
1723
				if (S9xBreakpoint[Number].Enabled)
1724
					sprintf(string, "%i @ $%02X:%04X", Number, S9xBreakpoint[Number].Bank, S9xBreakpoint[Number].Address);
1725
				else
1726
					sprintf(string, "%i @ Disabled", Number);
1727
1728
				debug_line_print(string);
1729
			}
1730
		}
1731
	}
1732
1733
	if (*Line == '?' || strcasecmp(Line, "help") == 0)
1734
	{
1735
		for (int i = 0; HelpMessage[i] != NULL; i++)
1736
			debug_line_print(HelpMessage[i]);
1737
	}
1738
1739
	if (*Line == 't')
1740
	{
1741
		CPU.Flags |= SINGLE_STEP_FLAG;
1742
		CPU.Flags &= ~DEBUG_MODE_FLAG;
1743
	}
1744
1745
	if (*Line == 'f')
1746
	{
1747
		CPU.Flags |= FRAME_ADVANCE_FLAG;
1748
		CPU.Flags &= ~DEBUG_MODE_FLAG;
1749
1750
		IPPU.RenderThisFrame = TRUE;
1751
		IPPU.FrameSkip = 0;
1752
1753
		if (sscanf(&Line[1], "%u", &ICPU.FrameAdvanceCount) != 1)
1754
			ICPU.Frame = 0;
1755
	}
1756
1757
	if (*Line == 'g')
1758
	{
1759
		S9xBreakpoint[5].Enabled = FALSE;
1760
1761
		bool8	found = FALSE;
1762
1763
		for (int i = 0; i < 5; i++)
1764
		{
1765
			if (S9xBreakpoint[i].Enabled)
1766
			{
1767
				found = TRUE;
1768
1769
				if (S9xBreakpoint[i].Bank == Registers.PB && S9xBreakpoint[i].Address == Registers.PCw)
1770
				{
1771
					S9xBreakpoint[i].Enabled = 2;
1772
					break;
1773
				}
1774
			}
1775
		}
1776
1777
		if (!found)
1778
			CPU.Flags &= ~BREAK_FLAG;
1779
1780
		ErrorCode = debug_get_start_address(Line, &Bank, &Address);
1781
1782
		if (ErrorCode == 1)
1783
		{
1784
			S9xBreakpoint[5].Enabled = TRUE;
1785
			S9xBreakpoint[5].Bank = Bank;
1786
			S9xBreakpoint[5].Address = Address;
1787
			CPU.Flags |= BREAK_FLAG;
1788
		}
1789
1790
		CPU.Flags &= ~DEBUG_MODE_FLAG;
1791
	}
1792
1793
	if (*Line == 'D')
1794
	{
1795
		Settings.TraceDMA = !Settings.TraceDMA;
1796
		printf("DMA tracing %s.\n", Settings.TraceDMA ? "enabled" : "disabled");
1797
	}
1798
1799
	if (*Line == 'V')
1800
	{
1801
		Settings.TraceVRAM = !Settings.TraceVRAM;
1802
		printf("Non-DMA VRAM write tracing %s.\n", Settings.TraceVRAM ? "enabled" : "disabled");
1803
	}
1804
1805
	if (*Line == 'H')
1806
	{
1807
		Settings.TraceHDMA = !Settings.TraceHDMA;
1808
		printf("HDMA tracing %s.\n", Settings.TraceHDMA ? "enabled" : "disabled");
1809
	}
1810
1811
	if (*Line == 'U')
1812
	{
1813
		Settings.TraceUnknownRegisters = !Settings.TraceUnknownRegisters;
1814
		printf("Unknown registers read/write tracing %s.\n", Settings.TraceUnknownRegisters ? "enabled" : "disabled");
1815
	}
1816
1817
	if (*Line == 'd')
1818
	{
1819
		int		CLine;
1820
		int		CByte;
1821
		uint8	MemoryByte;
1822
1823
		if (Debug.Dump.Bank != 0 || Debug.Dump.Address != 0)
1824
		{
1825
			Bank = Debug.Dump.Bank;
1826
			Address = Debug.Dump.Address;
1827
		}
1828
1829
		ErrorCode = debug_get_start_address(Line, &Bank, &Address);
1830
1831
		for (CLine = 0; CLine != 10; CLine++)
1832
		{
1833
			sprintf(string, "$%02X:%04X", Bank, Address);
1834
1835
			for (CByte = 0; CByte != 16; CByte++)
1836
			{
1837
				if (Address + CByte == 0x2140 ||
1838
				    Address + CByte == 0x2141 ||
1839
				    Address + CByte == 0x2142 ||
1840
				    Address + CByte == 0x2143 ||
1841
				    Address + CByte == 0x4210)
1842
					MemoryByte = 0;
1843
				else
2 by OV2
Update to latest WIP
1844
					MemoryByte = S9xDebugGetByte((Bank << 16) + Address + CByte);
1 by OV2
Initial 1.52 import
1845
1846
				sprintf(string, "%s %02X", string, MemoryByte);
1847
			}
1848
1849
			sprintf(string, "%s-", string);
1850
1851
			for (CByte = 0; CByte != 16; CByte++)
1852
			{
1853
				if (Address + CByte == 0x2140 ||
1854
				    Address + CByte == 0x2141 ||
1855
				    Address + CByte == 0x2142 ||
1856
				    Address + CByte == 0x2143 ||
1857
				    Address + CByte == 0x4210)
1858
					MemoryByte = 0;
1859
				else
2 by OV2
Update to latest WIP
1860
					MemoryByte = S9xDebugGetByte((Bank << 16) + Address + CByte);
1 by OV2
Initial 1.52 import
1861
1862
				if (MemoryByte < 32 || MemoryByte >= 127)
1863
					MemoryByte = '?';
1864
1865
				sprintf(string, "%s%c", string, MemoryByte);
1866
			}
1867
1868
			Address += 16;
1869
1870
			debug_line_print(string);
1871
		}
1872
1873
		Debug.Dump.Bank = Bank;
1874
		Debug.Dump.Address = Address;
1875
	}
1876
1877
	if (*Line == 'q')
1878
		S9xExit();
1879
1880
	if (*Line == 'W')
1881
		debug_whats_missing();
1882
1883
	if (*Line == 'w')
1884
		debug_whats_used();
1885
1886
	if (*Line == 'r')
1887
	{
1888
		debug_cpu_op_print(string, Bank, Address);
1889
		debug_line_print(string);
1890
	}
1891
1892
	if (*Line == 'u')
1893
	{
1894
		if (Debug.Unassemble.Bank != 0 || Debug.Unassemble.Address != 0)
1895
		{
1896
			Bank = Debug.Unassemble.Bank;
1897
			Address = Debug.Unassemble.Address;
1898
		}
1899
1900
		ErrorCode = debug_get_start_address(Line, &Bank, &Address);
1901
1902
		for (int i = 0; i != 10; i++)
1903
		{
1904
			Address += debug_cpu_op_print(string, Bank, Address);
1905
			debug_line_print(string);
1906
		}
1907
1908
		Debug.Unassemble.Bank = Bank;
1909
		Debug.Unassemble.Address = Address;
1910
	}
1911
1912
	debug_line_print("");
1913
1914
	return;
1915
}
1916
1917
static void debug_print_window (uint8 *window)
1918
{
1919
	for (int i = 0; i < 6; i++)
1920
	{
1921
		if (window[i])
1922
		{
1923
			switch (i)
1924
			{
1925
				case 0:
1926
					printf("Background 0, ");
1927
					break;
1928
1929
				case 1:
1930
					printf("Background 1, ");
1931
					break;
1932
1933
				case 2:
1934
					printf("Background 2, ");
1935
					break;
1936
1937
				case 3:
1938
					printf("Background 3, ");
1939
					break;
1940
1941
				case 4:
1942
					printf("Objects, ");
1943
					break;
1944
1945
				case 5:
1946
					printf("Color window, ");
1947
					break;
1948
			}
1949
		}
1950
	}
1951
}
1952
1953
static const char * debug_clip_fn (int logic)
1954
{
1955
	switch (logic)
1956
	{
1957
		case CLIP_OR:
1958
			return ("OR");
1959
1960
		case CLIP_AND:
1961
			return ("AND");
1962
1963
		case CLIP_XOR:
1964
			return ("XOR");
1965
1966
		case CLIP_XNOR:
1967
			return ("XNOR");
1968
1969
		default:
1970
			return ("???");
1971
	}
1972
}
1973
1974
static void debug_whats_used (void)
1975
{
1976
	printf("V-line: %ld, H-Pos: %ld, \n", (long) CPU.V_Counter, (long) CPU.Cycles);
1977
1978
	printf("Screen mode: %d, ", PPU.BGMode);
1979
1980
	if (PPU.BGMode <= 1 && (Memory.FillRAM[0x2105] & 8))
1981
		printf("(BG#2 Priority), ");
1982
1983
	printf("Brightness: %d, ", PPU.Brightness);
1984
1985
	if (Memory.FillRAM[0x2100] & 0x80)
1986
		printf("(screen blanked), ");
1987
1988
	printf("\n");
1989
1990
	if (Memory.FillRAM[0x2133] & 1)
1991
		printf("Interlace, ");
1992
1993
	if (Memory.FillRAM[0x2133] & 4)
1994
		printf("240 line visible, ");
1995
1996
	if (Memory.FillRAM[0x2133] & 8)
1997
		printf("Pseudo 512 pixels horizontal resolution, ");
1998
1999
	if (Memory.FillRAM[0x2133] & 0x40)
2000
		printf("Mode 7 priority per pixel, ");
2001
2002
	printf("\n");
2003
2004
	if (PPU.BGMode == 7 && (Memory.FillRAM[0x211a] & 3))
2005
		printf("Mode 7 flipping, ");
2006
2007
	if (PPU.BGMode == 7)
2008
		printf("Mode 7 screen repeat: %d, ", (Memory.FillRAM[0x211a] & 0xc0) >> 6);
2009
2010
	if (Memory.FillRAM[0x2130] & 1)
2011
		printf("32K colour mode, ");
2012
2013
	printf("\n");
2014
2015
	if (PPU.BGMode == 7)
2016
	{
2017
		// Sign extend 13 bit values to 16 bit values...
2018
		if (PPU.CentreX & (1 << 12))
2019
			PPU.CentreX |= 0xe000;
2020
2021
		if (PPU.CentreY & (1 << 12))
2022
			PPU.CentreY |= 0xe000;
2023
2024
		printf("Matrix A: %.3f, B: %.3f, C: %.3f, D: %.3f, Centre X: %d Y:%d, \n",
2025
		       (double) PPU.MatrixA / 256, (double) PPU.MatrixB / 256,
2026
		       (double) PPU.MatrixC / 256, (double) PPU.MatrixD / 256,
2027
		       PPU.CentreX, PPU.CentreY);
2028
	}
2029
2030
	if ((Memory.FillRAM[0x2106] & 0xf0) && (Memory.FillRAM[0x2106] & 0x0f))
2031
	{
2032
		printf("Mosaic effect(%d) on, ", PPU.Mosaic);
2033
2034
		for (int i = 0; i < 4; i++)
2035
			if (Memory.FillRAM[0x2106] & (1 << i))
2036
				printf("BG%d, ", i);
2037
	}
2038
2039
	printf("\n");
2040
2041
	if (PPU.HVBeamCounterLatched)
2042
		printf("V and H beam pos latched, \n");
2043
2044
	if (Memory.FillRAM[0x4200] & 0x20)
2045
		printf("V-IRQ enabled at %d, \n", PPU.IRQVBeamPos);
2046
2047
	if (Memory.FillRAM[0x4200] & 0x10)
2048
		printf("H-IRQ enabled at %d, \n", PPU.IRQHBeamPos);
2049
2050
	if (Memory.FillRAM[0x4200] & 0x80)
2051
		printf("V-blank NMI enabled, \n");
2052
2053
	for (int i = 0; i < 8; i++)
2054
	{
2055
		if (missing.hdma_this_frame & (1 << i))
2056
		{
2057
			printf("H-DMA %d [%d] 0x%02X%04X->0x21%02X %s %s 0x%02X%04X %s addressing, \n",
2058
			       i, DMA[i].TransferMode, DMA[i].ABank, DMA[i].AAddress, DMA[i].BAddress,
2059
			       DMA[i].AAddressDecrement ? "dec" : "inc",
2060
			       DMA[i].Repeat ? "repeat" : "continue",
2061
			       DMA[i].IndirectBank, DMA[i].IndirectAddress,
2062
			       DMA[i].HDMAIndirectAddressing ? "indirect" : "absolute");
2063
		}
2064
	}
2065
2066
	for (int i = 0; i < 8; i++)
2067
	{
2068
		if (missing.dma_this_frame & (1 << i))
2069
		{
2070
			printf("DMA %d [%d] 0x%02X%04X->0x21%02X Num: %d %s, \n",
2071
			       i, DMA[i].TransferMode, DMA[i].ABank, DMA[i].AAddress, DMA[i].BAddress, DMA[i].TransferBytes,
2072
			       DMA[i].AAddressFixed ? "fixed" : (DMA[i].AAddressDecrement ? "dec" : "inc"));
2073
		}
2074
	}
2075
2076
	printf("VRAM write address: 0x%04x(%s), Full Graphic: %d, Address inc: %d, \n",
2077
	       PPU.VMA.Address,
2078
	       PPU.VMA.High  ? "Byte" : "Word",
2079
	       PPU.VMA.FullGraphicCount, PPU.VMA.Increment);
2080
2081
	for (int i = 0; i < 4; i++)
2082
	{
2083
		printf("BG%d: VOffset:%d, HOffset:%d, W:%d, H:%d, TS:%d, BA:0x%04x, TA:0x%04X, \n",
2084
		       i, PPU.BG[i].VOffset, PPU.BG[i].HOffset,
2085
		       (PPU.BG[i].SCSize & 1) * 32 + 32,
2086
		       (PPU.BG[i].SCSize & 2) * 16 + 32,
2087
		       PPU.BG[i].BGSize * 8 + 8,
2088
		       PPU.BG[i].SCBase,
2089
		       PPU.BG[i].NameBase);
2090
	}
2091
2092
	const char	*s = "";
2093
2094
	switch ((Memory.FillRAM[0x2130] & 0xc0) >> 6)
2095
	{
2096
		case 0:
2097
			s = "always on";
2098
			break;
2099
2100
		case 1:
2101
			s = "inside";
2102
			break;
2103
2104
		case 2:
2105
			s = "outside";
2106
			break;
2107
2108
		case 3:
2109
			s = "always off";
2110
			break;
2111
	}
2112
2113
	printf("Main screen (%s): ", s);
2114
2115
	for (int i = 0; i < 5; i++)
2116
	{
2117
		if (Memory.FillRAM[0x212c] & (1 << i))
2118
		{
2119
			switch (i)
2120
			{
2121
				case 0:
2122
					printf("BG0, ");
2123
					break;
2124
2125
				case 1:
2126
					printf("BG1, ");
2127
					break;
2128
2129
				case 2:
2130
					printf("BG2, ");
2131
					break;
2132
2133
				case 3:
2134
					printf("BG3, ");
2135
					break;
2136
2137
				case 4:
2138
					printf("OBJ, ");
2139
					break;
2140
			}
2141
		}
2142
	}
2143
2144
	printf("\n");
2145
2146
	switch ((Memory.FillRAM[0x2130] & 0x30) >> 4)
2147
	{
2148
		case 0:
2149
			s = "always on";
2150
			break;
2151
2152
		case 1:
2153
			s = "inside";
2154
			break;
2155
2156
		case 2:
2157
			s = "outside";
2158
			break;
2159
2160
		case 3:
2161
			s = "always off";
2162
			break;
2163
	}
2164
2165
	printf("Subscreen (%s): ", s);
2166
2167
	for (int i = 0; i < 5; i++)
2168
	{
2169
		if (Memory.FillRAM[0x212d] & (1 << i))
2170
		{
2171
			switch (i)
2172
			{
2173
				case 0:
2174
					printf("BG0, ");
2175
					break;
2176
2177
				case 1:
2178
					printf("BG1, ");
2179
					break;
2180
2181
				case 2:
2182
					printf("BG2, ");
2183
					break;
2184
2185
				case 3:
2186
					printf("BG3, ");
2187
					break;
2188
2189
				case 4:
2190
					printf("OBJ, ");
2191
					break;
2192
			}
2193
		}
2194
	}
2195
2196
	printf("\n");
2197
2198
	if ((Memory.FillRAM[0x2131] & 0x3f))
2199
	{
2200
		if (Memory.FillRAM[0x2131] & 0x80)
2201
		{
2202
			if (Memory.FillRAM[0x2130] & 0x02)
2203
				printf("Subscreen subtract");
2204
			else
2205
				printf("Fixed colour subtract");
2206
		}
2207
		else
2208
		{
2209
			if (Memory.FillRAM[0x2130] & 0x02)
2210
				printf("Subscreen addition");
2211
			else
2212
				printf("Fixed colour addition");
2213
		}
2214
2215
		if (Memory.FillRAM[0x2131] & 0x40)
2216
			printf("(half): ");
2217
		else
2218
			printf(": ");
2219
2220
		for (int i = 0; i < 6; i++)
2221
		{
2222
			if (Memory.FillRAM[0x2131] & (1 << i))
2223
			{
2224
				switch (i)
2225
				{
2226
					case 0:
2227
						printf("BG0, ");
2228
						break;
2229
2230
					case 1:
2231
						printf("BG1, ");
2232
						break;
2233
2234
					case 2:
2235
						printf("BG2, ");
2236
						break;
2237
2238
					case 3:
2239
						printf("BG3, ");
2240
						break;
2241
2242
					case 4:
2243
						printf("OBJ, ");
2244
						break;
2245
2246
					case 5:
2247
						printf("BACK, ");
2248
						break;
2249
				}
2250
			}
2251
		}
2252
2253
		printf("\n");
2254
	}
2255
2256
	printf("Window 1 (%d, %d, %02x, %02x): ", PPU.Window1Left, PPU.Window1Right, Memory.FillRAM[0x212e], Memory.FillRAM[0x212f]);
2257
2258
	for (int i = 0; i < 6; i++)
2259
	{
2260
		if (PPU.ClipWindow1Enable[i])
2261
		{
2262
			switch (i)
2263
			{
2264
				case 0:
2265
					printf("BG0(%s-%s), ", PPU.ClipWindow1Inside[0] ? "I" : "O", debug_clip_fn(PPU.ClipWindowOverlapLogic[0]));
2266
					break;
2267
2268
				case 1:
2269
					printf("BG1(%s-%s), ", PPU.ClipWindow1Inside[1] ? "I" : "O", debug_clip_fn(PPU.ClipWindowOverlapLogic[1]));
2270
					break;
2271
2272
				case 2:
2273
					printf("BG2(%s-%s), ", PPU.ClipWindow1Inside[2] ? "I" : "O", debug_clip_fn(PPU.ClipWindowOverlapLogic[2]));
2274
					break;
2275
2276
				case 3:
2277
					printf("BG3(%s-%s), ", PPU.ClipWindow1Inside[3] ? "I" : "O", debug_clip_fn(PPU.ClipWindowOverlapLogic[3]));
2278
					break;
2279
2280
				case 4:
2281
					printf("OBJ(%s-%s), ", PPU.ClipWindow1Inside[4] ? "I" : "O", debug_clip_fn(PPU.ClipWindowOverlapLogic[4]));
2282
					break;
2283
2284
				case 5:
2285
					printf("COL(%s-%s), ", PPU.ClipWindow1Inside[5] ? "I" : "O", debug_clip_fn(PPU.ClipWindowOverlapLogic[5]));
2286
					break;
2287
			}
2288
		}
2289
	}
2290
2291
	printf("\n");
2292
2293
	printf("Window 2 (%d, %d): ", PPU.Window2Left, PPU.Window2Right);
2294
2295
	for (int i = 0; i < 6; i++)
2296
	{
2297
		if (PPU.ClipWindow2Enable[i])
2298
		{
2299
			switch (i)
2300
			{
2301
				case 0:
2302
					printf("BG0(%s), ", PPU.ClipWindow2Inside[0] ? "I" : "O");
2303
					break;
2304
2305
				case 1:
2306
					printf("BG1(%s), ", PPU.ClipWindow2Inside[1] ? "I" : "O");
2307
					break;
2308
2309
				case 2:
2310
					printf("BG2(%s), ", PPU.ClipWindow2Inside[2] ? "I" : "O");
2311
					break;
2312
2313
				case 3:
2314
					printf("BG3(%s), ", PPU.ClipWindow2Inside[3] ? "I" : "O");
2315
					break;
2316
2317
				case 4:
2318
					printf("OBJ(%s), ", PPU.ClipWindow2Inside[4] ? "I" : "O");
2319
					break;
2320
2321
				case 5:
2322
					printf("COL(%s), " , PPU.ClipWindow2Inside[5] ? "I" : "O");
2323
					break;
2324
			}
2325
		}
2326
	}
2327
2328
	printf("\n");
2329
2330
	printf("Fixed colour: %02x%02x%02x, \n", PPU.FixedColourRed, PPU.FixedColourGreen, PPU.FixedColourBlue);
2331
}
2332
2333
static void debug_whats_missing (void)
2334
{
2335
	printf("Processor: ");
2336
2337
	if (missing.emulate6502)
2338
		printf("emulation mode, ");
2339
2340
	if (missing.decimal_mode)
2341
		printf("decimal mode, ");
2342
2343
	if (missing.mv_8bit_index)
2344
		printf("MVP/MVN with 8bit index registers and XH or YH > 0, ");
2345
2346
	if (missing.mv_8bit_acc)
2347
		printf("MVP/MVN with 8bit accumulator > 255, ");
2348
2349
	printf("\n");
2350
2351
	printf("Screen modes used: ");
2352
2353
	for (int i = 0; i < 8; i++)
2354
		if (missing.modes[i])
2355
			printf("%d, ", i);
2356
2357
	printf("\n");
2358
2359
	if (missing.interlace)
2360
		printf("Interlace, ");
2361
2362
	if (missing.pseudo_512)
2363
		printf("Pseudo 512 pixels horizontal resolution, ");
2364
2365
	if (missing.lines_239)
2366
		printf("240 lines visible, ");
2367
2368
	if (missing.sprite_double_height)
2369
		printf("double-hight sprites, ");
2370
2371
	printf("\n");
2372
2373
	if (missing.mode7_fx)
2374
		printf("Mode 7 rotation/scaling, ");
2375
2376
	if (missing.matrix_read)
2377
		printf("Mode 7 read matrix registers, ");
2378
2379
	if (missing.mode7_flip)
2380
		printf("Mode 7 flipping, ");
2381
2382
	if (missing.mode7_bgmode)
2383
		printf("Mode 7 priority per pixel, ");
2384
2385
	if (missing.direct)
2386
		printf("Direct 32000 colour mode, ");
2387
2388
	printf("\n");
2389
2390
	if (missing.mosaic)
2391
		printf("Mosaic effect, ");
2392
2393
	if (missing.subscreen)
2394
		printf("Subscreen enabled, ");
2395
2396
	if (missing.subscreen_add)
2397
		printf("Subscreen colour add, ");
2398
2399
	if (missing.subscreen_sub)
2400
		printf("Subscreen colour subtract, ");
2401
2402
	if (missing.fixed_colour_add)
2403
		printf("Fixed colour add, ");
2404
2405
	if (missing.fixed_colour_sub)
2406
		printf("Fixed colour subtract, ");
2407
2408
	printf("\n");
2409
2410
	printf("Window 1 enabled on: ");
2411
	debug_print_window(missing.window1);
2412
2413
	printf("\n");
2414
	
2415
	printf("Window 2 enabled on: ");
2416
	debug_print_window(missing.window2);
2417
2418
	printf("\n");
2419
2420
	if (missing.bg_offset_read)
2421
		printf("BG offset read, ");
2422
2423
	if (missing.oam_address_read)
2424
		printf("OAM address read, ");
2425
2426
	if (missing.sprite_priority_rotation)
2427
		printf("Sprite priority rotation, ");
2428
2429
	if (missing.fast_rom)
2430
		printf("Fast 3.58MHz ROM access enabled, ");
2431
2432
	if (missing.matrix_multiply)
2433
		printf("Matrix multiply 16bit by 8bit used, ");
2434
2435
	printf("\n");
2436
2437
	if (missing.virq)
2438
		printf("V-IRQ used at line %d, ", missing.virq_pos);
2439
2440
	if (missing.hirq)
2441
		printf("H-IRQ used at position %d, ", missing.hirq_pos);
2442
2443
	printf("\n");
2444
2445
	if (missing.h_v_latch)
2446
		printf("H and V-Pos latched, ");
2447
2448
	if (missing.h_counter_read)
2449
		printf("H-Pos read, ");
2450
2451
	if (missing.v_counter_read)
2452
		printf("V-Pos read, ");
2453
2454
	printf("\n");
2455
2456
	if (missing.oam_read)
2457
		printf("OAM read, ");
2458
2459
	if (missing.vram_read)
2460
		printf("VRAM read, ");
2461
2462
	if (missing.cgram_read)
2463
		printf("CG-RAM read, ");
2464
2465
	if (missing.wram_read)
2466
		printf("WRAM read, ");
2467
2468
	if (missing.dma_read)
2469
		printf("DMA read, ");
2470
2471
	if (missing.vram_inc)
2472
		printf("VRAM inc: %d, ", missing.vram_inc);
2473
2474
	if (missing.vram_full_graphic_inc)
2475
		printf("VRAM full graphic inc: %d, ", missing.vram_full_graphic_inc);
2476
2477
	printf("\n");
2478
2479
	for (int i = 0; i < 8; i++)
2480
	{
2481
		if (missing.hdma[i].used)
2482
		{
2483
			printf("HDMA %d 0x%02X%04X->0x21%02X %s, ",
2484
			       i, missing.hdma[i].abus_bank, missing.hdma[i].abus_address, missing.hdma[i].bbus_address,
2485
			       missing.hdma[i].indirect_address ? "indirect" : "absolute");
2486
2487
			if (missing.hdma[i].force_table_address_write)
2488
				printf("Forced address write, ");
2489
2490
			if (missing.hdma[i].force_table_address_read)
2491
				printf("Current address read, ");
2492
2493
			if (missing.hdma[i].line_count_write)
2494
				printf("Line count write, ");
2495
2496
			if (missing.hdma[i].line_count_read)
2497
				printf("Line count read, ");
2498
2499
			printf("\n");
2500
		}
2501
	}
2502
2503
	for (int i = 0; i < 8; i++)
2504
	{
2505
		if (missing.dma_channels & (1 << i))
2506
		{
2507
			printf("DMA %d [%d] 0x%02X%04X->0x21%02X Num: %d %s, \n",
2508
			       i, DMA[i].TransferMode, DMA[i].ABank, DMA[i].AAddress, DMA[i].BAddress, DMA[i].TransferBytes,
2509
			       DMA[i].AAddressFixed ? "fixed" : (DMA[i].AAddressDecrement ? "dec" : "inc"));
2510
		}
2511
	}
2512
2513
	if (missing.unknownppu_read)
2514
		printf("Read from unknown PPU register: $%04X, \n", missing.unknownppu_read);
2515
2516
	if (missing.unknownppu_write)
2517
		printf("Write to unknown PPU register: $%04X, \n", missing.unknownppu_write);
2518
2519
	if (missing.unknowncpu_read)
2520
		printf("Read from unknown CPU register: $%04X, \n", missing.unknowncpu_read);
2521
2522
	if (missing.unknowncpu_write)
2523
		printf("Write to unknown CPU register: $%04X, \n", missing.unknowncpu_write);
2524
2525
	if (missing.unknowndsp_read)
2526
		printf("Read from unknown DSP register: $%04X, \n", missing.unknowndsp_read);
2527
2528
	if (missing.unknowndsp_write)
2529
		printf("Write to unknown DSP register: $%04X, \n", missing.unknowndsp_write);
2530
}
2531
2532
void S9xDoDebug (void)
2533
{
2534
	char	Line[513];
2535
2536
	Debug.Dump.Bank = 0;
2537
	Debug.Dump.Address = 0;
2538
	Debug.Unassemble.Bank = 0;
2539
	Debug.Unassemble.Address = 0;
2540
2541
	S9xTextMode();
2542
2543
	strcpy(Line, "r");
2544
	debug_process_command(Line);
2545
2546
	while (CPU.Flags & DEBUG_MODE_FLAG)
2547
	{
2548
		int32	Cycles;
2549
		char	*p;
2550
2551
		printf("> ");
2552
		fflush(stdout);
2553
2554
		p = fgets(Line, sizeof(Line) - 1, stdin);
2555
		Line[strlen(Line) - 1] = 0;
2556
2557
		Cycles = CPU.Cycles;
2558
		debug_process_command(Line);
2559
		CPU.Cycles = Cycles;
2560
	}
2561
2562
	if (!(CPU.Flags & SINGLE_STEP_FLAG))
2563
		S9xGraphicsMode();
2564
}
2565
2566
void S9xTrace (void)
2567
{
2568
	char	msg[512];
2569
58 by zones
Change debugger's log folder to LOG_DIR. / Mac: Add frame advance, change the timing of .srm save.
2570
	ENSURE_TRACE_OPEN(trace, "trace.log", "a")
1 by OV2
Initial 1.52 import
2571
2572
	debug_cpu_op_print(msg, Registers.PB, Registers.PCw);
2573
	fprintf(trace, "%s\n", msg);
2574
}
2575
2576
void S9xSA1Trace (void)
2577
{
2578
	char	msg[512];
2579
58 by zones
Change debugger's log folder to LOG_DIR. / Mac: Add frame advance, change the timing of .srm save.
2580
	ENSURE_TRACE_OPEN(trace2, "trace_sa1.log", "a")
1 by OV2
Initial 1.52 import
2581
2582
	debug_sa1_op_print(msg, SA1Registers.PB, SA1Registers.PCw);
2583
	fprintf(trace2, "%s\n", msg);
2584
}
2585
2586
void S9xTraceMessage (const char *s)
2587
{
2588
	if (s)
2589
	{
2590
		if (trace)
2591
			fprintf(trace, "%s\n", s);
2592
		else
2593
		if (trace2)
2594
			fprintf(trace2, "%s\n", s);
2595
	}
2596
}
2597
2598
void S9xTraceFormattedMessage (const char *s, ...)
2599
{
2600
	char	msg[512];
2601
2602
	if (s)
2603
	{
2604
		va_list	argptr;
2605
2606
		va_start(argptr, s);
2607
		vsprintf(msg, s, argptr);
2608
		va_end(argptr);
2609
2610
		S9xTraceMessage(msg);
2611
	}
2612
}
2613
91 by zones
Add ports list doc (adventure_of_link) / Add APU debugger / Fix the issue that echo breaks the boot ROM
2614
void S9xPrintHVPosition (char *s)
2615
{
2616
	sprintf(s, "HC:%04ld VC:%03ld FC:%02d", (long) CPU.Cycles, (long) CPU.V_Counter, IPPU.FrameCount);
2617
}
2618
1 by OV2
Initial 1.52 import
2619
#endif