mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-26 10:49:17 +00:00
testing out sub-frame replay slider, advanceFrameClock, fixed c64 memory corrupt
This commit is contained in:
parent
921d2b2253
commit
002aa41bad
20
index.html
20
index.html
@ -288,14 +288,24 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
</div>
|
||||
<div class="emulator disable-select" id="emulator">
|
||||
<!-- replay slider -->
|
||||
<div id="replaydiv" class="replaydiv" style="display:none">
|
||||
<div style="display:flex">
|
||||
<button id="replay_min" class="btn" title="Start of replay"><span class="glyphicon glyphicon-fast-backward" aria-hidden="true"></span></button>
|
||||
<div id="replaydiv" class="replaydiv" style="display:none;color:#ccc;text-align:left">
|
||||
<div style="display:flex; grid-gap:1em">
|
||||
<button id="replay_back" class="btn" title="Back one frame"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></button>
|
||||
<span id="replay_frame" style="text-align:center;width:3em;margin-left:1em;color:#ccc">-</span>
|
||||
<div>
|
||||
Frame<br>
|
||||
<span id="replay_frame" style="width:3em">-</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="0" value="0" class="slider" id="replayslider">
|
||||
<button id="replay_fwd" class="btn" title="Ahead one frame"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
|
||||
<button id="replay_max" class="btn" title="End of replay"><span class="glyphicon glyphicon-fast-forward" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
<div style="display:flex; grid-gap:1em" id="clockdiv">
|
||||
<button id="clock_back" class="btn" title="Back one step"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></button>
|
||||
<div>
|
||||
Step<br>
|
||||
<span id="replay_clock" style="width:3em">-</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="0" value="0" class="slider" id="clockslider">
|
||||
<button id="clock_fwd" class="btn" title="Forward one step"><span class="glyphicon glyphicon-forward" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- emulator video -->
|
||||
|
@ -112,7 +112,8 @@ export interface Platform {
|
||||
getMemoryMap?() : MemoryMap;
|
||||
|
||||
setRecorder?(recorder : EmuRecorder) : void;
|
||||
advance?(novideo? : boolean) : void;
|
||||
advance?(novideo? : boolean) : number;
|
||||
advanceFrameClock?(trap:DebugCondition, step:number) : number;
|
||||
showHelp?(tool:string, ident?:string) : void;
|
||||
resize?() : void;
|
||||
|
||||
@ -179,7 +180,7 @@ export abstract class BasePlatform {
|
||||
abstract saveState() : EmuState;
|
||||
abstract pause() : void;
|
||||
abstract resume() : void;
|
||||
abstract advance(novideo? : boolean) : void;
|
||||
abstract advance(novideo? : boolean) : number;
|
||||
|
||||
setRecorder(recorder : EmuRecorder) : void {
|
||||
this.recorder = recorder;
|
||||
@ -267,8 +268,9 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
||||
this.pollControls();
|
||||
this.updateRecorder();
|
||||
this.preFrame();
|
||||
this.advance(novideo);
|
||||
var steps = this.advance(novideo);
|
||||
this.postFrame();
|
||||
return steps;
|
||||
}
|
||||
// default debugging
|
||||
abstract getSP() : number;
|
||||
@ -1058,8 +1060,20 @@ export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPl
|
||||
}
|
||||
|
||||
advance(novideo:boolean) {
|
||||
this.machine.advanceFrame(this.getDebugCallback());
|
||||
var steps = this.machine.advanceFrame(this.getDebugCallback());
|
||||
if (!novideo && this.video) this.video.updateFrame();
|
||||
return steps;
|
||||
}
|
||||
|
||||
advanceFrameClock(trap, step) {
|
||||
if (!(step > 0)) return;
|
||||
if (this.machine instanceof BaseWASMMachine) {
|
||||
return this.machine.advanceFrameClock(trap, step);
|
||||
} else {
|
||||
return this.machine.advanceFrame(() => {
|
||||
return --step <= 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isRunning() {
|
||||
@ -1164,6 +1178,8 @@ export abstract class BaseWASMMachine {
|
||||
statearr : Uint8Array;
|
||||
cpustateptr : number;
|
||||
cpustatearr : Uint8Array;
|
||||
ctrlstateptr : number;
|
||||
ctrlstatearr : Uint8Array;
|
||||
cpu : CPU;
|
||||
romptr : number;
|
||||
romlen : number;
|
||||
@ -1215,6 +1231,9 @@ export abstract class BaseWASMMachine {
|
||||
var statesize = this.exports.machine_get_state_size();
|
||||
this.stateptr = this.exports.malloc(statesize);
|
||||
this.statearr = new Uint8Array(this.exports.memory.buffer, this.stateptr, statesize);
|
||||
var ctrlstatesize = this.exports.machine_get_controls_state_size();
|
||||
this.ctrlstateptr = this.exports.malloc(ctrlstatesize);
|
||||
this.ctrlstatearr = new Uint8Array(this.exports.memory.buffer, this.ctrlstateptr, ctrlstatesize);
|
||||
var cpustatesize = this.exports.machine_get_cpu_state_size();
|
||||
this.cpustateptr = this.exports.malloc(cpustatesize);
|
||||
this.cpustatearr = new Uint8Array(this.exports.memory.buffer, this.cpustateptr, cpustatesize);
|
||||
@ -1271,12 +1290,14 @@ export abstract class BaseWASMMachine {
|
||||
}
|
||||
// assume controls buffer is smaller than cpu buffer
|
||||
saveControlsState() : any {
|
||||
this.exports.machine_save_controls_state(this.sys, this.cpustateptr);
|
||||
return { controls:this.cpustatearr.slice(0, this.exports.machine_get_controls_state_size()) }
|
||||
//console.log(1, this.romptr, this.romlen, this.ctrlstateptr, this.romarr.slice(0,4), this.ctrlstatearr.slice(0,4));
|
||||
this.exports.machine_save_controls_state(this.sys, this.ctrlstateptr);
|
||||
//console.log(2, this.romptr, this.romlen, this.ctrlstateptr, this.romarr.slice(0,4), this.ctrlstatearr.slice(0,4));
|
||||
return { controls:this.ctrlstatearr.slice(0) }
|
||||
}
|
||||
loadControlsState(state) : void {
|
||||
this.cpustatearr.set(state.controls);
|
||||
this.exports.machine_load_controls_state(this.sys, this.cpustateptr);
|
||||
this.ctrlstatearr.set(state.controls);
|
||||
this.exports.machine_load_controls_state(this.sys, this.ctrlstateptr);
|
||||
}
|
||||
connectAudio(audio : SampledAudioSink) : void {
|
||||
this.audio = audio;
|
||||
|
@ -308,6 +308,7 @@ export abstract class BasicScanlineMachine extends BasicMachine implements Raste
|
||||
this.preFrame();
|
||||
var clock = 0;
|
||||
var endLineClock = 0;
|
||||
var steps = 0;
|
||||
this.probe.logNewFrame();
|
||||
for (var sl=0; sl<this.numTotalScanlines; sl++) {
|
||||
endLineClock += this.cpuCyclesPerLine;
|
||||
@ -320,13 +321,14 @@ export abstract class BasicScanlineMachine extends BasicMachine implements Raste
|
||||
break;
|
||||
}
|
||||
clock += this.advanceCPU();
|
||||
steps++;
|
||||
}
|
||||
this.drawScanline();
|
||||
this.probe.logNewScanline();
|
||||
this.probe.logClocks(clock-endLineClock);
|
||||
}
|
||||
this.postFrame();
|
||||
return clock;
|
||||
return steps; // TODO: return steps, not clock? for recorder
|
||||
}
|
||||
preFrame() { }
|
||||
postFrame() { }
|
||||
|
@ -1,6 +1,5 @@
|
||||
|
||||
import { Platform, BasePlatform, EmuState, EmuControlsState, EmuRecorder } from "./baseplatform";
|
||||
import { BaseDebugPlatform } from "./baseplatform";
|
||||
import { Platform, EmuState, EmuControlsState, EmuRecorder } from "./baseplatform";
|
||||
import { getNoiseSeed, setNoiseSeed } from "./emu";
|
||||
|
||||
// RECORDER
|
||||
@ -8,16 +7,19 @@ import { getNoiseSeed, setNoiseSeed } from "./emu";
|
||||
type FrameRec = {controls:EmuControlsState, seed:number};
|
||||
|
||||
export class StateRecorderImpl implements EmuRecorder {
|
||||
checkpointInterval : number = 60;
|
||||
|
||||
checkpointInterval : number = 10;
|
||||
callbackStateChanged : () => void;
|
||||
callbackNewCheckpoint : (state:EmuState) => void;
|
||||
maxCheckpoints : number = 120;
|
||||
maxCheckpoints : number = 300;
|
||||
|
||||
platform : Platform;
|
||||
checkpoints : EmuState[];
|
||||
framerecs : FrameRec[];
|
||||
frameCount : number;
|
||||
lastSeekFrame : number;
|
||||
lastSeekStep : number;
|
||||
lastStepCount : number;
|
||||
|
||||
constructor(platform : Platform) {
|
||||
this.reset();
|
||||
@ -29,6 +31,7 @@ export class StateRecorderImpl implements EmuRecorder {
|
||||
this.framerecs = [];
|
||||
this.frameCount = 0;
|
||||
this.lastSeekFrame = 0;
|
||||
this.lastSeekStep = 0;
|
||||
if (this.callbackStateChanged) this.callbackStateChanged();
|
||||
}
|
||||
|
||||
@ -50,6 +53,7 @@ export class StateRecorderImpl implements EmuRecorder {
|
||||
requested = (this.frameCount++ % this.checkpointInterval) == 0;
|
||||
}
|
||||
this.lastSeekFrame++;
|
||||
this.lastSeekStep = 0;
|
||||
if (this.callbackStateChanged) this.callbackStateChanged();
|
||||
return requested;
|
||||
}
|
||||
@ -62,6 +66,10 @@ export class StateRecorderImpl implements EmuRecorder {
|
||||
return this.lastSeekFrame;
|
||||
}
|
||||
|
||||
currentStep() : number {
|
||||
return this.lastSeekStep;
|
||||
}
|
||||
|
||||
recordFrame(state : EmuState) {
|
||||
this.checkpoints.push(state);
|
||||
if (this.callbackNewCheckpoint) this.callbackNewCheckpoint(state);
|
||||
@ -82,22 +90,35 @@ export class StateRecorderImpl implements EmuRecorder {
|
||||
return {frame:foundframe, state:this.checkpoints[foundidx]};
|
||||
}
|
||||
|
||||
loadFrame(seekframe : number) : number {
|
||||
if (seekframe == this.lastSeekFrame)
|
||||
loadFrame(seekframe : number, seekstep? : number) : number {
|
||||
seekframe |= 0;
|
||||
seekstep |= 0;
|
||||
if (seekframe == this.lastSeekFrame && seekstep == this.lastSeekStep) {
|
||||
return seekframe; // already set to this frame
|
||||
}
|
||||
// TODO: what if < 1?
|
||||
let {frame,state} = this.getStateAtOrBefore(seekframe-1);
|
||||
if (state) {
|
||||
var numSteps = 0;
|
||||
this.platform.pause();
|
||||
this.platform.loadState(state);
|
||||
// seek to frame index
|
||||
while (frame < seekframe) {
|
||||
if (frame < this.framerecs.length) {
|
||||
this.loadControls(frame);
|
||||
}
|
||||
frame++;
|
||||
this.platform.advance(frame < seekframe); // TODO: infinite loop?
|
||||
numSteps = this.platform.advance(frame < seekframe); // TODO: infinite loop?
|
||||
}
|
||||
// seek to step index
|
||||
// TODO: what if advance() returns clocks, but steps use insns?
|
||||
if (seekstep > 0 && this.platform.advanceFrameClock) {
|
||||
seekstep = this.platform.advanceFrameClock(null, seekstep);
|
||||
}
|
||||
// record new values
|
||||
this.lastSeekFrame = seekframe;
|
||||
this.lastSeekStep = seekstep;
|
||||
this.lastStepCount = numSteps;
|
||||
return seekframe;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -1261,6 +1261,7 @@ function clearBreakpoint() {
|
||||
|
||||
function resetAndDebug() {
|
||||
if (!checkRunReady()) return;
|
||||
var wasRecording = recorderActive;
|
||||
_disableRecording();
|
||||
if (platform.setupDebug && platform.readAddress) { // TODO??
|
||||
clearBreakpoint();
|
||||
@ -1274,6 +1275,7 @@ function resetAndDebug() {
|
||||
} else {
|
||||
platform.reset();
|
||||
}
|
||||
if (wasRecording) _enableRecording();
|
||||
}
|
||||
|
||||
function _breakExpression() {
|
||||
@ -1610,41 +1612,59 @@ function setupDebugControls() {
|
||||
|
||||
function setupReplaySlider() {
|
||||
var replayslider = $("#replayslider");
|
||||
var clockslider = $("#clockslider");
|
||||
var replayframeno = $("#replay_frame");
|
||||
var updateFrameNo = (n) => {
|
||||
replayframeno.text(n+"");
|
||||
var clockno = $("#replay_clock");
|
||||
if (!platform.advanceFrameClock) $("#clockdiv").hide(); // TODO: put this test in recorder?
|
||||
var updateFrameNo = () => {
|
||||
replayframeno.text(stateRecorder.lastSeekFrame+"");
|
||||
clockno.text(stateRecorder.lastSeekStep+"");
|
||||
};
|
||||
var sliderChanged = (e) => {
|
||||
_pause();
|
||||
var frame = (<any>e.target).value;
|
||||
if (stateRecorder.loadFrame(frame)) {
|
||||
updateFrameNo(frame);
|
||||
projectWindows.tick();
|
||||
showDebugInfo(platform.saveState());
|
||||
var frame : number = parseInt(replayslider.val().toString());
|
||||
var step : number = parseInt(clockslider.val().toString());
|
||||
if (stateRecorder.loadFrame(frame, step)) {
|
||||
clockslider.attr('min', 0);
|
||||
clockslider.attr('max', stateRecorder.lastStepCount);
|
||||
updateFrameNo();
|
||||
uiDebugCallback(platform.saveState());
|
||||
}
|
||||
};
|
||||
var setFrameTo = (frame:number) => {
|
||||
_pause();
|
||||
if (stateRecorder.loadFrame(frame)) {
|
||||
replayslider.val(frame);
|
||||
updateFrameNo(frame);
|
||||
projectWindows.tick();
|
||||
showDebugInfo(platform.saveState());
|
||||
updateFrameNo();
|
||||
uiDebugCallback(platform.saveState());
|
||||
}
|
||||
};
|
||||
var setClockTo = (clock:number) => {
|
||||
_pause();
|
||||
var frame : number = parseInt(replayslider.val().toString());
|
||||
if (stateRecorder.loadFrame(frame, clock)) {
|
||||
clockslider.val(clock);
|
||||
updateFrameNo();
|
||||
uiDebugCallback(platform.saveState());
|
||||
}
|
||||
};
|
||||
stateRecorder.callbackStateChanged = () => {
|
||||
replayslider.attr('min', 1);
|
||||
replayslider.attr('max', stateRecorder.numFrames());
|
||||
replayslider.val(stateRecorder.currentFrame());
|
||||
updateFrameNo(stateRecorder.currentFrame());
|
||||
clockslider.val(stateRecorder.currentStep());
|
||||
updateFrameNo();
|
||||
showDebugInfo(platform.saveState());
|
||||
};
|
||||
replayslider.on('input', sliderChanged);
|
||||
replayslider.on('change', sliderChanged);
|
||||
clockslider.on('input', sliderChanged);
|
||||
//replayslider.on('change', sliderChanged);
|
||||
$("#replay_min").click(() => { setFrameTo(1) });
|
||||
$("#replay_max").click(() => { setFrameTo(stateRecorder.numFrames()); });
|
||||
$("#replay_back").click(() => { setFrameTo(parseInt(replayslider.val().toString()) - 1); });
|
||||
$("#replay_fwd").click(() => { setFrameTo(parseInt(replayslider.val().toString()) + 1); });
|
||||
$("#clock_back").click(() => { setClockTo(parseInt(clockslider.val().toString()) - 1); });
|
||||
$("#clock_fwd").click(() => { setClockTo(parseInt(clockslider.val().toString()) + 1); });
|
||||
$("#replay_bar").show();
|
||||
uitoolbar.add('ctrl+alt+0', 'Start/Stop Replay Recording', 'glyphicon-record', _toggleRecording).prop('id','dbg_record');
|
||||
}
|
||||
|
@ -394,6 +394,7 @@ export class Atari7800 extends BasicMachine implements RasterFrameBased {
|
||||
var rgb;
|
||||
var mc = 0;
|
||||
var fc = 0;
|
||||
var steps = 0;
|
||||
this.probe.logNewFrame();
|
||||
//console.log(hex(this.cpu.getPC()), hex(this.maria.dll));
|
||||
// visible lines
|
||||
@ -411,6 +412,7 @@ export class Atari7800 extends BasicMachine implements RasterFrameBased {
|
||||
break; // TODO?
|
||||
}
|
||||
mc += this.advanceCPU() << 2;
|
||||
steps++;
|
||||
}
|
||||
// is this scanline visible?
|
||||
if (visible) {
|
||||
@ -443,6 +445,7 @@ export class Atari7800 extends BasicMachine implements RasterFrameBased {
|
||||
break;
|
||||
}
|
||||
mc += this.advanceCPU() << 2;
|
||||
steps++;
|
||||
}
|
||||
// audio
|
||||
this.audio && this.audioadapter.generate(this.audio);
|
||||
@ -455,7 +458,8 @@ export class Atari7800 extends BasicMachine implements RasterFrameBased {
|
||||
// TODO let bkcol = this.maria.regs[0x0];
|
||||
// TODO $(this.video.canvas).css('background-color', COLORS_WEB[bkcol]);
|
||||
*/
|
||||
return (this.lastFrameCycles = fc);
|
||||
this.lastFrameCycles = fc;
|
||||
return steps;
|
||||
}
|
||||
|
||||
getRasterX() { return this.lastFrameCycles % colorClocksPerLine; }
|
||||
|
@ -40,6 +40,9 @@ class BallyAstrocadePlatform extends BaseZ80MachinePlatform<BallyAstrocade> impl
|
||||
{name:'Screen RAM',start:0x4000,size:0x1000,type:'ram'},
|
||||
{name:'BIOS Variables',start:0x4fce,size:0x5000-0x4fce,type:'ram'},
|
||||
] } };
|
||||
showHelp(tool:string, ident:string) {
|
||||
window.open("https://8bitworkshop.com/blog/platforms/astrocade/", "_help"); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
class BallyAstrocadeBIOSPlatform extends BallyAstrocadePlatform implements Platform {
|
||||
|
@ -489,12 +489,13 @@ const _Atari8Platform = function(mainElement) {
|
||||
jacanvas.mousedown(rasterPosBreakFn);
|
||||
}
|
||||
|
||||
advance(novideo : boolean) {
|
||||
advance(novideo : boolean) : number {
|
||||
var idata = video.getFrameData();
|
||||
var iofs = 0;
|
||||
var debugCond = this.getDebugCallback();
|
||||
var rgb;
|
||||
var freeClocks = 0;
|
||||
var totalClocks = 0;
|
||||
// load controls
|
||||
// TODO
|
||||
gtia.regs[0x10] = inputs[0] ^ 1;
|
||||
@ -518,6 +519,7 @@ const _Atari8Platform = function(mainElement) {
|
||||
break;
|
||||
}
|
||||
cpu.clockPulse();
|
||||
totalClocks++;
|
||||
}
|
||||
// 4 ANTIC pulses = 8 pixels
|
||||
if (antic.v >= 24 && antic.h >= 44 && antic.h < 44+176) { // TODO: const
|
||||
@ -535,6 +537,7 @@ const _Atari8Platform = function(mainElement) {
|
||||
let bkcol = gtia.regs[COLBK];
|
||||
$(video.canvas).css('background-color', COLORS_WEB[bkcol]);
|
||||
}
|
||||
return totalClocks;
|
||||
}
|
||||
|
||||
loadROM(title, data) {
|
||||
|
@ -318,13 +318,14 @@ const _GalaxianPlatform = function(mainElement, options) {
|
||||
return (a == 0x7000 || a == 0x7800) ? null : membus.read(a); // ignore watchdog
|
||||
}
|
||||
|
||||
advance(novideo: boolean) {
|
||||
advance(novideo: boolean) : number {
|
||||
var steps = 0;
|
||||
for (var sl = 0; sl < scanlinesPerFrame; sl++) {
|
||||
this.scanline = sl;
|
||||
if (!novideo) {
|
||||
gfx.drawScanline(pixels, sl);
|
||||
}
|
||||
this.runCPU(cpu, cpuCyclesPerLine);
|
||||
steps += this.runCPU(cpu, cpuCyclesPerLine);
|
||||
}
|
||||
// visible area is 256x224 (before rotation)
|
||||
if (!novideo) {
|
||||
@ -337,6 +338,7 @@ const _GalaxianPlatform = function(mainElement, options) {
|
||||
}
|
||||
// NMI interrupt @ 0x66
|
||||
if (interruptEnabled) { cpu.NMI(); }
|
||||
return steps;
|
||||
}
|
||||
|
||||
getRasterScanline() { return this.scanline; }
|
||||
|
@ -156,8 +156,9 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
|
||||
pollControls() { this.poller.poll(); }
|
||||
|
||||
advance(novideo : boolean) {
|
||||
advance(novideo : boolean) : number {
|
||||
this.nes.frame();
|
||||
return 29780; //TODO
|
||||
}
|
||||
|
||||
updateDebugViews() {
|
||||
@ -479,7 +480,7 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
] } };
|
||||
|
||||
showHelp(tool:string, ident:string) {
|
||||
window.open("https://8bitworkshop.com/blog/platforms/nintendo-nes.md.html", "_help"); // TODO
|
||||
window.open("https://8bitworkshop.com/blog/platforms/nes/", "_help"); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,8 +135,9 @@ class VCSPlatform extends BasePlatform {
|
||||
Javatari.room.speaker.powerOff();
|
||||
Javatari.room.speaker.powerOn();
|
||||
}
|
||||
advance() {
|
||||
advance() : number {
|
||||
Javatari.room.console.clockPulse();
|
||||
return 0; //TODO
|
||||
}
|
||||
// for unit test
|
||||
nextFrame() {
|
||||
@ -303,7 +304,7 @@ class VCSPlatform extends BasePlatform {
|
||||
if (tool == 'bataribasic')
|
||||
window.open("help/bataribasic/manual.html", "_help");
|
||||
else
|
||||
window.open("https://8bitworkshop.com/blog/platforms/atari-2600-vcs.md.html", "_help"); // TODO
|
||||
window.open("https://8bitworkshop.com/blog/platforms/vcs/", "_help"); // TODO
|
||||
}
|
||||
|
||||
getMemoryMap = function() { return {main:[
|
||||
|
@ -838,14 +838,16 @@ class VectrexPlatform extends Base6809Platform {
|
||||
this.psg.psg.register[14] = ~this.inputs[2];
|
||||
}
|
||||
|
||||
advance(novideo:boolean) {
|
||||
advance(novideo:boolean) : number {
|
||||
if (!novideo) this.video.clear();
|
||||
this.updateControls();
|
||||
this.probe.logNewFrame();
|
||||
var cycles = 1500000 / 60;
|
||||
while (cycles > 0) {
|
||||
cycles -= this.step();
|
||||
var frameCycles = 1500000 / 60;
|
||||
var cycles = 0;
|
||||
while (cycles < frameCycles) {
|
||||
cycles += this.step();
|
||||
}
|
||||
return cycles;
|
||||
}
|
||||
|
||||
step() {
|
||||
|
@ -460,13 +460,14 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
}
|
||||
|
||||
// TODO: merge with prev func
|
||||
advance(novideo : boolean) {
|
||||
advance(novideo : boolean) : number {
|
||||
this.setGenInputs();
|
||||
this.updateVideoFrameCycles(cyclesPerFrame, true, false);
|
||||
gen.__unreset();
|
||||
if (!novideo) {
|
||||
this.refreshVideoFrame();
|
||||
}
|
||||
return cyclesPerFrame; //TODO?
|
||||
}
|
||||
|
||||
refreshVideoFrame() {
|
||||
|
Loading…
Reference in New Issue
Block a user