Documentation ¶
Overview ¶
Package rewind coordinates the periodic snapshotting of the emulation state. A previously seen frame can be returned to with the GotoFrame() function. If the requested frame is not in the history then the nearest frame that is will be used. The GotoLast() function will move the emulation to the last frame, whatever that might be.
The frequency at which snapshots are made is definable. Frames that are in between the snapshots can still be plumbed in, the rewind package handling the interleaving by running the emulation for the missing period.
In fact, the emulation is run even when the rewind package is set to snapshot every frame (a frequency of one) in order to generate the image data (storing the image data is memory wasteful). For this to work, the Rewind type is initialised with a reference to to the Runner interface. Implementations of the Runner interface should loop until the continueCheck() returns false.
Regular emulation loops (ie. not catch-up loop of the Runner interface) must call Check() after every CPU instruction to catch frame boundaries as early as possible. The rewind package will take the snapshot at the appropriate time.
The ExecutionState() function can be called to force a snapshot to be taken at any time. This should probably only ever be used when the emulation is paused. The rewind package will delete an execution snapshot when the next snapshot is taken (meaning that there is only ever one execution state in the history at any one time and that it will be at the end).
Snapshots are stored in frame order from the splice point. The splice point will be wherever the snapshot history has been rewound to. For example, in a history of length 100 frames: the emulation has rewound back to frame 50. When the emulation is resumed, snapshots will be added at this point. The previous history of frames 51 to 100 will be lost.
Reset and Boundary snapshots are special splice points that only ever occur once and at the beginning of the history. Reset occurs only when the Reset() function is called and is intended to be called whenver the VCS is power cycled (not the reset switch).
The Boundrary snapshot occurs when history has been cleared for some other reason. This was added to better support PlusROM cartridges and to ensure that network events are not replayed. The rewind package will add the boundary snapshot (to an empty history) automatically whenever the RewindBoundary() function from the attached cartridge returns true.
One of the weaknesses of the rewind package currently is the absence of any input replay. This might be particularly noticeable with large snapshot frequencies. Future versions of the package will record and replay input.
Index ¶
- type PokeHook
- type Preferences
- type Rewind
- func (r *Rewind) GetComparison() *State
- func (r *Rewind) GetCurrentState() *State
- func (r Rewind) GetSummary() Summary
- func (r *Rewind) GotoFrame(frame int) error
- func (r *Rewind) GotoFrameCoords(frame int, scanline int, clock int) error
- func (r *Rewind) GotoLast() error
- func (r *Rewind) GotoState(state *State) error
- func (r *Rewind) NewFrame(_ bool) error
- func (r *Rewind) RecordExecutionState()
- func (r *Rewind) RecordFrameState()
- func (r *Rewind) Reset()
- func (r *Rewind) RunFromState(from *State, to *State, poke PokeHook) error
- func (r *Rewind) SearchMemoryWrite(tgt *State, addr uint16, value uint8, valueMask uint8) (*State, error)
- func (r *Rewind) SearchRegisterWrite(tgt *State, reg rune, value uint8, valueMask uint8) (*State, error)
- func (r *Rewind) SetComparison()
- func (r *Rewind) String() string
- type Runner
- type State
- type Summary
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Preferences ¶
type Preferences struct { // whether to apply the high mirror bits to the displayed address MaxEntries prefs.Int Freq prefs.Int // contains filtered or unexported fields }
func (*Preferences) Load ¶
func (p *Preferences) Load() error
Load disassembly preferences and apply to the current disassembly.
func (*Preferences) Save ¶
func (p *Preferences) Save() error
Save current disassembly preferences to disk.
func (*Preferences) String ¶
func (p *Preferences) String() string
type Rewind ¶
type Rewind struct { // prefs for the rewind system Prefs *Preferences // contains filtered or unexported fields }
Rewind contains a history of machine states for the emulation.
func (*Rewind) GetComparison ¶
GetComparison gets a reference to current comparison point.
func (*Rewind) GetCurrentState ¶ added in v0.10.1
GetCurrentState creates a returns an adhoc snapshot of the current state. It does not add the state to the rewind history.
func (Rewind) GetSummary ¶
func (*Rewind) GotoFrame ¶
GotoFrame searches the timeline for the frame number. If the precise frame number can not be found the nearest frame will be plumbed in.
func (*Rewind) GotoFrameCoords ¶
GotoFrameCoords of current frame.
func (*Rewind) RecordExecutionState ¶ added in v0.10.1
func (r *Rewind) RecordExecutionState()
RecordExecutionState takes a snapshot of the emulation's ExecutionState state. It will do nothing if the last call to ResolveNewFrame() resulted in a snapshot being taken.
func (*Rewind) RecordFrameState ¶ added in v0.10.1
func (r *Rewind) RecordFrameState()
RecordFrameState should be called after every CPU instruction to check whether a new frame has been triggered since the last call. Delaying a call to this function may result in sub-optimal results.
func (*Rewind) Reset ¶
func (r *Rewind) Reset()
Reset rewind system removes all entries and takes a snapshot of the execution state. This should be called whenever a new cartridge is attached to the emulation.
func (*Rewind) RunFromState ¶ added in v0.10.1
RunFromState will the run the VCS from one state to another state.
func (*Rewind) SearchMemoryWrite ¶ added in v0.10.1
func (r *Rewind) SearchMemoryWrite(tgt *State, addr uint16, value uint8, valueMask uint8) (*State, error)
SearchMemoryWrite runs an emulation between two states looking for the instance when the address is written to with the value (valueMask is applied to mask specific bits)
The supplied target state is the upper limit of the search. The lower limit of the search is one frame before the target State.
The supplied address will be normalised.
Returns the most recent State at which the memory write was found. If a more recent address write is found but not the correct value, then no state is returned.
func (*Rewind) SearchRegisterWrite ¶ added in v0.10.1
func (r *Rewind) SearchRegisterWrite(tgt *State, reg rune, value uint8, valueMask uint8) (*State, error)
SearchMemoryWrite runs an emulation between two states looking for the instance when the register is written to with the value (valueMask is applied to mask specific bits)
The supplied target state is the upper limit of the search. The lower limit of the search is one frame before the target State.
Returns the most recent State at which the register write was found. If a more recent register write is found but not the correct value, then no state is returned.
func (*Rewind) SetComparison ¶
func (r *Rewind) SetComparison()
SetComparison points comparison to the most recent rewound entry.
type Runner ¶
type Runner interface { // CatchUpLoop implementations will run the emulation until continueCheck // returns false. // // Note that the TV's frame limiter is turned off before CatchUpLoop() is // called by the rewind system (and turned back to the previous setting // afterwards). // // CatchUpLoop may choose to service events (GUI events etc.) while it is // iterating but depending on required performance this may not be // necessary. CatchUpLoop(continueCheck func() bool) error }
Runner provides the rewind package the opportunity to run the emulation.
type State ¶
type State struct { CPU *cpu.CPU Mem *memory.Memory RIOT *riot.RIOT TIA *tia.TIA TV *television.State // contains filtered or unexported fields }
State contains pointers to areas of the VCS emulation. They can be read for reference.
type Summary ¶
Summary of the current state of the rewind system. The frame numbers for the snapshots at the start and end of the rewind history.
Useful for GUIs for example, to present the range of frame numbers that are available in the rewind history.
Note that there is no information about what type of snapshots the start and end frames are. This is intentional - I'm not sure that information would be useful.