Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/snes/cpu.hpp
2 views
1
#ifndef NALL_SNES_CPU_HPP
2
#define NALL_SNES_CPU_HPP
3
4
namespace nall {
5
6
struct SNESCPU {
7
enum : unsigned {
8
Implied, //
9
Constant, //#$00
10
AccumConstant, //#$00
11
IndexConstant, //#$00
12
Direct, //$00
13
DirectX, //$00,x
14
DirectY, //$00,y
15
IDirect, //($00)
16
IDirectX, //($00,x)
17
IDirectY, //($00),y
18
ILDirect, //[$00]
19
ILDirectY, //[$00],y
20
Address, //$0000
21
AddressX, //$0000,x
22
AddressY, //$0000,y
23
IAddressX, //($0000,x)
24
ILAddress, //[$0000]
25
PAddress, //PBR:$0000
26
PIAddress, //PBR:($0000)
27
Long, //$000000
28
LongX, //$000000,x
29
Stack, //$00,s
30
IStackY, //($00,s),y
31
BlockMove, //$00,$00
32
RelativeShort, //+/- $00
33
RelativeLong, //+/- $0000
34
};
35
36
struct OpcodeInfo {
37
char name[4];
38
unsigned mode;
39
};
40
41
static const OpcodeInfo opcodeInfo[256];
42
43
static unsigned getOpcodeLength(bool accum, bool index, uint8_t opcode);
44
static string disassemble(unsigned pc, bool accum, bool index, uint8_t opcode, uint8_t pl, uint8_t ph, uint8_t pb);
45
};
46
47
const SNESCPU::OpcodeInfo SNESCPU::opcodeInfo[256] = {
48
//0x00 - 0x0f
49
{ "brk", Constant },
50
{ "ora", IDirectX },
51
{ "cop", Constant },
52
{ "ora", Stack },
53
54
{ "tsb", Direct },
55
{ "ora", Direct },
56
{ "asl", Direct },
57
{ "ora", ILDirect },
58
59
{ "php", Implied },
60
{ "ora", AccumConstant },
61
{ "asl", Implied },
62
{ "phd", Implied },
63
64
{ "tsb", Address },
65
{ "ora", Address },
66
{ "asl", Address },
67
{ "ora", Long },
68
69
//0x10 - 0x1f
70
{ "bpl", RelativeShort },
71
{ "ora", IDirectY },
72
{ "ora", IDirect },
73
{ "ora", IStackY },
74
75
{ "trb", Direct },
76
{ "ora", DirectX },
77
{ "asl", DirectX },
78
{ "ora", ILDirectY },
79
80
{ "clc", Implied },
81
{ "ora", AddressY },
82
{ "inc", Implied },
83
{ "tcs", Implied },
84
85
{ "trb", Address },
86
{ "ora", AddressX },
87
{ "asl", AddressX },
88
{ "ora", LongX },
89
90
//0x20 - 0x2f
91
{ "jsr", Address },
92
{ "and", IDirectX },
93
{ "jsl", Long },
94
{ "and", Stack },
95
96
{ "bit", Direct },
97
{ "and", Direct },
98
{ "rol", Direct },
99
{ "and", ILDirect },
100
101
{ "plp", Implied },
102
{ "and", AccumConstant },
103
{ "rol", Implied },
104
{ "pld", Implied },
105
106
{ "bit", Address },
107
{ "and", Address },
108
{ "rol", Address },
109
{ "and", Long },
110
111
//0x30 - 0x3f
112
{ "bmi", RelativeShort },
113
{ "and", IDirectY },
114
{ "and", IDirect },
115
{ "and", IStackY },
116
117
{ "bit", DirectX },
118
{ "and", DirectX },
119
{ "rol", DirectX },
120
{ "and", ILDirectY },
121
122
{ "sec", Implied },
123
{ "and", AddressY },
124
{ "dec", Implied },
125
{ "tsc", Implied },
126
127
{ "bit", AddressX },
128
{ "and", AddressX },
129
{ "rol", AddressX },
130
{ "and", LongX },
131
132
//0x40 - 0x4f
133
{ "rti", Implied },
134
{ "eor", IDirectX },
135
{ "wdm", Constant },
136
{ "eor", Stack },
137
138
{ "mvp", BlockMove },
139
{ "eor", Direct },
140
{ "lsr", Direct },
141
{ "eor", ILDirect },
142
143
{ "pha", Implied },
144
{ "eor", AccumConstant },
145
{ "lsr", Implied },
146
{ "phk", Implied },
147
148
{ "jmp", PAddress },
149
{ "eor", Address },
150
{ "lsr", Address },
151
{ "eor", Long },
152
153
//0x50 - 0x5f
154
{ "bvc", RelativeShort },
155
{ "eor", IDirectY },
156
{ "eor", IDirect },
157
{ "eor", IStackY },
158
159
{ "mvn", BlockMove },
160
{ "eor", DirectX },
161
{ "lsr", DirectX },
162
{ "eor", ILDirectY },
163
164
{ "cli", Implied },
165
{ "eor", AddressY },
166
{ "phy", Implied },
167
{ "tcd", Implied },
168
169
{ "jml", Long },
170
{ "eor", AddressX },
171
{ "lsr", AddressX },
172
{ "eor", LongX },
173
174
//0x60 - 0x6f
175
{ "rts", Implied },
176
{ "adc", IDirectX },
177
{ "per", Address },
178
{ "adc", Stack },
179
180
{ "stz", Direct },
181
{ "adc", Direct },
182
{ "ror", Direct },
183
{ "adc", ILDirect },
184
185
{ "pla", Implied },
186
{ "adc", AccumConstant },
187
{ "ror", Implied },
188
{ "rtl", Implied },
189
190
{ "jmp", PIAddress },
191
{ "adc", Address },
192
{ "ror", Address },
193
{ "adc", Long },
194
195
//0x70 - 0x7f
196
{ "bvs", RelativeShort },
197
{ "adc", IDirectY },
198
{ "adc", IDirect },
199
{ "adc", IStackY },
200
201
{ "stz", DirectX },
202
{ "adc", DirectX },
203
{ "ror", DirectX },
204
{ "adc", ILDirectY },
205
206
{ "sei", Implied },
207
{ "adc", AddressY },
208
{ "ply", Implied },
209
{ "tdc", Implied },
210
211
{ "jmp", IAddressX },
212
{ "adc", AddressX },
213
{ "ror", AddressX },
214
{ "adc", LongX },
215
216
//0x80 - 0x8f
217
{ "bra", RelativeShort },
218
{ "sta", IDirectX },
219
{ "brl", RelativeLong },
220
{ "sta", Stack },
221
222
{ "sty", Direct },
223
{ "sta", Direct },
224
{ "stx", Direct },
225
{ "sta", ILDirect },
226
227
{ "dey", Implied },
228
{ "bit", AccumConstant },
229
{ "txa", Implied },
230
{ "phb", Implied },
231
232
{ "sty", Address },
233
{ "sta", Address },
234
{ "stx", Address },
235
{ "sta", Long },
236
237
//0x90 - 0x9f
238
{ "bcc", RelativeShort },
239
{ "sta", IDirectY },
240
{ "sta", IDirect },
241
{ "sta", IStackY },
242
243
{ "sty", DirectX },
244
{ "sta", DirectX },
245
{ "stx", DirectY },
246
{ "sta", ILDirectY },
247
248
{ "tya", Implied },
249
{ "sta", AddressY },
250
{ "txs", Implied },
251
{ "txy", Implied },
252
253
{ "stz", Address },
254
{ "sta", AddressX },
255
{ "stz", AddressX },
256
{ "sta", LongX },
257
258
//0xa0 - 0xaf
259
{ "ldy", IndexConstant },
260
{ "lda", IDirectX },
261
{ "ldx", IndexConstant },
262
{ "lda", Stack },
263
264
{ "ldy", Direct },
265
{ "lda", Direct },
266
{ "ldx", Direct },
267
{ "lda", ILDirect },
268
269
{ "tay", Implied },
270
{ "lda", AccumConstant },
271
{ "tax", Implied },
272
{ "plb", Implied },
273
274
{ "ldy", Address },
275
{ "lda", Address },
276
{ "ldx", Address },
277
{ "lda", Long },
278
279
//0xb0 - 0xbf
280
{ "bcs", RelativeShort },
281
{ "lda", IDirectY },
282
{ "lda", IDirect },
283
{ "lda", IStackY },
284
285
{ "ldy", DirectX },
286
{ "lda", DirectX },
287
{ "ldx", DirectY },
288
{ "lda", ILDirectY },
289
290
{ "clv", Implied },
291
{ "lda", AddressY },
292
{ "tsx", Implied },
293
{ "tyx", Implied },
294
295
{ "ldy", AddressX },
296
{ "lda", AddressX },
297
{ "ldx", AddressY },
298
{ "lda", LongX },
299
300
//0xc0 - 0xcf
301
{ "cpy", IndexConstant },
302
{ "cmp", IDirectX },
303
{ "rep", Constant },
304
{ "cmp", Stack },
305
306
{ "cpy", Direct },
307
{ "cmp", Direct },
308
{ "dec", Direct },
309
{ "cmp", ILDirect },
310
311
{ "iny", Implied },
312
{ "cmp", AccumConstant },
313
{ "dex", Implied },
314
{ "wai", Implied },
315
316
{ "cpy", Address },
317
{ "cmp", Address },
318
{ "dec", Address },
319
{ "cmp", Long },
320
321
//0xd0 - 0xdf
322
{ "bne", RelativeShort },
323
{ "cmp", IDirectY },
324
{ "cmp", IDirect },
325
{ "cmp", IStackY },
326
327
{ "pei", IDirect },
328
{ "cmp", DirectX },
329
{ "dec", DirectX },
330
{ "cmp", ILDirectY },
331
332
{ "cld", Implied },
333
{ "cmp", AddressY },
334
{ "phx", Implied },
335
{ "stp", Implied },
336
337
{ "jmp", ILAddress },
338
{ "cmp", AddressX },
339
{ "dec", AddressX },
340
{ "cmp", LongX },
341
342
//0xe0 - 0xef
343
{ "cpx", IndexConstant },
344
{ "sbc", IDirectX },
345
{ "sep", Constant },
346
{ "sbc", Stack },
347
348
{ "cpx", Direct },
349
{ "sbc", Direct },
350
{ "inc", Direct },
351
{ "sbc", ILDirect },
352
353
{ "inx", Implied },
354
{ "sbc", AccumConstant },
355
{ "nop", Implied },
356
{ "xba", Implied },
357
358
{ "cpx", Address },
359
{ "sbc", Address },
360
{ "inc", Address },
361
{ "sbc", Long },
362
363
//0xf0 - 0xff
364
{ "beq", RelativeShort },
365
{ "sbc", IDirectY },
366
{ "sbc", IDirect },
367
{ "sbc", IStackY },
368
369
{ "pea", Address },
370
{ "sbc", DirectX },
371
{ "inc", DirectX },
372
{ "sbc", ILDirectY },
373
374
{ "sed", Implied },
375
{ "sbc", AddressY },
376
{ "plx", Implied },
377
{ "xce", Implied },
378
379
{ "jsr", IAddressX },
380
{ "sbc", AddressX },
381
{ "inc", AddressX },
382
{ "sbc", LongX },
383
};
384
385
inline unsigned SNESCPU::getOpcodeLength(bool accum, bool index, uint8_t opcode) {
386
switch(opcodeInfo[opcode].mode) { default:
387
case Implied: return 1;
388
case Constant: return 2;
389
case AccumConstant: return 3 - accum;
390
case IndexConstant: return 3 - index;
391
case Direct: return 2;
392
case DirectX: return 2;
393
case DirectY: return 2;
394
case IDirect: return 2;
395
case IDirectX: return 2;
396
case IDirectY: return 2;
397
case ILDirect: return 2;
398
case ILDirectY: return 2;
399
case Address: return 3;
400
case AddressX: return 3;
401
case AddressY: return 3;
402
case IAddressX: return 3;
403
case ILAddress: return 3;
404
case PAddress: return 3;
405
case PIAddress: return 3;
406
case Long: return 4;
407
case LongX: return 4;
408
case Stack: return 2;
409
case IStackY: return 2;
410
case BlockMove: return 3;
411
case RelativeShort: return 2;
412
case RelativeLong: return 3;
413
}
414
}
415
416
inline string SNESCPU::disassemble(unsigned pc, bool accum, bool index, uint8_t opcode, uint8_t pl, uint8_t ph, uint8_t pb) {
417
string name = opcodeInfo[opcode].name;
418
unsigned mode = opcodeInfo[opcode].mode;
419
420
if(mode == Implied) return name;
421
if(mode == Constant) return { name, " #$", hex<2>(pl) };
422
if(mode == AccumConstant) return { name, " #$", accum ? "" : hex<2>(ph), hex<2>(pl) };
423
if(mode == IndexConstant) return { name, " #$", index ? "" : hex<2>(ph), hex<2>(pl) };
424
if(mode == Direct) return { name, " $", hex<2>(pl) };
425
if(mode == DirectX) return { name, " $", hex<2>(pl), ",x" };
426
if(mode == DirectY) return { name, " $", hex<2>(pl), ",y" };
427
if(mode == IDirect) return { name, " ($", hex<2>(pl), ")" };
428
if(mode == IDirectX) return { name, " ($", hex<2>(pl), ",x)" };
429
if(mode == IDirectY) return { name, " ($", hex<2>(pl), "),y" };
430
if(mode == ILDirect) return { name, " [$", hex<2>(pl), "]" };
431
if(mode == ILDirectY) return { name, " [$", hex<2>(pl), "],y" };
432
if(mode == Address) return { name, " $", hex<2>(ph), hex<2>(pl) };
433
if(mode == AddressX) return { name, " $", hex<2>(ph), hex<2>(pl), ",x" };
434
if(mode == AddressY) return { name, " $", hex<2>(ph), hex<2>(pl), ",y" };
435
if(mode == IAddressX) return { name, " ($", hex<2>(ph), hex<2>(pl), ",x)" };
436
if(mode == ILAddress) return { name, " [$", hex<2>(ph), hex<2>(pl), "]" };
437
if(mode == PAddress) return { name, " $", hex<2>(ph), hex<2>(pl) };
438
if(mode == PIAddress) return { name, " ($", hex<2>(ph), hex<2>(pl), ")" };
439
if(mode == Long) return { name, " $", hex<2>(pb), hex<2>(ph), hex<2>(pl) };
440
if(mode == LongX) return { name, " $", hex<2>(pb), hex<2>(ph), hex<2>(pl), ",x" };
441
if(mode == Stack) return { name, " $", hex<2>(pl), ",s" };
442
if(mode == IStackY) return { name, " ($", hex<2>(pl), ",s),y" };
443
if(mode == BlockMove) return { name, " $", hex<2>(ph), ",$", hex<2>(pl) };
444
if(mode == RelativeShort) {
445
unsigned addr = (pc + 2) + (int8_t)(pl << 0);
446
return { name, " $", hex<4>(addr) };
447
}
448
if(mode == RelativeLong) {
449
unsigned addr = (pc + 3) + (int16_t)((ph << 8) + (pl << 0));
450
return { name, " $", hex<4>(addr) };
451
}
452
453
return "";
454
}
455
456
}
457
458
#endif
459
460