mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
Fix audio timing (previous interrupt timing fix made previously fixed values incorrect)
This commit is contained in:
parent
606eabb629
commit
a5a9ccfa40
63
audio.cpp
63
audio.cpp
@ -1402,55 +1402,46 @@ static void update_volume(int nr, uae_u16 v)
|
||||
cdp->data.audvol = v;
|
||||
}
|
||||
|
||||
uae_u16 audio_dmal (void)
|
||||
uae_u16 audio_dmal(void)
|
||||
{
|
||||
uae_u16 dmal = 0;
|
||||
for (int nr = 0; nr < AUDIO_CHANNELS_PAULA; nr++) {
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
if (cdp->dr)
|
||||
dmal |= 1 << (nr * 2);
|
||||
if (cdp->dsr)
|
||||
dmal |= 1 << (nr * 2 + 1);
|
||||
if (cdp->dsr)
|
||||
dmal |= 1 << (nr * 2 + 0);
|
||||
cdp->dr = cdp->dsr = false;
|
||||
}
|
||||
return dmal;
|
||||
}
|
||||
|
||||
static int isirq (int nr)
|
||||
static int isirq(int nr)
|
||||
{
|
||||
return INTREQR () & (0x80 << nr);
|
||||
return INTREQR() & (0x80 << nr);
|
||||
}
|
||||
|
||||
static void audio_setirq_event(uae_u32 nr)
|
||||
{
|
||||
INTREQ_0 (0x8000 | (0x80 << nr));
|
||||
}
|
||||
|
||||
static void setirq (int nr, int which)
|
||||
static void setirq(int nr, int which)
|
||||
{
|
||||
#if DEBUG_AUDIO > 0
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
if (debugchannel (nr) && cdp->wlen > 1)
|
||||
write_log (_T("SETIRQ%d (%d,%d) PC=%08X\n"), nr, which, isirq (nr) ? 1 : 0, M68K_GETPC);
|
||||
#endif
|
||||
// audio interrupts are delayed by 2 cycles
|
||||
if (!currprefs.cachesize && currprefs.cpu_compatible) {
|
||||
event2_newevent_xx (-1, 2 * CYCLE_UNIT + CYCLE_UNIT / 2, nr, audio_setirq_event);
|
||||
} else {
|
||||
audio_setirq_event(nr);
|
||||
}
|
||||
// audio interrupts are delayed by 1 CCK
|
||||
INTREQ_INT(nr + 7, CYCLE_UNIT);
|
||||
}
|
||||
|
||||
static void newsample (int nr, sample8_t sample)
|
||||
static void newsample(int nr, sample8_t sample)
|
||||
{
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
#if DEBUG_AUDIO > 0
|
||||
if (!debugchannel (nr))
|
||||
if (!debugchannel(nr))
|
||||
sample = 0;
|
||||
#endif
|
||||
#if DEBUG_AUDIO > 2
|
||||
if (debugchannel (nr))
|
||||
write_log (_T("SAMPLE%d: %02x\n"), nr, sample & 0xff);
|
||||
if (debugchannel(nr))
|
||||
write_log(_T("SAMPLE%d: %02x\n"), nr, sample & 0xff);
|
||||
#endif
|
||||
if (!(audio_channel_mask & (1 << nr)))
|
||||
sample = 0;
|
||||
@ -2380,7 +2371,7 @@ static void audxdat_func(uae_u32 v)
|
||||
cdp->dat_written = false;
|
||||
}
|
||||
|
||||
void AUDxDAT (int nr, uae_u16 v, uaecptr addr)
|
||||
void AUDxDAT(int nr, uae_u16 v, uaecptr addr)
|
||||
{
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
int chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr));
|
||||
@ -2412,13 +2403,9 @@ void AUDxDAT (int nr, uae_u16 v, uaecptr addr)
|
||||
}
|
||||
uae_u32 vv = nr | (chan_ena ? 0x80 : 0) | (v << 8);
|
||||
if (!currprefs.cachesize && (cdp->per < PERIOD_LOW * CYCLE_UNIT || currprefs.cpu_compatible)) {
|
||||
int cyc;
|
||||
int cyc = 0;
|
||||
if (chan_ena) {
|
||||
// AUDxLEN is processed after 2 cycle delay
|
||||
cyc = 2 * CYCLE_UNIT;
|
||||
} else if (cdp->state == 0) {
|
||||
cyc = 1 * CYCLE_UNIT;
|
||||
} else {
|
||||
// AUDxLEN is processed after 1 CCK delay
|
||||
cyc = 1 * CYCLE_UNIT;
|
||||
}
|
||||
if (cyc > 0) {
|
||||
@ -2430,12 +2417,12 @@ void AUDxDAT (int nr, uae_u16 v, uaecptr addr)
|
||||
audxdat_func(vv);
|
||||
}
|
||||
}
|
||||
void AUDxDAT (int nr, uae_u16 v)
|
||||
void AUDxDAT(int nr, uae_u16 v)
|
||||
{
|
||||
AUDxDAT (nr, v, 0xffffffff);
|
||||
AUDxDAT(nr, v, 0xffffffff);
|
||||
}
|
||||
|
||||
uaecptr audio_getpt (int nr, bool reset)
|
||||
uaecptr audio_getpt(int nr, bool reset)
|
||||
{
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
uaecptr p = cdp->pt;
|
||||
@ -2443,14 +2430,14 @@ uaecptr audio_getpt (int nr, bool reset)
|
||||
if (reset)
|
||||
cdp->pt = cdp->lc;
|
||||
cdp->ptx_tofetch = false;
|
||||
return p;
|
||||
return p & ~1;
|
||||
}
|
||||
|
||||
void AUDxLCH (int nr, uae_u16 v)
|
||||
void AUDxLCH(int nr, uae_u16 v)
|
||||
{
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
audio_activate ();
|
||||
update_audio ();
|
||||
audio_activate();
|
||||
update_audio();
|
||||
|
||||
// someone wants to update PT but DSR has not yet been processed.
|
||||
// too fast CPU and some tracker players: enable DMA, CPU delay, update AUDxPT with loop position
|
||||
@ -2475,11 +2462,11 @@ void AUDxLCH (int nr, uae_u16 v)
|
||||
}
|
||||
}
|
||||
|
||||
void AUDxLCL (int nr, uae_u16 v)
|
||||
void AUDxLCL(int nr, uae_u16 v)
|
||||
{
|
||||
struct audio_channel_data *cdp = audio_channel + nr;
|
||||
audio_activate ();
|
||||
update_audio ();
|
||||
audio_activate();
|
||||
update_audio();
|
||||
if (usehacks() && ((cdp->ptx_tofetch && cdp->state == 1) || cdp->ptx_written)) {
|
||||
static int warned = 100;
|
||||
cdp->ptx = cdp->lc;
|
||||
|
||||
28
custom.cpp
28
custom.cpp
@ -11484,7 +11484,7 @@ static void hsync_scandoubler(int hpos)
|
||||
reset_scandoubler_sync(hpos);
|
||||
}
|
||||
|
||||
static void dmal_emu(uae_u32 v)
|
||||
static void dmal_emu(uae_u32 val)
|
||||
{
|
||||
// Disk and Audio DMA bits are ignored by Agnus. Including DMA master bit.
|
||||
int hpos = current_hpos();
|
||||
@ -11495,11 +11495,13 @@ static void dmal_emu(uae_u32 v)
|
||||
return;
|
||||
}
|
||||
}
|
||||
int dmalbits = val & 3;
|
||||
int dmalpos = val >> 8;
|
||||
|
||||
if (v >= 6 && v < 14) {
|
||||
v -= 6;
|
||||
int nr = v / 2;
|
||||
uaecptr pt = audio_getpt(nr, (v & 1) != 0);
|
||||
if (dmalpos >= 6 && dmalpos < 14) {
|
||||
dmalpos -= 6;
|
||||
int nr = dmalpos / 2;
|
||||
uaecptr pt = audio_getpt(nr, (dmalbits & 1) != 0);
|
||||
if (dmal_ce) {
|
||||
#ifdef DEBUGGER
|
||||
if (debug_dma) {
|
||||
@ -11523,9 +11525,9 @@ static void dmal_emu(uae_u32 v)
|
||||
}
|
||||
regs.chipset_latch_rw = last_custom_value = dat;
|
||||
AUDxDAT(nr, dat, pt);
|
||||
} else if (v >= 0 && v < 6) {
|
||||
} else if (dmalpos >= 0 && dmalpos < 6) {
|
||||
uae_u16 dat = 0;
|
||||
int w = v & 1;
|
||||
int w = (dmalbits & 3) == 3;
|
||||
// disk_fifostatus() needed in >100% disk speed modes
|
||||
if (w) {
|
||||
// write to disk
|
||||
@ -11534,7 +11536,7 @@ static void dmal_emu(uae_u32 v)
|
||||
if (dmal_ce) {
|
||||
#ifdef DEBUGGER
|
||||
if (debug_dma) {
|
||||
record_dma_read(0x26, pt, hpos, vpos, DMARECORD_DISK, v / 2);
|
||||
record_dma_read(0x26, pt, hpos, vpos, DMARECORD_DISK, dmalpos / 2);
|
||||
}
|
||||
if (memwatch_enabled) {
|
||||
debug_getpeekdma_chipram(pt, MW_MASK_DISK, 0x26, 0x20);
|
||||
@ -11563,7 +11565,7 @@ static void dmal_emu(uae_u32 v)
|
||||
if (dmal_ce) {
|
||||
#ifdef DEBUGGER
|
||||
if (debug_dma) {
|
||||
record_dma_write(0x08, dat, pt, hpos, vpos, DMARECORD_DISK, v / 2);
|
||||
record_dma_write(0x08, dat, pt, hpos, vpos, DMARECORD_DISK, dmalpos / 2);
|
||||
}
|
||||
if (memwatch_enabled) {
|
||||
debug_putpeekdma_chipram(pt, dat, MW_MASK_DISK, 0x08, 0x20);
|
||||
@ -11575,7 +11577,7 @@ static void dmal_emu(uae_u32 v)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
write_log(_T("invalid DMAL position %d\n"), v);
|
||||
write_log(_T("invalid DMAL position %d\n"), dmalpos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11589,7 +11591,7 @@ static void dmal_func2(uae_u32 v)
|
||||
{
|
||||
while (dmal) {
|
||||
if (dmal & 3) {
|
||||
dmal_emu(dmal_hpos + ((dmal & 2) ? 1 : 0));
|
||||
dmal_emu((dmal_hpos << 8) | (dmal & 3));
|
||||
}
|
||||
dmal_hpos += 2;
|
||||
dmal >>= 2;
|
||||
@ -11612,10 +11614,10 @@ static void events_dmal(int hpos)
|
||||
dmal_hpos += 2;
|
||||
}
|
||||
dmal_ce = true;
|
||||
event2_newevent2(hpos, dmal_hpos + ((dmal & 2) ? 1 : 0), dmal_func);
|
||||
event2_newevent2(hpos, (dmal_hpos << 8) | (dmal & 3), dmal_func);
|
||||
dmal &= ~3;
|
||||
} else {
|
||||
event2_newevent2(hpos, dmal_hpos, dmal_func2);
|
||||
event2_newevent2(hpos, 0, dmal_func2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user