From 312e9ce192d49b4bea2f8a7e3cd2eb91a860564f Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 25 Dec 2006 15:17:54 +0000 Subject: [PATCH] partial gmv implementation git-svn-id: file:///home/notaz/opt/svn/PicoDrive@6 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Memory.c | 11 +++++-- Pico/Pico.c | 44 +++++++++++++++++-------- Pico/PicoInt.h | 4 ++- Pico/Sek.c | 4 +-- Pico/VideoPort.c | 23 +++++++------ platform/gp2x/emu.c | 63 ++++++++++++++++++++++++++++-------- platform/gp2x/menu.c | 2 +- platform/linux/port_config.h | 4 +-- 8 files changed, 108 insertions(+), 47 deletions(-) diff --git a/Pico/Memory.c b/Pico/Memory.c index d3b931c..3104eb4 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -267,13 +267,16 @@ u32 OtherRead16(u32 a, int realsize) } // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers if (a==0xa11100) { - extern int z80stopCycle; // TODO: tidy d=Pico.m.z80Run&1; +#if 0 if (!d) { + // do we need this? + extern int z80stopCycle; // TODO: tidy int stop_before = SekCyclesDone() - z80stopCycle; - if (stop_before > 0 && stop_before <= 16*2) // Gens uses 16 here + if (stop_before > 0 && stop_before <= 16) // Gens uses 16 here d = 1; // bus not yet available } +#endif d=(d<<8)|0x8000|Pico.m.rotate++; dprintf("get_zrun: %04x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), SekPc); goto end; } @@ -569,7 +572,9 @@ static void CPU_CALL PicoWrite8(u32 a,u8 d) // dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); - if ((a&0xe00000)==0xe00000) { u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram + if ((a&0xe00000)==0xe00000) { + if((a&0xffff)==0xf62a) dprintf("(f62a) = %02x [%i|%i] @ %x", d, Pico.m.scanline, SekCyclesDone(), SekPc); + u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram a&=0xffffff; OtherWrite8(a,d,8); diff --git a/Pico/Pico.c b/Pico/Pico.c index 240c505..5ab8483 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -194,22 +194,32 @@ static int dma_timings[] = { 9, 18, 17, 9 // ... }; -static void CheckDMA(void) +static int dma_bsycles[] = { +(488<<8)/83, (488<<8)/167, (488<<8)/166, (488<<8)/83, +(488<<8)/102, (488<<8)/205, (488<<8)/204, (488<<8)/102, +(488<<8)/8, (488<<8)/16, (488<<8)/15, (488<<8)/8, +(488<<8)/9, (488<<8)/18, (488<<8)/17, (488<<8)/9 +}; + +//static +int CheckDMA(void) { int burn = 0, bytes_can = 0, dma_op = Pico.video.reg[0x17]>>6; // see gens for 00 and 01 modes int bytes = Pico.m.dma_bytes; + int dma_op1; - if(dma_op & 2) bytes_can = dma_op; - else if(Pico.video.type!=1) bytes_can = 1; // setting dma_timings offset here according to Gens - if(Pico.video.reg[12] & 1) bytes_can += 4; // 40 cell mode? - if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) { dma_op|=4; bytes_can += 8; } // active display? - bytes_can = dma_timings[bytes_can]; + if(!(dma_op&2)) dma_op = (Pico.video.type==1) ? 0 : 1; // setting dma_timings offset here according to Gens + dma_op1 = dma_op; + if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode? + if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display? + bytes_can = dma_timings[dma_op]; if(bytes <= bytes_can) { if(dma_op&2) Pico.video.status&=~2; // dma no longer busy else { - if(dma_op&4) burn = bytes*(((488<<8)/18 ))>>8; // have to be approximate because can't afford division.. - else burn = bytes*(((488<<8)/205))>>8; + burn = bytes * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division.. + //SekCycleCnt-=Pico.m.dma_endcycles; + //Pico.m.dma_endcycles = 0; } Pico.m.dma_bytes = 0; } else { @@ -217,8 +227,10 @@ static void CheckDMA(void) Pico.m.dma_bytes -= bytes_can; } - SekCycleCnt+=burn; - dprintf("~Dma %i op=%i can=%i burn=%i [%i|%i]", Pico.m.dma_bytes, dma_op, bytes_can, burn, Pico.m.scanline, SekCyclesDone()); + //SekCycleCnt+=burn; + dprintf("~Dma %i op=%i can=%i burn=%i [%i|%i]", Pico.m.dma_bytes, dma_op1, bytes_can, burn, Pico.m.scanline, SekCyclesDone()); + //dprintf("~aim: %i, cnt: %i", SekCycleAim, SekCycleCnt); + return burn; } static __inline void SekRun(int cyc) @@ -250,7 +262,9 @@ static __inline void SekRun(int cyc) Pico.m.scanline, SekCyclesDone()); } #endif + //dprintf("aim: %i, cnt: %i", SekCycleAim, SekCycleCnt); if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return; + //dprintf("cyc_do: %i", cyc_do); #if defined(EMU_C68K) && defined(EMU_M68K) // this means we do run-compare Cyclone vs Musashi SekCycleCnt+=CM_compareRun(cyc_do); @@ -390,12 +404,14 @@ static int PicoFrameHints(void) // V-Interrupt: if (y == lines_vis) { - //dprintf("vint: @ %06x [%i|%i]", SekPc, y, SekCycleCnt); - pv->status|=0x88; // V-Int happened, go into vblank + dprintf("vint: @ %06x [%i|%i], aim=%i cnt=%i", SekPc, y, SekCycleCnt, SekCycleAim, SekCycleCnt); + pv->status|=0x08; // go into vblank if(!Pico.m.dma_bytes||(Pico.video.reg[0x17]&0x80)) { // there must be a gap between H and V ints, also after vblank bit set (Mazin Saga, Bram Stoker's Dracula) - SekRun(128); SekCycleAim-=128; + SekRun(128); SekCycleAim-=128; // 128; ? } + dprintf("[%i|%i], aim=%i cnt=%i @ %x", y, SekCycleCnt, SekCycleAim, SekCycleCnt, SekPc); + pv->status|=0x80; // V-Int happened pv->pending_ints|=0x20; if(pv->reg[1]&0x20) SekInterrupt(6); if(Pico.m.z80Run && (PicoOpt&4)) // ? @@ -421,7 +437,7 @@ static int PicoFrameHints(void) getSamples(y); // Run scanline: - if(Pico.m.dma_bytes) CheckDMA(); + if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA(); SekRun(cycles_68k); if((PicoOpt&4) && Pico.m.z80Run) { Pico.m.z80Run|=2; diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index 4242452..dd1d417 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -124,7 +124,8 @@ struct PicoMisc unsigned char sram_slave; // EEPROM slave word for X24C02 and better SRAMs unsigned char prot_bytes[2]; // simple protection fakeing unsigned short dma_bytes; // - unsigned char pad1[6]; + unsigned char pad[2]; + unsigned int frame_count; // mainly for movies }; // some assembly stuff depend on these, do not touch! @@ -209,6 +210,7 @@ void PicoWriteCD32(unsigned int a, unsigned int d); extern struct Pico Pico; extern struct PicoSRAM SRam; extern int emustatus; +int CheckDMA(void); // cd/Pico.c int PicoInitMCD(void); diff --git a/Pico/Sek.c b/Pico/Sek.c index df98d9d..b3b35a3 100644 --- a/Pico/Sek.c +++ b/Pico/Sek.c @@ -81,8 +81,8 @@ static int SekUnrecognizedOpcode() #ifdef EMU_M68K static int SekIntAckM68K(int level) { - if (level == 4) { Pico.video.pending_ints = 0; } // dprintf("hack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); } - else if(level == 6) { Pico.video.pending_ints &= ~0x20; } // dprintf("vack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); } + if (level == 4) { Pico.video.pending_ints = 0; dprintf("hack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); } + else if(level == 6) { Pico.video.pending_ints &= ~0x20; dprintf("vack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); } CPU_INT_LEVEL = 0; return M68K_INT_ACK_AUTOVECTOR; } diff --git a/Pico/VideoPort.c b/Pico/VideoPort.c index 5d972f5..7f3d009 100644 --- a/Pico/VideoPort.c +++ b/Pico/VideoPort.c @@ -58,6 +58,7 @@ static unsigned int VideoRead() return d; } +#if 0 // calculate the number of cycles 68k->VDP dma operation would take static int DmaSlowBurn(int len) { @@ -75,6 +76,7 @@ static int DmaSlowBurn(int len) return burn; } +#endif static int GetDmaLength() { @@ -93,14 +95,15 @@ static void DmaSlow(int len) u16 *pd=0, *pdend, *r; unsigned int a=Pico.video.addr, a2, d; unsigned char inc=Pico.video.reg[0xf]; - unsigned int source, burn; + unsigned int source; // , burn; source =Pico.video.reg[0x15]<<1; source|=Pico.video.reg[0x16]<<9; source|=Pico.video.reg[0x17]<<17; - dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i]", Pico.video.type, source, a, len, inc, - (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), Pico.m.scanline, SekCyclesDone()); + dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i] @ %x", + Pico.video.type, source, a, len, inc, (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), + Pico.m.scanline, SekCyclesDone(), SekPc); if ((source&0xe00000)==0xe00000) { pd=(u16 *)(Pico.ram+(source&0xfffe)); pdend=(u16 *)(Pico.ram+0x10000); } // Ram else if(source>3; // hack + SekSetCyclesLeft(SekCyclesLeft - CheckDMA()); +// CheckDMA(); // dprintf("DmaSlow burn: %i @ %06x", burn, SekPc); switch (Pico.video.type) @@ -138,8 +145,6 @@ static void DmaSlow(int len) break; case 3: // cram - dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i]", Pico.video.type, source, a, len, inc, - (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), Pico.m.scanline, SekCyclesDone()); Pico.m.dirtyPal = 1; r = Pico.cram; for(a2=a&0x7f; len; len--) @@ -314,8 +319,8 @@ void PicoVideoWrite(unsigned int a,unsigned short d) { // Register write: int num=(d>>8)&0x1f; - //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); - //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); + 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); + 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); //if(num==01) dprintf("set_blank: %i @ %06x [%i|%i]", !((d&0x40)>>6), SekPc, Pico.m.scanline, SekCyclesDone()); //if(num==05) dprintf("spr_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone()); //if(num==10) dprintf("hint_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone()); diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 14eadeb..d84b053 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -55,7 +55,6 @@ static int combo_keys = 0, combo_acts = 0; // keys and actions which need button static int gp2x_old_gamma = 100; static unsigned char *movie_data = NULL; static int movie_size = 0; -int frame_count = 0; unsigned char *framebuff = 0; // temporary buffer for alt renderer int state_slot = 0; @@ -246,7 +245,7 @@ int emu_ReloadRom(void) if(currentConfig.EmuOpt & 1) emu_SaveLoadGame(1, 1); - frame_count = 0; + Pico.m.frame_count = 0; return 1; } @@ -713,7 +712,7 @@ static void updateKeys(void) if(movie_data) { - int offs = frame_count*3 + 0x40; + int offs = Pico.m.frame_count*3 + 0x40; if (offs+3 > movie_size) { free(movie_data); movie_data = 0; @@ -736,8 +735,6 @@ static void updateKeys(void) PicoPad[1] |= (~movie_data[offs+2] & 0xA0) << 4; // ! MZYX if(!(movie_data[offs+2] & 0x10)) PicoPad[1] |= 0x0400; // X if(!(movie_data[offs+2] & 0x40)) PicoPad[1] |= 0x0100; // Z - if ((PicoPad[0] & 0x80) || (PicoPad[1] & 0x80)) - printf("%d: start\n", frame_count); } } else @@ -745,7 +742,7 @@ static void updateKeys(void) PicoPad[0] = (unsigned short) allActions[0]; PicoPad[1] = (unsigned short) allActions[1]; } - frame_count++; + Pico.m.frame_count++; events = (allActions[0] | allActions[1]) >> 16; @@ -995,21 +992,59 @@ void emu_Loop(void) updateKeys(); PicoFrame(); +#if 0 +if (Pico.m.frame_count == 31563) { + FILE *f; + f = fopen("ram_p.bin", "wb"); + if (!f) { printf("!f\n"); exit(1); } + fwrite(Pico.ram, 1, 0x10000, f); + fclose(f); + exit(0); +} +#endif #if 0 // debug { - static unsigned char oldscr[320*240*2]; + #define BYTE unsigned char + #define WORD unsigned short + struct + { + BYTE IDLength; /* 00h Size of Image ID field */ + BYTE ColorMapType; /* 01h Color map type */ + BYTE ImageType; /* 02h Image type code */ + WORD CMapStart; /* 03h Color map origin */ + WORD CMapLength; /* 05h Color map length */ + BYTE CMapDepth; /* 07h Depth of color map entries */ + WORD XOffset; /* 08h X origin of image */ + WORD YOffset; /* 0Ah Y origin of image */ + WORD Width; /* 0Ch Width of image */ + WORD Height; /* 0Eh Height of image */ + BYTE PixelDepth; /* 10h Image pixel size */ + BYTE ImageDescriptor; /* 11h Image descriptor byte */ + } __attribute__((packed)) TGAHEAD; + static unsigned short oldscr[320*240]; FILE *f; char name[128]; int i; - for (i = 0; i < 320*240*2; i++) - if(oldscr[i] != ((unsigned char *)gp2x_screen)[i]) break; - if (i < 320*240*2) + + memset(&TGAHEAD, 0, sizeof(TGAHEAD)); + TGAHEAD.ImageType = 2; + TGAHEAD.Width = 320; + TGAHEAD.Height = 240; + TGAHEAD.PixelDepth = 16; + TGAHEAD.ImageDescriptor = 2<<4; // image starts at top-left + + #define CONV(X) (((X>>1)&0x7fe0)|(X&0x1f)) // 555? + + for (i = 0; i < 320*240; i++) + if(oldscr[i] != CONV(((unsigned short *)gp2x_screen)[i])) break; + if (i < 320*240) { - for (i = 0; i < 320*240*2; i++) - oldscr[i] = ((unsigned char *)gp2x_screen)[i]; - sprintf(name, "%05i.raw", frame_count); + for (i = 0; i < 320*240; i++) + oldscr[i] = CONV(((unsigned short *)gp2x_screen)[i]); + sprintf(name, "%05i.tga", Pico.m.frame_count); f = fopen(name, "wb"); if (!f) { printf("!f\n"); exit(1); } - fwrite(gp2x_screen, 1, 320*240*2, f); + fwrite(&TGAHEAD, 1, sizeof(TGAHEAD), f); + fwrite(oldscr, 1, 320*240*2, f); fclose(f); } } diff --git a/platform/gp2x/menu.c b/platform/gp2x/menu.c index 6336126..588e0c9 100644 --- a/platform/gp2x/menu.c +++ b/platform/gp2x/menu.c @@ -603,7 +603,7 @@ static void draw_amenu_options(int menu_sel) static void amenu_loop_options(void) { - int menu_sel = 0, menu_sel_max = 11; + int menu_sel = 0, menu_sel_max = 10; unsigned long inp = 0; for(;;) diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index b679bab..be76af4 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -12,9 +12,7 @@ // 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 -- 2.39.2