merged ppu code, added input+zapper, FDS/VS insert in menu
[fceu.git] / x6502.c
CommitLineData
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#include <string.h>
22
23#include "types.h"
24#include "x6502.h"
25#include "fce.h"
26#include "sound.h"
937bf65b 27#include "cart.h"
c62d2810 28
4fdfab07 29#include "dprintf.h"
30
c0bf6f9f 31#ifdef DEBUG_ASM_6502
81bd66a1 32#include <stdio.h>
33#include <stdlib.h>
c0bf6f9f 34extern uint32 PC_prev, OP_prev;
81bd66a1 35extern uint8 dreads[4];
36extern uint32 dwrites_c[2];
37extern int dread_count_c, dwrite_count_c;
370cff9a 38extern int mapirq_cyc_c;
39extern void (*MapIRQHook)(int a);
81bd66a1 40#define DummyRdMem(...)
41#else
42#define DummyRdMem RdMem
370cff9a 43void FP_FASTAPASS(1) (*MapIRQHook)(int a);
c0bf6f9f 44#endif
45
c62d2810 46X6502 X;
47uint32 timestamp;
c62d2810 48
49#define _PC X.PC
50#define _A X.A
51#define _X X.X
52#define _Y X.Y
53#define _S X.S
54#define _P X.P
55#define _PI X.mooPI
92e249b1 56//#define _PZ X.PZ // unused?
c62d2810 57#define _DB X.DB
58#define _count X.count
59#define _tcount X.tcount
60#define _IRQlow X.IRQlow
61#define _jammed X.jammed
62
63
64static INLINE uint8 RdMem(unsigned int A)
65{
0b65fdb3 66 int _DB1=ARead[A](A);
c0bf6f9f 67#ifdef DEBUG_ASM_6502
e7f52878 68 //_DB=_DB1;
81bd66a1 69 //printf("a == %x, pc == %x\n", A, _PC);
e7f52878 70 if (A >= 0x2000) {
71 if (A == _PC || A == _PC - 1 || A == _PC + 1) {
72 //printf("fr: %02x\n", _DB1);
73 }
74 _DB=_DB1;
75 }
81bd66a1 76 if (A >= 0x2000 && A != _PC && A != _PC - 1 && A != _PC + 1) {
0b65fdb3 77 dreads[dread_count_c++] = _DB1;
81bd66a1 78 if (dread_count_c > 4) { printf("dread_count out of range\n"); exit(1); }
79 }
e7f52878 80#else
81 _DB=_DB1;
c0bf6f9f 82#endif
0b65fdb3 83 return _DB1;
c62d2810 84}
85
86static INLINE void WrMem(unsigned int A, uint8 V)
87{
13a7da55 88 //printf("w [%04x] %02x\n", A, V);
937bf65b 89 if ((A&0xe000) == 0) { // RAM area (always 0-0x1fff)
90 RAM[A&0x7FF] = V;
91 return;
92 }
c62d2810 93 BWrite[A](A,V);
81bd66a1 94#ifdef DEBUG_ASM_6502
95 dwrites_c[dwrite_count_c++] = (A<<8)|V;
96 if (dwrite_count_c > 2) { printf("dwrite_count_c out of range\n"); exit(1); }
97#endif
c62d2810 98}
99
100static INLINE uint8 RdRAM(unsigned int A)
101{
0b65fdb3 102 //return((_DB=RAM[A]));
e7f52878 103 int _DB1=RAM[A];
104#ifndef DEBUG_ASM_6502
105 _DB=_DB1;
106#endif
107 return _DB1;
c62d2810 108}
109
110static INLINE void WrRAM(unsigned int A, uint8 V)
111{
112 RAM[A]=V;
113}
114
115static INLINE void ADDCYC(int x)
116{
370cff9a 117 _tcount+=x;
c62d2810 118 _count-=x*48;
119 timestamp+=x;
120}
121
af32b6c2 122void FASTAPASS(1) X6502_AddCycles_c(int x)
c62d2810 123{
124 ADDCYC(x);
125}
126
127static INLINE void PUSH(uint8 V)
128{
129 WrRAM(0x100+_S,V);
130 _S--;
131}
132
133static INLINE uint8 POP(void)
134{
135 _S++;
136 return(RdRAM(0x100+_S));
137}
138
937bf65b 139#if 0
c62d2810 140static uint8 ZNTable[256] = {
141 Z_FLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
142 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
143 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
144 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
145 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
146 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
147 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
148 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
149 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
150 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
151 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
152 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
153 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
154 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
155 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,
156 N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG,N_FLAG
157};
937bf65b 158#endif
c62d2810 159/* Some of these operations will only make sense if you know what the flag
160 constants are. */
937bf65b 161//#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);_P|=ZNTable[zort]
162//#define X_ZNT(zort) _P|=ZNTable[zort]
163#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);if(!zort) _P|=Z_FLAG;else _P|=zort&N_FLAG
c0bf6f9f 164#define X_ZNT(zort) if(!zort) _P|=Z_FLAG;else _P|=(zort&N_FLAG)
c62d2810 165
166/* Care must be taken if you want to turn this into a macro. Use { and }. */
167#define JR(); \
168{ \
169 uint32 tmp; \
170 int8 disp; \
171 disp=RdMem(_PC++); \
172 ADDCYC(1); \
173 tmp=_PC; \
174 _PC+=disp; \
175 if((tmp^_PC)&0x100) \
176 ADDCYC(1); \
177}
178
179#define LDA _A=x;X_ZN(_A)
180#define LDX _X=x;X_ZN(_X)
181#define LDY _Y=x;X_ZN(_Y)
182
183/* All of the freaky arithmetic operations. */
184#define AND _A&=x;X_ZN(_A)
937bf65b 185//#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
186#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);if(!(x&_A)) _P|=Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
c62d2810 187#define EOR _A^=x;X_ZN(_A)
188#define ORA _A|=x;X_ZN(_A)
189
190#define ADC { \
191 uint32 l=_A+x+(_P&1); \
192 _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
193 _P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \
194 _P|=(l>>8)&C_FLAG; \
195 _A=l; \
196 X_ZNT(_A); \
197 }
198#define SBC { \
199 uint32 l=_A-x-((_P&1)^1); \
200 _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
201 _P|=((_A^l)&(_A^x)&0x80)>>1; \
202 _P|=((l>>8)&C_FLAG)^C_FLAG; \
203 _A=l; \
204 X_ZNT(_A); \
205 }
206
207#define CMPL(a1,a2) { \
208 uint32 t=a1-a2; \
209 X_ZN(t&0xFF); \
210 _P&=~C_FLAG; \
211 _P|=((t>>8)&C_FLAG)^C_FLAG; \
212 }
213
214/* Special undocumented operation. Very similar to CMP. */
215#define AXS { \
216 uint32 t=(_A&_X)-x; \
217 X_ZN(t&0xFF); \
218 _P&=~C_FLAG; \
219 _P|=((t>>8)&C_FLAG)^C_FLAG; \
220 _X=t; \
221 }
222
223#define CMP CMPL(_A,x)
224#define CPX CMPL(_X,x)
225#define CPY CMPL(_Y,x)
226
227/* The following operations modify the byte being worked on. */
228#define DEC x--;X_ZN(x)
229#define INC x++;X_ZN(x)
230
231#define ASL _P&=~C_FLAG;_P|=x>>7;x<<=1;X_ZN(x)
232#define LSR _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=x&1;x>>=1;X_ZNT(x)
233
234/* For undocumented instructions, maybe for other things later... */
235#define LSRA _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=_A&1;_A>>=1;X_ZNT(_A)
236
237#define ROL { \
238 uint8 l=x>>7; \
239 x<<=1; \
240 x|=_P&C_FLAG; \
241 _P&=~(Z_FLAG|N_FLAG|C_FLAG); \
242 _P|=l; \
243 X_ZNT(x); \
244 }
245#define ROR { \
246 uint8 l=x&1; \
247 x>>=1; \
248 x|=(_P&C_FLAG)<<7; \
249 _P&=~(Z_FLAG|N_FLAG|C_FLAG); \
250 _P|=l; \
251 X_ZNT(x); \
252 }
937bf65b 253
c62d2810 254/* Icky icky thing for some undocumented instructions. Can easily be
255 broken if names of local variables are changed.
256*/
257
258/* Absolute */
259#define GetAB(target) \
260{ \
261 target=RdMem(_PC++); \
262 target|=RdMem(_PC++)<<8; \
263}
264
265/* Absolute Indexed(for reads) */
266#define GetABIRD(target, i) \
267{ \
268 unsigned int tmp; \
269 GetAB(tmp); \
270 target=tmp; \
271 target+=i; \
272 if((target^tmp)&0x100) \
273 { \
274 target&=0xFFFF; \
81bd66a1 275 DummyRdMem(target^0x100); \
c62d2810 276 ADDCYC(1); \
277 } \
278}
279
280/* Absolute Indexed(for writes and rmws) */
281#define GetABIWR(target, i) \
282{ \
283 unsigned int rt; \
284 GetAB(rt); \
285 target=rt; \
286 target+=i; \
287 target&=0xFFFF; \
81bd66a1 288 DummyRdMem((target&0x00FF)|(rt&0xFF00)); \
c62d2810 289}
290
291/* Zero Page */
292#define GetZP(target) \
293{ \
294 target=RdMem(_PC++); \
295}
296
297/* Zero Page Indexed */
298#define GetZPI(target,i) \
299{ \
300 target=i+RdMem(_PC++); \
301}
302
303/* Indexed Indirect */
304#define GetIX(target) \
305{ \
306 uint8 tmp; \
307 tmp=RdMem(_PC++); \
308 tmp+=_X; \
309 target=RdRAM(tmp++); \
310 target|=RdRAM(tmp)<<8; \
311}
312
313/* Indirect Indexed(for reads) */
314#define GetIYRD(target) \
315{ \
316 unsigned int rt; \
317 uint8 tmp; \
318 tmp=RdMem(_PC++); \
319 rt=RdRAM(tmp++); \
320 rt|=RdRAM(tmp)<<8; \
321 target=rt; \
322 target+=_Y; \
323 if((target^rt)&0x100) \
324 { \
325 target&=0xFFFF; \
81bd66a1 326 DummyRdMem(target^0x100); \
c62d2810 327 ADDCYC(1); \
328 } \
329}
330
331/* Indirect Indexed(for writes and rmws) */
332#define GetIYWR(target) \
333{ \
334 unsigned int rt; \
335 uint8 tmp; \
336 tmp=RdMem(_PC++); \
337 rt=RdRAM(tmp++); \
338 rt|=RdRAM(tmp)<<8; \
339 target=rt; \
340 target+=_Y; \
81bd66a1 341 DummyRdMem((target&0x00FF)|(rt&0xFF00)); \
c62d2810 342}
343
344/* Now come the macros to wrap up all of the above stuff addressing mode functions
345 and operation macros. Note that operation macros will always operate(redundant
346 redundant) on the variable "x".
347*/
348
349#define RMW_A(op) {uint8 x=_A; op; _A=x; break; } /* Meh... */
350#define RMW_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
351#define RMW_ABI(reg,op) {unsigned int A; uint8 x; GetABIWR(A,reg); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
352#define RMW_ABX(op) RMW_ABI(_X,op)
353#define RMW_ABY(op) RMW_ABI(_Y,op)
354#define RMW_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
355#define RMW_IY(op) {unsigned int A; uint8 x; GetIYWR(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
356#define RMW_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; WrRAM(A,x); break; }
357#define RMW_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; WrRAM(A,x); break;}
358
359#define LD_IM(op) {uint8 x; x=RdMem(_PC++); op; break;}
360#define LD_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; break;}
361#define LD_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; break;}
362#define LD_ZPY(op) {uint8 A; uint8 x; GetZPI(A,_Y); x=RdRAM(A); op; break;}
363#define LD_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); op; break; }
364#define LD_ABI(reg,op) {unsigned int A; uint8 x; GetABIRD(A,reg); x=RdMem(A); op; break;}
365#define LD_ABX(op) LD_ABI(_X,op)
366#define LD_ABY(op) LD_ABI(_Y,op)
367#define LD_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); op; break;}
368#define LD_IY(op) {unsigned int A; uint8 x; GetIYRD(A); x=RdMem(A); op; break;}
369
370#define ST_ZP(r) {uint8 A; GetZP(A); WrRAM(A,r); break;}
371#define ST_ZPX(r) {uint8 A; GetZPI(A,_X); WrRAM(A,r); break;}
372#define ST_ZPY(r) {uint8 A; GetZPI(A,_Y); WrRAM(A,r); break;}
373#define ST_AB(r) {unsigned int A; GetAB(A); WrMem(A,r); break;}
374#define ST_ABI(reg,r) {unsigned int A; GetABIWR(A,reg); WrMem(A,r); break; }
375#define ST_ABX(r) ST_ABI(_X,r)
376#define ST_ABY(r) ST_ABI(_Y,r)
377#define ST_IX(r) {unsigned int A; GetIX(A); WrMem(A,r); break; }
378#define ST_IY(r) {unsigned int A; GetIYWR(A); WrMem(A,r); break; }
379
380static uint8 CycTable[256] =
937bf65b 381{
c62d2810 382/*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
383/*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
384/*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
385/*0x30*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
386/*0x40*/ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,
387/*0x50*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
388/*0x60*/ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,
389/*0x70*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
390/*0x80*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
391/*0x90*/ 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,
392/*0xA0*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
393/*0xB0*/ 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,
394/*0xC0*/ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
395/*0xD0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
396/*0xE0*/ 2,6,3,8,3,3,5,5,2,2,2,2,4,4,6,6,
397/*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
398};
399
af32b6c2 400void FASTAPASS(1) X6502_IRQBegin_c(int w)
c62d2810 401{
ea80a45b 402 dprintf("IRQB %02x",w);
c62d2810 403 _IRQlow|=w;
404}
405
af32b6c2 406void FASTAPASS(1) X6502_IRQEnd_c(int w)
c62d2810 407{
ea80a45b 408 dprintf("IRQE %02x",w);
c62d2810 409 _IRQlow&=~w;
410}
411
af32b6c2 412void TriggerIRQ_c(void) /* This function should probably be phased out. */
c62d2810 413{
414 _IRQlow|=FCEU_IQTEMP;
415}
416
af32b6c2 417void TriggerNMINSF_c(void)
c62d2810 418{
419 ADDCYC(7);
420 PUSH(_PC>>8);
421 PUSH(_PC);
422 PUSH((_P&~B_FLAG)|(U_FLAG));
423 _PC=0x3800;
424}
425
af32b6c2 426void TriggerNMI_c(void)
c62d2810 427{
428 _IRQlow|=FCEU_IQNMI;
429}
430
431static void TriggerNMIReal(void)
432{
433 if(!_jammed)
434 {
4fdfab07 435 dprintf("NMI");
c62d2810 436 ADDCYC(7);
437 PUSH(_PC>>8);
438 PUSH(_PC);
c0bf6f9f 439 _P&=~B_FLAG;
440 PUSH(_P|U_FLAG);
c62d2810 441 _PC=RdMem(0xFFFA);
442 _PC|=RdMem(0xFFFB)<<8;
c0bf6f9f 443#ifdef DEBUG_ASM_6502
444 PC_prev = _PC;
445 OP_prev = 0x100;
446#endif
c62d2810 447 }
448}
449
450void TriggerIRQReal(void)
451{
452 if(!(_PI&I_FLAG) && !_jammed)
453 {
4fdfab07 454 dprintf("IRQ");
c62d2810 455 ADDCYC(7);
456 PUSH(_PC>>8);
457 PUSH(_PC);
c0bf6f9f 458 _P&=~B_FLAG;
459 PUSH(_P|U_FLAG);
c62d2810 460 _P|=I_FLAG;
461 _PC=RdMem(0xFFFE);
462 _PC|=RdMem(0xFFFF)<<8;
c0bf6f9f 463#ifdef DEBUG_ASM_6502
464 PC_prev = _PC;
465 OP_prev = 0x101;
466#endif
c62d2810 467 }
468}
469
af32b6c2 470void X6502_Reset_c(void)
c62d2810 471{
472 _PC=RdMem(0xFFFC);
473 _PC|=RdMem(0xFFFD)<<8;
c62d2810 474 _jammed=0;
475 _PI=_P=I_FLAG;
476}
477
af32b6c2 478void X6502_Power_c(void)
c62d2810 479{
937bf65b 480 memset((void *)&X,0,sizeof(X));
c62d2810 481 timestamp=0;
af32b6c2 482 X6502_Reset_c();
c62d2810 483}
484
937bf65b 485
486//int asdc = 0;
af32b6c2 487void X6502_Run_c(void/*int32 cycles*/)
c62d2810 488{
937bf65b 489/*
c62d2810 490 if(PAL)
491 cycles*=15; // 15*4=60
492 else
493 cycles*=16; // 16*4=64
494
495 _count+=cycles;
937bf65b 496*/
497// if (_count <= 0) asdc++;
c62d2810 498
499 while(_count>0)
500 {
501 int32 temp;
502 uint8 b1;
503
504 if(_IRQlow)
505 {
506 if(_IRQlow&FCEU_IQNMI)
507 TriggerNMIReal();
508 else
509 TriggerIRQReal();
510
511 _IRQlow&=~(FCEU_IQTEMP|FCEU_IQNMI);
370cff9a 512 if(_count<=0)
513 {
514#ifdef DEBUG_ASM_6502
515 if(MapIRQHook) mapirq_cyc_c = _tcount;
516 _tcount=0;
517#endif
518 _PI=_P;
519 return; /* Should increase accuracy without a major speed hit. */
520 }
c62d2810 521 }
522 _PI=_P;
523 b1=RdMem(_PC);
370cff9a 524 ADDCYC(CycTable[b1]);
525 temp=_tcount;
c62d2810 526
527 temp*=48;
528
529 fhcnt-=temp;
530 if(fhcnt<=0)
531 {
532 FrameSoundUpdate();
533 fhcnt+=fhinc;
534 }
535
c62d2810 536 if(PCMIRQCount>0)
537 {
538 PCMIRQCount-=temp;
539 if(PCMIRQCount<=0)
540 {
541 vdis=1;
542 if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40))
543 {
544 extern uint8 SIRQStat;
545 SIRQStat|=0x80;
f12b1f31 546 X6502_IRQBegin(FCEU_IQDPCM);
c62d2810 547 }
548 }
549 }
92e249b1 550
c0bf6f9f 551#ifdef DEBUG_ASM_6502
552 PC_prev = _PC;
553 OP_prev = b1;
c0bf6f9f 554#endif
c62d2810 555 //printf("$%04x:$%02x\n",_PC,b1);
556 //_PC++;
557 //printf("$%02x\n",b1);
558 _PC++;
559 switch(b1)
560 {
561 #include "ops.h"
937bf65b 562 }
af32b6c2 563
370cff9a 564 temp=_tcount; /* Gradius II (J) glitches if _tcount is not used */
565 _tcount=0;
566
567 if(MapIRQHook) {
568#ifdef DEBUG_ASM_6502
569 mapirq_cyc_c = temp;
570#endif
571 MapIRQHook(temp);
572 }
573
af32b6c2 574#ifdef DEBUG_ASM_6502
575 _PI=_P;
576#endif
c62d2810 577 }
578}
937bf65b 579
580