some refactoring, no change in performance seen
[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{
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{
103 return((_DB=RAM[A]));
104}
105
106static INLINE void WrRAM(unsigned int A, uint8 V)
107{
108 RAM[A]=V;
109}
110
111static INLINE void ADDCYC(int x)
112{
370cff9a 113 _tcount+=x;
c62d2810 114 _count-=x*48;
115 timestamp+=x;
116}
117
af32b6c2 118void FASTAPASS(1) X6502_AddCycles_c(int x)
c62d2810 119{
120 ADDCYC(x);
121}
122
123static INLINE void PUSH(uint8 V)
124{
125 WrRAM(0x100+_S,V);
126 _S--;
127}
128
129static INLINE uint8 POP(void)
130{
131 _S++;
132 return(RdRAM(0x100+_S));
133}
134
937bf65b 135#if 0
c62d2810 136static uint8 ZNTable[256] = {
137 Z_FLAG,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 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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 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};
937bf65b 154#endif
c62d2810 155/* Some of these operations will only make sense if you know what the flag
156 constants are. */
937bf65b 157//#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);_P|=ZNTable[zort]
158//#define X_ZNT(zort) _P|=ZNTable[zort]
159#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);if(!zort) _P|=Z_FLAG;else _P|=zort&N_FLAG
c0bf6f9f 160#define X_ZNT(zort) if(!zort) _P|=Z_FLAG;else _P|=(zort&N_FLAG)
c62d2810 161
162/* Care must be taken if you want to turn this into a macro. Use { and }. */
163#define JR(); \
164{ \
165 uint32 tmp; \
166 int8 disp; \
167 disp=RdMem(_PC++); \
168 ADDCYC(1); \
169 tmp=_PC; \
170 _PC+=disp; \
171 if((tmp^_PC)&0x100) \
172 ADDCYC(1); \
173}
174
175#define LDA _A=x;X_ZN(_A)
176#define LDX _X=x;X_ZN(_X)
177#define LDY _Y=x;X_ZN(_Y)
178
179/* All of the freaky arithmetic operations. */
180#define AND _A&=x;X_ZN(_A)
937bf65b 181//#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
182#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);if(!(x&_A)) _P|=Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
c62d2810 183#define EOR _A^=x;X_ZN(_A)
184#define ORA _A|=x;X_ZN(_A)
185
186#define ADC { \
187 uint32 l=_A+x+(_P&1); \
188 _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
189 _P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \
190 _P|=(l>>8)&C_FLAG; \
191 _A=l; \
192 X_ZNT(_A); \
193 }
194#define SBC { \
195 uint32 l=_A-x-((_P&1)^1); \
196 _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
197 _P|=((_A^l)&(_A^x)&0x80)>>1; \
198 _P|=((l>>8)&C_FLAG)^C_FLAG; \
199 _A=l; \
200 X_ZNT(_A); \
201 }
202
203#define CMPL(a1,a2) { \
204 uint32 t=a1-a2; \
205 X_ZN(t&0xFF); \
206 _P&=~C_FLAG; \
207 _P|=((t>>8)&C_FLAG)^C_FLAG; \
208 }
209
210/* Special undocumented operation. Very similar to CMP. */
211#define AXS { \
212 uint32 t=(_A&_X)-x; \
213 X_ZN(t&0xFF); \
214 _P&=~C_FLAG; \
215 _P|=((t>>8)&C_FLAG)^C_FLAG; \
216 _X=t; \
217 }
218
219#define CMP CMPL(_A,x)
220#define CPX CMPL(_X,x)
221#define CPY CMPL(_Y,x)
222
223/* The following operations modify the byte being worked on. */
224#define DEC x--;X_ZN(x)
225#define INC x++;X_ZN(x)
226
227#define ASL _P&=~C_FLAG;_P|=x>>7;x<<=1;X_ZN(x)
228#define LSR _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=x&1;x>>=1;X_ZNT(x)
229
230/* For undocumented instructions, maybe for other things later... */
231#define LSRA _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=_A&1;_A>>=1;X_ZNT(_A)
232
233#define ROL { \
234 uint8 l=x>>7; \
235 x<<=1; \
236 x|=_P&C_FLAG; \
237 _P&=~(Z_FLAG|N_FLAG|C_FLAG); \
238 _P|=l; \
239 X_ZNT(x); \
240 }
241#define ROR { \
242 uint8 l=x&1; \
243 x>>=1; \
244 x|=(_P&C_FLAG)<<7; \
245 _P&=~(Z_FLAG|N_FLAG|C_FLAG); \
246 _P|=l; \
247 X_ZNT(x); \
248 }
937bf65b 249
c62d2810 250/* Icky icky thing for some undocumented instructions. Can easily be
251 broken if names of local variables are changed.
252*/
253
254/* Absolute */
255#define GetAB(target) \
256{ \
257 target=RdMem(_PC++); \
258 target|=RdMem(_PC++)<<8; \
259}
260
261/* Absolute Indexed(for reads) */
262#define GetABIRD(target, i) \
263{ \
264 unsigned int tmp; \
265 GetAB(tmp); \
266 target=tmp; \
267 target+=i; \
268 if((target^tmp)&0x100) \
269 { \
270 target&=0xFFFF; \
81bd66a1 271 DummyRdMem(target^0x100); \
c62d2810 272 ADDCYC(1); \
273 } \
274}
275
276/* Absolute Indexed(for writes and rmws) */
277#define GetABIWR(target, i) \
278{ \
279 unsigned int rt; \
280 GetAB(rt); \
281 target=rt; \
282 target+=i; \
283 target&=0xFFFF; \
81bd66a1 284 DummyRdMem((target&0x00FF)|(rt&0xFF00)); \
c62d2810 285}
286
287/* Zero Page */
288#define GetZP(target) \
289{ \
290 target=RdMem(_PC++); \
291}
292
293/* Zero Page Indexed */
294#define GetZPI(target,i) \
295{ \
296 target=i+RdMem(_PC++); \
297}
298
299/* Indexed Indirect */
300#define GetIX(target) \
301{ \
302 uint8 tmp; \
303 tmp=RdMem(_PC++); \
304 tmp+=_X; \
305 target=RdRAM(tmp++); \
306 target|=RdRAM(tmp)<<8; \
307}
308
309/* Indirect Indexed(for reads) */
310#define GetIYRD(target) \
311{ \
312 unsigned int rt; \
313 uint8 tmp; \
314 tmp=RdMem(_PC++); \
315 rt=RdRAM(tmp++); \
316 rt|=RdRAM(tmp)<<8; \
317 target=rt; \
318 target+=_Y; \
319 if((target^rt)&0x100) \
320 { \
321 target&=0xFFFF; \
81bd66a1 322 DummyRdMem(target^0x100); \
c62d2810 323 ADDCYC(1); \
324 } \
325}
326
327/* Indirect Indexed(for writes and rmws) */
328#define GetIYWR(target) \
329{ \
330 unsigned int rt; \
331 uint8 tmp; \
332 tmp=RdMem(_PC++); \
333 rt=RdRAM(tmp++); \
334 rt|=RdRAM(tmp)<<8; \
335 target=rt; \
336 target+=_Y; \
81bd66a1 337 DummyRdMem((target&0x00FF)|(rt&0xFF00)); \
c62d2810 338}
339
340/* Now come the macros to wrap up all of the above stuff addressing mode functions
341 and operation macros. Note that operation macros will always operate(redundant
342 redundant) on the variable "x".
343*/
344
345#define RMW_A(op) {uint8 x=_A; op; _A=x; break; } /* Meh... */
346#define RMW_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
347#define RMW_ABI(reg,op) {unsigned int A; uint8 x; GetABIWR(A,reg); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
348#define RMW_ABX(op) RMW_ABI(_X,op)
349#define RMW_ABY(op) RMW_ABI(_Y,op)
350#define RMW_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
351#define RMW_IY(op) {unsigned int A; uint8 x; GetIYWR(A); x=RdMem(A); WrMem(A,x); op; WrMem(A,x); break; }
352#define RMW_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; WrRAM(A,x); break; }
353#define RMW_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; WrRAM(A,x); break;}
354
355#define LD_IM(op) {uint8 x; x=RdMem(_PC++); op; break;}
356#define LD_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; break;}
357#define LD_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; break;}
358#define LD_ZPY(op) {uint8 A; uint8 x; GetZPI(A,_Y); x=RdRAM(A); op; break;}
359#define LD_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); op; break; }
360#define LD_ABI(reg,op) {unsigned int A; uint8 x; GetABIRD(A,reg); x=RdMem(A); op; break;}
361#define LD_ABX(op) LD_ABI(_X,op)
362#define LD_ABY(op) LD_ABI(_Y,op)
363#define LD_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); op; break;}
364#define LD_IY(op) {unsigned int A; uint8 x; GetIYRD(A); x=RdMem(A); op; break;}
365
366#define ST_ZP(r) {uint8 A; GetZP(A); WrRAM(A,r); break;}
367#define ST_ZPX(r) {uint8 A; GetZPI(A,_X); WrRAM(A,r); break;}
368#define ST_ZPY(r) {uint8 A; GetZPI(A,_Y); WrRAM(A,r); break;}
369#define ST_AB(r) {unsigned int A; GetAB(A); WrMem(A,r); break;}
370#define ST_ABI(reg,r) {unsigned int A; GetABIWR(A,reg); WrMem(A,r); break; }
371#define ST_ABX(r) ST_ABI(_X,r)
372#define ST_ABY(r) ST_ABI(_Y,r)
373#define ST_IX(r) {unsigned int A; GetIX(A); WrMem(A,r); break; }
374#define ST_IY(r) {unsigned int A; GetIYWR(A); WrMem(A,r); break; }
375
376static uint8 CycTable[256] =
937bf65b 377{
c62d2810 378/*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
379/*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
380/*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
381/*0x30*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
382/*0x40*/ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,
383/*0x50*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
384/*0x60*/ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,
385/*0x70*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
386/*0x80*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
387/*0x90*/ 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,
388/*0xA0*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
389/*0xB0*/ 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,
390/*0xC0*/ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
391/*0xD0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
392/*0xE0*/ 2,6,3,8,3,3,5,5,2,2,2,2,4,4,6,6,
393/*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
394};
395
af32b6c2 396void FASTAPASS(1) X6502_IRQBegin_c(int w)
c62d2810 397{
398 _IRQlow|=w;
399}
400
af32b6c2 401void FASTAPASS(1) X6502_IRQEnd_c(int w)
c62d2810 402{
403 _IRQlow&=~w;
404}
405
af32b6c2 406void TriggerIRQ_c(void) /* This function should probably be phased out. */
c62d2810 407{
408 _IRQlow|=FCEU_IQTEMP;
409}
410
af32b6c2 411void TriggerNMINSF_c(void)
c62d2810 412{
413 ADDCYC(7);
414 PUSH(_PC>>8);
415 PUSH(_PC);
416 PUSH((_P&~B_FLAG)|(U_FLAG));
417 _PC=0x3800;
418}
419
af32b6c2 420void TriggerNMI_c(void)
c62d2810 421{
422 _IRQlow|=FCEU_IQNMI;
423}
424
425static void TriggerNMIReal(void)
426{
427 if(!_jammed)
428 {
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 {
447 ADDCYC(7);
448 PUSH(_PC>>8);
449 PUSH(_PC);
c0bf6f9f 450 _P&=~B_FLAG;
451 PUSH(_P|U_FLAG);
c62d2810 452 _P|=I_FLAG;
453 _PC=RdMem(0xFFFE);
454 _PC|=RdMem(0xFFFF)<<8;
c0bf6f9f 455#ifdef DEBUG_ASM_6502
456 PC_prev = _PC;
457 OP_prev = 0x101;
458#endif
c62d2810 459 }
460}
461
af32b6c2 462void X6502_Reset_c(void)
c62d2810 463{
464 _PC=RdMem(0xFFFC);
465 _PC|=RdMem(0xFFFD)<<8;
466 if(FCEUGameInfo.type==GIT_NSF) _PC=0x3830;
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;
516 b1=RdMem(_PC);
370cff9a 517 ADDCYC(CycTable[b1]);
518 temp=_tcount;
c62d2810 519
520 temp*=48;
521
522 fhcnt-=temp;
523 if(fhcnt<=0)
524 {
525 FrameSoundUpdate();
526 fhcnt+=fhinc;
527 }
528
c62d2810 529 if(PCMIRQCount>0)
530 {
531 PCMIRQCount-=temp;
532 if(PCMIRQCount<=0)
533 {
534 vdis=1;
535 if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40))
536 {
537 extern uint8 SIRQStat;
538 SIRQStat|=0x80;
af32b6c2 539 X6502_IRQBegin_c(FCEU_IQDPCM);
c62d2810 540 }
541 }
542 }
92e249b1 543
c0bf6f9f 544#ifdef DEBUG_ASM_6502
545 PC_prev = _PC;
546 OP_prev = b1;
c0bf6f9f 547#endif
c62d2810 548 //printf("$%04x:$%02x\n",_PC,b1);
549 //_PC++;
550 //printf("$%02x\n",b1);
551 _PC++;
552 switch(b1)
553 {
554 #include "ops.h"
937bf65b 555 }
af32b6c2 556
370cff9a 557 temp=_tcount; /* Gradius II (J) glitches if _tcount is not used */
558 _tcount=0;
559
560 if(MapIRQHook) {
561#ifdef DEBUG_ASM_6502
562 mapirq_cyc_c = temp;
563#endif
564 MapIRQHook(temp);
565 }
566
af32b6c2 567#ifdef DEBUG_ASM_6502
568 _PI=_P;
569#endif
c62d2810 570 }
571}
937bf65b 572
573