release r2, update credits
[fceu.git] / ops.h
1 /* FCE Ultra - NES/Famicom Emulator\r
2  *\r
3  * Copyright notice for this file:\r
4  *  Copyright (C) 2002 Xodnizel\r
5  *\r
6  * This program is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * This program is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  */\r
20 \r
21 case 0x00:  /* BRK */\r
22             _PC++;\r
23             PUSH(_PC>>8);\r
24             PUSH(_PC);\r
25             PUSH(_P|U_FLAG|B_FLAG);\r
26             _P|=I_FLAG;\r
27             _PI|=I_FLAG;\r
28             _PC=RdMem(0xFFFE);\r
29             _PC|=RdMem(0xFFFF)<<8;\r
30             break;\r
31 \r
32 case 0x40:  /* RTI */\r
33             _P=POP();\r
34             /* _PI=_P; This is probably incorrect, so it's commented out. */\r
35             _PI = _P;\r
36             _PC=POP();\r
37             _PC|=POP()<<8;\r
38             break;\r
39             \r
40 case 0x60:  /* RTS */\r
41             _PC=POP();\r
42             _PC|=POP()<<8;\r
43             _PC++;\r
44             break;\r
45 \r
46 case 0x48: /* PHA */\r
47            PUSH(_A);\r
48            break;\r
49 case 0x08: /* PHP */\r
50            PUSH(_P|U_FLAG|B_FLAG);\r
51            break;\r
52 case 0x68: /* PLA */\r
53            _A=POP();\r
54            X_ZN(_A);\r
55            break;\r
56 case 0x28: /* PLP */\r
57            _P=POP();\r
58            break;\r
59 case 0x4C:\r
60           {\r
61            uint16 ptmp=_PC;\r
62            unsigned int npc;\r
63 \r
64            npc=RdMem(ptmp);\r
65            ptmp++;\r
66            npc|=RdMem(ptmp)<<8;\r
67            _PC=npc;\r
68           }\r
69           break; /* JMP ABSOLUTE */\r
70 case 0x6C: \r
71            {\r
72             uint32 tmp;\r
73             GetAB(tmp);\r
74             _PC=RdMem(tmp);\r
75             _PC|=RdMem( ((tmp+1)&0x00FF) | (tmp&0xFF00))<<8;\r
76            }\r
77            break;\r
78 case 0x20: /* JSR */\r
79            {\r
80             uint8 npc;\r
81             npc=RdMem(_PC);\r
82             _PC++;\r
83             PUSH(_PC>>8);\r
84             PUSH(_PC);\r
85             _PC=RdMem(_PC)<<8;\r
86             _PC|=npc;\r
87            }\r
88            break;\r
89 \r
90 case 0xAA: /* TAX */\r
91            _X=_A;\r
92            X_ZN(_A);\r
93            break;\r
94 \r
95 case 0x8A: /* TXA */\r
96            _A=_X;\r
97            X_ZN(_A);\r
98            break;\r
99 \r
100 case 0xA8: /* TAY */\r
101            _Y=_A;\r
102            X_ZN(_A);\r
103            break;\r
104 case 0x98: /* TYA */\r
105            _A=_Y;\r
106            X_ZN(_A);\r
107            break;\r
108 \r
109 case 0xBA: /* TSX */\r
110            _X=_S;\r
111            X_ZN(_X);\r
112            break;\r
113 case 0x9A: /* TXS */\r
114            _S=_X;\r
115            break;\r
116 \r
117 case 0xCA: /* DEX */\r
118            _X--;\r
119            X_ZN(_X);\r
120            break;\r
121 case 0x88: /* DEY */\r
122            _Y--;\r
123            X_ZN(_Y);\r
124            break;\r
125 \r
126 case 0xE8: /* INX */\r
127            _X++;\r
128            X_ZN(_X);\r
129            break;\r
130 case 0xC8: /* INY */\r
131            _Y++;\r
132            X_ZN(_Y);\r
133            break;\r
134 \r
135 case 0x18: /* CLC */\r
136            _P&=~C_FLAG;\r
137            break;\r
138 case 0xD8: /* CLD */\r
139            _P&=~D_FLAG;\r
140            break;\r
141 case 0x58: /* CLI */\r
142            _P&=~I_FLAG;\r
143            break;\r
144 case 0xB8: /* CLV */\r
145            _P&=~V_FLAG;\r
146            break;\r
147 \r
148 case 0x38: /* SEC */\r
149            _P|=C_FLAG;\r
150            break;\r
151 case 0xF8: /* SED */\r
152            _P|=D_FLAG;\r
153            break;\r
154 case 0x78: /* SEI */\r
155            _P|=I_FLAG;\r
156            break;\r
157 \r
158 case 0xEA: /* NOP */\r
159            break;\r
160 \r
161 case 0x0A: RMW_A(ASL);\r
162 case 0x06: RMW_ZP(ASL);\r
163 case 0x16: RMW_ZPX(ASL);\r
164 case 0x0E: RMW_AB(ASL);\r
165 case 0x1E: RMW_ABX(ASL);\r
166 \r
167 case 0xC6: RMW_ZP(DEC);\r
168 case 0xD6: RMW_ZPX(DEC);\r
169 case 0xCE: RMW_AB(DEC);\r
170 case 0xDE: RMW_ABX(DEC);\r
171 \r
172 case 0xE6: RMW_ZP(INC);\r
173 case 0xF6: RMW_ZPX(INC);\r
174 case 0xEE: RMW_AB(INC);\r
175 case 0xFE: RMW_ABX(INC);\r
176 \r
177 case 0x4A: RMW_A(LSR);\r
178 case 0x46: RMW_ZP(LSR);\r
179 case 0x56: RMW_ZPX(LSR);\r
180 case 0x4E: RMW_AB(LSR);\r
181 case 0x5E: RMW_ABX(LSR);\r
182 \r
183 case 0x2A: RMW_A(ROL);\r
184 case 0x26: RMW_ZP(ROL);\r
185 case 0x36: RMW_ZPX(ROL);\r
186 case 0x2E: RMW_AB(ROL);\r
187 case 0x3E: RMW_ABX(ROL);\r
188 \r
189 case 0x6A: RMW_A(ROR);\r
190 case 0x66: RMW_ZP(ROR);\r
191 case 0x76: RMW_ZPX(ROR);\r
192 case 0x6E: RMW_AB(ROR);\r
193 case 0x7E: RMW_ABX(ROR);\r
194 \r
195 case 0x69: LD_IM(ADC);\r
196 case 0x65: LD_ZP(ADC);\r
197 case 0x75: LD_ZPX(ADC);\r
198 case 0x6D: LD_AB(ADC);\r
199 case 0x7D: LD_ABX(ADC);\r
200 case 0x79: LD_ABY(ADC);\r
201 case 0x61: LD_IX(ADC);\r
202 case 0x71: LD_IY(ADC);\r
203 \r
204 case 0x29: LD_IM(AND);\r
205 case 0x25: LD_ZP(AND);\r
206 case 0x35: LD_ZPX(AND);\r
207 case 0x2D: LD_AB(AND);\r
208 case 0x3D: LD_ABX(AND);\r
209 case 0x39: LD_ABY(AND);\r
210 case 0x21: LD_IX(AND);\r
211 case 0x31: LD_IY(AND);\r
212 \r
213 case 0x24: LD_ZP(BIT);\r
214 case 0x2C: LD_AB(BIT);\r
215 \r
216 case 0xC9: LD_IM(CMP);\r
217 case 0xC5: LD_ZP(CMP);\r
218 case 0xD5: LD_ZPX(CMP);\r
219 case 0xCD: LD_AB(CMP);\r
220 case 0xDD: LD_ABX(CMP);\r
221 case 0xD9: LD_ABY(CMP);\r
222 case 0xC1: LD_IX(CMP);\r
223 case 0xD1: LD_IY(CMP);\r
224 \r
225 case 0xE0: LD_IM(CPX);\r
226 case 0xE4: LD_ZP(CPX);\r
227 case 0xEC: LD_AB(CPX);\r
228 \r
229 case 0xC0: LD_IM(CPY);\r
230 case 0xC4: LD_ZP(CPY);\r
231 case 0xCC: LD_AB(CPY);\r
232 \r
233 case 0x49: LD_IM(EOR);\r
234 case 0x45: LD_ZP(EOR);\r
235 case 0x55: LD_ZPX(EOR);\r
236 case 0x4D: LD_AB(EOR);\r
237 case 0x5D: LD_ABX(EOR);\r
238 case 0x59: LD_ABY(EOR);\r
239 case 0x41: LD_IX(EOR);\r
240 case 0x51: LD_IY(EOR);\r
241 \r
242 case 0xA9: LD_IM(LDA);\r
243 case 0xA5: LD_ZP(LDA);\r
244 case 0xB5: LD_ZPX(LDA);\r
245 case 0xAD: LD_AB(LDA);\r
246 case 0xBD: LD_ABX(LDA);\r
247 case 0xB9: LD_ABY(LDA);\r
248 case 0xA1: LD_IX(LDA);\r
249 case 0xB1: LD_IY(LDA);\r
250 \r
251 case 0xA2: LD_IM(LDX);\r
252 case 0xA6: LD_ZP(LDX);\r
253 case 0xB6: LD_ZPY(LDX);\r
254 case 0xAE: LD_AB(LDX);\r
255 case 0xBE: LD_ABY(LDX);\r
256 \r
257 case 0xA0: LD_IM(LDY);\r
258 case 0xA4: LD_ZP(LDY);\r
259 case 0xB4: LD_ZPX(LDY);\r
260 case 0xAC: LD_AB(LDY);\r
261 case 0xBC: LD_ABX(LDY);\r
262 \r
263 case 0x09: LD_IM(ORA);\r
264 case 0x05: LD_ZP(ORA);\r
265 case 0x15: LD_ZPX(ORA);\r
266 case 0x0D: LD_AB(ORA);\r
267 case 0x1D: LD_ABX(ORA);\r
268 case 0x19: LD_ABY(ORA);\r
269 case 0x01: LD_IX(ORA);\r
270 case 0x11: LD_IY(ORA);\r
271 \r
272 case 0xEB:  /* (undocumented) */\r
273 case 0xE9: LD_IM(SBC);\r
274 case 0xE5: LD_ZP(SBC);\r
275 case 0xF5: LD_ZPX(SBC);\r
276 case 0xED: LD_AB(SBC);\r
277 case 0xFD: LD_ABX(SBC);\r
278 case 0xF9: LD_ABY(SBC);\r
279 case 0xE1: LD_IX(SBC);\r
280 case 0xF1: LD_IY(SBC);\r
281 \r
282 case 0x85: ST_ZP(_A);\r
283 case 0x95: ST_ZPX(_A);\r
284 case 0x8D: ST_AB(_A);\r
285 case 0x9D: ST_ABX(_A);\r
286 case 0x99: ST_ABY(_A);\r
287 case 0x81: ST_IX(_A);\r
288 case 0x91: ST_IY(_A);\r
289 \r
290 case 0x86: ST_ZP(_X);\r
291 case 0x96: ST_ZPY(_X);\r
292 case 0x8E: ST_AB(_X);\r
293 \r
294 case 0x84: ST_ZP(_Y);\r
295 case 0x94: ST_ZPX(_Y);\r
296 case 0x8C: ST_AB(_Y);\r
297 \r
298 /* BCC */\r
299 case 0x90: JR(!(_P&C_FLAG)); break;\r
300 \r
301 /* BCS */\r
302 case 0xB0: JR(_P&C_FLAG); break;\r
303 \r
304 /* BEQ */\r
305 case 0xF0: JR(_P&Z_FLAG); break;\r
306 \r
307 /* BNE */\r
308 case 0xD0: JR(!(_P&Z_FLAG)); break;\r
309 \r
310 /* BMI */\r
311 case 0x30: JR(_P&N_FLAG); break;\r
312 \r
313 /* BPL */\r
314 case 0x10: JR(!(_P&N_FLAG)); break;\r
315 \r
316 /* BVC */\r
317 case 0x50: JR(!(_P&V_FLAG)); break;\r
318 \r
319 /* BVS */\r
320 case 0x70: JR(_P&V_FLAG); break;\r
321 \r
322 //default: printf("Bad %02x at $%04x\n",b1,X.PC);break;\r
323 //ifdef moo\r
324 /* Here comes the undocumented instructions block.  Note that this implementation\r
325    may be "wrong".  If so, please tell me.\r
326 */\r
327 \r
328 /* AAC */\r
329 case 0x2B:\r
330 case 0x0B: LD_IM(AND;_P&=~C_FLAG;_P|=_A>>7);\r
331 \r
332 /* AAX */\r
333 case 0x87: ST_ZP(_A&_X);\r
334 case 0x97: ST_ZPY(_A&_X);\r
335 case 0x8F: ST_AB(_A&_X);\r
336 case 0x83: ST_IX(_A&_X);\r
337 \r
338 /* ARR - ARGH, MATEY! */\r
339 case 0x6B: { \r
340              uint8 arrtmp; \r
341              LD_IM(AND;_P&=~V_FLAG;_P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(_P&C_FLAG)<<7;_P&=~C_FLAG;_P|=arrtmp;X_ZN(_A));\r
342            }\r
343 /* ASR */\r
344 case 0x4B: LD_IM(AND;LSRA);\r
345 \r
346 /* ATX(OAL) Is this(OR with $EE) correct? Blargg did some test\r
347    and found the constant to be OR with is $FF for NES */\r
348 case 0xAB: LD_IM(_A|=0xFF;AND;_X=_A);\r
349 \r
350 /* AXS */ \r
351 case 0xCB: LD_IM(AXS);\r
352 \r
353 /* DCP */\r
354 case 0xC7: RMW_ZP(DEC;CMP);\r
355 case 0xD7: RMW_ZPX(DEC;CMP);\r
356 case 0xCF: RMW_AB(DEC;CMP);\r
357 case 0xDF: RMW_ABX(DEC;CMP);\r
358 case 0xDB: RMW_ABY(DEC;CMP);\r
359 case 0xC3: RMW_IX(DEC;CMP);\r
360 case 0xD3: RMW_IY(DEC;CMP);\r
361 \r
362 /* ISB */\r
363 case 0xE7: RMW_ZP(INC;SBC);\r
364 case 0xF7: RMW_ZPX(INC;SBC);\r
365 case 0xEF: RMW_AB(INC;SBC);\r
366 case 0xFF: RMW_ABX(INC;SBC);\r
367 case 0xFB: RMW_ABY(INC;SBC);\r
368 case 0xE3: RMW_IX(INC;SBC);\r
369 case 0xF3: RMW_IY(INC;SBC);\r
370 \r
371 /* DOP */\r
372 \r
373 case 0x04: _PC++;break;\r
374 case 0x14: _PC++;break;\r
375 case 0x34: _PC++;break;\r
376 case 0x44: _PC++;break;\r
377 case 0x54: _PC++;break;\r
378 case 0x64: _PC++;break;\r
379 case 0x74: _PC++;break;\r
380 \r
381 case 0x80: _PC++;break;\r
382 case 0x82: _PC++;break;\r
383 case 0x89: _PC++;break;\r
384 case 0xC2: _PC++;break;\r
385 case 0xD4: _PC++;break;\r
386 case 0xE2: _PC++;break;\r
387 case 0xF4: _PC++;break;\r
388 \r
389 /* KIL */\r
390 \r
391 case 0x02:\r
392 case 0x12:\r
393 case 0x22:\r
394 case 0x32:\r
395 case 0x42:\r
396 case 0x52:\r
397 case 0x62:\r
398 case 0x72:\r
399 case 0x92:\r
400 case 0xB2:\r
401 case 0xD2:\r
402 case 0xF2:ADDCYC(0xFF);\r
403           _jammed=1;\r
404           _PC--;\r
405           break;\r
406 \r
407 /* LAR */\r
408 case 0xBB: RMW_ABY(_S&=x;_A=_X=_S;X_ZN(_X));\r
409 \r
410 /* LAX */\r
411 case 0xA7: LD_ZP(LDA;LDX);\r
412 case 0xB7: LD_ZPY(LDA;LDX);\r
413 case 0xAF: LD_AB(LDA;LDX);\r
414 case 0xBF: LD_ABY(LDA;LDX);\r
415 case 0xA3: LD_IX(LDA;LDX);\r
416 case 0xB3: LD_IY(LDA;LDX);\r
417 \r
418 /* NOP */\r
419 case 0x1A:\r
420 case 0x3A:\r
421 case 0x5A:\r
422 case 0x7A:\r
423 case 0xDA:\r
424 case 0xFA: break;\r
425 \r
426 /* RLA */\r
427 case 0x27: RMW_ZP(ROL;AND);\r
428 case 0x37: RMW_ZPX(ROL;AND);\r
429 case 0x2F: RMW_AB(ROL;AND);\r
430 case 0x3F: RMW_ABX(ROL;AND);\r
431 case 0x3B: RMW_ABY(ROL;AND);\r
432 case 0x23: RMW_IX(ROL;AND);\r
433 case 0x33: RMW_IY(ROL;AND);\r
434 \r
435 /* RRA */\r
436 case 0x67: RMW_ZP(ROR;ADC);\r
437 case 0x77: RMW_ZPX(ROR;ADC);\r
438 case 0x6F: RMW_AB(ROR;ADC);\r
439 case 0x7F: RMW_ABX(ROR;ADC);\r
440 case 0x7B: RMW_ABY(ROR;ADC);\r
441 case 0x63: RMW_IX(ROR;ADC);\r
442 case 0x73: RMW_IY(ROR;ADC);\r
443 \r
444 /* SLO */\r
445 case 0x07: RMW_ZP(ASL;ORA);\r
446 case 0x17: RMW_ZPX(ASL;ORA);\r
447 case 0x0F: RMW_AB(ASL;ORA);\r
448 case 0x1F: RMW_ABX(ASL;ORA);\r
449 case 0x1B: RMW_ABY(ASL;ORA);\r
450 case 0x03: RMW_IX(ASL;ORA);\r
451 case 0x13: RMW_IY(ASL;ORA);\r
452 \r
453 /* SRE */\r
454 case 0x47: RMW_ZP(LSR;EOR);\r
455 case 0x57: RMW_ZPX(LSR;EOR);\r
456 case 0x4F: RMW_AB(LSR;EOR);\r
457 case 0x5F: RMW_ABX(LSR;EOR);\r
458 case 0x5B: RMW_ABY(LSR;EOR);\r
459 case 0x43: RMW_IX(LSR;EOR);\r
460 case 0x53: RMW_IY(LSR;EOR);\r
461 \r
462 /* AXA - SHA */\r
463 case 0x93: ST_IY(_A&_X&(((A-_Y)>>8)+1));\r
464 case 0x9F: ST_ABY(_A&_X&(((A-_Y)>>8)+1));\r
465 \r
466 /* SYA */\r
467 case 0x9C: ST_ABX(_Y&(((A-_X)>>8)+1));\r
468 \r
469 /* SXA */\r
470 case 0x9E: ST_ABY(_X&(((A-_Y)>>8)+1));\r
471 \r
472 /* XAS */\r
473 case 0x9B: _S=_A&_X;ST_ABY(_S& (((A-_Y)>>8)+1) );\r
474 \r
475 /* TOP */\r
476 case 0x0C: LD_AB(;);\r
477 case 0x1C: \r
478 case 0x3C: \r
479 case 0x5C: \r
480 case 0x7C: \r
481 case 0xDC: \r
482 case 0xFC: LD_ABX(;);\r
483 \r
484 /* XAA - BIG QUESTION MARK HERE */\r
485 case 0x8B: _A|=0xEE; _A&=_X; LD_IM(AND);\r
486 //endif\r