Added VRAM Viewer and tried to fix noise channel

This commit is contained in:
2026-05-15 16:34:34 +01:00
parent 787e403232
commit f52a5cbfdb
6 changed files with 227 additions and 96 deletions

View File

@@ -22,6 +22,7 @@ namespace Core.Audio
private int[] _counters = new int[4];
private int[] _polarities = new int[4] { 1, 1, 1, 1 }; // 1 = High, -1 = Low
private ushort _lfsr = 0x8000; // Linear Feedback Shift Register (For Noise)
private bool _noiseFlipFlop = false;
// The SN76489 Volume Table reduces amplitude by exactly 2 decibels per step.
private static readonly float[] VolumeTable = {
@@ -83,27 +84,33 @@ namespace Core.Audio
_counters[3]--;
if (_counters[3] <= 0)
{
// Noise rate depends on Bits 0-1 of Register 6
// Reload the counter
int shiftRate = Registers[6] & 0x03;
if (shiftRate == 0) _counters[3] = 0x10; // Fast
else if (shiftRate == 1) _counters[3] = 0x20; // Medium
else if (shiftRate == 2) _counters[3] = 0x40; // Slow
else _counters[3] = (Registers[4] == 0) ? 1024 : Registers[4]; // Linked to Tone 2!
else _counters[3] = (Registers[4] == 0) ? 1024 : Registers[4]; // Linked to Tone 2
// Shift the Noise LFSR
int tappedBit = _lfsr & 1;
_lfsr >>= 1;
// THE FIX: Toggle the internal clock (Divide by 2!)
_noiseFlipFlop = !_noiseFlipFlop;
if (tappedBit == 1)
// Only shift the random static when the clock goes High
if (_noiseFlipFlop)
{
bool isWhiteNoise = (Registers[6] & 0x04) != 0;
// The Sega Master System physically tapped bits 0 and 3 for its white noise
if (isWhiteNoise) _lfsr ^= 0x0009;
int tappedBit = _lfsr & 1;
_lfsr >>= 1;
_lfsr |= 0x8000; // Inject the high bit
if (tappedBit == 1)
{
bool isWhiteNoise = (Registers[6] & 0x04) != 0;
if (isWhiteNoise) _lfsr ^= 0x0009; // SMS-specific XOR mask
_lfsr |= 0x8000; // Inject the high bit
}
// The noise channel output is driven directly by the tapped bit
_polarities[3] = (tappedBit == 1) ? 1 : -1;
}
_polarities[3] = (tappedBit == 1) ? 1 : -1;
}
}
@@ -149,12 +156,14 @@ namespace Core.Audio
// Volume registers (1, 3, 5, 7) and Noise Control (6) only hold 4 bits total.
// We completely overwrite them.
Registers[_latchedRegister] = (ushort)data;
if (_latchedRegister == 6) _lfsr = 0x8000;
}
else
{
// Tone registers (0, 2, 4) hold 10 bits.
// A Latch byte ONLY overwrites the bottom 4 bits and leaves the top 6 alone!
Registers[_latchedRegister] = (ushort)((Registers[_latchedRegister] & 0x03F0) | data);
if (_latchedRegister == 6) _lfsr = 0x8000;
}
}
else