From 937bf65b1c80e9394547e5f105664bd26f3671de Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 12 Apr 2007 17:07:46 +0000 Subject: [PATCH] mmuhack, 6502 tweaks, fskip git-svn-id: file:///home/notaz/opt/svn/fceu@101 be3aeb3a-fb24-0410-a615-afba39da0efa --- Makefile.gp2x | 28 ++++++---- cart.c | 10 ++-- cart.h | 1 + drawing.h | 22 ++++---- driver.h | 2 +- drivers/gp2x/asmutils.h | 2 + drivers/gp2x/asmutils.s | 9 ++++ drivers/gp2x/dface.h | 4 +- drivers/gp2x/gp2x-video.c | 47 +++++------------ drivers/gp2x/gp2x.c | 11 +++- drivers/gp2x/input.c | 22 +++----- drivers/gp2x/main.c | 29 ++++++----- drivers/gp2x/minimal.c | 57 ++++++++++++++------ drivers/gp2x/mmuhack.c | 104 +++++++++++++++++++++++++++++++++++++ drivers/gp2x/mmuhack.o | Bin 0 -> 1720 bytes drivers/gp2x/mmuhack.txt | 4 ++ drivers/gp2x/squidgehack.c | 45 ++++++++++++++++ drivers/gp2x/squidgehack.h | 7 +++ drivers/gp2x/throttle.c | 4 +- drivers/gp2x/throttle.h | 2 +- fce.c | 33 ++++++++---- video.c | 16 +++--- video.h | 1 + x6502.c | 57 +++++++++++++++----- x6502.h | 11 +++- 25 files changed, 383 insertions(+), 145 deletions(-) create mode 100644 drivers/gp2x/asmutils.h create mode 100644 drivers/gp2x/asmutils.s create mode 100644 drivers/gp2x/mmuhack.c create mode 100644 drivers/gp2x/mmuhack.o create mode 100644 drivers/gp2x/mmuhack.txt create mode 100644 drivers/gp2x/squidgehack.c create mode 100644 drivers/gp2x/squidgehack.h diff --git a/Makefile.gp2x b/Makefile.gp2x index 4b1553a..ac85a1f 100644 --- a/Makefile.gp2x +++ b/Makefile.gp2x @@ -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 --- 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 --- 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]; diff --git a/drawing.h b/drawing.h index 8850c7a..61a94d3 100644 --- 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>z)&1) dest[y*width+(x<<3)+z]=fgcolor; } diff --git a/driver.h b/driver.h index f5c06c1..cfaf2cf 100644 --- 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 index 0000000..94c89ea --- /dev/null +++ b/drivers/gp2x/asmutils.h @@ -0,0 +1,2 @@ +void flushcache(unsigned int beginning_addr, unsigned int end_addr, unsigned int flags); + diff --git a/drivers/gp2x/asmutils.s b/drivers/gp2x/asmutils.s new file mode 100644 index 0000000..c87a3ab --- /dev/null +++ b/drivers/gp2x/asmutils.s @@ -0,0 +1,9 @@ +@ vim:filetype=armasm + +@ test +.global flushcache @ beginning_addr, end_addr, flags + +flushcache: + swi #0x9f0002 + mov pc, lr + diff --git a/drivers/gp2x/dface.h b/drivers/gp2x/dface.h index 6ff4459..c4d2bfb 100644 --- a/drivers/gp2x/dface.h +++ b/drivers/gp2x/dface.h @@ -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 */ diff --git a/drivers/gp2x/gp2x-video.c b/drivers/gp2x/gp2x-video.c index 6433724..8bd2be1 100644 --- a/drivers/gp2x/gp2x-video.c +++ b/drivers/gp2x/gp2x-video.c @@ -19,6 +19,8 @@ #include #include +#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; } diff --git a/drivers/gp2x/gp2x.c b/drivers/gp2x/gp2x.c index 0f3b9aa..fc70dd1 100644 --- a/drivers/gp2x/gp2x.c +++ b/drivers/gp2x/gp2x.c @@ -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); diff --git a/drivers/gp2x/input.c b/drivers/gp2x/input.c index 8936ec0..704cb3a 100644 --- a/drivers/gp2x/input.c +++ b/drivers/gp2x/input.c @@ -30,11 +30,11 @@ #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; diff --git a/drivers/gp2x/main.c b/drivers/gp2x/main.c index fc9c7b6..ad36e01 100644 --- a/drivers/gp2x/main.c +++ b/drivers/gp2x/main.c @@ -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(); } diff --git a/drivers/gp2x/minimal.c b/drivers/gp2x/minimal.c index 369a1c9..facef9e 100644 --- a/drivers/gp2x/minimal.c +++ b/drivers/gp2x/minimal.c @@ -113,19 +113,28 @@ */ #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 index 0000000..c0c2189 --- /dev/null +++ b/drivers/gp2x/mmuhack.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include + +#define MMUHACK_MINOR 225 +#define DEVICE_NAME "mmuhack" + +#if __GNUC__ == 3 +#include +static const char __module_kernel_version_gcc3[] __attribute__((__used__)) __attribute__((section(".modinfo"))) = +"kernel_version=" UTS_RELEASE; +#endif + +static ssize_t mmuhack_open(struct inode *inode, struct file *filp) +{ + unsigned int *pgtable; + unsigned int *cpt; + int i, j; + int ttb; + int ret = -EFAULT; + + // get the pointer to the translation table base... + asm volatile( + "stmdb sp!, {r0}\n\t" + "mrc p15, 0, r0, c2, c0, 0\n\t" + "mov %0, r0\n\t" + "ldmia sp!, {r0}\n\t": "=r"(ttb) + ); + + pgtable = __va(ttb); + + for (i = 0; i < 4096; i ++) if ( (pgtable[i] & 3) == 1 ) { + cpt = __va(pgtable[i] & 0xfffffc00); + + for (j = 0; j < 256; j ++) {/* + if ( (cpt[j] & 0xfe00000f) == 0x02000002 ) { + // set C and B bits in upper 32MB memory area... + printk("Set C&B bits %08x\n",cpt[j]); + cpt[j] |= 0xFFC; + ret = 0; + } + */ + if (((cpt[j] & 0xff000000) == 0x02000000) && ((cpt[j] & 12)==0) ) + { + //printk("Set C&B bits %08x\n",cpt[j]); + cpt[j] |= 0xFFC; + } + //if ((a>=0x31 && a<=0x36) && ((cpt[i] & 12)==0)) + if (((cpt[j] & 0xff000000) == 0x03000000) && ((cpt[j] & 12)==0)) + { + //printk("Set C&B bits %08x\n",cpt[j]); + //printf("SDL c and b bits not set, overwriting\n"); + cpt[j] |= 0xFFC; + } + } + } + + // drain the write buffer and flush the tlb caches... + asm volatile( + "stmdb sp!, {r0}\n\t" + "mov r0, #0\n\t" + "mcr 15, 0, r0, cr7, cr10, 4\n\t" + "mcr 15, 0, r0, cr8, cr7, 0\n\t" + "ldmia sp!, {r0}\n\t" + ); + + if (ret == 0) + printk("MMU hack applied.\n"); + + return 0; +} + +static struct file_operations mmuhack_fops = { + owner: THIS_MODULE, + open: mmuhack_open, +}; + + +static struct miscdevice mmuhack = { + MMUHACK_MINOR, DEVICE_NAME, &mmuhack_fops +}; + +static int __init mmuhack_init(void) +{ + misc_register(&mmuhack); +/* + printk("MMSP2 MMU Hack module.\n"); +*/ + return 0; +} + +static void __exit mmuhack_exit(void) +{ + misc_deregister(&mmuhack); +/* + printk(KERN_ALERT "MMU Hack module removed.\n"); +*/ +} + +module_init(mmuhack_init); +module_exit(mmuhack_exit); diff --git a/drivers/gp2x/mmuhack.o b/drivers/gp2x/mmuhack.o new file mode 100644 index 0000000000000000000000000000000000000000..475f4a54ae074c9a5cd1848f07d720cce3d9ccf0 GIT binary patch literal 1720 zcmb_c&ubGw6n?v#+O)PN7E!Stwjh!sUDDJZ{4Er1g(?l|MTEE}+jeQP3E8daNo@~$ z@Sq?fUR-az6#N4eauK|F@gSnmWEES4qTs=k@q5{sxGg<8F!|p1-ka~u%)ZI(Gm~c( zMKMVXg;JzQ0=%k*px!>ri-D@ZV z55MhzUyWT1deRGuGJK~~`n0GodAHG|Y_NyuV=U>{yD3}mh0XgS@`GoI&hc zH@y-NY7V1joSuLE(`gkjDhHuC=W2N9v&uHt0Qto(>=D@mi^O3^waZy`{+B;BLQ{)4~={hB$98 zCx{{Io&#qInO6hZFOz^WFDvq7=o9h|N)n0fge~{RVHLtx*bswj@rc%BejJ6S;M@*7 zfys4~n0&`ky$2mcui%qI>Pap!>W|USrt~vv?OO`H+J*`o?`ZAg-RKAAl+{P6^I$SAoJLkZt}Z%r5~sSI6Xh6ZjjGzXkK?(9i)+#KHG8zlkqy z;*U1*7vQp9AM}^OWj*Hd;Tn0G$>%dUyrYU;#G9sE4v%cUXyrEk4afz#a>a7mWV&2& zC6So39ouUY>n2F0YCGN>q`g_&75Y@N-F&WU&DgGIRYO*=+MGpXW*&bZ&U{5uzFP%- y_gJ7WuqN;=Bbw|zP{m_fWsb)E#T?BR$MKau^dFEp4;7cJGeVd3c^$uZj{gPHjSv<9 literal 0 HcmV?d00001 diff --git a/drivers/gp2x/mmuhack.txt b/drivers/gp2x/mmuhack.txt new file mode 100644 index 0000000..207e09c --- /dev/null +++ b/drivers/gp2x/mmuhack.txt @@ -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 index 0000000..f831bd4 --- /dev/null +++ b/drivers/gp2x/squidgehack.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include + +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 index 0000000..a83c737 --- /dev/null +++ b/drivers/gp2x/squidgehack.h @@ -0,0 +1,7 @@ +#ifndef __MMUHACK__ +#define __MMUHACK__ + +extern int mmuhack(void); +extern int mmuunhack(void); + +#endif /* __MMUHACK__ */ diff --git a/drivers/gp2x/throttle.c b/drivers/gp2x/throttle.c index 81cd916..e70bbd3 100644 --- a/drivers/gp2x/throttle.c +++ b/drivers/gp2x/throttle.c @@ -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; diff --git a/drivers/gp2x/throttle.h b/drivers/gp2x/throttle.h index 0ea9365..0b0ad9f 100644 --- a/drivers/gp2x/throttle.h +++ b/drivers/gp2x/throttle.h @@ -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 --- 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 --- 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 --- 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 --- 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 --- 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); + -- 2.39.2