48k - new ULA implementation - 80% faster
This commit is contained in:
parent
2b988954ee
commit
a5b50fe547
|
@ -106,17 +106,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// Helper function to refresh memory array (probably not the best way to do things)
|
||||
/// </summary>
|
||||
public abstract void ReInitMemory();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the memory contention value for the specified T-State (cycle)
|
||||
/// The ZX Spectrum memory access is contended when the ULA is accessing the lower 16k of RAM
|
||||
/// </summary>
|
||||
/// <param name="Cycle"></param>
|
||||
/// <returns></returns>
|
||||
public virtual byte GetContentionValue(int cycle)
|
||||
{
|
||||
var val = _renderingCycleTable[cycle % UlaFrameCycleCount].ContentionDelay;
|
||||
return val;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,28 +30,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="port"></param>
|
||||
/// <param name="value"></param>
|
||||
public abstract void WritePort(ushort port, byte value);
|
||||
|
||||
/// <summary>
|
||||
/// Apply I/O contention if necessary
|
||||
/// </summary>
|
||||
/// <param name="port"></param>
|
||||
public virtual void ContendPort(ushort port)
|
||||
{
|
||||
var lowBit = (port & 0x0001) != 0;
|
||||
var ulaHigh = (port & 0xc000) == 0x4000;
|
||||
var cfc = CurrentFrameCycle;
|
||||
if (cfc < 1)
|
||||
cfc = 1;
|
||||
|
||||
if (ulaHigh)
|
||||
{
|
||||
CPU.TotalExecutedCycles += GetContentionValue(cfc - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!lowBit)
|
||||
CPU.TotalExecutedCycles += GetContentionValue(cfc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
/// <summary>
|
||||
/// The abstract class that all emulated models will inherit from
|
||||
/// * Screen *
|
||||
|
@ -927,7 +929,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/*
|
||||
public int VsyncNumerator => NullVideo.DefaultVsyncNum;
|
||||
public int VsyncDenominator => NullVideo.DefaultVsyncDen;
|
||||
*/
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
/*
|
||||
|
@ -965,7 +967,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
case ZXSpectrum.BorderType.Medium:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
return _frameBuffer;
|
||||
|
||||
}
|
||||
|
@ -973,4 +975,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
#endregion
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -120,10 +120,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
BuzzerDevice.StartFrame();
|
||||
if (AYDevice != null)
|
||||
AYDevice.StartFrame();
|
||||
|
||||
PollInput();
|
||||
|
||||
var curr = CPU.TotalExecutedCycles;
|
||||
|
||||
|
||||
while (CurrentFrameCycle <= ULADevice.FrameLength) // UlaFrameCycleCount)
|
||||
{
|
||||
// check for interrupt
|
||||
|
@ -132,13 +131,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// run a single CPU instruction
|
||||
CPU.ExecuteOne();
|
||||
|
||||
// run a rendering cycle according to the current CPU cycle count
|
||||
/*
|
||||
var lastCycle = CurrentFrameCycle;
|
||||
RenderScreen(LastRenderedULACycle + 1, lastCycle);
|
||||
LastRenderedULACycle = lastCycle;
|
||||
*/
|
||||
|
||||
// update AY
|
||||
if (AYDevice != null)
|
||||
AYDevice.UpdateSound(CurrentFrameCycle);
|
||||
|
@ -146,9 +138,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// we have reached the end of a frame
|
||||
LastFrameStartCPUTick = CPU.TotalExecutedCycles - OverFlow;
|
||||
LastRenderedULACycle = OverFlow;
|
||||
|
||||
ULADevice.UpdateScreenBuffer(ULADevice.FrameLength);
|
||||
// paint the buffer if needed
|
||||
if (ULADevice.needsPaint)
|
||||
ULADevice.UpdateScreenBuffer(ULADevice.FrameLength);
|
||||
|
||||
BuzzerDevice.EndFrame();
|
||||
|
||||
|
@ -157,16 +150,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
FrameCount++;
|
||||
|
||||
// setup for next frame
|
||||
OverFlow = CurrentFrameCycle % UlaFrameCycleCount;
|
||||
ULADevice.ResetInterrupt();
|
||||
FrameCompleted = true;
|
||||
|
||||
if (FrameCount % FlashToggleFrames == 0)
|
||||
{
|
||||
_flashPhase = !_flashPhase;
|
||||
}
|
||||
|
||||
//RenderScreen(0, OverFlow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -174,8 +159,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public virtual void HardReset()
|
||||
{
|
||||
ResetBorder();
|
||||
ResetInterrupt();
|
||||
//ResetBorder();
|
||||
ULADevice.ResetInterrupt();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -183,8 +168,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public virtual void SoftReset()
|
||||
{
|
||||
ResetBorder();
|
||||
ResetInterrupt();
|
||||
//ResetBorder();
|
||||
ULADevice.ResetInterrupt();
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
|
@ -195,50 +180,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
ser.Sync("FrameCount", ref FrameCount);
|
||||
ser.Sync("_frameCycles", ref _frameCycles);
|
||||
ser.Sync("LastFrameStartCPUTick", ref LastFrameStartCPUTick);
|
||||
ser.Sync("LastULAOutByte", ref LastULAOutByte);
|
||||
ser.Sync("_flashPhase", ref _flashPhase);
|
||||
ser.Sync("_frameBuffer", ref _frameBuffer, false);
|
||||
ser.Sync("_flashOffColors", ref _flashOffColors, false);
|
||||
ser.Sync("_flashOnColors", ref _flashOnColors, false);
|
||||
ser.Sync("InterruptCycle", ref InterruptCycle);
|
||||
ser.Sync("InterruptRaised", ref InterruptRaised);
|
||||
ser.Sync("InterruptRevoked", ref InterruptRevoked);
|
||||
ser.Sync("UlaFrameCycleCount", ref UlaFrameCycleCount);
|
||||
ser.Sync("FirstScreenPixelCycle", ref FirstScreenPixelCycle);
|
||||
ser.Sync("FirstDisplayPixelCycle", ref FirstDisplayPixelCycle);
|
||||
ser.Sync("FirstPixelCycleInLine", ref FirstPixelCycleInLine);
|
||||
ser.Sync("AttributeDataPrefetchTime", ref AttributeDataPrefetchTime);
|
||||
ser.Sync("PixelDataPrefetchTime", ref PixelDataPrefetchTime);
|
||||
ser.Sync("ScreenLineTime", ref ScreenLineTime);
|
||||
ser.Sync("NonVisibleBorderRightTime", ref NonVisibleBorderRightTime);
|
||||
ser.Sync("BorderRightTime", ref BorderRightTime);
|
||||
ser.Sync("DisplayLineTime", ref DisplayLineTime);
|
||||
ser.Sync("BorderLeftTime", ref BorderLeftTime);
|
||||
ser.Sync("HorizontalBlankingTime", ref HorizontalBlankingTime);
|
||||
ser.Sync("ScreenWidth", ref ScreenWidth);
|
||||
ser.Sync("BorderRightPixels", ref BorderRightPixels);
|
||||
ser.Sync("BorderLeftPixels", ref BorderLeftPixels);
|
||||
ser.Sync("FirstDisplayLine", ref FirstDisplayLine);
|
||||
ser.Sync("ScreenLines", ref ScreenLines);
|
||||
ser.Sync("NonVisibleBorderBottomLines", ref NonVisibleBorderBottomLines);
|
||||
ser.Sync("BorderBottomLines", ref BorderBottomLines);
|
||||
ser.Sync("BorderTopLines", ref BorderTopLines);
|
||||
ser.Sync("NonVisibleBorderTopLines", ref NonVisibleBorderTopLines);
|
||||
ser.Sync("VerticalSyncLines", ref VerticalSyncLines);
|
||||
ser.Sync("FlashToggleFrames", ref FlashToggleFrames);
|
||||
ser.Sync("DisplayLines", ref DisplayLines);
|
||||
ser.Sync("DisplayWidth", ref DisplayWidth);
|
||||
ser.Sync("_pixelByte1", ref _pixelByte1);
|
||||
ser.Sync("_pixelByte2", ref _pixelByte2);
|
||||
ser.Sync("_attrByte1", ref _attrByte1);
|
||||
ser.Sync("_attrByte2", ref _attrByte2);
|
||||
ser.Sync("_xPos", ref _xPos);
|
||||
ser.Sync("_yPos", ref _yPos);
|
||||
ser.Sync("DisplayWidth", ref DisplayWidth);
|
||||
ser.Sync("DisplayWidth", ref DisplayWidth);
|
||||
ser.Sync("DisplayWidth", ref DisplayWidth);
|
||||
ser.Sync("DisplayWidth", ref DisplayWidth);
|
||||
ser.Sync("_borderColour", ref _borderColour);
|
||||
ser.Sync("LastULAOutByte", ref LastULAOutByte);
|
||||
ser.Sync("ROM0", ref ROM0, false);
|
||||
ser.Sync("ROM1", ref ROM1, false);
|
||||
ser.Sync("ROM2", ref ROM2, false);
|
||||
|
|
|
@ -6,11 +6,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
/// <summary>
|
||||
/// Another ULA implementation (maybe it will be more performant & accurate)
|
||||
/// -edit: it is :)
|
||||
/// </summary>
|
||||
public abstract class ULABase : IVideoProvider
|
||||
{
|
||||
#region ULA Configuration
|
||||
|
||||
#region General
|
||||
|
||||
/// <summary>
|
||||
|
@ -65,15 +64,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
#endregion
|
||||
|
||||
#region Interrupts
|
||||
|
||||
/// <summary>
|
||||
/// The number of T-States that the INT pin is simulated to be held low
|
||||
/// </summary>
|
||||
public int InterruptPeriod;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Contention
|
||||
|
||||
/// <summary>
|
||||
|
@ -142,6 +132,23 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
protected bool flashOn = false;
|
||||
|
||||
|
||||
protected int flashCounter;
|
||||
public int FlashCounter
|
||||
{
|
||||
get { return flashCounter; }
|
||||
set
|
||||
{
|
||||
flashCounter = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal frame counter used for flasher operations
|
||||
/// </summary>
|
||||
protected int frameCounter = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Last 8-bit bitmap read from display memory
|
||||
/// (Floating bus implementation)
|
||||
|
@ -230,10 +237,20 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
protected int AttributeLength;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when ULA has finished painting the entire screen
|
||||
/// </summary>
|
||||
public bool needsPaint = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Interrupt
|
||||
|
||||
/// <summary>
|
||||
/// The number of T-States that the INT pin is simulated to be held low
|
||||
/// </summary>
|
||||
public int InterruptPeriod;
|
||||
|
||||
/// <summary>
|
||||
/// The longest instruction cycle count
|
||||
/// </summary>
|
||||
|
@ -282,9 +299,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// interrupt should have already been raised and the cpu may or
|
||||
// may not have caught it. The time has passed so revoke the signal
|
||||
InterruptRevoked = true;
|
||||
//CPU.IFF1 = true;
|
||||
_machine.CPU.FlagI = false;
|
||||
//CPU.NonMaskableInterruptPending = true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -295,23 +310,15 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
return;
|
||||
}
|
||||
|
||||
// if CPU is masking the interrupt do not raise it
|
||||
//if (!CPU.IFF1)
|
||||
//return;
|
||||
|
||||
// Raise the interrupt
|
||||
InterruptRaised = true;
|
||||
//CPU.IFF1 = false;
|
||||
//CPU.IFF2 = false;
|
||||
_machine.CPU.FlagI = true;
|
||||
//FrameCount++;
|
||||
ULAUpdateStart();
|
||||
|
||||
// Signal the start of ULA processing
|
||||
ULAUpdateStart();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Construction & Initialisation
|
||||
|
||||
|
@ -320,11 +327,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
_machine = machine;
|
||||
}
|
||||
|
||||
public virtual void Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
@ -379,6 +381,15 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
ULAByteCtr = 0;
|
||||
screenByteCtr = DisplayStart;
|
||||
lastTState = actualULAStart;
|
||||
needsPaint = true;
|
||||
|
||||
flashCounter++;
|
||||
|
||||
if (flashCounter > 15)
|
||||
{
|
||||
flashOn = !flashOn;
|
||||
flashCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -406,6 +417,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the screen buffer based on the number of T-States supplied
|
||||
/// </summary>
|
||||
/// <param name="_tstates"></param>
|
||||
public virtual void UpdateScreenBuffer(int _tstates)
|
||||
{
|
||||
if (_tstates < actualULAStart)
|
||||
|
@ -415,6 +430,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
else if (_tstates >= FrameLength)
|
||||
{
|
||||
_tstates = FrameLength - 1;
|
||||
|
||||
needsPaint = true;
|
||||
}
|
||||
|
||||
//the additional 1 tstate is required to get correct number of bytes to output in ircontention.sna
|
||||
|
@ -542,6 +559,21 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
#endregion
|
||||
|
||||
#region IStatable
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("ULA");
|
||||
ser.Sync("ScreenBuffer", ref ScreenBuffer, false);
|
||||
ser.Sync("FrameLength", ref FrameLength);
|
||||
ser.Sync("ClockSpeed", ref ClockSpeed);
|
||||
ser.Sync("LateTiming", ref LateTiming);
|
||||
ser.Sync("borderColour", ref borderColour);
|
||||
ser.EndSection();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Attribution
|
||||
|
||||
|
|
|
@ -168,6 +168,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -178,13 +182,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
if ((addr & 0xC000) == 0x4000)
|
||||
{
|
||||
// addr is in RAM not ROM - apply memory contention if neccessary
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -196,17 +197,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
if (addr < 0x4000)
|
||||
{
|
||||
// Do nothing - we cannot write to ROM
|
||||
return;
|
||||
}
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// possible contended RAM
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
public partial class ZX128 : SpectrumBase
|
||||
{
|
||||
private int AYTStates = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Reads a byte of data from a specified port address
|
||||
/// </summary>
|
||||
|
@ -23,7 +21,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x0001) == 0;
|
||||
|
||||
ContendPort((ushort)port);
|
||||
ULADevice.Contend(port);
|
||||
CPU.TotalExecutedCycles++;
|
||||
|
||||
// Kempston Joystick
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
|
@ -124,9 +123,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// if unused port the floating memory bus should be returned (still todo)
|
||||
}
|
||||
|
||||
CPU.TotalExecutedCycles += 3;
|
||||
|
||||
|
||||
return (byte)result;
|
||||
}
|
||||
|
||||
|
@ -170,13 +167,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x01) == 0;
|
||||
|
||||
ContendPort(port);
|
||||
ULADevice.Contend(port);
|
||||
|
||||
// Only even addresses address the ULA
|
||||
if (lowBitReset)
|
||||
{
|
||||
// store the last OUT byte
|
||||
LastULAOutByte = value;
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
/*
|
||||
Bit 7 6 5 4 3 2 1 0
|
||||
|
@ -186,13 +184,17 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
*/
|
||||
|
||||
// Border - LSB 3 bits hold the border colour
|
||||
BorderColour = value & BORDER_BIT;
|
||||
if (ULADevice.borderColour != (value & BORDER_BIT))
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
|
||||
ULADevice.borderColour = value & BORDER_BIT;
|
||||
|
||||
// Buzzer
|
||||
BuzzerDevice.ProcessPulseValue(false, (value & EAR_BIT) != 0);
|
||||
|
||||
// Tape
|
||||
TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
|
||||
|
||||
}
|
||||
|
||||
// Active AY Register
|
||||
|
|
|
@ -29,19 +29,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// init addressable memory from ROM and RAM banks
|
||||
ReInitMemory();
|
||||
|
||||
//DisplayLineTime = 132;
|
||||
//VsyncNumerator = 3546900 * 2;
|
||||
|
||||
InitScreenConfig(borderType);
|
||||
InitScreen();
|
||||
|
||||
ResetULACycle();
|
||||
ULADevice = new ULA48(this);
|
||||
|
||||
BuzzerDevice = new Buzzer(this);
|
||||
BuzzerDevice.Init(44100, UlaFrameCycleCount);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
||||
AYDevice = new AY38912();
|
||||
AYDevice.Init(44100, UlaFrameCycleCount);
|
||||
AYDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
||||
KeyboardDevice = new Keyboard48(this);
|
||||
KempstonDevice = new KempstonJoystick(this);
|
||||
|
|
|
@ -307,7 +307,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -318,13 +322,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
if ((addr & 0xC000) == 0x4000)
|
||||
{
|
||||
// addr is in RAM not ROM - apply memory contention if neccessary
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -336,18 +337,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
if (addr < 0x4000)
|
||||
{
|
||||
// Do nothing - we cannot write to ROM
|
||||
return;
|
||||
}
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// possible contended RAM
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x0001) == 0;
|
||||
|
||||
ContendPort((ushort)port);
|
||||
ULADevice.Contend(port);
|
||||
|
||||
// Kempston Joystick
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
|
@ -141,7 +141,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x01) == 0;
|
||||
|
||||
ContendPort(port);
|
||||
ULADevice.Contend(port);
|
||||
|
||||
// Only even addresses address the ULA
|
||||
if (lowBitReset)
|
||||
|
@ -157,7 +157,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
*/
|
||||
|
||||
// Border - LSB 3 bits hold the border colour
|
||||
BorderColour = value & BORDER_BIT;
|
||||
if (ULADevice.borderColour != (value & BORDER_BIT))
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
|
||||
ULADevice.borderColour = value & BORDER_BIT;
|
||||
|
||||
// Buzzer
|
||||
BuzzerDevice.ProcessPulseValue(false, (value & EAR_BIT) != 0);
|
||||
|
|
|
@ -29,19 +29,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// init addressable memory from ROM and RAM banks
|
||||
ReInitMemory();
|
||||
|
||||
//DisplayLineTime = 132;
|
||||
//VsyncNumerator = 3546900;
|
||||
|
||||
InitScreenConfig(borderType);
|
||||
InitScreen();
|
||||
|
||||
ResetULACycle();
|
||||
ULADevice = new ULA48(this);
|
||||
|
||||
BuzzerDevice = new Buzzer(this);
|
||||
BuzzerDevice.Init(44100, UlaFrameCycleCount);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
||||
AYDevice = new AY38912();
|
||||
AYDevice.Init(44100, UlaFrameCycleCount);
|
||||
AYDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
||||
KeyboardDevice = new Keyboard48(this);
|
||||
KempstonDevice = new KempstonJoystick(this);
|
||||
|
|
|
@ -94,20 +94,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
CPU.TotalExecutedCycles += 3;
|
||||
|
||||
var data = ReadBus(addr);
|
||||
if ((addr & 0xC000) == 0x4000)
|
||||
{
|
||||
// addr is in RAM not ROM - apply memory contention if neccessary
|
||||
if (addr >= 0x8000)
|
||||
{
|
||||
data = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -119,22 +111,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
if (addr < 0x4000)
|
||||
{
|
||||
// Do nothing - we cannot write to ROM
|
||||
return;
|
||||
}
|
||||
else if (addr >= 0x8000)
|
||||
{
|
||||
// memory does not exist
|
||||
return;
|
||||
}
|
||||
else if (addr < 0x8000)
|
||||
{
|
||||
// possible contended RAM
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
CPU.TotalExecutedCycles += 3;
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
|
|
@ -77,13 +77,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
|
||||
var data = ReadBus(addr);
|
||||
if ((addr & 0xC000) == 0x4000)
|
||||
{
|
||||
// addr is in RAM not ROM - apply memory contention if neccessary
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -95,24 +93,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
if (addr < 0x4000)
|
||||
{
|
||||
// Do nothing - we cannot write to ROM
|
||||
return;
|
||||
}
|
||||
/*
|
||||
else if (addr < 0xC000)
|
||||
{
|
||||
// possible contended RAM
|
||||
var delay = GetContentionValue(CurrentFrameCycle);
|
||||
CPU.TotalExecutedCycles += delay;
|
||||
}
|
||||
*/
|
||||
|
||||
// apply contention if necessry
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x0001) == 0;
|
||||
|
||||
ContendPort((ushort)port);
|
||||
ULADevice.Contend(port);
|
||||
|
||||
// Kempston Joystick
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
|
@ -159,8 +159,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// Tape
|
||||
TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
|
||||
|
||||
CPU.TotalExecutedCycles += 3;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
ULADevice = new ULA48(this);
|
||||
|
||||
InitScreenConfig(borderType);
|
||||
InitScreen();
|
||||
|
||||
ResetULACycle();
|
||||
|
||||
BuzzerDevice = new Buzzer(this);
|
||||
BuzzerDevice.Init(44100, UlaFrameCycleCount);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
||||
KeyboardDevice = new Keyboard48(this);
|
||||
KempstonDevice = new KempstonJoystick(this);
|
||||
|
|
Loading…
Reference in New Issue