mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
move more globals to PicoInterface
similar reasons as before
This commit is contained in:
parent
075672bf9f
commit
6311a3baf5
27 changed files with 244 additions and 247 deletions
|
@ -391,8 +391,8 @@ int pm_seek(pm_file *stream, long offset, int whence)
|
|||
offset = pos;
|
||||
}
|
||||
|
||||
if (PicoMessage != NULL && offset > 4 * 1024 * 1024)
|
||||
PicoMessage("Decompressing data...");
|
||||
if (PicoIn.osdMessage != NULL && offset > 4 * 1024 * 1024)
|
||||
PicoIn.osdMessage("Decompressing data...");
|
||||
|
||||
while (offset > 0) {
|
||||
char buf[16 * 1024];
|
||||
|
|
|
@ -1297,8 +1297,8 @@ void cdd_process(void)
|
|||
set_reg16(0x3e, 0x0000);
|
||||
set_reg16(0x40, 0x000f);
|
||||
|
||||
if (PicoMCDcloseTray)
|
||||
PicoMCDcloseTray();
|
||||
if (PicoIn.mcdTrayClose)
|
||||
PicoIn.mcdTrayClose();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1316,8 +1316,8 @@ void cdd_process(void)
|
|||
set_reg16(0x3e, 0x0000);
|
||||
set_reg16(0x40, ~CD_OPEN & 0x0f);
|
||||
|
||||
if (PicoMCDopenTray)
|
||||
PicoMCDopenTray();
|
||||
if (PicoIn.mcdTrayOpen)
|
||||
PicoIn.mcdTrayOpen();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,6 @@ static unsigned int mcd_m68k_cycle_mult;
|
|||
static unsigned int mcd_m68k_cycle_base;
|
||||
static unsigned int mcd_s68k_cycle_base;
|
||||
|
||||
void (*PicoMCDopenTray)(void) = NULL;
|
||||
void (*PicoMCDcloseTray)(void) = NULL;
|
||||
|
||||
|
||||
PICO_INTERNAL void PicoInitMCD(void)
|
||||
{
|
||||
|
|
|
@ -387,14 +387,14 @@ void PDebugZ80Frame(void)
|
|||
|
||||
if (/*Pico.m.z80Run &&*/ !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80))
|
||||
PicoSyncZ80(Pico.t.m68c_cnt + line_sample * 488);
|
||||
if (PsndOut)
|
||||
if (PicoIn.sndOut)
|
||||
PsndGetSamples(line_sample);
|
||||
|
||||
if (/*Pico.m.z80Run &&*/ !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80)) {
|
||||
PicoSyncZ80(Pico.t.m68c_cnt + 224 * 488);
|
||||
z80_int();
|
||||
}
|
||||
if (PsndOut)
|
||||
if (PicoIn.sndOut)
|
||||
PsndGetSamples(224);
|
||||
|
||||
// sync z80
|
||||
|
@ -402,7 +402,7 @@ void PDebugZ80Frame(void)
|
|||
Pico.t.m68c_cnt += Pico.m.pal ? 151809 : 127671; // cycles adjusted for converter
|
||||
PicoSyncZ80(Pico.t.m68c_cnt);
|
||||
}
|
||||
if (PsndOut && ym2612.dacen && PsndDacLine < lines)
|
||||
if (PicoIn.sndOut && ym2612.dacen && Pico.snd.dac_line < lines)
|
||||
PsndDoDAC(lines - 1);
|
||||
PsndDoPSG(lines - 1);
|
||||
|
||||
|
|
|
@ -389,7 +389,7 @@ static int get_scanline(int is_from_z80);
|
|||
static void psg_write_68k(u32 d)
|
||||
{
|
||||
// look for volume write and update if needed
|
||||
if ((d & 0x90) == 0x90 && PsndPsgLine < Pico.m.scanline)
|
||||
if ((d & 0x90) == 0x90 && Pico.snd.psg_line < Pico.m.scanline)
|
||||
PsndDoPSG(Pico.m.scanline);
|
||||
|
||||
SN76496Write(d);
|
||||
|
@ -399,7 +399,7 @@ static void psg_write_z80(u32 d)
|
|||
{
|
||||
if ((d & 0x90) == 0x90) {
|
||||
int scanline = get_scanline(1);
|
||||
if (PsndPsgLine < scanline)
|
||||
if (Pico.snd.psg_line < scanline)
|
||||
PsndDoPSG(scanline);
|
||||
}
|
||||
|
||||
|
@ -895,41 +895,41 @@ void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new)
|
|||
int xcycles = z80_cycles << 8;
|
||||
|
||||
/* check for overflows */
|
||||
if ((mode_old & 4) && xcycles > timer_a_next_oflow)
|
||||
if ((mode_old & 4) && xcycles > Pico.t.timer_a_next_oflow)
|
||||
ym2612.OPN.ST.status |= 1;
|
||||
|
||||
if ((mode_old & 8) && xcycles > timer_b_next_oflow)
|
||||
if ((mode_old & 8) && xcycles > Pico.t.timer_b_next_oflow)
|
||||
ym2612.OPN.ST.status |= 2;
|
||||
|
||||
/* update timer a */
|
||||
if (mode_old & 1)
|
||||
while (xcycles > timer_a_next_oflow)
|
||||
timer_a_next_oflow += timer_a_step;
|
||||
while (xcycles > Pico.t.timer_a_next_oflow)
|
||||
Pico.t.timer_a_next_oflow += Pico.t.timer_a_step;
|
||||
|
||||
if ((mode_old ^ mode_new) & 1) // turning on/off
|
||||
{
|
||||
if (mode_old & 1)
|
||||
timer_a_next_oflow = TIMER_NO_OFLOW;
|
||||
Pico.t.timer_a_next_oflow = TIMER_NO_OFLOW;
|
||||
else
|
||||
timer_a_next_oflow = xcycles + timer_a_step;
|
||||
Pico.t.timer_a_next_oflow = xcycles + Pico.t.timer_a_step;
|
||||
}
|
||||
if (mode_new & 1)
|
||||
elprintf(EL_YMTIMER, "timer a upd to %i @ %i", timer_a_next_oflow>>8, z80_cycles);
|
||||
elprintf(EL_YMTIMER, "timer a upd to %i @ %i", Pico.t.timer_a_next_oflow>>8, z80_cycles);
|
||||
|
||||
/* update timer b */
|
||||
if (mode_old & 2)
|
||||
while (xcycles > timer_b_next_oflow)
|
||||
timer_b_next_oflow += timer_b_step;
|
||||
while (xcycles > Pico.t.timer_b_next_oflow)
|
||||
Pico.t.timer_b_next_oflow += Pico.t.timer_b_step;
|
||||
|
||||
if ((mode_old ^ mode_new) & 2)
|
||||
{
|
||||
if (mode_old & 2)
|
||||
timer_b_next_oflow = TIMER_NO_OFLOW;
|
||||
Pico.t.timer_b_next_oflow = TIMER_NO_OFLOW;
|
||||
else
|
||||
timer_b_next_oflow = xcycles + timer_b_step;
|
||||
Pico.t.timer_b_next_oflow = xcycles + Pico.t.timer_b_step;
|
||||
}
|
||||
if (mode_new & 2)
|
||||
elprintf(EL_YMTIMER, "timer b upd to %i @ %i", timer_b_next_oflow>>8, z80_cycles);
|
||||
elprintf(EL_YMTIMER, "timer b upd to %i @ %i", Pico.t.timer_b_next_oflow>>8, z80_cycles);
|
||||
}
|
||||
|
||||
// ym2612 DAC and timer I/O handlers for z80
|
||||
|
@ -941,7 +941,7 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
|
|||
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);
|
||||
//elprintf(EL_STATUS, "%03i -> %03i dac w %08x z80 %i", Pico.snd.dac_line, scanline, d, is_from_z80);
|
||||
ym2612.dacout = ((int)d - 0x80) << 6;
|
||||
if (ym2612.dacen)
|
||||
PsndDoDAC(scanline);
|
||||
|
@ -977,13 +977,13 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
|
|||
ym2612.OPN.ST.TA = TAnew;
|
||||
//ym2612.OPN.ST.TAC = (1024-TAnew)*18;
|
||||
//ym2612.OPN.ST.TAT = 0;
|
||||
timer_a_step = TIMER_A_TICK_ZCYCLES * (1024 - TAnew);
|
||||
Pico.t.timer_a_step = TIMER_A_TICK_ZCYCLES * (1024 - TAnew);
|
||||
if (ym2612.OPN.ST.mode & 1) {
|
||||
// this is not right, should really be done on overflow only
|
||||
int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();
|
||||
timer_a_next_oflow = (cycles << 8) + timer_a_step;
|
||||
Pico.t.timer_a_next_oflow = (cycles << 8) + Pico.t.timer_a_step;
|
||||
}
|
||||
elprintf(EL_YMTIMER, "timer a set to %i, %i", 1024 - TAnew, timer_a_next_oflow>>8);
|
||||
elprintf(EL_YMTIMER, "timer a set to %i, %i", 1024 - TAnew, Pico.t.timer_a_next_oflow>>8);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -993,12 +993,12 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
|
|||
ym2612.OPN.ST.TB = d;
|
||||
//ym2612.OPN.ST.TBC = (256-d) * 288;
|
||||
//ym2612.OPN.ST.TBT = 0;
|
||||
timer_b_step = TIMER_B_TICK_ZCYCLES * (256 - d); // 262800
|
||||
Pico.t.timer_b_step = TIMER_B_TICK_ZCYCLES * (256 - d); // 262800
|
||||
if (ym2612.OPN.ST.mode & 2) {
|
||||
int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();
|
||||
timer_b_next_oflow = (cycles << 8) + timer_b_step;
|
||||
Pico.t.timer_b_next_oflow = (cycles << 8) + Pico.t.timer_b_step;
|
||||
}
|
||||
elprintf(EL_YMTIMER, "timer b set to %i, %i", 256 - d, timer_b_next_oflow>>8);
|
||||
elprintf(EL_YMTIMER, "timer b set to %i, %i", 256 - d, Pico.t.timer_b_next_oflow>>8);
|
||||
}
|
||||
return 0;
|
||||
case 0x27: { /* mode, timer control */
|
||||
|
@ -1029,7 +1029,7 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
|
|||
int scanline = get_scanline(is_from_z80);
|
||||
if (ym2612.dacen != (d & 0x80)) {
|
||||
ym2612.dacen = d & 0x80;
|
||||
PsndDacLine = scanline;
|
||||
Pico.snd.dac_line = scanline;
|
||||
}
|
||||
#ifdef __GP2X__
|
||||
if (PicoIn.opt & POPT_EXT_FM) YM2612Write_940(a, d, scanline);
|
||||
|
@ -1065,9 +1065,9 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
|
|||
|
||||
|
||||
#define ym2612_read_local() \
|
||||
if (xcycles >= timer_a_next_oflow) \
|
||||
if (xcycles >= Pico.t.timer_a_next_oflow) \
|
||||
ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 1; \
|
||||
if (xcycles >= timer_b_next_oflow) \
|
||||
if (xcycles >= Pico.t.timer_b_next_oflow) \
|
||||
ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 2
|
||||
|
||||
static u32 ym2612_read_local_z80(void)
|
||||
|
@ -1076,8 +1076,9 @@ static u32 ym2612_read_local_z80(void)
|
|||
|
||||
ym2612_read_local();
|
||||
|
||||
elprintf(EL_YMTIMER, "timer z80 read %i, sched %i, %i @ %i|%i", ym2612.OPN.ST.status,
|
||||
timer_a_next_oflow>>8, timer_b_next_oflow>>8, xcycles >> 8, (xcycles >> 8) / 228);
|
||||
elprintf(EL_YMTIMER, "timer z80 read %i, sched %i, %i @ %i|%i",
|
||||
ym2612.OPN.ST.status, Pico.t.timer_a_next_oflow >> 8,
|
||||
Pico.t.timer_b_next_oflow >> 8, xcycles >> 8, (xcycles >> 8) / 228);
|
||||
return ym2612.OPN.ST.status;
|
||||
}
|
||||
|
||||
|
@ -1087,8 +1088,9 @@ static u32 ym2612_read_local_68k(void)
|
|||
|
||||
ym2612_read_local();
|
||||
|
||||
elprintf(EL_YMTIMER, "timer 68k read %i, sched %i, %i @ %i|%i", ym2612.OPN.ST.status,
|
||||
timer_a_next_oflow>>8, timer_b_next_oflow>>8, xcycles >> 8, (xcycles >> 8) / 228);
|
||||
elprintf(EL_YMTIMER, "timer 68k read %i, sched %i, %i @ %i|%i",
|
||||
ym2612.OPN.ST.status, Pico.t.timer_a_next_oflow >> 8,
|
||||
Pico.t.timer_b_next_oflow >> 8, xcycles >> 8, (xcycles >> 8) / 228);
|
||||
return ym2612.OPN.ST.status;
|
||||
}
|
||||
|
||||
|
@ -1098,10 +1100,12 @@ void ym2612_pack_state(void)
|
|||
int tac, tat = 0, tbc, tbt = 0;
|
||||
tac = 1024 - ym2612.OPN.ST.TA;
|
||||
tbc = 256 - ym2612.OPN.ST.TB;
|
||||
if (timer_a_next_oflow != TIMER_NO_OFLOW)
|
||||
tat = (int)((double)(timer_a_step - timer_a_next_oflow) / (double)timer_a_step * tac * 65536);
|
||||
if (timer_b_next_oflow != TIMER_NO_OFLOW)
|
||||
tbt = (int)((double)(timer_b_step - timer_b_next_oflow) / (double)timer_b_step * tbc * 65536);
|
||||
if (Pico.t.timer_a_next_oflow != TIMER_NO_OFLOW)
|
||||
tat = (int)((double)(Pico.t.timer_a_step - Pico.t.timer_a_next_oflow)
|
||||
/ (double)Pico.t.timer_a_step * tac * 65536);
|
||||
if (Pico.t.timer_b_next_oflow != TIMER_NO_OFLOW)
|
||||
tbt = (int)((double)(Pico.t.timer_b_step - Pico.t.timer_b_next_oflow)
|
||||
/ (double)Pico.t.timer_b_step * tbc * 65536);
|
||||
elprintf(EL_YMTIMER, "save: timer a %i/%i", tat >> 16, tac);
|
||||
elprintf(EL_YMTIMER, "save: timer b %i/%i", tbt >> 16, tbc);
|
||||
|
||||
|
@ -1154,15 +1158,15 @@ void ym2612_unpack_state(void)
|
|||
tac = (1024 - ym2612.OPN.ST.TA) << 16;
|
||||
tbc = (256 - ym2612.OPN.ST.TB) << 16;
|
||||
if (ym2612.OPN.ST.mode & 1)
|
||||
timer_a_next_oflow = (int)((double)(tac - tat) / (double)tac * timer_a_step);
|
||||
Pico.t.timer_a_next_oflow = (int)((double)(tac - tat) / (double)tac * Pico.t.timer_a_step);
|
||||
else
|
||||
timer_a_next_oflow = TIMER_NO_OFLOW;
|
||||
Pico.t.timer_a_next_oflow = TIMER_NO_OFLOW;
|
||||
if (ym2612.OPN.ST.mode & 2)
|
||||
timer_b_next_oflow = (int)((double)(tbc - tbt) / (double)tbc * timer_b_step);
|
||||
Pico.t.timer_b_next_oflow = (int)((double)(tbc - tbt) / (double)tbc * Pico.t.timer_b_step);
|
||||
else
|
||||
timer_b_next_oflow = TIMER_NO_OFLOW;
|
||||
elprintf(EL_YMTIMER, "load: %i/%i, timer_a_next_oflow %i", tat>>16, tac>>16, timer_a_next_oflow >> 8);
|
||||
elprintf(EL_YMTIMER, "load: %i/%i, timer_b_next_oflow %i", tbt>>16, tbc>>16, timer_b_next_oflow >> 8);
|
||||
Pico.t.timer_b_next_oflow = TIMER_NO_OFLOW;
|
||||
elprintf(EL_YMTIMER, "load: %i/%i, timer_a_next_oflow %i", tat>>16, tac>>16, Pico.t.timer_a_next_oflow >> 8);
|
||||
elprintf(EL_YMTIMER, "load: %i/%i, timer_b_next_oflow %i", tbt>>16, tbc>>16, Pico.t.timer_b_next_oflow >> 8);
|
||||
}
|
||||
|
||||
#if defined(NO_32X) && defined(_ASM_MEMORY_C)
|
||||
|
|
|
@ -14,7 +14,6 @@ struct Pico Pico;
|
|||
struct PicoMem PicoMem;
|
||||
PicoInterface PicoIn;
|
||||
|
||||
void (*PicoWriteSound)(int len) = NULL; // called at the best time to send sound buffer (PsndOut) to hardware
|
||||
void (*PicoResetHook)(void) = NULL;
|
||||
void (*PicoLineHook)(void) = NULL;
|
||||
|
||||
|
@ -344,6 +343,4 @@ void PicoGetInternal(pint_t which, pint_ret_t *r)
|
|||
}
|
||||
}
|
||||
|
||||
// callback to output message from emu
|
||||
void (*PicoMessage)(const char *msg)=NULL;
|
||||
|
||||
// vim:ts=2:sw=2:expandtab
|
||||
|
|
17
pico/pico.h
17
pico/pico.h
|
@ -97,6 +97,15 @@ typedef struct
|
|||
|
||||
unsigned short quirks; // game-specific quirks: PQUIRK_*
|
||||
unsigned short overclockM68k; // overclock the emulated 68k, in %
|
||||
|
||||
int sndRate; // rate in Hz
|
||||
short *sndOut; // PCM output buffer
|
||||
void (*writeSound)(int len); // write .sndOut callback, called once per frame
|
||||
|
||||
void (*osdMessage)(const char *msg); // output OSD message from emu, optional
|
||||
|
||||
void (*mcdTrayOpen)(void);
|
||||
void (*mcdTrayClose)(void);
|
||||
} PicoInterface;
|
||||
|
||||
extern PicoInterface PicoIn;
|
||||
|
@ -108,18 +117,12 @@ int PicoReset(void);
|
|||
void PicoLoopPrepare(void);
|
||||
void PicoFrame(void);
|
||||
void PicoFrameDrawOnly(void);
|
||||
extern void (*PicoWriteSound)(int bytes); // called once per frame at the best time to send sound buffer (PsndOut) to hardware
|
||||
extern void (*PicoMessage)(const char *msg); // callback to output text message from emu
|
||||
typedef enum { PI_ROM, PI_ISPAL, PI_IS40_CELL, PI_IS240_LINES } pint_t;
|
||||
typedef union { int vint; void *vptr; } pint_ret_t;
|
||||
void PicoGetInternal(pint_t which, pint_ret_t *ret);
|
||||
|
||||
struct PicoEState;
|
||||
|
||||
// cd/mcd.c
|
||||
extern void (*PicoMCDopenTray)(void);
|
||||
extern void (*PicoMCDcloseTray)(void);
|
||||
|
||||
// pico.c
|
||||
#define XPCM_BUFFER_SIZE (320+160)
|
||||
typedef struct
|
||||
|
@ -230,8 +233,6 @@ void Pico32xSetClocks(int msh2_hz, int ssh2_hz);
|
|||
#define PICO_SSH2_HZ ((int)(7670442.0 * 2.4))
|
||||
|
||||
// sound.c
|
||||
extern int PsndRate,PsndLen;
|
||||
extern short *PsndOut;
|
||||
extern void (*PsndMix_32_to_16l)(short *dest, int *src, int count);
|
||||
void PsndRerate(int preserve_state);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ PICO_INTERNAL void PicoPicoPCMReset(void)
|
|||
|
||||
PICO_INTERNAL void PicoPicoPCMRerate(int xpcm_rate)
|
||||
{
|
||||
stepsamples = (PsndRate<<10)/xpcm_rate;
|
||||
stepsamples = (PicoIn.sndRate<<10)/xpcm_rate;
|
||||
}
|
||||
|
||||
#define XSHIFT 6
|
||||
|
|
|
@ -153,7 +153,7 @@ static int PicoFrameHints(void)
|
|||
}
|
||||
|
||||
// get samples from sound chips
|
||||
if ((y == 224 || y == line_sample) && PsndOut)
|
||||
if ((y == 224 || y == line_sample) && PicoIn.sndOut)
|
||||
{
|
||||
cycles = SekCyclesDone();
|
||||
|
||||
|
@ -241,7 +241,7 @@ static int PicoFrameHints(void)
|
|||
#endif
|
||||
|
||||
// get samples from sound chips
|
||||
if (y == 224 && PsndOut)
|
||||
if (y == 224 && PicoIn.sndOut)
|
||||
PsndGetSamples(y);
|
||||
|
||||
// Run scanline:
|
||||
|
@ -324,9 +324,9 @@ static int PicoFrameHints(void)
|
|||
cycles = SekCyclesDone();
|
||||
if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80))
|
||||
PicoSyncZ80(cycles);
|
||||
if (PsndOut && ym2612.dacen && PsndDacLine < lines)
|
||||
if (PicoIn.sndOut && ym2612.dacen && Pico.snd.dac_line < lines)
|
||||
PsndDoDAC(lines - 1);
|
||||
if (PsndOut && PsndPsgLine < lines)
|
||||
if (PicoIn.sndOut && Pico.snd.psg_line < lines)
|
||||
PsndDoPSG(lines - 1);
|
||||
|
||||
#ifdef PICO_CD
|
||||
|
|
|
@ -409,6 +409,19 @@ struct PicoTiming
|
|||
unsigned int z80c_cnt; // z80 cycles done (this frame)
|
||||
unsigned int z80c_aim;
|
||||
int z80_scanline;
|
||||
|
||||
int timer_a_next_oflow, timer_a_step; // in z80 cycles
|
||||
int timer_b_next_oflow, timer_b_step;
|
||||
};
|
||||
|
||||
struct PicoSound
|
||||
{
|
||||
short len; // number of mono samples
|
||||
short len_use; // adjusted
|
||||
int len_e_add; // for non-int samples/frame
|
||||
int len_e_cnt;
|
||||
short dac_line;
|
||||
short psg_line;
|
||||
};
|
||||
|
||||
// run tools/mkoffsets pico/pico_int_o32.h if you change these
|
||||
|
@ -419,6 +432,7 @@ struct Pico
|
|||
struct PicoMisc m;
|
||||
struct PicoTiming t;
|
||||
struct PicoCartSave sv;
|
||||
struct PicoSound snd;
|
||||
struct PicoEState est;
|
||||
struct PicoMS ms;
|
||||
|
||||
|
@ -781,10 +795,6 @@ void SekInterruptClearS68k(int irq);
|
|||
|
||||
// sound/sound.c
|
||||
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
|
||||
extern int timer_b_next_oflow, timer_b_step;
|
||||
|
||||
void cdda_start_play(int lba_base, int lba_offset, int lb_len);
|
||||
|
||||
|
@ -799,16 +809,16 @@ void ym2612_unpack_state(void);
|
|||
#define TIMER_B_TICK_ZCYCLES 262800 // 275251 broken, see Dai Makaimura
|
||||
|
||||
#define timers_cycle() \
|
||||
if (timer_a_next_oflow > 0 && timer_a_next_oflow < TIMER_NO_OFLOW) \
|
||||
timer_a_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256; \
|
||||
if (timer_b_next_oflow > 0 && timer_b_next_oflow < TIMER_NO_OFLOW) \
|
||||
timer_b_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256; \
|
||||
if (Pico.t.timer_a_next_oflow > 0 && Pico.t.timer_a_next_oflow < TIMER_NO_OFLOW) \
|
||||
Pico.t.timer_a_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256; \
|
||||
if (Pico.t.timer_b_next_oflow > 0 && Pico.t.timer_b_next_oflow < TIMER_NO_OFLOW) \
|
||||
Pico.t.timer_b_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256; \
|
||||
ym2612_sync_timers(0, ym2612.OPN.ST.mode, ym2612.OPN.ST.mode);
|
||||
|
||||
#define timers_reset() \
|
||||
timer_a_next_oflow = timer_b_next_oflow = TIMER_NO_OFLOW; \
|
||||
timer_a_step = TIMER_A_TICK_ZCYCLES * 1024; \
|
||||
timer_b_step = TIMER_B_TICK_ZCYCLES * 256;
|
||||
Pico.t.timer_a_next_oflow = Pico.t.timer_b_next_oflow = TIMER_NO_OFLOW; \
|
||||
Pico.t.timer_a_step = TIMER_A_TICK_ZCYCLES * 1024; \
|
||||
Pico.t.timer_b_step = TIMER_B_TICK_ZCYCLES * 256;
|
||||
|
||||
|
||||
// videoport.c
|
||||
|
@ -850,7 +860,6 @@ PICO_INTERNAL void PsndDoPSG(int line_to);
|
|||
PICO_INTERNAL void PsndClear(void);
|
||||
PICO_INTERNAL void PsndGetSamples(int y);
|
||||
PICO_INTERNAL void PsndGetSamplesMS(void);
|
||||
extern int PsndDacLine, PsndPsgLine;
|
||||
|
||||
// sms.c
|
||||
#ifndef NO_SMS
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
#define OFS_Pico_m_hardware 0x0047
|
||||
#define OFS_Pico_m_z80_reset 0x004f
|
||||
#define OFS_Pico_m_sram_reg 0x0049
|
||||
#define OFS_Pico_sv 0x007c
|
||||
#define OFS_Pico_sv_data 0x007c
|
||||
#define OFS_Pico_sv_start 0x0080
|
||||
#define OFS_Pico_sv_end 0x0084
|
||||
#define OFS_Pico_sv_flags 0x0088
|
||||
#define OFS_Pico_rom 0x031c
|
||||
#define OFS_Pico_romsize 0x0320
|
||||
#define OFS_Pico_sv 0x008c
|
||||
#define OFS_Pico_sv_data 0x008c
|
||||
#define OFS_Pico_sv_start 0x0090
|
||||
#define OFS_Pico_sv_end 0x0094
|
||||
#define OFS_Pico_sv_flags 0x0098
|
||||
#define OFS_Pico_rom 0x033c
|
||||
#define OFS_Pico_romsize 0x0340
|
||||
#define OFS_EST_DrawScanline 0x00
|
||||
#define OFS_EST_rendstatus 0x04
|
||||
#define OFS_EST_DrawLineDest 0x08
|
||||
|
|
|
@ -131,7 +131,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
|
|||
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
if ((d & 0x90) == 0x90 && PsndPsgLine < Pico.m.scanline)
|
||||
if ((d & 0x90) == 0x90 && Pico.snd.psg_line < Pico.m.scanline)
|
||||
PsndDoPSG(Pico.m.scanline);
|
||||
SN76496Write(d);
|
||||
break;
|
||||
|
@ -300,14 +300,14 @@ void PicoFrameMS(void)
|
|||
}
|
||||
|
||||
// 224 because of how it's done for MD...
|
||||
if (y == 224 && PsndOut)
|
||||
if (y == 224 && PicoIn.sndOut)
|
||||
PsndGetSamplesMS();
|
||||
|
||||
cycles_aim += cycles_line;
|
||||
cycles_done += z80_run((cycles_aim - cycles_done) >> 8) << 8;
|
||||
}
|
||||
|
||||
if (PsndOut && PsndPsgLine < lines)
|
||||
if (PicoIn.sndOut && Pico.snd.psg_line < lines)
|
||||
PsndDoPSG(lines - 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,31 +25,20 @@ static unsigned short dac_info[312+4]; // pos in sample buffer
|
|||
// cdda output buffer
|
||||
short cdda_out_buffer[2*1152];
|
||||
|
||||
// for Pico
|
||||
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, PsndPsgLine;
|
||||
short *PsndOut=NULL; // PCM data buffer
|
||||
static int PsndLen_use;
|
||||
|
||||
// timers
|
||||
int timer_a_next_oflow, timer_a_step; // in z80 cycles
|
||||
int timer_b_next_oflow, timer_b_step;
|
||||
|
||||
// sn76496
|
||||
extern int *sn76496_regs;
|
||||
|
||||
|
||||
static void dac_recalculate(void)
|
||||
{
|
||||
int i, dac_cnt, pos, len, lines = Pico.m.pal ? 313 : 262, mid = Pico.m.pal ? 68 : 93;
|
||||
int lines = Pico.m.pal ? 313 : 262;
|
||||
int mid = Pico.m.pal ? 68 : 93;
|
||||
int i, dac_cnt, pos, len;
|
||||
|
||||
if (PsndLen <= lines)
|
||||
if (Pico.snd.len <= lines)
|
||||
{
|
||||
// shrinking algo
|
||||
dac_cnt = -PsndLen;
|
||||
dac_cnt = -Pico.snd.len;
|
||||
len=1; pos=0;
|
||||
dac_info[225] = 1;
|
||||
|
||||
|
@ -60,14 +49,14 @@ static void dac_recalculate(void)
|
|||
pos++;
|
||||
dac_cnt += lines;
|
||||
}
|
||||
dac_cnt -= PsndLen;
|
||||
dac_cnt -= Pico.snd.len;
|
||||
dac_info[i] = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// stretching
|
||||
dac_cnt = PsndLen;
|
||||
dac_cnt = Pico.snd.len;
|
||||
pos=0;
|
||||
for(i = 225; i != 224; i++)
|
||||
{
|
||||
|
@ -78,11 +67,11 @@ static void dac_recalculate(void)
|
|||
len++;
|
||||
}
|
||||
if (i == mid) // midpoint
|
||||
while(pos+len < PsndLen/2) {
|
||||
while(pos+len < Pico.snd.len/2) {
|
||||
dac_cnt -= lines;
|
||||
len++;
|
||||
}
|
||||
dac_cnt += PsndLen;
|
||||
dac_cnt += Pico.snd.len;
|
||||
pos += len;
|
||||
dac_info[i] = pos;
|
||||
}
|
||||
|
@ -112,7 +101,7 @@ void PsndRerate(int preserve_state)
|
|||
ym2612_pack_state();
|
||||
memcpy(state, YM2612GetRegs(), 0x204);
|
||||
}
|
||||
YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PsndRate);
|
||||
YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PicoIn.sndRate);
|
||||
if (preserve_state) {
|
||||
// feed it back it's own registers, just like after loading state
|
||||
memcpy(YM2612GetRegs(), state, 0x204);
|
||||
|
@ -120,16 +109,16 @@ void PsndRerate(int preserve_state)
|
|||
}
|
||||
|
||||
if (preserve_state) memcpy(state, sn76496_regs, 28*4); // remember old state
|
||||
SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PsndRate);
|
||||
SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PicoIn.sndRate);
|
||||
if (preserve_state) memcpy(sn76496_regs, state, 28*4); // restore old state
|
||||
|
||||
if (state)
|
||||
free(state);
|
||||
|
||||
// calculate PsndLen
|
||||
PsndLen=PsndRate / target_fps;
|
||||
PsndLen_exc_add=((PsndRate - PsndLen*target_fps)<<16) / target_fps;
|
||||
PsndLen_exc_cnt=0;
|
||||
// calculate Pico.snd.len
|
||||
Pico.snd.len = PicoIn.sndRate / target_fps;
|
||||
Pico.snd.len_e_add = ((PicoIn.sndRate - Pico.snd.len * target_fps) << 16) / target_fps;
|
||||
Pico.snd.len_e_cnt = 0;
|
||||
|
||||
// recalculate dac info
|
||||
dac_recalculate();
|
||||
|
@ -137,7 +126,7 @@ void PsndRerate(int preserve_state)
|
|||
// clear all buffers
|
||||
memset32(PsndBuffer, 0, sizeof(PsndBuffer)/4);
|
||||
memset(cdda_out_buffer, 0, sizeof(cdda_out_buffer));
|
||||
if (PsndOut)
|
||||
if (PicoIn.sndOut)
|
||||
PsndClear();
|
||||
|
||||
// set mixer
|
||||
|
@ -150,24 +139,24 @@ void PsndRerate(int preserve_state)
|
|||
|
||||
PICO_INTERNAL void PsndStartFrame(void)
|
||||
{
|
||||
// compensate for float part of PsndLen
|
||||
PsndLen_use = PsndLen;
|
||||
PsndLen_exc_cnt += PsndLen_exc_add;
|
||||
if (PsndLen_exc_cnt >= 0x10000) {
|
||||
PsndLen_exc_cnt -= 0x10000;
|
||||
PsndLen_use++;
|
||||
// compensate for float part of Pico.snd.len
|
||||
Pico.snd.len_use = Pico.snd.len;
|
||||
Pico.snd.len_e_cnt += Pico.snd.len_e_add;
|
||||
if (Pico.snd.len_e_cnt >= 0x10000) {
|
||||
Pico.snd.len_e_cnt -= 0x10000;
|
||||
Pico.snd.len_use++;
|
||||
}
|
||||
|
||||
PsndDacLine = PsndPsgLine = 0;
|
||||
Pico.snd.dac_line = Pico.snd.psg_line = 0;
|
||||
Pico.m.status &= ~1;
|
||||
dac_info[224] = PsndLen_use;
|
||||
dac_info[224] = Pico.snd.len_use;
|
||||
}
|
||||
|
||||
PICO_INTERNAL void PsndDoDAC(int line_to)
|
||||
{
|
||||
int pos, pos1, len;
|
||||
int dout = ym2612.dacout;
|
||||
int line_from = PsndDacLine;
|
||||
int line_from = Pico.snd.dac_line;
|
||||
|
||||
if (line_to >= 313)
|
||||
line_to = 312;
|
||||
|
@ -178,23 +167,23 @@ PICO_INTERNAL void PsndDoDAC(int line_to)
|
|||
if (len <= 0)
|
||||
return;
|
||||
|
||||
PsndDacLine = line_to + 1;
|
||||
Pico.snd.dac_line = line_to + 1;
|
||||
|
||||
if (!PsndOut)
|
||||
if (!PicoIn.sndOut)
|
||||
return;
|
||||
|
||||
if (PicoIn.opt & POPT_EN_STEREO) {
|
||||
short *d = PsndOut + pos*2;
|
||||
short *d = PicoIn.sndOut + pos*2;
|
||||
for (; len > 0; len--, d+=2) *d += dout;
|
||||
} else {
|
||||
short *d = PsndOut + pos;
|
||||
short *d = PicoIn.sndOut + pos;
|
||||
for (; len > 0; len--, d++) *d += dout;
|
||||
}
|
||||
}
|
||||
|
||||
PICO_INTERNAL void PsndDoPSG(int line_to)
|
||||
{
|
||||
int line_from = PsndPsgLine;
|
||||
int line_from = Pico.snd.psg_line;
|
||||
int pos, pos1, len;
|
||||
int stereo = 0;
|
||||
|
||||
|
@ -209,16 +198,16 @@ PICO_INTERNAL void PsndDoPSG(int line_to)
|
|||
if (len <= 0)
|
||||
return;
|
||||
|
||||
PsndPsgLine = line_to + 1;
|
||||
Pico.snd.psg_line = line_to + 1;
|
||||
|
||||
if (!PsndOut || !(PicoIn.opt & POPT_EN_PSG))
|
||||
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))
|
||||
return;
|
||||
|
||||
if (PicoIn.opt & POPT_EN_STEREO) {
|
||||
stereo = 1;
|
||||
pos <<= 1;
|
||||
}
|
||||
SN76496Update(PsndOut + pos, len, stereo);
|
||||
SN76496Update(PicoIn.sndOut + pos, len, stereo);
|
||||
}
|
||||
|
||||
// cdda
|
||||
|
@ -227,8 +216,8 @@ static void cdda_raw_update(int *buffer, int length)
|
|||
int ret, cdda_bytes, mult = 1;
|
||||
|
||||
cdda_bytes = length*4;
|
||||
if (PsndRate <= 22050 + 100) mult = 2;
|
||||
if (PsndRate < 22050 - 100) mult = 4;
|
||||
if (PicoIn.sndRate <= 22050 + 100) mult = 2;
|
||||
if (PicoIn.sndRate < 22050 - 100) mult = 4;
|
||||
cdda_bytes *= mult;
|
||||
|
||||
ret = pm_read(cdda_out_buffer, cdda_bytes, Pico_mcd->cdda_stream);
|
||||
|
@ -270,12 +259,12 @@ void cdda_start_play(int lba_base, int lba_offset, int lb_len)
|
|||
|
||||
PICO_INTERNAL void PsndClear(void)
|
||||
{
|
||||
int len = PsndLen;
|
||||
if (PsndLen_exc_add) len++;
|
||||
int len = Pico.snd.len;
|
||||
if (Pico.snd.len_e_add) len++;
|
||||
if (PicoIn.opt & POPT_EN_STEREO)
|
||||
memset32((int *) PsndOut, 0, len); // assume PsndOut to be aligned
|
||||
memset32((int *) PicoIn.sndOut, 0, len); // assume PicoIn.sndOut to be aligned
|
||||
else {
|
||||
short *out = PsndOut;
|
||||
short *out = PicoIn.sndOut;
|
||||
if ((long)out & 2) { *out++ = 0; len--; }
|
||||
memset32((int *) out, 0, len/2);
|
||||
if (len & 1) out[len-1] = 0;
|
||||
|
@ -294,7 +283,7 @@ static int PsndRender(int offset, int length)
|
|||
pprof_start(sound);
|
||||
|
||||
if (PicoIn.AHW & PAHW_PICO) {
|
||||
PicoPicoPCMUpdate(PsndOut+offset, length, stereo);
|
||||
PicoPicoPCMUpdate(PicoIn.sndOut+offset, length, stereo);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -330,7 +319,7 @@ static int PsndRender(int offset, int length)
|
|||
p32x_pwm_update(buf32, length, stereo);
|
||||
|
||||
// convert + limit to normal 16bit output
|
||||
PsndMix_32_to_16l(PsndOut+offset, buf32, length);
|
||||
PsndMix_32_to_16l(PicoIn.sndOut+offset, buf32, length);
|
||||
|
||||
pprof_end(sound);
|
||||
|
||||
|
@ -342,47 +331,47 @@ PICO_INTERNAL void PsndGetSamples(int y)
|
|||
{
|
||||
static int curr_pos = 0;
|
||||
|
||||
if (ym2612.dacen && PsndDacLine < y)
|
||||
if (ym2612.dacen && Pico.snd.dac_line < y)
|
||||
PsndDoDAC(y - 1);
|
||||
PsndDoPSG(y - 1);
|
||||
|
||||
if (y == 224)
|
||||
{
|
||||
if (Pico.m.status & 2)
|
||||
curr_pos += PsndRender(curr_pos, PsndLen-PsndLen/2);
|
||||
else curr_pos = PsndRender(0, PsndLen_use);
|
||||
curr_pos += PsndRender(curr_pos, Pico.snd.len-Pico.snd.len/2);
|
||||
else curr_pos = PsndRender(0, Pico.snd.len_use);
|
||||
if (Pico.m.status & 1)
|
||||
Pico.m.status |= 2;
|
||||
else Pico.m.status &= ~2;
|
||||
if (PicoWriteSound)
|
||||
PicoWriteSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||
if (PicoIn.writeSound)
|
||||
PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||
// clear sound buffer
|
||||
PsndClear();
|
||||
PsndDacLine = 224;
|
||||
Pico.snd.dac_line = 224;
|
||||
dac_info[224] = 0;
|
||||
}
|
||||
else if (Pico.m.status & 3) {
|
||||
Pico.m.status |= 2;
|
||||
Pico.m.status &= ~1;
|
||||
curr_pos = PsndRender(0, PsndLen/2);
|
||||
curr_pos = PsndRender(0, Pico.snd.len/2);
|
||||
}
|
||||
}
|
||||
|
||||
PICO_INTERNAL void PsndGetSamplesMS(void)
|
||||
{
|
||||
int length = PsndLen_use;
|
||||
int length = Pico.snd.len_use;
|
||||
|
||||
PsndDoPSG(223);
|
||||
|
||||
// upmix to "stereo" if needed
|
||||
if (PicoIn.opt & POPT_EN_STEREO) {
|
||||
int i, *p;
|
||||
for (i = length, p = (void *)PsndOut; i > 0; i--, p++)
|
||||
for (i = length, p = (void *)PicoIn.sndOut; i > 0; i--, p++)
|
||||
*p |= *p << 16;
|
||||
}
|
||||
|
||||
if (PicoWriteSound != NULL)
|
||||
PicoWriteSound(length * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||
if (PicoIn.writeSound != NULL)
|
||||
PicoIn.writeSound(length * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||
PsndClear();
|
||||
|
||||
dac_info[224] = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue