1 #pragma once
2 
3 #include "common/util.h"
4 
5 namespace Instructions {
6 
7 namespace Instr {
8 enum Type {
9   INVALID,
10   ADC, AND, ASL, BCC, BCS, BEQ, BIT, BMI,
11   BNE, BPL, BRK, BVC, BVS, CLC, CLD, CLI,
12   CLV, CMP, CPX, CPY, DEC, DEX, DEY, EOR,
13   INC, INX, INY, JMP, JSR, LDA, LDX, LDY,
14   LSR, NOP, ORA, PHA, PHP, PLA, PLP, ROL,
15   ROR, RTI, RTS, SBC, SEC, SED, SEI, STA,
16   STX, STY, TAX, TAY, TSX, TXA, TXS, TYA,
17 };
18 }
19 
20 namespace AddrM {
21 enum Type {
22   INVALID,
23   abs_, absX, absY, // Absolute (Indexed)
24   ind_, indY, Xind, // Indirect (Indexed)
25   zpg_, zpgX, zpgY, // Zero Page (Indexed)
26   acc,  // Accumulator
27   imm,  // Immediate
28   impl, // Implied
29   rel,  // Relative
30 };
31 }
32 
33 struct Opcode {
34   u8          raw;    // raw opcode byte
35   Instr::Type instr;  // Instruction Enum
36   AddrM::Type addrm;  // Addressing Mode Enum
37   u8          cycles; // Base cycles
38 
39   bool check_pg_cross; // Should be an extra cycle on page cross?
40 
41   const char* instr_name; // Instruction Name
42   const char* addrm_type; // Addressing Mode Name
43 };
44 
45 // This macro magic makes the Opcode definition list look a lot nicer comapred
46 // to the raw alternative.
47 // Just compare a raw definition to a corresponding macro'd definition:
48 //
49 // raw:   /* 0x11 */ { Instr::ORA , AddrM::indY , 5 , true, "ORA", "indY" }
50 // macro: O( 0x11 , ORA , ind_ , 5 , * )
51 //
52 // PS: isn't it neat that I can use a * as a flag? pretty wicked imho
53 
54 #include "common/overload_macro.h"
55 #define O(...) VFUNC(O, __VA_ARGS__)
56 
57 // Defines a invalid Opcode
58 #define O1(opcode) \
59   { opcode, Instr::INVALID , AddrM::INVALID , 0 , false , "KIL" , "----" }
60 
61 // Defines a regular Opcode
62 #define O4(opcode, instr, addrm, cycles) \
63   { opcode, Instr:: instr , AddrM:: addrm , cycles , false , #instr, #addrm }
64 
65 // Defines a Opcode that takes 1 extra cycle when reading memory across pages
66 #define O5(opcode, instr, addrm, cycles, page_cross) \
67   { opcode, Instr:: instr , AddrM:: addrm , cycles , true  , #instr, #addrm }
68 
69 // Main Opcode lookup table
70 constexpr Opcode Opcodes[256] = {
71 O( 0x00 , BRK , impl , 0     ), // call to CPU::service_interrupt takes 7 cycles
72 O( 0x01 , ORA , Xind , 6     ),
73 O( 0x02                      ),
74 O( 0x03                      ),
75 O( 0x04                      ),
76 O( 0x05 , ORA , zpg_ , 3     ),
77 O( 0x06 , ASL , zpg_ , 5     ),
78 O( 0x07                      ),
79 O( 0x08 , PHP , impl , 3     ),
80 O( 0x09 , ORA , imm  , 2     ),
81 O( 0x0A , ASL , acc  , 2     ),
82 O( 0x0B                      ),
83 O( 0x0C                      ),
84 O( 0x0D , ORA , abs_ , 4     ),
85 O( 0x0E , ASL , abs_ , 6     ),
86 O( 0x0F                      ),
87 O( 0x10 , BPL , rel  , 2     ),
88 O( 0x11 , ORA , indY , 5 , * ),
89 O( 0x12                      ),
90 O( 0x13                      ),
91 O( 0x14                      ),
92 O( 0x15 , ORA , zpgX , 4     ),
93 O( 0x16 , ASL , zpgX , 6     ),
94 O( 0x17                      ),
95 O( 0x18 , CLC , impl , 2     ),
96 O( 0x19 , ORA , absY , 4 , * ),
97 O( 0x1A                      ),
98 O( 0x1B                      ),
99 O( 0x1C                      ),
100 O( 0x1D , ORA , absX , 4 , * ),
101 O( 0x1E , ASL , absX , 7     ),
102 O( 0x1F                      ),
103 O( 0x20 , JSR , abs_ , 6     ),
104 O( 0x21 , AND , Xind,  6     ),
105 O( 0x22                      ),
106 O( 0x23                      ),
107 O( 0x24 , BIT , zpg_ , 3     ),
108 O( 0x25 , AND , zpg_ , 3     ),
109 O( 0x26 , ROL , zpg_ , 5     ),
110 O( 0x27                      ),
111 O( 0x28 , PLP , impl , 4     ),
112 O( 0x29 , AND , imm  , 2     ),
113 O( 0x2A , ROL , acc  , 2     ),
114 O( 0x2B                      ),
115 O( 0x2C , BIT , abs_ , 4     ),
116 O( 0x2D , AND , abs_ , 4     ),
117 O( 0x2E , ROL , abs_ , 6     ),
118 O( 0x2F                      ),
119 O( 0x30 , BMI , rel  , 2     ),
120 O( 0x31 , AND , indY , 5 , * ),
121 O( 0x32                      ),
122 O( 0x33                      ),
123 O( 0x34                      ),
124 O( 0x35 , AND , zpgX , 4     ),
125 O( 0x36 , ROL , zpgX , 6     ),
126 O( 0x37                      ),
127 O( 0x38 , SEC , impl , 2     ),
128 O( 0x39 , AND , absY , 4 , * ),
129 O( 0x3A                      ),
130 O( 0x3B                      ),
131 O( 0x3C                      ),
132 O( 0x3D , AND , absX , 4 , * ),
133 O( 0x3E , ROL , absX , 7     ),
134 O( 0x3F                      ),
135 O( 0x40 , RTI , impl , 6     ),
136 O( 0x41 , EOR , Xind,  6     ),
137 O( 0x42                      ),
138 O( 0x43                      ),
139 O( 0x44                      ),
140 O( 0x45 , EOR , zpg_ , 3     ),
141 O( 0x46 , LSR , zpg_ , 5     ),
142 O( 0x47                      ),
143 O( 0x48 , PHA , impl , 3     ),
144 O( 0x49 , EOR , imm  , 2     ),
145 O( 0x4A , LSR , acc  , 2     ),
146 O( 0x4B                      ),
147 O( 0x4C , JMP , abs_ , 3     ),
148 O( 0x4D , EOR , abs_ , 4     ),
149 O( 0x4E , LSR , abs_ , 6     ),
150 O( 0x4F                      ),
151 O( 0x50 , BVC , rel  , 2     ),
152 O( 0x51 , EOR , indY , 5 , * ),
153 O( 0x52                      ),
154 O( 0x53                      ),
155 O( 0x54                      ),
156 O( 0x55 , EOR , zpgX , 4     ),
157 O( 0x56 , LSR , zpgX , 6     ),
158 O( 0x57                      ),
159 O( 0x58 , CLI , impl , 2     ),
160 O( 0x59 , EOR , absY , 4 , * ),
161 O( 0x5A                      ),
162 O( 0x5B                      ),
163 O( 0x5C                      ),
164 O( 0x5D , EOR , absX , 4 , * ),
165 O( 0x5E , LSR , absX , 7     ),
166 O( 0x5F                      ),
167 O( 0x60 , RTS , impl , 6     ),
168 O( 0x61 , ADC , Xind,  6     ),
169 O( 0x62                      ),
170 O( 0x63                      ),
171 O( 0x64                      ),
172 O( 0x65 , ADC , zpg_ , 3     ),
173 O( 0x66 , ROR , zpg_ , 5     ),
174 O( 0x67                      ),
175 O( 0x68 , PLA , impl , 4     ),
176 O( 0x69 , ADC , imm  , 2     ),
177 O( 0x6A , ROR , acc  , 2     ),
178 O( 0x6B                      ),
179 O( 0x6C , JMP , ind_,  5     ),
180 O( 0x6D , ADC , abs_ , 4     ),
181 O( 0x6E , ROR , abs_ , 6     ),
182 O( 0x6F                      ),
183 O( 0x70 , BVS , rel  , 2     ),
184 O( 0x71 , ADC , indY , 5 , * ),
185 O( 0x72                      ),
186 O( 0x73                      ),
187 O( 0x74                      ),
188 O( 0x75 , ADC , zpgX , 4     ),
189 O( 0x76 , ROR , zpgX , 6     ),
190 O( 0x77                      ),
191 O( 0x78 , SEI , impl , 2     ),
192 O( 0x79 , ADC , absY , 4 , * ),
193 O( 0x7A                      ),
194 O( 0x7B                      ),
195 O( 0x7C                      ),
196 O( 0x7D , ADC , absX , 4 , * ),
197 O( 0x7E , ROR , absX , 7     ),
198 O( 0x7F                      ),
199 O( 0x80                      ),
200 O( 0x81 , STA , Xind,  6     ),
201 O( 0x82                      ),
202 O( 0x83                      ),
203 O( 0x84 , STY , zpg_ , 3     ),
204 O( 0x85 , STA , zpg_ , 3     ),
205 O( 0x86 , STX , zpg_ , 3     ),
206 O( 0x87                      ),
207 O( 0x88 , DEY , impl , 2     ),
208 O( 0x89                      ),
209 O( 0x8A , TXA , impl , 2     ),
210 O( 0x8B                      ),
211 O( 0x8C , STY , abs_ , 4     ),
212 O( 0x8D , STA , abs_ , 4     ),
213 O( 0x8E , STX , abs_ , 4     ),
214 O( 0x8F                      ),
215 O( 0x90 , BCC , rel  , 2     ),
216 O( 0x91 , STA , indY , 6     ),
217 O( 0x92                      ),
218 O( 0x93                      ),
219 O( 0x94 , STY , zpgX , 4     ),
220 O( 0x95 , STA , zpgX , 4     ),
221 O( 0x96 , STX , zpgY , 4     ),
222 O( 0x97                      ),
223 O( 0x98 , TYA , impl , 2     ),
224 O( 0x99 , STA , absY , 5     ),
225 O( 0x9A , TXS , impl , 2     ),
226 O( 0x9B                      ),
227 O( 0x9C                      ),
228 O( 0x9D , STA , absX , 5     ),
229 O( 0x9E                      ),
230 O( 0x9F                      ),
231 O( 0xA0 , LDY , imm  , 2     ),
232 O( 0xA1 , LDA , Xind,  6     ),
233 O( 0xA2 , LDX , imm  , 2     ),
234 O( 0xA3                      ),
235 O( 0xA4 , LDY , zpg_ , 3     ),
236 O( 0xA5 , LDA , zpg_ , 3     ),
237 O( 0xA6 , LDX , zpg_ , 3     ),
238 O( 0xA7                      ),
239 O( 0xA8 , TAY , impl , 2     ),
240 O( 0xA9 , LDA , imm  , 2     ),
241 O( 0xAA , TAX , impl , 2     ),
242 O( 0xAB                      ),
243 O( 0xAC , LDY , abs_ , 4     ),
244 O( 0xAD , LDA , abs_ , 4     ),
245 O( 0xAE , LDX , abs_ , 4     ),
246 O( 0xAF                      ),
247 O( 0xB0 , BCS , rel  , 2     ),
248 O( 0xB1 , LDA , indY , 5 , * ),
249 O( 0xB2                      ),
250 O( 0xB3                      ),
251 O( 0xB4 , LDY , zpgX , 4     ),
252 O( 0xB5 , LDA , zpgX , 4     ),
253 O( 0xB6 , LDX , zpgY , 4     ),
254 O( 0xB7                      ),
255 O( 0xB8 , CLV , impl , 2     ),
256 O( 0xB9 , LDA , absY , 4 , * ),
257 O( 0xBA , TSX , impl , 2     ),
258 O( 0xBB                      ),
259 O( 0xBC , LDY , absX , 4 , * ),
260 O( 0xBD , LDA , absX , 4 , * ),
261 O( 0xBE , LDX , absY , 4 , * ),
262 O( 0xBF                      ),
263 O( 0xC0 , CPY , imm  , 2     ),
264 O( 0xC1 , CMP , Xind,  6     ),
265 O( 0xC2                      ),
266 O( 0xC3                      ),
267 O( 0xC4 , CPY , zpg_ , 3     ),
268 O( 0xC5 , CMP , zpg_ , 3     ),
269 O( 0xC6 , DEC , zpg_ , 5     ),
270 O( 0xC7                      ),
271 O( 0xC8 , INY , impl , 2     ),
272 O( 0xC9 , CMP , imm  , 2     ),
273 O( 0xCA , DEX , impl , 2     ),
274 O( 0xCB                      ),
275 O( 0xCC , CPY , abs_ , 4     ),
276 O( 0xCD , CMP , abs_ , 4     ),
277 O( 0xCE , DEC , abs_ , 6     ),
278 O( 0xCF                      ),
279 O( 0xD0 , BNE , rel  , 2     ),
280 O( 0xD1 , CMP , indY , 5 , * ),
281 O( 0xD2                      ),
282 O( 0xD3                      ),
283 O( 0xD4                      ),
284 O( 0xD5 , CMP , zpgX , 4     ),
285 O( 0xD6 , DEC , zpgX , 6     ),
286 O( 0xD7                      ),
287 O( 0xD8 , CLD , impl , 2     ),
288 O( 0xD9 , CMP , absY , 4 , * ),
289 O( 0xDA                      ),
290 O( 0xDB                      ),
291 O( 0xDC                      ),
292 O( 0xDD , CMP , absX , 4 , * ),
293 O( 0xDE , DEC , absX , 7     ),
294 O( 0xDF                      ),
295 O( 0xE0 , CPX , imm  , 2     ),
296 O( 0xE1 , SBC , Xind,  6     ),
297 O( 0xE2                      ),
298 O( 0xE3                      ),
299 O( 0xE4 , CPX , zpg_ , 3     ),
300 O( 0xE5 , SBC , zpg_ , 3     ),
301 O( 0xE6 , INC , zpg_ , 5     ),
302 O( 0xE7                      ),
303 O( 0xE8 , INX , impl , 2     ),
304 O( 0xE9 , SBC , imm  , 2     ),
305 O( 0xEA , NOP , impl , 2     ),
306 O( 0xEB                      ),
307 O( 0xEC , CPX , abs_ , 4     ),
308 O( 0xED , SBC , abs_ , 4     ),
309 O( 0xEE , INC , abs_ , 6     ),
310 O( 0xEF                      ),
311 O( 0xF0 , BEQ , rel  , 2     ),
312 O( 0xF1 , SBC , indY , 5 , * ),
313 O( 0xF2                      ),
314 O( 0xF3                      ),
315 O( 0xF4                      ),
316 O( 0xF5 , SBC , zpgX , 4     ),
317 O( 0xF6 , INC , zpgX , 6     ),
318 O( 0xF7                      ),
319 O( 0xF8 , SED , impl , 2     ),
320 O( 0xF9 , SBC , absY , 4 , * ),
321 O( 0xFA                      ),
322 O( 0xFB                      ),
323 O( 0xFC                      ),
324 O( 0xFD , SBC , absX , 4 , * ),
325 O( 0xFE , INC , absX , 7     ),
326 O( 0xFF                      ),
327 };
328 
329 } // Instructions
330