optimizations, fixes, hacks, psp, ...
[picodrive.git] / Pico / sound / sound.c
index 5f9836b..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
@@ -220,8 +207,14 @@ PICO_INTERNAL void PsndClear(void)
 {\r
   int len = PsndLen;\r
   if (PsndLen_exc_add) len++;\r
-  if (PicoOpt & 8) memset32((int *) PsndOut, 0, len); // clear both channels at once\r
-  else memset(PsndOut, 0, len<<1);\r
+  if (PicoOpt & 8)\r
+    memset32((int *) PsndOut, 0, len); // assume PsndOut to be aligned\r
+  else {\r
+    short *out = PsndOut;\r
+    if ((int)out & 2) { *out++ = 0; len--; }\r
+    memset32((int *) out, 0, len/2);\r
+    if (len & 1) out[len-1] = 0;\r
+  }\r
 }\r
 \r
 \r
@@ -300,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
@@ -373,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
@@ -399,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
@@ -448,7 +414,8 @@ PICO_INTERNAL void z80_pack(unsigned char *data)
   memcpy(data+4, &drZ80, 0x54);\r
 #elif defined(_USE_CZ80)\r
   *(int *)data = 0x00007a43; // "Cz"\r
-  memcpy(data+4, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80);\r
+  *(int *)(data+4) = Cz80_Get_Reg(&CZ80, CZ80_PC);\r
+  memcpy(data+8, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80);\r
 #endif\r
 }\r
 \r
@@ -476,9 +443,10 @@ PICO_INTERNAL void z80_unpack(unsigned char *data)
     z80_int(); // try to goto int handler, maybe we won't execute trash there?\r
   }\r
 #elif defined(_USE_CZ80)\r
-  if (*(int *)data == 0x00007a43) // "Cz" save?\r
-    memcpy(&CZ80, data+4, (INT32)&CZ80.BasePC - (INT32)&CZ80);\r
-  else {\r
+  if (*(int *)data == 0x00007a43) { // "Cz" save?\r
+    memcpy(&CZ80, data+8, (INT32)&CZ80.BasePC - (INT32)&CZ80);\r
+    Cz80_Set_Reg(&CZ80, CZ80_PC, *(int *)(data+4));\r
+  } else {\r
     z80_reset();\r
     z80_int();\r
   }\r