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