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