]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Fix audio timing (previous interrupt timing fix made previously fixed values incorrect)
authorToni Wilen <twilen@winuae.net>
Thu, 17 Nov 2022 17:57:24 +0000 (19:57 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 17 Nov 2022 17:57:24 +0000 (19:57 +0200)
audio.cpp
custom.cpp

index 74385f23ecde8ec144ffe2ac76fe869d141c9d5a..3c08caa2e4d180d025d1d205a5779b53a779b291 100644 (file)
--- a/audio.cpp
+++ b/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;
index 6d9a612a4c0f3876b7084cb3691d1a890ae50fce..767ca08d2482433745354a23fca12ee180e8ecfe 100644 (file)
@@ -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);
        }
 }