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); } } }