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