new z80 scheduling method, timers are still wip

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@459 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-05-25 21:25:46 +00:00
parent 170435846c
commit 4b9c588826
15 changed files with 377 additions and 364 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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;
int cnt;
z80_cycle_aim = cycles_68k_to_z80(m68k_cycles_done);
cnt = z80_cycle_aim - z80_cycle_cnt;
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();
}
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 (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
}
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;
// do remaining sections without 68k
if (sects) {
SekCycleCnt += sects * cycles_68k_block;
SekCycleAim += sects * cycles_68k_block;
// this "run" is for approriate line counter, etc
SekCycleCnt += c;
SekCycleAim += c;
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)

View file

@ -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;y<lines_vis;y++)
@ -148,15 +125,18 @@ static int PicoFrameHints(void)
}
}
if (PicoOpt&POPT_EN_FM)
Psnd_timers_and_dac(y);
#ifndef PICO_CD
// get samples from sound chips
if (y == 32 && PsndOut)
emustatus &= ~1;
else if ((y == 224 || y == line_sample) && PsndOut)
{
if (Pico.m.z80Run && (PicoOpt&POPT_EN_Z80))
PicoSyncZ80(SekCycleCnt);
if (ym2612.dacen && PsndDacLine <= y)
PsndDoDAC(y);
getSamples(y);
}
#endif
// Run scanline:
@ -205,24 +185,27 @@ static int PicoFrameHints(void)
// also delay between F bit (bit 7) is set in SR and IRQ happens (Ex-Mutants)
// also delay between last H-int and V-int (Golden Axe 3)
SekRunM68k(CYCLES_M68K_VINT_LAG);
if (pv->reg[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;
}

View file

@ -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"

View file

@ -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);
int pos, pos1, len;
int dout = ym2612.dacout;
int line_from = PsndDacLine;
// Our raster lasts 63.61323/64.102564 microseconds (NTSC/PAL)
YM2612PicoTick(1);
PsndDacLine = line_to + 1;
if (!do_dac /*&& !do_pcm*/) return;
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;
}
for (; len > 0; len--, d+=2) *d = 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++) *d = dout;
}
#if 0

View file

@ -116,7 +116,7 @@
#ifndef EXTERNAL_YM2612
#include <stdlib.h>
// 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;

View file

@ -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_(); \

View file

@ -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 ) {
switch (a) {
case 0: /* address port 0 */
if (!*addr_A1 && ST_address == v)
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 (!*addr_A1 && (v & 0xf0) == 0x20 &&
(v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a))
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 */
}
addr = ST_address;
REGS[addr] = v;
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) */
return 0;
case 0x2b: /* DAC Sel (YM2612) */
/* b7 = dac enable */
dacen = v & 0x80;
upd = 0;
break; // other side has to know this
default:
break;
}
break;
}
if (ST_address == 0x2b) upd = 0; /* DAC sel */
break;
case 2: /* address port 1 */
if (*addr_A1 && ST_address == v)
if (addr_A1 == 1 && ST_address == v)
return 0;
ST_address = v;
*addr_A1 = 1;
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);

View file

@ -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);

View file

@ -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:

View file

@ -1,2 +1,2 @@
#define VERSION "1.40c"
#define VERSION "1.45"

View file

@ -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);

View file

@ -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