diff --git a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
index 648ddcc81d..333a3e0f21 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
@@ -67,12 +67,10 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// Get Video data
///
/// opaque state pointer
- /// where to send left audio to
- /// where to send right audio to
- /// number of left samples
- /// number of right samples
+ /// where to send left audio to
+ /// number of left samples
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern uint MSX_get_audio(IntPtr core, uint[] aud_buf_L, uint[] aud_buf_R, ref uint n_samp_L, ref uint n_samp_R);
+ public static extern uint MSX_get_audio(IntPtr core, uint[] aud_buf, ref uint n_samp);
#endregion
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
index 2331e539aa..86924ea5f3 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
@@ -70,27 +70,19 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
MSX_Pntr = IntPtr.Zero;
}
- if (blip_L != null)
+ if (blip != null)
{
- blip_L.Dispose();
- blip_L = null;
- }
-
- if (blip_R != null)
- {
- blip_R.Dispose();
- blip_R = null;
+ blip.Dispose();
+ blip = null;
}
}
#region Audio
- public BlipBuffer blip_L = new BlipBuffer(4500);
- public BlipBuffer blip_R = new BlipBuffer(4500);
+ public BlipBuffer blip = new BlipBuffer(4500);
- public uint[] Aud_L = new uint [9000];
- public uint[] Aud_R = new uint[9000];
- public uint num_samp_L, num_samp_R;
+ public uint[] Aud = new uint [9000];
+ public uint num_samp;
const int blipbuffsize = 4500;
@@ -116,32 +108,24 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
public void GetSamplesSync(out short[] samples, out int nsamp)
{
- uint f_clock = LibMSX.MSX_get_audio(MSX_Pntr, Aud_L, Aud_R, ref num_samp_L, ref num_samp_R);
+ uint f_clock = LibMSX.MSX_get_audio(MSX_Pntr, Aud, ref num_samp);
- for (int i = 0; i < num_samp_L;i++)
+ for (int i = 0; i < num_samp;i++)
{
- blip_L.AddDelta(Aud_L[i * 2], (int)Aud_L[i * 2 + 1]);
+ blip.AddDelta(Aud[i * 2], (int)Aud[i * 2 + 1]);
}
- for (int i = 0; i < num_samp_R; i++)
- {
- blip_R.AddDelta(Aud_R[i * 2], (int)Aud_R[i * 2 + 1]);
- }
+ blip.EndFrame(f_clock);
- blip_L.EndFrame(f_clock);
- blip_R.EndFrame(f_clock);
-
- nsamp = Math.Max(Math.Max(blip_L.SamplesAvailable(), blip_R.SamplesAvailable()), 1);
+ nsamp = blip.SamplesAvailable();
samples = new short[nsamp * 2];
- blip_L.ReadSamplesLeft(samples, nsamp);
- blip_R.ReadSamplesRight(samples, nsamp);
+ blip.ReadSamples(samples, nsamp, true);
}
public void DiscardSamples()
{
- blip_L.Clear();
- blip_R.Clear();
+ blip.Clear();
}
#endregion
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
index e35a1a3af1..19e65498ef 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
@@ -43,8 +43,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
LibMSX.MSX_load_bios(MSX_Pntr, Bios, Basic);
LibMSX.MSX_load(MSX_Pntr, RomData, (uint)RomData.Length, 0, RomData, (uint)RomData.Length, 0);
- blip_L.SetRates(3579545, 44100);
- blip_R.SetRates(3579545, 44100);
+ blip.SetRates(3579545, 44100);
(ServiceProvider as BasicServiceProvider).Register(this);
diff --git a/BizHawk.Emulation.Cores/Consoles/Coleco/AY_3_8910_SGM.cs b/BizHawk.Emulation.Cores/Consoles/Coleco/AY_3_8910_SGM.cs
index d1aef90365..cc21e6a0f7 100644
--- a/BizHawk.Emulation.Cores/Consoles/Coleco/AY_3_8910_SGM.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Coleco/AY_3_8910_SGM.cs
@@ -281,7 +281,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
else
{
- v = (short)(sound_out_A ? VolumeTable[vol_A] : 0);
+ v = (short)(sound_out_A ? VolumeTable[env_E] : 0);
}
if (env_vol_B == 0)
diff --git a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs
index 573cb89d41..ed414dea08 100644
--- a/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs
+++ b/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/Audio.cs
@@ -282,7 +282,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
}
else
{
- v = (short)(sound_out_A ? VolumeTable[vol_A] : 0);
+ v = (short)(sound_out_A ? VolumeTable[env_E] : 0);
}
if (env_vol_B == 0)
diff --git a/libHawk/MSXHawk/MSXHawk/AY_3_8910.h b/libHawk/MSXHawk/MSXHawk/AY_3_8910.h
new file mode 100644
index 0000000000..77a36ad53e
--- /dev/null
+++ b/libHawk/MSXHawk/MSXHawk/AY_3_8910.h
@@ -0,0 +1,439 @@
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+namespace MSXHawk
+{
+ class AY_3_8910
+ {
+ public:
+
+ #pragma region AY_3_8910
+
+ AY_3_8910()
+ {
+ Reset();
+ }
+
+ bool A_on, B_on, C_on;
+ bool A_up, B_up, C_up;
+ bool A_noise, B_noise, C_noise;
+ bool env_vol_A, env_vol_B, env_vol_C;
+
+ uint8_t env_shape;
+ uint8_t port_sel;
+ uint8_t vol_A, vol_B, vol_C;
+ uint8_t Register[16] = {};
+
+ uint32_t psg_clock;
+ uint32_t sq_per_A, sq_per_B, sq_per_C;
+ uint32_t clock_A, clock_B, clock_C;
+
+ uint32_t env_per;
+ uint32_t env_clock;
+
+ int32_t env_E;
+ int32_t E_up_down;
+
+ uint32_t noise_clock;
+ uint32_t noise_per;
+ uint32_t noise = 0x1;
+
+ uint32_t old_sample;
+
+ // non stated if only on frame boundaries
+ bool sound_out_A;
+ bool sound_out_B;
+ bool sound_out_C;
+
+ uint8_t Clock_Divider;
+
+ uint32_t current_sample;
+ uint32_t sampleclock;
+ uint32_t num_samples;
+ uint32_t samples[9000] = {};
+
+ void Reset()
+ {
+ clock_A = clock_B = clock_C = 0x1000;
+ noise_clock = 0x20;
+ port_sel = 0;
+
+ for (int i = 0; i < 16; i++)
+ {
+ Register[i] = 0x0;
+ }
+ sync_psg_state();
+ }
+
+ short Sample()
+ {
+ return current_sample;
+ }
+
+ const uint32_t VolumeTable[16] =
+ {
+ 0x0000, 0x0055, 0x0079, 0x00AB, 0x00F1, 0x0155, 0x01E3, 0x02AA,
+ 0x03C5, 0x0555, 0x078B, 0x0AAB, 0x0F16, 0x1555, 0x1E2B, 0x2AAA
+ };
+
+ uint8_t ReadReg()
+ {
+ return Register[port_sel];
+ }
+
+ void sync_psg_state()
+ {
+ sq_per_A = (Register[0] & 0xFF) | (((Register[1] & 0xF) << 8));
+ if (sq_per_A == 0)
+ {
+ sq_per_A = 0x1000;
+ }
+
+ sq_per_B = (Register[2] & 0xFF) | (((Register[3] & 0xF) << 8));
+ if (sq_per_B == 0)
+ {
+ sq_per_B = 0x1000;
+ }
+
+ sq_per_C = (Register[4] & 0xFF) | (((Register[5] & 0xF) << 8));
+ if (sq_per_C == 0)
+ {
+ sq_per_C = 0x1000;
+ }
+
+ env_per = (Register[11] & 0xFF) | (((Register[12] & 0xFF) << 8));
+ if (env_per == 0)
+ {
+ env_per = 0x10000;
+ }
+
+ env_per *= 2;
+
+ A_on = (Register[7] & 0x1) > 0;
+ B_on = (Register[7] & 0x2) > 0;
+ C_on = (Register[7] & 0x4) > 0;
+ A_noise = (Register[7] & 0x8) > 0;
+ B_noise = (Register[7] & 0x10) > 0;
+ C_noise = (Register[7] & 0x20) > 0;
+
+ noise_per = Register[6] & 0x1F;
+ if (noise_per == 0)
+ {
+ noise_per = 0x20;
+ }
+
+ uint8_t shape_select = Register[13] & 0xF;
+
+ if (shape_select < 4) { env_shape = 0; }
+ else if (shape_select < 8) { env_shape = 1; }
+ else { env_shape = 2 + (shape_select - 8); }
+
+ vol_A = Register[8] & 0xF;
+ env_vol_A = ((Register[8] >> 4) & 0x1) > 0;
+
+ vol_B = Register[9] & 0xF;
+ env_vol_B = ((Register[9] >> 4) & 0x1) > 0;
+
+ vol_C = Register[10] & 0xF;
+ env_vol_C = ((Register[10] >> 4) & 0x1) > 0;
+ }
+
+ void WriteReg(uint8_t value)
+ {
+ value &= 0xFF;
+
+ Register[port_sel] = value;
+
+ sync_psg_state();
+
+ if (port_sel == 13)
+ {
+ env_clock = env_per;
+
+ if (env_shape == 0 || env_shape == 2 || env_shape == 3 || env_shape == 4 || env_shape == 5)
+ {
+ env_E = 15;
+ E_up_down = -1;
+ }
+ else
+ {
+ env_E = 0;
+ E_up_down = 1;
+ }
+ }
+ }
+
+ void generate_sound()
+ {
+ // there are 8 cpu cycles for every psg cycle
+ clock_A--;
+ clock_B--;
+ clock_C--;
+
+ noise_clock--;
+ env_clock--;
+
+ // clock noise
+ if (noise_clock == 0)
+ {
+ noise = (noise >> 1) ^ (((noise &0x1) > 0) ? 0x10004 : 0);
+ noise_clock = noise_per;
+ }
+
+ if (env_clock == 0)
+ {
+ env_clock = env_per;
+
+ env_E += E_up_down;
+
+ if (env_E == 16 || env_E == -1)
+ {
+ // we just completed a period of the envelope, determine what to do now based on the envelope shape
+ if (env_shape == 0 || env_shape == 1 || env_shape == 3 || env_shape == 9)
+ {
+ E_up_down = 0;
+ env_E = 0;
+ }
+ else if (env_shape == 5 || env_shape == 7)
+ {
+ E_up_down = 0;
+ env_E = 15;
+ }
+ else if (env_shape == 4 || env_shape == 8)
+ {
+ if (env_E == 16)
+ {
+ env_E = 15;
+ E_up_down = -1;
+ }
+ else
+ {
+ env_E = 0;
+ E_up_down = 1;
+ }
+ }
+ else if (env_shape == 2)
+ {
+ env_E = 15;
+ }
+ else
+ {
+ env_E = 0;
+ }
+ }
+ }
+
+ if (clock_A == 0)
+ {
+ A_up = !A_up;
+ clock_A = sq_per_A;
+ }
+
+ if (clock_B == 0)
+ {
+ B_up = !B_up;
+ clock_B = sq_per_B;
+ }
+
+ if (clock_C == 0)
+ {
+ C_up = !C_up;
+ clock_C = sq_per_C;
+ }
+
+ sound_out_A = (((noise & 0x1) > 0) | A_noise) & (A_on | A_up);
+ sound_out_B = (((noise & 0x1) > 0) | B_noise) & (B_on | B_up);
+ sound_out_C = (((noise & 0x1) > 0) | C_noise) & (C_on | C_up);
+
+ // now calculate the volume of each channel and add them together
+ current_sample = 0;
+
+ if (env_vol_A)
+ {
+ current_sample = (sound_out_A ? VolumeTable[env_E] : 0);
+ }
+ else
+ {
+ current_sample = (sound_out_A ? VolumeTable[vol_A] : 0);
+ }
+
+ if (env_vol_B)
+ {
+ current_sample += (sound_out_B ? VolumeTable[env_E] : 0);
+ }
+ else
+ {
+ current_sample += (sound_out_B ? VolumeTable[vol_B] : 0);
+ }
+
+ if (env_vol_C)
+ {
+ current_sample += (sound_out_C ? VolumeTable[env_E] : 0);
+ }
+ else
+ {
+ current_sample += (sound_out_C ? VolumeTable[vol_C] : 0);
+ }
+
+ if ((current_sample != old_sample) && (num_samples < 4500))
+ {
+ samples[num_samples * 2] = sampleclock;
+ samples[num_samples * 2 + 1] = current_sample - old_sample;
+ num_samples++;
+ old_sample = current_sample;
+ }
+ }
+
+ #pragma endregion
+
+ #pragma region State Save / Load
+
+ uint8_t* SaveState(uint8_t* saver)
+ {
+ *saver = (uint8_t)(A_on ? 1 : 0); saver++;
+ *saver = (uint8_t)(B_on ? 1 : 0); saver++;
+ *saver = (uint8_t)(C_on ? 1 : 0); saver++;
+ *saver = (uint8_t)(A_up ? 1 : 0); saver++;
+ *saver = (uint8_t)(B_up ? 1 : 0); saver++;
+ *saver = (uint8_t)(C_up ? 1 : 0); saver++;
+ *saver = (uint8_t)(A_noise ? 1 : 0); saver++;
+ *saver = (uint8_t)(B_noise ? 1 : 0); saver++;
+ *saver = (uint8_t)(C_noise ? 1 : 0); saver++;
+ *saver = (uint8_t)(env_vol_A ? 1 : 0); saver++;
+ *saver = (uint8_t)(env_vol_B ? 1 : 0); saver++;
+ *saver = (uint8_t)(env_vol_C ? 1 : 0); saver++;
+
+ *saver = env_shape; saver++;
+ *saver = port_sel; saver++;
+ *saver = vol_A; saver++;
+ *saver = vol_B; saver++;
+ *saver = vol_C; saver++;
+
+ for (int i = 0; i < 16; i++) { *saver = Register[i]; saver++; }
+
+ *saver = (uint8_t)(psg_clock & 0xFF); saver++; *saver = (uint8_t)((psg_clock >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((psg_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((psg_clock >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(sq_per_A & 0xFF); saver++; *saver = (uint8_t)((sq_per_A >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((sq_per_A >> 16) & 0xFF); saver++; *saver = (uint8_t)((sq_per_A >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(sq_per_B & 0xFF); saver++; *saver = (uint8_t)((sq_per_B >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((sq_per_B >> 16) & 0xFF); saver++; *saver = (uint8_t)((sq_per_B >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(sq_per_C & 0xFF); saver++; *saver = (uint8_t)((sq_per_C >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((sq_per_C >> 16) & 0xFF); saver++; *saver = (uint8_t)((sq_per_C >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(clock_A & 0xFF); saver++; *saver = (uint8_t)((clock_A >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((clock_A >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_A >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(clock_B & 0xFF); saver++; *saver = (uint8_t)((clock_B >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((clock_B >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_B >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(clock_C & 0xFF); saver++; *saver = (uint8_t)((clock_C >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((clock_C >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_C >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(env_per & 0xFF); saver++; *saver = (uint8_t)((env_per >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((env_per >> 16) & 0xFF); saver++; *saver = (uint8_t)((env_per >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(env_clock & 0xFF); saver++; *saver = (uint8_t)((env_clock >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((env_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((env_clock >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(env_E & 0xFF); saver++; *saver = (uint8_t)((env_E >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((env_E >> 16) & 0xFF); saver++; *saver = (uint8_t)((env_E >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(E_up_down & 0xFF); saver++; *saver = (uint8_t)((E_up_down >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((E_up_down >> 16) & 0xFF); saver++; *saver = (uint8_t)((E_up_down >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(noise_clock & 0xFF); saver++; *saver = (uint8_t)((noise_clock >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((noise_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise_clock >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(noise_per & 0xFF); saver++; *saver = (uint8_t)((noise_per >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((noise_per >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise_per >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(noise & 0xFF); saver++; *saver = (uint8_t)((noise >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((noise >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise >> 24) & 0xFF); saver++;
+
+ *saver = (uint8_t)(old_sample & 0xFF); saver++; *saver = (uint8_t)((old_sample >> 8) & 0xFF); saver++;
+ *saver = (uint8_t)((old_sample >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample >> 24) & 0xFF); saver++;
+
+ return saver;
+ }
+
+ uint8_t* LoadState(uint8_t* loader)
+ {
+ A_on = *loader == 1; loader++;
+ B_on = *loader == 1; loader++;
+ C_on = *loader == 1; loader++;
+ A_up = *loader == 1; loader++;
+ B_up = *loader == 1; loader++;
+ C_up = *loader == 1; loader++;
+ A_noise = *loader == 1; loader++;
+ B_noise = *loader == 1; loader++;
+ C_noise = *loader == 1; loader++;
+ env_vol_A = *loader == 1; loader++;
+ env_vol_B = *loader == 1; loader++;
+ env_vol_C = *loader == 1; loader++;
+
+ env_shape = *loader; loader++;
+ port_sel = *loader; loader++;
+ vol_A = *loader; loader++;
+ vol_B = *loader; loader++;
+ vol_C = *loader; loader++;
+
+ for (int i = 0; i < 16; i++) { Register[i] = *loader; loader++; }
+
+ psg_clock = *loader; loader++; psg_clock |= (*loader << 8); loader++;
+ psg_clock |= (*loader << 16); loader++; psg_clock |= (*loader << 24); loader++;
+
+ sq_per_A = *loader; loader++; sq_per_A |= (*loader << 8); loader++;
+ sq_per_A |= (*loader << 16); loader++; sq_per_A |= (*loader << 24); loader++;
+
+ sq_per_B = *loader; loader++; sq_per_B |= (*loader << 8); loader++;
+ sq_per_B |= (*loader << 16); loader++; sq_per_B |= (*loader << 24); loader++;
+
+ sq_per_C = *loader; loader++; sq_per_C |= (*loader << 8); loader++;
+ sq_per_C |= (*loader << 16); loader++; sq_per_C |= (*loader << 24); loader++;
+
+ clock_A = *loader; loader++; clock_A |= (*loader << 8); loader++;
+ clock_A |= (*loader << 16); loader++; clock_A |= (*loader << 24); loader++;
+
+ clock_B = *loader; loader++; clock_B |= (*loader << 8); loader++;
+ clock_B |= (*loader << 16); loader++; clock_B |= (*loader << 24); loader++;
+
+ clock_C = *loader; loader++; clock_C |= (*loader << 8); loader++;
+ clock_C |= (*loader << 16); loader++; clock_C |= (*loader << 24); loader++;
+
+ env_per = *loader; loader++; env_per |= (*loader << 8); loader++;
+ env_per |= (*loader << 16); loader++; env_per |= (*loader << 24); loader++;
+
+ env_clock = *loader; loader++; env_clock |= (*loader << 8); loader++;
+ env_clock |= (*loader << 16); loader++; env_clock |= (*loader << 24); loader++;
+
+ env_E = *loader; loader++; env_E |= (*loader << 8); loader++;
+ env_E |= (*loader << 16); loader++; env_E |= (*loader << 24); loader++;
+
+ E_up_down = *loader; loader++; E_up_down |= (*loader << 8); loader++;
+ E_up_down |= (*loader << 16); loader++; E_up_down |= (*loader << 24); loader++;
+
+ noise_clock = *loader; loader++; noise_clock |= (*loader << 8); loader++;
+ noise_clock |= (*loader << 16); loader++; noise_clock |= (*loader << 24); loader++;
+
+ noise_per = *loader; loader++; noise_per |= (*loader << 8); loader++;
+ noise_per |= (*loader << 16); loader++; noise_per |= (*loader << 24); loader++;
+
+ noise = *loader; loader++; noise |= (*loader << 8); loader++;
+ noise |= (*loader << 16); loader++; noise |= (*loader << 24); loader++;
+
+ old_sample = *loader; loader++; old_sample |= (*loader << 8); loader++;
+ old_sample |= (*loader << 16); loader++; old_sample |= (*loader << 24); loader++;
+
+ return loader;
+ }
+
+ #pragma endregion
+ };
+}
\ No newline at end of file
diff --git a/libHawk/MSXHawk/MSXHawk/Core.h b/libHawk/MSXHawk/MSXHawk/Core.h
index 013b7d49af..f933315b1f 100644
--- a/libHawk/MSXHawk/MSXHawk/Core.h
+++ b/libHawk/MSXHawk/MSXHawk/Core.h
@@ -4,7 +4,7 @@
#include
#include "Z80A.h"
-#include "PSG.h"
+#include "AY_3_8910.h"
#include "TMS9918A.h"
#include "Memory.h"
@@ -26,7 +26,7 @@ namespace MSXHawk
TMS9918A vdp;
Z80A cpu;
- SN76489sms psg;
+ AY_3_8910 psg;
MemoryManager MemMap;
void Load_BIOS(uint8_t* bios, uint8_t* basic)
@@ -49,8 +49,7 @@ namespace MSXHawk
uint32_t scanlinesPerFrame = 262;
vdp.SpriteLimit = true;
- psg.num_samples_L = 0;
- psg.num_samples_R = 0;
+ psg.num_samples = 0;
psg.sampleclock = 0;
for (uint32_t i = 0; i < scanlinesPerFrame; i++)
@@ -90,19 +89,13 @@ namespace MSXHawk
std::memcpy(dst, src, sizeof uint32_t * 256 * 192);
}
- uint32_t GetAudio(uint32_t* dest_L, uint32_t* dest_R, uint32_t* n_samp_L, uint32_t* n_samp_R)
+ uint32_t GetAudio(uint32_t* dest, uint32_t* n_samp)
{
- uint32_t* src_L = psg.samples_L;
- uint32_t* dst_L = dest_L;
+ uint32_t* src = psg.samples;
+ uint32_t* dst = dest;
- std::memcpy(dst_L, src_L, sizeof uint32_t * psg.num_samples_L * 2);
- n_samp_L[0] = psg.num_samples_L;
-
- uint32_t* src_R = psg.samples_R;
- uint32_t* dst_R = dest_R;
-
- std::memcpy(dst_R, src_R, sizeof uint32_t * psg.num_samples_R * 2);
- n_samp_R[0] = psg.num_samples_R;
+ std::memcpy(dst, src, sizeof uint32_t * psg.num_samples * 2);
+ n_samp[0] = psg.num_samples;
return psg.sampleclock;
}
diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
index 7bb21252a5..a122e11a1b 100644
--- a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
+++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
@@ -54,9 +54,9 @@ MSXHawk_EXPORT void MSX_get_video(MSXCore* p, uint32_t* dest)
}
// send audio data to external audio provider
-MSXHawk_EXPORT uint32_t MSX_get_audio(MSXCore* p, uint32_t* dest_L, uint32_t* dest_R, uint32_t* n_samp_L, uint32_t* n_samp_R)
+MSXHawk_EXPORT uint32_t MSX_get_audio(MSXCore* p, uint32_t* dest, uint32_t* n_samp)
{
- return p->GetAudio(dest_L, dest_R, n_samp_L, n_samp_R);
+ return p->GetAudio(dest, n_samp);
}
#pragma region State Save / Load
diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj b/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj
index b1dfcdac86..6176713181 100644
--- a/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj
+++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj
@@ -161,7 +161,7 @@
-
+
diff --git a/libHawk/MSXHawk/MSXHawk/Memory.cpp b/libHawk/MSXHawk/MSXHawk/Memory.cpp
index 8e1c17169e..f61c9eaea2 100644
--- a/libHawk/MSXHawk/MSXHawk/Memory.cpp
+++ b/libHawk/MSXHawk/MSXHawk/Memory.cpp
@@ -6,7 +6,7 @@
#include "Memory.h"
#include "Z80A.h"
#include "TMS9918A.h"
-#include "PSG.h"
+#include "AY_3_8910.h"
using namespace std;
@@ -24,9 +24,9 @@ namespace MSXHawk
{
return vdp_pntr->ReadVdpStatus();
}
- else if (port == 0xA1)
+ else if (port == 0xA2)
{
- // not readable
+ return psg_pntr->ReadReg();
}
else if (port == 0xA8)
{
@@ -47,7 +47,11 @@ namespace MSXHawk
else if(port == 0x99) // VDP
{
vdp_pntr->WriteVdpControl(value);
- }
+ }
+ else if (port == 0xA0)
+ {
+ psg_pntr->port_sel = (value & 0xF);
+ }
else if (port == 0xA1)
{
psg_pntr->WriteReg(value);
diff --git a/libHawk/MSXHawk/MSXHawk/Memory.h b/libHawk/MSXHawk/MSXHawk/Memory.h
index b34ac72e66..d9c60d36e4 100644
--- a/libHawk/MSXHawk/MSXHawk/Memory.h
+++ b/libHawk/MSXHawk/MSXHawk/Memory.h
@@ -9,14 +9,14 @@ namespace MSXHawk
{
class Z80A;
class TMS9918A;
- class SN76489sms;
+ class AY_3_8910;
class MemoryManager
{
public:
TMS9918A* vdp_pntr = nullptr;
- SN76489sms* psg_pntr = nullptr;
+ AY_3_8910* psg_pntr = nullptr;
Z80A* cpu_pntr = nullptr;
uint8_t* rom_1 = nullptr;
uint8_t* rom_2 = nullptr;
diff --git a/libHawk/MSXHawk/MSXHawk/PSG.h b/libHawk/MSXHawk/MSXHawk/PSG.h
deleted file mode 100644
index de535cd9bd..0000000000
--- a/libHawk/MSXHawk/MSXHawk/PSG.h
+++ /dev/null
@@ -1,360 +0,0 @@
-#include
-#include
-#include
-#include
-
-using namespace std;
-
-namespace MSXHawk
-{
- class SN76489sms
- {
- public:
-
- #pragma region PSG
-
- bool vol_tone;
- bool noise_type;
- bool noise_bit;
- bool A_L, B_L, C_L, noise_L;
- bool A_R, B_R, C_R, noise_R;
- bool A_up, B_up, C_up;
-
- uint8_t Chan_vol[4];
- uint8_t stereo_panning;
- uint8_t chan_sel;
- uint8_t noise_rate;
-
- uint16_t Chan_tone[4];
-
- uint32_t psg_clock;
- uint32_t clock_A, clock_B, clock_C;
- uint32_t noise_clock;
- uint32_t noise;
-
- // only old_sample_L/R is savestated, this only works if savestates are only made at frame boundaries
- // These would need to be included for subframe states
- uint32_t old_sample_L;
- uint32_t old_sample_R;
- uint32_t current_sample_L;
- uint32_t current_sample_R;
- uint32_t sampleclock;
- uint32_t num_samples_L;
- uint32_t num_samples_R;
- uint32_t samples_L[9000] = {};
- uint32_t samples_R[9000] = {};
- uint32_t Clock_Divider;
-
- const uint8_t LogScale[16] = { 255, 203, 161, 128, 102, 86, 64, 51, 40, 32, 26, 20, 16, 13, 10, 0 };
-
- SN76489sms()
- {
- Reset();
- }
-
- void Reset()
- {
- clock_A = clock_B = clock_C = 0x1000;
- noise_clock = 0x10;
- chan_sel = 0;
-
- // reset the shift register
- noise = 0x40000;
-
- Chan_vol[0] = 0xF;
- Chan_vol[1] = 0xF;
- Chan_vol[2] = 0xF;
- Chan_vol[3] = 0xF;
-
- Set_Panning(0xFF);
- }
-
- void Set_Panning(uint8_t value)
- {
- A_L = (value & 0x10) != 0;
- A_R = (value & 0x01) != 0;
- B_L = (value & 0x20) != 0;
- B_R = (value & 0x02) != 0;
- C_L = (value & 0x40) != 0;
- C_R = (value & 0x04) != 0;
- noise_L = (value & 0x80) != 0;
- noise_R = (value & 0x08) != 0;
-
- stereo_panning = value;
- }
-
- uint8_t ReadReg()
- {
- // not used, reading not allowed, just return 0xFF
- return 0xFF;
- }
-
- void WriteReg(uint8_t value)
- {
- // if bit 7 is set, change the latch, otherwise modify the currently latched register
- if ((value & 0x80) > 0)
- {
- chan_sel = (value >> 5) & 3;
- vol_tone = ((value & 0x10) > 0);
-
- if (vol_tone)
- {
- Chan_vol[chan_sel] = (uint8_t)(value & 0xF);
- }
- else
- {
- if (chan_sel < 3)
- {
- Chan_tone[chan_sel] &= 0x3F0;
- Chan_tone[chan_sel] |= (uint16_t)(value & 0xF);
- }
- else
- {
- noise_type = ((value & 0x4) > 0);
- noise_rate = value & 3;
-
- // reset the shift register
- noise = 0x40000;
- }
- }
- }
- else
- {
- if (vol_tone)
- {
- Chan_vol[chan_sel] = (uint8_t)(value & 0xF);
- }
- else
- {
- if (chan_sel < 3)
- {
- Chan_tone[chan_sel] &= 0xF;
- Chan_tone[chan_sel] |= (uint16_t)((value & 0x3F) << 4);
- }
- else
- {
- noise_type = ((value & 0x4) > 0);
- noise_rate = value & 3;
-
- // reset the shift register
- noise = 0x40000;
- }
- }
- }
- }
-
- void generate_sound()
- {
- clock_A--;
- clock_B--;
- clock_C--;
- noise_clock--;
-
- // clock noise
- if (noise_clock == 0)
- {
- noise_bit = ((noise & 1) > 0);
- if (noise_type)
- {
- noise = (((noise & 1) ^ ((noise >> 1) & 1)) << 14) | (noise >> 1);
- }
- else
- {
- noise = ((noise & 1) << 14) | (noise >> 1);
- }
-
- if (noise_rate == 0)
- {
- noise_clock = 0x10;
- }
- else if (noise_rate == 1)
- {
- noise_clock = 0x20;
- }
- else if (noise_rate == 2)
- {
- noise_clock = 0x40;
- }
- else
- {
- noise_clock = Chan_tone[2] + 1;
- }
-
- noise_clock *= 2;
- }
-
- if (clock_A == 0)
- {
- A_up = !A_up;
- clock_A = Chan_tone[0] + 1;
- }
-
- if (clock_B == 0)
- {
- B_up = !B_up;
- clock_B = Chan_tone[1] + 1;
- }
-
- if (clock_C == 0)
- {
- C_up = !C_up;
- clock_C = Chan_tone[2] + 1;
- }
-
- // now calculate the volume of each channel and add them together
- current_sample_L = (A_L ? (A_up ? LogScale[Chan_vol[0]] * 42 : 0) : 0);
-
- current_sample_L += (B_L ? (B_up ? LogScale[Chan_vol[1]] * 42 : 0) : 0);
-
- current_sample_L += (C_L ? (C_up ? LogScale[Chan_vol[2]] * 42 : 0) : 0);
-
- current_sample_L += (noise_L ? (noise_bit ? LogScale[Chan_vol[3]] * 42 : 0) : 0);
-
- current_sample_R = (A_R ? (A_up ? LogScale[Chan_vol[0]] * 42 : 0) : 0);
-
- current_sample_R += (B_R ? (B_up ? LogScale[Chan_vol[1]] * 42 : 0) : 0);
-
- current_sample_R += (C_R ? (C_up ? LogScale[Chan_vol[2]] * 42 : 0) : 0);
-
- current_sample_R += (noise_R ? (noise_bit ? LogScale[Chan_vol[3]] * 42 : 0) : 0);
-
- if ((current_sample_L != old_sample_L) && (num_samples_L < 4500))
- {
- samples_L[num_samples_L * 2] = sampleclock;
- samples_L[num_samples_L * 2 + 1] = current_sample_L - old_sample_L;
- num_samples_L++;
- old_sample_L = current_sample_L;
- }
-
- if ((current_sample_R != old_sample_R) && (num_samples_R < 4500))
- {
- samples_R[num_samples_R * 2] = sampleclock;
- samples_R[num_samples_R * 2 + 1] = current_sample_R - old_sample_R;
- num_samples_R++;
- old_sample_R = current_sample_R;
- }
- }
-
- #pragma endregion
-
- #pragma region State Save / Load
-
- uint8_t* SaveState(uint8_t* saver)
- {
- *saver = (uint8_t)(vol_tone ? 1 : 0); saver++;
- *saver = (uint8_t)(noise_type ? 1 : 0); saver++;
- *saver = (uint8_t)(noise_bit ? 1 : 0); saver++;
- *saver = (uint8_t)(A_L ? 1 : 0); saver++;
- *saver = (uint8_t)(B_L ? 1 : 0); saver++;
- *saver = (uint8_t)(C_L ? 1 : 0); saver++;
- *saver = (uint8_t)(noise_L ? 1 : 0); saver++;
- *saver = (uint8_t)(A_R ? 1 : 0); saver++;
- *saver = (uint8_t)(B_R ? 1 : 0); saver++;
- *saver = (uint8_t)(C_R ? 1 : 0); saver++;
- *saver = (uint8_t)(noise_R ? 1 : 0); saver++;
- *saver = (uint8_t)(A_up ? 1 : 0); saver++;
- *saver = (uint8_t)(B_up ? 1 : 0); saver++;
- *saver = (uint8_t)(C_up ? 1 : 0); saver++;
-
- *saver = Chan_vol[0]; saver++;
- *saver = Chan_vol[1]; saver++;
- *saver = Chan_vol[2]; saver++;
- *saver = Chan_vol[3]; saver++;
-
- *saver = stereo_panning; saver++;
- *saver = chan_sel; saver++;
- *saver = noise_rate; saver++;
-
- *saver = (uint8_t)(Chan_tone[0] & 0xFF); saver++; *saver = (uint8_t)((Chan_tone[0] >> 8) & 0xFF); saver++;
- *saver = (uint8_t)(Chan_tone[1] & 0xFF); saver++; *saver = (uint8_t)((Chan_tone[1] >> 8) & 0xFF); saver++;
- *saver = (uint8_t)(Chan_tone[2] & 0xFF); saver++; *saver = (uint8_t)((Chan_tone[2] >> 8) & 0xFF); saver++;
- *saver = (uint8_t)(Chan_tone[3] & 0xFF); saver++; *saver = (uint8_t)((Chan_tone[3] >> 8) & 0xFF); saver++;
-
- *saver = (uint8_t)(psg_clock & 0xFF); saver++; *saver = (uint8_t)((psg_clock >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((psg_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((psg_clock >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(clock_A & 0xFF); saver++; *saver = (uint8_t)((clock_A >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((clock_A >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_A >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(clock_B & 0xFF); saver++; *saver = (uint8_t)((clock_B >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((clock_B >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_B >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(clock_C & 0xFF); saver++; *saver = (uint8_t)((clock_C >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((clock_C >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_C >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(noise_clock & 0xFF); saver++; *saver = (uint8_t)((noise_clock >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((noise_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise_clock >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(noise & 0xFF); saver++; *saver = (uint8_t)((noise >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((noise >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(old_sample_L & 0xFF); saver++; *saver = (uint8_t)((old_sample_L >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((old_sample_L >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample_L >> 24) & 0xFF); saver++;
-
- *saver = (uint8_t)(old_sample_R & 0xFF); saver++; *saver = (uint8_t)((old_sample_R >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((old_sample_R >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample_R >> 24) & 0xFF); saver++;
-
- return saver;
- }
-
- uint8_t* LoadState(uint8_t* loader)
- {
- vol_tone = *loader == 1; loader++;
- noise_type = *loader == 1; loader++;
- noise_bit = *loader == 1; loader++;
- A_L = *loader == 1; loader++;
- B_L = *loader == 1; loader++;
- C_L = *loader == 1; loader++;
- noise_L = *loader == 1; loader++;
- A_R = *loader == 1; loader++;
- B_R = *loader == 1; loader++;
- C_R = *loader == 1; loader++;
- noise_R = *loader == 1; loader++;
- A_up = *loader == 1; loader++;
- B_up = *loader == 1; loader++;
- C_up = *loader == 1; loader++;
-
- Chan_vol[0] = *loader; loader++;
- Chan_vol[1] = *loader; loader++;
- Chan_vol[2] = *loader; loader++;
- Chan_vol[3] = *loader; loader++;
-
- stereo_panning = *loader; loader++;
- chan_sel = *loader; loader++;
- noise_rate = *loader; loader++;
-
- Chan_tone[0] = *loader; loader++; Chan_tone[0] |= (*loader << 8); loader++;
- Chan_tone[1] = *loader; loader++; Chan_tone[1] |= (*loader << 8); loader++;
- Chan_tone[2] = *loader; loader++; Chan_tone[2] |= (*loader << 8); loader++;
- Chan_tone[3] = *loader; loader++; Chan_tone[3] |= (*loader << 8); loader++;
-
- psg_clock = *loader; loader++; psg_clock |= (*loader << 8); loader++;
- psg_clock |= (*loader << 16); loader++; psg_clock |= (*loader << 24); loader++;
-
- clock_A = *loader; loader++; clock_A |= (*loader << 8); loader++;
- clock_A |= (*loader << 16); loader++; clock_A |= (*loader << 24); loader++;
-
- clock_B = *loader; loader++; clock_B |= (*loader << 8); loader++;
- clock_B |= (*loader << 16); loader++; clock_B |= (*loader << 24); loader++;
-
- clock_C = *loader; loader++; clock_C |= (*loader << 8); loader++;
- clock_C |= (*loader << 16); loader++; clock_C |= (*loader << 24); loader++;
-
- noise_clock = *loader; loader++; noise_clock |= (*loader << 8); loader++;
- noise_clock |= (*loader << 16); loader++; noise_clock |= (*loader << 24); loader++;
-
- noise = *loader; loader++; noise |= (*loader << 8); loader++;
- noise |= (*loader << 16); loader++; noise |= (*loader << 24); loader++;
-
- old_sample_L = *loader; loader++; old_sample_L |= (*loader << 8); loader++;
- old_sample_L |= (*loader << 16); loader++; old_sample_L |= (*loader << 24); loader++;
-
- old_sample_R = *loader; loader++; old_sample_R |= (*loader << 8); loader++;
- old_sample_R |= (*loader << 16); loader++; old_sample_R |= (*loader << 24); loader++;
-
- return loader;
- }
-
- #pragma endregion
- };
-}
\ No newline at end of file
diff --git a/libHawk/MSXHawk/MSXHawk/TMS9918A.h b/libHawk/MSXHawk/MSXHawk/TMS9918A.h
index c07c2676af..298a0c4428 100644
--- a/libHawk/MSXHawk/MSXHawk/TMS9918A.h
+++ b/libHawk/MSXHawk/MSXHawk/TMS9918A.h
@@ -45,11 +45,35 @@ namespace MSXHawk
uint32_t TmsSpriteAttributeBase;
uint32_t FrameBuffer[192 * 256] = {};
+ uint8_t ScanlinePriorityBuffer[256] = {};
+ uint8_t SpriteCollisionBuffer[256] = {};
// constants after load, not stated
uint32_t BackgroundColor = 0;
uint32_t IPeriod = 228;
+ // temporary variables not stated if on frame boundary
+ bool is_top;
+ uint32_t yc;
+ uint32_t yofs;
+ uint32_t FrameBufferOffset;
+ uint32_t PatternNameOffset;
+ uint32_t ScreenBGColor;
+ uint32_t yrow;
+ uint32_t PatternGeneratorOffset;
+ uint32_t ColorOffset;
+ uint32_t pn;
+ uint32_t pv;
+ uint32_t colorEntry;
+ uint32_t fgIndex;
+ uint32_t bgIndex;
+ uint32_t fgColor;
+ uint32_t bgColor;
+ uint32_t lColorIndex;
+ uint32_t rColorIndex;
+ uint32_t lColor;
+ uint32_t rColor;
+
uint32_t PaletteTMS9918[16] =
{
0xFF000000,
@@ -105,8 +129,7 @@ namespace MSXHawk
case 0x40: // write VRAM
break;
case 0x80: // VDP register write
- uint32_t reg = value & 0x0F;
- WriteRegister(reg, VdpLatch);
+ WriteRegister(value & 0x0F, VdpLatch);
break;
}
}
@@ -218,21 +241,21 @@ namespace MSXHawk
return;
}
- uint32_t yc = scanLine / 8;
- uint32_t yofs = scanLine % 8;
- uint32_t FrameBufferOffset = scanLine * 256;
- uint32_t PatternNameOffset = TmsPatternNameTableBase + (yc * 32);
- uint32_t ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
+ yc = scanLine / 8;
+ yofs = scanLine % 8;
+ FrameBufferOffset = scanLine * 256;
+ PatternNameOffset = TmsPatternNameTableBase + (yc * 32);
+ ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
for (uint32_t xc = 0; xc < 32; xc++)
{
- uint32_t pn = VRAM[PatternNameOffset++];
- uint32_t pv = VRAM[PatternGeneratorBase + (pn * 8) + yofs];
- uint32_t colorEntry = VRAM[ColorTableBase + (pn / 8)];
- uint32_t fgIndex = (colorEntry >> 4) & 0x0F;
- uint32_t bgIndex = colorEntry & 0x0F;
- uint32_t fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
- uint32_t bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
+ pn = VRAM[PatternNameOffset++];
+ pv = VRAM[PatternGeneratorBase + (pn * 8) + yofs];
+ colorEntry = VRAM[ColorTableBase + (pn / 8)];
+ fgIndex = (colorEntry >> 4) & 0x0F;
+ bgIndex = colorEntry & 0x0F;
+ fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
+ bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
FrameBuffer[FrameBufferOffset++] = ((pv & 0x80) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x40) > 0) ? fgColor : bgColor;
@@ -253,21 +276,21 @@ namespace MSXHawk
return;
}
- uint32_t yc = scanLine / 8;
- uint32_t yofs = scanLine % 8;
- uint32_t FrameBufferOffset = scanLine * 256;
- uint32_t PatternNameOffset = TmsPatternNameTableBase + (yc * 40);
- uint32_t ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
+ yc = scanLine / 8;
+ yofs = scanLine % 8;
+ FrameBufferOffset = scanLine * 256;
+ PatternNameOffset = TmsPatternNameTableBase + (yc * 40);
+ ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
for (uint32_t xc = 0; xc < 40; xc++)
{
- uint32_t pn = VRAM[PatternNameOffset++];
- uint32_t pv = VRAM[PatternGeneratorBase + (pn * 8) + yofs];
- uint32_t colorEntry = Registers[7];
- uint32_t fgIndex = (colorEntry >> 4) & 0x0F;
- uint32_t bgIndex = colorEntry & 0x0F;
- uint32_t fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
- uint32_t bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
+ pn = VRAM[PatternNameOffset++];
+ pv = VRAM[PatternGeneratorBase + (pn * 8) + yofs];
+ colorEntry = Registers[7];
+ fgIndex = (colorEntry >> 4) & 0x0F;
+ bgIndex = colorEntry & 0x0F;
+ fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
+ bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
FrameBuffer[FrameBufferOffset++] = ((pv & 0x80) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x40) > 0) ? fgColor : bgColor;
@@ -286,23 +309,23 @@ namespace MSXHawk
return;
}
- uint32_t yrow = scanLine / 8;
- uint32_t yofs = scanLine % 8;
- uint32_t FrameBufferOffset = scanLine * 256;
- uint32_t PatternNameOffset = TmsPatternNameTableBase + (yrow * 32);
- uint32_t PatternGeneratorOffset = (((Registers[4] & 4) << 11) & 0x2000);
- uint32_t ColorOffset = (ColorTableBase & 0x2000);
- uint32_t ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
+ yrow = scanLine / 8;
+ yofs = scanLine % 8;
+ FrameBufferOffset = scanLine * 256;
+ PatternNameOffset = TmsPatternNameTableBase + (yrow * 32);
+ PatternGeneratorOffset = (((Registers[4] & 4) << 11) & 0x2000);
+ ColorOffset = (ColorTableBase & 0x2000);
+ ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
for (uint32_t xc = 0; xc < 32; xc++)
{
- uint32_t pn = VRAM[PatternNameOffset++] + ((yrow / 8) * 0x100);
- uint32_t pv = VRAM[PatternGeneratorOffset + (pn * 8) + yofs];
- uint32_t colorEntry = VRAM[ColorOffset + (pn * 8) + yofs];
- uint32_t fgIndex = (colorEntry >> 4) & 0x0F;
- uint32_t bgIndex = colorEntry & 0x0F;
- uint32_t fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
- uint32_t bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
+ pn = VRAM[PatternNameOffset++] + ((yrow / 8) * 0x100);
+ pv = VRAM[PatternGeneratorOffset + (pn * 8) + yofs];
+ colorEntry = VRAM[ColorOffset + (pn * 8) + yofs];
+ fgIndex = (colorEntry >> 4) & 0x0F;
+ bgIndex = colorEntry & 0x0F;
+ fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
+ bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
FrameBuffer[FrameBufferOffset++] = ((pv & 0x80) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x40) > 0) ? fgColor : bgColor;
@@ -323,21 +346,21 @@ namespace MSXHawk
return;
}
- uint32_t yc = scanLine / 8;
- bool top = (scanLine & 4) == 0; // am I in the top 4 pixels of an 8-pixel character?
- uint32_t FrameBufferOffset = scanLine * 256;
- uint32_t PatternNameOffset = TmsPatternNameTableBase + (yc * 32);
- uint32_t ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
+ yc = scanLine / 8;
+ is_top = (scanLine & 4) == 0; // am I in the top 4 pixels of an 8-pixel character?
+ FrameBufferOffset = scanLine * 256;
+ PatternNameOffset = TmsPatternNameTableBase + (yc * 32);
+ ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
for (uint32_t xc = 0; xc < 32; xc++)
{
- uint32_t pn = VRAM[PatternNameOffset++];
- uint32_t pv = VRAM[PatternGeneratorBase + (pn * 8) + ((yc & 3) * 2) + (top ? 0 : 1)];
+ pn = VRAM[PatternNameOffset++];
+ pv = VRAM[PatternGeneratorBase + (pn * 8) + ((yc & 3) * 2) + (is_top ? 0 : 1)];
- uint32_t lColorIndex = pv & 0xF;
- uint32_t rColorIndex = pv >> 4;
- uint32_t lColor = lColorIndex == 0 ? ScreenBGColor : PaletteTMS9918[lColorIndex];
- uint32_t rColor = rColorIndex == 0 ? ScreenBGColor : PaletteTMS9918[rColorIndex];
+ lColorIndex = pv & 0xF;
+ rColorIndex = pv >> 4;
+ lColor = lColorIndex == 0 ? ScreenBGColor : PaletteTMS9918[lColorIndex];
+ rColor = rColorIndex == 0 ? ScreenBGColor : PaletteTMS9918[rColorIndex];
FrameBuffer[FrameBufferOffset++] = lColor;
FrameBuffer[FrameBufferOffset++] = lColor;
@@ -350,9 +373,6 @@ namespace MSXHawk
}
}
- uint8_t ScanlinePriorityBuffer[256] = {};
- uint8_t SpriteCollisionBuffer[256] = {};
-
void RenderTmsSprites(int32_t scanLine)
{
if (EnableDoubledSprites() == false)