098 renderer added
[fceu.git] / x6502.c
diff --git a/x6502.c b/x6502.c
index c1e55b3..c20edf9 100644 (file)
--- a/x6502.c
+++ b/x6502.c
 #include "sound.h"
 #include "cart.h"
 
+#include "dprintf.h"
+
+#ifdef DEBUG_ASM_6502
+#include <stdio.h>
+#include <stdlib.h>
+extern uint32 PC_prev, OP_prev;
+extern uint8  dreads[4];
+extern uint32 dwrites_c[2];
+extern int dread_count_c, dwrite_count_c;
+extern int mapirq_cyc_c;
+extern void (*MapIRQHook)(int a);
+#define DummyRdMem(...)
+#else
+#define DummyRdMem RdMem
+void FP_FASTAPASS(1) (*MapIRQHook)(int a);
+#endif
+
 X6502 X;
 uint32 timestamp;
-void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 
 #define _PC              X.PC
 #define _A               X.A
@@ -37,7 +53,7 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 #define _S               X.S
 #define _P               X.P
 #define _PI              X.mooPI
-#define _PZ              X.PZ
+//#define _PZ              X.PZ                // unused?
 #define _DB              X.DB
 #define _count           X.count
 #define _tcount          X.tcount
@@ -47,33 +63,48 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 
 static INLINE uint8 RdMem(unsigned int A)
 {
- // notaz: try to avoid lookup of every address at least for ROM and RAM areas
- // I've verified that if ARead[0xfff0] points to CartBR, it is always normal ROM read.
-#if 0
- if ((A&0x8000)/* && ARead[0xfff0] == CartBR*/) {
-  return (_DB=Page[A>>11][A]);
+ int _DB1=ARead[A](A);
+#ifdef DEBUG_ASM_6502
+ //_DB=_DB1;
+ //printf("a == %x, pc == %x\n", A, _PC);
+ if (A >= 0x2000) {
+  if (A == _PC || A == _PC - 1 || A == _PC + 1) {
+   //printf("fr: %02x\n", _DB1);
+  }
+  _DB=_DB1;
  }
-#endif
-#if 0 // enabling this causes 4fps slowdown. Why?
- if ((A&0xe000) == 0) { // RAM area (always 0-0x1fff)
-  return (_DB=RAM[A&0x7FF]);
+ if (A >= 0x2000 && A != _PC - 1) {
+  dreads[dread_count_c++] = _DB1;
+  if (dread_count_c > 4) { printf("dread_count out of range\n"); exit(1); }
  }
+#else
+ _DB=_DB1;
 #endif
- return((_DB=ARead[A](A)));
+ return _DB1;
 }
 
 static INLINE void WrMem(unsigned int A, uint8 V)
 {
+ //printf("w [%04x] %02x\n", A, V);
  if ((A&0xe000) == 0) { // RAM area (always 0-0x1fff)
   RAM[A&0x7FF] = V;
   return;
  }
  BWrite[A](A,V);
+#ifdef DEBUG_ASM_6502
+ dwrites_c[dwrite_count_c++] = (A<<8)|V;
+ if (dwrite_count_c > 2) { printf("dwrite_count_c out of range\n"); exit(1); }
+#endif
 }
 
 static INLINE uint8 RdRAM(unsigned int A)
 {
- return((_DB=RAM[A]));
+ //return((_DB=RAM[A]));
+ int _DB1=RAM[A];
+#ifndef DEBUG_ASM_6502
+ _DB=_DB1;
+#endif
+ return _DB1;
 }
 
 static INLINE void WrRAM(unsigned int A, uint8 V)
@@ -83,12 +114,12 @@ static INLINE void WrRAM(unsigned int A, uint8 V)
 
 static INLINE void ADDCYC(int x)
 {
//_tcount+=x;
+ _tcount+=x;
  _count-=x*48;
  timestamp+=x;
 }
 
-void FASTAPASS(1) X6502_AddCycles(int x)
+void FASTAPASS(1) X6502_AddCycles_c(int x)
 {
  ADDCYC(x);
 }
@@ -130,7 +161,7 @@ static uint8 ZNTable[256] = {
 //#define X_ZN(zort)         _P&=~(Z_FLAG|N_FLAG);_P|=ZNTable[zort]
 //#define X_ZNT(zort)  _P|=ZNTable[zort]
 #define X_ZN(zort)         _P&=~(Z_FLAG|N_FLAG);if(!zort) _P|=Z_FLAG;else _P|=zort&N_FLAG
-#define X_ZNT(zort)    if(!zort) _P|=Z_FLAG;else _P|=zort&N_FLAG
+#define X_ZNT(zort)    if(!zort) _P|=Z_FLAG;else _P|=(zort&N_FLAG)
 
 /* Care must be taken if you want to turn this into a macro.  Use { and }. */
 #define JR();  \
@@ -241,7 +272,7 @@ static uint8 ZNTable[256] = {
  if((target^tmp)&0x100)        \
  {     \
   target&=0xFFFF;      \
-  RdMem(target^0x100); \
+  DummyRdMem(target^0x100);    \
   ADDCYC(1);   \
  }     \
 }
@@ -254,7 +285,7 @@ static uint8 ZNTable[256] = {
  target=rt;    \
  target+=i;    \
  target&=0xFFFF;       \
RdMem((target&0x00FF)|(rt&0xFF00));   \
DummyRdMem((target&0x00FF)|(rt&0xFF00));      \
 }
 
 /* Zero Page */
@@ -292,7 +323,7 @@ static uint8 ZNTable[256] = {
  if((target^rt)&0x100) \
  {     \
   target&=0xFFFF;      \
-  RdMem(target^0x100); \
+  DummyRdMem(target^0x100);    \
   ADDCYC(1);   \
  }     \
 }
@@ -307,7 +338,7 @@ static uint8 ZNTable[256] = {
  rt|=RdRAM(tmp)<<8;    \
  target=rt;    \
  target+=_Y;   \
RdMem((target&0x00FF)|(rt&0xFF00));   \
DummyRdMem((target&0x00FF)|(rt&0xFF00));      \
 }
 
 /* Now come the macros to wrap up all of the above stuff addressing mode functions
@@ -348,6 +379,7 @@ static uint8 ZNTable[256] = {
 
 static uint8 CycTable[256] =
 {
+/*       0 1 2 3 4 5 6 7 8 9 a b c d e f */
 /*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
 /*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
 /*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
@@ -366,31 +398,24 @@ static uint8 CycTable[256] =
 /*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
 };
 
-void FASTAPASS(1) X6502_IRQBegin(int w)
+void FASTAPASS(1) X6502_IRQBegin_c(int w)
 {
+ dprintf("IRQB %02x",w);
  _IRQlow|=w;
 }
 
-void FASTAPASS(1) X6502_IRQEnd(int w)
+void FASTAPASS(1) X6502_IRQEnd_c(int w)
 {
+ dprintf("IRQE %02x",w);
  _IRQlow&=~w;
 }
 
-void TriggerIRQ(void)  /* This function should probably be phased out. */
+void TriggerIRQ_c(void)        /* This function should probably be phased out. */
 {
  _IRQlow|=FCEU_IQTEMP;
 }
 
-void TriggerNMINSF(void)
-{
- ADDCYC(7);
- PUSH(_PC>>8);
- PUSH(_PC);
- PUSH((_P&~B_FLAG)|(U_FLAG));
- _PC=0x3800;
-}
-
-void TriggerNMI(void)
+void TriggerNMI_c(void)
 {
  _IRQlow|=FCEU_IQNMI;
 }
@@ -399,12 +424,18 @@ static void TriggerNMIReal(void)
 {
  if(!_jammed)
  {
+  dprintf("NMI");
   ADDCYC(7);
   PUSH(_PC>>8);
   PUSH(_PC);
-  PUSH((_P&~B_FLAG)|(U_FLAG));
+  _P&=~B_FLAG;
+  PUSH(_P|U_FLAG);
   _PC=RdMem(0xFFFA);
   _PC|=RdMem(0xFFFB)<<8;
+#ifdef DEBUG_ASM_6502
+  PC_prev = _PC;
+  OP_prev = 0x100;
+#endif
  }
 }
 
@@ -412,36 +443,40 @@ void TriggerIRQReal(void)
 {
  if(!(_PI&I_FLAG) && !_jammed)
  {
+  dprintf("IRQ");
   ADDCYC(7);
   PUSH(_PC>>8);
   PUSH(_PC);
-  PUSH((_P&~B_FLAG)|(U_FLAG));
+  _P&=~B_FLAG;
+  PUSH(_P|U_FLAG);
   _P|=I_FLAG;
   _PC=RdMem(0xFFFE);
   _PC|=RdMem(0xFFFF)<<8;
+#ifdef DEBUG_ASM_6502
+  PC_prev = _PC;
+  OP_prev = 0x101;
+#endif
  }
 }
 
-void X6502_Reset(void)
+void X6502_Reset_c(void)
 {
   _PC=RdMem(0xFFFC);
   _PC|=RdMem(0xFFFD)<<8;
-  if(FCEUGameInfo.type==GIT_NSF) _PC=0x3830;
   _jammed=0;
   _PI=_P=I_FLAG;
 }
 
-void X6502_Power(void)
+void X6502_Power_c(void)
 {
  memset((void *)&X,0,sizeof(X));
  timestamp=0;
- X6502_Reset();
+ X6502_Reset_c();
 }
 
 
 //int asdc = 0;
-
-void X6502_Run_(void/*int32 cycles*/)
+void X6502_Run_c(void/*int32 cycles*/)
 {
 /*
        if(PAL)
@@ -466,16 +501,24 @@ void X6502_Run_(void/*int32 cycles*/)
           TriggerIRQReal();
 
          _IRQlow&=~(FCEU_IQTEMP|FCEU_IQNMI);
-         if(_count<=0) {_PI=_P;return;} /* Should increase accuracy without a */
-                                          /* major speed hit. */
+         if(_count<=0)
+         {
+#ifdef DEBUG_ASM_6502
+          if(MapIRQHook) mapirq_cyc_c = _tcount;
+          _tcount=0;
+#endif
+          _PI=_P;
+          return; /* Should increase accuracy without a major speed hit. */
+         }
         }
         _PI=_P;
+#ifdef DEBUG_ASM_6502
+        b1=RdMem(_PC++); _PC--;
+#else
         b1=RdMem(_PC);
-        temp=CycTable[b1];
-        ADDCYC(temp);
-        //temp=_tcount;
-        //_tcount=0;
-        if(MapIRQHook) MapIRQHook(temp);
+#endif
+        ADDCYC(CycTable[b1]);
+        temp=_tcount;
 
         temp*=48;
 
@@ -486,7 +529,6 @@ void X6502_Run_(void/*int32 cycles*/)
          fhcnt+=fhinc;
         }
 
-
         if(PCMIRQCount>0)
         {
          PCMIRQCount-=temp;
@@ -501,6 +543,11 @@ void X6502_Run_(void/*int32 cycles*/)
           }
          }
         }
+
+#ifdef DEBUG_ASM_6502
+        PC_prev = _PC;
+        OP_prev = b1;
+#endif
          //printf("$%04x:$%02x\n",_PC,b1);
         //_PC++;
         //printf("$%02x\n",b1);
@@ -509,6 +556,20 @@ void X6502_Run_(void/*int32 cycles*/)
          {
           #include "ops.h"
          }
+
+        temp=_tcount; /* Gradius II (J) glitches if _tcount is not used */
+        _tcount=0;
+
+        if(MapIRQHook) {
+#ifdef DEBUG_ASM_6502
+         mapirq_cyc_c = temp;
+#endif
+         MapIRQHook(temp);
+        }
+
+#ifdef DEBUG_ASM_6502
+        _PI=_P;
+#endif
        }
 }