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