int PicoRegionOverride = 0; // override the region detection 0: Auto, 1: Japan NTSC, 2: Japan PAL, 4: US, 8: Europe\r
int PicoAutoRgnOrder = 0;\r
int emustatus = 0;\r
-void (*PicoWriteSound)(void) = 0; // called once per frame at the best time to send sound buffer (PsndOut) to hardware\r
+void (*PicoWriteSound)(int len) = 0; // called once per frame at the best time to send sound buffer (PsndOut) to hardware\r
\r
struct PicoSRAM SRam;\r
-int z80startCycle = 0, z80stopCycle = 0; // in 68k cycles\r
+int z80startCycle, z80stopCycle; // in 68k cycles\r
//int z80ExtraCycles = 0;\r
int PicoPad[2]; // Joypads, format is SACB RLDU\r
int PicoMCD = 0; // mega CD status: scd_started, reset_pending\r
// to be called once on emu exit\r
void PicoExit(void)\r
{\r
- PicoExitMCD();\r
+ if (PicoMCD&1)\r
+ PicoExitMCD();\r
z80_exit();\r
\r
// notaz: sram\r
else PicoMemSetup();\r
PicoMemReset();\r
SekReset();\r
+ // s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games).\r
+ SekSetRealTAS(PicoMCD & 1);\r
SekCycleCntT=0;\r
z80_reset();\r
\r
// reset VDP state, VRAM and PicoMisc\r
//memset(&Pico.video,0,sizeof(Pico.video));\r
//memset(&Pico.vram,0,sizeof(Pico.vram));\r
+ memset(Pico.ioports,0,sizeof(Pico.ioports)); // needed for MCD to reset properly\r
memset(&Pico.m,0,sizeof(Pico.m));\r
Pico.video.pending_ints=0;\r
emustatus = 0;\r
\r
if (PicoMCD & 1) {\r
PicoResetMCD(hard);\r
- SRam.data = 0;\r
return 0;\r
}\r
\r
// Dino Dini's Soccer malfunctions if SRAM is not filled with 0xff\r
if (strncmp((char *)Pico.rom+0x150, "IDOND NI'I", 10) == 0)\r
memset(SRam.data, 0xff, sram_size);\r
+ dprintf("sram: det: %i; eeprom: %i; start: %06x; end: %06x\n",\r
+ (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end);\r
}\r
\r
Pico.m.sram_reg = SRam.reg_back; // restore sram_reg\r
// to be called on 224 or line_sample scanlines only\r
static __inline void getSamples(int y)\r
{\r
+ static int curr_pos = 0;\r
+\r
if(y == 224) {\r
//dprintf("sta%i: %i [%i]", (emustatus & 2), emustatus, y);\r
if(emustatus & 2)\r
- sound_render(PsndLen/2, PsndLen-PsndLen/2);\r
- else sound_render(0, PsndLen);\r
+ curr_pos += sound_render(curr_pos, PsndLen-PsndLen/2);\r
+ else curr_pos = sound_render(0, PsndLen);\r
if (emustatus&1) emustatus|=2; else emustatus&=~2;\r
- if (PicoWriteSound) PicoWriteSound();\r
+ if (PicoWriteSound) PicoWriteSound(curr_pos);\r
// clear sound buffer\r
- memset(PsndOut, 0, (PicoOpt & 8) ? (PsndLen<<2) : (PsndLen<<1));\r
+ sound_clear();\r
}\r
else if(emustatus & 3) {\r
emustatus|= 2;\r
emustatus&=~1;\r
- sound_render(0, PsndLen/2);\r
+ curr_pos = sound_render(0, PsndLen/2);\r
}\r
}\r
\r
getSamples(y);\r
\r
// Run scanline:\r
- if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA();\r
+ if (Pico.m.dma_bytes) SekCyclesBurn(CheckDMA());\r
SekRun(cycles_68k);\r
- if((PicoOpt&4) && Pico.m.z80Run) {\r
- Pico.m.z80Run|=2;\r
- z80CycleAim+=cycles_z80;\r
+ if ((PicoOpt&4) && Pico.m.z80Run) {\r
+ if (Pico.m.z80Run & 2) z80CycleAim+=cycles_z80;\r
+ else {\r
+ int cnt = SekCyclesDone() - z80startCycle;\r
+ cnt = (cnt>>1)-(cnt>>5);\r
+ //if (cnt > cycles_z80) printf("FIXME: z80 cycles: %i\n", cnt);\r
+ if (cnt > cycles_z80) cnt = cycles_z80;\r
+ Pico.m.z80Run |= 2;\r
+ z80CycleAim+=cnt;\r
+ }\r
total_z80+=z80_run(z80CycleAim-total_z80);\r
}\r
}\r
\r
if(!(PicoOpt&4) || Pico.m.z80Run == 0) { line_from_r = line_to_r; line_to_r = 0; }\r
\r
- if(z80startCycle != 0) {\r
+ if(z80startCycle != 0x01000000) {\r
line_from_r = vcounts[z80startCycle>>8]+1;\r
- z80startCycle = 0;\r
+ z80startCycle = 0x01000000;\r
}\r
- if(z80stopCycle != 0) {\r
+ if(z80stopCycle != 0x01000000) {\r
line_to_r = vcounts[z80stopCycle>>8]+1;\r
- z80stopCycle = 0;\r
+ z80stopCycle = 0x01000000;\r
}\r
\r
if(PicoOpt&1) {\r
int y=0,line=0,lines=0,lines_step=0,sects;\r
int cycles_68k_vblock,cycles_68k_block;\r
\r
- if(Pico.m.pal) {\r
+ // we don't emulate DMA timing in this mode\r
+ if (Pico.m.dma_bytes) {\r
+ Pico.m.dma_bytes=0;\r
+ Pico.video.status&=~2;\r
+ }\r
+\r
+ if (Pico.m.pal) {\r
// M68k cycles/frame: 152009.78\r
if(pv->reg[1]&8) { // 240 lines\r
cycles_68k_block = (int) ((double) OSC_PAL / 7 / 50 / 312 * 15 + 0.4); // 16 sects, 16*15=240, 7308\r
\r
// here we render sound if ym2612 is disabled\r
if(!(PicoOpt&1) && PsndOut) {\r
- sound_render(0, PsndLen);\r
- if(PicoWriteSound) PicoWriteSound();\r
+ int len = sound_render(0, PsndLen);\r
+ if(PicoWriteSound) PicoWriteSound(len);\r
// clear sound buffer\r
- memset(PsndOut, 0, (PicoOpt & 8) ? (PsndLen<<2) : (PsndLen<<1));\r
+ sound_clear();\r
}\r
\r
// render screen\r
return 0;\r
}\r
\r
-static int DefaultCram(int cram)\r
+void PicoFrameDrawOnly(void)\r
{\r
- int high=0x0841;\r
- // Convert 0000bbbb ggggrrrr\r
- // to rrrr1ggg g10bbbb1\r
- high|=(cram&0x00f)<<12; // Red\r
- high|=(cram&0x0f0)<< 3; // Green\r
- high|=(cram&0xf00)>> 7; // Blue\r
- return high;\r
+ int y;\r
+ PicoFrameStart();\r
+ for (y=0;y<224;y++) PicoLine(y);\r
}\r
\r
-// Function to convert Megadrive Cram into a native colour:\r
-int (*PicoCram)(int cram)=DefaultCram;\r
+// callback to output message from emu\r
+void (*PicoMessage)(const char *msg)=NULL;\r
\r
-#if defined(__DEBUG_PRINT) || defined(WIN32)\r
+#if defined(__DEBUG_PRINT) || defined(__GP2X__)\r
// tmp debug: dump some stuff\r
#define bit(r, x) ((r>>x)&1)\r
void z80_debug(char *dstr);\r
-char *debugString()\r
+char *debugString(void)\r
{\r
#if 1\r
static char dstr[1024];\r
- unsigned char *reg=Pico.video.reg, r;\r
-\r
- // dump some info\r
- sprintf(dstr, "mode set 1: %02x\n", (r=reg[0]));\r
- sprintf(dstr, "%sdisplay_disable: %i, M3: %i, palette: %i, ?, hints: %i\n\n", dstr, bit(r,0), bit(r,1), bit(r,2), bit(r,4));\r
- sprintf(dstr, "%smode set 2: %02x\n", dstr, (r=reg[1]));\r
- sprintf(dstr, "%sSMS/genesis: %i, pal: %i, dma: %i, vints: %i, disp: %i, TMS9918: %i\n\n",dstr, bit(r,2), bit(r,3), bit(r,4), bit(r,5), bit(r,6), bit(r,7));\r
- sprintf(dstr, "%smode set 3: %02x\n", dstr, (r=reg[0xB]));\r
- sprintf(dstr, "%sLSCR: %i, HSCR: %i, 2cell vscroll: %i, IE2: %i\n\n", dstr, bit(r,0), bit(r,1), bit(r,2), bit(r,3));\r
- sprintf(dstr, "%smode set 4: %02x\n", dstr, (r=reg[0xC]));\r
- sprintf(dstr, "%sinterlace: %i%i; cells: %i; shadow: %i\n\n", dstr, bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3));\r
- sprintf(dstr, "%sscroll size: w: %i; h: %i\n\n", dstr, reg[0x10]&3, (reg[0x10]&0x30)>>4);\r
- sprintf(dstr, "%sSRAM: det: %i; eeprom: %i\n", dstr, bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2));\r
- sprintf(dstr, "%sCPU state: PC: %06x cycles: %i\n", dstr, SekPc, SekCyclesDoneT());\r
+ struct PicoVideo *pv=&Pico.video;\r
+ unsigned char *reg=pv->reg, r;\r
+ char *dstrp;\r
+\r
+ dstrp = dstr;\r
+ sprintf(dstrp, "mode set 1: %02x\n", (r=reg[0])); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "display_disable: %i, M3: %i, palette: %i, ?, hints: %i\n", bit(r,0), bit(r,1), bit(r,2), bit(r,4));\r
+ dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "mode set 2: %02x\n", (r=reg[1])); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "SMS/gen: %i, pal: %i, dma: %i, vints: %i, disp: %i, TMS: %i\n", bit(r,2), bit(r,3), bit(r,4),\r
+ bit(r,5), bit(r,6), bit(r,7)); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "mode set 3: %02x\n", (r=reg[0xB])); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "LSCR: %i, HSCR: %i, 2cell vscroll: %i, IE2: %i\n", bit(r,0), bit(r,1), bit(r,2), bit(r,3)); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3));\r
+ dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i\n", reg[0x10]&3, (reg[0x10]&0x30)>>4,\r
+ bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2)); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status);\r
+ dstrp+=strlen(dstrp);\r
#ifdef EMU_C68K\r
- for(r=0; r < 8; r++)\r
- sprintf(dstr, "%sd%i=%08x, a%i=%08x\n", dstr, r, PicoCpu.d[r], r, PicoCpu.a[r]);\r
+ sprintf(dstrp, "M68k: PC: %06x, st_flg: %x, cycles: %u\n", SekPc, PicoCpu.state_flags, SekCyclesDoneT());\r
+ dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "d0=%08x, a0=%08x, osp=%08x, irql=%i\n", PicoCpu.d[0], PicoCpu.a[0], PicoCpu.osp, PicoCpu.irq); dstrp+=strlen(dstrp);\r
+ sprintf(dstrp, "d1=%08x, a1=%08x, sr=%04x\n", PicoCpu.d[1], PicoCpu.a[1], CycloneGetSr(&PicoCpu)); dstrp+=strlen(dstrp);\r
+ for(r=2; r < 8; r++) {\r
+ sprintf(dstrp, "d%i=%08x, a%i=%08x\n", r, PicoCpu.d[r], r, PicoCpu.a[r]); dstrp+=strlen(dstrp);\r
+ }\r
#endif\r
- z80_debug(dstr);\r
+ sprintf(dstrp, "z80Run: %i, pal: %i, frame#: %i\n", Pico.m.z80Run, Pico.m.pal, Pico.m.frame_count); dstrp+=strlen(dstrp);\r
+ z80_debug(dstrp); dstrp+=strlen(dstrp);\r
+ if (strlen(dstr) > sizeof(dstr))\r
+ printf("warning: debug buffer overflow (%i/%i)\n", strlen(dstr), sizeof(dstr));\r
\r
#else\r
struct PicoVideo *pvid=&Pico.video;\r