CPCHawk: PSG now sounds *almost* right
This commit is contained in:
parent
1268b09849
commit
a7e0e728a7
|
@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// Represents a PSG device (in this case an AY-3-891x)
|
||||
/// </summary>
|
||||
public interface IPSG : ISoundProvider, IPortIODevice
|
||||
public interface IPSG : ISoundProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initlization routine
|
||||
|
@ -17,6 +17,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
void SetFunction(int data);
|
||||
|
||||
//void ClockCycle();
|
||||
|
||||
/// <summary>
|
||||
/// Activates a register
|
||||
/// </summary>
|
||||
|
|
|
@ -71,6 +71,54 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
#endregion
|
||||
|
||||
public void ReadStatus(ref int data)
|
||||
{
|
||||
// read main status register
|
||||
// this can happen at any time
|
||||
data = ReadMainStatus();
|
||||
if (writeDebug)
|
||||
{
|
||||
//outputString += data + ",,," + ActiveCommand.CommandCode + "\r\n";
|
||||
workingArr[0] = data.ToString();
|
||||
BuildCSVLine();
|
||||
//System.IO.File.WriteAllText(outputfile, outputString);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadData(ref int data)
|
||||
{
|
||||
// Z80 is trying to read from the data register
|
||||
data = ReadDataRegister();
|
||||
if (writeDebug)
|
||||
{
|
||||
workingArr[2] = data.ToString();
|
||||
//outputString += ",," + data + "," + ActiveCommand.CommandCode + "\r\n";
|
||||
BuildCSVLine();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteData(int data)
|
||||
{
|
||||
// Z80 is attempting to write to the data register
|
||||
WriteDataRegister((byte)data);
|
||||
if (writeDebug)
|
||||
{
|
||||
//outputString += "," + data + ",," + ActiveCommand.CommandCode + "\r\n";
|
||||
workingArr[1] = data.ToString();
|
||||
BuildCSVLine();
|
||||
//System.IO.File.WriteAllText(outputfile, outputString);
|
||||
}
|
||||
}
|
||||
|
||||
public void Motor(int data)
|
||||
{
|
||||
// set disk motor on/off
|
||||
if (data > 0)
|
||||
FDD_FLAG_MOTOR = true;
|
||||
else
|
||||
FDD_FLAG_MOTOR = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Device responds to an IN instruction
|
||||
/// </summary>
|
||||
|
|
|
@ -608,31 +608,31 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
if (CRCT.VSYNC && CRCT.HSYNC)
|
||||
{
|
||||
// both hsync and vsync active
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.HSYNCandVSYNC, VideoByte1, VideoByte2, ColourRegisters);
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.HSYNCandVSYNC, VideoByte1, VideoByte2, ColourRegisters.ToArray());
|
||||
//CRT.AddScanlineCharacter(VLC, HCC++, RenderPhase.HSYNCandVSYNC, VideoByte1, VideoByte2, ColourRegisters);
|
||||
}
|
||||
else if (CRCT.VSYNC)
|
||||
{
|
||||
// vsync is active but hsync is not
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.VSYNC, VideoByte1, VideoByte2, ColourRegisters);
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.VSYNC, VideoByte1, VideoByte2, ColourRegisters.ToArray());
|
||||
//CRT.AddScanlineCharacter(VLC, HCC++, RenderPhase.VSYNC, VideoByte1, VideoByte2, ColourRegisters);
|
||||
}
|
||||
else if (CRCT.HSYNC)
|
||||
{
|
||||
// hsync is active but vsync is not
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.HSYNC, VideoByte1, VideoByte2, ColourRegisters);
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.HSYNC, VideoByte1, VideoByte2, ColourRegisters.ToArray());
|
||||
//CRT.AddScanlineCharacter(VLC, HCC++, RenderPhase.HSYNC, VideoByte1, VideoByte2, ColourRegisters);
|
||||
}
|
||||
else if (!CRCT.DISPTMG)
|
||||
{
|
||||
// border generation
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.BORDER, VideoByte1, VideoByte2, ColourRegisters);
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.BORDER, VideoByte1, VideoByte2, ColourRegisters.ToArray());
|
||||
//CRT.AddScanlineCharacter(VLC, HCC++, RenderPhase.BORDER, VideoByte1, VideoByte2, ColourRegisters);
|
||||
}
|
||||
else if (CRCT.DISPTMG)
|
||||
{
|
||||
// pixels generated from video RAM
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.DISPLAY, VideoByte1, VideoByte2, ColourRegisters);
|
||||
CRT.CurrentLine.AddScanlineCharacter(HCC++, RenderPhase.DISPLAY, VideoByte1, VideoByte2, ColourRegisters.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,7 +656,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
case 0:
|
||||
CRCT.ClockCycle();
|
||||
//PSG.ClockCycle();
|
||||
//PSG.ClockCycle(FrameClock);
|
||||
WaitLine = false;
|
||||
break;
|
||||
case 1:
|
||||
|
|
|
@ -197,6 +197,19 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The offset into vRAM
|
||||
/// </summary>
|
||||
public int VideoRAMOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
ushort combined = (ushort)(Regs[12] << 8 | Regs[13]);
|
||||
int offset = combined & 0x3ff;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Easier memory functions */
|
||||
|
||||
|
@ -210,6 +223,21 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// </summary>
|
||||
public int ByteCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Set at every HSYNC
|
||||
/// </summary>
|
||||
public int LatchedRAMOffset;
|
||||
|
||||
/// <summary>
|
||||
/// set at every HSYNC
|
||||
/// </summary>
|
||||
public int LatchedRAMStartAddress;
|
||||
|
||||
/// <summary>
|
||||
/// set at every HSYNC
|
||||
/// </summary>
|
||||
public int LatchedScreenWidthBytes;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Registers and State
|
||||
|
@ -383,12 +411,12 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// Vertical Character Count
|
||||
/// </summary>
|
||||
private int VCC;
|
||||
public int VCC;
|
||||
|
||||
/// <summary>
|
||||
/// Vertical Scanline Count
|
||||
/// </summary>
|
||||
private int VLC;
|
||||
public int VLC;
|
||||
|
||||
/// <summary>
|
||||
/// Internal cycle counter
|
||||
|
@ -445,6 +473,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
}
|
||||
|
||||
if (HSYNC && HSYNCCounter == 1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// move one horizontal character
|
||||
HCC++;
|
||||
|
||||
|
@ -463,8 +496,15 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
var line = VCC;
|
||||
var row = VLC;
|
||||
var addr = VideoPageBase + (line * 0x50) + (row * 0x800) + (ByteCounter);
|
||||
CurrentByteAddress = (ushort)addr;
|
||||
var addrX = (LatchedRAMOffset * 2) + ((VCC * LatchedScreenWidthBytes) & 0x7ff) + ByteCounter;
|
||||
// remove artifacts caused by certain hardware scrolling addresses
|
||||
addrX &= 0x7ff;
|
||||
var addrY = LatchedRAMStartAddress + (2048 * VLC);
|
||||
|
||||
//var addr = VideoPageBase + (line * (0x50)) + (row * 0x800) + (ByteCounter);
|
||||
CurrentByteAddress = (ushort)(addrX + addrY);
|
||||
|
||||
|
||||
|
||||
ByteCounter += 2;
|
||||
}
|
||||
|
@ -558,6 +598,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
HSYNC = true;
|
||||
HSYNCCounter = 0;
|
||||
|
||||
LatchedRAMStartAddress = VideoPageBase;
|
||||
LatchedRAMOffset = VideoRAMOffset;
|
||||
LatchedScreenWidthBytes = DisplayWidth * 2;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -332,7 +332,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
switch (ScreenMode)
|
||||
{
|
||||
case 0:
|
||||
Characters[charIndex].Pixels = new int[8];
|
||||
Characters[charIndex].Pixels = new int[4];
|
||||
break;
|
||||
case 1:
|
||||
Characters[charIndex].Pixels = new int[8];
|
||||
|
@ -527,7 +527,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
|
||||
// render out the scanline
|
||||
int pCount = (LineIndex - CRT.TopLinesToTrim) * 2 * CRT.BufferWidth;
|
||||
int pCount = (LineIndex - CRT.TopLinesToTrim) * vScale * CRT.BufferWidth;
|
||||
|
||||
// vScale
|
||||
for (int s = 0; s < vScale; s++)
|
||||
|
|
|
@ -24,10 +24,12 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
private int _tStatesPerFrame;
|
||||
private int _sampleRate;
|
||||
private int _samplesPerFrame;
|
||||
private int _tStatesPerSample;
|
||||
private double _tStatesPerSample;
|
||||
private short[] _audioBuffer;
|
||||
private int _audioBufferIndex;
|
||||
private int _lastStateRendered;
|
||||
private int _clockCyclesPerFrame;
|
||||
private int _cyclesPerSample;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -39,6 +41,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
public AY38912(CPCBase machine)
|
||||
{
|
||||
_machine = machine;
|
||||
|
||||
//_blipL.SetRates(1000000, 44100);
|
||||
//_blipL.SetRates((_machine.GateArray.FrameLength * 50) / 4, 44100);
|
||||
//_blipR.SetRates(1000000, 44100);
|
||||
//_blipR.SetRates((_machine.GateArray.FrameLength * 50) / 4, 44100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -51,46 +58,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
Reset();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPortIODevice
|
||||
|
||||
public bool ReadPort(ushort port, ref int value)
|
||||
{
|
||||
if (port != 0xfffd)
|
||||
{
|
||||
// port read is not addressing this device
|
||||
return false;
|
||||
}
|
||||
|
||||
value = PortRead();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool WritePort(ushort port, int value)
|
||||
{
|
||||
if (port == 0xfffd)
|
||||
{
|
||||
// register select
|
||||
SelectedRegister = value & 0x0f;
|
||||
return true;
|
||||
}
|
||||
else if (port == 0xbffd)
|
||||
{
|
||||
// Update the audiobuffer based on the current CPU cycle
|
||||
// (this process the previous data BEFORE writing to the currently selected register)
|
||||
int d = (int)(_machine.CurrentFrameCycle);
|
||||
BufferUpdate(d);
|
||||
|
||||
// write to register
|
||||
PortWrite(value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region AY Implementation
|
||||
|
||||
|
@ -239,7 +207,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
if (_activeRegister < 16)
|
||||
return _registers[_activeRegister];
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -366,11 +334,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
// do audio processing
|
||||
BufferUpdate((int)_machine.CurrentFrameCycle);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -396,7 +366,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <param name="frameCycle"></param>
|
||||
public void UpdateSound(int frameCycle)
|
||||
{
|
||||
BufferUpdate(frameCycle);
|
||||
BufferUpdate(frameCycle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -471,7 +441,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// The frequency of the AY chip
|
||||
/// </summary>
|
||||
private static int _chipFrequency = 1773400;
|
||||
private static int _chipFrequency = 1000000; // 1773400;
|
||||
|
||||
/// <summary>
|
||||
/// The rendering resolution of the chip
|
||||
|
@ -640,8 +610,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
}
|
||||
|
||||
private int mult_const;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes timing information for the frame
|
||||
/// </summary>
|
||||
|
@ -651,21 +619,19 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
_sampleRate = sampleRate;
|
||||
_tStatesPerFrame = frameTactCount;
|
||||
_samplesPerFrame = 882;
|
||||
_samplesPerFrame = sampleRate / 50; //882
|
||||
|
||||
_tStatesPerSample = 79; //(int)Math.Round(((double)_tStatesPerFrame * 50D) /
|
||||
//(16D * (double)_sampleRate),
|
||||
//MidpointRounding.AwayFromZero);
|
||||
|
||||
//_samplesPerFrame = _tStatesPerFrame / _tStatesPerSample;
|
||||
_audioBuffer = new short[_samplesPerFrame * 2]; //[_sampleRate / 50];
|
||||
_tStatesPerSample = (double)frameTactCount / (double)_samplesPerFrame; // 90; //(int)Math.Round(((double)_tStatesPerFrame * 50D) /
|
||||
//(16D * (double)_sampleRate),
|
||||
//MidpointRounding.AwayFromZero);
|
||||
_audioBuffer = new short[_samplesPerFrame * 2];
|
||||
_audioBufferIndex = 0;
|
||||
|
||||
mult_const = ((_chipFrequency / 8) << 14) / _machine.GateArray.Z80ClockSpeed;
|
||||
|
||||
var aytickspercputick = (double)_machine.GateArray.Z80ClockSpeed / (double)_chipFrequency;
|
||||
int ayCyclesPerSample = (int)((double)_tStatesPerSample * (double)aytickspercputick);
|
||||
ticksPerSample = ((double)_chipFrequency / sampleRate / 8);
|
||||
}
|
||||
private double ticksPerSample;
|
||||
|
||||
private double tickCounter = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the audiobuffer based on the current frame t-state
|
||||
|
@ -682,14 +648,18 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
// get the current length of the audiobuffer
|
||||
int bufferLength = _samplesPerFrame; // _audioBuffer.Length;
|
||||
|
||||
int toEnd = ((bufferLength * cycle) / _tStatesPerFrame);
|
||||
double toEnd = ((double)(bufferLength * cycle) / (double)_tStatesPerFrame);
|
||||
|
||||
// loop through the number of samples we need to render
|
||||
while (_audioBufferIndex < toEnd)
|
||||
{
|
||||
// run the AY chip processing at the correct resolution
|
||||
for (int i = 0; i < _tStatesPerSample / 14; i++)
|
||||
tickCounter += ticksPerSample;
|
||||
|
||||
while (tickCounter > 0)
|
||||
{
|
||||
tickCounter--;
|
||||
|
||||
if (++_countA >= _dividerA)
|
||||
{
|
||||
_countA = 0;
|
||||
|
@ -795,6 +765,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
public void DiscardSamples()
|
||||
{
|
||||
_audioBuffer = new short[_samplesPerFrame * 2];
|
||||
//_blipL.Clear();
|
||||
//_blipR.Clear();
|
||||
}
|
||||
|
||||
public void GetSamplesSync(out short[] samples, out int nsamp)
|
||||
|
@ -802,6 +774,43 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
nsamp = _samplesPerFrame;
|
||||
samples = _audioBuffer;
|
||||
DiscardSamples();
|
||||
tickCounter = 0;
|
||||
return;
|
||||
/*
|
||||
_blipL.EndFrame((uint)SampleClock);
|
||||
_blipR.EndFrame((uint)SampleClock);
|
||||
SampleClock = 0;
|
||||
|
||||
int sampL = _blipL.SamplesAvailable();
|
||||
int sampR = _blipR.SamplesAvailable();
|
||||
|
||||
if (sampL > sampR)
|
||||
nsamp = sampL;
|
||||
else
|
||||
nsamp = sampR;
|
||||
|
||||
short[] buffL = new short[sampL];
|
||||
short[] buffR = new short[sampR];
|
||||
|
||||
_blipL.ReadSamples(buffL, sampL - 1, false);
|
||||
_blipR.ReadSamples(buffR, sampR - 1, false);
|
||||
|
||||
if (_audioBuffer.Length != nsamp * 2)
|
||||
_audioBuffer = new short[nsamp * 2];
|
||||
|
||||
int p = 0;
|
||||
for (int i = 0; i < nsamp; i++)
|
||||
{
|
||||
if (i < sampL)
|
||||
_audioBuffer[p++] = buffL[i];
|
||||
if (i < sampR)
|
||||
_audioBuffer[p++] = buffR[i];
|
||||
}
|
||||
|
||||
//nsamp = _samplesPerFrame;
|
||||
samples = _audioBuffer;
|
||||
DiscardSamples();
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -823,7 +832,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
ser.Sync("_tStatesPerFrame", ref _tStatesPerFrame);
|
||||
ser.Sync("_sampleRate", ref _sampleRate);
|
||||
ser.Sync("_samplesPerFrame", ref _samplesPerFrame);
|
||||
ser.Sync("_tStatesPerSample", ref _tStatesPerSample);
|
||||
//ser.Sync("_tStatesPerSample", ref _tStatesPerSample);
|
||||
ser.Sync("_audioBufferIndex", ref _audioBufferIndex);
|
||||
ser.Sync("_audioBuffer", ref _audioBuffer, false);
|
||||
ser.Sync("PortAInput", ref PortAInput);
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// <summary>
|
||||
/// Device blipbuffer
|
||||
/// </summary>
|
||||
private readonly BlipBuffer blip = new BlipBuffer(1024);
|
||||
private readonly BlipBuffer blip = new BlipBuffer(883);
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -122,7 +122,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// </summary>
|
||||
public void Init(int sampleRate, int tStatesPerFrame)
|
||||
{
|
||||
blip.SetRates((tStatesPerFrame * 50), sampleRate);
|
||||
blip.SetRates((4000000), sampleRate);
|
||||
_sampleRate = sampleRate;
|
||||
_tStatesPerFrame = tStatesPerFrame;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,20 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
else if (DecodeINPort(port) == PortDevice.Expansion)
|
||||
{
|
||||
|
||||
if (!port.Bit(7))
|
||||
{
|
||||
// FDC
|
||||
if (port.Bit(8) && !port.Bit(0))
|
||||
{
|
||||
// FDC status register
|
||||
UPDDiskDevice.ReadStatus(ref result);
|
||||
}
|
||||
if (port.Bit(8) && port.Bit(0))
|
||||
{
|
||||
// FDC data register
|
||||
UPDDiskDevice.ReadData(ref result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (byte)result;
|
||||
|
@ -104,7 +117,20 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
else if (d == PortDevice.Expansion)
|
||||
{
|
||||
|
||||
if (!port.Bit(7))
|
||||
{
|
||||
// FDC
|
||||
if (port.Bit(8) && !port.Bit(0) || port.Bit(8) && port.Bit(0))
|
||||
{
|
||||
// FDC data register
|
||||
UPDDiskDevice.WriteData(value);
|
||||
}
|
||||
if ((!port.Bit(8) && !port.Bit(0)) || (!port.Bit(8) && port.Bit(0)))
|
||||
{
|
||||
// FDC motor
|
||||
UPDDiskDevice.Motor(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -157,19 +157,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// </summary>
|
||||
protected void LoadDiskMedia()
|
||||
{
|
||||
/*
|
||||
if (this.GetType() != typeof(ZX128Plus3))
|
||||
if (this.GetType() == typeof(CPC464))
|
||||
{
|
||||
Spectrum.CoreComm.ShowMessage("You are trying to load one of more disk images.\n\n Please select ZX Spectrum +3 emulation immediately and reboot the core");
|
||||
CPC.CoreComm.ShowMessage("You are trying to load one of more disk images.\n\n Please select something other than CPC 464 emulation immediately and reboot the core");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Spectrum.CoreComm.ShowMessage("You are attempting to load a disk into the +3 disk drive.\n\nThis DOES NOT currently work properly but IS under active development.");
|
||||
}
|
||||
|
||||
UPDDiskDevice.FDD_LoadDisk(diskImages[diskMediaIndex]);
|
||||
*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -194,7 +188,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
// cdt tape file
|
||||
return CPCMediaType.Tape;
|
||||
}
|
||||
|
||||
|
||||
// not found
|
||||
return CPCMediaType.None;
|
||||
|
|
|
@ -63,9 +63,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// </summary>
|
||||
public int RAM64KBank;
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Memory Related Methods
|
||||
|
|
|
@ -152,8 +152,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
if (_renderSound)
|
||||
{
|
||||
if (AYDevice != null)
|
||||
AYDevice.StartFrame();
|
||||
AYDevice.StartFrame();
|
||||
}
|
||||
|
||||
PollInput();
|
||||
|
|
|
@ -58,6 +58,55 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// CDT format is essentially exactly the same as the TZX format
|
||||
/// However all timings are based on spectrum timings (3.5Mhz)
|
||||
/// so need to be adjusted for the CPC (4Mhz)
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns></returns>
|
||||
private TapeDataBlock ConvertClock(TapeDataBlock db)
|
||||
{
|
||||
TapeDataBlock tb = new TapeDataBlock();
|
||||
tb.BlockDescription = db.BlockDescription;
|
||||
tb.BlockID = db.BlockID;
|
||||
tb.Command = db.Command;
|
||||
tb.DataPeriods = new List<int>();
|
||||
tb.InitialPulseLevel = db.InitialPulseLevel;
|
||||
tb.MetaData = db.MetaData;
|
||||
tb.PauseInMS = db.PauseInMS;
|
||||
|
||||
double multiplier = (double)4 / (double)3.5;
|
||||
double cycleScale = ((40 << 16) / 35);
|
||||
double origPeriods = db.DataPeriods.Count();
|
||||
|
||||
for (int i = 0; i < origPeriods; i++)
|
||||
{
|
||||
int orig = db.DataPeriods[i];
|
||||
int np = (int)((double)orig * multiplier);
|
||||
int nnp = ClockAdjust(orig);
|
||||
tb.DataPeriods.Add(np);
|
||||
}
|
||||
|
||||
return tb;
|
||||
}
|
||||
|
||||
private int ClockAdjust(int val)
|
||||
{
|
||||
int cycleScale = ((40 << 16) / 35);
|
||||
int res = (val * cycleScale) >> 16;
|
||||
return res;
|
||||
}
|
||||
|
||||
private int Scale => ((40 << 16) / 35);
|
||||
|
||||
private int Adjust(int val)
|
||||
{
|
||||
return (int)((val * CLOCK_MULTIPLIER));
|
||||
}
|
||||
|
||||
private const double CLOCK_MULTIPLIER = 1.142857;
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if tzx header is detected
|
||||
/// </summary>
|
||||
|
@ -142,6 +191,17 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
ProcessBlock(data, ID);
|
||||
}
|
||||
|
||||
/*
|
||||
// convert for Amstrad CPC
|
||||
List<TapeDataBlock> newBlocks = new List<TapeDataBlock>();
|
||||
for (int i = 0; i < _datacorder.DataBlocks.Count(); i++)
|
||||
{
|
||||
newBlocks.Add(ConvertClock(_datacorder.DataBlocks[i]));
|
||||
}
|
||||
|
||||
_datacorder.DataBlocks.Clear();
|
||||
_datacorder.DataBlocks.AddRange(newBlocks);
|
||||
*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1632,6 +1692,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
int bitsInLastByte = 8
|
||||
)
|
||||
{
|
||||
|
||||
// first get the block description
|
||||
string description = string.Empty;
|
||||
|
||||
|
@ -1857,12 +1918,16 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
)
|
||||
{
|
||||
|
||||
|
||||
int pilotCount = 3220;
|
||||
/*
|
||||
// pilot count needs to be ascertained from flag byte
|
||||
int pilotCount;
|
||||
if (blockData[0] < 128)
|
||||
pilotCount = 8063;
|
||||
else
|
||||
pilotCount = 3223;
|
||||
*/
|
||||
|
||||
// now we can decode
|
||||
var nBlock = DecodeDataBlock
|
||||
|
|
|
@ -184,8 +184,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
else
|
||||
{
|
||||
// just process what we have as-is
|
||||
}
|
||||
// just process what we have as-is
|
||||
}
|
||||
}
|
||||
|
||||
// mix the soundproviders together
|
||||
|
@ -197,10 +197,14 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
short sectorVal = 0;
|
||||
foreach (var sp in SoundProviders)
|
||||
{
|
||||
if (sp.Buffer[i] > sp.MaxVolume)
|
||||
sectorVal += (short)sp.MaxVolume;
|
||||
else
|
||||
sectorVal += sp.Buffer[i];
|
||||
if (i < sp.Buffer.Length)
|
||||
{
|
||||
if (sp.Buffer[i] > sp.MaxVolume)
|
||||
sectorVal += (short)sp.MaxVolume;
|
||||
else
|
||||
sectorVal += sp.Buffer[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
samples[i] = sectorVal;
|
||||
|
|
Loading…
Reference in New Issue