3ac1cc0b |
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 |