diff --git a/css/ui.css b/css/ui.css index 989332c3..edc0a2c5 100644 --- a/css/ui.css +++ b/css/ui.css @@ -44,6 +44,10 @@ color:#ffcccc; background-color:#660000; } +.tooltipinfoline { + color:#ccccff; + background-color:#000066; +} #controls_top { position: absolute; padding: 0.5em; diff --git a/doc/notes.txt b/doc/notes.txt index fbe89694..8eea96ae 100644 --- a/doc/notes.txt +++ b/doc/notes.txt @@ -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? diff --git a/scripts/sync-blog.sh b/scripts/sync-blog.sh deleted file mode 100755 index c410e1e5..00000000 --- a/scripts/sync-blog.sh +++ /dev/null @@ -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 diff --git a/src/baseplatform.ts b/src/baseplatform.ts index 597d2f29..3b0db7fe 100644 --- a/src/baseplatform.ts +++ b/src/baseplatform.ts @@ -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 && (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 && (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() { diff --git a/src/emu.ts b/src/emu.ts index dcdf73d9..d33a3856 100644 --- a/src/emu.ts +++ b/src/emu.ts @@ -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 = ""; diff --git a/src/platform/vcs.ts b/src/platform/vcs.ts index 6bfe0a44..ecaf6ad6 100644 --- a/src/platform/vcs.ts +++ b/src/platform/vcs.ts @@ -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)); } diff --git a/src/ui.ts b/src/ui.ts index 058970fe..a42d60b2 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -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"; diff --git a/src/views.ts b/src/views.ts index d4f59707..5f8d0a78 100644 --- a/src/views.ts +++ b/src/views.ts @@ -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