inspect variables by selecting

This commit is contained in:
Steven Hugg 2018-08-27 09:28:31 -04:00
parent 49593cc38d
commit 8581fcabd6
8 changed files with 81 additions and 51 deletions

View File

@ -44,6 +44,10 @@
color:#ffcccc;
background-color:#660000;
}
.tooltipinfoline {
color:#ccccff;
background-color:#000066;
}
#controls_top {
position: absolute;
padding: 0.5em;

View File

@ -52,6 +52,8 @@ TODO:
- navigator.getGamepads
- VCS library
- better VCS single stepping, maybe also listings
- New File (include file)
- VCS skips step on lsr/lsr after run to line
FYI: Image links for the books on http://8bitworkshop.com/ are broken
On the website the additional grey spacing next to the program line numbers is not dynamically resized when the web browser window size is changed. Intentional?

View File

@ -1,5 +0,0 @@
#!/bin/bash
. ./scripts/env.sh
rsync --stats -rilv -e "ssh -p 2222" ./blog/ $RSYNC_PATH/blog/
#rsync --stats -rilv -e "ssh -p 2222" ./scripts/ pzp@104.131.86.119:./backups

View File

@ -46,7 +46,7 @@ export interface Platform {
loadControlsState?(state : EmuControlsState) : void;
saveControlsState?() : EmuControlsState;
inspect?(ident:string) : void;
inspect?(ident:string) : string;
disassemble?(addr:number, readfn:(addr:number)=>number) : DisasmLine;
readAddress?(addr:number) : number;
setFrameRate?(fps:number) : void;
@ -97,22 +97,36 @@ export interface EmuRecorder {
/////
abstract class BaseDebugPlatform {
export abstract class BasePlatform {
recorder : EmuRecorder = null;
abstract loadState(state : EmuState) : void;
abstract saveState() : EmuState;
abstract pause() : void;
abstract resume() : void;
setRecorder(recorder : EmuRecorder) : void {
this.recorder = recorder;
}
updateRecorder() {
// are we recording and do we need to save a frame?
if (this.recorder && (<Platform><any>this).isRunning() && this.recorder.frameRequested()) {
this.recorder.recordFrame(this.saveState());
}
}
}
export abstract class BaseDebugPlatform extends BasePlatform {
onBreakpointHit : BreakpointCallback;
debugCondition : DebugCondition;
debugSavedState : EmuState = null;
debugBreakState : EmuState = null;
debugTargetClock : number = 0;
debugClock : number = 0;
recorder : EmuRecorder = null;
abstract getCPUState() : CpuState;
abstract saveState() : EmuState;
abstract loadState?(state : EmuState) : void;
abstract pause() : void;
abstract resume() : void;
abstract readAddress?(addr:number) : number;
abstract advance?(novideo? : boolean) : void;
abstract readAddress(addr:number) : number;
abstract advance(novideo? : boolean) : void;
getDebugCallback() : DebugCondition {
return this.debugCondition;
@ -139,15 +153,6 @@ abstract class BaseDebugPlatform {
this.debugBreakState = null;
this.resume();
}
setRecorder?(recorder : EmuRecorder) : void {
this.recorder = recorder;
}
updateRecorder() {
// are we recording and do we need to save a frame?
if (this.recorder && (<Platform><any>this).isRunning() && this.recorder.frameRequested()) {
this.recorder.recordFrame(this.saveState());
}
}
preFrame() {
this.updateRecorder();
}
@ -160,7 +165,7 @@ abstract class BaseDebugPlatform {
}
}
abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
export abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
debugPCDelta = -1;
evalDebugCondition() {

View File

@ -230,7 +230,7 @@ export var AnimationTimer = function(frequencyHz:number, callback:() => void) {
}
}
//
// TODO: move to util?
export function dumpRAM(ram:number[], ramofs:number, ramlen:number) : string {
var s = "";

View File

@ -1,6 +1,6 @@
"use strict";
import { Platform, cpuStateToLongString_6502, BaseMAMEPlatform, EmuRecorder, dumpStackToString, DisasmLine } from "../baseplatform";
import { Platform, BasePlatform, cpuStateToLongString_6502, BaseMAMEPlatform, EmuRecorder, dumpStackToString, DisasmLine } from "../baseplatform";
import { PLATFORMS, RAM, newAddressDecoder, dumpRAM } from "../emu";
import { hex, lpad, tobin, byte2signed } from "../util";
import { CodeAnalyzer_vcs } from "../analysis";
@ -48,9 +48,9 @@ Javatari.CARTRIDGE_CHANGE_DISABLED = true;
Javatari.DEBUG_SCANLINE_OVERFLOW = false; // TODO: make a switch
Javatari.AUDIO_BUFFER_SIZE = 256;
class VCSPlatform {
class VCSPlatform extends BasePlatform {
recorder : EmuRecorder;
lastDebugState;
getPresets() { return VCS_PRESETS; }
@ -119,11 +119,13 @@ class VCSPlatform {
state.c.PC = (state.c.PC - 1) & 0xffff;
Javatari.room.console.pause();
Javatari.room.speaker.mute();
this.lastDebugState = state;
callback(state);
}
Javatari.room.speaker.mute();
}
clearDebug() {
this.lastDebugState = null;
Javatari.room.console.disableDebug();
Javatari.room.console.onBreakpointHit = null;
if (this.isRunning()) Javatari.room.speaker.play();
@ -147,6 +149,9 @@ class VCSPlatform {
loadState(state) {
return Javatari.room.console.loadState(state);
}
getCPUState() {
return Javatari.room.console.saveState().c;
}
saveControlsState() {
return Javatari.room.console.saveControlsState();
}
@ -154,7 +159,11 @@ class VCSPlatform {
Javatari.room.console.loadControlsState(state);
}
readAddress(addr) {
return Javatari.room.console.readAddress(addr);
// TODO: shouldn't have to do this when debugging
if (this.lastDebugState && addr >= 0x80 && addr < 0x100)
return this.getRAMForState(this.lastDebugState)[addr & 0x7f];
else
return Javatari.room.console.readAddress(addr);
}
writeAddress(addr,value) {
Javatari.room.console.writeAddress(addr,value);
@ -233,15 +242,6 @@ class VCSPlatform {
return s;
}
setRecorder(recorder : EmuRecorder) : void {
this.recorder = recorder;
}
updateRecorder() {
// are we recording and do we need to save a frame?
if (this.recorder && this.isRunning() && this.recorder.frameRequested()) {
this.recorder.recordFrame(this.saveState());
}
}
disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {
return disassemble6502(pc, read(pc), read(pc+1), read(pc+2));
}

View File

@ -65,13 +65,6 @@ var lastDebugInfo; // last debug info (CPU text)
var lastDebugState; // last debug state (object)
var debugCategory; // current debug category
function inspectVariable(ed, name) { // TODO: ed?
var val;
if (platform.inspect) {
platform.inspect(name);
}
}
function getCurrentPresetTitle() : string {
if (!current_preset_entry)
return main_file_id || "ROM";

View File

@ -1,6 +1,7 @@
"use strict";
import $ = require("jquery");
//import CodeMirror = require("codemirror");
import { CodeProject } from "./project";
import { SourceFile, WorkerError } from "./workertypes";
import { Platform } from "./baseplatform";
@ -27,14 +28,12 @@ declare var CodeMirror;
declare var platform : Platform;
declare var platform_id : string;
declare var compparams;
declare var symbolmap : {[ident:string]:number};
declare var addr2symbol : {[addr:number]:string};
declare var current_project : CodeProject;
declare var VirtualList;
declare var lastDebugState;
// TODO: functions
declare function inspectVariable(ed, name?:string);
// helper function for editor
function jumpToLine(ed, i:number) {
var t = ed.charCoords({line: i, ch: 0}, "local").top;
@ -61,6 +60,7 @@ export class SourceEditor implements ProjectView {
currentDebugLine : number;
errormsgs = [];
errorwidgets = [];
inspectWidget;
createDiv(parent:HTMLElement, text:string) {
var div = document.createElement('div');
@ -97,16 +97,47 @@ export class SourceEditor implements ProjectView {
this.editor.on('cursorActivity', (ed) => {
var start = this.editor.getCursor(true);
var end = this.editor.getCursor(false);
if (start.line == end.line && start.ch < end.ch) {
if (start.line == end.line && start.ch < end.ch && end.ch-start.ch < 80) {
var name = this.editor.getSelection();
inspectVariable(this.editor, name);
this.inspect(name);
} else {
inspectVariable(this.editor);
this.inspect(null);
}
});
//scrollProfileView(editor);
this.editor.setOption("mode", this.mode);
}
inspect(ident : string) : void {
var result;
if (platform.inspect) {
result = platform.inspect(ident);
} else if (!platform.isRunning() && platform.readAddress) { // only inspect when stopped
// TODO: platform should know its symbols
var addr = symbolmap[ident];
if (addr) {
var size=4;
result = "$" + hex(addr,4) + ":";
for (var i=0; i<size; i++) {
var byte = platform.readAddress(addr+i);
result += " $" + hex(byte,2) + " (" + byte + ")";
if (addr2symbol[addr+1]) break; // stop if we hit another symbol
else if (i==size-1) result += " ...";
}
}
}
if (this.inspectWidget) {
this.inspectWidget.clear();
this.inspectWidget = null;
}
if (result) {
var infospan = document.createElement("span");
infospan.setAttribute("class", "tooltipinfoline");
infospan.appendChild(document.createTextNode(result));
var line = this.editor.getCursor().line;
this.inspectWidget = this.editor.addLineWidget(line, infospan, {above:false});
}
}
setText(text:string) {
this.editor.setValue(text); // calls setCode()