rewind

package
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2021 License: GPL-3.0, GPL-3.0 Imports: 15 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type PokeHook added in v0.10.1

type PokeHook func(res *State) error

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 NewRewind

func NewRewind(vcs *hardware.VCS, runner Runner) (*Rewind, error)

NewRewind is the preferred method of initialisation for the Rewind type.

func (*Rewind) GetComparison

func (r *Rewind) GetComparison() *State

GetComparison gets a reference to current comparison point.

func (*Rewind) GetCurrentState added in v0.10.1

func (r *Rewind) GetCurrentState() *State

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 (r Rewind) GetSummary() Summary

func (*Rewind) GotoFrame

func (r *Rewind) GotoFrame(frame int) error

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

func (r *Rewind) GotoFrameCoords(frame int, scanline int, clock int) error

GotoFrameCoords of current frame.

func (*Rewind) GotoLast

func (r *Rewind) GotoLast() error

GotoLast sets the position to the last in the timeline.

func (*Rewind) GotoState added in v0.10.1

func (r *Rewind) GotoState(state *State) error

GotoState will the run the VCS to the quoted state.

func (*Rewind) NewFrame

func (r *Rewind) NewFrame(_ television.FrameInfo) error

NewFrame is in an implementation of television.FrameTrigger.

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

func (r *Rewind) RunFromState(from *State, to *State, poke PokeHook) error

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.

func (*Rewind) String

func (r *Rewind) String() string

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.

func (State) String

func (s State) String() string

type Summary

type Summary struct {
	Start int
	End   int
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL