mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-06 23:58:04 -04:00
core, revisit ym2612 busy flag implementation
This commit is contained in:
parent
e948a120ed
commit
f5c022a8e4
5 changed files with 24 additions and 16 deletions
|
@ -1174,7 +1174,7 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
|
||||||
|
|
||||||
// the busy flag in the YM2612 status is actually a 32 cycle timer
|
// the busy flag in the YM2612 status is actually a 32 cycle timer
|
||||||
// (89.6 Z80 cycles), triggered by any write to the data port.
|
// (89.6 Z80 cycles), triggered by any write to the data port.
|
||||||
Pico.t.ym2612_busy = (cycles + 90) << 8; // Q8 for convenience
|
Pico.t.ym2612_busy = (cycles << 8) + YMBUSY_ZCYCLES; // Q8 for convenience
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
@ -1284,9 +1284,11 @@ static u32 ym2612_read_local_68k(void)
|
||||||
void ym2612_pack_state(void)
|
void ym2612_pack_state(void)
|
||||||
{
|
{
|
||||||
// timers are saved as tick counts, in 16.16 int format
|
// timers are saved as tick counts, in 16.16 int format
|
||||||
int tac, tat = 0, tbc, tbt = 0;
|
int tac, tat = 0, tbc, tbt = 0, busy = 0;
|
||||||
tac = 1024 - ym2612.OPN.ST.TA;
|
tac = 1024 - ym2612.OPN.ST.TA;
|
||||||
tbc = 256 - ym2612.OPN.ST.TB;
|
tbc = 256 - ym2612.OPN.ST.TB;
|
||||||
|
if (Pico.t.ym2612_busy > 0)
|
||||||
|
busy = cycles_z80_to_68k(Pico.t.ym2612_busy);
|
||||||
if (Pico.t.timer_a_next_oflow != TIMER_NO_OFLOW)
|
if (Pico.t.timer_a_next_oflow != TIMER_NO_OFLOW)
|
||||||
tat = (int)((double)(Pico.t.timer_a_step - Pico.t.timer_a_next_oflow)
|
tat = (int)((double)(Pico.t.timer_a_step - Pico.t.timer_a_next_oflow)
|
||||||
/ (double)Pico.t.timer_a_step * tac * 65536);
|
/ (double)Pico.t.timer_a_step * tac * 65536);
|
||||||
|
@ -1301,12 +1303,12 @@ void ym2612_pack_state(void)
|
||||||
YM2612PicoStateSave2_940(tat, tbt);
|
YM2612PicoStateSave2_940(tat, tbt);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
YM2612PicoStateSave2(tat, tbt);
|
YM2612PicoStateSave2(tat, tbt, busy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ym2612_unpack_state(void)
|
void ym2612_unpack_state(void)
|
||||||
{
|
{
|
||||||
int i, ret, tac, tat, tbc, tbt;
|
int i, ret, tac, tat, tbc, tbt, busy = 0;
|
||||||
YM2612PicoStateLoad();
|
YM2612PicoStateLoad();
|
||||||
|
|
||||||
// feed all the registers and update internal state
|
// feed all the registers and update internal state
|
||||||
|
@ -1336,12 +1338,13 @@ void ym2612_unpack_state(void)
|
||||||
ret = YM2612PicoStateLoad2_940(&tat, &tbt);
|
ret = YM2612PicoStateLoad2_940(&tat, &tbt);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
ret = YM2612PicoStateLoad2(&tat, &tbt);
|
ret = YM2612PicoStateLoad2(&tat, &tbt, &busy);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
elprintf(EL_STATUS, "old ym2612 state");
|
elprintf(EL_STATUS, "old ym2612 state");
|
||||||
return; // no saved timers
|
return; // no saved timers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pico.t.ym2612_busy = cycles_68k_to_z80(busy);
|
||||||
tac = (1024 - ym2612.OPN.ST.TA) << 16;
|
tac = (1024 - ym2612.OPN.ST.TA) << 16;
|
||||||
tbc = (256 - ym2612.OPN.ST.TB) << 16;
|
tbc = (256 - ym2612.OPN.ST.TB) << 16;
|
||||||
if (ym2612.OPN.ST.mode & 1)
|
if (ym2612.OPN.ST.mode & 1)
|
||||||
|
|
|
@ -209,6 +209,7 @@ extern struct DrZ80 drZ80;
|
||||||
|
|
||||||
// 68k clock = OSC/7, z80 clock = OSC/15, 68k:z80 ratio = 7/15 = 3822.9/8192
|
// 68k clock = OSC/7, z80 clock = OSC/15, 68k:z80 ratio = 7/15 = 3822.9/8192
|
||||||
#define cycles_68k_to_z80(x) ((x) * 3823 >> 13)
|
#define cycles_68k_to_z80(x) ((x) * 3823 >> 13)
|
||||||
|
#define cycles_z80_to_68k(x) ((x) * 8777 >> 12)
|
||||||
|
|
||||||
// ----------------------- SH2 CPU -----------------------
|
// ----------------------- SH2 CPU -----------------------
|
||||||
|
|
||||||
|
@ -898,10 +899,12 @@ void ym2612_unpack_state(void);
|
||||||
|
|
||||||
#define TIMER_NO_OFLOW 0x70000000
|
#define TIMER_NO_OFLOW 0x70000000
|
||||||
|
|
||||||
// tA = 72 * (1024 - TA) / M, with M = mclock/2
|
// tA = 24*3 * (1024 - TA) / M, with M = mclock/2
|
||||||
#define TIMER_A_TICK_ZCYCLES cycles_68k_to_z80(256LL* 72*2) // Q8
|
#define TIMER_A_TICK_ZCYCLES cycles_68k_to_z80(256LL* 24*3*2) // Q8
|
||||||
// tB = 16*72 * ( 256 - TB) / M
|
// tB = 16*24*3 * ( 256 - TB) / M
|
||||||
#define TIMER_B_TICK_ZCYCLES cycles_68k_to_z80(256LL*16*72*2) // Q8
|
#define TIMER_B_TICK_ZCYCLES cycles_68k_to_z80(256LL*16*24*3*2) // Q8
|
||||||
|
// busy = 32*3 / M
|
||||||
|
#define YMBUSY_ZCYCLES cycles_68k_to_z80(256LL* 32*3*2) // Q8
|
||||||
|
|
||||||
#define timers_cycle(ticks) \
|
#define timers_cycle(ticks) \
|
||||||
if (Pico.t.ym2612_busy > 0) \
|
if (Pico.t.ym2612_busy > 0) \
|
||||||
|
|
|
@ -2049,7 +2049,7 @@ typedef struct
|
||||||
UINT32 eg_timer;
|
UINT32 eg_timer;
|
||||||
UINT32 lfo_cnt;
|
UINT32 lfo_cnt;
|
||||||
UINT16 lfo_ampm;
|
UINT16 lfo_ampm;
|
||||||
UINT16 unused2;
|
INT16 busy_timer;
|
||||||
UINT32 keyon_field; // 20
|
UINT32 keyon_field; // 20
|
||||||
UINT32 kcode_fc_sl3_3;
|
UINT32 kcode_fc_sl3_3;
|
||||||
UINT32 reserved[2];
|
UINT32 reserved[2];
|
||||||
|
@ -2063,7 +2063,7 @@ typedef struct
|
||||||
} ym_save_addon2;
|
} ym_save_addon2;
|
||||||
|
|
||||||
|
|
||||||
void YM2612PicoStateSave2(int tat, int tbt)
|
void YM2612PicoStateSave2(int tat, int tbt, int busy)
|
||||||
{
|
{
|
||||||
ym_save_addon_slot ss;
|
ym_save_addon_slot ss;
|
||||||
ym_save_addon2 sa2;
|
ym_save_addon2 sa2;
|
||||||
|
@ -2121,10 +2121,11 @@ void YM2612PicoStateSave2(int tat, int tbt)
|
||||||
sa.eg_timer = ym2612.OPN.eg_timer;
|
sa.eg_timer = ym2612.OPN.eg_timer;
|
||||||
sa.lfo_cnt = ym2612.OPN.lfo_cnt;
|
sa.lfo_cnt = ym2612.OPN.lfo_cnt;
|
||||||
sa.lfo_ampm = g_lfo_ampm;
|
sa.lfo_ampm = g_lfo_ampm;
|
||||||
|
sa.busy_timer = busy;
|
||||||
memcpy(ptr, &sa, sizeof(sa)); // 0x30 max
|
memcpy(ptr, &sa, sizeof(sa)); // 0x30 max
|
||||||
}
|
}
|
||||||
|
|
||||||
int YM2612PicoStateLoad2(int *tat, int *tbt)
|
int YM2612PicoStateLoad2(int *tat, int *tbt, int *busy)
|
||||||
{
|
{
|
||||||
ym_save_addon_slot ss;
|
ym_save_addon_slot ss;
|
||||||
ym_save_addon2 sa2;
|
ym_save_addon2 sa2;
|
||||||
|
@ -2150,6 +2151,7 @@ int YM2612PicoStateLoad2(int *tat, int *tbt)
|
||||||
g_lfo_ampm = sa.lfo_ampm;
|
g_lfo_ampm = sa.lfo_ampm;
|
||||||
if (tat != NULL) *tat = sa.TAT;
|
if (tat != NULL) *tat = sa.TAT;
|
||||||
if (tbt != NULL) *tbt = sa.TBT;
|
if (tbt != NULL) *tbt = sa.TBT;
|
||||||
|
if (busy != NULL) *busy = sa.busy_timer;
|
||||||
|
|
||||||
// chans 1,2,3
|
// chans 1,2,3
|
||||||
ptr = &ym2612.REGS[0x0b8];
|
ptr = &ym2612.REGS[0x0b8];
|
||||||
|
|
|
@ -177,8 +177,8 @@ int YM2612PicoTick_(int n);
|
||||||
void YM2612PicoStateLoad_(void);
|
void YM2612PicoStateLoad_(void);
|
||||||
|
|
||||||
void *YM2612GetRegs(void);
|
void *YM2612GetRegs(void);
|
||||||
void YM2612PicoStateSave2(int tat, int tbt);
|
void YM2612PicoStateSave2(int tat, int tbt, int busy);
|
||||||
int YM2612PicoStateLoad2(int *tat, int *tbt);
|
int YM2612PicoStateLoad2(int *tat, int *tbt, int *busy);
|
||||||
|
|
||||||
/* NB must be macros for compiling GP2X 940 code */
|
/* NB must be macros for compiling GP2X 940 code */
|
||||||
#ifndef __GP2X__
|
#ifndef __GP2X__
|
||||||
|
|
|
@ -187,7 +187,7 @@ void Main940(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JOB940_PICOSTATESAVE2:
|
case JOB940_PICOSTATESAVE2:
|
||||||
YM2612PicoStateSave2(0, 0);
|
YM2612PicoStateSave2(0, 0, 0);
|
||||||
memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200);
|
memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ void Main940(void)
|
||||||
|
|
||||||
case JOB940_PICOSTATELOAD2:
|
case JOB940_PICOSTATELOAD2:
|
||||||
memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200);
|
memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200);
|
||||||
YM2612PicoStateLoad2(0, 0);
|
YM2612PicoStateLoad2(0, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JOB940_YM2612UPDATEONE:
|
case JOB940_YM2612UPDATEONE:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue