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