using System.Collections.Generic;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
///
/// This class is responsible to "play" a tape file.
///
public class TapeBlockSetPlayer : ISupportsTapeBlockSetPlayback
{
///
/// All data blocks that can be played back
///
public List DataBlocks { get; }
///
/// Signs that the player completed playing back the file
///
public bool Eof { get; private set; }
///
/// Gets the currently playing block's index
///
public int CurrentBlockIndex { get; private set; }
///
/// The current playable block
///
public ISupportsTapeBlockPlayback CurrentBlock => DataBlocks[CurrentBlockIndex];
///
/// The current playing phase
///
public PlayPhase PlayPhase { get; private set; }
///
/// The cycle count of the CPU when playing starts
///
public long StartCycle { get; private set; }
public TapeBlockSetPlayer(List dataBlocks)
{
DataBlocks = dataBlocks;
Eof = dataBlocks.Count == 0;
}
///
/// Initializes the player
///
public void InitPlay(long startTact)
{
CurrentBlockIndex = -1;
NextBlock(startTact);
PlayPhase = PlayPhase.None;
StartCycle = startTact;
}
///
/// Gets the EAR bit value for the specified cycle
///
/// Cycles to retrieve the EAR bit
///
/// A tuple of the EAR bit and a flag that indicates it is time to move to the next block
///
public bool GetEarBit(long currentCycle)
{
// --- Check for EOF
if (CurrentBlockIndex == DataBlocks.Count - 1
&& (CurrentBlock.PlayPhase == PlayPhase.Pause || CurrentBlock.PlayPhase == PlayPhase.Completed))
{
Eof = true;
}
if (CurrentBlockIndex >= DataBlocks.Count || CurrentBlock == null)
{
// --- After all playable block played back, there's nothing more to do
PlayPhase = PlayPhase.Completed;
return true;
}
var earbit = CurrentBlock.GetEarBit(currentCycle);
if (CurrentBlock.PlayPhase == PlayPhase.Completed)
{
NextBlock(currentCycle);
}
return earbit;
}
///
/// Moves the current block index to the next playable block
///
/// Cycles time to start the next block
public void NextBlock(long currentCycle)
{
if (CurrentBlockIndex >= DataBlocks.Count - 1)
{
PlayPhase = PlayPhase.Completed;
Eof = true;
return;
}
CurrentBlockIndex++;
CurrentBlock.InitPlay(currentCycle);
}
}
}