import { CpuHistoryClass } from '../cpuhistory' ; import { HistoryInstructionInfo } from '../decodehistinfo' ; import { Settings } from '../../settings' ; import { Utility } from '../../misc/utility' ; /**
 * This class takes care of the internal simulator history.
 * Pleae note that for performance reasons (push is faster than unshift)
 * the history array has been turned around:
 * The oldest item is at 0, the youngest at historyIndex.
 * Please also note that the array is used as a ringbuffer once the
 * maximum size has reached (because of performance).
 * Variables:
 * - historyIndex: Read index (in ring buffer). Current position in history.
 * - historyWriteIndex: Write index (in ring buffer). Last written position.
 *
 * If history-buffer <= maxSize:
 * |-----|------------| . . . . . . . . . . . . |
 * 0     h.Index      h.writeIndex=h.length-1   maxSize
 *
 * if history-buffer > maxSize:
 * |-----|------------|-------------------------|
 * 0     h.Index      h.writeIndex    h.length=maxSize
 */ export class ZSimCpuHistory extends CpuHistoryClass { protected historyWriteIndex : number ; constructor ( ) { super ( ) ; } /**
     * Init.
     */ public init ( ) { super . init ( ) ; this . historyWriteIndex = - 1 ; } /**
     * The internal simulator (because it's internal) has a special way to store the history.
     */ public clear ( ) { ( async ( ) => { this . historyIndex = - 1 ; this . revDbgHistory . length = 0 ; this . reverseDbgStack = undefined as any ; } ) ( ) ; } returns public async getPrevRegistersAsync ( ) { let index = this . historyIndex ; if ( index < 0 ) { index = this . historyWriteIndex ; } else { index -- ; if ( index < 0 ) index = this . history . length - 1 ; if ( index == this . historyWriteIndex ) return undefined ; } this . historyIndex = index ; const regs = this . history [ index ] ; return regs ; } returns public getNextRegisters ( ) { let index = this . historyIndex ; if ( index == this . historyWriteIndex ) { this . historyIndex = - 1 ; return undefined ; } index ++ ; if ( index >= this . history . length ) index = 0 ; this . historyIndex = index ; const regs = this . history [ index ] ; return regs ; } param line public pushHistoryInfo ( line , exchange = false ) { if ( this . history . length >= this . maxSize ) { let index = this . historyWriteIndex ; index ++ ; if ( index >= this . maxSize ) index = 0 ; this . historyWriteIndex = index ; const oldObj = this . history [ index ] ; oldObj . set ( line ) ; } else { this . history . push ( line ) ; this . historyWriteIndex ++ ; } } param i returns public getPreviousAddress ( i ) { const len = this . history . length ; if ( len == 0 ) return undefined ; let k = this . historyIndex - i ; while ( k < 0 ) k += len ; if ( k == this . historyWriteIndex ) return undefined ; const line = this . history [ k ] ; const addr = this . getAddress ( line ) ; return addr ; } /**
     * Emits 'historySpot' to signal that the files should be decorated.
     * It can happen that this method has to retrieve data from the
     * remote.
     */ protected emitHistorySpot ( ) { let count = Settings . launch . history . spotCount ; if ( count <= 0 ) return ; const len = this . history . length ; Utility . assert ( len > 0 ) ; let startIndex = this . historyIndex ; if ( startIndex < 0 ) startIndex = this . historyWriteIndex ; let index = startIndex ; const indices = new Array < number > ( ) ; for ( let i = 0 ; i < count ; i ++ ) { indices . push ( index ) ; index -- ; if ( index < 0 ) index = len - 1 ; if ( index == this . historyWriteIndex ) break ; } index = startIndex ; for ( let i = 0 ; i < count ; i ++ ) { if ( index == this . historyWriteIndex ) break ; index ++ ; if ( index >= len ) index = 0 ; indices . unshift ( index ) ; } let convertedStartIndex = index ; const { addresses , registers } = this . calcSpotHistoryAddressesAndRegisters ( indices ) ; convertedStartIndex = this . historyWriteIndex - convertedStartIndex ; if ( convertedStartIndex < 0 ) convertedStartIndex += len ; this . emit ( 'historySpot' , convertedStartIndex , addresses , registers ) ; } }