optimizations, fixes, hacks, psp, ...
authornotaz <notasas@gmail.com>
Thu, 15 Nov 2007 23:01:20 +0000 (23:01 +0000)
committernotaz <notasas@gmail.com>
Thu, 15 Nov 2007 23:01:20 +0000 (23:01 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@295 be3aeb3a-fb24-0410-a615-afba39da0efa

37 files changed:
Pico/Draw.c
Pico/Draw2.c
Pico/Memory.c
Pico/Memory.s
Pico/MemoryCmn.c
Pico/Memory_amips.s
Pico/Misc.c
Pico/Misc_amips.s [new file with mode: 0644]
Pico/Pico.c
Pico/PicoInt.h
Pico/Sek.c
Pico/cd/Area.c
Pico/cd/Memory.c
Pico/cd/Pico.c
Pico/cd/buffering.c
Pico/sound/sound.c
Pico/sound/ym2612.c
Pico/sound/ym2612.h
cpu/DrZ80/drz80.s
cpu/cz80/cz80.c
cpu/cz80/cz80.h
cpu/cz80/cz80macro.h
cpu/fame/famec.c
platform/gp2x/940ctl.c
platform/gp2x/Makefile
platform/gp2x/version.h
platform/linux/940ctl_ym2612.c
platform/linux/Makefile
platform/psp/Makefile
platform/psp/emu.c
platform/psp/emu.h
platform/psp/menu.c
platform/psp/mp3.c
platform/psp/mp3.h [new file with mode: 0644]
platform/psp/psp.c
platform/psp/version.h
tools/gcda.c [new file with mode: 0644]

index 55ceda7..49f3f40 100644 (file)
@@ -66,7 +66,7 @@ void blockcpy_or(void *dst, void *src, size_t n, int pat)
 #endif\r
 \r
 \r
-#ifdef _ASM_DRAW_C_MIPS\r
+#ifdef _ASM_DRAW_C_AMIPS\r
 int TileNorm(int sx,int addr,int pal);\r
 int TileFlip(int sx,int addr,int pal);\r
 #else\r
@@ -1127,8 +1127,7 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh)
 #ifndef _ASM_DRAW_C\r
 static void BackFill(int reg7, int sh)\r
 {\r
-  unsigned int back=0;\r
-  unsigned int *pd=NULL,*end=NULL;\r
+  unsigned int back;\r
 \r
   // Start with a blank scanline (background colour):\r
   back=reg7&0x3f;\r
@@ -1136,10 +1135,7 @@ static void BackFill(int reg7, int sh)
   back|=back<<8;\r
   back|=back<<16;\r
 \r
-  pd= (unsigned int *)(HighCol+8);\r
-  end=(unsigned int *)(HighCol+8+320);\r
-\r
-  do { pd[0]=pd[1]=pd[2]=pd[3]=back; pd+=4; } while (pd<end);\r
+  memset32((int *)(HighCol+8), back, 320/4);\r
 }\r
 #endif\r
 \r
index 3a511b2..ec82e44 100644 (file)
@@ -485,8 +485,7 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
 #ifndef _ASM_DRAW_C\r
 static void BackFillFull(int reg7)\r
 {\r
-       unsigned int back, i;\r
-       unsigned int *p=(unsigned int *)PicoDraw2FB;\r
+       unsigned int back;\r
 \r
        // Start with a background color:\r
 //     back=PicoCramHigh[reg7&0x3f];\r
@@ -494,12 +493,7 @@ static void BackFillFull(int reg7)
        back|=back<<8;\r
        back|=back<<16;\r
 \r
-       for(i = LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/16; i; i--) {\r
-               *p++ = back; // do 16 pixels per iteration\r
-               *p++ = back;\r
-               *p++ = back;\r
-               *p++ = back;\r
-       }\r
+       memset32((int *)PicoDraw2FB, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);\r
 }\r
 #endif\r
 \r
index ca92e81..1e6630d 100644 (file)
@@ -334,9 +334,12 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
   log_io(a, 8, 0);\r
   if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
 \r
-  d=OtherRead16(a&~1, 8); if ((a&1)==0) d>>=8;\r
+  if ((a&0xe700e0)==0xc00000) // VDP\r
+       d=PicoVideoRead(a);\r
+  else d=OtherRead16(a&~1, 8);\r
+  if ((a&1)==0) d>>=8;\r
+\r
 \r
-end:\r
 #ifdef __debug_io\r
   dprintf("r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
 #endif\r
@@ -370,7 +373,9 @@ PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
   if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom\r
   log_io(a, 16, 0);\r
 \r
-  d = OtherRead16(a, 16);\r
+  if ((a&0xe700e0)==0xc00000)\r
+       d = PicoVideoRead(a);\r
+  else d = OtherRead16(a, 16);\r
 \r
 end:\r
 #ifdef __debug_io\r
@@ -404,7 +409,9 @@ PICO_INTERNAL_ASM u32 PicoRead32(u32 a)
   if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom\r
   log_io(a, 32, 0);\r
 \r
-  d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
+  if ((a&0xe700e0)==0xc00000)\r
+       d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);\r
+  else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
 \r
 end:\r
 #ifdef __debug_io\r
@@ -454,6 +461,7 @@ void PicoWrite16(u32 a,u16 d)
   log_io(a, 16, 1);\r
 \r
   a&=0xfffffe;\r
+  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP\r
   OtherWrite16(a,d);\r
 }\r
 \r
@@ -476,6 +484,14 @@ static void PicoWrite32(u32 a,u32 d)
   log_io(a, 32, 1);\r
 \r
   a&=0xfffffe;\r
+  if ((a&0xe700e0)==0xc00000)\r
+  {\r
+    // VDP:\r
+    PicoVideoWrite(a,  (u16)(d>>16));\r
+    PicoVideoWrite(a+2,(u16)d);\r
+    return;\r
+  }\r
+\r
   OtherWrite16(a,  (u16)(d>>16));\r
   OtherWrite16(a+2,(u16)d);\r
 }\r
@@ -660,10 +676,6 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
 {\r
   u8 ret = 0;\r
 \r
-#ifndef _USE_DRZ80\r
-  if (a<0x4000) return Pico.zram[a&0x1fff];\r
-#endif\r
-\r
   if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)\r
   {\r
     if (PicoOpt&1) ret = (u8) YM2612Read();\r
@@ -681,10 +693,8 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a)
     return ret;\r
   }\r
 \r
-#ifdef _USE_DRZ80\r
-  // should not be needed || dprintf("z80_read RAM");\r
+  // should not be needed, cores should be able to access RAM themselves\r
   if (a<0x4000) return Pico.zram[a&0x1fff];\r
-#endif\r
 \r
   elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, ret);\r
   return ret;\r
@@ -696,10 +706,6 @@ PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a)
 PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)\r
 #endif\r
 {\r
-#ifndef _USE_DRZ80\r
-  if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }\r
-#endif\r
-\r
   if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald)\r
   {\r
     if(PicoOpt&1) emustatus|=YM2612Write(a, data) & 1;\r
@@ -730,10 +736,8 @@ PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
     return;\r
   }\r
 \r
-#ifdef _USE_DRZ80\r
-  // should not be needed, drZ80 knows how to access RAM itself || dprintf("z80_write RAM @ %08x", lr);\r
+  // should not be needed\r
   if (a<0x4000) { Pico.zram[a&0x1fff]=data; return; }\r
-#endif\r
 \r
   elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);\r
 }\r
index 732e6b8..7e16384 100644 (file)
@@ -386,17 +386,14 @@ m_read8_misc2:
     cmp     r2, #0x4000\r
     mvnne   r0, #0\r
     bxne    lr                @ invalid\r
-.if EXTERNAL_YM2612\r
     ldr     r1, =PicoOpt\r
     ldr     r1, [r1]\r
     tst     r1, #1\r
-    beq     m_read8_fake_ym2612\r
-    tst     r1, #0x200\r
-    beq     YM2612Read_\r
-    b       YM2612Read_940\r
-.else\r
-    b       YM2612Read_\r
-.endif\r
+\r
+    ldrne   r1, =ym2612_st\r
+    ldrne   r1, [r1]\r
+    ldrneb  r0, [r1, #0x11]   @ ym2612_st->status\r
+    bxne    lr\r
 \r
 m_read8_fake_ym2612:\r
     ldr     r3, =(Pico+0x22200)\r
index f31a11e..145a7e6 100644 (file)
@@ -72,9 +72,9 @@ static
 void z80WriteBusReq(u32 d)
 {
   d&=1; d^=1;
-  //if (Pico.m.scanline != -1)
   {
-    if(!d) {
+    if (!d)
+    {
       // this is for a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)
       if (Pico.m.z80Run) {
         int lineCycles;
@@ -85,7 +85,7 @@ void z80WriteBusReq(u32 d)
         if (lineCycles > 0) { // && lineCycles <= 488) {
           //dprintf("zrun: %i/%i cycles", lineCycles, (lineCycles>>1)-(lineCycles>>5));
           lineCycles=(lineCycles>>1)-(lineCycles>>5);
-          z80_run(lineCycles);
+          z80_run_nr(lineCycles);
         }
       }
     } else {
@@ -136,10 +136,6 @@ u32 OtherRead16(u32 a, int realsize)
     goto end;
   }
 
-#ifndef _ASM_MEMORY_C
-  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }
-#endif
-
   d = OtherRead16End(a, realsize);
 
 end:
@@ -204,7 +200,6 @@ static
 #endif
 void OtherWrite16(u32 a,u32 d)
 {
-  if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }
   if (a==0xa11100)            { z80WriteBusReq(d>>8); return; }
   if (a==0xa11200)            { dprintf("write z80reset: %04x", d); if(!(d&0x100)) z80_reset(); return; }
   if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports
index 0fab4f4..b5ec099 100644 (file)
@@ -425,8 +425,10 @@ m_read8_z80_misc:
     andi    $t0, 1
     beqz    $t0, m_read8_fake_ym2612
     lui     $t0, %hi(Pico+0x22208)
-    j       YM2612Read_
-    nop
+    lui     $t0, %hi(ym2612_st)
+    lw      $t0, %lo(ym2612_st)($t0)
+    jr      $ra
+    lb      $v0, 0x11($t0)
 
 m_read8_fake_ym2612:
     lb      $v0, %lo(Pico+0x22208)($t0) # Pico.m.rotate
index a092b93..f21c511 100644 (file)
@@ -353,7 +353,7 @@ PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count)
                *dest++ = (src_[0] << 8) | src_[1];\r
 }\r
 \r
-\r
+#ifndef _ASM_MISC_C_AMIPS\r
 PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)\r
 {\r
        intblock *bd = (intblock *) dest, *bs = (intblock *) src;\r
@@ -376,5 +376,7 @@ PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)
        while (count--)\r
                *dest++ = c;\r
 }\r
+void memset32_uncached(int *dest, int c, int count) { memset32(dest, c, count); }\r
+#endif\r
 #endif\r
 \r
diff --git a/Pico/Misc_amips.s b/Pico/Misc_amips.s
new file mode 100644 (file)
index 0000000..f6efeb0
--- /dev/null
@@ -0,0 +1,171 @@
+# vim:filetype=mips
+
+.set noreorder
+.set noat
+
+.text
+.align 4
+
+.globl memset32 # int *dest, int c, int count
+
+memset32:
+ms32_aloop:
+    andi    $t0, $a0, 0x3f
+    beqz    $t0, ms32_bloop_prep
+    nop
+    sw      $a1, 0($a0)
+    addiu   $a2, -1
+    beqz    $a2, ms32_return
+    addiu   $a0, 4
+    j       ms32_aloop
+    nop
+
+ms32_bloop_prep:
+    srl     $t0, $a2, 4    # we will do 64 bytes per iteration (cache line)
+    beqz    $t0, ms32_bloop_end
+
+ms32_bloop:
+    addiu   $t0, -1
+    cache   0x18, ($a0)    # create dirty exclusive
+    sw      $a1, 0x00($a0)
+    sw      $a1, 0x04($a0)
+    sw      $a1, 0x08($a0)
+    sw      $a1, 0x0c($a0)
+    sw      $a1, 0x10($a0)
+    sw      $a1, 0x14($a0)
+    sw      $a1, 0x18($a0)
+    sw      $a1, 0x1c($a0)
+    sw      $a1, 0x20($a0)
+    sw      $a1, 0x24($a0)
+    sw      $a1, 0x28($a0)
+    sw      $a1, 0x2c($a0)
+    sw      $a1, 0x30($a0)
+    sw      $a1, 0x34($a0)
+    sw      $a1, 0x38($a0)
+    sw      $a1, 0x3c($a0)
+    bnez    $t0, ms32_bloop
+    addiu   $a0, 0x40
+
+ms32_bloop_end:
+    andi    $a2, $a2, 0x0f
+    beqz    $a2, ms32_return
+
+ms32_cloop:
+    addiu   $a2, -1
+    sw      $a1, 0($a0)
+    bnez    $a2, ms32_cloop
+    addiu   $a0, 4
+
+ms32_return:
+    jr      $ra
+    nop
+
+
+.globl memset32_uncached # int *dest, int c, int count
+
+memset32_uncached:
+    srl     $t0, $a2, 3    # we will do 32 bytes per iteration
+    beqz    $t0, ms32u_bloop_end
+
+ms32u_bloop:
+    addiu   $t0, -1
+    sw      $a1, 0x00($a0)
+    sw      $a1, 0x04($a0)
+    sw      $a1, 0x08($a0)
+    sw      $a1, 0x0c($a0)
+    sw      $a1, 0x10($a0)
+    sw      $a1, 0x14($a0)
+    sw      $a1, 0x18($a0)
+    sw      $a1, 0x1c($a0)
+    bnez    $t0, ms32u_bloop
+    addiu   $a0, 0x20
+
+ms32u_bloop_end:
+    andi    $a2, $a2, 0x0f
+    beqz    $a2, ms32u_return
+
+ms32u_cloop:
+    addiu   $a2, -1
+    sw      $a1, 0($a0)
+    bnez    $a2, ms32u_cloop
+    addiu   $a0, 4
+
+ms32u_return:
+    jr      $ra
+    nop
+
+
+.globl memcpy32 # int *dest, int *src, int count
+
+memcpy32:
+mc32_aloop:
+    andi    $t0, $a0, 0x3f
+    beqz    $t0, mc32_bloop_prep
+    nop
+    lw      $t1, 0($a1)
+    addiu   $a2, -1
+    sw      $t1, 0($a0)
+    beqz    $a2, mc32_return
+    addiu   $a0, 4
+    j       mc32_aloop
+    addiu   $a1, 4
+
+mc32_bloop_prep:
+    srl     $t0, $a2, 4    # we will do 64 bytes per iteration (cache line)
+    beqz    $t0, mc32_bloop_end
+
+mc32_bloop:
+    addiu   $t0, -1
+    cache   0x18, ($a0)    # create dirty exclusive
+    lw      $t2, 0x00($a1)
+    lw      $t3, 0x04($a1)
+    lw      $t4, 0x08($a1)
+    lw      $t5, 0x0c($a1)
+    lw      $t6, 0x10($a1)
+    lw      $t7, 0x14($a1)
+    lw      $t8, 0x18($a1)
+    lw      $t9, 0x1c($a1)
+    sw      $t2, 0x00($a0)
+    sw      $t3, 0x04($a0)
+    sw      $t4, 0x08($a0)
+    sw      $t5, 0x0c($a0)
+    sw      $t6, 0x10($a0)
+    sw      $t7, 0x14($a0)
+    sw      $t8, 0x18($a0)
+    sw      $t9, 0x1c($a0)
+    lw      $t2, 0x20($a1)
+    lw      $t3, 0x24($a1)
+    lw      $t4, 0x28($a1)
+    lw      $t5, 0x2c($a1)
+    lw      $t6, 0x30($a1)
+    lw      $t7, 0x34($a1)
+    lw      $t8, 0x38($a1)
+    lw      $t9, 0x3c($a1)
+    sw      $t2, 0x20($a0)
+    sw      $t3, 0x24($a0)
+    sw      $t4, 0x28($a0)
+    sw      $t5, 0x2c($a0)
+    sw      $t6, 0x30($a0)
+    sw      $t7, 0x34($a0)
+    sw      $t8, 0x38($a0)
+    sw      $t9, 0x3c($a0)
+    addiu   $a0, 0x40
+    bnez    $t0, mc32_bloop
+    addiu   $a1, 0x40
+
+mc32_bloop_end:
+    andi    $a2, $a2, 0x0f
+    beqz    $a2, mc32_return
+
+mc32_cloop:
+    lw      $t1, 0($a1)
+    addiu   $a2, -1
+    addiu   $a1, 4
+    sw      $t1, 0($a0)
+    bnez    $a2, mc32_cloop
+    addiu   $a0, 4
+
+mc32_return:
+    jr      $ra
+    nop
+
index bc764b6..9ad226d 100644 (file)
@@ -297,10 +297,10 @@ static void PicoRunZ80Simple(int line_from, int line_to)
       if ((line == 224 || line == line_sample) && PsndOut) getSamples(line);\r
       if (line == 32 && PsndOut) emustatus &= ~1;\r
       if (line >= line_from_r && line < line_to_r)\r
-        z80_run(228);\r
+        z80_run_nr(228);\r
     }\r
   } else if (line_to_r-line_from_r > 0) {\r
-    z80_run(228*(line_to_r-line_from_r));\r
+    z80_run_nr(228*(line_to_r-line_from_r));\r
     // samples will be taken by caller\r
   }\r
 }\r
index f68079e..0cd0644 100644 (file)
@@ -49,6 +49,9 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
 #define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }\r
 #define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }\r
 #define SekShouldInterrupt (PicoCpuCM68k.irq > (PicoCpuCM68k.srh&7))\r
+\r
+#define SekInterrupt(i) PicoCpuCM68k.irq=i\r
+\r
 #ifdef EMU_M68K\r
 #define EMU_CORE_DEBUG\r
 #endif\r
@@ -56,7 +59,7 @@ extern struct Cyclone PicoCpuCM68k, PicoCpuCS68k;
 \r
 #ifdef EMU_F68K\r
 #include "../cpu/fame/fame.h"\r
-M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;\r
+extern M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;\r
 #define SekCyclesLeftNoMCD PicoCpuFM68k.io_cycle_counter\r
 #define SekCyclesLeft \\r
        (((PicoMCD&1) && (PicoOpt & 0x2000)) ? (SekCycleAim-SekCycleCnt) : SekCyclesLeftNoMCD)\r
@@ -77,6 +80,9 @@ M68K_CONTEXT PicoCpuFM68k, PicoCpuFS68k;
        if (x) { PicoCpuFS68k.execinfo |= FM68K_HALTED; PicoCpuFS68k.io_cycle_counter = 0; } \\r
 }\r
 #define SekShouldInterrupt fm68k_would_interrupt()\r
+\r
+#define SekInterrupt(irq) PicoCpuFM68k.interrupts[0]=irq\r
+\r
 #ifdef EMU_M68K\r
 #define EMU_CORE_DEBUG\r
 #endif\r
@@ -106,6 +112,14 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
        else PicoCpuMS68k.stopped=0; \\r
 }\r
 #define SekShouldInterrupt (CPU_INT_LEVEL > FLAG_INT_MASK)\r
+\r
+#define SekInterrupt(irq) {\r
+       void *oldcontext = m68ki_cpu_p; \\r
+       m68k_set_context(&PicoCpuMM68k); \\r
+       m68k_set_irq(irq); \\r
+       m68k_set_context(oldcontext); \\r
+}\r
+\r
 #endif\r
 #endif\r
 \r
@@ -148,6 +162,46 @@ extern int SekCycleAimS68k;
 #define SekEndRun(c)\r
 #endif\r
 \r
+// ----------------------- Z80 CPU -----------------------\r
+\r
+#if defined(_USE_MZ80)\r
+#include "../../cpu/mz80/mz80.h"\r
+\r
+#define z80_run(cycles)    mz80_run(cycles)\r
+#define z80_run_nr(cycles) mz80_run(cycles)\r
+#define z80_int()          mz80int(0)\r
+#define z80_resetCycles()  mz80GetElapsedTicks(1)\r
+\r
+#elif defined(_USE_DRZ80)\r
+#include "../../cpu/DrZ80/drz80.h"\r
+\r
+extern struct DrZ80 drZ80;\r
+\r
+#define z80_run(cycles)    ((cycles) - DrZ80Run(&drZ80, cycles))\r
+#define z80_run_nr(cycles) DrZ80Run(&drZ80, cycles)\r
+#define z80_int() { \\r
+  drZ80.z80irqvector = 0xFF; /* default IRQ vector RST opcode */ \\r
+  drZ80.Z80_IRQ = 1; \\r
+}\r
+#define z80_resetCycles()\r
+\r
+#elif defined(_USE_CZ80)\r
+#include "../../cpu/cz80/cz80.h"\r
+\r
+#define z80_run(cycles)    Cz80_Exec(&CZ80, cycles)\r
+#define z80_run_nr(cycles) Cz80_Exec(&CZ80, cycles)\r
+#define z80_int()          Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE)\r
+#define z80_resetCycles()\r
+\r
+#else\r
+\r
+#define z80_run(cycles)    (cycles)\r
+#define z80_run_nr(cycles)\r
+#define z80_int()\r
+#define z80_resetCycles()\r
+\r
+#endif\r
+\r
 // ---------------------------------------------------------\r
 \r
 extern int PicoMCD;\r
@@ -358,7 +412,6 @@ PICO_INTERNAL int PicoFrameMCD(void);
 // Sek.c\r
 PICO_INTERNAL int SekInit(void);\r
 PICO_INTERNAL int SekReset(void);\r
-PICO_INTERNAL int SekInterrupt(int irq);\r
 PICO_INTERNAL void SekState(int *data);\r
 PICO_INTERNAL void SekSetRealTAS(int use_real);\r
 \r
@@ -398,9 +451,6 @@ PICO_INTERNAL int  PsndRender(int offset, int length);
 PICO_INTERNAL void PsndClear(void);\r
 // z80 functionality wrappers\r
 PICO_INTERNAL void z80_init(void);\r
-PICO_INTERNAL void z80_resetCycles(void);\r
-PICO_INTERNAL void z80_int(void);\r
-PICO_INTERNAL int  z80_run(int cycles);\r
 PICO_INTERNAL void z80_pack(unsigned char *data);\r
 PICO_INTERNAL void z80_unpack(unsigned char *data);\r
 PICO_INTERNAL void z80_reset(void);\r
index df13fba..4bf06d1 100644 (file)
@@ -165,33 +165,6 @@ PICO_INTERNAL int SekReset()
 }\r
 \r
 \r
-PICO_INTERNAL int SekInterrupt(int irq)\r
-{\r
-#ifdef EMU_CORE_DEBUG\r
-  {\r
-    extern int dbg_irq_level;\r
-    dbg_irq_level=irq;\r
-    return 0;\r
-  }\r
-#endif\r
-#ifdef EMU_C68K\r
-  PicoCpuCM68k.irq=irq;\r
-#endif\r
-#ifdef EMU_M68K\r
-  {\r
-    void *oldcontext = m68ki_cpu_p;\r
-    m68k_set_context(&PicoCpuMM68k);\r
-    m68k_set_irq(irq); // raise irq (gets lowered after taken or must be done in ack)\r
-    m68k_set_context(oldcontext);\r
-  }\r
-#endif\r
-#ifdef EMU_F68K\r
-  PicoCpuFM68k.interrupts[0]=irq;\r
-#endif\r
-\r
-  return 0;\r
-}\r
-\r
 // data must be word aligned\r
 PICO_INTERNAL void SekState(int *data)\r
 {\r
index 1dd6fc4..aba08e3 100644 (file)
@@ -164,8 +164,12 @@ static int g_read_offs = 0;
        g_read_offs += len;
 
 #define CHECKED_READ2(len2,data) \
-       if (len2 != len) R_ERROR_RETURN("unexpected len, wanted " #len2); \
-       CHECKED_READ(len2, data)
+       if (len2 != len) { \
+               printf("unexpected len %i, wanted %i (%s)", len, len2, #len2); \
+               if (len > len2) R_ERROR_RETURN("failed."); \
+               /* else read anyway and hope for the best.. */ \
+       } \
+       CHECKED_READ(len, data)
 
 #define CHECKED_READ_BUFF(buff) CHECKED_READ2(sizeof(buff), &buff);
 
index 8053185..1910825 100644 (file)
@@ -454,47 +454,72 @@ static u32 PicoReadM68k8(u32 a)
 {\r
   u32 d=0;\r
 \r
-  if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram\r
-\r
   a&=0xffffff;\r
 \r
-  if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios\r
+  switch (a >> 17)\r
+  {\r
+    case 0x00>>1: // BIOS: 000000 - 020000\r
+      d = *(u8 *)(Pico_mcd->bios+(a^1));\r
+      break;\r
+    case 0x02>>1: // prg RAM\r
+      if ((Pico_mcd->m.busreq&3)!=1) {\r
+        u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+        d = *(prg_bank+((a^1)&0x1ffff));\r
+      }\r
+      break;\r
+    case 0x20>>1: // word RAM: 200000 - 220000\r
+      wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
+      a &= 0x1ffff;\r
+      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        d = Pico_mcd->word_ram1M[bank][a^1];\r
+      } else {\r
+        // allow access in any mode, like Gens does\r
+        d = Pico_mcd->word_ram2M[a^1];\r
+      }\r
+      wrdprintf("ret = %02x", (u8)d);\r
+      break;\r
+    case 0x22>>1: // word RAM: 220000 - 240000\r
+      wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
+      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
+        d = Pico_mcd->word_ram1M[bank][a^1];\r
+      } else {\r
+        // allow access in any mode, like Gens does\r
+        d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
+      }\r
+      wrdprintf("ret = %02x", (u8)d);\r
+      break;\r
+    case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
+    case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
+    case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
+    case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
+      // VDP\r
+      if ((a&0xe700e0)==0xc00000) {\r
+        d=PicoVideoRead(a);\r
+        if ((a&1)==0) d>>=8;\r
+      }\r
+      break;\r
+    case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
+    case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
+    case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
+    case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:\r
+      // RAM:\r
+      d = *(u8 *)(Pico.ram+((a^1)&0xffff));\r
+      break;\r
+    default:\r
+      if ((a&0xff4000)==0xa00000) { d=z80Read8(a); break; } // Z80 Ram\r
+      if ((a&0xffffc0)==0xa12000)\r
+        rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
 \r
-  // prg RAM\r
-  if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
-    u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-    d = *(prg_bank+((a^1)&0x1ffff));\r
-    goto end;\r
-  }\r
+      d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
 \r
-  // word RAM\r
-  if ((a&0xfc0000)==0x200000) {\r
-    wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      int bank = Pico_mcd->s68k_regs[3]&1;\r
-      if (a >= 0x220000)\r
-           a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
-      else a &= 0x1ffff;\r
-      d = Pico_mcd->word_ram1M[bank][a^1];\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
-    }\r
-    wrdprintf("ret = %02x", (u8)d);\r
-    goto end;\r
+      if ((a&0xffffc0)==0xa12000)\r
+        rdprintf("ret = %02x", (u8)d);\r
+      break;\r
   }\r
 \r
-  if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
-\r
-  if ((a&0xffffc0)==0xa12000)\r
-    rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
-  d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
-\r
-  if ((a&0xffffc0)==0xa12000)\r
-    rdprintf("ret = %02x", (u8)d);\r
-\r
-  end:\r
 \r
 #ifdef __debug_io\r
   dprintf("r8 : %06x,   %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
@@ -517,47 +542,71 @@ static u32 PicoReadM68k16(u32 a)
 {\r
   u32 d=0;\r
 \r
-  if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram\r
-\r
   a&=0xfffffe;\r
 \r
-  if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios\r
+  switch (a >> 17)\r
+  {\r
+    case 0x00>>1: // BIOS: 000000 - 020000\r
+      d = *(u16 *)(Pico_mcd->bios+a);\r
+      break;\r
+    case 0x02>>1: // prg RAM\r
+      if ((Pico_mcd->m.busreq&3)!=1) {\r
+        u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+        wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
+        d = *(u16 *)(prg_bank+(a&0x1fffe));\r
+        wrdprintf("ret = %04x", d);\r
+      }\r
+      break;\r
+    case 0x20>>1: // word RAM: 200000 - 220000\r
+      wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
+      a &= 0x1fffe;\r
+      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
+      } else {\r
+        // allow access in any mode, like Gens does\r
+        d = *(u16 *)(Pico_mcd->word_ram2M+a);\r
+      }\r
+      wrdprintf("ret = %04x", d);\r
+      break;\r
+    case 0x22>>1: // word RAM: 220000 - 240000\r
+      wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
+      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
+        d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
+      } else {\r
+        // allow access in any mode, like Gens does\r
+        d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
+      }\r
+      wrdprintf("ret = %04x", d);\r
+      break;\r
+    case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
+    case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
+    case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
+    case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
+      // VDP\r
+      if ((a&0xe700e0)==0xc00000)\r
+        d=PicoVideoRead(a);\r
+      break;\r
+    case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
+    case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
+    case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
+    case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1:\r
+      // RAM:\r
+      d=*(u16 *)(Pico.ram+(a&0xfffe));\r
+      break;\r
+    default:\r
+      if ((a&0xffffc0)==0xa12000)\r
+        rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
 \r
-  // prg RAM\r
-  if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
-    u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-    wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
-    d = *(u16 *)(prg_bank+(a&0x1fffe));\r
-    wrdprintf("ret = %04x", d);\r
-    goto end;\r
-  }\r
+      d = OtherRead16(a, 16);\r
 \r
-  // word RAM\r
-  if ((a&0xfc0000)==0x200000) {\r
-    wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      int bank = Pico_mcd->s68k_regs[3]&1;\r
-      if (a >= 0x220000)\r
-           a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
-      else a &= 0x1fffe;\r
-      d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
-    }\r
-    wrdprintf("ret = %04x", d);\r
-    goto end;\r
+      if ((a&0xffffc0)==0xa12000)\r
+        rdprintf("ret = %04x", d);\r
+      break;\r
   }\r
 \r
-  if ((a&0xffffc0)==0xa12000)\r
-    rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
-\r
-  d = OtherRead16(a, 16);\r
-\r
-  if ((a&0xffffc0)==0xa12000)\r
-    rdprintf("ret = %04x", d);\r
-\r
-  end:\r
 \r
 #ifdef __debug_io\r
   dprintf("r16: %06x, %04x  @%06x", a&0xffffff, d, SekPc);\r
@@ -580,52 +629,81 @@ static u32 PicoReadM68k32(u32 a)
 {\r
   u32 d=0;\r
 \r
-  if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram\r
-\r
   a&=0xfffffe;\r
 \r
-  if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios\r
-\r
-  // prg RAM\r
-  if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
-    u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
-    u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
-    d = (pm[0]<<16)|pm[1];\r
-    goto end;\r
-  }\r
-\r
-  // word RAM\r
-  if ((a&0xfc0000)==0x200000) {\r
-    wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
-    if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
-      int bank = Pico_mcd->s68k_regs[3]&1;\r
-      if (a >= 0x220000) { // cell arranged\r
+  switch (a >> 17)\r
+  {\r
+    case 0x00>>1: { // BIOS: 000000 - 020000\r
+      u16 *pm=(u16 *)(Pico_mcd->bios+a);\r
+      d = (pm[0]<<16)|pm[1];\r
+      break;\r
+    }\r
+    case 0x02>>1: // prg RAM\r
+      if ((Pico_mcd->m.busreq&3)!=1) {\r
+        u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+        u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
+        d = (pm[0]<<16)|pm[1];\r
+      }\r
+      break;\r
+    case 0x20>>1: // word RAM: 200000 - 220000\r
+      wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
+      a&=0x1fffe;\r
+      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
+        u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
+       d = (pm[0]<<16)|pm[1];\r
+      } else {\r
+        // allow access in any mode, like Gens does\r
+        u16 *pm=(u16 *)(Pico_mcd->word_ram2M+a);\r
+       d = (pm[0]<<16)|pm[1];\r
+      }\r
+      wrdprintf("ret = %08x", d);\r
+      break;\r
+    case 0x22>>1: // word RAM: 220000 - 240000\r
+      wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
+      if (Pico_mcd->s68k_regs[3]&4) { // 1M mode, cell arranged?\r
         u32 a1, a2;\r
+        int bank = Pico_mcd->s68k_regs[3]&1;\r
         a1 = (a&2) | (cell_map(a >> 2) << 2);\r
         if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
         else     a2 = a1 + 2;\r
         d  = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;\r
         d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);\r
       } else {\r
-        u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
+        // allow access in any mode, like Gens does\r
+        u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
+       d = (pm[0]<<16)|pm[1];\r
       }\r
-    } else {\r
-      // allow access in any mode, like Gens does\r
-      u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
+      wrdprintf("ret = %08x", d);\r
+      break;\r
+    case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1:\r
+    case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1:\r
+    case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
+    case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
+      // VDP\r
+      d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);\r
+      break;\r
+    case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
+    case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
+    case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1:\r
+    case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: {\r
+      // RAM:\r
+      u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
+      d = (pm[0]<<16)|pm[1];\r
+      break;\r
     }\r
-    wrdprintf("ret = %08x", d);\r
-    goto end;\r
-  }\r
+    default:\r
+      if ((a&0xffffc0)==0xa12000)\r
+        rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
 \r
-  if ((a&0xffffc0)==0xa12000)\r
-    rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
+      d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
 \r
-  d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
+      if ((a&0xffffc0)==0xa12000)\r
+        rdprintf("ret = %08x", d);\r
+      break;\r
+  }\r
 \r
-  if ((a&0xffffc0)==0xa12000)\r
-    rdprintf("ret = %08x", d);\r
 \r
-  end:\r
 #ifdef __debug_io\r
   dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
 #endif\r
@@ -659,8 +737,6 @@ static void PicoWriteM68k8(u32 a,u8 d)
     return;\r
   }\r
 \r
-  a&=0xffffff;\r
-\r
   // prg RAM\r
   if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
     u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
@@ -668,6 +744,8 @@ static void PicoWriteM68k8(u32 a,u8 d)
     return;\r
   }\r
 \r
+  a&=0xffffff;\r
+\r
   // word RAM\r
   if ((a&0xfc0000)==0x200000) {\r
     wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
@@ -712,8 +790,6 @@ static void PicoWriteM68k16(u32 a,u16 d)
     return;\r
   }\r
 \r
-  a&=0xfffffe;\r
-\r
   // prg RAM\r
   if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
     u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
@@ -722,6 +798,8 @@ static void PicoWriteM68k16(u32 a,u16 d)
     return;\r
   }\r
 \r
+  a&=0xfffffe;\r
+\r
   // word RAM\r
   if ((a&0xfc0000)==0x200000) {\r
     wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
@@ -756,6 +834,12 @@ static void PicoWriteM68k16(u32 a,u16 d)
     return;\r
   }\r
 \r
+  // VDP\r
+  if ((a&0xe700e0)==0xc00000) {\r
+    PicoVideoWrite(a,(u16)d);\r
+    return;\r
+  }\r
+\r
   OtherWrite16(a,d);\r
 }\r
 #endif\r
@@ -781,8 +865,6 @@ static void PicoWriteM68k32(u32 a,u32 d)
     return;\r
   }\r
 \r
-  a&=0xfffffe;\r
-\r
   // prg RAM\r
   if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
     u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
@@ -791,6 +873,8 @@ static void PicoWriteM68k32(u32 a,u32 d)
     return;\r
   }\r
 \r
+  a&=0xfffffe;\r
+\r
   // word RAM\r
   if ((a&0xfc0000)==0x200000) {\r
     if (d != 0) // don't log clears\r
@@ -821,6 +905,14 @@ static void PicoWriteM68k32(u32 a,u32 d)
     if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);\r
   }\r
 \r
+  // VDP\r
+  if ((a&0xe700e0)==0xc00000)\r
+  {\r
+    PicoVideoWrite(a,  (u16)(d>>16));\r
+    PicoVideoWrite(a+2,(u16)d);\r
+    return;\r
+  }\r
+\r
   OtherWrite16(a,  (u16)(d>>16));\r
   OtherWrite16(a+2,(u16)d);\r
 }\r
index a97e325..0847f29 100644 (file)
@@ -79,6 +79,7 @@ PICO_INTERNAL int PicoResetMCD(int hard)
   SRam.data = NULL;
   if (PicoOpt&0x8000)
     SRam.data = calloc(1, 0x12000);
+  SRam.start = SRam.end = 0; // unused
 
   return 0;
 }
index 8287618..ad8b355 100644 (file)
@@ -80,6 +80,7 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
                dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
                pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
        }
+else if (prev_lba == 0x80000000) printf("wtf?\n");
 
        dprintf("CD buffer miss %i -> %i\n", prev_lba, lba);
 
@@ -89,6 +90,7 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
                dprintf("CD buffer move=%i, read_len=%i", PicoCDBuffers - read_len, read_len);
                memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048);
                moved = 1;
+if (prev_lba == 0x80000000) printf("wtf?\n");
        }
        else
        {
@@ -104,17 +106,20 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
        {
                int i = 0;
 #if REDUCE_IO_CALLS
-               int bufs = (read_len*2048+304) / (2048+304);
+               int bufs = (read_len*2048) / (2048+304);
                pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F);
                for (i = 1; i < bufs; i++)
                        // should really use memmove here, but my memcpy32 implementation is also suitable here
                        memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4);
 #endif
-               for (; i < read_len; i++)
+               for (; i < read_len - 1; i++)
                {
                        pm_read(cd_buffer + i*2048, 2048 + 304, Pico_mcd->TOC.Tracks[0].F);
                        // pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); // seeking is slower, in PSP case even more
                }
+               // further data might be moved, do not overwrite
+               pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F);
+               pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR);
        }
        else
        {
index 68106bc..d901a1d 100644 (file)
@@ -1,7 +1,7 @@
 // This is part of Pico Library\r
 \r
 // (c) Copyright 2004 Dave, All rights reserved.\r
-// (c) Copyright 2006 notaz, All rights reserved.\r
+// (c) Copyright 2006,2007 notaz, All rights reserved.\r
 // Free for non-commercial use.\r
 \r
 // For commercial use, separate licencing terms must be obtained.\r
 #include "ym2612.h"\r
 #include "sn76496.h"\r
 \r
-#if defined(_USE_MZ80)\r
-#include "../../cpu/mz80/mz80.h"\r
-#elif defined(_USE_DRZ80)\r
-#include "../../cpu/DrZ80/drz80.h"\r
-#elif defined(_USE_CZ80)\r
-#include "../../cpu/cz80/cz80.h"\r
-#endif\r
-\r
 #include "../PicoInt.h"\r
 #include "../cd/pcm.h"\r
 #include "mix.h"\r
@@ -36,11 +28,6 @@ int PsndLen_exc_add=0; // this is for non-integer sample counts per line, eg. 22
 int PsndLen_exc_cnt=0;\r
 short *PsndOut=NULL; // PCM data buffer\r
 \r
-// from ym2612.c\r
-extern int   *ym2612_dacen;\r
-extern INT32 *ym2612_dacout;\r
-void YM2612TimerHandler(int c,int cnt);\r
-\r
 // sn76496\r
 extern int *sn76496_regs;\r
 \r
@@ -306,9 +293,16 @@ static struct z80PortWrite mz80_io_write[]={
   {(UINT16) -1,(UINT16) -1,NULL}\r
 };\r
 \r
+int mz80_run(int cycles)\r
+{\r
+  int ticks_pre = mz80GetElapsedTicks(0);\r
+  mz80exec(cycles);\r
+  return mz80GetElapsedTicks(0) - ticks_pre;\r
+}\r
+\r
 #elif defined(_USE_DRZ80)\r
 \r
-static struct DrZ80 drZ80;\r
+struct DrZ80 drZ80;\r
 \r
 static unsigned int DrZ80_rebasePC(unsigned short a)\r
 {\r
@@ -379,7 +373,7 @@ PICO_INTERNAL void z80_init(void)
   Cz80_Init(&CZ80);\r
   Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM\r
   Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram - 0x2000); // mirror\r
-  Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read);\r
+  Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read); // unused (hacked in)\r
   Cz80_Set_WriteB(&CZ80, z80_write);\r
   Cz80_Set_INPort(&CZ80, z80_in);\r
   Cz80_Set_OUTPort(&CZ80, z80_out);\r
@@ -405,40 +399,6 @@ PICO_INTERNAL void z80_reset(void)
   Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled\r
 }\r
 \r
-PICO_INTERNAL void z80_resetCycles(void)\r
-{\r
-#if defined(_USE_MZ80)\r
-  mz80GetElapsedTicks(1);\r
-#endif\r
-}\r
-\r
-PICO_INTERNAL void z80_int(void)\r
-{\r
-#if defined(_USE_MZ80)\r
-  mz80int(0);\r
-#elif defined(_USE_DRZ80)\r
-  drZ80.z80irqvector = 0xFF; // default IRQ vector RST opcode\r
-  drZ80.Z80_IRQ = 1;\r
-#elif defined(_USE_CZ80)\r
-  Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE);\r
-#endif\r
-}\r
-\r
-// returns number of cycles actually executed\r
-PICO_INTERNAL int z80_run(int cycles)\r
-{\r
-#if defined(_USE_MZ80)\r
-  int ticks_pre = mz80GetElapsedTicks(0);\r
-  mz80exec(cycles);\r
-  return mz80GetElapsedTicks(0) - ticks_pre;\r
-#elif defined(_USE_DRZ80)\r
-  return cycles - DrZ80Run(&drZ80, cycles);\r
-#elif defined(_USE_CZ80)\r
-  return Cz80_Exec(&CZ80, cycles);\r
-#else\r
-  return cycles;\r
-#endif\r
-}\r
 \r
 PICO_INTERNAL void z80_pack(unsigned char *data)\r
 {\r
index f626260..8e081b4 100644 (file)
@@ -553,20 +553,21 @@ INLINE void set_timers( int v )
 }\r
 \r
 \r
-INLINE void FM_KEYON(FM_CH *CH , int s )\r
+INLINE void FM_KEYON(int c , int s )\r
 {\r
-       FM_SLOT *SLOT = &CH->SLOT[s];\r
+       FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];\r
        if( !SLOT->key )\r
        {\r
                SLOT->key = 1;\r
                SLOT->phase = 0;                /* restart Phase Generator */\r
                SLOT->state = EG_ATT;   /* phase -> Attack */\r
+               ym2612.slot_mask |= (1<<s) << (c*4);\r
        }\r
 }\r
 \r
-INLINE void FM_KEYOFF(FM_CH *CH , int s )\r
+INLINE void FM_KEYOFF(int c , int s )\r
 {\r
-       FM_SLOT *SLOT = &CH->SLOT[s];\r
+       FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];\r
        if( SLOT->key )\r
        {\r
                SLOT->key = 0;\r
@@ -844,6 +845,9 @@ typedef struct
        UINT32 pack;     // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16]\r
        UINT32 algo;     /* 50: algo[3], was_update */\r
        INT32  op1_out;\r
+#ifdef _MIPS_ARCH_ALLEGREX\r
+       UINT32 pad1[3+8];\r
+#endif\r
 } chan_rend_context;\r
 \r
 \r
@@ -905,16 +909,6 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
 \r
                switch( ct->CH->ALGO )\r
                {\r
-#if 0\r
-                       case 0: smp = upd_algo0(ct); break;\r
-                       case 1: smp = upd_algo1(ct); break;\r
-                       case 2: smp = upd_algo2(ct); break;\r
-                       case 3: smp = upd_algo3(ct); break;\r
-                       case 4: smp = upd_algo4(ct); break;\r
-                       case 5: smp = upd_algo5(ct); break;\r
-                       case 6: smp = upd_algo6(ct); break;\r
-                       case 7: smp = upd_algo7(ct); break;\r
-#else\r
                        case 0:\r
                        {\r
                                /* M1---C1---MEM---M2---C2---OUT */\r
@@ -1064,7 +1058,6 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
                                }\r
                                break;\r
                        }\r
-#endif\r
                }\r
                /* done calculating channel sample */\r
 \r
@@ -1092,55 +1085,54 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
 void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);\r
 #endif\r
 \r
+static chan_rend_context __attribute__((aligned(64))) crct;\r
 \r
-static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
+static int chan_render(int *buffer, int length, int c, UINT32 flags) // flags: stereo, ?, disabled, ?, pan_r, pan_l\r
 {\r
-       chan_rend_context ct;\r
-\r
-       ct.CH = CH;\r
-       ct.mem = CH->mem_value;         /* one sample delay memory */\r
-       ct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
-       ct.lfo_inc = ym2612.OPN.lfo_inc;\r
+       crct.CH = &ym2612.CH[c];\r
+       crct.mem = crct.CH->mem_value;          /* one sample delay memory */\r
+       crct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
+       crct.lfo_inc = ym2612.OPN.lfo_inc;\r
 \r
-       flags &= 0x37;\r
+       flags &= 0x35;\r
 \r
-       if (ct.lfo_inc) {\r
+       if (crct.lfo_inc) {\r
                flags |= 8;\r
                flags |= g_lfo_ampm << 16;\r
-               flags |= CH->AMmasks << 8;\r
-               if (CH->ams == 8) // no ams\r
-                        flags &= ~0xf00;\r
-               else flags |= (CH->ams&3)<<6;\r
+               flags |= crct.CH->AMmasks << 8;\r
+               if (crct.CH->ams == 8) // no ams\r
+                    flags &= ~0xf00;\r
+               else flags |= (crct.CH->ams&3)<<6;\r
        }\r
-       flags |= (CH->FB&0xf)<<12;                              /* feedback shift */\r
-       ct.pack = flags;\r
+       flags |= (crct.CH->FB&0xf)<<12;                         /* feedback shift */\r
+       crct.pack = flags;\r
 \r
-       ct.eg_cnt = ym2612.OPN.eg_cnt;                  /* envelope generator counter */\r
-       ct.eg_timer = ym2612.OPN.eg_timer;\r
-       ct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
+       crct.eg_cnt = ym2612.OPN.eg_cnt;                        /* envelope generator counter */\r
+       crct.eg_timer = ym2612.OPN.eg_timer;\r
+       crct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
 \r
        /* precalculate phase modulation incr */\r
-       ct.phase1 = CH->SLOT[SLOT1].phase;\r
-       ct.phase2 = CH->SLOT[SLOT2].phase;\r
-       ct.phase3 = CH->SLOT[SLOT3].phase;\r
-       ct.phase4 = CH->SLOT[SLOT4].phase;\r
+       crct.phase1 = crct.CH->SLOT[SLOT1].phase;\r
+       crct.phase2 = crct.CH->SLOT[SLOT2].phase;\r
+       crct.phase3 = crct.CH->SLOT[SLOT3].phase;\r
+       crct.phase4 = crct.CH->SLOT[SLOT4].phase;\r
 \r
        /* current output from EG circuit (without AM from LFO) */\r
-       ct.vol_out1 = CH->SLOT[SLOT1].tl + ((UINT32)CH->SLOT[SLOT1].volume);\r
-       ct.vol_out2 = CH->SLOT[SLOT2].tl + ((UINT32)CH->SLOT[SLOT2].volume);\r
-       ct.vol_out3 = CH->SLOT[SLOT3].tl + ((UINT32)CH->SLOT[SLOT3].volume);\r
-       ct.vol_out4 = CH->SLOT[SLOT4].tl + ((UINT32)CH->SLOT[SLOT4].volume);\r
+       crct.vol_out1 = crct.CH->SLOT[SLOT1].tl + ((UINT32)crct.CH->SLOT[SLOT1].volume);\r
+       crct.vol_out2 = crct.CH->SLOT[SLOT2].tl + ((UINT32)crct.CH->SLOT[SLOT2].volume);\r
+       crct.vol_out3 = crct.CH->SLOT[SLOT3].tl + ((UINT32)crct.CH->SLOT[SLOT3].volume);\r
+       crct.vol_out4 = crct.CH->SLOT[SLOT4].tl + ((UINT32)crct.CH->SLOT[SLOT4].volume);\r
 \r
-       ct.op1_out = CH->op1_out;\r
-       ct.algo = CH->ALGO & 7;\r
+       crct.op1_out = crct.CH->op1_out;\r
+       crct.algo = crct.CH->ALGO & 7;\r
 \r
-       if(CH->pms)\r
+       if(crct.CH->pms)\r
        {\r
                /* add support for 3 slot mode */\r
-               UINT32 block_fnum = CH->block_fnum;\r
+               UINT32 block_fnum = crct.CH->block_fnum;\r
 \r
                UINT32 fnum_lfo   = ((block_fnum & 0x7f0) >> 4) * 32 * 8;\r
-               INT32  lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + ((ct.pack>>16)&0xff) ];\r
+               INT32  lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + crct.CH->pms + ((crct.pack>>16)&0xff) ];\r
 \r
                if (lfo_fn_table_index_offset)  /* LFO phase modulation active */\r
                {\r
@@ -1158,45 +1150,51 @@ static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flag
                        /* phase increment counter */\r
                        fc = fn_table[fn]>>(7-blk);\r
 \r
-                       ct.incr1 = ((fc+CH->SLOT[SLOT1].DT[kc])*CH->SLOT[SLOT1].mul) >> 1;\r
-                       ct.incr2 = ((fc+CH->SLOT[SLOT2].DT[kc])*CH->SLOT[SLOT2].mul) >> 1;\r
-                       ct.incr3 = ((fc+CH->SLOT[SLOT3].DT[kc])*CH->SLOT[SLOT3].mul) >> 1;\r
-                       ct.incr4 = ((fc+CH->SLOT[SLOT4].DT[kc])*CH->SLOT[SLOT4].mul) >> 1;\r
+                       crct.incr1 = ((fc+crct.CH->SLOT[SLOT1].DT[kc])*crct.CH->SLOT[SLOT1].mul) >> 1;\r
+                       crct.incr2 = ((fc+crct.CH->SLOT[SLOT2].DT[kc])*crct.CH->SLOT[SLOT2].mul) >> 1;\r
+                       crct.incr3 = ((fc+crct.CH->SLOT[SLOT3].DT[kc])*crct.CH->SLOT[SLOT3].mul) >> 1;\r
+                       crct.incr4 = ((fc+crct.CH->SLOT[SLOT4].DT[kc])*crct.CH->SLOT[SLOT4].mul) >> 1;\r
                }\r
                else    /* LFO phase modulation  = zero */\r
                {\r
-                       ct.incr1 = CH->SLOT[SLOT1].Incr;\r
-                       ct.incr2 = CH->SLOT[SLOT2].Incr;\r
-                       ct.incr3 = CH->SLOT[SLOT3].Incr;\r
-                       ct.incr4 = CH->SLOT[SLOT4].Incr;\r
+                       crct.incr1 = crct.CH->SLOT[SLOT1].Incr;\r
+                       crct.incr2 = crct.CH->SLOT[SLOT2].Incr;\r
+                       crct.incr3 = crct.CH->SLOT[SLOT3].Incr;\r
+                       crct.incr4 = crct.CH->SLOT[SLOT4].Incr;\r
                }\r
        }\r
        else    /* no LFO phase modulation */\r
        {\r
-               ct.incr1 = CH->SLOT[SLOT1].Incr;\r
-               ct.incr2 = CH->SLOT[SLOT2].Incr;\r
-               ct.incr3 = CH->SLOT[SLOT3].Incr;\r
-               ct.incr4 = CH->SLOT[SLOT4].Incr;\r
+               crct.incr1 = crct.CH->SLOT[SLOT1].Incr;\r
+               crct.incr2 = crct.CH->SLOT[SLOT2].Incr;\r
+               crct.incr3 = crct.CH->SLOT[SLOT3].Incr;\r
+               crct.incr4 = crct.CH->SLOT[SLOT4].Incr;\r
        }\r
 \r
-       chan_render_loop(&ct, buffer, length);\r
+       chan_render_loop(&crct, buffer, length);\r
 \r
-       // write back persistent stuff:\r
-       if (flags & 2) { /* last channel */\r
-               ym2612.OPN.eg_cnt = ct.eg_cnt;\r
-               ym2612.OPN.eg_timer = ct.eg_timer;\r
-               g_lfo_ampm = ct.pack >> 16;\r
-               ym2612.OPN.lfo_cnt = ct.lfo_cnt;\r
+       crct.CH->op1_out = crct.op1_out;\r
+       crct.CH->mem_value = crct.mem;\r
+       if (crct.CH->SLOT[SLOT1].state | crct.CH->SLOT[SLOT2].state | crct.CH->SLOT[SLOT3].state | crct.CH->SLOT[SLOT4].state)\r
+       {\r
+               crct.CH->SLOT[SLOT1].phase = crct.phase1;\r
+               crct.CH->SLOT[SLOT2].phase = crct.phase2;\r
+               crct.CH->SLOT[SLOT3].phase = crct.phase3;\r
+               crct.CH->SLOT[SLOT4].phase = crct.phase4;\r
        }\r
+       else\r
+               ym2612.slot_mask &= ~(0xf << (c*4));\r
 \r
-       CH->op1_out = ct.op1_out;\r
-       CH->SLOT[SLOT1].phase = ct.phase1;\r
-       CH->SLOT[SLOT2].phase = ct.phase2;\r
-       CH->SLOT[SLOT3].phase = ct.phase3;\r
-       CH->SLOT[SLOT4].phase = ct.phase4;\r
-       CH->mem_value = ct.mem;\r
+       // if this the last call, write back persistent stuff:\r
+       if ((ym2612.slot_mask >> ((c+1)*4)) == 0)\r
+       {\r
+               ym2612.OPN.eg_cnt = crct.eg_cnt;\r
+               ym2612.OPN.eg_timer = crct.eg_timer;\r
+               g_lfo_ampm = crct.pack >> 16;\r
+               ym2612.OPN.lfo_cnt = crct.lfo_cnt;\r
+       }\r
 \r
-       return (ct.algo & 8) >> 3; // had output\r
+       return (crct.algo & 8) >> 3; // had output\r
 }\r
 \r
 /* update phase increment and envelope generator */\r
@@ -1274,7 +1272,7 @@ static void init_timetables(const UINT8 *dttable)
 }\r
 \r
 \r
-static void reset_channels(FM_CH *CH, int num)\r
+static void reset_channels(FM_CH *CH)\r
 {\r
        int c,s;\r
 \r
@@ -1284,7 +1282,7 @@ static void reset_channels(FM_CH *CH, int num)
        ym2612.OPN.ST.TB     = 0;\r
        ym2612.OPN.ST.TBC    = 0;\r
 \r
-       for( c = 0 ; c < num ; c++ )\r
+       for( c = 0 ; c < 6 ; c++ )\r
        {\r
                CH[c].fc = 0;\r
                for(s = 0 ; s < 4 ; s++ )\r
@@ -1293,6 +1291,7 @@ static void reset_channels(FM_CH *CH, int num)
                        CH[c].SLOT[s].volume = MAX_ATT_INDEX;\r
                }\r
        }\r
+       ym2612.slot_mask = 0;\r
 }\r
 \r
 /* initialize generic tables */\r
@@ -1401,6 +1400,7 @@ static void init_tables(void)
 \r
 \r
 /* CSM Key Controll */\r
+#if 0\r
 INLINE void CSMKeyControll(FM_CH *CH)\r
 {\r
        /* this is wrong, atm */\r
@@ -1411,6 +1411,7 @@ INLINE void CSMKeyControll(FM_CH *CH)
        FM_KEYON(CH,SLOT3);\r
        FM_KEYON(CH,SLOT4);\r
 }\r
+#endif\r
 \r
 \r
 /* prescaler set (and make time tables) */\r
@@ -1585,6 +1586,7 @@ static int OPNWriteReg(int r, int v)
 \r
 int   *ym2612_dacen;\r
 INT32 *ym2612_dacout;\r
+FM_ST *ym2612_st;\r
 \r
 \r
 /* Generate samples for YM2612 */\r
@@ -1596,6 +1598,24 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
        // if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash\r
        if (is_buf_empty) memset32(buffer, 0, length<<stereo);\r
 \r
+/*\r
+       {\r
+               int c, s;\r
+               ppp();\r
+               for (c = 0; c < 6; c++) {\r
+                       int slr = 0, slm;\r
+                       printf("%i: ", c);\r
+                       for (s = 0; s < 4; s++) {\r
+                               if (ym2612.CH[c].SLOT[s].state != EG_OFF) slr = 1;\r
+                               printf(" %i", ym2612.CH[c].SLOT[s].state != EG_OFF);\r
+                       }\r
+                       slm = (ym2612.slot_mask&(0xf<<(c*4))) ? 1 : 0;\r
+                       printf(" | %i", slm);\r
+                       printf(" | %i\n", ym2612.CH[c].SLOT[SLOT1].Incr==-1);\r
+                       if (slr != slm) exit(1);\r
+               }\r
+       }\r
+*/\r
        /* refresh PG and EG */\r
        refresh_fc_eg_chan( &ym2612.CH[0] );\r
        refresh_fc_eg_chan( &ym2612.CH[1] );\r
@@ -1618,13 +1638,13 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
        if (stereo) stereo = 1;\r
 \r
        /* mix to 32bit dest */\r
-       // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
-       active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0;\r
-       active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1;\r
-       active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030)   )) << 2;\r
-       active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3;\r
-       active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4;\r
-       active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5;\r
+       // flags: stereo, ?, disabled, ?, pan_r, pan_l\r
+       if (ym2612.slot_mask & 0x00000f) active_chs |= chan_render(buffer, length, 0, stereo|((pan&0x003)<<4)) << 0;\r
+       if (ym2612.slot_mask & 0x0000f0) active_chs |= chan_render(buffer, length, 1, stereo|((pan&0x00c)<<2)) << 1;\r
+       if (ym2612.slot_mask & 0x000f00) active_chs |= chan_render(buffer, length, 2, stereo|((pan&0x030)   )) << 2;\r
+       if (ym2612.slot_mask & 0x00f000) active_chs |= chan_render(buffer, length, 3, stereo|((pan&0x0c0)>>2)) << 3;\r
+       if (ym2612.slot_mask & 0x0f0000) active_chs |= chan_render(buffer, length, 4, stereo|((pan&0x300)>>4)) << 4;\r
+       if (ym2612.slot_mask & 0xf00000) active_chs |= chan_render(buffer, length, 5, stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)) << 5;\r
 \r
        return active_chs; // 1 if buffer updated\r
 }\r
@@ -1636,6 +1656,7 @@ void YM2612Init_(int clock, int rate)
        // notaz\r
        ym2612_dacen = &ym2612.dacen;\r
        ym2612_dacout = &ym2612.dacout;\r
+       ym2612_st = &ym2612.OPN.ST;\r
 \r
        memset(&ym2612, 0, sizeof(ym2612));\r
        init_tables();\r
@@ -1663,7 +1684,7 @@ void YM2612ResetChip_(void)
        ym2612.OPN.eg_cnt   = 0;\r
        ym2612.OPN.ST.status = 0;\r
 \r
-       reset_channels( &ym2612.CH[0] , 6 );\r
+       reset_channels( &ym2612.CH[0] );\r
        for(i = 0xb6 ; i >= 0xb4 ; i-- )\r
        {\r
                OPNWriteReg(i      ,0xc0);\r
@@ -1763,16 +1784,14 @@ int YM2612Write_(unsigned int a, unsigned int v)
                        case 0x28:      /* key on / off */\r
                                {\r
                                        UINT8 c;\r
-                                       FM_CH *CH;\r
 \r
                                        c = v & 0x03;\r
                                        if( c == 3 ) { ret=0; break; }\r
                                        if( v&0x04 ) c+=3;\r
-                                       CH = &ym2612.CH[c];\r
-                                       if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);\r
-                                       if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);\r
-                                       if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);\r
-                                       if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);\r
+                                       if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);\r
+                                       if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);\r
+                                       if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);\r
+                                       if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4);\r
                                        break;\r
                                }\r
                        case 0x2a:      /* DAC data (YM2612) */\r
@@ -1823,12 +1842,12 @@ int YM2612Write_(unsigned int a, unsigned int v)
        return ret;\r
 }\r
 \r
+#if 0\r
 UINT8 YM2612Read_(void)\r
 {\r
        return ym2612.OPN.ST.status;\r
 }\r
 \r
-\r
 int YM2612PicoTick_(int n)\r
 {\r
        int ret = 0;\r
@@ -1852,14 +1871,14 @@ int YM2612PicoTick_(int n)
 \r
        return ret;\r
 }\r
-\r
+#endif\r
 \r
 void YM2612PicoStateLoad_(void)\r
 {\r
 #ifndef EXTERNAL_YM2612\r
        int i, real_A1 = ym2612.addr_A1;\r
 \r
-       reset_channels( &ym2612.CH[0], 6 );\r
+       reset_channels( &ym2612.CH[0] );\r
 \r
        // feed all the registers and update internal state\r
        for(i = 0; i < 0x100; i++) {\r
@@ -1874,11 +1893,10 @@ void YM2612PicoStateLoad_(void)
 \r
        ym2612.addr_A1 = real_A1;\r
 #else\r
-       reset_channels( &ym2612.CH[0], 6 );\r
+       reset_channels( &ym2612.CH[0] );\r
 #endif\r
 }\r
 \r
-\r
 #ifndef EXTERNAL_YM2612\r
 void *YM2612GetRegs(void)\r
 {\r
index 20147ff..e87cbc1 100644 (file)
@@ -76,15 +76,16 @@ typedef struct
 {\r
        int             clock;          /* master clock  (Hz)   */\r
        int             rate;           /* sampling rate (Hz)   */\r
-       double  freqbase;       /* frequency base       */\r
-       UINT8   address;        /* address register     */\r
-       UINT8   status;         /* status flag          */\r
+       double  freqbase;       /* 08 frequency base       */\r
+       UINT8   address;        /* 10 address register     */\r
+       UINT8   status;         /* 11 status flag          */\r
        UINT8   mode;           /* mode  CSM / 3SLOT    */\r
        UINT8   fn_h;           /* freq latch           */\r
        int             TA;                     /* timer a              */\r
        int             TAC;            /* timer a maxval       */\r
        int             TAT;            /* timer a ticker       */\r
        UINT8   TB;                     /* timer b              */\r
+       UINT8   pad[3];\r
        int             TBC;            /* timer b maxval       */\r
        int             TBT;            /* timer b ticker       */\r
        /* local time tables */\r
@@ -135,9 +136,32 @@ typedef struct
        INT32           dacout;\r
 \r
        FM_OPN          OPN;                            /* OPN state            */\r
+\r
+       UINT32          slot_mask;                      /* active slot mask (performance hack) */\r
 } YM2612;\r
 #endif\r
 \r
+extern int   *ym2612_dacen;\r
+extern INT32 *ym2612_dacout;\r
+extern FM_ST *ym2612_st;\r
+\r
+\r
+#define YM2612Read() ym2612_st->status\r
+\r
+#define YM2612PicoTick(n) \\r
+{ \\r
+       /* timer A */ \\r
+       if(ym2612_st->mode & 0x01 && (ym2612_st->TAT+=64*n) >= ym2612_st->TAC) { \\r
+               ym2612_st->TAT -= ym2612_st->TAC; \\r
+               if(ym2612_st->mode & 0x04) ym2612_st->status |= 1; \\r
+       } \\r
+ \\r
+       /* timer B */ \\r
+       if(ym2612_st->mode & 0x02 && (ym2612_st->TBT+=64*n) >= ym2612_st->TBC) { \\r
+               ym2612_st->TBT -= ym2612_st->TBC; \\r
+               if(ym2612_st->mode & 0x08) ym2612_st->status |= 2; \\r
+       } \\r
+}\r
 \r
 \r
 void YM2612Init_(int baseclock, int rate);\r
@@ -157,8 +181,6 @@ void *YM2612GetRegs(void);
 #define YM2612ResetChip     YM2612ResetChip_\r
 #define YM2612UpdateOne     YM2612UpdateOne_\r
 #define YM2612Write         YM2612Write_\r
-#define YM2612Read          YM2612Read_\r
-#define YM2612PicoTick      YM2612PicoTick_\r
 #define YM2612PicoStateLoad YM2612PicoStateLoad_\r
 #else\r
 /* GP2X specific */\r
@@ -177,10 +199,6 @@ extern int PicoOpt;
                                YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);\r
 #define YM2612Write(a,v) \\r
        (PicoOpt&0x200) ?  YM2612Write_940(a, v) : YM2612Write_(a, v)\r
-#define YM2612Read() \\r
-       (PicoOpt&0x200) ?  YM2612Read_940()      : YM2612Read_()\r
-#define YM2612PicoTick(n) \\r
-       (PicoOpt&0x200) ?  YM2612PicoTick_940(n) : YM2612PicoTick_(n)\r
 #define YM2612PicoStateLoad() { \\r
        if (PicoOpt&0x200) YM2612PicoStateLoad_940(); \\r
        else               YM2612PicoStateLoad_(); \\r
index 5a4801a..ee14013 100644 (file)
 .endif\r
 \r
 .if DRZ80_FOR_PICODRIVE\r
-.include "port_config.s"\r
-      .extern YM2612Read_\r
-.if EXTERNAL_YM2612\r
-      .extern YM2612Read_940\r
-.endif\r
       .extern PicoRead8\r
       .extern Pico\r
       .extern z80_write\r
+      .extern ym2612_st\r
 .endif\r
 \r
 DrZ80Ver: .long 0x0001\r
@@ -111,37 +107,18 @@ DrZ80Ver: .long 0x0001
 .if DRZ80_FOR_PICODRIVE\r
 \r
 .macro YM2612Read_and_ret8\r
-    stmfd sp!,{r3,r12,lr}\r
-.if EXTERNAL_YM2612\r
-    ldr r1,=PicoOpt\r
-    ldr r1,[r1]\r
-    tst r1,#0x200\r
-    ldrne r2, =YM2612Read_940\r
-    ldreq r2, =YM2612Read_\r
-    mov lr,pc\r
-    bx r2\r
-.else\r
-    bl YM2612Read_\r
-.endif\r
-    ldmfd sp!,{r3,r12,pc}\r
+    ldr r0, =ym2612_st\r
+    ldr r0, [r0]\r
+    ldrb r0, [r0, #0x11]   ;@ ym2612_st->status\r
+    bx lr\r
 .endm\r
 \r
 .macro YM2612Read_and_ret16\r
-    stmfd sp!,{r3,r12,lr}\r
-.if EXTERNAL_YM2612\r
-    ldr r0,=PicoOpt\r
-    ldr r0,[r0]\r
-    tst r0,#0x200\r
-    ldrne r2, =YM2612Read_940\r
-    ldreq r2, =YM2612Read_\r
-    mov lr,pc\r
-    bx r2\r
+    ldr r0, =ym2612_st\r
+    ldr r0, [r0]\r
+    ldrb r0, [r0, #0x11]   ;@ ym2612_st->status\r
     orr r0,r0,r0,lsl #8\r
-.else\r
-    bl YM2612Read_\r
-    orr r0,r0,r0,lsl #8\r
-.endif\r
-    ldmfd sp!,{r3,r12,pc}\r
+    bx lr\r
 .endm\r
 \r
 pico_z80_read8: @ addr\r
@@ -214,13 +191,13 @@ pico_z80_read16: @ addr
     add r0,r4,#1\r
     bl PicoRead8\r
     orr r0,r5,r0,lsl #8\r
-       ldmfd sp!,{r3-r5,r12,pc}\r
+    ldmfd sp!,{r3-r5,r12,pc}\r
 1:\r
     mov r1,r0,lsr #13\r
     cmp r1,#2              @ YM2612 (0x4000-0x5fff)\r
     bne 0f\r
     and r0,r0,#3\r
-       YM2612Read_and_ret16\r
+    YM2612Read_and_ret16\r
 0:\r
     cmp r0,#0x4000\r
     movge r0,#0xff\r
index f2ab003..461b46a 100644 (file)
 #include <string.h>\r
 #include "cz80.h"\r
 \r
+#if PICODRIVE_HACKS\r
+#include <Pico/PicoInt.h>\r
+#endif\r
+\r
 #ifndef ALIGN_DATA\r
 #define ALIGN_DATA      __attribute__((aligned(4)))\r
 #endif\r
@@ -203,6 +207,13 @@ void Cz80_Reset(cz80_struc *CPU)
        Cz80_Set_Reg(CPU, CZ80_PC, 0);\r
 }\r
 \r
+/* */\r
+#if PICODRIVE_HACKS\r
+static inline unsigned char picodrive_read(unsigned short a)\r
+{\r
+       return (a < 0x4000) ? Pico.zram[a&0x1fff] : z80_read(a);\r
+}\r
+#endif\r
 \r
 /*--------------------------------------------------------\r
        CPU\8eÀ\8ds\r
index a5da31d..e097460 100644 (file)
@@ -52,6 +52,7 @@ extern "C" {
 #define CZ80_FETCH_SFT                 (16 - CZ80_FETCH_BITS)\r
 #define CZ80_FETCH_BANK                        (1 << CZ80_FETCH_BITS)\r
 \r
+#define PICODRIVE_HACKS                1\r
 #define CZ80_LITTLE_ENDIAN             1\r
 #define CZ80_USE_JUMPTABLE             1\r
 #define CZ80_BIG_FLAGS_ARRAY   1\r
index 91b49ef..7118dcc 100644 (file)
 //#ifndef BUILD_CPS1PSP\r
 //#define READ_MEM8(A)         memory_region_cpu2[(A)]\r
 //#else\r
+#if PICODRIVE_HACKS\r
+#define READ_MEM8(A)           picodrive_read(A)\r
+#else\r
 #define READ_MEM8(A)           CPU->Read_Byte(A)\r
+#endif\r
 //#endif\r
 #if CZ80_LITTLE_ENDIAN\r
 #define READ_MEM16(A)          (READ_MEM8(A) | (READ_MEM8((A) + 1) << 8))\r
 #define READ_MEM16(A)          ((READ_MEM8(A) << 8) | READ_MEM8((A) + 1))\r
 #endif\r
 \r
+#if PICODRIVE_HACKS\r
+#define WRITE_MEM8(A, D) { \\r
+       unsigned short a = A; \\r
+       unsigned char d = D; \\r
+       if (a < 0x4000) Pico.zram[a&0x1fff] = d; \\r
+       else z80_write(a, d); \\r
+}\r
+#else\r
 #define WRITE_MEM8(A, D)       CPU->Write_Byte(A, D);\r
+#endif\r
 #if CZ80_LITTLE_ENDIAN\r
 #define WRITE_MEM16(A, D)      { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }\r
 #else\r
index 6b147b2..e8753e4 100644 (file)
@@ -16,8 +16,8 @@
 \r
 // Options //\r
 #define FAMEC_ROLL_INLINE\r
-#define FAMEC_EMULATE_TRACE\r
-#define FAMEC_CHECK_BRANCHES\r
+//#define FAMEC_EMULATE_TRACE\r
+//#define FAMEC_CHECK_BRANCHES\r
 #define FAMEC_EXTRA_INLINE\r
 // #define FAMEC_DEBUG\r
 //#define FAMEC_NO_GOTOS\r
@@ -280,11 +280,18 @@ typedef signed int        s32;
        ((u32)PC - BasePC)\r
 \r
 \r
+#ifdef FAMEC_CHECK_BRANCHES\r
+#define FORCE_ALIGNMENT(pc)\r
+#else\r
+#define FORCE_ALIGNMENT(pc) pc&=~1;\r
+#endif\r
+\r
 #ifndef FAMEC_32BIT_PC\r
 \r
 #define SET_PC(A)               \\r
 { \\r
     u32 pc = A; \\r
+    FORCE_ALIGNMENT(pc); \\r
     BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK];    \\r
     PC = (u16*)((pc & M68K_ADR_MASK) + BasePC);        \\r
 }\r
@@ -294,6 +301,7 @@ typedef signed int  s32;
 #define SET_PC(A)               \\r
 { \\r
     u32 pc = A; \\r
+    FORCE_ALIGNMENT(pc); \\r
     BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK];    \\r
     BasePC -= pc & 0xFF000000;    \\r
     PC = (u16*)(pc + BasePC); \\r
@@ -734,7 +742,9 @@ static FAMEC_EXTRA_INLINE u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR)
 #ifndef FAMEC_32BIT_PC\r
        newPC&=M68K_ADR_MASK\r
 #endif\r
+#ifdef FAMEC_CHECK_BRANCHES\r
        newPC&=~1; // don't crash on games with bad vector tables\r
+#endif\r
 \r
        // SET_PC(newPC)\r
 \r
@@ -948,6 +958,7 @@ famec_End:
 #ifdef PICODRIVE_HACK\r
 dualcore_mode:\r
 \r
+       while (1)\r
        {\r
                extern int SekCycleAim, SekCycleCnt, SekCycleAimS68k, SekCycleCntS68k;\r
                #define PS_STEP_M68K ((488<<16)/20) // ~24\r
@@ -989,7 +1000,6 @@ dualcore_mode:
                        }\r
                        cycles = m68kcontext.io_cycle_counter = 0;\r
                }\r
-               goto dualcore_mode;\r
        }\r
 #endif\r
 \r
index a927913..917ed29 100644 (file)
@@ -51,22 +51,12 @@ static FILE *loaded_mp3 = 0;
 }\r
 \r
 /* these will be managed locally on our side */\r
-extern int   *ym2612_dacen;\r
-extern INT32 *ym2612_dacout;\r
 static UINT8 *REGS = 0;                /* we will also keep local copy of regs for savestates and such */\r
 static INT32 *addr_A1;         /* address line A1      */\r
 \r
 static int   dacen;\r
 static INT32 dacout;\r
 static UINT8 ST_address;       /* address register     */\r
-static UINT8 ST_status;                /* status flag          */\r
-static UINT8 ST_mode;          /* mode  CSM / 3SLOT    */\r
-static int   ST_TA;                    /* timer a              */\r
-static int   ST_TAC;           /* timer a maxval       */\r
-static int   ST_TAT;           /* timer a ticker       */\r
-static UINT8 ST_TB;                    /* timer b              */\r
-static int   ST_TBC;           /* timer b maxval       */\r
-static int   ST_TBT;           /* timer b ticker       */\r
 \r
 static int   writebuff_ptr = 0;\r
 \r
@@ -84,16 +74,16 @@ static int set_timers( int v )
        /* b2 = timer enable a */\r
        /* b1 = load b */\r
        /* b0 = load a */\r
-       change = (ST_mode ^ v) & 0xc0;\r
-       ST_mode = v;\r
+       change = (ym2612_st->mode ^ v) & 0xc0;\r
+       ym2612_st->mode = v;\r
 \r
        /* reset Timer b flag */\r
        if( v & 0x20 )\r
-               ST_status &= ~2;\r
+               ym2612_st->status &= ~2;\r
 \r
        /* reset Timer a flag */\r
        if( v & 0x10 )\r
-               ST_status &= ~1;\r
+               ym2612_st->status &= ~1;\r
 \r
        return change;\r
 }\r
@@ -139,30 +129,30 @@ int YM2612Write_940(unsigned int a, unsigned int v)
                        switch( addr )\r
                        {\r
                        case 0x24: { // timer A High 8\r
-                                       int TAnew = (ST_TA & 0x03)|(((int)v)<<2);\r
-                                       if(ST_TA != TAnew) {\r
+                                       int TAnew = (ym2612_st->TA & 0x03)|(((int)v)<<2);\r
+                                       if (ym2612_st->TA != TAnew) {\r
                                                // we should reset ticker only if new value is written. Outrun requires this.\r
-                                               ST_TA = TAnew;\r
-                                               ST_TAC = (1024-TAnew)*18;\r
-                                               ST_TAT = 0;\r
+                                               ym2612_st->TA = TAnew;\r
+                                               ym2612_st->TAC = (1024-TAnew)*18;\r
+                                               ym2612_st->TAT = 0;\r
                                        }\r
                                        return 0;\r
                                }\r
                        case 0x25: { // timer A Low 2\r
-                                       int TAnew = (ST_TA & 0x3fc)|(v&3);\r
-                                       if(ST_TA != TAnew) {\r
-                                               ST_TA = TAnew;\r
-                                               ST_TAC = (1024-TAnew)*18;\r
-                                               ST_TAT = 0;\r
+                                       int TAnew = (ym2612_st->TA & 0x3fc)|(v&3);\r
+                                       if (ym2612_st->TA != TAnew) {\r
+                                               ym2612_st->TA = TAnew;\r
+                                               ym2612_st->TAC = (1024-TAnew)*18;\r
+                                               ym2612_st->TAT = 0;\r
                                        }\r
                                        return 0;\r
                                }\r
                        case 0x26: // timer B\r
-                               if(ST_TB != v) {\r
-                                       ST_TB = v;\r
-                                       ST_TBC  = (256-v)<<4;\r
-                                       ST_TBC *= 18;\r
-                                       ST_TBT  = 0;\r
+                               if (ym2612_st->TB != v) {\r
+                                       ym2612_st->TB = v;\r
+                                       ym2612_st->TBC  = (256-v)<<4;\r
+                                       ym2612_st->TBC *= 18;\r
+                                       ym2612_st->TBT  = 0;\r
                                }\r
                                return 0;\r
                        case 0x27:      /* mode, timer control */\r
@@ -229,38 +219,6 @@ int YM2612Write_940(unsigned int a, unsigned int v)
        return 0; // cause the engine to do updates once per frame only\r
 }\r
 \r
-UINT8 YM2612Read_940(void)\r
-{\r
-       return ST_status;\r
-}\r
-\r
-\r
-int YM2612PicoTick_940(int n)\r
-{\r
-       //int ret = 0;\r
-\r
-       // timer A\r
-       if(ST_mode & 0x01 && (ST_TAT+=64*n) >= ST_TAC) {\r
-               ST_TAT -= ST_TAC;\r
-               if(ST_mode & 0x04) ST_status |= 1;\r
-               // CSM mode total level latch and auto key on\r
-/*             FIXME\r
-               if(ST_mode & 0x80) {\r
-                       CSMKeyControll( &(ym2612_940->CH[2]) ); // Vectorman2, etc.\r
-                       ret = 1;\r
-               }\r
-*/\r
-       }\r
-\r
-       // timer B\r
-       if(ST_mode & 0x02 && (ST_TBT+=64*n) >= ST_TBC) {\r
-               ST_TBT -= ST_TBC;\r
-               if(ST_mode & 0x08) ST_status |= 2;\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
 \r
 #define CHECK_BUSY(job) \\r
        (gp2x_memregs[0x3b46>>1] & (1<<(job-1)))\r
@@ -339,12 +297,14 @@ void YM2612PicoStateLoad_940(void)
 static void internal_reset(void)\r
 {\r
        writebuff_ptr = 0;\r
-       ST_mode   = 0;\r
-       ST_status = 0;  /* normal mode */\r
-       ST_TA     = 0;\r
-       ST_TAC    = 0;\r
-       ST_TB     = 0;\r
-       ST_TBC    = 0;\r
+       ym2612_st->mode   = 0;\r
+       ym2612_st->status = 0;  /* normal mode */\r
+       ym2612_st->TA     = 0;\r
+       ym2612_st->TAC    = 0;\r
+       ym2612_st->TAT    = 0;\r
+       ym2612_st->TB     = 0;\r
+       ym2612_st->TBC    = 0;\r
+       ym2612_st->TBT    = 0;\r
        dacen     = 0;\r
        dacout    = 0;\r
        ST_address= 0;\r
index dcd4531..eeb37c7 100644 (file)
@@ -138,15 +138,10 @@ endif
 all: PicoDrive.gpe\r
 \r
 PicoDrive.gpe : $(OBJS) ../common/helix/helix_mp3.a\r
-       @echo $@\r
-       @$(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map\r
+       @echo ">>>" $@\r
+       $(GCC) -o $@ $(COPT) $^ -lm -lpng -Wl,-Map=PicoDrive.map\r
 ifeq ($(DEBUG),)\r
-       @$(STRIP) $@\r
-endif\r
-#      @$(GCC) $(COPT) $(OBJS) -lm -o PicoDrive_.gpe\r
-#      @gpecomp PicoDrive_.gpe $@\r
-ifeq "$(up)" "1"\r
-       @cmd //C copy $@ \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
+       $(STRIP) $@\r
 endif\r
 \r
 up: PicoDrive.gpe\r
@@ -155,45 +150,40 @@ up: PicoDrive.gpe
 #      @cmd //C copy PicoDrive.gpe \\\\10.0.1.2\\gp2x\\mnt\\sd\\games\\PicoDrive\\\r
 \r
 \r
-testrefr.gpe : test.o gp2x.o\r
-       @echo $@\r
-       @$(GCC) $(COPT) $^ -o $@\r
-       @$(STRIP) $@\r
-\r
 .c.o:\r
-       @echo $<\r
-       @$(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
+       @echo ">>>" $<\r
+       $(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
 .s.o:\r
-       @echo $<\r
-       @$(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
+       @echo ">>>" $<\r
+       $(GCC) $(COPT) $(DEFINC) -c $< -o $@\r
 \r
 ../../Pico/draw_asm.o : ../../Pico/Draw.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/draw2_asm.o : ../../Pico/Draw2.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/memory_asm.o : ../../Pico/Memory.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/sound/ym2612_asm.o : ../../Pico/sound/ym2612.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/sound/mix_asm.o : ../../Pico/sound/mix.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/misc_asm.o : ../../Pico/Misc.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/cd/pico_asm.o : ../../Pico/cd/Pico.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/cd/memory_asm.o : ../../Pico/cd/Memory.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 ../../Pico/cd/misc_asm.o : ../../Pico/cd/Misc.s\r
-       @echo $<\r
-       @$(AS) $(ASOPT) $< -o $@\r
+       @echo ">>>" $<\r
+       $(AS) $(ASOPT) $< -o $@\r
 \r
 # build Cyclone\r
 ../../cpu/Cyclone/proj/Cyclone.s :\r
index 93ee956..f2fb563 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.34"\r
+#define VERSION "1.35"\r
 \r
index 403cca2..ee63458 100644 (file)
@@ -40,19 +40,6 @@ int YM2612Write_940(unsigned int a, unsigned int v)
        return 0; // cause the engine to do updates once per frame only
 }
 
-UINT8 YM2612Read_940(void)
-{
-       return YM2612Read_();
-}
-
-
-int YM2612PicoTick_940(int n)
-{
-       YM2612PicoTick_(n);
-
-       return 0;
-}
-
 
 void YM2612PicoStateLoad_940(void)
 {
index 9dd365f..0af279c 100644 (file)
@@ -13,8 +13,8 @@ STRIP = strip
 AS = gcc
 
 ifeq "$(profile)" "1"
-COPT_COMMON = -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -fprofile-generate # -static
-COPT = $(COPT_COMMON) # -mtune=arm920t
+COPT_COMMON = -s -O3 -ftracer -fstrength-reduce -Wall -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -fprofile-generate
+COPT = $(COPT_COMMON)
 else
 COPT = -ggdb -Wall -fno-strict-aliasing # -pg -O3  -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -ffast-math
 COPT_COMMON = $(COPT)
index 6acc3eb..c3b04cd 100644 (file)
@@ -6,23 +6,19 @@ PSPSDK = $(shell psp-config --pspsdk-path)
 #use_musashi = 1\r
 #use_mz80 = 1\r
 amalgamate = 0\r
-#profile = 1\r
-#up = 1\r
 \r
 \r
 CFLAGS += -I../.. -I. -DNO_SYNC -DLPRINTF_STDIO\r
 CFLAGS += -Wall -Winline -G0\r
+CFLAGS += -DLPRINTF_STDIO\r
+#CFLAGS += -fprofile-generate\r
+#CFLAGS += -fprofile-use\r
+#CFLAGS += -pg\r
 ifeq ($(DEBUG),)\r
 CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math\r
 else\r
 CFLAGS += -ggdb\r
 endif\r
-ifeq "$(profile)" "1"\r
-CFLAGS += -fprofile-generate\r
-endif\r
-ifeq "$(profile)" "2"\r
-CFLAGS += -fprofile-use\r
-endif\r
 \r
 \r
 # frontend\r
@@ -37,7 +33,7 @@ OBJS += ../../PicoAll.o
 else\r
 OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.o \\r
                ../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o \\r
-               ../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o\r
+               ../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o ../../Pico/Misc_amips.o\r
 # Pico - CD\r
 OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pico/cd/LC89510.o \\r
                ../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/gfx_cd.o \\r
@@ -77,8 +73,10 @@ OBJS += data/bg32.o data/bg40.o
 \r
 \r
 LIBS += -lpng -lm -lpspgu -lpsppower -lpspaudio -lpsprtc -lpspaudiocodec\r
+#LIBS += -lpspprof\r
 LDFLAGS += -Wl,-Map=PicoDrive.map\r
 \r
+\r
 # target\r
 TARGET = PicoDrive\r
 EXTRA_TARGETS = EBOOT.PBP\r
@@ -114,7 +112,11 @@ AS := psp-as
 \r
 ../../Pico/Draw.o : ../../Pico/Draw.c\r
        @echo ">>>" $<\r
-       $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_DRAW_C_MIPS\r
+       $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_DRAW_C_AMIPS\r
+\r
+../../Pico/Misc.o : ../../Pico/Misc.c\r
+       @echo ">>>" $<\r
+       $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_MISC_C_AMIPS\r
 \r
 readme.txt: ../../tools/textfilter ../base_readme.txt\r
        ../../tools/textfilter ../base_readme.txt $@ PSP\r
@@ -152,6 +154,5 @@ endif
 \r
 # ?\r
 rel: EBOOT.PBP readme.txt\r
-       zip -9 -j ../../PicoDrive_$(VER).zip $^\r
-#      zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt\r
+       zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt\r
 \r
index b7d6bae..6ce910d 100644 (file)
@@ -11,6 +11,7 @@
 #include "psp.h"
 #include "menu.h"
 #include "emu.h"
+#include "mp3.h"
 #include "../common/emu.h"
 #include "../common/lprintf.h"
 #include "../../Pico/PicoInt.h"
@@ -57,7 +58,7 @@ static void osd_text(int x, const char *text, int is_active, int clear_all)
        for (h = 0; h < 8; h++) {
                p = (int *) (screen+x+512*(264+h));
                p = (int *) ((int)p & ~3); // align
-               memset32(p, 0, len);
+               memset32_uncached(p, 0, len);
        }
        if (is_active) { tmp = psp_screen; psp_screen = screen; } // nasty pointer tricks
        emu_textOut16(x, 264, text);
@@ -126,8 +127,8 @@ void emu_setDefaultConfig(void)
 {
        memset(&currentConfig, 0, sizeof(currentConfig));
        currentConfig.lastRomFile[0] = 0;
-       currentConfig.EmuOpt  = 0x1f | 0x680; // | confirm_save, cd_leds, 16bit rend
-       currentConfig.PicoOpt = 0x0f | 0xc00; // | cd_pcm, cd_cdda
+       currentConfig.EmuOpt  = 0x1d | 0x680;  // | confirm_save, cd_leds, acc rend
+       currentConfig.PicoOpt = 0x0f | 0x1c00; // | gfx_cd, cd_pcm, cd_cdda
        currentConfig.PsndRate = 22050;
        currentConfig.PicoRegion = 0; // auto
        currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP
@@ -172,7 +173,7 @@ static int fbimg_offs = 0;
 
 static void set_scaling_params(void)
 {
-       int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs;
+       int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs, border_hack = 0;
        g_vertices[0].x = g_vertices[0].y =
        g_vertices[0].z = g_vertices[1].z = 0;
 
@@ -185,9 +186,13 @@ static void set_scaling_params(void)
                src_width = 256;
        }
 
+       if (fbimg_width  & 1) fbimg_width++;  // make even
+       if (fbimg_height & 1) fbimg_height++;
+
        if (fbimg_width >= 480) {
                g_vertices[0].u = (fbimg_width-480)/2;
-               g_vertices[1].u = src_width - (fbimg_width-480)/2;
+               g_vertices[1].u = src_width - (fbimg_width-480)/2 - 1;
+               if (fbimg_width == 480) border_hack = 1;
                fbimg_width = 480;
                fbimg_xoffs = 0;
        } else {
@@ -211,6 +216,12 @@ static void set_scaling_params(void)
        g_vertices[1].y = fbimg_height;
        if (fbimg_xoffs < 0) fbimg_xoffs = 0;
        if (fbimg_yoffs < 0) fbimg_yoffs = 0;
+       if (border_hack) {
+               g_vertices[0].u++;
+               g_vertices[0].x++;
+               g_vertices[1].u--;
+               g_vertices[1].x--;
+       }
        fbimg_offs = (fbimg_yoffs*512 + fbimg_xoffs) * 2; // dst is always 16bit
 
        /*
@@ -371,7 +382,7 @@ static void cd_leds(void)
        *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r;
 }
 
-
+#if 0
 static void dbg_text(void)
 {
        int *p, h, len;
@@ -382,11 +393,11 @@ static void dbg_text(void)
        for (h = 0; h < 8; h++) {
                p = (int *) ((unsigned short *) psp_screen+2+512*(256+h));
                p = (int *) ((int)p & ~3); // align
-               memset32(p, 0, len);
+               memset32_uncached(p, 0, len);
        }
        emu_textOut16(2, 256, text);
 }
-
+#endif
 
 /* called after rendering is done, but frame emulation is not finished */
 void blit1(void)
@@ -415,7 +426,7 @@ static void blit2(const char *fps, const char *notice, int lagging_behind)
                if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
        }
 
-       dbg_text();
+       //dbg_text();
 
        if ((emu_opt & 0x400) && (PicoMCD & 1))
                cd_leds();
@@ -431,15 +442,15 @@ static void blit2(const char *fps, const char *notice, int lagging_behind)
 static void clearArea(int full)
 {
        if (full) {
-               memset32(psp_screen, 0, 512*272*2/4);
+               memset32_uncached(psp_screen, 0, 512*272*2/4);
                psp_video_flip(0);
-               memset32(psp_screen, 0, 512*272*2/4);
+               memset32_uncached(psp_screen, 0, 512*272*2/4);
                memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*240/4);
                memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4);
        } else {
                void *fb = psp_video_get_active_fb();
-               memset32((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
-               memset32((int *)((char *)fb         + 512*264*2), 0, 512*8*2/4);
+               memset32_uncached((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
+               memset32_uncached((int *)((char *)fb         + 512*264*2), 0, 512*8*2/4);
        }
 }
 
@@ -659,7 +670,7 @@ void emu_forcedFrame(void)
        vidResetMode();
        memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
        memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
-       memset32((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
+       memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
 
        PicoDrawSetColorFormat(-1);
        PicoScan = EmuScanSlow;
@@ -1036,7 +1047,7 @@ void emu_Loop(void)
        }
 
        // clear fps counters and stuff
-       memset32((int *)psp_video_get_active_fb() + 512*264*2/4, 0, 512*8*2/4);
+       memset32_uncached((int *)psp_video_get_active_fb() + 512*264*2/4, 0, 512*8*2/4);
 }
 
 
index d122a20..affd540 100644 (file)
@@ -28,4 +28,6 @@ void emu_forcedFrame(void);
 
 void emu_msg_cb(const char *msg);
 
+// actually comes from Pico/Misc_amips.s
+void memset32_uncached(int *dest, int c, int count);
 
index 86628ca..52381eb 100644 (file)
@@ -154,7 +154,7 @@ void menu_romload_prepare(const char *rom_name)
 
        psp_video_switch_to_single();
        if (rom_data) menu_draw_begin();
-       else memset32(psp_screen, 0, 512*272*2/4);
+       else memset32_uncached(psp_screen, 0, 512*272*2/4);
 
        smalltext_out16(1, 1, "Loading", 0xffff);
        smalltext_out16_lim(1, 10, p, 0xffff, 80);
@@ -453,8 +453,10 @@ static void draw_debug(void)
 
 static void debug_menu_loop(void)
 {
+       int ret = 0;
        draw_debug();
-       wait_for_input(BTN_X|BTN_CIRCLE, 0);
+       while (!(ret & (BTN_X|BTN_CIRCLE)))
+               ret = wait_for_input(BTN_X|BTN_CIRCLE, 0);
 }
 
 // ------------ patch/gg menu ------------
@@ -1059,7 +1061,7 @@ static void menu_opt3_preview(int is_32col)
                        lprintf("uncompress returned %i\n", ret);
        }
 
-       memset32(psp_screen, 0, 512*272*2/4);
+       memset32_uncached(psp_screen, 0, 512*272*2/4);
        emu_forcedFrame();
        menu_prepare_bg(1, 0);
 
@@ -1119,6 +1121,7 @@ static void dispmenu_loop_options(void)
                        if (setting != NULL) {
                                while ((inp = psp_pad_read(0)) & (BTN_LEFT|BTN_RIGHT)) {
                                        *setting += (inp & BTN_LEFT) ? -0.01 : 0.01;
+                                       if (*setting <= 0) *setting = 0.01;
                                        menu_opt3_preview(is_32col);
                                        draw_dispmenu_options(menu_sel); // will wait vsync
                                }
@@ -1735,12 +1738,12 @@ static void menu_prepare_bg(int use_game_bg, int use_fg)
                int i;
                for (i = 272; i > 0; i--, dst += 480, src += 512)
                        menu_darken_bg(dst, src, 480, 1);
-               //memset32((int *)(bg_buffer + 480*264), 0, 480*8*2/4);
+               //memset32_uncached((int *)(bg_buffer + 480*264), 0, 480*8*2/4);
        }
        else
        {
                // should really only happen once, on startup..
-               memset32((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4);
+               memset32_uncached((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4);
                readpng(bg_buffer, "skin/background.png", READPNG_BG);
        }
        sceKernelDcacheWritebackAll();
@@ -1814,7 +1817,7 @@ int menu_loop_tray(void)
        for (;;)
        {
                draw_menu_tray(menu_sel);
-               inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_X, 0);
+               inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_CIRCLE, 0);
                if(inp & BTN_UP  )  { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
                if(inp & BTN_DOWN)  { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
                if(inp & BTN_CIRCLE)  {
index f3abc2f..5a87877 100644 (file)
@@ -181,8 +181,6 @@ int mp3_init(void)
                goto fail2;
        }
 
-       lprintf("thread_busy_sem: %08x, thread_job_sem: %08x\n", thread_busy_sem, thread_job_sem);
-
        thread_exit = 0;
        thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, 0); /* use slightly higher prio then main */
        if (thid < 0) {
@@ -273,7 +271,7 @@ static int decode_thread(SceSize args, void *argp)
 
 int mp3_get_bitrate(FILE *f, int size)
 {
-       int ret = -1, sample_rate, bitrate;
+       int ret, retval = -1, sample_rate, bitrate;
        // filenames are stored instead handles in PSP, due to stupid max open file limit
        char *fname = (char *)f;
 
@@ -307,14 +305,14 @@ int mp3_get_bitrate(FILE *f, int size)
        }
 
        /* looking good.. */
-       ret = bitrate;
+       retval = bitrate;
 end:
        if (mp3_handle >= 0) sceIoClose(mp3_handle);
        mp3_handle = -1;
        mp3_fname = NULL;
        psp_sem_unlock(thread_busy_sem);
-       if (ret < 0) mp3_last_error = -1; // remember we had a problem..
-       return ret;
+       if (retval < 0) mp3_last_error = -1; // remember we had a problem..
+       return retval;
 }
 
 
diff --git a/platform/psp/mp3.h b/platform/psp/mp3.h
new file mode 100644 (file)
index 0000000..d95d04b
--- /dev/null
@@ -0,0 +1,8 @@
+
+// additional stuff for PSP mp3 decoder implementation
+extern int mp3_last_error;
+
+int  mp3_init(void);
+void mp3_deinit(void);
+
+
index 05af63d..c8d73ac 100644 (file)
@@ -10,6 +10,7 @@
 #include <pspgu.h>
 
 #include "psp.h"
+#include "emu.h"
 #include "../common/lprintf.h"
 
 PSP_MODULE_INFO("PicoDrive", 0, 1, 34);
@@ -28,6 +29,19 @@ static int exit_callback(int arg1, int arg2, void *common)
        return 0;
 }
 
+/* Power Callback */
+static int power_callback(int unknown, int pwrflags, void *common)
+{
+       /* check for power switch and suspending as one is manual and the other automatic */
+       if (pwrflags & PSP_POWER_CB_POWER_SWITCH || pwrflags & PSP_POWER_CB_SUSPENDING)
+       {
+               lprintf("power_callback: flags: 0x%08X: suspending\n", pwrflags);
+               engineState = PGS_Menu;
+       }
+       sceDisplayWaitVblankStart();
+       return 0;
+}
+
 /* Callback thread */
 static int callback_thread(SceSize args, void *argp)
 {
@@ -38,6 +52,8 @@ static int callback_thread(SceSize args, void *argp)
 
        cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
        sceKernelRegisterExitCallback(cbid);
+       cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
+       scePowerRegisterCallback(0, cbid);
 
        sceKernelSleepThreadCB();
 
index 93ee956..f2fb563 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.34"\r
+#define VERSION "1.35"\r
 \r
diff --git a/tools/gcda.c b/tools/gcda.c
new file mode 100644 (file)
index 0000000..1fb6baf
--- /dev/null
@@ -0,0 +1,110 @@
+#include <stdio.h>
+//#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static int search_gcda(const char *str, int len)
+{
+       int i;
+       for (i = 0; i < len - 6; i++)
+               if (str[i]   == '.' && str[i+1] == 'g' && str[i+2] == 'c' &&
+                   str[i+3] == 'd' && str[i+4] == 'a' && str[i+5] == 0)
+                       return i;
+       return -1;
+}
+
+static int is_good_char(char c)
+{
+       return c >= ' ' && c < 0x7f;
+}
+
+static int is_good_path(char *path)
+{
+       int len = strlen(path);
+
+       path[len-2] = 'n';
+       path[len-1] = 'o';
+
+       FILE *f = fopen(path, "rb");
+
+       path[len-2] = 'd';
+       path[len-1] = 'a';
+
+       if (f) {
+               fclose(f);
+               return 1;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       char buff[1024], *p;
+       char cwd[4096];
+       FILE *f;
+       int l, pos, pos1, old_len, cwd_len;
+
+       if (argc != 2) return 1;
+
+       getcwd(cwd, sizeof(cwd));
+       cwd_len = strlen(cwd);
+       if (cwd[cwd_len-1] != '/') {
+               cwd[cwd_len++] = '/';
+               cwd[cwd_len] = 0;
+       }
+
+       f = fopen(argv[1], "rb+");
+       if (f == NULL) return 2;
+
+       while (1)
+       {
+readnext:
+               l = fread(buff, 1, sizeof(buff), f);
+               if (l <= 16) break;
+
+               pos = 0;
+               while (pos < l)
+               {
+                       pos1 = search_gcda(buff + pos, l - pos);
+                       if (pos1 < 0) {
+                               fseek(f, -5, SEEK_CUR);
+                               goto readnext;
+                       }
+                       pos += pos1;
+
+                       while (pos > 0 && is_good_char(buff[pos-1])) pos--;
+
+                       if (pos == 0) {
+                               fseek(f, -16, SEEK_CUR);
+                               goto readnext;
+                       }
+
+                       // paths must start with /
+                       while (pos < l && buff[pos] != '/') pos++;
+                       p = buff + pos;
+                       old_len = strlen(p);
+
+                       if (!is_good_path(p)) {
+                               pos += old_len;
+                               continue;
+                       }
+
+                       if (strncmp(p, cwd, cwd_len) != 0) {
+                               printf("can't handle: %s\n", p);
+                               pos += old_len;
+                               continue;
+                       }
+
+                       memmove(p, p + cwd_len, old_len - cwd_len + 1);
+                       fseek(f, -(sizeof(buff) - pos), SEEK_CUR);
+                       fwrite(p, 1, old_len, f);
+                       goto readnext;
+               }
+       }
+
+       fclose(f);
+
+       return 0;
+}
+