bugfixes in cd/Memory.s, poll loop detection
authornotaz <notasas@gmail.com>
Sat, 24 Mar 2007 18:25:17 +0000 (18:25 +0000)
committernotaz <notasas@gmail.com>
Sat, 24 Mar 2007 18:25:17 +0000 (18:25 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@77 be3aeb3a-fb24-0410-a615-afba39da0efa

Pico/PicoInt.h
Pico/cd/Memory.c
Pico/cd/Memory.s
platform/gp2x/emu.c
platform/gp2x/version.h
platform/linux/port_config.h

index 18e779b..6caff48 100644 (file)
@@ -27,12 +27,16 @@ extern struct Cyclone PicoCpu, PicoCpuS68k;
 #define SekCyclesLeftNoMCD PicoCpu.cycles // cycles left for this run\r
 #define SekCyclesLeft \\r
        (((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)\r
+#define SekCyclesLeftS68k \\r
+       ((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoCpuS68k.cycles)\r
 #define SekSetCyclesLeftNoMCD(c) PicoCpu.cycles=c\r
 #define SekSetCyclesLeft(c) { \\r
        if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SekSetCyclesLeftNoMCD(c); \\r
 }\r
 #define SekPc (PicoCpu.pc-PicoCpu.membase)\r
 #define SekPcS68k (PicoCpuS68k.pc-PicoCpuS68k.membase)\r
+#define SekSetStop(x) { PicoCpu.stopped=x; if (x) PicoCpu.cycles=0; }\r
+#define SekSetStopS68k(x) { PicoCpuS68k.stopped=x; if (x) PicoCpuS68k.cycles=0; }\r
 #endif\r
 \r
 #ifdef EMU_A68K\r
@@ -60,15 +64,25 @@ extern int m68k_ICount;
 extern m68ki_cpu_core PicoM68kCPU; // MD's CPU\r
 extern m68ki_cpu_core PicoS68kCPU; // Mega CD's CPU\r
 #ifndef SekCyclesLeft\r
-#define SekCyclesLeftNoMCD m68k_cycles_remaining()\r
+#define SekCyclesLeftNoMCD PicoM68kCPU.cyc_remaining_cycles\r
 #define SekCyclesLeft \\r
        (((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)\r
+#define SekCyclesLeftS68k \\r
+       ((PicoOpt & 0x2000) ? (SekCycleAimS68k-SekCycleCntS68k) : PicoS68kCPU.cyc_remaining_cycles)\r
 #define SekSetCyclesLeftNoMCD(c) SET_CYCLES(c)\r
 #define SekSetCyclesLeft(c) { \\r
        if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt=SekCycleAim-(c); else SET_CYCLES(c); \\r
 }\r
 #define SekPc m68k_get_reg(&PicoM68kCPU, M68K_REG_PC)\r
 #define SekPcS68k m68k_get_reg(&PicoS68kCPU, M68K_REG_PC)\r
+#define SekSetStop(x) { \\r
+       if(x) { SET_CYCLES(0); PicoM68kCPU.stopped=STOP_LEVEL_STOP; } \\r
+       else PicoM68kCPU.stopped=0; \\r
+}\r
+#define SekSetStopS68k(x) { \\r
+       if(x) { SET_CYCLES(0); PicoS68kCPU.stopped=STOP_LEVEL_STOP; } \\r
+       else PicoS68kCPU.stopped=0; \\r
+}\r
 #endif\r
 #endif\r
 \r
@@ -91,6 +105,7 @@ extern int SekCycleCntS68k;
 extern int SekCycleAimS68k;\r
 \r
 #define SekCyclesResetS68k() {SekCycleCntS68k=SekCycleAimS68k=0;}\r
+#define SekCyclesDoneS68k()  (SekCycleAimS68k-SekCyclesLeftS68k)\r
 \r
 // does not work as expected\r
 //extern int z80ExtraCycles; // extra z80 cycles, used when z80 is [en|dis]abled\r
index 0b11e98..fdbf316 100644 (file)
@@ -33,6 +33,12 @@ typedef unsigned int   u32;
 \r
 // -----------------------------------------------------------------\r
 \r
+// poller detection\r
+#define USE_POLL_DETECT\r
+#define POLL_LIMIT 16\r
+#define POLL_CYCLES 124\r
+// int m68k_poll_addr, m68k_poll_cnt;\r
+unsigned int s68k_poll_adclk, s68k_poll_cnt;\r
 \r
 #ifndef _ASM_CD_MEMORY_C\r
 static u32 m68k_reg_read16(u32 a)\r
@@ -126,12 +132,12 @@ void m68k_reg_write8(u32 a, u32 d)
         if (d & 2) dold &= ~1; // return word RAM to s68k in 2M mode\r
       }\r
       Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register\r
-\r
-/*\r
-     d |= Pico_mcd->s68k_regs[3]&0x1d;\r
-     if (!(d & 4) && (d & 2)) d &= ~1; // return word RAM to s68k in 2M mode\r
-     Pico_mcd->s68k_regs[3] = d; // really use s68k side register\r
-*/\r
+#ifdef USE_POLL_DETECT\r
+      if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = 0;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
       return;\r
     }\r
     case 6:\r
@@ -141,14 +147,28 @@ void m68k_reg_write8(u32 a, u32 d)
       Pico_mcd->bios[0x72] = d;\r
       dprintf("hint vector set to %08x", PicoRead32(0x70));\r
       return;\r
+    case 0xf:\r
+      d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
     case 0xe:\r
       //dprintf("m68k: comm flag: %02x", d);\r
       Pico_mcd->s68k_regs[0xe] = d;\r
+#ifdef USE_POLL_DETECT\r
+      if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = 0;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
       return;\r
   }\r
 \r
   if ((a&0xf0) == 0x10) {\r
       Pico_mcd->s68k_regs[a] = d;\r
+#ifdef USE_POLL_DETECT\r
+      if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = 0;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
       return;\r
   }\r
 \r
@@ -178,48 +198,64 @@ u32 s68k_reg_read16(u32 a)
 \r
   switch (a) {\r
     case 0:\r
-      d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
-      goto end;\r
+      return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
     case 2:\r
       d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
       dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
-      goto end;\r
+      goto poll_detect;\r
     case 6:\r
-      d = CDC_Read_Reg();\r
-      goto end;\r
+      return CDC_Read_Reg();\r
     case 8:\r
-      d = Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
-      goto end;\r
+      return Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
     case 0xC:\r
       d = Pico_mcd->m.timer_stopwatch >> 16;\r
       dprintf("s68k stopwatch timer read (%04x)", d);\r
-      goto end;\r
+      return d;\r
     case 0x30:\r
-      dprintf("s68k int3 timer read (%02x%02x)", Pico_mcd->s68k_regs[30], Pico_mcd->s68k_regs[31]);\r
-      break;\r
+      dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
+      return Pico_mcd->s68k_regs[31];\r
     case 0x34: // fader\r
-      d = 0; // no busy bit\r
-      goto end;\r
+      return 0; // no busy bit\r
     case 0x50: // font data (check: Lunar 2, Silpheed)\r
       READ_FONT_DATA(0x00100000);\r
-      goto end;\r
+      return d;\r
     case 0x52:\r
       READ_FONT_DATA(0x00010000);\r
-      goto end;\r
+      return d;\r
     case 0x54:\r
       READ_FONT_DATA(0x10000000);\r
-      goto end;\r
+      return d;\r
     case 0x56:\r
       READ_FONT_DATA(0x01000000);\r
-      goto end;\r
+      return d;\r
   }\r
 \r
   d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
 \r
-end:\r
+  if (a >= 0x0e && a < 0x30) goto poll_detect;\r
 \r
-  // dprintf("ret = %04x", d);\r
+  return d;\r
 \r
+poll_detect:\r
+#ifdef USE_POLL_DETECT\r
+  // polling detection\r
+  if (a == (s68k_poll_adclk&0xfe)) {\r
+    unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\r
+    if (clkdiff <= POLL_CYCLES) {\r
+      s68k_poll_cnt++;\r
+      //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);\r
+      if (s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(1);\r
+        //printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, SekPcS68k, a);\r
+      }\r
+      s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
+      return d;\r
+    }\r
+  }\r
+  s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
+  s68k_poll_cnt = 0;\r
+\r
+#endif\r
   return d;\r
 }\r
 \r
@@ -292,8 +328,7 @@ void s68k_reg_write8(u32 a, u32 d)
       Pico_mcd->m.timer_stopwatch = 0;\r
       return;\r
     case 0xe:\r
-      Pico_mcd->s68k_regs[0Xf] = (d>>1) | (d<<7); // ror8, Gens note: Dragons lair\r
-      Pico_mcd->m.timer_stopwatch = 0;\r
+      Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
       return;\r
     case 0x31:\r
       dprintf("s68k set int3 timer: %02x", d);\r
@@ -634,8 +669,23 @@ static void PicoWriteM68k16(u32 a,u16 d)
     return;\r
   }\r
 \r
-  if ((a&0xffffc0)==0xa12000)\r
+  // regs\r
+  if ((a&0xffffc0)==0xa12000) {\r
     rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
+    if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
+      Pico_mcd->s68k_regs[0xe] = d >> 8;\r
+#ifdef USE_POLL_DETECT\r
+      if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
+        SekSetStopS68k(0); s68k_poll_adclk = -1;\r
+        //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a);\r
+      }\r
+#endif\r
+      return;\r
+    }\r
+    m68k_reg_write8(a,  d>>8);\r
+    m68k_reg_write8(a+1,d&0xff);\r
+    return;\r
+  }\r
 \r
   OtherWrite16(a,d);\r
 }\r
@@ -1408,6 +1458,8 @@ void PicoMemSetupCD()
   PicoCpuS68k.write16=PicoWriteS68k16;\r
   PicoCpuS68k.write32=PicoWriteS68k32;\r
 #endif\r
+  // m68k_poll_addr = m68k_poll_cnt = 0;\r
+  s68k_poll_adclk = s68k_poll_cnt = 0;\r
 }\r
 \r
 \r
index 6bdf3e5..8c360f8 100644 (file)
@@ -7,6 +7,7 @@
 
 
 .equiv PCM_STEP_SHIFT, 11
+.equiv POLL_LIMIT, 16
 
 @ jump tables
 .data
@@ -132,6 +133,8 @@ m_s68k_decode_write_table:
 .extern SRam
 .extern gfx_cd_write16
 .extern s68k_reg_write8
+.extern s68k_poll_adclk
+.extern PicoCpuS68k
 
 
 @ r0=reg3, r1-r3=temp
@@ -665,7 +668,7 @@ m_m68k_read16_m68k_regs:
     .long   m_m68k_read16_r0c
 m_m68k_read16_r00:
     add     r1, r1, #0x110000
-    ldr     r0, [r1, #30]
+    ldr     r0, [r1, #0x30]
     add     r1, r1, #0x002200
     ldrb    r1, [r1, #2]              @ Pico_mcd->m.busreq
     and     r0, r0, #0x04000000       @ we need irq2 mask state
@@ -1073,6 +1076,9 @@ m_m68k_write16_system_io:
     bne     OtherWrite16
 
 m_m68k_write16_m68k_regs:
+    and     r0, r0, #0x3e
+    cmp     r0, #0x0e
+    beq     m_m68k_write16_regs_spec
     and     r3, r1, #0xff
     add     r2, r0, #1
     stmfd   sp!,{r2,r3,lr}
@@ -1081,6 +1087,24 @@ m_m68k_write16_m68k_regs:
     ldmfd   sp!,{r0,r1,lr}
     b       m68k_reg_write8
 
+m_m68k_write16_regs_spec:               @ special case
+    ldr     r2, =(Pico+0x22200)
+    ldr     r3, =s68k_poll_adclk
+    mov     r0, #0x110000
+    ldr     r2, [r2]
+    add     r0, r0, #0x00000e
+    mov     r1, r1, lsr #8
+    strb    r1, [r2, r0]                @ if (a == 0xe) s68k_regs[0x0e] = d >> 8;
+    ldr     r2, [r3]
+    mov     r1, #0
+    and     r2, r2, #0xfe
+    cmp     r2, #0x0e
+    bxne    lr
+    ldr     r0, =PicoCpuS68k
+    str     r1, [r0, #0x58]             @ push s68k out of stopped state
+    str     r1, [r3]
+    bx      lr
+
 
 m_m68k_write16_vdp:
     tst     r0, #0x70000
@@ -1454,7 +1478,10 @@ m_s68k_read16_regs:
     sub     r2, r0, #0x58
     cmp     r2, #0x10
     blo     gfx_cd_read
-    b       s68k_reg_read16
+    cmp     r0, #8
+    bne     s68k_reg_read16
+    mov     r0, #1
+    b       Read_CDC_Host
 
 
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1664,7 +1691,7 @@ m_s68k_write8_backup:                   @ 0xfe0000 - 0xfe3fff (repeated?)
     strb    r1, [r2, r0]
     ldr     r1, =SRam
     mov     r0, #1
-    str     r0, [r1, #0x0e]             @ SRam.changed = 1
+    strb    r0, [r1, #0x0e]             @ SRam.changed = 1
     bx      lr
 
 
index 60907ff..f43f9b7 100644 (file)
@@ -790,6 +790,9 @@ static void emu_msg_cb(const char *msg)
        }\r
        gettimeofday(&noticeMsgTime, 0);\r
        noticeMsgTime.tv_sec -= 2;\r
+\r
+       /* assumption: emu_msg_cb gets called only when something slow is about to happen */\r
+       reset_timing = 1;\r
 }\r
 \r
 static void emu_state_cb(const char *str)\r
@@ -1168,7 +1171,9 @@ void emu_Loop(void)
                                if (frames_shown > frames_done) frames_shown = frames_done;\r
                        }\r
                }\r
-\r
+#if 0\r
+               sprintf(fpsbuff, "%05i", Pico.m.frame_count);\r
+#endif\r
                lim_time = (frames_done+1) * target_frametime;\r
                if(currentConfig.Frameskip >= 0) { // frameskip enabled\r
                        for(i = 0; i < currentConfig.Frameskip; i++) {\r
index db5382d..7bb0de2 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.201"\r
+#define VERSION "1.30"\r
 \r
index e5c88bb..a0a855a 100644 (file)
@@ -12,8 +12,8 @@
 // pico.c
 #define CAN_HANDLE_240_LINES   1
 
-#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
-//#define dprintf(x...)
+//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
+#define dprintf(x...)
 
 #endif //PORT_CONFIG_H