X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Pico%2FPico.c;h=5f90db383ae2744b325fdb307434cd057d67dcf3;hb=7d4906bfc93ced40a544534f433f06b00add52b0;hp=91d9331f3bce9a70efb548b2caccb7b113010d56;hpb=e849512f15a68e71f01c392b0b9719e192154371;p=picodrive.git diff --git a/Pico/Pico.c b/Pico/Pico.c index 91d9331..5f90db3 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -16,14 +16,13 @@ int PicoOpt=0; // disable everything by default int PicoSkipFrame=0; // skip rendering frame? int PicoRegionOverride = 0; // override the region detection 0: Auto, 1: Japan NTSC, 2: Japan PAL, 4: US, 8: Europe int PicoAutoRgnOrder = 0; -int emustatus = 0; +int emustatus = 0; // rapid_ym2612, multi_ym_updates void (*PicoWriteSound)(int len) = 0; // called once per frame at the best time to send sound buffer (PsndOut) to hardware -struct PicoSRAM SRam; +struct PicoSRAM SRam = {0,}; int z80startCycle, z80stopCycle; // in 68k cycles -//int z80ExtraCycles = 0; int PicoPad[2]; // Joypads, format is SACB RLDU -int PicoMCD = 0; // mega CD status: scd_started, reset_pending +int PicoMCD = 0; // mega CD status: scd_started // to be called once on emu init int PicoInit(void) @@ -39,7 +38,6 @@ int PicoInit(void) PicoInitMCD(); SRam.data=0; - SRam.resize=1; return 0; } @@ -59,13 +57,10 @@ int PicoReset(int hard) unsigned int region=0; int support=0,hw=0,i=0; unsigned char pal=0; + unsigned char sram_reg=Pico.m.sram_reg; // must be preserved if (Pico.romsize<=0) return 1; - // setup correct memory map - if (PicoMCD & 1) - PicoMemSetupCD(); - else PicoMemSetup(); PicoMemReset(); SekReset(); // s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games). @@ -149,56 +144,17 @@ int PicoReset(int hard) return 0; } - if(SRam.resize) { - int sram_size = 0; - if(SRam.data) free(SRam.data); SRam.data=0; - Pico.m.sram_reg = 0; - - if(*(Pico.rom+0x1B1) == 'R' && *(Pico.rom+0x1B0) == 'A') { - if(*(Pico.rom+0x1B2) & 0x40) { - // EEPROM - // what kind of EEPROMs are actually used? X24C02? X24C04? (X24C01 has only 128), but we will support up to 8K - SRam.start = PicoRead32(0x1B4) & ~1; // zero address is used for clock by some games - SRam.end = PicoRead32(0x1B8); - sram_size = 0x2000; - Pico.m.sram_reg = 4; - } else { - // normal SRAM - SRam.start = PicoRead32(0x1B4) & 0xFFFF00; - SRam.end = PicoRead32(0x1B8) | 1; - sram_size = SRam.end - SRam.start + 1; - } - Pico.m.sram_reg |= 0x10; // SRAM was detected - } - if(sram_size <= 0) { - // some games may have bad headers, like S&K and Sonic3 - SRam.start = 0x200000; - SRam.end = 0x203FFF; - sram_size = 0x004000; - } + // reset sram state; enable sram access by default if it doesn't overlap with ROM + Pico.m.sram_reg=sram_reg&0x14; + if (!(Pico.m.sram_reg&4) && Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1; - // enable sram access by default if it doesn't overlap with ROM - if(Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1; - SRam.reg_back = Pico.m.sram_reg; - - if(sram_size) { - SRam.data = (unsigned char *) calloc(sram_size, 1); - if(!SRam.data) return 1; - } - SRam.resize=0; - // Dino Dini's Soccer malfunctions if SRAM is not filled with 0xff - if (strncmp((char *)Pico.rom+0x150, "IDOND NI'I", 10) == 0) - memset(SRam.data, 0xff, sram_size); - elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x", - (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end); - } - - Pico.m.sram_reg = SRam.reg_back; // restore sram_reg - SRam.changed = 0; + elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x", + (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end); return 0; } + // dma2vram settings are just hacks to unglitch Legend of Galahad (needs <= 104 to work) // same for Outrunners (92-121, when active is set to 24) static const int dma_timings[] = { @@ -242,7 +198,7 @@ PICO_INTERNAL int CheckDMA(void) return burn; } -static __inline void SekRun(int cyc) +static __inline void SekRunM68k(int cyc) { int cyc_do; SekCycleAim+=cyc; @@ -308,6 +264,8 @@ static int CheckIdle(void) return 0; } +void lprintf_al(const char *fmt, ...); + // to be called on 224 or line_sample scanlines only static __inline void getSamples(int y) { @@ -465,24 +423,34 @@ static int PicoFrameHints(void) #include "PicoFrameHints.c" #endif -// helper z80 runner +// helper z80 runner. Runs only if z80 is enabled at this point +// (z80WriteBusReq will handle the rest) static void PicoRunZ80Simple(int line_from, int line_to) { - int line_from_r=line_from, line_to_r=line_to, line = line_from; + int line_from_r=line_from, line_to_r=line_to, line=0; int line_sample = Pico.m.pal ? 68 : 93; - if(!(PicoOpt&4) || Pico.m.z80Run == 0) { line_from_r = line_to_r; line_to_r = 0; } + if (!(PicoOpt&4) || Pico.m.z80Run == 0) line_to_r = 0; + else { + extern const unsigned short vcounts[]; + if (z80startCycle) { + line = vcounts[z80startCycle>>8]; + if (line > line_from) + line_from_r = line; + } + z80startCycle = SekCyclesDone(); + } - if(PicoOpt&1) { + if (PicoOpt&1) { // we have ym2612 enabled, so we have to run Z80 in lines, so we could update DAC and timers - for(; line < line_to; line++) { + for (line = line_from; line < line_to; line++) { sound_timers_and_dac(line); - if((line == 224 || line == line_sample) && PsndOut) getSamples(line); - if(line == 32 && PsndOut) emustatus &= ~1; - if(line >= line_from_r && line < line_to_r) + if ((line == 224 || line == line_sample) && PsndOut) getSamples(line); + if (line == 32 && PsndOut) emustatus &= ~1; + if (line >= line_from_r && line < line_to_r) z80_run(228); } - } else if(line_to_r-line_from_r > 0) { + } else if (line_to_r-line_from_r > 0) { z80_run(228*(line_to_r-line_from_r)); // samples will be taken by caller } @@ -524,6 +492,7 @@ static int PicoFrameSimple(void) Pico.video.status|=0x200; Pico.m.scanline=-1; + z80startCycle=0; SekCyclesReset(); @@ -539,7 +508,7 @@ static int PicoFrameSimple(void) if (CheckIdle()) break; lines += lines_step; - SekRun(cycles_68k_block); + SekRunM68k(cycles_68k_block); PicoRunZ80Simple(line, lines); line=lines; @@ -549,11 +518,12 @@ static int PicoFrameSimple(void) if(sects) { int c = sects*cycles_68k_block; - lines += sects*lines_step; - PicoRunZ80Simple(line, lines); - // this is for approriate line counter, etc + // this "run" is for approriate line counter, etc SekCycleCnt += c; SekCycleAim += c; + + lines += sects*lines_step; + PicoRunZ80Simple(line, lines); } // here we render sound if ym2612 is disabled @@ -584,7 +554,7 @@ static int PicoFrameSimple(void) // a gap between flags set and vint pv->pending_ints|=0x20; pv->status|=8; // go into vblank - SekRun(68+4); + SekRunM68k(68+4); // ---- V-Blanking period ---- // fix line counts @@ -611,7 +581,7 @@ static int PicoFrameSimple(void) while (sects) { lines += lines_step; - SekRun(cycles_68k_vblock); + SekRunM68k(cycles_68k_vblock); PicoRunZ80Simple(line, lines); line=lines; @@ -668,7 +638,7 @@ void PicoFrameDrawOnly(void) // callback to output message from emu void (*PicoMessage)(const char *msg)=NULL; -#if defined(__DEBUG_PRINT) || defined(__GP2X__) +#if 1 // defined(__DEBUG_PRINT) // tmp debug: dump some stuff #define bit(r, x) ((r>>x)&1) void z80_debug(char *dstr); @@ -692,12 +662,12 @@ char *debugString(void) sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); dstrp+=strlen(dstrp); sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); dstrp+=strlen(dstrp); - sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i\n", reg[0x10]&3, (reg[0x10]&0x30)>>4, - bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2)); dstrp+=strlen(dstrp); + sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4, + bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2), SRam.eeprom_type); dstrp+=strlen(dstrp); sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); dstrp+=strlen(dstrp); sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); dstrp+=strlen(dstrp); -#ifdef EMU_C68K +#if defined(EMU_C68K) sprintf(dstrp, "M68k: PC: %06x, st_flg: %x, cycles: %u\n", SekPc, PicoCpu.state_flags, SekCyclesDoneT()); dstrp+=strlen(dstrp); sprintf(dstrp, "d0=%08x, a0=%08x, osp=%08x, irql=%i\n", PicoCpu.d[0], PicoCpu.a[0], PicoCpu.osp, PicoCpu.irq); dstrp+=strlen(dstrp); @@ -705,6 +675,8 @@ char *debugString(void) for(r=2; r < 8; r++) { sprintf(dstrp, "d%i=%08x, a%i=%08x\n", r, PicoCpu.d[r], r, PicoCpu.a[r]); dstrp+=strlen(dstrp); } +#elif defined(EMU_M68K) + sprintf(dstrp, "M68k: PC: %06x, cycles: %u, irql: %i\n", SekPc, SekCyclesDoneT(), PicoM68kCPU.int_level>>8); dstrp+=strlen(dstrp); #endif sprintf(dstrp, "z80Run: %i, pal: %i, frame#: %i\n", Pico.m.z80Run, Pico.m.pal, Pico.m.frame_count); dstrp+=strlen(dstrp); z80_debug(dstrp); dstrp+=strlen(dstrp);