-
Notifications
You must be signed in to change notification settings - Fork 0
/
MosHeader.h
450 lines (401 loc) · 16.5 KB
/
MosHeader.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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
/*
* Source code wrote by Gabriel Correia
*/
#pragma once
#include <array>
#include <string_view>
#include <cstdint>
#include <cstdarg>
#include <fmt/core.h>
/* Set to 1 to enable callback functions */
#define USE_6502_CALLBACKS 1
/* Set to 1 to enable the internal ram memory (You won't need to provide one into the constructor) */
#define USE_INTERNAL_RAM 0
constexpr uint16_t
/* The start address location for the stack pointer, the stack will grow from 0x1ff to 0x100 */
START_STACK_ADDRESS = 0x1ff,
/* The base stack address */
BASE_STACK_ADDRESS = 0x100,
/* Default max RAM size (can be change normally by the developer) */
/* Using only 2KiB of memory (Nothing more) */
MAX_RAM_STORAGE = 0x800,
/* Max rom storage */
MAX_ROM_STORAGE = 0xffff - MAX_RAM_STORAGE;
/* The count of official 6502 instructions count */
constexpr unsigned CPU_6502_INSTRUCTION_COUNT = 151;
/* The status after the reset signal */
constexpr uint8_t RESET_STATUS_SIGNAL = 0xfb;
enum class IVT_index
{
ABORT, COP, IRQ_BRK, NMI, RESET
};
enum class CPU_status
{
CARRY, ZERO, IRQ, DECIMAL, BRK, OVERFLOW, NEGATIVE
};
enum class CPU_content
{
REG_A, REG_X, REG_Y, PC, SP, DATA, ADDRESS
};
constexpr uint16_t INTERRUPT_VECTOR_TABLE[5][2] = {
/* ABORT */
{0xfff8, 0xfff9},
/* COP (UNUSED) */
{0xfff4, 0xfff5},
/* IRQ AND BRK */
{0xfffe, 0xffff},
/* NMI REQUEST */
{0xfffa, 0xfffb},
/* RESET */
{0xfffc, 0xfffd}
};
/*
6502 Memory layout
[END ROM]
[0xffff]
|INT VECTORS|
[0xfff4]
|ROM MEMORY]
[0x7fff]
|MAIN RAM|
[0x01ff]
|STACK|
[0x0100]
|ZERO PAGE|
[0x0000]
*/
#if USE_6502_CALLBACKS
typedef uint8_t (*cpu_read) (uint16_t);
typedef void (*cpu_write) (uint16_t, uint8_t);
#endif
class cpu6502
{
public:
#if USE_6502_CALLBACKS
cpu6502(cpu_read read_function, cpu_write write_function);
#else
cpu6502(uint8_t *ram, uint8_t *rom);
#endif
~cpu6502() = default;
void reset();
void printcs();
/* Interrupt request functions */
void nmi();
void irq();
/* ABORT is raised when an invalid opcode has been detected */
void abort();
/* Execute cycles_count cycles */
std::pair<size_t, size_t> clock(size_t cycles_count, size_t &executed_cycles);
size_t step(size_t &executed_cycles);
std::pair<size_t, size_t> step_count(size_t cycles_count, size_t &executed_cycles);
/* Processor status manipulation functions */
bool getf(const CPU_status status) const;
void setf(const CPU_status status, const bool state);
/* Some get functions, commoly used into unit test code section */
auto get_register_a() const{ return m_a; }
auto get_register_x() const { return m_x; }
auto get_register_y() const { return m_y; }
auto get_register_pc() const { return m_pc; }
auto get_register_s() const { return m_s; }
auto get_last_fetched_data() const { return m_data; }
auto get_last_acceded_address() const { return m_address; }
private:
/* Functions and variables used in the read/write data operations */
/* This variables will be used to read and write into the memory (a read operation will store the result
* in 2 bytes, a write operation will perform a AND with 0x00ff and a cast for uint8_t before wrote the data)
*/
uint16_t m_data{};
uint16_t m_address{};
#if USE_6502_CALLBACKS
#else
constexpr uint8_t* select_memory(const uint16_t address) const
{
uint8_t *memory{};
if (address < MAX_RAM_STORAGE)
memory = m_ram;
else
memory = m_rom;
return memory;
}
#endif
uint8_t make_branch(const bool condition)
{
uint16_t branch_address;
read_memory8();
if (condition)
{
branch_address = m_pc + ((int8_t)m_data);
m_pc = branch_address;
}
return check_pages(branch_address, m_pc) + 1;
}
/* CPU read/write operations (8 and 16 bit ranges are implemented) */
void read_memory16();
void read_memory8();
void write_memory8();
void write_memory16();
#if USE_6502_CALLBACKS
cpu_read m_cpu_read_function{};
cpu_write m_cpu_write_function{};
#endif
bool check_pages(const uint16_t first, const uint16_t second)
{
/* 0x`00´ff ONE PAGE */
/* 0x`01´00 ANOTHER PAGE */
if ((first & 0xff00) != (second & 0xff00))
return true;
return false;
}
void push8()
{
m_address = --m_s | BASE_STACK_ADDRESS;
/* "Allocating" memory into the stack */
/* Writting data into it */
write_memory8();
}
void push16()
{
push8();
m_data >>= 8;
push8();
}
void pop8()
{
/* Pop an 8 bit value from the stack */
m_address = m_s++ | BASE_STACK_ADDRESS;
read_memory8();
}
void pop16()
{
m_address = m_s++;
read_memory16();
m_s++;
}
/* General purposes registers */
uint8_t m_a{}, m_x{}, m_y{};
#if USE_6502_CALLBACKS
#else
#if USE_INTERNAL_RAM
std::array<uint8_t, MAX_RAM_STORAGE> m_ram;
#else
uint8_t *m_ram{};
#endif
uint8_t *m_rom{};
#endif
/* CPU status register */
union
{
struct
{
unsigned carry: 1;
unsigned zero: 1;
unsigned irq: 1;
unsigned decimal: 1;
unsigned brk: 1;
unsigned reserved: 1;
unsigned overflow: 1;
unsigned negative: 1;
};
uint8_t status;
} m_p{};
/* Stack pointer register */
uint8_t m_s{};
/* PC (The program counter) the dual register used to pointer to the next operation to be executed by the CPU */
uint16_t m_pc{};
/* All cycles wasted will be stored into this variable */
uint64_t m_cycles_wasted{};
/* Skip N cycles, this ability is used into emulators/simulators env */
uint16_t m_skip_cycles{};
/* A specific status for determine if the instruction will use the accumulator register
* as operand or not
*/
bool m_use_accumulator{};
/* Setted if the current operation can promove a cross a page */
bool m_can_page_cross{};
/* Helper functions with the addressing processor specs */
typedef void (cpu6502::*loadaddr_t)();
loadaddr_t m_load_address{};
#pragma region
/* Instruction operations */
uint8_t cpu_adc();
uint8_t cpu_and();
uint8_t cpu_asl();
uint8_t cpu_bcc();
uint8_t cpu_bcs();
uint8_t cpu_beq();
uint8_t cpu_bit();
uint8_t cpu_bmi();
uint8_t cpu_bne();
uint8_t cpu_bpl();
uint8_t cpu_brk();
uint8_t cpu_bvc();
uint8_t cpu_bvs();
uint8_t cpu_clc();
uint8_t cpu_cld();
uint8_t cpu_cli();
uint8_t cpu_clv();
uint8_t cpu_cmp();
uint8_t cpu_cpx();
uint8_t cpu_cpy();
uint8_t cpu_dec();
uint8_t cpu_dex();
uint8_t cpu_dey();
uint8_t cpu_eor();
uint8_t cpu_inc();
uint8_t cpu_inx();
uint8_t cpu_iny();
uint8_t cpu_jmp();
uint8_t cpu_jsr();
uint8_t cpu_lda();
uint8_t cpu_ldx();
uint8_t cpu_ldy();
uint8_t cpu_lsr();
uint8_t cpu_nop();
uint8_t cpu_ora();
uint8_t cpu_pha();
uint8_t cpu_php();
uint8_t cpu_pla();
uint8_t cpu_plp();
uint8_t cpu_rol();
uint8_t cpu_ror();
uint8_t cpu_rti();
uint8_t cpu_rts();
uint8_t cpu_sbc();
uint8_t cpu_sec();
uint8_t cpu_sed();
uint8_t cpu_sei();
uint8_t cpu_sta();
uint8_t cpu_stx();
uint8_t cpu_sty();
uint8_t cpu_tax();
uint8_t cpu_tay();
uint8_t cpu_tsx();
uint8_t cpu_txa();
uint8_t cpu_txs();
uint8_t cpu_tya();
/* Addressing modes operations */
void mem_none();
void mem_a();
void mem_abs();
void mem_absx();
void mem_absy();
void mem_imm();
void mem_impl();
void mem_ind();
void mem_indx();
void mem_indy();
void mem_rel();
void mem_zp();
void mem_zpx();
void mem_zpy();
#pragma endregion "CPU instructions definition"
#pragma region
typedef struct opcode_info_st
{
/* Referenced function to be executed */
uint8_t (cpu6502::* instruction)();
/* The addressing mode needed to be performed until the operation call */
void (cpu6502::* addressing)();
/* The count of cycles wasted to execute the current instruction */
uint8_t cycles_wasted;
/* The switch to advice the CPU that the current instruction can extrapolate the wasted cycles */
uint8_t can_exceeded;
/* The count of bytes consumed inside all operation */
uint8_t bytes_consumed;
} opcode_info_t;
using cpu = cpu6502;
std::array<opcode_info_t, 0x100> const
m_cpu_isa {{
{&cpu::cpu_brk, &cpu::mem_impl, 7, 0, 1}, {&cpu::cpu_ora, &cpu::mem_indx, 6, 0, 2}, {}, {}, {},
{&cpu::cpu_ora, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_asl, &cpu::mem_zpx, 5, 0, 2}, {},
{&cpu::cpu_php, &cpu::mem_impl, 3, 0, 1}, {&cpu::cpu_ora, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_asl, &cpu::mem_a, 2, 0, 1}, {}, {},
{&cpu::cpu_ora, &cpu::mem_abs, 4, 0, 3}, {&cpu::cpu_asl, &cpu::mem_abs, 6, 0, 3}, {},
{&cpu::cpu_bpl, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_ora, &cpu::mem_indy, 5, 0, 2}, {}, {}, {},
{&cpu::cpu_ora, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_asl, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_clc, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_ora, &cpu::mem_absy, 4, 1, 3}, {}, {}, {},
{&cpu::cpu_ora, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_asl, &cpu::mem_absx, 7, 0, 3}, {},
{&cpu::cpu_jsr, &cpu::mem_abs, 6, 0, 3}, {&cpu::cpu_and, &cpu::mem_indx, 6, 0, 2}, {}, {},
{&cpu::cpu_bit, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_and, &cpu::mem_zp, 3, 0, 2},
{&cpu::cpu_rol, &cpu::mem_zp, 5, 0, 2}, {},
{&cpu::cpu_plp, &cpu::mem_impl, 4, 0, 1}, {&cpu::cpu_and, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_rol, &cpu::mem_a, 2, 0, 1}, {},
{&cpu::cpu_bit, &cpu::mem_abs, 4, 0, 3}, {&cpu::cpu_and, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_rol, &cpu::mem_abs, 6, 0, 3}, {},
{&cpu::cpu_bmi, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_and, &cpu::mem_indy, 5, 1, 2}, {}, {}, {},
{&cpu::cpu_and, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_rol, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_sec, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_and, &cpu::mem_absy, 5, 1, 2}, {}, {}, {},
{&cpu::cpu_and, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_rol, &cpu::mem_absx, 7, 0, 3}, {},
{&cpu::cpu_rti, &cpu::mem_impl, 6, 0, 1}, {&cpu::cpu_eor, &cpu::mem_indx, 6, 0, 2}, {}, {}, {},
{&cpu::cpu_eor, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_lsr, &cpu::mem_zp, 5, 0, 2}, {},
{&cpu::cpu_pha, &cpu::mem_impl, 3, 0, 1}, {&cpu::cpu_eor, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_lsr, &cpu::mem_a, 2, 0, 1}, {},
{&cpu::cpu_jmp, &cpu::mem_abs, 3, 0, 3}, {&cpu::cpu_eor, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_lsr, &cpu::mem_abs, 6, 0, 3}, {},
{&cpu::cpu_bvc, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_eor, &cpu::mem_indy, 5, 1, 2}, {}, {}, {},
{&cpu::cpu_eor, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_lsr, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_cli, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_eor, &cpu::mem_absy, 4, 1, 3}, {}, {}, {},
{&cpu::cpu_eor, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_lsr, &cpu::mem_absx, 7, 0, 3}, {},
{&cpu::cpu_rts, &cpu::mem_impl, 6, 0, 1}, {&cpu::cpu_adc, &cpu::mem_indx, 6, 0, 2}, {}, {}, {},
{&cpu::cpu_adc, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_ror, &cpu::mem_zp, 5, 0, 2}, {},
{&cpu::cpu_pla, &cpu::mem_impl, 4, 0, 1}, {&cpu::cpu_adc, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_ror, &cpu::mem_a, 2, 0, 1}, {},
{&cpu::cpu_jmp, &cpu::mem_ind, 5, 0, 3}, {&cpu::cpu_adc, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_ror, &cpu::mem_abs, 6, 0, 3}, {},
{&cpu::cpu_bvs, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_adc, &cpu::mem_indy, 5, 1, 2}, {}, {}, {},
{&cpu::cpu_adc, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_ror, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_sei, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_adc, &cpu::mem_absy, 4, 1, 3}, {}, {}, {},
{&cpu::cpu_adc, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_ror, &cpu::mem_absx, 7, 0, 3}, {}, {},
{&cpu::cpu_sta, &cpu::mem_indx, 6, 0, 2}, {}, {},
{&cpu::cpu_sty, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_sta, &cpu::mem_zp, 3, 0, 2},
{&cpu::cpu_stx, &cpu::mem_zp, 3, 0, 2}, {},
{&cpu::cpu_dey, &cpu::mem_impl, 2, 0, 1}, {},
{&cpu::cpu_tax, &cpu::mem_impl, 2, 0, 1}, {},
{&cpu::cpu_sty, &cpu::mem_abs, 4, 0, 3}, {&cpu::cpu_sta, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_stx, &cpu::mem_zp, 3, 0, 2}, {},
{&cpu::cpu_bcc, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_sta, &cpu::mem_indy, 6, 0, 2}, {}, {},
{&cpu::cpu_sty, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_sta, &cpu::mem_absx, 5, 0, 3},
{&cpu::cpu_stx, &cpu::mem_zpy, 4, 0, 2}, {},
{&cpu::cpu_tya, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_sta, &cpu::mem_absy, 5, 0, 3},
{&cpu::cpu_txs, &cpu::mem_impl, 2, 0, 1}, {}, {},
{&cpu::cpu_sta, &cpu::mem_absx, 5, 0, 3}, {}, {},
{&cpu::cpu_ldy, &cpu::mem_imm, 2, 0, 2}, {&cpu::cpu_lda, &cpu::mem_indx, 6, 0, 2},
{&cpu::cpu_ldx, &cpu::mem_imm, 2, 0, 2}, {},
{&cpu::cpu_ldy, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_lda, &cpu::mem_zp, 3, 0, 2},
{&cpu::cpu_ldx, &cpu::mem_zp, 3, 0, 2}, {},
{&cpu::cpu_tay, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_lda, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_tax, &cpu::mem_impl, 2, 0, 1}, {},
{&cpu::cpu_ldy, &cpu::mem_abs, 4, 0, 3}, {&cpu::cpu_lda, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_ldx, &cpu::mem_abs, 4, 0, 3}, {},
{&cpu::cpu_bcs, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_lda, &cpu::mem_indy, 5, 1, 2}, {}, {},
{&cpu::cpu_ldy, &cpu::mem_zp, 4, 0, 2}, {&cpu::cpu_lda, &cpu::mem_zpx, 4, 0, 2},
{&cpu::cpu_lda, &cpu::mem_zpy, 4, 0, 2}, {},
{&cpu::cpu_clv, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_lda, &cpu::mem_absy, 4, 1, 3},
{&cpu::cpu_tsx, &cpu::mem_impl, 2, 0, 1}, {},
{&cpu::cpu_ldy, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_lda, &cpu::mem_absx, 4, 1, 3},
{&cpu::cpu_ldx, &cpu::mem_absy, 4, 1, 3}, {},
{&cpu::cpu_cpy, &cpu::mem_imm, 2, 0, 2}, {&cpu::cpu_cmp, &cpu::mem_indx, 6, 0, 2}, {}, {},
{&cpu::cpu_cpy, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_cmp, &cpu::mem_zp, 3, 0, 2},
{&cpu::cpu_dec, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_iny, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_cmp, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_dex, &cpu::mem_impl, 2, 0, 1}, {},
{&cpu::cpu_cpy, &cpu::mem_abs, 4, 0, 3}, {&cpu::cpu_cmp, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_dec, &cpu::mem_abs, 6, 0, 3}, {},
{&cpu::cpu_bne, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_cmp, &cpu::mem_indy, 5, 1, 2}, {}, {}, {},
{&cpu::cpu_cmp, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_dec, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_cld, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_cmp, &cpu::mem_absy, 4, 1, 3}, {}, {}, {},
{&cpu::cpu_cmp, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_dec, &cpu::mem_absx, 7, 0, 3}, {},
{&cpu::cpu_cpx, &cpu::mem_imm, 2, 0, 2}, {&cpu::cpu_sbc, &cpu::mem_indx, 6, 0, 2}, {}, {},
{&cpu::cpu_cpx, &cpu::mem_zp, 3, 0, 2}, {&cpu::cpu_sbc, &cpu::mem_zp, 3, 0, 2},
{&cpu::cpu_inc, &cpu::mem_zp, 5, 0, 2}, {},
{&cpu::cpu_inx, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_sbc, &cpu::mem_imm, 2, 0, 2},
{&cpu::cpu_nop, &cpu::mem_impl, 2, 0, 1}, {},
{&cpu::cpu_cpx, &cpu::mem_abs, 4, 0, 3}, {&cpu::cpu_sbc, &cpu::mem_abs, 4, 0, 3},
{&cpu::cpu_inc, &cpu::mem_abs, 6, 0, 3}, {},
{&cpu::cpu_beq, &cpu::mem_rel, 2, 1, 2}, {&cpu::cpu_sbc, &cpu::mem_indy, 5, 1, 2}, {}, {}, {},
{&cpu::cpu_sbc, &cpu::mem_zpx, 4, 0, 2}, {&cpu::cpu_inc, &cpu::mem_zpx, 6, 0, 2}, {},
{&cpu::cpu_sed, &cpu::mem_impl, 2, 0, 1}, {&cpu::cpu_sbc, &cpu::mem_absy, 4, 1, 3}, {}, {}, {},
{&cpu::cpu_sbc, &cpu::mem_absx, 4, 1, 3}, {&cpu::cpu_inc, &cpu::mem_absx, 7, 0, 3}, {}
}};
#pragma endregion "Opcodes table"
};