mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-18 00:30:43 +00:00
working on call graph view
This commit is contained in:
parent
6731231b23
commit
d73e9963ce
@ -113,68 +113,6 @@ export function xorshift32(x : number) : number {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HOOKS
|
|
||||||
|
|
||||||
export interface Hook<T> {
|
|
||||||
//target : T;
|
|
||||||
unhook();
|
|
||||||
}
|
|
||||||
|
|
||||||
export class BusHook implements Hook<Bus> {
|
|
||||||
//target : Bus;
|
|
||||||
constructor(bus : Bus, profiler : ProbeBus) {
|
|
||||||
//this.target = bus;
|
|
||||||
var oldread = bus.read.bind(bus);
|
|
||||||
var oldwrite = bus.write.bind(bus);
|
|
||||||
bus.read = (a:number):number => {
|
|
||||||
var val = oldread(a);
|
|
||||||
profiler.logRead(a,val);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
bus.write = (a:number,v:number) => {
|
|
||||||
profiler.logWrite(a,v);
|
|
||||||
oldwrite(a,v);
|
|
||||||
}
|
|
||||||
this.unhook = () => {
|
|
||||||
bus.read = oldread;
|
|
||||||
bus.write = oldwrite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unhook : () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CPUClockHook implements Hook<CPU&ClockBased> {
|
|
||||||
//target : CPU&ClockBased;
|
|
||||||
constructor(cpu : CPU&ClockBased, profiler : ProbeCPU) {
|
|
||||||
//this.target = cpu;
|
|
||||||
var oldclock = cpu.advanceClock.bind(cpu);
|
|
||||||
cpu.advanceClock = () => {
|
|
||||||
profiler.logExecute(cpu.getPC());
|
|
||||||
return oldclock();
|
|
||||||
}
|
|
||||||
this.unhook = () => {
|
|
||||||
cpu.advanceClock = oldclock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unhook : () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CPUInsnHook implements Hook<CPU&InstructionBased> {
|
|
||||||
//target : CPU&InstructionBased;
|
|
||||||
constructor(cpu : CPU&InstructionBased, profiler : ProbeCPU) {
|
|
||||||
//this.target = cpu;
|
|
||||||
var oldinsn = cpu.advanceInsn.bind(cpu);
|
|
||||||
cpu.advanceInsn = () => {
|
|
||||||
profiler.logExecute(cpu.getPC());
|
|
||||||
return oldinsn();
|
|
||||||
}
|
|
||||||
this.unhook = () => {
|
|
||||||
cpu.advanceInsn = oldinsn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unhook : () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// PROFILER
|
/// PROFILER
|
||||||
|
|
||||||
export interface ProbeTime {
|
export interface ProbeTime {
|
||||||
@ -184,7 +122,7 @@ export interface ProbeTime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ProbeCPU {
|
export interface ProbeCPU {
|
||||||
logExecute(address:number);
|
logExecute(address:number, SP:number);
|
||||||
logInterrupt(type:number);
|
logInterrupt(type:number);
|
||||||
logIllegal(address:number);
|
logIllegal(address:number);
|
||||||
}
|
}
|
||||||
@ -288,7 +226,7 @@ export abstract class BasicHeadlessMachine implements HasCPU, Bus, AcceptsROM, P
|
|||||||
advanceCPU() {
|
advanceCPU() {
|
||||||
var c = this.cpu as any;
|
var c = this.cpu as any;
|
||||||
var n = 1;
|
var n = 1;
|
||||||
if (this.cpu.isStable()) { this.probe.logExecute(this.cpu.getPC()); }
|
if (this.cpu.isStable()) { this.probe.logExecute(this.cpu.getPC(), this.cpu.getSP()); }
|
||||||
if (c.advanceClock) { c.advanceClock(); }
|
if (c.advanceClock) { c.advanceClock(); }
|
||||||
else if (c.advanceInsn) { n = c.advanceInsn(1); }
|
else if (c.advanceInsn) { n = c.advanceInsn(1); }
|
||||||
this.probe.logClocks(n);
|
this.probe.logClocks(n);
|
||||||
|
@ -138,7 +138,7 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable {
|
|||||||
// insert debug hook
|
// insert debug hook
|
||||||
this.nes.cpu._emulate = this.nes.cpu.emulate;
|
this.nes.cpu._emulate = this.nes.cpu.emulate;
|
||||||
this.nes.cpu.emulate = () => {
|
this.nes.cpu.emulate = () => {
|
||||||
this.probe.logExecute(this.nes.cpu.REG_PC-1);
|
this.probe.logExecute(this.nes.cpu.REG_PC-1, this.nes.cpu.REG_SP);
|
||||||
var cycles = this.nes.cpu._emulate();
|
var cycles = this.nes.cpu._emulate();
|
||||||
this.evalDebugCondition();
|
this.evalDebugCondition();
|
||||||
this.probe.logClocks(cycles);
|
this.probe.logClocks(cycles);
|
||||||
|
@ -130,6 +130,8 @@ export enum ProbeFlags {
|
|||||||
VRAM_WRITE = 0x07000000,
|
VRAM_WRITE = 0x07000000,
|
||||||
INTERRUPT = 0x08000000,
|
INTERRUPT = 0x08000000,
|
||||||
ILLEGAL = 0x09000000,
|
ILLEGAL = 0x09000000,
|
||||||
|
SP_PUSH = 0x0a000000,
|
||||||
|
SP_POP = 0x0b000000,
|
||||||
SCANLINE = 0x7e000000,
|
SCANLINE = 0x7e000000,
|
||||||
FRAME = 0x7f000000,
|
FRAME = 0x7f000000,
|
||||||
}
|
}
|
||||||
@ -145,6 +147,7 @@ export class ProbeRecorder implements ProbeAll {
|
|||||||
idx = 0;
|
idx = 0;
|
||||||
fclk = 0;
|
fclk = 0;
|
||||||
sl = 0;
|
sl = 0;
|
||||||
|
cur_sp = -1;
|
||||||
m : Probeable;
|
m : Probeable;
|
||||||
singleFrame : boolean = true;
|
singleFrame : boolean = true;
|
||||||
|
|
||||||
@ -161,7 +164,7 @@ export class ProbeRecorder implements ProbeAll {
|
|||||||
this.idx = 0;
|
this.idx = 0;
|
||||||
}
|
}
|
||||||
log(a:number) {
|
log(a:number) {
|
||||||
// TODO: coalesce READ and EXECUTE
|
// TODO: coalesce READ and EXECUTE and PUSH/POP
|
||||||
if (this.idx >= this.buf.length) return;
|
if (this.idx >= this.buf.length) return;
|
||||||
this.buf[this.idx++] = a;
|
this.buf[this.idx++] = a;
|
||||||
}
|
}
|
||||||
@ -198,7 +201,16 @@ export class ProbeRecorder implements ProbeAll {
|
|||||||
this.sl = 0;
|
this.sl = 0;
|
||||||
if (this.singleFrame) this.reset();
|
if (this.singleFrame) this.reset();
|
||||||
}
|
}
|
||||||
logExecute(address:number) {
|
logExecute(address:number, SP:number) {
|
||||||
|
if (this.cur_sp !== SP) {
|
||||||
|
if (SP < this.cur_sp) {
|
||||||
|
this.log(ProbeFlags.SP_PUSH | (this.cur_sp - SP));
|
||||||
|
}
|
||||||
|
if (SP > this.cur_sp) {
|
||||||
|
this.log(ProbeFlags.SP_POP | (SP - this.cur_sp));
|
||||||
|
}
|
||||||
|
this.cur_sp = SP;
|
||||||
|
}
|
||||||
this.log(address | ProbeFlags.EXECUTE);
|
this.log(address | ProbeFlags.EXECUTE);
|
||||||
}
|
}
|
||||||
logInterrupt(type:number) {
|
logInterrupt(type:number) {
|
||||||
|
@ -276,6 +276,9 @@ function refreshWindowList() {
|
|||||||
addWindowItem("#crtheatmap", "CRT Probe", () => {
|
addWindowItem("#crtheatmap", "CRT Probe", () => {
|
||||||
return new Views.RasterPCHeatMapView();
|
return new Views.RasterPCHeatMapView();
|
||||||
});
|
});
|
||||||
|
addWindowItem("#spheatmap", "Stack Probe", () => {
|
||||||
|
return new Views.RasterStackMapView();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
addWindowItem('#asseteditor', 'Asset Editor', () => {
|
addWindowItem('#asseteditor', 'Asset Editor', () => {
|
||||||
return new Views.AssetEditorView();
|
return new Views.AssetEditorView();
|
||||||
|
37
src/views.ts
37
src/views.ts
@ -1055,7 +1055,6 @@ export class RasterHeatMapView extends ProbeBitmapViewBase implements ProjectVie
|
|||||||
data = data | rgb | 0xff000000;
|
data = data | rgb | 0xff000000;
|
||||||
this.datau32[iofs] = data;
|
this.datau32[iofs] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1069,7 +1068,43 @@ export class RasterPCHeatMapView extends ProbeBitmapViewBase implements ProjectV
|
|||||||
data = data | rgb | 0xff000000;
|
data = data | rgb | 0xff000000;
|
||||||
this.datau32[iofs] = data;
|
this.datau32[iofs] = data;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RasterStackMapView extends ProbeBitmapViewBase implements ProjectView {
|
||||||
|
pcstack = [];
|
||||||
|
pushed = false;
|
||||||
|
color = 0;
|
||||||
|
root = {};
|
||||||
|
|
||||||
|
drawEvent(op, addr, col, row) {
|
||||||
|
var iofs = col + row * this.canvas.width;
|
||||||
|
if (op == ProbeFlags.SP_PUSH) {
|
||||||
|
this.pcstack.push({});
|
||||||
|
this.pushed = true;
|
||||||
|
} else if (op == ProbeFlags.SP_POP) {
|
||||||
|
var entry = this.pcstack.pop();
|
||||||
|
if (entry && entry.addr !== undefined) {
|
||||||
|
var node = this.root;
|
||||||
|
for (var e of this.pcstack) {
|
||||||
|
if (node[e.addr]) {
|
||||||
|
node = node[e.addr];
|
||||||
|
} else {
|
||||||
|
node = node[e.addr] = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if (this.pcstack.length == 1) console.log(this.root);
|
||||||
|
this.pushed = false;
|
||||||
|
} else if (op == ProbeFlags.EXECUTE) {
|
||||||
|
if (this.pushed) {
|
||||||
|
this.pcstack.pop();
|
||||||
|
this.pcstack.push({addr:addr, scol:col, srow:row});
|
||||||
|
this.pushed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var data = 0xff224488 << this.pcstack.length;
|
||||||
|
this.datau32[iofs] = data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
Loading…
x
Reference in New Issue
Block a user