mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
more tooltips for probe views; removed Event Probe view; fixed NES probe installation
This commit is contained in:
parent
236c4bd0dd
commit
9d6e97749d
@ -50,7 +50,7 @@ export class DebugSymbols {
|
||||
this.symbolmap = symbolmap;
|
||||
this.addr2symbol = invertMap(symbolmap);
|
||||
//// TODO: shouldn't be necc.
|
||||
if (!this.addr2symbol[0x0]) this.addr2symbol[0x0] = '__START__'; // needed for ...
|
||||
if (!this.addr2symbol[0x0]) this.addr2symbol[0x0] = ' '; // needed for ...
|
||||
this.addr2symbol[0x10000] = '__END__'; // ... dump memory to work
|
||||
}
|
||||
}
|
||||
@ -1089,7 +1089,6 @@ export abstract class Base6502MachinePlatform<T extends Machine> extends BaseMac
|
||||
default: return isDebuggable(this.machine) && this.machine.getDebugInfo(category, state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export abstract class BaseZ80MachinePlatform<T extends Machine> extends BaseMachinePlatform<T> {
|
||||
|
@ -351,6 +351,7 @@ export abstract class BasicMachine implements HasCPU, Bus, SampledAudioSource, A
|
||||
connectCPUIOBus(iobus:Bus) : void {
|
||||
this.cpu['connectIOBus'](this.probeIOBus(iobus));
|
||||
}
|
||||
// TODO: probe interrupts
|
||||
}
|
||||
|
||||
export abstract class BasicScanlineMachine extends BasicMachine implements RasterFrameBased {
|
||||
|
@ -144,23 +144,6 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
this.probe.logClocks(cycles);
|
||||
return cycles;
|
||||
}
|
||||
var ppu = this.nes.ppu;
|
||||
var old_endScanline = ppu.endScanline.bind(ppu);
|
||||
var old_startFrame = ppu.startFrame.bind(ppu);
|
||||
var old_writeMem = ppu.writeMem.bind(ppu);
|
||||
ppu.endScanline = () => {
|
||||
old_endScanline();
|
||||
this.probe.logNewScanline();
|
||||
}
|
||||
ppu.startFrame = () => {
|
||||
old_startFrame();
|
||||
this.probe.logNewFrame();
|
||||
}
|
||||
ppu.writeMem = (a,v) => {
|
||||
old_writeMem(a,v);
|
||||
this.probe.logVRAMWrite(a,v);
|
||||
}
|
||||
|
||||
this.timer = new AnimationTimer(60, this.nextFrame.bind(this));
|
||||
// set keyboard map
|
||||
this.poller = setKeyboardFromMap(this.video, [], JSNES_KEYCODE_MAP, (o,key,code,flags) => {
|
||||
@ -221,33 +204,55 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
var romstr = byteArrayToString(data);
|
||||
this.nes.loadROM(romstr);
|
||||
this.frameindex = 0;
|
||||
this.installIntercepts();
|
||||
}
|
||||
installIntercepts() {
|
||||
// intercept bus calls, unless we did it already
|
||||
if (!this.nes.mmap.haveProxied) {
|
||||
var oldload = this.nes.mmap.load.bind(this.nes.mmap);
|
||||
var oldwrite = this.nes.mmap.write.bind(this.nes.mmap);
|
||||
//var oldregLoad = this.nes.mmap.regLoad.bind(this.nes.mmap);
|
||||
//var oldregWrite = this.nes.mmap.regWrite.bind(this.nes.mmap);
|
||||
this.nes.mmap.load = (addr) => {
|
||||
var mmap = this.nes.mmap;
|
||||
if (!mmap.haveProxied) {
|
||||
var oldload = mmap.load.bind(mmap);
|
||||
var oldwrite = mmap.write.bind(mmap);
|
||||
//var oldregLoad = mmap.regLoad.bind(mmap);
|
||||
//var oldregWrite = mmap.regWrite.bind(mmap);
|
||||
mmap.load = (addr) => {
|
||||
var val = oldload(addr);
|
||||
this.probe.logRead(addr, val);
|
||||
return val;
|
||||
}
|
||||
this.nes.mmap.write = (addr, val) => {
|
||||
mmap.write = (addr, val) => {
|
||||
this.probe.logWrite(addr, val);
|
||||
oldwrite(addr, val);
|
||||
}
|
||||
/*
|
||||
this.nes.mmap.regLoad = (addr) => {
|
||||
mmap.regLoad = (addr) => {
|
||||
var val = oldregLoad(addr);
|
||||
this.probe.logIORead(addr, val);
|
||||
return val;
|
||||
}
|
||||
this.nes.mmap.regWrite = (addr, val) => {
|
||||
mmap.regWrite = (addr, val) => {
|
||||
this.probe.logIOWrite(addr, val);
|
||||
oldregWrite(addr, val);
|
||||
}
|
||||
*/
|
||||
this.nes.mmap.haveProxied = true;
|
||||
mmap.haveProxied = true;
|
||||
}
|
||||
var ppu = this.nes.ppu;
|
||||
if (!ppu.haveProxied) {
|
||||
var old_endScanline = ppu.endScanline.bind(ppu);
|
||||
var old_startFrame = ppu.startFrame.bind(ppu);
|
||||
var old_writeMem = ppu.writeMem.bind(ppu);
|
||||
ppu.endScanline = () => {
|
||||
old_endScanline();
|
||||
this.probe.logNewScanline();
|
||||
}
|
||||
ppu.startFrame = () => {
|
||||
old_startFrame();
|
||||
this.probe.logNewFrame();
|
||||
}
|
||||
ppu.writeMem = (a,v) => {
|
||||
old_writeMem(a,v);
|
||||
this.probe.logVRAMWrite(a,v);
|
||||
}
|
||||
}
|
||||
}
|
||||
newCodeAnalyzer() {
|
||||
@ -261,6 +266,7 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
reset() {
|
||||
//this.nes.cpu.reset(); // doesn't work right, crashes
|
||||
this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);
|
||||
this.installIntercepts();
|
||||
}
|
||||
isRunning() {
|
||||
return this.timer.isRunning();
|
||||
@ -312,6 +318,7 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
this.nes.ppu.spriteMem = state.ppu.spriteMem.slice(0);
|
||||
this.loadControlsState(state.ctrl);
|
||||
//$.extend(this.nes, state);
|
||||
this.installIntercepts();
|
||||
}
|
||||
saveControlsState() {
|
||||
return {
|
||||
@ -324,10 +331,10 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
||||
this.nes.controllers[2].state = state.c2;
|
||||
}
|
||||
readAddress(addr) {
|
||||
return this.nes.cpu.mem[addr] & 0xff;
|
||||
return this.nes.cpu.mem[addr];
|
||||
}
|
||||
readVRAMAddress(addr : number) : number {
|
||||
return this.nes.ppu.vramMem[addr & 0x7fff] & 0xff;
|
||||
return this.nes.ppu.vramMem[addr];
|
||||
}
|
||||
copy6502REGvars(c) {
|
||||
c.T = 0;
|
||||
|
@ -215,7 +215,6 @@ export class ProbeRecorder implements ProbeAll {
|
||||
}
|
||||
start() {
|
||||
this.m.connectProbe(this);
|
||||
this.reset();
|
||||
}
|
||||
stop() {
|
||||
this.m.connectProbe(null);
|
||||
|
@ -250,14 +250,11 @@ function refreshWindowList() {
|
||||
});
|
||||
}
|
||||
if (platform.startProbing) {
|
||||
addWindowItem("#eventprobe", "Event Probe", () => {
|
||||
return new Views.EventProbeView();
|
||||
});
|
||||
addWindowItem("#memheatmap", "Memory Heatmap", () => {
|
||||
addWindowItem("#memheatmap", "Memory Probe", () => {
|
||||
return new Views.AddressHeatMapView();
|
||||
});
|
||||
// TODO: only if raster
|
||||
addWindowItem("#crtheatmap", "Screen Heatmap", () => {
|
||||
addWindowItem("#crtheatmap", "CRT Probe", () => {
|
||||
return new Views.RasterPCHeatMapView();
|
||||
});
|
||||
}
|
||||
|
135
src/views.ts
135
src/views.ts
@ -1,5 +1,4 @@
|
||||
|
||||
import $ = require("jquery");
|
||||
//import CodeMirror = require("codemirror");
|
||||
import { SourceFile, WorkerError, Segment, FileData } from "./workertypes";
|
||||
import { Platform, EmuState, ProfilerOutput, lookupSymbol, BaseDebugPlatform } from "./baseplatform";
|
||||
@ -536,6 +535,7 @@ export class MemoryView implements ProjectView {
|
||||
maindiv : HTMLElement;
|
||||
static IGNORE_SYMS = {s__INITIALIZER:true, /* s__GSINIT:true, */ _color_prom:true};
|
||||
recreateOnResize = true;
|
||||
totalRows = 0x1400;
|
||||
|
||||
createDiv(parent : HTMLElement) {
|
||||
var div = document.createElement('div');
|
||||
@ -550,7 +550,7 @@ export class MemoryView implements ProjectView {
|
||||
w: $(workspace).width(),
|
||||
h: $(workspace).height(),
|
||||
itemHeight: getVisibleEditorLineHeight(),
|
||||
totalRows: 0x1400,
|
||||
totalRows: this.totalRows,
|
||||
generatorFn: (row : number) => {
|
||||
var s = this.getMemoryLineAt(row);
|
||||
var linediv = document.createElement("div");
|
||||
@ -695,6 +695,7 @@ export class MemoryView implements ProjectView {
|
||||
}
|
||||
|
||||
export class VRAMMemoryView extends MemoryView {
|
||||
totalRows = 0x800;
|
||||
readAddress(n : number) {
|
||||
return platform.readVRAMAddress(n);
|
||||
}
|
||||
@ -959,6 +960,15 @@ abstract class ProbeViewBase {
|
||||
return this.maindiv = div;
|
||||
}
|
||||
|
||||
addr2str(addr : number) : string {
|
||||
var _addr2sym = (platform.debugSymbols && platform.debugSymbols.addr2symbol) || {};
|
||||
var sym = _addr2sym[addr];
|
||||
if (typeof sym === 'string')
|
||||
return '$' + hex(addr) + ' (' + sym + ')';
|
||||
else
|
||||
return '$' + hex(addr);
|
||||
}
|
||||
|
||||
initCanvas() {
|
||||
}
|
||||
|
||||
@ -982,6 +992,7 @@ abstract class ProbeViewBase {
|
||||
setVisible(showing : boolean) : void {
|
||||
if (showing) {
|
||||
this.probe = platform.startProbing();
|
||||
this.tick();
|
||||
} else {
|
||||
platform.stopProbing();
|
||||
this.probe = null;
|
||||
@ -989,14 +1000,6 @@ abstract class ProbeViewBase {
|
||||
}
|
||||
|
||||
clear() {
|
||||
var ctx = this.ctx;
|
||||
//ctx.globalCompositeOperation = 'source-over';
|
||||
//ctx.globalAlpha = 1.0;
|
||||
//ctx.fillStyle = '#000000';
|
||||
//ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
ctx.globalAlpha = 1.0;
|
||||
ctx.globalCompositeOperation = 'lighter';
|
||||
}
|
||||
|
||||
redraw( eventfn:(op,addr,col,row) => void ) {
|
||||
@ -1020,23 +1023,8 @@ abstract class ProbeViewBase {
|
||||
}
|
||||
|
||||
tick() {
|
||||
var ctx = this.ctx;
|
||||
this.clear();
|
||||
this.redraw(this.drawEvent.bind(this));
|
||||
if (this.probe && !this.probe.singleFrame) this.probe.reset();
|
||||
}
|
||||
|
||||
setContextForOp(op) {
|
||||
var ctx = this.ctx;
|
||||
switch (op) {
|
||||
//case ProbeFlags.EXECUTE: ctx.fillStyle = "green"; break;
|
||||
//case ProbeFlags.MEM_READ: ctx.fillStyle = "#7f7f7f"; break;
|
||||
case ProbeFlags.MEM_WRITE: ctx.fillStyle = "red"; break;
|
||||
case ProbeFlags.IO_READ: ctx.fillStyle = "green"; break;
|
||||
case ProbeFlags.IO_WRITE: ctx.fillStyle = "magenta"; break;
|
||||
case ProbeFlags.INTERRUPT: ctx.fillStyle = "yellow"; break;
|
||||
default: ctx.fillStyle = "blue"; break;
|
||||
}
|
||||
}
|
||||
|
||||
abstract drawEvent(op, addr, col, row);
|
||||
@ -1067,13 +1055,13 @@ abstract class ProbeBitmapViewBase extends ProbeViewBase {
|
||||
y = y|0;
|
||||
var s = "";
|
||||
this.redraw( (op,addr,col,row) => {
|
||||
if (col == x && row == y) {
|
||||
if (y == row && x == col) {
|
||||
s += "\n" + this.opToString(op, addr);
|
||||
}
|
||||
} );
|
||||
return '(' + x + ',' + y + ')' + s;
|
||||
}
|
||||
opToString(op:number, addr:number) {
|
||||
return 'X: ' + x + ' Y: ' + y + ' ' + s;
|
||||
}
|
||||
opToString(op:number, addr?:number) {
|
||||
var s = "";
|
||||
switch (op) {
|
||||
case ProbeFlags.EXECUTE: s = "Exec"; break;
|
||||
@ -1086,7 +1074,7 @@ abstract class ProbeBitmapViewBase extends ProbeViewBase {
|
||||
case ProbeFlags.INTERRUPT: s = "Interrupt"; break;
|
||||
default: s = ""; break;
|
||||
}
|
||||
return s + " $" + hex(addr);
|
||||
return typeof addr == 'number' ? s + " " + this.addr2str(addr) : s;
|
||||
}
|
||||
|
||||
refresh() {
|
||||
@ -1107,9 +1095,9 @@ abstract class ProbeBitmapViewBase extends ProbeViewBase {
|
||||
case ProbeFlags.MEM_WRITE: return 0x010180;
|
||||
case ProbeFlags.IO_READ: return 0x018080;
|
||||
case ProbeFlags.IO_WRITE: return 0xc00180;
|
||||
case ProbeFlags.VRAM_READ: return 0x018080;
|
||||
case ProbeFlags.VRAM_WRITE: return 0xc00180;
|
||||
case ProbeFlags.INTERRUPT: return 0xc0c001;
|
||||
case ProbeFlags.VRAM_READ: return 0x808001;
|
||||
case ProbeFlags.VRAM_WRITE: return 0x4080c0;
|
||||
case ProbeFlags.INTERRUPT: return 0xcfcfcf;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@ -1141,9 +1129,22 @@ export class AddressHeatMapView extends ProbeBitmapViewBase implements ProjectVi
|
||||
}
|
||||
|
||||
getTooltipText(x:number, y:number) : string {
|
||||
var addr = (x & 0xff) + (y << 8);
|
||||
return '$'+hex(addr);
|
||||
}
|
||||
var a = (x & 0xff) + (y << 8);
|
||||
var s = this.addr2str(a);
|
||||
var pc = -1;
|
||||
var already = {};
|
||||
this.redraw( (op,addr,col,row) => {
|
||||
if (op == ProbeFlags.EXECUTE) {
|
||||
pc = addr;
|
||||
}
|
||||
var key = op|pc;
|
||||
if (addr == a && !already[key]) {
|
||||
s += "\nPC " + this.addr2str(pc) + " " + this.opToString(op);
|
||||
already[key] = 1;
|
||||
}
|
||||
} );
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1175,68 +1176,6 @@ export class RasterPCHeatMapView extends ProbeBitmapViewBase implements ProjectV
|
||||
|
||||
}
|
||||
|
||||
export class EventProbeView extends ProbeViewBase implements ProjectView {
|
||||
symcache : Map<number,symbol> = new Map();
|
||||
xmax : number = 1;
|
||||
ymax : number = 1;
|
||||
lastsym : string;
|
||||
xx : number;
|
||||
yy : number;
|
||||
|
||||
createDiv(parent : HTMLElement) {
|
||||
return this.createCanvas( parent, $(parent).width(), $(parent).height() );
|
||||
}
|
||||
|
||||
drawEvent(op, addr, col, row) {
|
||||
var ctx = this.ctx;
|
||||
this.xmax = Math.max(this.xmax, col);
|
||||
this.ymax = Math.max(this.ymax, row);
|
||||
var xscale = this.canvas.width / this.xmax; // TODO: pixels
|
||||
var yscale = (this.canvas.height - 12) / this.ymax; // TODO: lines
|
||||
var x = col * xscale;
|
||||
var y = row * yscale;
|
||||
x = this.xx;
|
||||
y = this.yy = Math.max(this.yy, y);
|
||||
var sym = this.getSymbol(addr);
|
||||
if (!sym && op == ProbeFlags.IO_WRITE) sym = hex(addr,4);
|
||||
//TODO if (!sym && op == ProbeFlags.IO_READ) sym = hex(addr,4);
|
||||
if (sym && sym != this.lastsym) {
|
||||
this.setContextForOp(op);
|
||||
ctx.textAlign = 'left'; //ctx.textAlign = (x < this.canvas.width/2) ? 'left' : 'right';
|
||||
ctx.textBaseline = 'top'; //ctx.textBaseline = (y < this.canvas.height/2) ? 'top' : 'bottom';
|
||||
var mt = ctx.measureText(sym);
|
||||
if (x + mt.width > this.canvas.width) {
|
||||
x = 0;
|
||||
y += 12;
|
||||
}
|
||||
ctx.fillText(sym, x, y);
|
||||
this.xx = x + mt.width + 10;
|
||||
this.yy = y;
|
||||
this.lastsym = sym;
|
||||
}
|
||||
}
|
||||
|
||||
getSymbol(addr:number) : string {
|
||||
var sym = this.symcache[addr];
|
||||
if (!sym) {
|
||||
sym = lookupSymbol(platform, addr, false);
|
||||
this.symcache[addr] = sym;
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
tick() {
|
||||
this.xx = this.yy = 0;
|
||||
this.lastsym = '';
|
||||
super.tick();
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.tick();
|
||||
this.symcache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
export class AssetEditorView implements ProjectView, pixed.EditorContext {
|
||||
|
@ -974,6 +974,7 @@ function linkLD65(step:BuildStep) {
|
||||
}
|
||||
// build segment map
|
||||
var seg_re = /^__(\w+)_SIZE__$/;
|
||||
// TODO: move to Platform class
|
||||
var segments = [];
|
||||
segments.push({name:'CPU Stack',start:0x100,size:0x100,type:'ram'});
|
||||
segments.push({name:'CPU Vectors',start:0xfffa,size:0x6,type:'rom'});
|
||||
|
Loading…
Reference in New Issue
Block a user