-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug.h
189 lines (172 loc) · 5.62 KB
/
debug.h
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
/*
spiffy - ZX spectrum emulator
Copyright Edward Cree, 2010-13
debug.h - debugger functions
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "z80.h"
#include "ops.h"
#include "audio.h"
#include "vchips.h"
typedef enum
{
DEBUGTYPE_BYTE, // b
DEBUGTYPE_WORD, // w
DEBUGTYPE_FLOAT, // f
DEBUGTYPE_GRID, // 8
DEBUGTYPE_ROW, // R
DEBUGTYPE_ERR, // used to signal a syntax error
}
debugtype;
typedef union
{
uint8_t b;
uint16_t w;
double f;
uint8_t r[16]; // used by 8 and R
}
debugval_val;
typedef enum
{
DEBUGADDR_NULL, // NULL pointer
DEBUGADDR_MAIN, // RAM as seen by the CPU
DEBUGADDR_PAGE, // RAM as a linear page array
DEBUGADDR_CPU, // CPU registers (nonlinear; access is 8-bit, unless debugaddr.page in which case it's 16-bit)
DEBUGADDR_ULAPLUS, // ULA+ registers
DEBUGADDR_AY, // AY registers
}
debugaddrtype;
typedef struct
{
debugaddrtype type;
uint16_t addr;
unsigned int page;
}
debugaddr;
typedef struct
{
debugtype type;
debugval_val val;
debugaddr addr; // NULL if it's not an lvalue
}
debugval;
typedef struct
{
int Tstates;
z80 *cpu;
bus_t *bus;
ram_t *ram;
ula_t *ula;
ay_t *ay;
}
debugctx;
char typename(debugtype type);
size_t typelength(debugtype type);
void dwrite(debugaddr addr, debugval val, debugctx ctx);
debugval dread(debugaddr addr, debugtype type, debugctx ctx);
void debugger_tokenise(char *line, int *drgc, char *drgv[256]);
debugval debugger_expr(FILE *f, int ec, const char *const ev[256], debugctx ctx);
void show_state(debugctx);
void debugval_display(FILE *f, debugval val);
int reg16(const char *name);
/* debugger help text */
#define h_h "spiffy debugger: help sections\n\
h commands list\n\
h h this section list\n\
h p expression evaluation\n\
h m memory commands\n\
h v BASIC variables\n\
h k BASIC listing\n\
h = register assignments\n\
h u ULAplus state\n"
#define h_u "spiffy debugger: ULAplus state\n\
u display ULAplus summary\n\
u xx decode ULAplus palette entry literal xx\n\
u [xx] decode xxth ULAplus palette entry\n\
u [xx] yy write yy to xxth ULAplus palette entry\n\
u m xx write xx to ULAplus mode register\n"
#define h_p "spiffy debugger: expression evaluation\n\
\tp-expressions are given in Polish Notation; that is, every operator\n\
\tis a prefix operator. So to read a byte from IX+0x25, use\n\
\t\t.b + #IX 25\n\
\tFor full details see the debugger manual.\n\
\tSome more examples:\n\
.b 8ccc - byte at 0x8ccc\n\
.f dead - 5-byte float at 0xdead\n\
.w @VARS - word at VARS\n\
.8 + .w @CHARS 118 - 8 bytes from [[CHARS]+280]\n\
= .b #DE .b #HL - copies a byte from [HL] to [DE]\n\
.b:AY 5 - byte from AY register 5\n"/*\
>> #A 1 - value of A, shifted right once\n\
<<< #A 3 - value of A, rotated left three times\n"*/
#define h_m "spiffy debugger: memory commands\n\
\tThe m[emory] command has been superseded by p[rint], see help p\n\
\tHere are p versions of the old m commands\n\
m r xxxx p .b xxxx\n\
m w xxxx yy p = .b xxxx yy\n\
m lr xxxx p .w xxxx\n\
m lw xxxx yyyy p = .w xxxx yyyy\n\
m fr xxxx p .f xxxx\n\
m fw xxxx d p = .f xxxx _d\n\
m 8r xxxx p .8 xxxx\n\
m Rr xxxx p .R xxxx\n"
#define h_v "spiffy debugger: BASIC variables\n\
v list all variables\n\
v foo examine (numeric) foo\n\
v a$ examine (string) a$\n\
v a 1 2 3 examine numeric array a\n\
v a$ 4 examine character array a$\n\
v a () examine array a rather than variable a\n\
If the variable is numeric, the listed address is that of the 5-byte float\n\
value; if string, the listed address is the start of the variable's\n\
metadata (the string data starts 3 bytes later). If it's an array, the\n\
address of the first element of the array is given (that is, the address\n\
when all the remaining subscripts are filled out with 1s); this is the\n\
case regardless of whether the array is numeric or character.\n"
#define h_k "spiffy debugger: BASIC listing\n\
k entire program listing\n\
kn listing with float numbers\n\
k 10 display line 10 of the program\n"
#define h_eq "spiffy debugger: registers\n\
p #reg displays the value of register reg\n\
p = #reg val assigns val (hex) to register reg\n\
\n\
The (16-bit) registers are: PC AF BC DE HL IX IY SP AF' BC' DE' HL'\n\
8-bit reads/writes can be made as follows:\n\
MSB LSB register\n\
A F AF\n\
B C BC\n\
D E DE\n\
H L HL\n\
X x IX\n\
Y y IY\n\
I R IR (can't access as 16-bit)\n\
S P SP\n\
a f AF'\n\
b c BC'\n\
d e DE'\n\
h l HL'\n"
#define h_cmds "spiffy debugger:\n\
n[ext] single-step the Z80\n\
[!]1 enable/disable Tstate stepping\n\
c[ont] continue emulation\n\
h[elp] [sect] get debugger help (see 'h h')\n\
s[tate] show Z80 state\n\
t[race] trace Z80 state\n\
b[reak] xxxx set a breakpoint\n\
!b[reak] xxxx delete a breakpoint\n\
l[ist] list breakpoints\n\
p[rint] ... evaluate & print expression (see 'h p')\n\
ei enable interrupts\n\
di disable interrupts\n\
r[eset] reset the Z80\n\
[!]i[nt] set/clear INT line\n\
[!]nmi set/clear NMI line\n\
v[ars] ... examine BASIC variables (see 'h v')\n\
k ... examine BASIC listing (see 'h k')\n\
y examine system variables\n\
a[ystate] [r] show AY state (if AY enabled)\n\
u[laplus] show ULAplus state (if ULA+ enabled)\n\
q[uit] quit Spiffy\n"