asm cpu works, added sync()s
authornotaz <notasas@gmail.com>
Sat, 14 Apr 2007 20:52:13 +0000 (20:52 +0000)
committernotaz <notasas@gmail.com>
Sat, 14 Apr 2007 20:52:13 +0000 (20:52 +0000)
git-svn-id: file:///home/notaz/opt/svn/fceu@103 be3aeb3a-fb24-0410-a615-afba39da0efa

15 files changed:
Makefile.gp2x
drivers/common/config.c
drivers/gp2x/gp2x-video.c
drivers/gp2x/minimal.c
fce.c
fce.h
ines.c
ncpu.S
ncpu.h
ncpu_debug.c
state.c
unif.c
video.c
x6502.c
x6502.h

index bca522a..5071037 100644 (file)
@@ -16,7 +16,7 @@ LDRIVER       += -O3 # -pg
 endif
 
 asm_6502=1
-debug_asm_6502=1
+#debug_asm_6502=1
 
 all:           fceu
 
@@ -43,7 +43,7 @@ endif
 
 x6502.o: x6502.c x6502.h ops.h fce.h sound.h
 ncpu.o: ncpu.S ncpu.h
-       $(CC) -c $< -o $@
+       $(CC) $(TFLAGS) -c $< -o $@
 
 include Makefile.base
 
index 6f87f55..f82323d 100644 (file)
@@ -29,6 +29,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef GP2X
+#include <unistd.h>
+#endif
 
 #include "../../types.h"
 #include "config.h"
@@ -40,7 +43,7 @@ static int FReadString(FILE *fp, char *str, int n)
  {
   z=fgetc(fp);
   str[x]=z;
-  x++;  
+  x++;
   if(z<=0) break;
   if(x>=n) return 0;
  }
@@ -122,6 +125,9 @@ void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst)
        SaveParse(cfgst,fp);
 
        fclose(fp);
+#ifdef GP2X
+       sync();
+#endif
 }
 
 static void LoadParse(CFGSTRUCT *cfgst, FILE *fp)
index 8bd2be1..f7f09bd 100644 (file)
@@ -214,9 +214,12 @@ static INLINE void printFps(uint8 *screen)
                        }
                        if (showfps)
                        {
-                               fps_str[2] = 0;
-                               gp2x_text(screen, 0,  0, fps_str,   FPS_COLOR, 0);
-                               gp2x_text(screen, 0, 10, fps_str+3, FPS_COLOR, 0);
+                               int sep;
+                               for (sep=1; sep < 5; sep++)
+                                       if (fps_str[sep] == '/' || fps_str[sep] == 0) break;
+                               fps_str[sep] = 0;
+                               gp2x_text(screen, 0,  0, fps_str,       FPS_COLOR, 0);
+                               gp2x_text(screen, 0, 10, fps_str+sep+1, FPS_COLOR, 0);
                        }
                        needfpsflip--;
                }
index facef9e..0250587 100644 (file)
@@ -439,8 +439,17 @@ void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, in
     frag = 0x40000|13;
     ioctl(gp2x_dev[3], SNDCTL_DSP_SETFRAGMENT, &frag);
 
-
-    printf("minimal() do sound, rate %d, bits %d, stereo %d, frag %d\n", rate, bits, stereo, frag);
+    {
+       // calculate buffer size
+       int frag = 0, bsize, buffers = 16;
+       bsize = rate / 32;
+       if (rate > 22050) { bsize*=4; buffers*=2; } // 44k mode seems to be very demanding
+       while ((bsize>>=1)) frag++;
+       frag |= buffers<<16; // 16 buffers
+       ioctl(gp2x_dev[3], SNDCTL_DSP_SETFRAGMENT, &frag);
+       printf("gp2x_set_sound: %i/%ibit/%s, %i buffers of %i bytes\n",
+               rate, bits, stereo?"stereo":"mono", frag>>16, 1<<(frag&0xffff));
+    }
 
     if(first)
     {
diff --git a/fce.c b/fce.c
index 3e4dde5..64bb8dc 100644 (file)
--- a/fce.c
+++ b/fce.c
 #define Pal     (PALRAM)
 
 
+#ifdef DEBUG_ASM_6502
+extern int cpu_repeat;
+extern int cpu_lastval;
+#endif
+
 static void (*RefreshLine)(uint8 *P, uint32 vofs) = NULL;
 static void PRefreshLine(void);
 
@@ -98,6 +103,71 @@ static readfunc *AReadG;
 static writefunc *BWriteG;
 static int RWWrap=0;
 
+#ifdef ASM_6502
+static void asmcpu_update(int32 cycles)
+{
+ // timestamp..
+ timestamp += ((cycles >> 4) * 43) >> 7; // aproximating /= 48
+
+ // some code from x6502.c
+ fhcnt-=cycles;
+ if(fhcnt<=0)
+ {
+  FrameSoundUpdate();
+  fhcnt+=fhinc;
+ }
+
+ if(PCMIRQCount>0)
+ {
+  PCMIRQCount-=cycles;
+  if(PCMIRQCount<=0)
+  {
+   vdis=1;
+   if((PSG[0x10]&0x80) && !(PSG[0x10]&0x40))
+   {
+    extern uint8 SIRQStat;
+    SIRQStat|=0x80;
+    X6502_IRQBegin(FCEU_IQDPCM);
+   }
+  }
+ }
+}
+
+void asmcpu_unpack(void)
+{
+       nes_registers[0] = X.A << 24;
+       nes_registers[1] = X.X;
+       nes_registers[2] = X.Y;
+       pc_base = 0;
+       nes_registers[3] = X.PC;
+       X6502_rebase_a();
+       nes_registers[4] = X.S << 24;
+       nes_registers[4]|= X.IRQlow << 8;
+       nes_registers[7] = (uint32)X.count;
+
+       // NVUB DIZC
+       nes_registers[4]|= X.P & 0x5d;
+       nes_registers[5] = X.P << 24; // N
+       if (!(X.P&0x02)) nes_registers[5] |= 1; // Z
+}
+
+void asmcpu_pack(void)
+{
+       X.A = nes_registers[0] >> 24;
+       X.X = nes_registers[1];
+       X.Y = nes_registers[2];
+       X.PC= nes_registers[3] - pc_base;
+       X.S = nes_registers[4] >> 24;
+       X.IRQlow = nes_registers[4] >> 8;
+       X.count = (int32) nes_registers[7];
+
+       // NVUB DIZC
+       X.P = nes_registers[4] & 0x5d;
+       if (  nes_registers[5]&0x80000000)  X.P |= 0x80; // N
+       if (!(nes_registers[5]&0x000000ff)) X.P |= 0x02; // Z
+}
+#endif
+
 DECLFW(BNull)
 {
 
@@ -203,12 +273,11 @@ uint32 TempAddr,RefreshAddr;
 /* scanline is equal to the current visible scanline we're on. */
 
 int scanline;
-static uint32 scanlines_per_frame;
 
 uint8 GameMemBlock[131072] __attribute__ ((aligned (4)));
 uint8 NTARAM[0x800] __attribute__ ((aligned (4)));
 uint8 PALRAM[0x20] __attribute__ ((aligned (4)));
-#ifndef ASM_6502
+#if !defined(ASM_6502) || defined(DEBUG_ASM_6502)
 uint8 RAM[0x800] __attribute__ ((aligned (4)));
 #endif
 
@@ -245,9 +314,15 @@ static DECLFR(ARAMH)
 static DECLFR(A2002)
 {
                         uint8 ret;
+#ifdef DEBUG_ASM_6502
+       if (cpu_repeat) return cpu_lastval;
+#endif
                         ret = PPU_status;
                         vtoggle=0;
                         PPU_status&=0x7F;
+#ifdef DEBUG_ASM_6502
+       cpu_lastval=ret|(PPUGenLatch&0x1F);
+#endif
                         return ret|(PPUGenLatch&0x1F);
 }
 
@@ -260,6 +335,9 @@ static DECLFR(A2007)
 {
                         uint8 ret;
                        uint32 tmp=RefreshAddr&0x3FFF;
+#ifdef DEBUG_ASM_6502
+       if (cpu_repeat) return cpu_lastval;
+#endif
 
                         PPUGenLatch=ret=VRAMBuffer;
                        if(PPU_hook) PPU_hook(tmp);
@@ -275,6 +353,9 @@ static DECLFR(A2007)
                         if (INC32) RefreshAddr+=32;
                         else RefreshAddr++;
                        if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
+#ifdef DEBUG_ASM_6502
+       cpu_lastval=ret;
+#endif
                         return ret;
 }
 
@@ -400,9 +481,16 @@ static DECLFW(B4014)
 {
        uint32 t=V<<8;
        int x;
+#ifdef DEBUG_ASM_6502
+  if (cpu_repeat) { X6502_AddCycles_a(512); return; }
+       for(x=0;x<256;x++)
+        B2004(0x2004,X.DB=ARead[t+x](t+x));
+       X6502_AddCycles_c(512);
+#else
        for(x=0;x<256;x++)
         B2004(0x2004,X.DB=ARead[t+x](t+x));
        X6502_AddCycles(512);
+#endif
 }
 
 void BGRender(uint8 *target)
@@ -1006,14 +1094,12 @@ void FCEU_ResetVidSys(void)
  if(w)
  {
   PAL=1;
-  scanlines_per_frame=312;
   FSettings.FirstSLine=FSettings.UsrFirstSLine[1];
   FSettings.LastSLine=FSettings.UsrLastSLine[1];
  }
  else
  {
   PAL=0;
-  scanlines_per_frame=262;
   FSettings.FirstSLine=FSettings.UsrFirstSLine[0];
   FSettings.LastSLine=FSettings.UsrLastSLine[0];
  }
@@ -1076,6 +1162,7 @@ void EmLoop(void)
 {
  for(;;)
  {
+  uint32 scanlines_per_frame = PAL ? 312 : 262;
        //extern int asdc;
        //printf("asdc: %i\n", asdc);
        //asdc=0;
@@ -1096,7 +1183,9 @@ void EmLoop(void)
   else if(VBlankON)
    TriggerNMI();
 
-  X6502_Run((scanlines_per_frame-242)*(256+85)-12);
+  X6502_Run(256+85-12);
+  for(scanline=242+1;scanline<scanlines_per_frame;scanline++)
+    X6502_Run(256+85);
 
   PPU_status&=0x1f;
 
@@ -1247,6 +1336,8 @@ void PowerNES(void)
 
         GeniePower();
 
+printf("X.DB offs: %02x\n", (int)&X.DB - (int)&X);
+
         memset(RAM,0x00,0x800);
         ResetMapping();
        GameInterface(GI_POWER);
diff --git a/fce.h b/fce.h
index 6c4865c..8734f4c 100644 (file)
--- a/fce.h
+++ b/fce.h
@@ -1,4 +1,10 @@
 #ifndef _FCEH
+
+#ifdef ASM_6502
+void asmcpu_unpack(void);
+void asmcpu_pack(void);
+#endif
+
 extern int GameLoaded;
 void ResetGameLoaded(void);
 
@@ -52,7 +58,7 @@ extern readfunc ARead[0x10000];
 extern writefunc BWrite[0x10000];
 
 #define        VBlankON        (PPU[0]&0x80)   /* Generate VBlank NMI */
-#define        SpHitON         (PPU[0]&0x40)   
+#define        SpHitON         (PPU[0]&0x40)
 #define        Sprite16        (PPU[0]&0x20)   /* Sprites 8x16/8x8        */
 #define        BGAdrHI         (PPU[0]&0x10)   /* BG pattern adr $0000/$1000 */
 #define        SpAdrHI         (PPU[0]&0x08)   /* Sprite pattern adr $0000/$1000 */
diff --git a/ines.c b/ines.c
index b71460d..6f8bb1b 100644 (file)
--- a/ines.c
+++ b/ines.c
@@ -1,7 +1,7 @@
 /* FCE Ultra - NES/Famicom Emulator
  *
  * Copyright notice for this file:
- *  Copyright (C) 1998 BERO 
+ *  Copyright (C) 1998 BERO
  *  Copyright (C) 2002 Ben Parnell
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef GP2X
+#include <unistd.h>
+#endif
 
 #include "types.h"
 #include "x6502.h"
@@ -58,7 +61,7 @@ static int SaveGame=0;
 
 static iNES_HEADER head;
 
-/*  MapperReset() is called when the NES is reset(with the reset button).  
+/*  MapperReset() is called when the NES is reset(with the reset button).
     Mapperxxx_init is called when the NES has been powered on.
 */
 
@@ -77,7 +80,7 @@ static void iNESGI(int h)
   case GI_CLOSE:
                {
                 FILE *sp;
-               
+
                 if(ROM) {free(ROM);ROM=0;}
                 if(VROM) {free(VROM);VROM=0;}
 
@@ -110,6 +113,9 @@ static void iNESGI(int h)
 
                   fwrite(ptr,1,amount,sp);
                   fclose(sp);
+#ifdef GP2X
+                  sync();
+#endif
                  }
                 }
                 if(MapClose) MapClose();
@@ -236,7 +242,7 @@ static void CheckHInfo(void)
         {0x932ff06e,34,1},     /* Classic Concentration */
         {0x4c7c1af3,34,1},     /* Caesar's Palace */
         {0x9ea1dc76,2,0},      /* Rainbow Islands */
-        
+
         {0x9eefb4b4,4,8},      /* Pachi Slot Adventure 2 */
         {0x5337f73c,4,8},      /* Niji no Silk Road */
         {0x7474ac92,4,8},      /* Kabuki: Quantum Fighter */
@@ -411,7 +417,7 @@ static void CheckHInfo(void)
    sprintf(gigastr+strlen(gigastr),"Mirroring should be set to \"%s\".  ",mstr[Mirroring&3]);
   }
   if(tofix&4)
-   strcat(gigastr,"The battery-backed bit should be set.  ");  
+   strcat(gigastr,"The battery-backed bit should be set.  ");
   if(tofix&8)
    strcat(gigastr,"This game should not have any CHR ROM.  ");
   strcat(gigastr,"\n");
@@ -465,8 +471,8 @@ int iNESLoad(char *name, int fp)
 
         if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14)))
         return 0;
-               
-        if (VROM_size) 
+
+        if (VROM_size)
          if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13)))
         {
          free(ROM);
@@ -523,7 +529,7 @@ int iNESLoad(char *name, int fp)
        else if(MapperNo==1) DetectMMC1WRAMSize();
 
         if(head.ROM_type&2)
-        {         
+        {
          char *soot;
 
          SaveGame=1;
@@ -589,7 +595,7 @@ static void NONE_init(void)
         ROM_BANK16(0x8000,0);
         ROM_BANK16(0xC000,~0);
 
-        if(VROM_size) 
+        if(VROM_size)
         VROM_BANK8(0);
         else
         setvram8(CHRRAM);
@@ -616,7 +622,7 @@ static uint8 *secptr;
 static void CheckVSUni(void)
 {
         FCEUGameInfo.type=GIT_VSUNI;
-       
+
        /* FCE Ultra doesn't complain when headers for these games are bad. */
        secptr=0;
        switch(iNESGameCRC32)
@@ -625,9 +631,9 @@ static void CheckVSUni(void)
 
         case 0xffbef374: pale=1;break; /* Castlevania */
 
-        case 0x98e3c75a: 
+        case 0x98e3c75a:
         case 0x7cff0f84: pale=2;break; /* SMB */
-       
+
         case 0xef7af338: pale=2;break; /* Ice Climber */
         case 0xabe1a0c2: FCEUGameInfo.input[0]=SI_ZAPPER;break; /*Duck hunt */
         case 0x16aa4e2d: pale=7;FCEUGameInfo.input[0]=SI_ZAPPER;break; /* hoganal ^_^ */
@@ -653,7 +659,7 @@ static void CheckVSUni(void)
 
          case 0x159ef3c1:break; /* Star Luster */
          case 0x9768e5e0:break; /* Stroke and Match Golf */
-       
+
         /* FCE Ultra doesn't have correct palettes for the following games. */
         case 0x0fa322c2:pale=2;break; /* Clu Clu Land */
 
@@ -664,7 +670,7 @@ static void CheckVSUni(void)
         case 0x832cf592:FCEUGameInfo.input[0]=SI_ZAPPER;break; /* Freedom Force */
         case 0x63abf889:break; /* Ladies Golf */
         case 0x8c0c2df5:pale=2;MapperNo=1;Mirroring=1;break; /* Top Gun */
-        case 0x52c501d0:vsdip=0x80;MapperNo=4;secptr=secdata[0];break; 
+        case 0x52c501d0:vsdip=0x80;MapperNo=4;secptr=secdata[0];break;
                        /* TKO Boxing */
        }
 
@@ -753,14 +759,14 @@ void (*MapStateRestore)(int version);
 void iNESStateRestore(int version)
 {
  int x;
+
  if(!MapperNo) return;
 
  for(x=0;x<4;x++)
   setprg8(0x8000+x*8192,PRGBankList[x]);
 
  if(VROM_size)
-  for(x=0;x<8;x++) 
+  for(x=0;x<8;x++)
     setchr1(0x400*x,CHRBankList[x]);
 
  switch(Mirroring)
@@ -833,7 +839,7 @@ static int MMC_init(int type)
         if(head.ROM_type&8)
          AddExState(ExtraNTARAM, 2048, 0, "EXNR");
 
-       /* Exclude some mappers whose emulation code handle save state stuff 
+       /* Exclude some mappers whose emulation code handle save state stuff
           themselves. */
        if(type && type!=13 && type!=96)
        {
@@ -846,7 +852,7 @@ static int MMC_init(int type)
          for(x=0;x<8;x++)
          {
           char tak[8];
-          sprintf(tak,"CBL%d",x);         
+          sprintf(tak,"CBL%d",x);
           AddExState(&CHRBankList[x], 2, 1,tak);
          }
        }
diff --git a/ncpu.S b/ncpu.S
index 381437f..2a7fafe 100644 (file)
--- a/ncpu.S
+++ b/ncpu.S
@@ -15,6 +15,8 @@
 #define OTOFFS_NES_STACK (nes_stack        - cpu_exec_table)
 #define OTOFFS_NES_REGS  (nes_registers    - cpu_exec_table)
 #define OTOFFS_PC_BASE   (pc_base          - cpu_exec_table)
+#define OTOFFS_IRQ_HOOK  (MapIRQHook       - cpu_exec_table)
+#define OTOFFS_X         (X                - cpu_exec_table)
 
 @ fceu
 #define FCEU_IQNMI      0x08
 .endm
 
 
-.macro RETURN_FROM_CPU_EXEC
-       b       cpu_exec_end
-.endm
-
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -68,6 +66,9 @@
 
        subs    REG_CYCLE, REG_CYCLE, #\n*48
        ble     cpu_exec_end
+       tst     REG_P_REST, #1<<16
+       movne   r0, #\n
+       blne    do_irq_hook
        ldrb    r0, [REG_PC], #1
        tst     REG_P_REST, #0xff<<8
        ldreq   pc, [REG_OP_TABLE, r0, lsl #2]
        subgt   REG_CYCLE,REG_CYCLE,#1*48
 .endm
 
+@ Indirect Indexed (for writes and rmws)
+.macro INDY_ADDR_W
+       ZERO_ADDR
+       ZP_READ_ADDR
+       add     REG_ADDR, REG_ADDR, REG_Y
+       bic     REG_ADDR, REG_ADDR, #0x10000
+.endm
+
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        subgt   REG_CYCLE,REG_CYCLE,#1*48
 .endm
 
+@ Absolute Indexed (for writes and rmws)
+.macro ABSX_ADDR_W
+       ABS_ADDR
+       add     REG_ADDR, REG_ADDR, REG_X
+       bic     REG_ADDR, REG_ADDR, #0x10000
+.endm
+
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@ $nnnn, Y
 .macro ABSY_ADDR
        subgt   REG_CYCLE,REG_CYCLE,#1*48
 .endm
 
+@ Absolute Indexed (for writes and rmws)
+.macro ABSY_ADDR_W
+       ABS_ADDR
+       add     REG_ADDR, REG_ADDR, REG_Y
+       bic     REG_ADDR, REG_ADDR, #0x10000
+.endm
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
 @@@ P ¤òÉü¸µ¤¹¤ë
 @@@ r0         => 6502 ¤Î P ¥ì¥¸¥¹¥¿
 @@@ REG_NZ     <= Éü¸µ¤µ¤ì¤¿ REG_NZ
@@ -843,7 +868,7 @@ op8D:       @ STA $nnnn
        CYCLE_NEXT 4
 
 op9D:  @ STA $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        OP_STA
        WRITE_1
        CYCLE_NEXT 5
@@ -851,7 +876,7 @@ op9D:       @ STA $nnnn, X
        CYCLE_NEXT 5
 
 op99:  @ STA $nnnn, Y
-       ABSY_ADDR
+       ABSY_ADDR_W
        OP_STA
        WRITE_1
        CYCLE_NEXT 5
@@ -867,7 +892,7 @@ op81:       @ STA ($nn, X)
        CYCLE_NEXT 6
 
 op91:  @ STA ($nn), Y
-       INDY_ADDR
+       INDY_ADDR_W
        OP_STA
        WRITE_1
        CYCLE_NEXT 6
@@ -974,7 +999,7 @@ opEE:       @ INC $nnnn
        CYCLE_NEXT      6
 
 opFE:  @ INC $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_INC
        READ_WRITE_2
@@ -1020,7 +1045,7 @@ opCE:     @ DEC $nnnn
        CYCLE_NEXT      6
 
 opDE:  @ DEC $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_DEC
        READ_WRITE_2
@@ -1660,7 +1685,7 @@ op0E:     @ ASL $nnnn
        CYCLE_NEXT      6
 
 op1E:  @ ASL $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_ASL
        READ_WRITE_2
@@ -1702,7 +1727,7 @@ op4E:     @ LSR $nnnn
        CYCLE_NEXT      6
 
 op5E:  @ LSR $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_LSR
        READ_WRITE_2
@@ -1790,7 +1815,7 @@ op2E:     @ ROL $nnnn
 
 
 op3E:  @ ROL $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_ROL
        READ_WRITE_2
@@ -1832,7 +1857,7 @@ op6E:     @ ROR $nnnn
        CYCLE_NEXT      6
 
 op7E:  @ ROR $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_ROR
        READ_WRITE_2
@@ -2078,7 +2103,7 @@ op43:     @ SRE ($nn, X)
        CYCLE_NEXT      8
 
 op53:  @ SRE ($nn), Y
-       INDY_ADDR
+       INDY_ADDR_W
        READ_WRITE_1
        OP_SRE
        READ_WRITE_2
@@ -2090,7 +2115,7 @@ op53:     @ SRE ($nn), Y
 
 
 op9C:  @ SHY $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        OP_SHY
        WRITE_1
        CYCLE_NEXT 5
@@ -2264,7 +2289,7 @@ op1F:     @ SLO $nnnn, X
        CYCLE_NEXT      7
 
 op1B:  @ SLO $nnnn, Y
-       ABSY_ADDR
+       ABSY_ADDR_W
        READ_WRITE_1
        OP_SLO
        READ_WRITE_2
@@ -2286,7 +2311,7 @@ op03:     @ SLO ($nn, X)
        CYCLE_NEXT      8
 
 op13:  @ SLO ($nn), Y
-       INDY_ADDR
+       INDY_ADDR_W
        READ_WRITE_1
        OP_SLO
        READ_WRITE_2
@@ -2409,7 +2434,7 @@ op2F:     @ RLA $nnnn
        CYCLE_NEXT      6
 
 op3F:  @ RLA $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_RLA
        READ_WRITE_2
@@ -2420,11 +2445,11 @@ op3F:   @ RLA $nnnn, X
        CYCLE_NEXT      7
 
 op3B:  @ RLA $nnnn, Y
-       ABSY_ADDR
+       ABSY_ADDR_W
        READ_WRITE_1
        OP_RLA
-    READ_WRITE_2
-    CYCLE_NEXT 7
+       READ_WRITE_2
+       CYCLE_NEXT      7
        READ_WRITE_3
        OP_RLA
        READ_WRITE_4
@@ -2442,7 +2467,7 @@ op23:     @ RLA ($nn, X)
        CYCLE_NEXT      8
 
 op33:  @ RLA ($nn), Y
-       INDY_ADDR
+       INDY_ADDR_W
        READ_WRITE_1
        OP_RLA
        READ_WRITE_2
@@ -2482,7 +2507,7 @@ op6F:     @ RRA $nnnn
        CYCLE_NEXT      6
 
 op7F:  @ RRA $nnnn, X
-       ABSX_ADDR
+       ABSX_ADDR_W
        READ_WRITE_1
        OP_RRA
        READ_WRITE_2
@@ -2495,7 +2520,7 @@ op7F:     @ RRA $nnnn, X
        CYCLE_NEXT      7
 
 op7B:  @ RRA $nnnn, Y
-       ABSY_ADDR
+       ABSY_ADDR_W
        READ_WRITE_1
        OP_RRA
        READ_WRITE_2
@@ -2521,7 +2546,7 @@ op63:     @ RRA ($nn, X)
        CYCLE_NEXT      8
 
 op73:  @ RRA ($nn), Y
-       INDY_ADDR
+       INDY_ADDR_W
        READ_WRITE_1
        OP_RRA
        READ_WRITE_2
@@ -2708,9 +2733,11 @@ op60:
 
 @@@
 @@@ ³ä¤ê¹þ¤ß¤Î½èÍý
+@@@ WARNING: decrements REG_PC
 @@@
 do_int:
        ldr     r0, [REG_OP_TABLE, #OTOFFS_PC_BASE]
+       sub     REG_PC, REG_PC, #1
        sub     r0, REG_PC, r0
        PUSH_WORD
        bic     REG_P_REST, REG_P_REST, #P_REST_B_FLAG
@@ -2742,6 +2769,12 @@ reset_cpu:
        @@REG_P_REST = 0, don't touch REG_S
        bic     REG_P_REST, REG_P_REST, #0xff
 
+       @ fceu: set MapIRQHook present flag
+       ldr     r0, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
+       tst     r0, r0
+       orrne   REG_P_REST, REG_P_REST, #1<<16
+       biceq   REG_P_REST, REG_P_REST, #1<<16
+
        @@ R bit is always 1
        orr     REG_NZ, REG_NZ, #P_R_FLAG
 
@@ -2763,12 +2796,26 @@ reset_cpu:
 @@@ low-level memhandlers
 @@@
 
+read_rom_byte:
+       ldr     r0, =CartBR
+       ldr     r2, =ARead
+       mov     r1, #0xff00
+       orr     r1, r1, r1, lsr #4
+       ldr     r1, [r2, r1, lsl #2]            @ if (ARead[0xfff0] == CartBR)
+       cmp     r0, r1
+       bne     read_ppu_reg
+       ldr     r2, =Page
+       mov     r1, REG_ADDR, lsr #11
+       ldr     r2, [r2, r1, lsl #2]
+       ldrb    r0, [r2, REG_ADDR]
+       bx      lr
+
+
 read_ppu_reg:
 read_high_reg:
 read_save_ram:
-read_rom_byte:
        @ must preserve r3 for the callers too
-       @ TODO: check if all of saves are needed, optimize read_rom_byte, _DB
+       @ TODO: check if all of saves are needed, _DB (is full needed?)
        str     REG_PC,     [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x0c)]   @ might get rebased
        str     REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)]   @ might set irq
        str     REG_CYCLE,  [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x1c)]   @ might get used
@@ -2786,6 +2833,7 @@ read_rom_byte:
        ldr     REG_PC,     [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x0c)]   @ might get rebased
        ldr     REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)]   @ might set irq
        ldr     REG_CYCLE,  [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x1c)]   @ might get used
+       strb    r0,         [REG_OP_TABLE, #(OTOFFS_X + 0x10)]          @ X.DB
        bx      lr
 
 
@@ -2910,7 +2958,9 @@ cpu_exec_table:
 @@@
 nes_registers:
        .fill   0x40, 1, 0
+#ifndef DEBUG_ASM_6502
 RAM:
+#endif
 nes_internal_ram:
        .fill   0x100, 1, 0
 nes_stack:
@@ -2918,6 +2968,13 @@ nes_stack:
 @ TODO: write code which keeps it up-to-date
 pc_base:
        .long   0
+#ifndef DEBUG_ASM_6502
+MapIRQHook:
+       .long   0
+timestamp:
+       .long   0
+X:     .fill   0x20, 1, 0
+#endif
 
 .pool
 
@@ -2982,16 +3039,12 @@ opAB:   @ LXA #$nn
 @op37: @ RLA $nn, X
 @op2F: @ RLA $nnnn
 @op3F: @ RLA $nnnn, X
-@op3B: @ RLA $nnnn, Y
 @op23: @ RLA ($nn, X)
-@op33: @ RLA ($nn), Y
 @op67: @ RRA $nn
 @op77: @ RRA $nn, X
 @op6F: @ RRA $nnnn
 @op7F: @ RRA $nnnn, X
-@op7B: @ RRA $nnnn, Y
 @op63: @ RRA ($nn, X)
-@op73: @ RRA ($nn), Y
 op87:  @ SAX $nn
 op97:  @ SAX $nn, Y
 op8F:  @ SAX $nnnn
@@ -3001,21 +3054,17 @@ op9F:   @ SHA $nnnn, Y
 op93:  @ SHA ($nn), Y
 op9B:  @ SHS $nnnn, Y
 op9E:  @ SHX $nnnn, Y
-@op9C: @ SHY $nnnn, X
 @op03:   @ SLO ($nn, X)
 @op07: @ SLO $nn
 @op17: @ SLO $nn, X
 @op0F: @ SLO $nnnn
 @op1F: @ SLO $nnnn, X
-@op1B: @ SLO $nnnn, Y
-@op13: @ SLO ($nn), Y
 @op47: @ SRE $nn
 @op57: @ SRE $nn, X
 @op4F: @ SRE $nnnn
 @op5F: @ SRE $nnnn, X
 @op5B: @ SRE $nnnn, Y
 @op43: @ SRE ($nn, X)
-@op53: @ SRE ($nn), Y
        CYCLE_NEXT   1
 @ emu_panic?
 
@@ -3029,20 +3078,19 @@ op9E:   @ SHX $nnnn, Y
 .extern Page
 .extern ARead
 .extern BWrite
+.extern MapIRQHook
 
 
        SECTION_DATA
        ALIGN
-@      .globl  X
-       .globl  RAM
        .globl  nes_registers @ TODO: hide?
        .globl  pc_base
-@      .globl  timestamp
-@      .globl  MapIRQHook @ (int a)
-@ TODO... .. conversion X <-> nes_registers for savestates
-@timestamp:    .long   0
-@MapIRQHook:   .long   0
-@X:            .fill   0x20, 1, 0
+#ifndef DEBUG_ASM_6502
+       .globl  X
+       .globl  RAM
+       .globl  timestamp
+       .globl  MapIRQHook @ (int a)
+#endif
        .globl  X6502_Reset_a @ (void);
        .globl  X6502_Power_a @ (void);
        .globl  X6502_Run_a @ (int32 cycles);
@@ -3099,7 +3147,7 @@ X6502_IRQEnd_a:
 
 
 TriggerNMI_a:
-       mov     r0, #FCEU_IQTEMP
+       mov     r0, #FCEU_IQNMI
        b       X6502_IRQBegin_a
 
 
@@ -3111,7 +3159,7 @@ TriggerNMINSF_a:
 X6502_AddCycles_a:
        ldr     r2, =nes_registers
        ldr     r1, [r2, #0x1c]
-       mvn     r3, #49
+       mvn     r3, #47                 @ r3=-48
        mla     r0, r3, r0, r1
        str     r0, [r2, #0x1c]
        bx      lr
@@ -3131,5 +3179,21 @@ X6502_rebase_a:
 .pool
 
 
+@ the nasty MapIRQHook thing from FCE..
+do_irq_hook:
+       @ I have reviewed all MapIRQHook functions, they only seem to cause IRQs, not messing cycles or something
+       str     REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)]   @ might set irq
+       mov     REG_P_REST, lr                  @ r8
+
+       @ if somebody modifies MapIRQHook without calling reset, we are doomed
+       mov     lr, pc
+       ldr     pc, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
+
+       ldr     REG_OP_TABLE, =cpu_exec_table   @ got trashed because was in r12
+       mov     lr, REG_P_REST
+       ldr     REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)]   @ might set irq
+       bx      lr
+
+
 @ vim:filetype=armasm
 
diff --git a/ncpu.h b/ncpu.h
index 015320a..c123dc7 100644 (file)
--- a/ncpu.h
+++ b/ncpu.h
@@ -78,7 +78,8 @@
  * note: fceu uses this differently
  * [7:0]   - interrupt flags (same as above)
  * [15:8]  - FCEU IRQ pending sources
- * [23:16] - unused
+ * [16]    - a flag which indicates that MapIRQHook is not null
+ * [23:17] - unused
  * [31:24] - stack pointer
  */
 
index 864cae3..ebb32fa 100644 (file)
@@ -8,12 +8,14 @@
 // asm core state
 extern uint32 nes_registers[0x10];
 extern uint32 pc_base;
-uint32 PC_prev = 0;
+uint32 PC_prev = 0, g_cnt = 0;
 
+int cpu_repeat;
+int cpu_lastval;
 
 static void leave(void)
 {
-       printf("A: %02x, X: %02x, Y: %02x, S: %02x\n", X.A, X.X, X.Y, X.S);
+       printf("\nA: %02x, X: %02x, Y: %02x, S: %02x\n", X.A, X.X, X.Y, X.S);
        printf("PC = %04lx, OP=%02X\n", PC_prev, (PC_prev < 0x2000) ? RAM[PC_prev&0x7ff] : ARead[PC_prev](PC_prev));
        exit(1);
 }
@@ -21,35 +23,36 @@ static void leave(void)
 static void compare_state(void)
 {
        uint8 nes_flags;
+       int fail = 0;
 
        if ((nes_registers[0] >> 24) != X.A) {
                printf("A: %02lx vs %02x\n", nes_registers[0] >> 24, X.A);
-               leave();
+               fail = 1;
        }
 
        if ((nes_registers[1] & 0xff) != X.X) {
                printf("X: %02lx vs %02x\n", nes_registers[1] & 0xff, X.X);
-               leave();
+               fail = 1;
        }
 
        if ((nes_registers[2] & 0xff) != X.Y) {
                printf("Y: %02lx vs %02x\n", nes_registers[2] & 0xff, X.Y);
-               leave();
+               fail = 1;
        }
 
        if (nes_registers[3] - pc_base != X.PC) {
                printf("PC: %04lx vs %04x\n", nes_registers[3] - pc_base, X.PC);
-               leave();
+               fail = 1;
        }
 
        if ((nes_registers[4] >> 24) != X.S) {
                printf("S: %02lx vs %02x\n", nes_registers[4] >> 24, X.S);
-               leave();
+               fail = 1;
        }
 
        if (((nes_registers[4]>>8)&0xff) != X.IRQlow) {
                printf("IRQlow: %02lx vs %02x\n", ((nes_registers[4]>>8)&0xff), X.IRQlow);
-               leave();
+               fail = 1;
        }
 
        // NVUB DIZC
@@ -58,15 +61,17 @@ static void compare_state(void)
        if (!(nes_registers[5]&0x000000ff)) nes_flags |= 0x02; // Z
        // nes_flags |= 0x20; // U, not set in C core (set only when pushing)
 
-       if (nes_flags != X.P) {
-               printf("flags: %02x vs %02x\n", nes_flags, X.P);
-               leave();
+       if (nes_flags != (X.P&~0x20)) {
+               printf("flags: %02x vs %02x\n", nes_flags, (X.P&~0x20));
+               fail = 1;
        }
 
        if ((int32)nes_registers[7] != X.count) {
                printf("cycles: %li vs %li\n", (int32)nes_registers[7], X.count);
-               leave();
+               fail = 1;
        }
+
+       if (fail) leave();
 }
 
 
@@ -95,18 +100,26 @@ void X6502_Run_d(int32 c)
        int32 cycles = c << 4; /* *16 */ \
        if (PAL) cycles -= c;  /* *15 */ \
 
-       printf("-- run(%i)\n", (int)c);
+       //printf("-- %06i: run(%i)\n", (int)g_cnt, (int)c);
+       g_cnt += c;
 
        while (cycles > 0)
        {
                PC_prev = X.PC;
                nes_registers[7]=1;
                X.count=1;
+
+               cpu_repeat = 0;
                X6502_Run_c();
+
+               cpu_repeat = 1;
                X6502_Run_a();
+
                compare_state();
                cycles -= 1 - X.count;
        }
+
+       //printf("-- run_end\n");
 }
 
 void X6502_Reset_d(void)
@@ -129,10 +142,12 @@ void X6502_Power_d(void)
 
 void X6502_AddCycles_d(int x)
 {
-       printf("-- AddCycles(%i)\n", x);
+       printf("-- AddCycles(%i|%i)\n", x, x*48);
 
-       X6502_AddCycles_c(x);
-       X6502_AddCycles_a(x);
+       printf("can't use this in debug\n");
+       exit(1);
+       //X6502_AddCycles_c(x);
+       //X6502_AddCycles_a(x);
        //compare_state();
 }
 
diff --git a/state.c b/state.c
index 871ef80..5e4308d 100644 (file)
--- a/state.c
+++ b/state.c
@@ -24,6 +24,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef GP2X
+#include <unistd.h>
+#endif
 
 #include "types.h"
 #include "x6502.h"
@@ -255,7 +258,11 @@ for(;;)
   if(!read32(&size,st)) break;
   switch(t)
   {
-   case 1:if(!ReadStateChunk(st,SFCPU,SFCPUELEMENTS,size)) ret=0;break;
+   case 1:if(!ReadStateChunk(st,SFCPU,SFCPUELEMENTS,size)) ret=0;
+#ifdef ASM_6502
+          asmcpu_unpack();
+#endif
+         break;
    case 2:if(!ReadStateChunk(st,SFCPUC,SFCPUCELEMENTS,size)) ret=0;
           else
          {
@@ -299,6 +306,9 @@ void SaveState(void)
          header[3]=VERSION_NUMERIC;
          fwrite(header,1,16,st);
 
+#ifdef ASM_6502
+          asmcpu_pack();
+#endif
          totalsize=WriteStateChunk(st,1,SFCPU,SFCPUELEMENTS);
          totalsize+=WriteStateChunk(st,2,SFCPUC,SFCPUCELEMENTS);
          totalsize+=WriteStateChunk(st,3,SFPPU,SFPPUELEMENTS);
@@ -310,6 +320,9 @@ void SaveState(void)
          write32(totalsize,st);
          SaveStateStatus[CurrentState]=1;
          fclose(st);
+#ifdef GP2X
+         sync();
+#endif
          FCEU_DispMessage("State %d saved.",CurrentState);
         }
         else
diff --git a/unif.c b/unif.c
index 07ec184..bcd2d3d 100644 (file)
--- a/unif.c
+++ b/unif.c
@@ -27,6 +27,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef GP2X
+#include <unistd.h>
+#endif
 
 
 #include       "types.h"
@@ -132,7 +135,7 @@ static int DoMirroring(int fp)
 {
  uint8 t;
  t=FCEU_fgetc(fp);
- mirrortodo=t; 
+ mirrortodo=t;
 
  {
   static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};
@@ -209,7 +212,7 @@ static int LoadPRG(int fp)
  else
   puts("");
 
- SetupCartPRGMapping(z,malloced[z],t,0); 
+ SetupCartPRGMapping(z,malloced[z],t,0);
  return(1);
 }
 
@@ -340,13 +343,13 @@ int LoadUNIFChunks(int fp)
    for(;;)
    {
     t=FCEU_fread(&uchead,1,4,fp);
-    if(t<4) 
+    if(t<4)
     {
      if(t>0)
-      return 0; 
+      return 0;
      return 1;
     }
-    if(!(FCEU_read32(&uchead.info,fp))) 
+    if(!(FCEU_read32(&uchead.info,fp)))
      return 0;
     t=0;
     for(x=0;x<BMF;x++)
@@ -356,7 +359,7 @@ int LoadUNIFChunks(int fp)
      if(!bfunc[x].init(fp))
       return 0;
      t=1;
-     break;     
+     break;
     }
     if(!t)
      if(FCEU_fseek(fp,uchead.info,SEEK_CUR))
@@ -416,7 +419,7 @@ int UNIFLoad(char *name, int fp)
         FCEU_fseek(fp,0,SEEK_SET);
         FCEU_fread(&unhead,1,4,fp);
         if(memcmp(&unhead,"UNIF",4))
-         return 0;        
+         return 0;
 
        ResetCartMapping();
 
@@ -433,7 +436,7 @@ int UNIFLoad(char *name, int fp)
 
         GameInterface=UNIFGI;
         return 1;
-       
+
        aborto:
 
        FreeUNIF();
@@ -467,4 +470,7 @@ void UNIFCloseWRAM(void)
  if(fssp)
   fclose(fssp);
  fssp=0;
+#ifdef GP2X
+ sync();
+#endif
 }
diff --git a/video.c b/video.c
index 1b0298e..adcb786 100644 (file)
--- a/video.c
+++ b/video.c
@@ -30,6 +30,9 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef GP2X
+#include <unistd.h>
+#endif
 
 #include "types.h"
 #include "video.h"
@@ -249,6 +252,9 @@ int SaveSnapshot(void)
 
  free(compmem);
  fclose(pp);
+#ifdef GP2X
+ sync();
+#endif
 
  return u+1;
 
diff --git a/x6502.c b/x6502.c
index 87ba0f5..cb0d761 100644 (file)
--- a/x6502.c
+++ b/x6502.c
@@ -37,7 +37,7 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 #define _S               X.S
 #define _P               X.P
 #define _PI              X.mooPI
-#define _PZ              X.PZ          // unused?
+//#define _PZ              X.PZ                // unused?
 #define _DB              X.DB
 #define _count           X.count
 #define _tcount          X.tcount
@@ -475,7 +475,7 @@ void X6502_Run_c(void/*int32 cycles*/)
         ADDCYC(temp);
         //temp=_tcount;
         //_tcount=0;
-/*
+
         if(MapIRQHook) MapIRQHook(temp);
 
         temp*=48;
@@ -487,7 +487,6 @@ void X6502_Run_c(void/*int32 cycles*/)
          fhcnt+=fhinc;
         }
 
-
         if(PCMIRQCount>0)
         {
          PCMIRQCount-=temp;
@@ -502,7 +501,7 @@ void X6502_Run_c(void/*int32 cycles*/)
           }
          }
         }
-*/
+
          //printf("$%04x:$%02x\n",_PC,b1);
         //_PC++;
         //printf("$%02x\n",b1);
diff --git a/x6502.h b/x6502.h
index 48843fc..9411108 100644 (file)
--- a/x6502.h
+++ b/x6502.h
@@ -24,7 +24,7 @@ typedef struct {
         uint16 PC;             /* I'll change this to uint32 later... */
                                /* I'll need to AND PC after increments to 0xFFFF */
                                /* when I do, though.  Perhaps an IPC() macro? */
-        uint8 A,X,Y,S,P,mooPI,PZ;
+        uint8 A,X,Y,S,P,mooPI;
         uint8 DB;               /* Data bus "cache" for reads from certain areas */
        uint8 IRQlow;           /* Simulated IRQ pin held low(or is it high?). */
        uint8 jammed;
@@ -78,16 +78,30 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 #define X6502_IRQEnd X6502_IRQEnd_a
 #define X6502_A
 
-extern uint32 nes_registers[0x10];
 #define X6502_Run(c) \
 { \
  int32 cycles = (c) << 4; /* *16 */ \
  if (PAL) cycles -= (c);  /* *15 */ \
  nes_registers[7]+=cycles; \
- if (nes_registers[7] > 0) X6502_Run_a(); \
+ if (nes_registers[7] > 0) { \
+   cycles = (int32)nes_registers[7]; \
+   X6502_Run_a(); \
+   cycles -= (int32)nes_registers[7]; \
+   asmcpu_update(cycles); \
+ } \
 }
 
 #else
+#define TriggerIRQ TriggerIRQ_c
+#define TriggerNMI TriggerNMI_c
+#define TriggerNMINSF TriggerNMINSF_c
+#define X6502_Reset X6502_Reset_c
+#define X6502_Power X6502_Power_c
+#define X6502_AddCycles X6502_AddCycles_c
+#define X6502_IRQBegin X6502_IRQBegin_c
+#define X6502_IRQEnd X6502_IRQEnd_c
+#define X6502_C
+
 #define X6502_Run(c) \
 { \
  int32 cycles = (c) << 4; /* *16 */ \
@@ -113,6 +127,8 @@ void FASTAPASS(1) X6502_IRQEnd_c(int w);
 
 // asm
 #ifdef X6502_A
+extern uint32 nes_registers[0x10];
+extern uint32 pc_base;
 void TriggerIRQ_a(void);
 void TriggerNMI_a(void);
 void TriggerNMINSF_a(void);
@@ -122,6 +138,7 @@ void X6502_Power_a(void);
 void X6502_AddCycles_a(int x);
 void X6502_IRQBegin_a(int w);
 void X6502_IRQEnd_a(int w);
+void X6502_rebase_a(void);
 #endif
 
 // debug