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