mmuhack, 6502 tweaks, fskip
authornotaz <notasas@gmail.com>
Thu, 12 Apr 2007 17:07:46 +0000 (17:07 +0000)
committernotaz <notasas@gmail.com>
Thu, 12 Apr 2007 17:07:46 +0000 (17:07 +0000)
git-svn-id: file:///home/notaz/opt/svn/fceu@101 be3aeb3a-fb24-0410-a615-afba39da0efa

25 files changed:
Makefile.gp2x
cart.c
cart.h
drawing.h
driver.h
drivers/gp2x/asmutils.h [new file with mode: 0644]
drivers/gp2x/asmutils.s [new file with mode: 0644]
drivers/gp2x/dface.h
drivers/gp2x/gp2x-video.c
drivers/gp2x/gp2x.c
drivers/gp2x/input.c
drivers/gp2x/main.c
drivers/gp2x/minimal.c
drivers/gp2x/mmuhack.c [new file with mode: 0644]
drivers/gp2x/mmuhack.o [new file with mode: 0644]
drivers/gp2x/mmuhack.txt [new file with mode: 0644]
drivers/gp2x/squidgehack.c [new file with mode: 0644]
drivers/gp2x/squidgehack.h [new file with mode: 0644]
drivers/gp2x/throttle.c
drivers/gp2x/throttle.h
fce.c
video.c
video.h
x6502.c
x6502.h

index 4b1553a..ac85a1f 100644 (file)
@@ -1,12 +1,18 @@
-CC     = arm-linux-gcc
-STRIP  = arm-linux-strip
-TFLAGS  = -mcpu=arm920t -Izlib -DGP2X=1 -DLSB_FIRST -DUNIX -DPSS_STYLE=1 -DZLIB -DFRAMESKIP -D_REENTRANT
+CROSS  = arm-linux-
+CC     = $(CROSS)gcc
+STRIP  = $(CROSS)strip
+AS     = $(CROSS)as
+TFLAGS  = -Winline -mcpu=arm920t -Izlib -DGP2X=1 -DLSB_FIRST -DUNIX -DPSS_STYLE=1 -DZLIB -DFRAMESKIP -D_REENTRANT
+ASFLAGS        = -mcpu=arm920t -mfloat-abi=soft
 RM     = rm -f
 B      = drivers/gp2x/
 ifdef DEBUG
 TFLAGS += -ggdb
+LDRIVER        += -ggdb
 else
-TFLAGS += -O3
+TFLAGS += -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math
+TFLAGS += -O3 # -pg
+LDRIVER        += -O3 # -pg
 endif
 
 all:           fceu
@@ -16,23 +22,23 @@ gpfce: fceu
 
 include zlib/Makefile
 
-OBJDRIVER      = ${B}minimal.o ${B}gp2x.o ${B}main.o ${B}throttle.o ${B}unix-netplay.o ${B}gp2x-sound.o ${B}gp2x-video.o ${B}lnx-joystick.o drivers/common/cheat.o drivers/common/config.o drivers/common/args.o drivers/common/vidblit.o ${UNZIPOBJS} ppu.o
-LDRIVER                = -L /mnt/sd/lib  -L/mnt/sd/gp2x/usr/lib -lm -lz -static
+OBJDRIVER       = ${B}minimal.o ${B}squidgehack.o ${B}asmutils.o ${B}gp2x.o ${B}main.o ${B}throttle.o \
+               ${B}unix-netplay.o ${B}gp2x-sound.o ${B}gp2x-video.o ${B}lnx-joystick.o \
+               drivers/common/cheat.o drivers/common/config.o drivers/common/args.o drivers/common/vidblit.o ${UNZIPOBJS} ppu.o
+LDRIVER                += -L /mnt/sd/lib  -L/mnt/sd/gp2x/usr/lib -lm -lz -static
 
 include Makefile.base
 
-${B}lnx-joystick.o:    ${B}lnx-joystick.c
 ${B}main.o:            ${B}main.c ${B}main.h ${B}usage.h ${B}input.c
 ${B}gp2x.o:            ${B}gp2x.c ${B}gp2x.h
-${B}gp2x-video.o:      ${B}gp2x-video.c
-${B}gp2x-video.o:      ${B}minimal.c
-${B}gp2x-sound.o:      ${B}gp2x-sound.c
-${B}unix-netplay.o:    ${B}unix-netplay.c
 ${B}throttle.o:         ${B}throttle.c ${B}main.h ${B}throttle.h
 ppu.o:                 ppu.c ppu.h
 
 include Makefile.common
 
+#x6502.o:      x6502.c x6502.h ops.h fce.h sound.h
+#      $(CC) $(CFLAGS) -finline-limit=60000 -c $< -o $@
+
 up: fceu
        cp -v fceu /mnt/gp2x/mnt/sd/emus/Gpfce_v02/gpfce
 
diff --git a/cart.c b/cart.c
index 0f9e10e..6a32021 100644 (file)
--- a/cart.c
+++ b/cart.c
@@ -31,7 +31,7 @@
 #include "general.h"
 #include "svga.h"
 
-/* 
+/*
    This file contains all code for coordinating the mapping in of the
    address space external to the NES.
    It's also (ab)used by the NSF code.
@@ -110,7 +110,7 @@ void SetupCartPRGMapping(int chip, uint8 *p, uint32 size, int ram)
  PRGmask4[chip]=(size>>12)-1;
  PRGmask8[chip]=(size>>13)-1;
  PRGmask16[chip]=(size>>14)-1;
- PRGmask32[chip]=(size>>15)-1; 
+ PRGmask32[chip]=(size>>15)-1;
 
  PRGram[chip]=ram?1:0;
 }
@@ -444,7 +444,7 @@ void OpenGenie(void)
     goto grerr;
   }
   fclose(fp);
+
   /* Workaround for the FCE Ultra CHR page size only being 1KB */
   for(x=0;x<4;x++)
    memcpy(GENIEROM+4096+(x<<8),GENIEROM+4096,256);
@@ -492,7 +492,7 @@ static DECLFW(GenieWrite)
               else
               {
                modcon=V^0xFF;
-               if(V==0x71) 
+               if(V==0x71)
                modcon=0;
               }
               break;
@@ -549,7 +549,7 @@ void FixGenieMap(void)
 
  VPageR=VPage;
  FlushGenieRW();
+
  for(x=0;x<3;x++)
   if((modcon>>(4+x))&1)
   {
diff --git a/cart.h b/cart.h
index b066771..2a91681 100644 (file)
--- a/cart.h
+++ b/cart.h
@@ -6,6 +6,7 @@ void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram);
 void SetupCartMirroring(int m, int hard, uint8 *extra);
 
 DECLFR(CartBR);
+
 extern uint8 *PRGptr[32];
 extern uint8 *CHRptr[32];
 
index 8850c7a..61a94d3 100644 (file)
--- a/drawing.h
+++ b/drawing.h
@@ -16,7 +16,7 @@ static void DrawDips(void)
    {
     *dest=0x81818181;
     dest+=2;
-   }   
+   }
 
   dest=(uint32 *)(XBuf+272*(12+4)+164+6 );
   for(x=0;x<8;x++,dest+=2)
@@ -25,10 +25,10 @@ static void DrawDips(void)
 
    if(!((vsdip>>x)&1))
     da+=(272>>2)*10;
-    
+
    for(y=4;y;y--,da+=272>>2)
     *da=0x80808080;
-   
+
   }
 }
 
@@ -38,9 +38,9 @@ static void DrawMessage(void)
   {
    uint8 *t;
    howlong--;
-   t=XBuf+(FSettings.LastSLine-29)*272+32;
+   t=XBuf+(FSettings.LastSLine-29)*320+32;
    if(t>=XBuf)
-    DrawTextTrans(t,272,(uint8 *)errmsg,132);
+    DrawTextTrans(t,320,(uint8 *)errmsg,132);
   }
 }
 
@@ -80,11 +80,11 @@ static void DrawState(void)
  if(XBaf>=XBuf)
  for(z=1;z<11;z++)
  {
-  if(SaveStateStatus[z%10]) 
+  if(SaveStateStatus[z%10])
    {
           for(y=0;y<13;y++)
            for(x=0;x<21;x++)
-           XBaf[y*272+x+z*21+z]=sstat[y*21+x+(z-1)*21*12];           
+           XBaf[y*272+x+z*21+z]=sstat[y*21+x+(z-1)*21*12];
    } else {
           for(y=0;y<13;y++)
            for(x=0;x<21;x++)
@@ -103,7 +103,7 @@ static void DrawState(void)
     for(x=0;x<21;x++)
      XBaf[3264+x+z*21+z*1]=132;
    }
-  } 
+  }
  StateShow--;
 }
 
@@ -114,9 +114,9 @@ void DrawTextTrans(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor)
        uint8 y;
        uint8 z;
 
-       for(x=0;x<length;x++)    
-         for(y=0;y<8;y++)       
-          for(z=0;z<8;z++) 
+       for(x=0;x<length;x++)
+         for(y=0;y<8;y++)
+          for(z=0;z<8;z++)
            if((fontdata2[(textmsg[x]<<3)+y]>>z)&1) dest[y*width+(x<<3)+z]=fgcolor;
 }
 
index f5c06c1..cfaf2cf 100644 (file)
--- a/driver.h
+++ b/driver.h
@@ -3,7 +3,7 @@
 
 /* Prototypes for platform interface functions follow: */
 
-void FCEUD_Update(uint8 *XBuf, int16 *Buffer, int Count);
+void FCEUD_Update(uint8 *buf, int16 *Buffer, int Count);
 
 /* Video interface */
 void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b);
diff --git a/drivers/gp2x/asmutils.h b/drivers/gp2x/asmutils.h
new file mode 100644 (file)
index 0000000..94c89ea
--- /dev/null
@@ -0,0 +1,2 @@
+void flushcache(unsigned int beginning_addr, unsigned int end_addr, unsigned int flags);\r
+\r
diff --git a/drivers/gp2x/asmutils.s b/drivers/gp2x/asmutils.s
new file mode 100644 (file)
index 0000000..c87a3ab
--- /dev/null
@@ -0,0 +1,9 @@
+@ vim:filetype=armasm
+
+@ test
+.global flushcache @ beginning_addr, end_addr, flags
+
+flushcache:
+    swi #0x9f0002
+    mov pc, lr
+
index 6ff4459..c4d2bfb 100644 (file)
@@ -6,7 +6,7 @@ void DoDriverArgs(void);
 void GetBaseDirectory(char *BaseDirectory);
 
 int InitSound(void);
-void WriteSound(int16 *Buffer, int Count, int NoWaiting);
+void WriteSound(int16 *Buffer, int Count);
 void KillSound(void);
 void SilenceSound(int s); /* DOS and SDL */
 
@@ -26,7 +26,7 @@ void KillKeyboard(void);
 
 int InitVideo(void);
 void KillVideo(void);
-void BlitScreen(uint8 *XBuf);
+void BlitScreen(uint8 *buf);
 void LockConsole(void);
 void UnlockConsole(void);
 void ToggleFS();               /* SDL */
index 6433724..8bd2be1 100644 (file)
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <sys/time.h>
 
+#include "../../video.h"
+
 #include "gp2x.h"
 #include "minimal.h"
 
@@ -27,7 +29,7 @@ extern int showfps;
 static char fps_str[32];
 static int framesEmulated, framesRendered;
 
-int stretch_offset=32;
+int scaled_display=0;
 int paletterefresh;
 
 #define FPS_COLOR 61
@@ -136,6 +138,7 @@ void CleanSurface(void)
                memset (gp2x_screen8, 0x80, 320*240);
                gp2x_video_flip();
        }
+       XBuf = gp2x_screen8;
 }
 
 
@@ -154,6 +157,7 @@ int InitVideo(void)
 
        srendline=0;
        erendline=239;
+       XBuf = gp2x_screen8; // TODO: use mmuhacked upper mem
        return 1;
 }
 
@@ -194,19 +198,19 @@ static INLINE void printFps(uint8 *screen)
                prevsec = tv_now.tv_sec;
        }
 
-       if (stretch_offset > 0)
+       if (!scaled_display)
        {
                if (needfpsflip)
                {
                        int y, *destt = (int *) screen;
-                       for (y = 240; y; y--)
+                       for (y = 20/*240*/; y; y--)
                        {
                                *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
                                *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
-                               destt += 64;
+                               destt += 64+8;
 
-                               *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
-                               *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
+                               //*destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
+                               //*destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F;
                        }
                        if (showfps)
                        {
@@ -221,46 +225,23 @@ static INLINE void printFps(uint8 *screen)
        {
                if (showfps)
                {
-                       gp2x_text(screen, 0, 0, fps_str, FPS_COLOR, 0);
+                       gp2x_text(screen+32, 0, 0, fps_str, FPS_COLOR, 0);
                }
        }
 }
 
 
-void BlitScreen(uint8 * XBuf)
+void BlitScreen(uint8 *buf)
 {
-       int x, y, yinc;
-
        framesEmulated++;
 
-       if (!XBuf) return;
+       if (!buf) return;
 
        framesRendered++;
 
-#if 1 // 48->54
-       y=240;
-       yinc=272*(y-1);
-       while (y--)
-       {
-               int* dest=(int *) (gp2x_screen8+((y << 8) + (y << 6))+stretch_offset);
-
-               int* src=(int *) (XBuf+yinc);
-               x=64;
-               while (x--)
-               {
-                       dest[x]=src[x];
-               }
-               yinc-=272;
-       }
-
-       if (paletterefresh)
-       {
-               gp2x_video_setpalette();
-               paletterefresh = 0;
-       }
-#endif
        printFps(gp2x_screen8);
        gp2x_video_flip();
+       XBuf = gp2x_screen8;
 }
 
 
index 0f3b9aa..fc70dd1 100644 (file)
@@ -14,6 +14,7 @@ extern void SetVideoScaling(int, int, int);
 
 //#define SOUND_RATE 44100
 #define SOUND_RATE 22050
+#define GP2X_PORT_VERSION "0.3"
 
 DSETTINGS Settings;
 CFGSTRUCT DriverConfig[]={
@@ -202,13 +203,16 @@ char *GetKeyboard(void)
 #include "unix-basedir.h"
 extern int showfps;
 extern int swapbuttons;
+char **g_argv;
 
 int main(int argc, char *argv[])
 {
+       g_argv = argv;
 
-        puts("Starting GPFCE - Port version 0.2 05-29-2006");
+        puts("Starting GPFCE - Port version " GP2X_PORT_VERSION " (" __DATE__ ")");
         puts("Based on FCE Ultra "VERSION_STRING"...");
-        puts("Ported by Zheng Zhu\n");
+        puts("Ported by Zheng Zhu");
+        puts("Additional optimization/misc work by notaz\n");
 
          //  stereo
         //gp2x_init (1000, 8, SOUND_RATE, 16, 1, 60);
@@ -218,6 +222,9 @@ int main(int argc, char *argv[])
         // mono 22khz
        gp2x_init (1000, 8, SOUND_RATE, 16, 0, 60);
 
+        // unscale the screen, in case this is bad.
+        SetVideoScaling(320, 320, 240);
+
         SetDefaults();
         int ret=CLImain(argc,argv);
 
index 8936ec0..704cb3a 100644 (file)
 
 #include "minimal.h"
 extern int swapbuttons;
-extern int stretch_offset;
+extern int scaled_display;
 extern int FSkip_setting;
 
 extern void SetVideoScaling(int pixels,int width,int height);
-INLINE long UpdateGamepadGP2X(void);
+static INLINE long UpdateGamepadGP2X(void);
 
 
 
@@ -125,7 +125,7 @@ static void setsoundvol(int soundvolume)
  * GP2x joystick reader
  *
  */
-INLINE long UpdateGamepadGP2X(void)
+static INLINE long UpdateGamepadGP2X(void)
 {
   uint32 JS=0;
 
@@ -173,23 +173,15 @@ INLINE long UpdateGamepadGP2X(void)
           // still pressed down from stretching from last one
           goto no_pad;
        }
-        if (stretch_offset == 32)
-       {
-          stretch_offset=0;
-       }
-        else
-       {
-          stretch_offset=32;
-       }
+        scaled_display = !scaled_display;
 
-        if (stretch_offset == 32)
+        if (scaled_display)
        {
-          SetVideoScaling(320, 320, 240);
-          CleanSurface();
+         SetVideoScaling(320, 256, 240);
        }
         else
        {
-         SetVideoScaling(320, 256, 240);
+          SetVideoScaling(320, 320, 240);
        }
 
         goto no_pad;
index fc9c7b6..ad36e01 100644 (file)
@@ -304,17 +304,23 @@ int CLImain(int argc, char *argv[])
        FCEUGI *tmp;
        int ret;
 
+        if(argc<=1)
+        {
+         ShowUsage(argv[0]);
+         return 1;
+        }
+
+        if(!DriverInitialize())
+        {
+        return 1;
+        }
+
        if(!(ret=FCEUI_Initialize()))
          return(1);
         GetBaseDirectory(BaseDirectory);
        FCEUI_SetBaseDirectory(BaseDirectory);
 
        CreateDirs();
-        if(argc<=1)
-        {
-         ShowUsage(argv[0]);
-         return 1;
-        }
         LoadConfig();
         DoArgs(argc-2,&argv[1]);
        if(cpalette)
@@ -329,11 +335,6 @@ int CLImain(int argc, char *argv[])
         }
        ParseGI(tmp);
        //RefreshThrottleFPS();
-        if(!DriverInitialize())
-        {
-         ret=0;
-         goto dk;
-        }
        InitOtherInput();
        FCEUI_Emulate();
 
@@ -373,13 +374,13 @@ static void DriverKill(void)
  inited=0;
 }
 
-void FCEUD_Update(uint8 *XBuf, int16 *Buffer, int Count)
+void FCEUD_Update(uint8 *xbuf, int16 *Buffer, int Count)
 {
  if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
   SpeedThrottle();
- BlitScreen(XBuf);
- if(Count)
-  WriteSound(Buffer,Count,NoWaiting);
+ BlitScreen(xbuf);
+ if(Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
+  WriteSound(Buffer,Count);
  FCEUD_UpdateInput();
 }
 
index 369a1c9..facef9e 100644 (file)
 */
 
 #include "minimal.h"
+#include "squidgehack.h"
+#include "asmutils.h"
 
          unsigned char  *gp2x_screen8                 ,*gp2x_upperRAM;
          unsigned long   gp2x_dev[8]={0,0,0,0,0,0,0,0}, gp2x_physvram[8], *gp2x_memregl,       gp2x_volume,                      gp2x_ticks_per_second;
-volatile unsigned long   gp2x_sound_pausei=1,           gp2x_ticks=0,      gp2x_sound=0,      *gp2x_dualcore_ram;
+volatile unsigned long   gp2x_sound_pausei=1,           gp2x_ticks=0,      gp2x_sound=0,      *gp2x_dualcore_ram=0;
          unsigned short *gp2x_memregs,                 *gp2x_screen15,    *gp2x_logvram15[4],  gp2x_sound_buffer[4+((44100/25)*2)*8]; //25 Hz gives our biggest supported sampling buffer
 volatile unsigned short  gp2x_palette[512];
 
 extern void gp2x_sound_frame(void *blah, void *buff, int samples);
 
+// hack
+static int scaling_enabled = 0;
 
 void gp2x_video_flip(void)
 {
   unsigned long address=gp2x_physvram[gp2x_physvram[7]];
+  if (scaling_enabled) address += 32;
+
+  // since we are using the mmu hack, we must flush the cache first
+  // (the params are most likely wrong, but they seem to work somehow)
+  flushcache(address, address + 320*240, 0);
 
   if(++gp2x_physvram[7]==4) gp2x_physvram[7]=0;
   gp2x_screen15=gp2x_logvram15[gp2x_physvram[7]];
@@ -258,6 +267,7 @@ static void *gp2x_sound_play(void *blah)
 }
 #endif
 
+#if 0
 static void gp2x_initqueue(gp2x_queue *q, unsigned long queue_items, unsigned long *position920t, unsigned long *position940t)
 {
   q->head  = q->tail  = q->items = 0;
@@ -281,8 +291,7 @@ static void gp2x_enqueue(gp2x_queue *q, unsigned long data)
   q->items--;
   return q->place920t[q->tail = (q->tail < q->max_items ? q->tail+1 : 0)];
 } */
-
-
+#endif
 
        void gp2x_dualcore_pause(int yes) { if(yes) gp2x_memregs[0x0904>>1] &= 0xFFFE; else gp2x_memregs[0x0904>>1] |= 1; }
 static void gp2x_940t_reset(int yes)     { gp2x_memregs[0x3B48>>1] = ((yes&1) << 7) | (0x03); }
@@ -311,6 +320,7 @@ static void gp2x_dualcore_registers(int save)
  }
 }
 
+#if 0
 void gp2x_dualcore_sync(void)
 {
   gp2x_queue *q=(gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR);
@@ -351,6 +361,7 @@ void gp2x_dualcore_launch_program_from_disk(const char *file, unsigned long offs
  free(data);
  fclose(in);
 }
+#endif
 
 void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, int Hz)
 {
@@ -362,6 +373,7 @@ void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, in
   int frag=0;
   int channels=1;
   int stereoLocal=0;
+  int ret;
 
   gp2x_ticks_per_second=7372800/ticks_per_second;
 
@@ -369,6 +381,23 @@ void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, in
   if(!gp2x_dev[1])   gp2x_dev[1] = open("/dev/fb1",   O_RDWR);
   if(!gp2x_dev[2])   gp2x_dev[2] = open("/dev/mem",   O_RDWR);
 
+  ioctl(gp2x_dev[gp2x_physvram[7]=0], FBIOGET_FSCREENINFO, &fixed_info);
+   gp2x_physvram[2]=gp2x_physvram[0]=fixed_info.smem_start;
+   gp2x_screen15=gp2x_logvram15[2]=gp2x_logvram15[0]=
+    (unsigned short *)mmap(0, 0x20000*2, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], gp2x_physvram[0]);
+                                        gp2x_screen8=(unsigned char *)gp2x_screen15;
+  printf("/dev/fb0 is @ %08lx / %p\n", gp2x_physvram[0], gp2x_screen15);
+
+  ioctl(gp2x_dev[1], FBIOGET_FSCREENINFO, &fixed_info);
+   gp2x_physvram[3]=gp2x_physvram[1]=fixed_info.smem_start;
+   gp2x_logvram15[3]=gp2x_logvram15[1]=
+    (unsigned short *)mmap(0, 0x20000*2, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], gp2x_physvram[1]);
+  printf("/dev/fb1 is @ %08lx / %p\n", gp2x_physvram[1], gp2x_logvram15[1]);
+
+  // apply the MMU hack
+  ret = mmuhack();
+  printf("squidge hack code finished and returned %s\n", ret ? "ok" : "fail");
+
   // don't run sound right now
   if ( gp2x_do_sound)
   {
@@ -376,7 +405,7 @@ void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, in
     if(!gp2x_dev[4])   gp2x_dev[4] = open("/dev/mixer", O_RDWR);
   }
 
-  gp2x_dualcore_ram=(unsigned long  *)mmap(0, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x03000000);
+//  gp2x_dualcore_ram=(unsigned long  *)mmap(0, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x03000000);
 /*gp2x_dualcore_ram=(unsigned long  *)mmap(0, 0x2000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x02000000);*/
        gp2x_memregl=(unsigned long  *)mmap(0, 0x10000,   PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0xc0000000);
         gp2x_memregs=(unsigned short *)gp2x_memregl;
@@ -387,28 +416,20 @@ void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, in
               gp2x_memregs[0x0F16>>1] = 0x830a; usleep(100000);
               gp2x_memregs[0x0F58>>1] = 0x100c; usleep(100000); }
 
-  ioctl(gp2x_dev[gp2x_physvram[7]=0], FBIOGET_FSCREENINFO, &fixed_info);
-   gp2x_screen15=gp2x_logvram15[2]=gp2x_logvram15[0]=(unsigned short *)mmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, gp2x_dev[0], 0);
-                                        gp2x_screen8=(unsigned char *)gp2x_screen15;
-                   gp2x_physvram[2]=gp2x_physvram[0]=fixed_info.smem_start;
-
-  ioctl(gp2x_dev[1], FBIOGET_FSCREENINFO, &fixed_info);
-                 gp2x_logvram15[3]=gp2x_logvram15[1]=(unsigned short *)mmap(0, 320*240*2, PROT_WRITE, MAP_SHARED, gp2x_dev[1], 0);
-                   gp2x_physvram[3]=gp2x_physvram[1]=fixed_info.smem_start;
-
   gp2x_memregs[0x28DA>>1]=(((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/
   gp2x_memregs[0x290C>>1]=320*((bpp+1)/8);       /*line width in bytes*/
 
   memset(gp2x_screen15, 0, 320*240*2); gp2x_video_flip();
   memset(gp2x_screen15, 0, 320*240*2); gp2x_video_flip();
 
-  if(bpp==8)  gp2x_physvram[2]+=320*240,    gp2x_physvram[3]+=320*240,
-             gp2x_logvram15[2]+=320*240/2, gp2x_logvram15[3]+=320*240/2;
+  //if(bpp==8)  gp2x_physvram[2]+=320*240,    gp2x_physvram[3]+=320*240,
+  //           gp2x_logvram15[2]+=320*240/2, gp2x_logvram15[3]+=320*240/2;
+  if(bpp==8)  gp2x_physvram[2]+=0x20000,   gp2x_physvram[3]+=0x20000,
+             gp2x_logvram15[2]+=0x20000/2, gp2x_logvram15[3]+=0x20000/2;
 
 
  if ( gp2x_do_sound)
  {
-
     ioctl(gp2x_dev[3], SNDCTL_DSP_SPEED,  &rate);
     ioctl(gp2x_dev[3], SNDCTL_DSP_SETFMT, &bits);
 
@@ -426,7 +447,6 @@ void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, in
       first=0;
     }
   }
-
 }
 
 
@@ -436,6 +456,7 @@ void gp2x_deinit(void)
   while((gp2x_sound++)<1000000);                               //wait arm920t threads to finish
 
   gp2x_dualcore_registers(0);
+  mmuunhack();
 
   gp2x_memregs[0x28DA>>1]=0x4AB;                               //set video mode
   gp2x_memregs[0x290C>>1]=640;
@@ -454,6 +475,8 @@ void SetVideoScaling(int pixels,int width,int height)
 
         int bpp=(gp2x_memregs[0x28DA>>1]>>9)&0x3;  /* bytes per pixel */
 
+       scaling_enabled = (width == 320) ? 0 : 1;
+
         if(gp2x_memregs[0x2800>>1]&0x100) /* TV-Out ON? */
         {
                 xscale=489.0; /* X-Scale with TV-Out (PAL or NTSC) */
diff --git a/drivers/gp2x/mmuhack.c b/drivers/gp2x/mmuhack.c
new file mode 100644 (file)
index 0000000..c0c2189
--- /dev/null
@@ -0,0 +1,104 @@
+#include <linux/config.h>\r
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/init.h>\r
+#include <linux/miscdevice.h>\r
+#include <asm/memory.h>\r
+\r
+#define MMUHACK_MINOR 225\r
+#define DEVICE_NAME "mmuhack"\r
+\r
+#if __GNUC__ == 3\r
+#include <linux/version.h>\r
+static const char __module_kernel_version_gcc3[] __attribute__((__used__)) __attribute__((section(".modinfo"))) =\r
+"kernel_version=" UTS_RELEASE;\r
+#endif\r
+\r
+static ssize_t mmuhack_open(struct inode *inode, struct file *filp)\r
+{\r
+    unsigned int *pgtable;\r
+       unsigned int *cpt;\r
+    int i, j;\r
+       int ttb;\r
+       int ret = -EFAULT;\r
+\r
+       // get the pointer to the translation table base...\r
+       asm volatile(\r
+               "stmdb sp!, {r0}\n\t"\r
+               "mrc p15, 0, r0, c2, c0, 0\n\t"\r
+               "mov %0, r0\n\t"\r
+               "ldmia sp!, {r0}\n\t": "=r"(ttb)\r
+       );\r
+\r
+       pgtable = __va(ttb);\r
+\r
+    for (i = 0; i < 4096; i ++) if ( (pgtable[i] & 3) == 1 ) {\r
+               cpt = __va(pgtable[i] & 0xfffffc00);\r
+\r
+               for (j = 0; j < 256; j ++) {/*\r
+                       if ( (cpt[j] & 0xfe00000f) == 0x02000002 ) {\r
+                               // set C and B bits in upper 32MB memory area...\r
+                               printk("Set C&B bits %08x\n",cpt[j]);\r
+                               cpt[j] |= 0xFFC;\r
+                               ret = 0;\r
+                       }\r
+                                          */\r
+                       if (((cpt[j] & 0xff000000) == 0x02000000) && ((cpt[j] & 12)==0) )\r
+                       {\r
+                               //printk("Set C&B bits %08x\n",cpt[j]);\r
+                               cpt[j] |= 0xFFC;\r
+                       }\r
+                       //if ((a>=0x31 && a<=0x36) && ((cpt[i] & 12)==0))\r
+                       if (((cpt[j] & 0xff000000) == 0x03000000) && ((cpt[j] & 12)==0))\r
+                       {\r
+                               //printk("Set C&B bits %08x\n",cpt[j]);\r
+                               //printf("SDL   c and b bits not set, overwriting\n");\r
+                               cpt[j] |= 0xFFC;\r
+                       }\r
+               }\r
+    }\r
+\r
+       // drain the write buffer and flush the tlb caches...\r
+       asm volatile(\r
+               "stmdb sp!, {r0}\n\t"\r
+               "mov    r0, #0\n\t"\r
+               "mcr    15, 0, r0, cr7, cr10, 4\n\t"\r
+               "mcr    15, 0, r0, cr8, cr7, 0\n\t"\r
+               "ldmia sp!, {r0}\n\t"\r
+       );\r
+\r
+       if (ret == 0)\r
+               printk("MMU hack applied.\n");\r
+\r
+       return 0;\r
+}\r
+\r
+static struct file_operations mmuhack_fops = {\r
+    owner:      THIS_MODULE,\r
+    open:       mmuhack_open,\r
+};\r
+\r
+\r
+static struct miscdevice mmuhack = {\r
+    MMUHACK_MINOR, DEVICE_NAME, &mmuhack_fops\r
+};\r
+\r
+static int __init mmuhack_init(void)\r
+{\r
+       misc_register(&mmuhack);\r
+/*\r
+       printk("MMSP2 MMU Hack module.\n");\r
+*/\r
+    return 0;\r
+}\r
+\r
+static void __exit mmuhack_exit(void)\r
+{\r
+    misc_deregister(&mmuhack);\r
+/*\r
+       printk(KERN_ALERT "MMU Hack module removed.\n");\r
+*/\r
+}\r
+\r
+module_init(mmuhack_init);\r
+module_exit(mmuhack_exit);\r
diff --git a/drivers/gp2x/mmuhack.o b/drivers/gp2x/mmuhack.o
new file mode 100644 (file)
index 0000000..475f4a5
Binary files /dev/null and b/drivers/gp2x/mmuhack.o differ
diff --git a/drivers/gp2x/mmuhack.txt b/drivers/gp2x/mmuhack.txt
new file mode 100644 (file)
index 0000000..207e09c
--- /dev/null
@@ -0,0 +1,4 @@
+Squidge's MMU Hack modularized.
+Original code by Squidge.
+Module by Annonymous?
+Slightly modified by me to suit my need.
diff --git a/drivers/gp2x/squidgehack.c b/drivers/gp2x/squidgehack.c
new file mode 100644 (file)
index 0000000..f831bd4
--- /dev/null
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+extern char **g_argv;
+
+/* Call this MMU Hack kernel module after doing mmap, and before doing memset*/
+int mmuhack(void)
+{
+       char kocmd[1024];
+       int i, mmufd = open("/dev/mmuhack", O_RDWR);
+
+       if(mmufd < 0) {
+               strcpy(kocmd, "/sbin/insmod ");
+               strncpy(kocmd+13, g_argv[0], 1023-13);
+               kocmd[1023] = 0;
+               for (i = strlen(kocmd); i > 0; i--)
+                       if (kocmd[i] == '/') { kocmd[i] = 0; break; }
+               strcat(kocmd, "/mmuhack.o");
+
+               printf("Installing NK's kernel module for Squidge MMU Hack (%s)...\n", kocmd);
+               system(kocmd);
+               mmufd = open("/dev/mmuhack", O_RDWR);
+       }
+       if(mmufd < 0) return 0;
+        
+       close(mmufd);
+       return 1;
+}       
+
+
+/* Unload MMU Hack kernel module after closing all memory devices*/
+int mmuunhack(void)
+{
+       int ret;
+       printf("Removing NK's kernel module for Squidge MMU Hack... "); fflush(stdout);
+       ret = system("/sbin/rmmod mmuhack");
+       printf("done (%i)\n", ret);
+
+       return ret;
+}
diff --git a/drivers/gp2x/squidgehack.h b/drivers/gp2x/squidgehack.h
new file mode 100644 (file)
index 0000000..a83c737
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MMUHACK__
+#define __MMUHACK__
+
+extern int mmuhack(void);
+extern int mmuunhack(void);
+
+#endif /* __MMUHACK__ */
index 81cd916..e70bbd3 100644 (file)
@@ -82,11 +82,11 @@ INLINE void SpeedThrottle(void)
                        FSkip = 1;
                }
        }
-       else if (usec_done > usec_aim)
+       else if (usec_done > usec_aim + 1024*4)
        {
                /* auto frameskip */
                if (usec_done - usec_aim > 150000)
-                       usec_done = usec_aim = 0; // too much behind, try to recover..
+                       usec_done = usec_aim = 1; // too much behind, try to recover..
                FSkip = 1;
                tv_prev = tv_now;
                return;
index 0ea9365..0b0ad9f 100644 (file)
@@ -1,2 +1,2 @@
 void RefreshThrottleFPS(void);
-INLINE void SpeedThrottle(void);
+void SpeedThrottle(void);
diff --git a/fce.c b/fce.c
index 42a4d76..4c7ffc6 100644 (file)
--- a/fce.c
+++ b/fce.c
@@ -441,7 +441,7 @@ static void Loop6502(void)
 {
        uint32 tem;
        int x;
-        uint8 *target=XBuf+(scanline<<8)+(scanline<<4)+8;
+        uint8 *target=XBuf+scanline*320+32;
 
         if(ScreenON || SpriteON)
         {
@@ -481,18 +481,19 @@ static void Loop6502(void)
          if(PPU[1]&0x01)
          {
           for(x=63;x>=0;x--)
-           *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])&0xF0F0F0F0;
+           ((uint32 *)target)[x]=((uint32*)target)[x]&0xF0F0F0F0;
          }
           if((PPU[1]>>5)==0x7)
            for(x=63;x>=0;x--)
-            *(uint32 *)&target[x<<2]=((*(uint32*)&target[x<<2])&0x3f3f3f3f)|0x40404040;
+            ((uint32 *)target)[x]=(((uint32*)target)[x]&0x3f3f3f3f)|0x40404040;
           else if(PPU[1]&0xE0)
            for(x=63;x>=0;x--)
-            *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])|0xC0C0C0C0;
+            ((uint32 *)target)[x]=((uint32*)target)[x]|0xC0C0C0C0;
           else
             for(x=63;x>=0;x--)
-             *(uint32 *)&target[x<<2]=(*(uint32*)&target[x<<2])&0x3f3f3f3f;
-
+             ((uint32 *)target)[x]=((uint32*)target)[x]&0x3f3f3f3f;
+         FCEU_dwmemset(target-  8,0x3f3f3f3f,8);
+         FCEU_dwmemset(target+256,0x3f3f3f3f,8);
         #ifdef FRAMESKIP
         }
         #endif
@@ -784,7 +785,8 @@ static void SetRefreshLine(void)
         }
 }
 
-static INLINE void Fixit2(void)
+//static INLINE
+void Fixit2(void)
 {
    if(ScreenON || SpriteON)
    {
@@ -796,7 +798,8 @@ static INLINE void Fixit2(void)
    }
 }
 
-static INLINE void Fixit1(void)
+//static INLINE
+void Fixit1(void)
 {
    if(ScreenON || SpriteON)
    {
@@ -824,7 +827,10 @@ static INLINE void Fixit1(void)
    }
 }
 
+//#define NEW_TRY
+
 /*      This is called at the beginning of all h-blanks on visible lines. */
+#ifndef NEW_TRY
 static void DoHBlank(void)
 {
  if(ScreenON || SpriteON)
@@ -846,7 +852,7 @@ static void DoHBlank(void)
  //PPU_hook(0,-1);
  //fprintf(stderr,"%3d: $%04x\n",scanline,RefreshAddr);
 }
-
+#endif
 
 
 // ============================//
@@ -1029,6 +1035,7 @@ int FCEUI_Initialize(void)
 static INLINE void Thingo(void)
 {
    Loop6502();
+#ifndef NEW_TRY
 
    if(tosprite>=256)
    {
@@ -1057,6 +1064,9 @@ static INLINE void Thingo(void)
     tosprite=256;
    }
    DoHBlank();
+#else
+   X6502_Run_scanline();
+#endif
 }
 #undef harko
 
@@ -1064,6 +1074,9 @@ void EmLoop(void)
 {
  for(;;)
  {
+       //extern int asdc;
+       //printf("asdc: %i\n", asdc);
+       //asdc=0;
   ApplyPeriodicCheats();
   X6502_Run(256+85);
 
@@ -1102,7 +1115,9 @@ void EmLoop(void)
    if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
   }
   if(FCEUGameInfo.type==GIT_NSF)
+  {
    X6502_Run((256+85)*240);
+  }
   else
   {
    int x,max,maxref;
diff --git a/video.c b/video.c
index 245a6b1..1b0298e 100644 (file)
--- a/video.c
+++ b/video.c
@@ -46,17 +46,17 @@ int InitVirtualVideo(void)
  uint32 m;
 
  if(!XBuf)             /* Some driver code may allocate XBuf externally. */
-  if(!(XBuf = (uint8*) (FCEU_malloc((256+16) * 240 + 8))))
+  if(!(XBuf = (uint8*) (FCEU_malloc(320 * 240))))
    return 0;
-
+/*
  if(sizeof(uint8*)==4)
  {
   m=(uint32) XBuf;
   m+=8;m&=0xFFFFFFF8;
   XBuf=(uint8 *)m;
- } 
-
- memset(XBuf,128,272*240);
+ }
+*/
+ memset(XBuf,128,320*240);
  return 1;
 }
 
@@ -116,7 +116,7 @@ int SaveSnapshot(void)
   fputc(b,pp);
  }
  fclose(pp);
+
  return u+1;
 }
 
@@ -207,7 +207,7 @@ int SaveSnapshot(void)
 
  {
   char pdata[256*3];
-  
+
   //void FCEUD_GetPalette(uint8 i,uint8 *r, unsigned char *g, unsigned char *b);
   for(x=0;x<256;x++)
    FCEUD_GetPalette(x,(uint8*)(pdata+x*3),(unsigned char*)(pdata+x*3+1),(unsigned char*)(pdata+x*3+2));
@@ -231,7 +231,7 @@ int SaveSnapshot(void)
    *dest=0;                    // No filter.
    dest++;
    for(x=256;x;x--,tmp++,dest++)
-    *dest=*tmp;        
+    *dest=*tmp;
    tmp+=16;
   }
 
diff --git a/video.h b/video.h
index 751fb3a..8d972b9 100644 (file)
--- a/video.h
+++ b/video.h
@@ -1,3 +1,4 @@
+#include "types.h"
 int InitVirtualVideo(void);
 int SaveSnapshot(void);
 extern uint8 *XBuf;
diff --git a/x6502.c b/x6502.c
index daba073..c1e55b3 100644 (file)
--- a/x6502.c
+++ b/x6502.c
@@ -24,6 +24,7 @@
 #include "x6502.h"
 #include "fce.h"
 #include "sound.h"
+#include "cart.h"
 
 X6502 X;
 uint32 timestamp;
@@ -46,11 +47,27 @@ 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]);
+ }
+#endif
+#if 0 // enabling this causes 4fps slowdown. Why?
+ if ((A&0xe000) == 0) { // RAM area (always 0-0x1fff)
+  return (_DB=RAM[A&0x7FF]);
+ }
+#endif
  return((_DB=ARead[A](A)));
 }
 
 static INLINE void WrMem(unsigned int A, uint8 V)
 {
+ if ((A&0xe000) == 0) { // RAM area (always 0-0x1fff)
+  RAM[A&0x7FF] = V;
+  return;
+ }
  BWrite[A](A,V);
 }
 
@@ -66,7 +83,7 @@ static INLINE void WrRAM(unsigned int A, uint8 V)
 
 static INLINE void ADDCYC(int x)
 {
- _tcount+=x;
//_tcount+=x;
  _count-=x*48;
  timestamp+=x;
 }
@@ -88,6 +105,7 @@ static INLINE uint8 POP(void)
  return(RdRAM(0x100+_S));
 }
 
+#if 0
 static uint8 ZNTable[256] = {
         Z_FLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -106,10 +124,13 @@ static uint8 ZNTable[256] = {
         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,
         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
 };
+#endif
 /* Some of these operations will only make sense if you know what the flag
    constants are. */
-#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);_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
 
 /* Care must be taken if you want to turn this into a macro.  Use { and }. */
 #define JR();  \
@@ -130,7 +151,8 @@ static uint8 ZNTable[256] = {
 
 /*  All of the freaky arithmetic operations. */
 #define AND        _A&=x;X_ZN(_A)
-#define BIT        _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
+//#define BIT        _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
+#define BIT        _P&=~(Z_FLAG|V_FLAG|N_FLAG);if(!(x&_A)) _P|=Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
 #define EOR        _A^=x;X_ZN(_A)
 #define ORA        _A|=x;X_ZN(_A)
 
@@ -197,7 +219,7 @@ static uint8 ZNTable[256] = {
                 _P|=l; \
                 X_ZNT(x);      \
                }
-                
+
 /* Icky icky thing for some undocumented instructions.  Can easily be
    broken if names of local variables are changed.
 */
@@ -325,7 +347,7 @@ static uint8 ZNTable[256] = {
 #define ST_IY(r)       {unsigned int A; GetIYWR(A); WrMem(A,r); break; }
 
 static uint8 CycTable[256] =
-{                             
+{
 /*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,
@@ -411,19 +433,25 @@ void X6502_Reset(void)
 
 void X6502_Power(void)
 {
- memset((void *)&X,0,sizeof(X)); 
+ memset((void *)&X,0,sizeof(X));
  timestamp=0;
  X6502_Reset();
 }
 
-void X6502_Run(int32 cycles)
+
+//int asdc = 0;
+
+void X6502_Run_(void/*int32 cycles*/)
 {
+/*
        if(PAL)
         cycles*=15;          // 15*4=60
        else
         cycles*=16;          // 16*4=64
 
        _count+=cycles;
+*/
+//     if (_count <= 0) asdc++;
 
        while(_count>0)
        {
@@ -443,9 +471,10 @@ void X6502_Run(int32 cycles)
         }
         _PI=_P;
         b1=RdMem(_PC);
-        ADDCYC(CycTable[b1]);
-        temp=_tcount;
-        _tcount=0;
+        temp=CycTable[b1];
+        ADDCYC(temp);
+        //temp=_tcount;
+        //_tcount=0;
         if(MapIRQHook) MapIRQHook(temp);
 
         temp*=48;
@@ -457,7 +486,7 @@ void X6502_Run(int32 cycles)
          fhcnt+=fhinc;
         }
 
-       
+
         if(PCMIRQCount>0)
         {
          PCMIRQCount-=temp;
@@ -479,6 +508,8 @@ void X6502_Run(int32 cycles)
          switch(b1)
          {
           #include "ops.h"
-         } 
+         }
        }
 }
+
+
diff --git a/x6502.h b/x6502.h
index 414533b..86f4f06 100644 (file)
--- a/x6502.h
+++ b/x6502.h
@@ -55,7 +55,15 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 
 void X6502_Reset(void);
 void X6502_Power(void);
-void X6502_Run(int32 cycles);
+#define X6502_Run(c) \
+{ \
+ int32 cycles = (c) << 4; /* *16 */ \
+ if (PAL) cycles -= (c);  /* *15 */ \
+ X.count+=cycles; \
+ if (X.count > 0) X6502_Run_(); \
+}
+void X6502_Run_(void);
+
 
 void TriggerIRQ(void);
 void TriggerNMI(void);
@@ -64,3 +72,4 @@ void TriggerNMINSF(void);
 void FASTAPASS(1) X6502_AddCycles(int x);
 void FASTAPASS(1) X6502_IRQBegin(int w);
 void FASTAPASS(1) X6502_IRQEnd(int w);
+