From 4b9c58882616c5205a5ad5c9350f20a3d22bd7e1 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 25 May 2008 21:25:46 +0000 Subject: [PATCH] new z80 scheduling method, timers are still wip git-svn-id: file:///home/notaz/opt/svn/PicoDrive@459 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Memory.c | 171 +++++++++++++++++++++++++++++- Pico/Memory.s | 24 ++--- Pico/MemoryCmn.c | 29 ++---- Pico/Pico.c | 134 +++++++++++------------- Pico/PicoFrameHints.c | 60 +++++------ Pico/PicoInt.h | 40 +++++-- Pico/sound/sound.c | 56 ++++------ Pico/sound/ym2612.c | 17 +-- Pico/sound/ym2612.h | 9 +- platform/gp2x/940ctl.c | 183 +++++++-------------------------- platform/gp2x/940ctl.h | 2 +- platform/gp2x/Makefile | 4 +- platform/gp2x/version.h | 2 +- platform/linux/940ctl_ym2612.c | 6 +- platform/linux/Makefile | 4 +- 15 files changed, 377 insertions(+), 364 deletions(-) diff --git a/Pico/Memory.c b/Pico/Memory.c index 0304e27..45d9fdf 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -687,6 +687,168 @@ static void m68k_mem_setup(void) #endif // EMU_M68K +// ----------------------------------------------------------------- + +extern const unsigned short vcounts[]; + +static int get_scanline(int is_from_z80) +{ + if (is_from_z80) { + int cycles = z80_cyclesDone(); + while (cycles - z80_scanline_cycles >= 228) + z80_scanline++, z80_scanline_cycles += 228; + return z80_scanline; + } + + if (Pico.m.scanline != -1) + return Pico.m.scanline; + + return vcounts[SekCyclesDone()>>8]; +} + +// ym2612 DAC and timer I/O handlers for z80 +int ym2612_write_local(u32 a, u32 d, int is_from_z80) +{ + int addr; + + a &= 3; + if (a == 1 && ym2612.OPN.ST.address == 0x2a) /* DAC data */ + { + int scanline = get_scanline(is_from_z80); + //elprintf(EL_STATUS, "%03i -> %03i dac w %08x z80 %i", PsndDacLine, scanline, d, is_from_z80); + ym2612.dacout = ((int)d - 0x80) << 6; + if (PsndOut && ym2612.dacen && scanline >= PsndDacLine) + PsndDoDAC(scanline); + return 0; + } + + switch (a) + { + case 0: /* address port 0 */ + ym2612.OPN.ST.address = d; + ym2612.addr_A1 = 0; +#ifdef __GP2X__ + if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, -1); +#endif + return 0; + + case 1: /* data port 0 */ + if (ym2612.addr_A1 != 0) + return 0; + + addr = ym2612.OPN.ST.address; + ym2612.REGS[addr] = d; + + switch (addr) + { + case 0x24: // timer A High 8 + case 0x25: { // timer A Low 2 + int TAnew = (addr == 0x24) ? ((ym2612.OPN.ST.TA & 0x03)|(((int)d)<<2)) + : ((ym2612.OPN.ST.TA & 0x3fc)|(d&3)); + if (ym2612.OPN.ST.TA != TAnew) + { + //elprintf(EL_STATUS, "timer a set %i", TAnew); + ym2612.OPN.ST.TA = TAnew; + //ym2612.OPN.ST.TAC = (1024-TAnew)*18; + //ym2612.OPN.ST.TAT = 0; + // + timer_a_step = 16495 * (1024 - TAnew); + if ((ym2612.OPN.ST.mode & 5) == 5) { + int cycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone()); + timer_a_next_oflow = (cycles << 8) + timer_a_step; + //elprintf(EL_STATUS, "set to %i @ %i", timer_a_next_oflow>>8, cycles); + } + } + return 0; + } + case 0x26: // timer B + if (ym2612.OPN.ST.TB != d) { + //elprintf(EL_STATUS, "timer b set %i", d); + ym2612.OPN.ST.TB = d; + //ym2612.OPN.ST.TBC = (256-d)<<4; + //ym2612.OPN.ST.TBC *= 18; + //ym2612.OPN.ST.TBT = 0; + } + return 0; + case 0x27: { /* mode, timer control */ + int old_mode = ym2612.OPN.ST.mode; + int xcycles = is_from_z80 ? z80_cyclesDone() : cycles_68k_to_z80(SekCyclesDone()); + xcycles <<= 8; + + //elprintf(EL_STATUS, "st mode %02x", d); + + if ((ym2612.OPN.ST.mode & 5) != 5 && (d & 5) == 5) { + timer_a_next_oflow = xcycles + timer_a_step; + //elprintf(EL_STATUS, "set to %i @ %i st", timer_a_next_oflow>>8, xcycles >> 8); + } + + /* reset Timer b flag */ + if (d & 0x20) + ym2612.OPN.ST.status &= ~2; + + /* reset Timer a flag */ + if (d & 0x10) { + if (ym2612.OPN.ST.status & 1) + while (xcycles > timer_a_next_oflow) + timer_a_next_oflow += timer_a_step; + ym2612.OPN.ST.status &= ~1; + } + if (!(d & 5)) timer_a_next_oflow = 0x80000000; + ym2612.OPN.ST.mode = d; +#ifdef __GP2X__ + if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, get_scanline(is_from_z80)); +#endif + return 0; + } + case 0x2b: { /* DAC Sel (YM2612) */ + int scanline = get_scanline(is_from_z80); + ym2612.dacen = d & 0x80; + if (d & 0x80) PsndDacLine = scanline; +#ifdef __GP2X__ + if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, scanline); +#endif + return 0; + } + } + break; + + case 2: /* address port 1 */ + ym2612.OPN.ST.address = d; + ym2612.addr_A1 = 1; +#ifdef __GP2X__ + if (PicoOpt & POPT_EXT_FM) YM2612Write_940(a, d, -1); +#endif + return 0; + + case 3: /* data port 1 */ + if (ym2612.addr_A1 != 1) + return 0; + + addr = ym2612.OPN.ST.address | 0x100; + ym2612.REGS[addr] = d; + break; + } + +#ifdef __GP2X__ + if (PicoOpt & POPT_EXT_FM) + return YM2612Write_940(a, d, get_scanline(is_from_z80)); +#endif + return YM2612Write_(a, d); +} + +// TODO: timer b, 68k side + asm, savestates +u32 ym2612_read_local_z80(void) +{ + int xcycles = z80_cyclesDone() << 8; + if (timer_a_next_oflow != 0x80000000 && xcycles >= timer_a_next_oflow) { + ym2612.OPN.ST.status |= 1; + } + + //elprintf(EL_STATUS, "timer %i, sched %i, @ %i|%i", ym2612.OPN.ST.status, timer_a_next_oflow>>8, + // xcycles >> 8, (xcycles >> 8) / 228); + return ym2612.OPN.ST.status; +} + // ----------------------------------------------------------------- // z80 memhandlers @@ -696,7 +858,7 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a) if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald) { - if (PicoOpt&POPT_EN_FM) ret = (u8) YM2612Read(); + if (PicoOpt&POPT_EN_FM) ret = ym2612_read_local_z80(); return ret; } @@ -710,7 +872,10 @@ PICO_INTERNAL unsigned char z80_read(unsigned short a) if (PicoAHW & PAHW_MCD) ret = PicoReadM68k8(addr68k); else ret = PicoRead8(addr68k); - elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); + if (addr68k >= 0x400000) // not many games do this + { elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret); } + else + { elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); } return ret; } @@ -729,7 +894,7 @@ PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data) { if ((a>>13)==2) // 0x4000-0x5fff (Charles MacDonald) { - if(PicoOpt&POPT_EN_FM) emustatus|=YM2612Write(a, data) & 1; + if(PicoOpt&POPT_EN_FM) emustatus|=ym2612_write_local(a, data, 1) & 1; return; } diff --git a/Pico/Memory.s b/Pico/Memory.s index 368b640..dbe76ac 100644 --- a/Pico/Memory.s +++ b/Pico/Memory.s @@ -879,27 +879,21 @@ m_write8_z80_not_ram: and r2, r0, #0x6000 cmp r2, #0x4000 bne m_write8_z80_not_ym2612 - ldr r2, =PicoOpt + ldr r3, =PicoOpt and r0, r0, #3 - ldr r2, [r2] - tst r2, #1 + ldr r3, [r3] + mov r2, #0 @ is_from_z80 = 0 + tst r3, #1 bxeq lr stmfd sp!,{lr} -.if EXTERNAL_YM2612 - tst r2, #0x200 - ldreq r2, =YM2612Write_ - ldrne r2, =YM2612Write_940 - mov lr, pc - bx r2 -.else - bl YM2612Write_ -.endif + and r1, r1, #0xff + bl ym2612_write_local ldr r2, =emustatus ldmfd sp!,{lr} ldr r1, [r2] and r0, r0, #1 orr r1, r0, r1 - str r1, [r2] @ emustatus|=YM2612Write(a&3, d); + str r1, [r2] @ emustatus|=ym2612_write_local(a&3, d); bx lr m_write8_z80_not_ym2612: @ not too likely @@ -916,7 +910,7 @@ m_write8_z80_not_ym2612: @ not too likely m_write8_z80_bank_reg: ldr r3, =(Pico+0x22208) @ Pico.m ldrh r2, [r3, #0x0a] - mov r1, r1, lsr #8 + mov r1, r1, lsl #8 orr r2, r1, r2, lsr #1 bic r2, r2, #0xfe00 strh r2, [r3, #0x0a] @@ -932,7 +926,7 @@ m_write8_not_z80: bne OtherWrite8 m_write8_psg: ldr r2, =PicoOpt - mov r0, r1 + and r0, r1, #0xff ldr r2, [r2] tst r2, #2 bxeq lr diff --git a/Pico/MemoryCmn.c b/Pico/MemoryCmn.c index 62e6867..2cf8e8d 100644 --- a/Pico/MemoryCmn.c +++ b/Pico/MemoryCmn.c @@ -69,25 +69,14 @@ void z80WriteBusReq(u32 d) { if (!d) { - // this is for a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III) if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run) { - int lineCycles; z80stopCycle = SekCyclesDone(); - if ((Pico.m.z80Run&2) && Pico.m.scanline != -1) - lineCycles=(488-SekCyclesLeft)&0x1ff; - else lineCycles=z80stopCycle-z80startCycle; // z80 was started at current line - if (lineCycles > 0) { // && lineCycles <= 488) { - //dprintf("zrun: %i/%i cycles", lineCycles, (lineCycles>>1)-(lineCycles>>5)); - lineCycles=(lineCycles>>1)-(lineCycles>>5); - z80_run_nr(lineCycles); - } + PicoSyncZ80(z80stopCycle); } } else { if (!Pico.m.z80Run) - z80startCycle = SekCyclesDone(); - else - d|=Pico.m.z80Run; + z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone()); } } elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc); @@ -169,12 +158,12 @@ void OtherWrite8(u32 a,u32 d) if ((a&0xff4000)==0xa00000) { // z80 RAM if (!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)d; else { - elprintf(EL_ANOMALY, "68k z80 write with no bus! [%06x] %02x @ %06x", a, d, SekPc); + elprintf(EL_ANOMALY, "68k z80 write with no bus! [%06x] %02x @ %06x", a, d&0xff, SekPc); SekCyclesBurn(4); // hack? } return; } - if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d)&1; return; } // FM Sound + if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=ym2612_write_local(a&3, d&0xff, 0)&1; return; } // FM Sound if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports #endif if (a==0xa11100) { z80WriteBusReq(d); return; } @@ -185,6 +174,7 @@ void OtherWrite8(u32 a,u32 d) Pico.m.z80_reset = 0; YM2612ResetChip(); z80_reset(); + timers_reset(); } return; } @@ -204,7 +194,7 @@ void OtherWrite8(u32 a,u32 d) return; } - PicoWrite8Hook(a, d, 8); + PicoWrite8Hook(a, d&0xff, 8); } @@ -216,10 +206,10 @@ void OtherWrite16(u32 a,u32 d) if (a==0xa11100) { z80WriteBusReq(d>>8); return; } if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports if ((a&0xe700f8)==0xc00010||(a&0xff7ff8)==0xa07f10) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound - if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d)&1; return; } // FM Sound (??) + if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=ym2612_write_local(a&3, d&0xff, 0)&1; return; } // FM Sound if ((a&0xff4000)==0xa00000) { // Z80 ram (MSB only) if (!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)(d>>8); - else elprintf(EL_ANOMALY, "68k z80 write with no bus! [%06x] %02x @ %06x", a, d, SekPc); + else elprintf(EL_ANOMALY, "68k z80 write with no bus! [%06x] %02x @ %06x", a, d&0xffff, SekPc); return; } if (a==0xa11200) { @@ -229,6 +219,7 @@ void OtherWrite16(u32 a,u32 d) Pico.m.z80_reset = 0; YM2612ResetChip(); z80_reset(); + timers_reset(); } return; } @@ -256,6 +247,6 @@ void OtherWrite16(u32 a,u32 d) } #endif - PicoWrite16Hook(a, d, 16); + PicoWrite16Hook(a, d&0xffff, 16); } diff --git a/Pico/Pico.c b/Pico/Pico.c index d206fcb..93d04e7 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -19,7 +19,6 @@ int PicoPad[2]; // Joypads, format is SACB RLDU int PicoAHW = 0; // active addon hardware: scd_active, 32x_active, svp_active, pico_active int PicoRegionOverride = 0; // override the region detection 0: Auto, 1: Japan NTSC, 2: Japan PAL, 4: US, 8: Europe int PicoAutoRgnOrder = 0; -int z80startCycle, z80stopCycle; // in 68k cycles struct PicoSRAM SRam = {0,}; void (*PicoWriteSound)(int len) = NULL; // called at the best time to send sound buffer (PsndOut) to hardware @@ -307,62 +306,54 @@ static __inline void getSamples(int y) #include "PicoFrameHints.c" -// 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 z80stopCycle; +int z80_cycle_cnt; /* 'done' z80 cycles before z80_run() */ +int z80_cycle_aim; +int z80_scanline; +int z80_scanline_cycles; /* cycles done until z80_scanline */ + +/* sync z80 to 68k */ +PICO_INTERNAL void PicoSyncZ80(int m68k_cycles_done) { - int line_from_r=line_from, line_to_r=line_to, line=0; - int line_sample = Pico.m.pal ? 68 : 93; - - if (!(PicoOpt&POPT_EN_Z80) || 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(); - } + int cnt; + z80_cycle_aim = cycles_68k_to_z80(m68k_cycles_done); + cnt = z80_cycle_aim - z80_cycle_cnt; - if (PicoOpt&POPT_EN_FM) { - // we have ym2612 enabled, so we have to run Z80 in lines, so we could update DAC and timers - for (line = line_from; line < line_to; line++) { - Psnd_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) - z80_run_nr(228); - } - } else if (line_to_r-line_from_r > 0) { - z80_run_nr(228*(line_to_r-line_from_r)); - // samples will be taken by caller - } + elprintf(EL_ANOMALY, "z80 sync %i (%i|%i -> %i|%i)", cnt, z80_cycle_cnt, z80_cycle_cnt / 228, + z80_cycle_aim, z80_cycle_aim / 228); + + if (cnt > 0) + z80_cycle_cnt += z80_run(cnt); } + // Simple frame without H-Ints static int PicoFrameSimple(void) { struct PicoVideo *pv=&Pico.video; - int y=0,line=0,lines=0,lines_step=0,sects; + int y=0,lines_step=0,sects,line_last; int cycles_68k_vblock,cycles_68k_block; // split to 16 run calls for active scan, for vblank split to 2 (ntsc), 3 (pal 240), 4 (pal 224) - if (Pico.m.pal && (pv->reg[1]&8)) { + if (Pico.m.pal) + { if(pv->reg[1]&8) { // 240 lines - cycles_68k_block = 7329; // (488*240+148)/16.0, -4 - cycles_68k_vblock = 11640; // (72*488-148-68)/3.0, 0 + cycles_68k_block = 7308; + cycles_68k_vblock = 11694; lines_step = 15; } else { - cycles_68k_block = 6841; // (488*224+148)/16.0, -4 - cycles_68k_vblock = 10682; // (88*488-148-68)/4.0, 0 + cycles_68k_block = 6821; + cycles_68k_vblock = 10719; lines_step = 14; } + line_last = 312-1; } else { // M68k cycles/frame: 127840.71 cycles_68k_block = 6841; // (488*224+148)/16.0, -4 cycles_68k_vblock = 9164; // (38*488-148-68)/2.0, 0 lines_step = 14; + line_last = 262-1; } // a hack for VR, to get it running in fast mode @@ -380,9 +371,11 @@ static int PicoFrameSimple(void) Pico.video.status|=0x200; Pico.m.scanline=-1; - z80startCycle=0; + PsndDacLine = 0; SekCyclesReset(); + z80_resetCycles(); + timers_cycle(); // 6 button pad: let's just say it timed out now Pico.m.padTHPhase[0]=Pico.m.padTHPhase[1]=0; @@ -391,28 +384,19 @@ static int PicoFrameSimple(void) pv->status&=~0x88; // clear V-Int, come out of vblank // Run in sections: - for(sects=16; sects; sects--) + for (sects=16; sects; sects--) { if (CheckIdle()) break; - lines += lines_step; SekRunM68k(cycles_68k_block); - - PicoRunZ80Simple(line, lines); if (PicoLineHook) PicoLineHook(lines_step); - line=lines; } - // run Z80 for remaining sections - if(sects) { - int c = sects*cycles_68k_block; - - // this "run" is for approriate line counter, etc - SekCycleCnt += c; - SekCycleAim += c; + // do remaining sections without 68k + if (sects) { + SekCycleCnt += sects * cycles_68k_block; + SekCycleAim += sects * cycles_68k_block; - lines += sects*lines_step; - PicoRunZ80Simple(line, lines); if (PicoLineHook) PicoLineHook(sects*lines_step); } @@ -446,33 +430,37 @@ static int PicoFrameSimple(void) #endif } - // here we render sound if ym2612 is disabled - if (!(PicoOpt&POPT_EN_FM) && PsndOut) { - int len = PsndRender(0, PsndLen); - if (PicoWriteSound) PicoWriteSound(len); - // clear sound buffer - PsndClear(); - } - // a gap between flags set and vint pv->pending_ints|=0x20; pv->status|=8; // go into vblank SekRunM68k(68+4); + if (Pico.m.z80Run && (PicoOpt&POPT_EN_Z80)) + PicoSyncZ80(SekCycleCnt); + + // render sound + if (PsndOut) + { + int len; + if (ym2612.dacen && PsndDacLine <= lines_step*16) + PsndDoDAC(lines_step*16); + len = PsndRender(0, PsndLen); + if (PicoWriteSound) PicoWriteSound(len); + // clear sound buffer + PsndClear(); + } + // ---- V-Blanking period ---- // fix line counts if(Pico.m.pal) { if(pv->reg[1]&8) { // 240 lines - lines = line = 240; sects = 3; lines_step = 24; } else { - lines = line = 224; sects = 4; lines_step = 22; } } else { - lines = line = 224; sects = 2; lines_step = 19; } @@ -481,27 +469,28 @@ static int PicoFrameSimple(void) if (Pico.m.z80Run && (PicoOpt&POPT_EN_Z80)) z80_int(); - while (sects) + while (1) { - lines += lines_step; - SekRunM68k(cycles_68k_vblock); - - PicoRunZ80Simple(line, lines); if (PicoLineHook) PicoLineHook(lines_step); - line=lines; sects--; - if (sects && CheckIdle()) break; + if (sects == 0) break; + if (CheckIdle()) break; } - // run Z80 for remaining sections if (sects) { - lines += sects*lines_step; - PicoRunZ80Simple(line, lines); + SekCycleCnt += sects * cycles_68k_vblock; + SekCycleAim += sects * cycles_68k_vblock; if (PicoLineHook) PicoLineHook(sects*lines_step); } + // must sync z80 before return, and extend last DAC sample + if (Pico.m.z80Run && (PicoOpt&POPT_EN_Z80)) + PicoSyncZ80(SekCycleCnt); + if (PsndOut && ym2612.dacen && PsndDacLine <= line_last) + PsndDoDAC(line_last); + return 0; } @@ -556,7 +545,6 @@ void PicoGetInternal(pint_t which, pint_ret_t *r) void (*PicoMessage)(const char *msg)=NULL; #if 1 // defined(__DEBUG_PRINT) -// tmp debug: dump some stuff #define bit(r, x) ((r>>x)&1) void z80_debug(char *dstr); char *debugString(void) diff --git a/Pico/PicoFrameHints.c b/Pico/PicoFrameHints.c index d1efa9a..0d414b2 100644 --- a/Pico/PicoFrameHints.c +++ b/Pico/PicoFrameHints.c @@ -16,29 +16,10 @@ if(Pico.m.padDelay[1]++ > 25) Pico.m.padTHPhase[1]=0; \ } -#define Z80_RUN(z80_cycles) \ -{ \ - if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run) \ - { \ - int cnt; \ - if (Pico.m.z80Run & 2) z80CycleAim += z80_cycles; \ - else { \ - cnt = SekCyclesDone() - z80startCycle; \ - cnt = (cnt>>1)-(cnt>>5); \ - if (cnt < 0 || cnt > (z80_cycles)) cnt = z80_cycles; \ - Pico.m.z80Run |= 2; \ - z80CycleAim+=cnt; \ - } \ - cnt=z80CycleAim-total_z80; \ - if (cnt > 0) total_z80+=z80_run(cnt); \ - } \ -} - // CPUS_RUN #ifndef PICO_CD #define CPUS_RUN(m68k_cycles,z80_cycles,s68k_cycles) \ - SekRunM68k(m68k_cycles); \ - Z80_RUN(z80_cycles); + SekRunM68k(m68k_cycles); #else #define CPUS_RUN(m68k_cycles,z80_cycles,s68k_cycles) \ { \ @@ -49,7 +30,6 @@ if ((Pico_mcd->m.busreq&3) == 1) /* no busreq/no reset */ \ SekRunS68k(s68k_cycles); \ } \ - Z80_RUN(z80_cycles); \ } #endif @@ -57,7 +37,7 @@ static int PicoFrameHints(void) { struct PicoVideo *pv=&Pico.video; - int lines, y, lines_vis = 224, total_z80 = 0, z80CycleAim = 0, line_sample, skip; + int lines, y, lines_vis = 224, line_sample, skip; int hint; // Hint counter if ((PicoOpt&POPT_ALT_RENDERER) && !PicoSkipFrame && (pv->reg[1]&0x40)) { // fast rend., display enabled @@ -72,20 +52,19 @@ static int PicoFrameHints(void) else skip=PicoSkipFrame; if (Pico.m.pal) { - //cycles_68k = (int) ((double) OSC_PAL / 7 / 50 / 312 + 0.4); // should compile to a constant (488) - //cycles_z80 = (int) ((double) OSC_PAL / 15 / 50 / 312 + 0.4); // 228 line_sample = 68; if(pv->reg[1]&8) lines_vis = 240; } else { - //cycles_68k = (int) ((double) OSC_NTSC / 7 / 60 / 262 + 0.4); // 488 - //cycles_z80 = (int) ((double) OSC_NTSC / 15 / 60 / 262 + 0.4); // 228 line_sample = 93; } SekCyclesReset(); + z80_resetCycles(); #ifdef PICO_CD SekCyclesResetS68k(); #endif + timers_cycle(); + PsndDacLine = 0; pv->status&=~0x88; // clear V-Int, come out of vblank @@ -93,8 +72,6 @@ static int PicoFrameHints(void) //dprintf("-hint: %i", hint); // This is to make active scan longer (needed for Double Dragon 2, mainly) - // also trying to adjust for z80 overclock here (due to int line cycle counts) - z80CycleAim = Pico.m.pal ? -40 : 7; CPUS_RUN(CYCLES_M68K_ASD, 0, CYCLES_S68K_ASD); for (y=0;yreg[1]&0x20) { elprintf(EL_INTS, "vint: @ %06x [%i]", SekPc, SekCycleCnt); SekInterrupt(6); } if (Pico.m.z80Run && (PicoOpt&POPT_EN_Z80)) { + PicoSyncZ80(SekCycleCnt); elprintf(EL_INTS, "zint"); z80_int(); } - if (PicoOpt&POPT_EN_FM) - Psnd_timers_and_dac(y); - // get samples from sound chips #ifndef PICO_CD if (y == 224) #endif if (PsndOut) + { + if (ym2612.dacen && PsndDacLine <= y) + PsndDoDAC(y); getSamples(y); + } // Run scanline: if (Pico.m.dma_xfers) SekCyclesBurn(CheckDMA()); @@ -247,9 +230,6 @@ static int PicoFrameHints(void) check_cd_dma(); #endif - if (PicoOpt&POPT_EN_FM) - Psnd_timers_and_dac(y); - // Run scanline: if (Pico.m.dma_xfers) SekCyclesBurn(CheckDMA()); CPUS_RUN(CYCLES_M68K_LINE, CYCLES_Z80_LINE, CYCLES_S68K_LINE); @@ -261,6 +241,12 @@ static int PicoFrameHints(void) #endif } + // sync z80 + if (Pico.m.z80Run && (PicoOpt&POPT_EN_Z80)) + PicoSyncZ80(SekCycleCnt); + if (PsndOut && ym2612.dacen && PsndDacLine <= lines-1) + PsndDoDAC(lines-1); + return 0; } diff --git a/Pico/PicoInt.h b/Pico/PicoInt.h index d348598..8525198 100644 --- a/Pico/PicoInt.h +++ b/Pico/PicoInt.h @@ -137,7 +137,7 @@ extern unsigned int SekCycleCntT; // total cycle counter, updated once per frame SekCycleAim=0; \ } #define SekCyclesBurn(c) SekCycleCnt+=c -#define SekCyclesDone() (SekCycleAim-SekCyclesLeft) // nuber of cycles done in this frame (can be checked anywhere) +#define SekCyclesDone() (SekCycleAim-SekCyclesLeft) // number of cycles done in this frame (can be checked anywhere) #define SekCyclesDoneT() (SekCycleCntT+SekCyclesDone()) // total nuber of cycles done for this rom #define SekEndRun(after) { \ @@ -174,10 +174,9 @@ extern int dbg_irq_level; #if defined(_USE_MZ80) #include "../cpu/mz80/mz80.h" -#define z80_run(cycles) mz80_run(cycles) +#define z80_run(cycles) { mz80GetElapsedTicks(1); mz80_run(cycles) } #define z80_run_nr(cycles) mz80_run(cycles) #define z80_int() mz80int(0) -#define z80_resetCycles() mz80GetElapsedTicks(1) #elif defined(_USE_DRZ80) #include "../cpu/DrZ80/drz80.h" @@ -190,7 +189,8 @@ extern struct DrZ80 drZ80; drZ80.z80irqvector = 0xFF; /* default IRQ vector RST opcode */ \ drZ80.Z80_IRQ = 1; \ } -#define z80_resetCycles() + +#define z80_cyclesLeft drZ80.cycles #elif defined(_USE_CZ80) #include "../cpu/cz80/cz80.h" @@ -198,17 +198,31 @@ extern struct DrZ80 drZ80; #define z80_run(cycles) Cz80_Exec(&CZ80, cycles) #define z80_run_nr(cycles) Cz80_Exec(&CZ80, cycles) #define z80_int() Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE) -#define z80_resetCycles() + +#define z80_cyclesLeft (CZ80.ICount - CZ80.ExtraCycles) #else #define z80_run(cycles) (cycles) #define z80_run_nr(cycles) #define z80_int() -#define z80_resetCycles() #endif +extern int z80stopCycle; /* in 68k cycles */ +extern int z80_cycle_cnt; /* 'done' z80 cycles before z80_run() */ +extern int z80_cycle_aim; +extern int z80_scanline; +extern int z80_scanline_cycles; /* cycles done until z80_scanline */ + +#define z80_resetCycles() \ + z80_cycle_cnt = z80_cycle_aim = z80_scanline = z80_scanline_cycles = 0; + +#define z80_cyclesDone() \ + (z80_cycle_aim - z80_cyclesLeft) + +#define cycles_68k_to_z80(x) ((x)*957 >> 11) + // --------------------------------------------------------- // main oscillator clock which controls timing @@ -405,6 +419,7 @@ PICO_INTERNAL unsigned short z80_read16(unsigned short a); #else PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data); #endif +PICO_INTERNAL int ym2612_write_local(unsigned int a, unsigned int d, int is_from_z80); extern unsigned int (*PicoRead16Hook)(unsigned int a, int realsize); extern void (*PicoWrite8Hook) (unsigned int a,unsigned int d,int realsize); extern void (*PicoWrite16Hook)(unsigned int a,unsigned int d,int realsize); @@ -421,11 +436,11 @@ PICO_INTERNAL void PicoMemSetupPico(void); extern struct Pico Pico; extern struct PicoSRAM SRam; extern int emustatus; -extern int z80startCycle, z80stopCycle; // in 68k cycles extern void (*PicoResetHook)(void); extern void (*PicoLineHook)(int count); PICO_INTERNAL int CheckDMA(void); PICO_INTERNAL void PicoDetectRegion(void); +PICO_INTERNAL void PicoSyncZ80(int m68k_cycles_done); // cd/Pico.c PICO_INTERNAL int PicoInitMCD(void); @@ -459,6 +474,13 @@ PICO_INTERNAL void cdda_start_play(); extern short cdda_out_buffer[2*1152]; extern int PsndLen_exc_cnt; extern int PsndLen_exc_add; +extern int timer_a_next_oflow, timer_a_step; // in z80 cycles + +#define timers_cycle() \ + if (timer_a_next_oflow > 0) timer_a_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256 + +#define timers_reset() \ + timer_a_next_oflow = 0x80000000 // VideoPort.c PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d); @@ -483,7 +505,7 @@ PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba); // sound/sound.c PICO_INTERNAL void PsndReset(void); -PICO_INTERNAL void Psnd_timers_and_dac(int raster); +PICO_INTERNAL void PsndDoDAC(int line_to); PICO_INTERNAL int PsndRender(int offset, int length); PICO_INTERNAL void PsndClear(void); // z80 functionality wrappers @@ -492,7 +514,7 @@ PICO_INTERNAL void z80_pack(unsigned char *data); PICO_INTERNAL void z80_unpack(unsigned char *data); PICO_INTERNAL void z80_reset(void); PICO_INTERNAL void z80_exit(void); - +extern int PsndDacLine; #ifdef __cplusplus } // End of extern "C" diff --git a/Pico/sound/sound.c b/Pico/sound/sound.c index 1d6c168..6c7c6d8 100644 --- a/Pico/sound/sound.c +++ b/Pico/sound/sound.c @@ -21,7 +21,7 @@ void (*PsndMix_32_to_16l)(short *dest, int *src, int count) = mix_32_to_16l_ster static int PsndBuffer[2*44100/50]; // dac -static unsigned short dac_info[312]; // pppppppp ppppllll, p - pos in buff, l - length to write for this sample +static unsigned short dac_info[312+4]; // pppppppp ppppllll, p - pos in buff, l - length to write for this sample // cdda output buffer short cdda_out_buffer[2*1152]; @@ -31,8 +31,13 @@ int PsndRate=0; int PsndLen=0; // number of mono samples, multiply by 2 for stereo int PsndLen_exc_add=0; // this is for non-integer sample counts per line, eg. 22050/60 int PsndLen_exc_cnt=0; +int PsndDacLine=0; short *PsndOut=NULL; // PCM data buffer +// timers +int timer_a_next_oflow, timer_a_step; // in z80 cycles +//int + // sn76496 extern int *sn76496_regs; @@ -83,6 +88,8 @@ static void dac_recalculate(void) if (PsndLen_exc_add) len++; dac_info[224] = (pos<<4)|len; } + for (i = lines; i < sizeof(dac_info) / sizeof(dac_info[0]); i++) + dac_info[i] = 0; //for(i=len=0; i < lines; i++) { // printf("%03i : %03i : %i\n", i, dac_info[i]>>4, dac_info[i]&0xf); // len+=dac_info[i]&0xf; @@ -100,7 +107,7 @@ PICO_INTERNAL void PsndReset(void) // also clear the internal registers+addr line ym2612_regs = YM2612GetRegs(); memset(ym2612_regs, 0, 0x200+4); - z80startCycle = z80stopCycle = 0; + timers_reset(); PsndRerate(0); } @@ -164,44 +171,25 @@ void PsndRerate(int preserve_state) } -// This is called once per raster (aka line), but not necessarily for every line -PICO_INTERNAL void Psnd_timers_and_dac(int raster) +PICO_INTERNAL void PsndDoDAC(int line_to) { - int pos, len; - int do_dac = PsndOut && (PicoOpt&POPT_EN_FM) && *ym2612_dacen; -// int do_pcm = PsndOut && (PicoAHW&1) && (PicoOpt&0x400); - - // Our raster lasts 63.61323/64.102564 microseconds (NTSC/PAL) - YM2612PicoTick(1); + int pos, pos1, len; + int dout = ym2612.dacout; + int line_from = PsndDacLine; - if (!do_dac /*&& !do_pcm*/) return; + PsndDacLine = line_to + 1; - pos=dac_info[raster], len=pos&0xf; + pos =dac_info[line_from]>>4; + pos1=dac_info[line_to]; + len = ((pos1>>4)-pos) + (pos1&0xf); if (!len) return; - pos>>=4; - - if (do_dac) - { + if (PicoOpt & POPT_EN_STEREO) { short *d = PsndOut + pos*2; - int dout = *ym2612_dacout; - if(PicoOpt&POPT_EN_STEREO) { - // some manual loop unrolling here :) - d[0] = dout; - if (len > 1) { - d[2] = dout; - if (len > 2) - d[4] = dout; - } - } else { - short *d = PsndOut + pos; - d[0] = dout; - if (len > 1) { - d[1] = dout; - if (len > 2) - d[2] = dout; - } - } + for (; len > 0; len--, d+=2) *d = dout; + } else { + short *d = PsndOut + pos; + for (; len > 0; len--, d++) *d = dout; } #if 0 diff --git a/Pico/sound/ym2612.c b/Pico/sound/ym2612.c index 144c334..b9749f2 100644 --- a/Pico/sound/ym2612.c +++ b/Pico/sound/ym2612.c @@ -116,7 +116,7 @@ #ifndef EXTERNAL_YM2612 #include // let it be 1 global to simplify things -static YM2612 ym2612; +YM2612 ym2612; #else extern YM2612 *ym2612_940; @@ -1584,11 +1584,8 @@ static int OPNWriteReg(int r, int v) /* YM2612 local section */ /*******************************************************************************/ -int *ym2612_dacen; -INT32 *ym2612_dacout; FM_ST *ym2612_st; - /* Generate samples for YM2612 */ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty) { @@ -1654,8 +1651,6 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty) void YM2612Init_(int clock, int rate) { // notaz - ym2612_dacen = &ym2612.dacen; - ym2612_dacout = &ym2612.dacout; ym2612_st = &ym2612.OPN.ST; memset(&ym2612, 0, sizeof(ym2612)); @@ -1728,9 +1723,6 @@ int YM2612Write_(unsigned int a, unsigned int v) } addr = ym2612.OPN.ST.address; -#ifndef EXTERNAL_YM2612 - ym2612.REGS[addr] = v; -#endif switch( addr & 0xf0 ) { @@ -1747,6 +1739,7 @@ int YM2612Write_(unsigned int a, unsigned int v) ym2612.OPN.lfo_inc = 0; } break; +#if 0 // handled elsewhere case 0x24: { // timer A High 8 int TAnew = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2); if(ym2612.OPN.ST.TA != TAnew) { @@ -1781,6 +1774,7 @@ int YM2612Write_(unsigned int a, unsigned int v) set_timers( v ); ret=0; break; +#endif case 0x28: /* key on / off */ { UINT8 c; @@ -1794,6 +1788,7 @@ int YM2612Write_(unsigned int a, unsigned int v) if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4); break; } +#if 0 case 0x2a: /* DAC data (YM2612) */ ym2612.dacout = ((int)v - 0x80) << 6; /* level unknown (notaz: 8 seems to be too much) */ ret=0; @@ -1803,6 +1798,7 @@ int YM2612Write_(unsigned int a, unsigned int v) ym2612.dacen = v & 0x80; ret=0; break; +#endif default: break; } @@ -1826,9 +1822,6 @@ int YM2612Write_(unsigned int a, unsigned int v) } addr = ym2612.OPN.ST.address | 0x100; -#ifndef EXTERNAL_YM2612 - ym2612.REGS[addr] = v; -#endif ret = OPNWriteReg(addr, v); break; diff --git a/Pico/sound/ym2612.h b/Pico/sound/ym2612.h index e87cbc1..39c3cf6 100644 --- a/Pico/sound/ym2612.h +++ b/Pico/sound/ym2612.h @@ -141,10 +141,10 @@ typedef struct } YM2612; #endif -extern int *ym2612_dacen; -extern INT32 *ym2612_dacout; extern FM_ST *ym2612_st; - +#ifndef EXTERNAL_YM2612 +extern YM2612 ym2612; +#endif #define YM2612Read() ym2612_st->status @@ -180,7 +180,6 @@ void *YM2612GetRegs(void); #define YM2612Init YM2612Init_ #define YM2612ResetChip YM2612ResetChip_ #define YM2612UpdateOne YM2612UpdateOne_ -#define YM2612Write YM2612Write_ #define YM2612PicoStateLoad YM2612PicoStateLoad_ #else /* GP2X specific */ @@ -197,8 +196,6 @@ extern int PicoOpt; #define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) \ (PicoOpt&0x200) ? YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty) : \ YM2612UpdateOne_(buffer, length, stereo, is_buf_empty); -#define YM2612Write(a,v) \ - (PicoOpt&0x200) ? YM2612Write_940(a, v) : YM2612Write_(a, v) #define YM2612PicoStateLoad() { \ if (PicoOpt&0x200) YM2612PicoStateLoad_940(); \ else YM2612PicoStateLoad_(); \ diff --git a/platform/gp2x/940ctl.c b/platform/gp2x/940ctl.c index f217dea..8c8b18b 100644 --- a/platform/gp2x/940ctl.c +++ b/platform/gp2x/940ctl.c @@ -51,160 +51,64 @@ static FILE *loaded_mp3 = 0; } /* these will be managed locally on our side */ -static UINT8 *REGS = 0; /* we will also keep local copy of regs for savestates and such */ -static INT32 *addr_A1; /* address line A1 */ - -static int dacen; -static INT32 dacout; static UINT8 ST_address; /* address register */ +static INT32 addr_A1; /* address line A1 */ static int writebuff_ptr = 0; -/* OPN Mode Register Write */ -static int set_timers( int v ) -{ - int change; - - /* b7 = CSM MODE */ - /* b6 = 3 slot mode */ - /* b5 = reset b */ - /* b4 = reset a */ - /* b3 = timer enable b */ - /* b2 = timer enable a */ - /* b1 = load b */ - /* b0 = load a */ - change = (ym2612_st->mode ^ v) & 0xc0; - ym2612_st->mode = v; - - /* reset Timer b flag */ - if( v & 0x20 ) - ym2612_st->status &= ~2; - - /* reset Timer a flag */ - if( v & 0x10 ) - ym2612_st->status &= ~1; - - return change; -} - /* YM2612 write */ /* a = address */ /* v = value */ /* returns 1 if sample affecting state changed */ -int YM2612Write_940(unsigned int a, unsigned int v) +int YM2612Write_940(unsigned int a, unsigned int v, int scanline) { - int addr; int upd = 1; /* the write affects sample generation */ - v &= 0xff; /* adjust to 8 bit bus */ a &= 3; //printf("%05i:%03i: ym w ([%i] %02x)\n", Pico.m.frame_count, Pico.m.scanline, a, v); - switch( a ) { - case 0: /* address port 0 */ - if (!*addr_A1 && ST_address == v) - return 0; /* address already selected, don't send this command to 940 */ - ST_address = v; - /* don't send DAC or timer related address changes to 940 */ - if (!*addr_A1 && (v & 0xf0) == 0x20 && - (v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a)) + switch (a) { + case 0: /* address port 0 */ + if (addr_A1 == 0 && ST_address == v) + return 0; /* address already selected, don't send this command to 940 */ + ST_address = v; + addr_A1 = 0; + /* don't send DAC or timer related address changes to 940 */ + if (v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a) return 0; - *addr_A1 = 0; - upd = 0; - break; - - case 1: /* data port 0 */ - if (*addr_A1 != 0) { - return 0; /* verified on real YM2608 */ - } + upd = 0; + break; - addr = ST_address; - REGS[addr] = v; + case 1: /* data port 0 */ + if (ST_address == 0x2b) upd = 0; /* DAC sel */ + break; - switch( addr & 0xf0 ) - { - case 0x20: /* 0x20-0x2f Mode */ - switch( addr ) - { - case 0x24: { // timer A High 8 - int TAnew = (ym2612_st->TA & 0x03)|(((int)v)<<2); - if (ym2612_st->TA != TAnew) { - // we should reset ticker only if new value is written. Outrun requires this. - ym2612_st->TA = TAnew; - ym2612_st->TAC = (1024-TAnew)*18; - ym2612_st->TAT = 0; - } - return 0; - } - case 0x25: { // timer A Low 2 - int TAnew = (ym2612_st->TA & 0x3fc)|(v&3); - if (ym2612_st->TA != TAnew) { - ym2612_st->TA = TAnew; - ym2612_st->TAC = (1024-TAnew)*18; - ym2612_st->TAT = 0; - } - return 0; - } - case 0x26: // timer B - if (ym2612_st->TB != v) { - ym2612_st->TB = v; - ym2612_st->TBC = (256-v)<<4; - ym2612_st->TBC *= 18; - ym2612_st->TBT = 0; - } - return 0; - case 0x27: /* mode, timer control */ - if (set_timers( v )) - break; // other side needs ST.mode for 3slot mode - return 0; - case 0x2a: /* DAC data (YM2612) */ - dacout = ((int)v - 0x80) << 6; /* level unknown (notaz: 8 seems to be too much) */ + case 2: /* address port 1 */ + if (addr_A1 == 1 && ST_address == v) return 0; - case 0x2b: /* DAC Sel (YM2612) */ - /* b7 = dac enable */ - dacen = v & 0x80; - upd = 0; - break; // other side has to know this - default: - break; - } + ST_address = v; + addr_A1 = 1; + upd = 0; break; - } - break; - - case 2: /* address port 1 */ - if (*addr_A1 && ST_address == v) - return 0; - ST_address = v; - *addr_A1 = 1; - upd = 0; - break; - - case 3: /* data port 1 */ - if (*addr_A1 != 1) { - return 0; /* verified on real YM2608 */ - } - - addr = ST_address | 0x100; - REGS[addr] = v; - break; } //printf("ym pass\n"); - if(currentConfig.EmuOpt & 4) { + if (currentConfig.EmuOpt & 4) + { UINT16 *writebuff = shared_ctl->writebuffsel ? shared_ctl->writebuff0 : shared_ctl->writebuff1; /* detect rapid ym updates */ - if (upd && !(writebuff_ptr & 0x80000000) && Pico.m.scanline < 224) { + if (upd && !(writebuff_ptr & 0x80000000) && scanline < 224) + { int mid = Pico.m.pal ? 68 : 93; - if (Pico.m.scanline > mid) { - //printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, Pico.m.scanline); + if (scanline > mid) { + //printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, scanline); writebuff[writebuff_ptr++ & 0xffff] = 0xfffe; writebuff_ptr |= 0x80000000; - //printf("%05i:%03i: ym w ([%02x] %02x, upd=%i)\n", Pico.m.frame_count, Pico.m.scanline, addr, v, upd); + //printf("%05i:%03i: ym w ([%02x] %02x, upd=%i)\n", Pico.m.frame_count, scanline, addr, v, upd); } } @@ -272,7 +176,9 @@ static void add_job_940(int job) void YM2612PicoStateLoad_940(void) { - int i, old_A1 = *addr_A1; + UINT8 *REGS = YM2612GetRegs(); + + int i; /* make sure JOB940_PICOSTATELOAD gets done before next JOB940_YM2612UPDATEONE */ add_job_940(JOB940_PICOSTATELOAD); @@ -282,32 +188,22 @@ void YM2612PicoStateLoad_940(void) // feed all the registers and update internal state for(i = 0; i < 0x100; i++) { - YM2612Write_940(0, i); - YM2612Write_940(1, REGS[i]); + YM2612Write_940(0, i, -1); + YM2612Write_940(1, REGS[i], -1); } for(i = 0; i < 0x100; i++) { - YM2612Write_940(2, i); - YM2612Write_940(3, REGS[i|0x100]); + YM2612Write_940(2, i, -1); + YM2612Write_940(3, REGS[i|0x100], -1); } - *addr_A1 = old_A1; + addr_A1 = *(INT32 *) (REGS + 0x200); } static void internal_reset(void) { writebuff_ptr = 0; - ym2612_st->mode = 0; - ym2612_st->status = 0; /* normal mode */ - ym2612_st->TA = 0; - ym2612_st->TAC = 0; - ym2612_st->TAT = 0; - ym2612_st->TB = 0; - ym2612_st->TBC = 0; - ym2612_st->TBT = 0; - dacen = 0; - dacout = 0; - ST_address= 0; + ST_address = addr_A1 = -1; } @@ -405,12 +301,6 @@ void YM2612Init_940(int baseclock, int rate) /* cause local ym2612 to init REGS */ YM2612Init_(baseclock, rate); - REGS = YM2612GetRegs(); - addr_A1 = (INT32 *) (REGS + 0x200); - - ym2612_dacen = &dacen; - ym2612_dacout = &dacout; - internal_reset(); loaded_mp3 = 0; @@ -440,6 +330,7 @@ void YM2612ResetChip_940(void) return; } + YM2612ResetChip_(); internal_reset(); add_job_940(JOB940_YM2612RESETCHIP); diff --git a/platform/gp2x/940ctl.h b/platform/gp2x/940ctl.h index 95e9a07..0318c1c 100644 --- a/platform/gp2x/940ctl.h +++ b/platform/gp2x/940ctl.h @@ -5,7 +5,7 @@ void YM2612Init_940(int baseclock, int rate); void YM2612ResetChip_940(void); int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty); -int YM2612Write_940(unsigned int a, unsigned int v); +int YM2612Write_940(unsigned int a, unsigned int v, int scanline); unsigned char YM2612Read_940(void); int YM2612PicoTick_940(int n); diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 59a7c15..4ebecb4 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -74,7 +74,7 @@ OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pi ../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o endif # Pico - Pico -OBJS += ../../Pico/Pico/Pico.o ../../Pico/Pico/Memory.o +OBJS += ../../Pico/Pico/Pico.o ../../Pico/Pico/Memory.o ../../Pico/Pico/xpcm.o # Pico - carthw OBJS += ../../Pico/carthw/carthw.o ../../Pico/carthw/svp/svp.o ../../Pico/carthw/svp/Memory.o \ ../../Pico/carthw/svp/ssp16.o ../../Pico/carthw/svp/compiler.o ../../Pico/carthw/svp/stub_arm.o @@ -203,6 +203,8 @@ up: PicoDrive.gpe ../../cpu/musashi/m68kops.c : @make -C ../../cpu/musashi +../../Pico/Pico.o : ../../Pico/PicoFrameHints.c ../../Pico/PicoInt.h +../../Pico/Memory.o Pico/cd/Memory.o : ../../Pico/MemoryCmn.c ../../Pico/PicoInt.h # build helix libs ../common/helix/helix_mp3.a: diff --git a/platform/gp2x/version.h b/platform/gp2x/version.h index 848b48b..580a8ae 100644 --- a/platform/gp2x/version.h +++ b/platform/gp2x/version.h @@ -1,2 +1,2 @@ -#define VERSION "1.40c" +#define VERSION "1.45" diff --git a/platform/linux/940ctl_ym2612.c b/platform/linux/940ctl_ym2612.c index 9e07b9f..32e672f 100644 --- a/platform/linux/940ctl_ym2612.c +++ b/platform/linux/940ctl_ym2612.c @@ -17,10 +17,6 @@ #include "../../Pico/PicoInt.h" -static YM2612 ym2612; - -YM2612 *ym2612_940 = &ym2612; - // static _940_data_t shared_data_; static _940_ctl_t shared_ctl_; // static _940_data_t *shared_data = &shared_data_; @@ -33,7 +29,7 @@ unsigned char *mp3_mem = 0; /***********************************************************/ -int YM2612Write_940(unsigned int a, unsigned int v) +int YM2612Write_940(unsigned int a, unsigned int v, int scanline) { YM2612Write_(a, v); diff --git a/platform/linux/Makefile b/platform/linux/Makefile index e3c89fc..cafe81e 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -99,8 +99,8 @@ mkdirs: mkdir -p $(DIRS) Pico/carthw/svp/compiler.o : ../../Pico/carthw/svp/gen_arm.c - -Pico/Pico.o : ../../Pico/PicoFrameHints.c +Pico/Pico.o : ../../Pico/PicoFrameHints.c ../../Pico/PicoInt.h +Pico/Memory.o Pico/cd/Memory.o : ../../Pico/MemoryCmn.c ../../Pico/PicoInt.h ../../cpu/musashi/m68kops.c : @make -C ../../cpu/musashi -- 2.39.2