}\r
// |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers\r
if (a==0xa11100) {\r
- extern int z80stopCycle; // TODO: tidy\r
d=Pico.m.z80Run&1;\r
+#if 0\r
if (!d) {\r
+ // do we need this?\r
+ extern int z80stopCycle; // TODO: tidy\r
int stop_before = SekCyclesDone() - z80stopCycle;\r
- if (stop_before > 0 && stop_before <= 16*2) // Gens uses 16 here\r
+ if (stop_before > 0 && stop_before <= 16) // Gens uses 16 here\r
d = 1; // bus not yet available\r
}\r
+#endif\r
d=(d<<8)|0x8000|Pico.m.rotate++;\r
dprintf("get_zrun: %04x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), SekPc);\r
goto end; }\r
// dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);\r
\r
\r
- if ((a&0xe00000)==0xe00000) { u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram\r
+ if ((a&0xe00000)==0xe00000) {\r
+ if((a&0xffff)==0xf62a) dprintf("(f62a) = %02x [%i|%i] @ %x", d, Pico.m.scanline, SekCyclesDone(), SekPc);\r
+ u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram\r
\r
a&=0xffffff;\r
OtherWrite8(a,d,8);\r
9, 18, 17, 9 // ...\r
};\r
\r
-static void CheckDMA(void)\r
+static int dma_bsycles[] = {\r
+(488<<8)/83, (488<<8)/167, (488<<8)/166, (488<<8)/83,\r
+(488<<8)/102, (488<<8)/205, (488<<8)/204, (488<<8)/102,\r
+(488<<8)/8, (488<<8)/16, (488<<8)/15, (488<<8)/8,\r
+(488<<8)/9, (488<<8)/18, (488<<8)/17, (488<<8)/9\r
+};\r
+\r
+//static\r
+int CheckDMA(void)\r
{\r
int burn = 0, bytes_can = 0, dma_op = Pico.video.reg[0x17]>>6; // see gens for 00 and 01 modes\r
int bytes = Pico.m.dma_bytes;\r
+ int dma_op1;\r
\r
- if(dma_op & 2) bytes_can = dma_op;\r
- else if(Pico.video.type!=1) bytes_can = 1; // setting dma_timings offset here according to Gens\r
- if(Pico.video.reg[12] & 1) bytes_can += 4; // 40 cell mode?\r
- if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) { dma_op|=4; bytes_can += 8; } // active display?\r
- bytes_can = dma_timings[bytes_can];\r
+ if(!(dma_op&2)) dma_op = (Pico.video.type==1) ? 0 : 1; // setting dma_timings offset here according to Gens\r
+ dma_op1 = dma_op;\r
+ if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode?\r
+ if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display?\r
+ bytes_can = dma_timings[dma_op];\r
\r
if(bytes <= bytes_can) {\r
if(dma_op&2) Pico.video.status&=~2; // dma no longer busy\r
else {\r
- if(dma_op&4) burn = bytes*(((488<<8)/18 ))>>8; // have to be approximate because can't afford division..\r
- else burn = bytes*(((488<<8)/205))>>8;\r
+ burn = bytes * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division..\r
+ //SekCycleCnt-=Pico.m.dma_endcycles;\r
+ //Pico.m.dma_endcycles = 0;\r
}\r
Pico.m.dma_bytes = 0;\r
} else {\r
Pico.m.dma_bytes -= bytes_can;\r
}\r
\r
- SekCycleCnt+=burn;\r
- dprintf("~Dma %i op=%i can=%i burn=%i [%i|%i]", Pico.m.dma_bytes, dma_op, bytes_can, burn, Pico.m.scanline, SekCyclesDone());\r
+ //SekCycleCnt+=burn;\r
+ dprintf("~Dma %i op=%i can=%i burn=%i [%i|%i]", Pico.m.dma_bytes, dma_op1, bytes_can, burn, Pico.m.scanline, SekCyclesDone());\r
+ //dprintf("~aim: %i, cnt: %i", SekCycleAim, SekCycleCnt);\r
+ return burn;\r
}\r
\r
static __inline void SekRun(int cyc)\r
Pico.m.scanline, SekCyclesDone());\r
}\r
#endif\r
+ //dprintf("aim: %i, cnt: %i", SekCycleAim, SekCycleCnt);\r
if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;\r
+ //dprintf("cyc_do: %i", cyc_do);\r
#if defined(EMU_C68K) && defined(EMU_M68K)\r
// this means we do run-compare Cyclone vs Musashi\r
SekCycleCnt+=CM_compareRun(cyc_do);\r
// V-Interrupt:\r
if (y == lines_vis)\r
{\r
- //dprintf("vint: @ %06x [%i|%i]", SekPc, y, SekCycleCnt);\r
- pv->status|=0x88; // V-Int happened, go into vblank\r
+ dprintf("vint: @ %06x [%i|%i], aim=%i cnt=%i", SekPc, y, SekCycleCnt, SekCycleAim, SekCycleCnt);\r
+ pv->status|=0x08; // go into vblank\r
if(!Pico.m.dma_bytes||(Pico.video.reg[0x17]&0x80)) {\r
// there must be a gap between H and V ints, also after vblank bit set (Mazin Saga, Bram Stoker's Dracula)\r
- SekRun(128); SekCycleAim-=128;\r
+ SekRun(128); SekCycleAim-=128; // 128; ?\r
}\r
+ dprintf("[%i|%i], aim=%i cnt=%i @ %x", y, SekCycleCnt, SekCycleAim, SekCycleCnt, SekPc);\r
+ pv->status|=0x80; // V-Int happened\r
pv->pending_ints|=0x20;\r
if(pv->reg[1]&0x20) SekInterrupt(6);\r
if(Pico.m.z80Run && (PicoOpt&4)) // ?\r
getSamples(y);\r
\r
// Run scanline:\r
- if(Pico.m.dma_bytes) CheckDMA();\r
+ if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA();\r
SekRun(cycles_68k);\r
if((PicoOpt&4) && Pico.m.z80Run) {\r
Pico.m.z80Run|=2;\r
unsigned char sram_slave; // EEPROM slave word for X24C02 and better SRAMs\r
unsigned char prot_bytes[2]; // simple protection fakeing\r
unsigned short dma_bytes; //\r
- unsigned char pad1[6];\r
+ unsigned char pad[2];\r
+ unsigned int frame_count; // mainly for movies\r
};\r
\r
// some assembly stuff depend on these, do not touch!\r
extern struct Pico Pico;\r
extern struct PicoSRAM SRam;\r
extern int emustatus;\r
+int CheckDMA(void);\r
\r
// cd/Pico.c\r
int PicoInitMCD(void);\r
#ifdef EMU_M68K\r
static int SekIntAckM68K(int level)\r
{\r
- if (level == 4) { Pico.video.pending_ints = 0; } // dprintf("hack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
- else if(level == 6) { Pico.video.pending_ints &= ~0x20; } // dprintf("vack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
+ if (level == 4) { Pico.video.pending_ints = 0; dprintf("hack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
+ else if(level == 6) { Pico.video.pending_ints &= ~0x20; dprintf("vack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
CPU_INT_LEVEL = 0;\r
return M68K_INT_ACK_AUTOVECTOR;\r
}\r
return d;\r
}\r
\r
+#if 0\r
// calculate the number of cycles 68k->VDP dma operation would take\r
static int DmaSlowBurn(int len)\r
{\r
\r
return burn;\r
}\r
+#endif\r
\r
static int GetDmaLength()\r
{\r
u16 *pd=0, *pdend, *r;\r
unsigned int a=Pico.video.addr, a2, d;\r
unsigned char inc=Pico.video.reg[0xf];\r
- unsigned int source, burn;\r
+ unsigned int source; // , burn;\r
\r
source =Pico.video.reg[0x15]<<1;\r
source|=Pico.video.reg[0x16]<<9;\r
source|=Pico.video.reg[0x17]<<17;\r
\r
- dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i]", Pico.video.type, source, a, len, inc,\r
- (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), Pico.m.scanline, SekCyclesDone());\r
+ dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i] @ %x",\r
+ Pico.video.type, source, a, len, inc, (Pico.video.status&8)||!(Pico.video.reg[1]&0x40),\r
+ Pico.m.scanline, SekCyclesDone(), SekPc);\r
\r
if ((source&0xe00000)==0xe00000) { pd=(u16 *)(Pico.ram+(source&0xfffe)); pdend=(u16 *)(Pico.ram+0x10000); } // Ram\r
else if(source<Pico.romsize) { pd=(u16 *)(Pico.rom+(source&~1)); pdend=(u16 *)(Pico.rom+Pico.romsize); } // Rom\r
#else\r
Pico.m.dma_bytes += len;\r
#endif\r
- if(!(Pico.video.status&8))\r
- SekEndRun(0);\r
+ //if(!(Pico.video.status&8))\r
+// SekEndRun(0);\r
+ //Pico.m.dma_endcycles = 0;//SekCyclesLeft;\r
+ //Pico.m.dma_endcycles -= Pico.m.dma_endcycles>>3; // hack\r
+ SekSetCyclesLeft(SekCyclesLeft - CheckDMA());\r
+// CheckDMA();\r
// dprintf("DmaSlow burn: %i @ %06x", burn, SekPc);\r
\r
switch (Pico.video.type)\r
break;\r
\r
case 3: // cram\r
- dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i]", Pico.video.type, source, a, len, inc,\r
- (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), Pico.m.scanline, SekCyclesDone());\r
Pico.m.dirtyPal = 1;\r
r = Pico.cram;\r
for(a2=a&0x7f; len; len--)\r
{\r
// Register write:\r
int num=(d>>8)&0x1f;\r
- //if(num==00) dprintf("hint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[0]&0x10)>>4, (d&0x10)>>4, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc);\r
- //if(num==01) dprintf("vint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[1]&0x20)>>5, (d&0x20)>>5, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc);\r
+ if(num==00) dprintf("hint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[0]&0x10)>>4, (d&0x10)>>4, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc);\r
+ if(num==01) dprintf("vint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[1]&0x20)>>5, (d&0x20)>>5, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc);\r
//if(num==01) dprintf("set_blank: %i @ %06x [%i|%i]", !((d&0x40)>>6), SekPc, Pico.m.scanline, SekCyclesDone());\r
//if(num==05) dprintf("spr_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone());\r
//if(num==10) dprintf("hint_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone());\r
static int gp2x_old_gamma = 100;\r
static unsigned char *movie_data = NULL;\r
static int movie_size = 0;\r
-int frame_count = 0;\r
unsigned char *framebuff = 0; // temporary buffer for alt renderer\r
int state_slot = 0;\r
\r
if(currentConfig.EmuOpt & 1)\r
emu_SaveLoadGame(1, 1);\r
\r
- frame_count = 0;\r
+ Pico.m.frame_count = 0;\r
\r
return 1;\r
}\r
\r
if(movie_data)\r
{\r
- int offs = frame_count*3 + 0x40;\r
+ int offs = Pico.m.frame_count*3 + 0x40;\r
if (offs+3 > movie_size) {\r
free(movie_data);\r
movie_data = 0;\r
PicoPad[1] |= (~movie_data[offs+2] & 0xA0) << 4; // ! MZYX\r
if(!(movie_data[offs+2] & 0x10)) PicoPad[1] |= 0x0400; // X\r
if(!(movie_data[offs+2] & 0x40)) PicoPad[1] |= 0x0100; // Z\r
- if ((PicoPad[0] & 0x80) || (PicoPad[1] & 0x80))\r
- printf("%d: start\n", frame_count);\r
}\r
}\r
else\r
PicoPad[0] = (unsigned short) allActions[0];\r
PicoPad[1] = (unsigned short) allActions[1];\r
}\r
- frame_count++;\r
+ Pico.m.frame_count++;\r
\r
events = (allActions[0] | allActions[1]) >> 16;\r
\r
updateKeys();\r
PicoFrame();\r
\r
+#if 0\r
+if (Pico.m.frame_count == 31563) {\r
+ FILE *f;\r
+ f = fopen("ram_p.bin", "wb");\r
+ if (!f) { printf("!f\n"); exit(1); }\r
+ fwrite(Pico.ram, 1, 0x10000, f);\r
+ fclose(f);\r
+ exit(0);\r
+}\r
+#endif\r
#if 0\r
// debug\r
{\r
- static unsigned char oldscr[320*240*2];\r
+ #define BYTE unsigned char\r
+ #define WORD unsigned short\r
+ struct\r
+ {\r
+ BYTE IDLength; /* 00h Size of Image ID field */\r
+ BYTE ColorMapType; /* 01h Color map type */\r
+ BYTE ImageType; /* 02h Image type code */\r
+ WORD CMapStart; /* 03h Color map origin */\r
+ WORD CMapLength; /* 05h Color map length */\r
+ BYTE CMapDepth; /* 07h Depth of color map entries */\r
+ WORD XOffset; /* 08h X origin of image */\r
+ WORD YOffset; /* 0Ah Y origin of image */\r
+ WORD Width; /* 0Ch Width of image */\r
+ WORD Height; /* 0Eh Height of image */\r
+ BYTE PixelDepth; /* 10h Image pixel size */\r
+ BYTE ImageDescriptor; /* 11h Image descriptor byte */\r
+ } __attribute__((packed)) TGAHEAD;\r
+ static unsigned short oldscr[320*240];\r
FILE *f; char name[128]; int i;\r
- for (i = 0; i < 320*240*2; i++)\r
- if(oldscr[i] != ((unsigned char *)gp2x_screen)[i]) break;\r
- if (i < 320*240*2)\r
+\r
+ memset(&TGAHEAD, 0, sizeof(TGAHEAD));\r
+ TGAHEAD.ImageType = 2;\r
+ TGAHEAD.Width = 320;\r
+ TGAHEAD.Height = 240;\r
+ TGAHEAD.PixelDepth = 16;\r
+ TGAHEAD.ImageDescriptor = 2<<4; // image starts at top-left\r
+\r
+ #define CONV(X) (((X>>1)&0x7fe0)|(X&0x1f)) // 555?\r
+\r
+ for (i = 0; i < 320*240; i++)\r
+ if(oldscr[i] != CONV(((unsigned short *)gp2x_screen)[i])) break;\r
+ if (i < 320*240)\r
{\r
- for (i = 0; i < 320*240*2; i++)\r
- oldscr[i] = ((unsigned char *)gp2x_screen)[i];\r
- sprintf(name, "%05i.raw", frame_count);\r
+ for (i = 0; i < 320*240; i++)\r
+ oldscr[i] = CONV(((unsigned short *)gp2x_screen)[i]);\r
+ sprintf(name, "%05i.tga", Pico.m.frame_count);\r
f = fopen(name, "wb");\r
if (!f) { printf("!f\n"); exit(1); }\r
- fwrite(gp2x_screen, 1, 320*240*2, f);\r
+ fwrite(&TGAHEAD, 1, sizeof(TGAHEAD), f);\r
+ fwrite(oldscr, 1, 320*240*2, f);\r
fclose(f);\r
}\r
}\r
\r
static void amenu_loop_options(void)\r
{\r
- int menu_sel = 0, menu_sel_max = 11;\r
+ int menu_sel = 0, menu_sel_max = 10;\r
unsigned long inp = 0;\r
\r
for(;;)\r
// pico.c
#define CAN_HANDLE_240_LINES 1
-extern int frame_count;
-
-#define dprintf(f,...) printf("%05i: " f "\n",frame_count,##__VA_ARGS__)
+#define dprintf(f,...) printf("%05i: " f "\n",Pico.m.frame_count,##__VA_ARGS__)
//#define dprintf(x...)
#endif //PORT_CONFIG_H