diff --git a/Assets/gamedb/gamedb_a7800.txt b/Assets/gamedb/gamedb_a7800.txt index 5e74e79fb3..2e681ed698 100644 --- a/Assets/gamedb/gamedb_a7800.txt +++ b/Assets/gamedb/gamedb_a7800.txt @@ -7,6 +7,9 @@ ;5 = Rescue on Fractulus ;6 = Dev Cart +md5:03DAA19B7AAE2D27E61F2A4DBE3B9B79 MUSIC A78 PAL=true;board=0;Pokey=true +md5:F5150C0FC1948832211E57852ABB0C6E Utility Cart A78 NTSC=true;board=0;Pokey=true +md5:F9FA5107ED213E709858D8876359309E Pokey Test A78 NTSC=true;board=0;Pokey=true md5:0D9452D4DB4D1E1CF843F4F10605EB7D Dev Cart A78 NTSC=true;board=0 md5:31FBCF03946E804FC2D77CCA5D61C928 Mode Test A78 NTSC=true;board=0 md5:91041AADD1700A7A4076F4005F2C362F Diagnostics A78 NTSC=true;board=0 diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs index 0028e969a4..a51b0c24e5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs @@ -46,6 +46,12 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk public byte lg_1_trigger_hit; public byte lg_2_trigger_hit; + public int temp_s_tia; + public int temp_s_pokey; + public int samp_l, samp_c; + public uint master_audio_clock; + public int temp; + // there are 4 maria cycles in a CPU cycle (fast access, both NTSC and PAL) // if the 6532 or TIA are accessed (PC goes to one of those addresses) the next access will be slower by 1/2 a CPU cycle // i.e. it will take 6 Maria cycles instead of 4 @@ -159,10 +165,10 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk // do the audio sampling if (tia._hsyncCnt == 113 || tia._hsyncCnt == 340) { - tia.Execute(0); + temp_s_tia = tia.Execute(0); // even though its clocked seperately, we sample the Pokey here - if (is_pokey) { pokey.sample(); } + //if (is_pokey) { pokey.sample(); } } // tick the m6532 timer, which is still active although not recommended to use @@ -173,12 +179,29 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk m6532.Timer.Tick(); } - // the pokey chip ticks at the nominal clock rate (same as maria) - if (is_pokey) + samp_l = temp_s_tia + 3 * temp_s_pokey; + + if (samp_l != samp_c) { - pokey.Tick(); + _blip.AddDelta(master_audio_clock, samp_l - samp_c); + samp_c = samp_l; } + temp++; + if (temp == 4) + { + // the pokey chip ticks at the nominal cpu speed, but is unaffected by cpu slowdown (I think) + if (is_pokey) + { + pokey.Tick(); + temp_s_pokey = pokey.sample(); + } + + master_audio_clock++; + temp = 0; + } + + if (cpu_cycle <= (2 + (slow_access ? 1 : 0))) { cpu_is_haltable = true; @@ -312,6 +335,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk maria = null; tia = null; m6532 = null; + DisposeSound(); } @@ -357,8 +381,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk #region Sound provider - private int _spf; - + private BlipBuffer _blip = new BlipBuffer(4096); + public bool CanProvideAsync => false; public void SetSyncMode(SyncSoundMode mode) @@ -373,21 +397,21 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk public void GetSamplesSync(out short[] samples, out int nsamp) { - short[] ret = new short[_spf * 2]; + _blip.EndFrame(master_audio_clock); - nsamp = _spf; - tia.GetSamples(ret); - if (is_pokey) + nsamp = _blip.SamplesAvailable(); + + samples = new short[nsamp * 2]; + + _blip.ReadSamples(samples, nsamp, true); + + for (int i = 0; i < nsamp * 2; i += 2) { - short[] ret2 = new short[_spf * 2]; - pokey.GetSamples(ret2); - for (int i = 0; i < _spf * 2; i ++) - { - ret[i] += (short)(ret2[i] * 3); - } + samples[i + 1] = samples[i]; } - samples = ret; + master_audio_clock = 0; + temp = 0; } public void GetSamplesAsync(short[] samples) @@ -398,7 +422,16 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk public void DiscardSamples() { tia.AudioClocks = 0; - if (is_pokey) { pokey.AudioClocks = 0; } + master_audio_clock = 0; + _blip.Clear(); + + } + + public void DisposeSound() + { + _blip.Clear(); + _blip.Dispose(); + _blip = null; } #endregion diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IStatable.cs index 1a698d4b9d..7a0b6d38fc 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IStatable.cs @@ -40,21 +40,14 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk private void SyncState(Serializer ser) { - byte[] core = null; - if (ser.IsWriter) - { - var ms = new MemoryStream(); - ms.Close(); - core = ms.ToArray(); - } cpu.SyncState(ser); tia.SyncState(ser); maria.SyncState(ser); m6532.SyncState(ser); mapper.SyncState(ser); + pokey.SyncState(ser); ser.BeginSection("Atari7800"); - ser.Sync("core", ref core, false); ser.Sync("Lag", ref _lagcount); ser.Sync("Frame", ref _frame); ser.Sync("IsLag", ref _islag); @@ -62,7 +55,6 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk ser.Sync("A7800_control_register", ref A7800_control_register); ser.Sync("_isPAL", ref _isPAL); - ser.Sync("_spf", ref _spf); ser.Sync("Maria_regs", ref Maria_regs, false); ser.Sync("RAM", ref RAM, false); @@ -87,7 +79,14 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk ser.Sync("left_was_pressed", ref left_was_pressed); ser.Sync("right_was_pressed", ref right_was_pressed); - ser.EndSection(); + ser.Sync("temp_s_tia", ref temp_s_tia); + ser.Sync("temp_s_pokey", ref temp_s_pokey); + ser.Sync("samp_l", ref samp_l); + ser.Sync("samp_c", ref samp_c); + ser.Sync("master_audio_clock", ref master_audio_clock); + ser.Sync("temp", ref temp); + + ser.EndSection(); } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs index 41a953d2a8..fe4f02855d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs @@ -89,6 +89,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk CoreComm = comm; + _blip.SetRates(1789773, 44100); + _settings = (A7800Settings)settings ?? new A7800Settings(); _syncSettings = (A7800SyncSettings)syncSettings ?? new A7800SyncSettings(); _controllerDeck = new A7800HawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2); @@ -280,7 +282,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk _vidbuffer = new int[VirtualWidth * VirtualHeight]; - _spf = (_frameHz > 55) ? 740 : 880; + master_audio_clock = 0; + samp_c = samp_l = 0; } private void ExecFetch(ushort addr) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Pokey.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Pokey.cs index c9c9e22302..2be958f57a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Pokey.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Pokey.cs @@ -22,8 +22,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk { public A7800Hawk Core { get; set; } - public readonly short[] LocalAudioCycles = new short[2000]; - public int AudioClocks; + public int LocalAudioCycles; // state variables public byte[] Regs = new byte[16]; @@ -45,33 +44,15 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk } - public void sample() + public int sample() { - LocalAudioCycles[AudioClocks] += (short)(ch_vol[0] + ch_vol[1] + ch_vol[2] + ch_vol[3]); - AudioClocks++; - } + LocalAudioCycles = 0; + LocalAudioCycles += ch_vol[0]; + LocalAudioCycles += ch_vol[1]; + LocalAudioCycles += ch_vol[2]; + LocalAudioCycles += ch_vol[3]; - public void GetSamples(short[] samples) - { - if (AudioClocks > 0) - { - var samples31Khz = new short[AudioClocks]; // mono - - for (int i = 0; i < AudioClocks; i++) - { - samples31Khz[i] = LocalAudioCycles[i]; - LocalAudioCycles[i] = 0; - } - - // convert from 31khz to 44khz - for (var i = 0; i < samples.Length / 2; i++) - { - samples[i * 2] = samples31Khz[(int)(((double)samples31Khz.Length / (double)(samples.Length / 2)) * i)]; - samples[(i * 2) + 1] = samples[i * 2]; - } - } - - AudioClocks = 0; + return LocalAudioCycles; } public byte ReadReg(int reg) @@ -136,20 +117,33 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk if (Regs[8].Bit(6)) { clock_ch[0] = true; - clock_ch[2] = true; } else { inc_ch[0]++; - inc_ch[2]++; if (Regs[8].Bit(0)) { - if (inc_ch[0] >= 114) { inc_ch[0] = 0; clock_ch[0] = true; } - if (inc_ch[2] >= 114) { inc_ch[2] = 0; clock_ch[2] = true; } + if (inc_ch[0] >= 114) { inc_ch[0] = 0; clock_ch[0] = true; } } else { if (inc_ch[0] >= 28) { inc_ch[0] = 0; clock_ch[0] = true; } + } + } + + if (Regs[8].Bit(5)) + { + clock_ch[2] = true; + } + else + { + inc_ch[2]++; + if (Regs[8].Bit(0)) + { + if (inc_ch[2] >= 114) { inc_ch[2] = 0; clock_ch[2] = true; } + } + else + { if (inc_ch[2] >= 28) { inc_ch[2] = 0; clock_ch[2] = true; } } } @@ -164,6 +158,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk if (Regs[8].Bit(0)) { if (inc_ch[1] >= 114) { inc_ch[1] = 0; clock_ch[1] = true; } + } else { @@ -180,7 +175,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk inc_ch[3]++; if (Regs[8].Bit(0)) { - if (inc_ch[3] >= 114) { inc_ch[3] = 0; clock_ch[3] = true; } + if (inc_ch[3] >= 114) { inc_ch[3] = 0; clock_ch[3] = true; } } else { @@ -251,10 +246,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk else if ((Regs[i * 2 + 1] & 0xF0) == 0xA0) { // tone - if (ch_src[i]) - { ch_out[i] = !ch_out[i]; - } } else if ((Regs[i * 2 + 1] & 0xF0) == 0xC0) { @@ -309,7 +301,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk ser.Sync("high_pass_1", ref high_pass_1); ser.Sync("high_pass_2", ref high_pass_2); - ser.EndSection(); + ser.EndSection(); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/TIA_Sound/TIA.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/TIA_Sound/TIA.cs index d0571d2f5b..0a5739c036 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/TIA_Sound/TIA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/TIA_Sound/TIA.cs @@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk // current audio register state used to sample correct positions in the scanline (clrclk 0 and 114) ////public byte[] current_audio_register = new byte[6]; - public readonly short[] LocalAudioCycles = new short[2000]; + public int LocalAudioCycles; public void Reset() { @@ -34,13 +34,16 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk } // Execute TIA cycles - public void Execute(int cycles) - { - LocalAudioCycles[AudioClocks] += (short)(AUD[0].Cycle() / 2); - LocalAudioCycles[AudioClocks] += (short)(AUD[1].Cycle() / 2); - AudioClocks++; - } + public int Execute(int cycles) + { + LocalAudioCycles = 0; + LocalAudioCycles += (AUD[0].Cycle() / 2); + LocalAudioCycles += (AUD[1].Cycle() / 2); + //AudioClocks++; + return LocalAudioCycles; + } + /* public void GetSamples(short[] samples) { if (AudioClocks > 0) @@ -63,7 +66,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk AudioClocks = 0; } - + */ public byte ReadMemory(ushort addr, bool peek) { var maskedAddr = (ushort)(addr & 0x000F); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs index e236c07464..4d16137978 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Audio.cs @@ -1073,8 +1073,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public bool CanProvideAsync => false; - public short[] AudioSamples = new short[150000]; - public void SetSyncMode(SyncSoundMode mode) { if (mode != SyncSoundMode.Sync)