mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-23 18:29:02 +00:00
nes updates, runToFrameClock()
This commit is contained in:
parent
810d0af58b
commit
0a9fffee73
@ -116,6 +116,8 @@ TODO:
|
|||||||
- debug highlight doesn't go away when debugging -> running
|
- debug highlight doesn't go away when debugging -> running
|
||||||
- replay doesn't work for nes (force background tile redraw)
|
- replay doesn't work for nes (force background tile redraw)
|
||||||
- running profiler while replaying? grand unified replay?
|
- running profiler while replaying? grand unified replay?
|
||||||
|
- click on profiler to step to position
|
||||||
|
- breakpoints stop profiler from running
|
||||||
|
|
||||||
WEB WORKER FORMAT
|
WEB WORKER FORMAT
|
||||||
|
|
||||||
|
@ -9,9 +9,10 @@
|
|||||||
;;;;; OTHER VARIABLES
|
;;;;; OTHER VARIABLES
|
||||||
|
|
||||||
seg.u RAM
|
seg.u RAM
|
||||||
|
; page-align to prevent messing up the timing
|
||||||
org $300
|
org $300
|
||||||
|
|
||||||
LineXLo ds 224
|
LineXLo ds 224
|
||||||
|
align $100
|
||||||
LineXHi ds 224
|
LineXHi ds 224
|
||||||
|
|
||||||
;;;;; NES CARTRIDGE HEADER
|
;;;;; NES CARTRIDGE HEADER
|
||||||
@ -74,11 +75,11 @@ SetPalette: subroutine
|
|||||||
; set sprite 0
|
; set sprite 0
|
||||||
SetSprite0: subroutine
|
SetSprite0: subroutine
|
||||||
sta $200 ;y
|
sta $200 ;y
|
||||||
lda #1 ;code
|
lda #$01 ;code
|
||||||
sta $201
|
sta $201
|
||||||
lda #0 ;flags
|
lda #$20 ;flags
|
||||||
sta $202
|
sta $202
|
||||||
lda #8 ;xpos
|
lda #$fe ;xpos
|
||||||
sta $203
|
sta $203
|
||||||
rts
|
rts
|
||||||
|
|
||||||
@ -90,7 +91,10 @@ SetSprite0: subroutine
|
|||||||
|
|
||||||
NMIHandler: subroutine
|
NMIHandler: subroutine
|
||||||
SAVE_REGS
|
SAVE_REGS
|
||||||
lda #112
|
lda #0
|
||||||
|
sta PPU_SCROLL
|
||||||
|
sta PPU_SCROLL
|
||||||
|
lda #111
|
||||||
jsr SetSprite0
|
jsr SetSprite0
|
||||||
; load sprites
|
; load sprites
|
||||||
lda #$02
|
lda #$02
|
||||||
|
@ -106,12 +106,18 @@ abstract class CodeAnalyzer6502 implements CodeAnalyzer {
|
|||||||
constraints = null;
|
constraints = null;
|
||||||
// TODO: if jump to zero-page, maybe assume RTS?
|
// TODO: if jump to zero-page, maybe assume RTS?
|
||||||
switch (meta.opcode) {
|
switch (meta.opcode) {
|
||||||
/*
|
case 0x19: case 0x1d:
|
||||||
case 0xb9: // TODO: hack for zero page,y
|
case 0x39: case 0x3d:
|
||||||
if (addr < 0x100)
|
case 0x59: case 0x5d:
|
||||||
meta.maxCycles -= 1;
|
case 0x79: case 0x7d:
|
||||||
|
case 0x99: case 0x9d:
|
||||||
|
case 0xa9: case 0xad:
|
||||||
|
case 0xb9: case 0xbd: case 0xbc: case 0xbe:
|
||||||
|
case 0xd9: case 0xdd:
|
||||||
|
case 0xf9: case 0xfd:
|
||||||
|
if (lob == 0)
|
||||||
|
meta.maxCycles -= 1; // no page boundary crossed
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
// TODO: only VCS
|
// TODO: only VCS
|
||||||
case 0x85:
|
case 0x85:
|
||||||
if (lob == 0x2) { // STA WSYNC
|
if (lob == 0x2) { // STA WSYNC
|
||||||
|
@ -85,6 +85,7 @@ export interface Platform {
|
|||||||
runUntilReturn?() : void;
|
runUntilReturn?() : void;
|
||||||
stepBack?() : void;
|
stepBack?() : void;
|
||||||
runEval?(evalfunc : DebugEvalCondition) : void;
|
runEval?(evalfunc : DebugEvalCondition) : void;
|
||||||
|
runToFrameClock?(clock : number) : void;
|
||||||
|
|
||||||
getOpcodeMetadata?(opcode:number, offset:number) : OpcodeMetadata; //TODO
|
getOpcodeMetadata?(opcode:number, offset:number) : OpcodeMetadata; //TODO
|
||||||
getSP?() : number;
|
getSP?() : number;
|
||||||
@ -328,6 +329,16 @@ export abstract class Base6502Platform extends BaseDebugPlatform {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
runToFrameClock?(clock : number) : void {
|
||||||
|
this.restartDebugging();
|
||||||
|
this.debugTargetClock = clock;
|
||||||
|
this.setDebugCondition( () => {
|
||||||
|
if (this.debugClock++ > this.debugTargetClock) {
|
||||||
|
this.breakpointHit(this.debugClock-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
step() {
|
step() {
|
||||||
var previousPC = -1;
|
var previousPC = -1;
|
||||||
this.setDebugCondition( () => {
|
this.setDebugCondition( () => {
|
||||||
@ -678,12 +689,12 @@ export abstract class Base6809Platform extends BaseZ80Platform {
|
|||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
runUntilReturn() {
|
runUntilReturn() {
|
||||||
var depth = 1;
|
var depth = 1;
|
||||||
this.runEval((c:CpuState) => {
|
this.runEval((c:CpuState) => {
|
||||||
if (depth <= 0)
|
if (depth <= 0)
|
||||||
return true;
|
return true;
|
||||||
var op = this.readAddress(c.PC);
|
var op = this.readAddress(c.PC);
|
||||||
// TODO: 6809 opcodes
|
// TODO: 6809 opcodes
|
||||||
if (op == 0x9d || op == 0xad || op == 0xbd) // CALL
|
if (op == 0x9d || op == 0xad || op == 0xbd) // CALL
|
||||||
depth++;
|
depth++;
|
||||||
@ -693,7 +704,7 @@ export abstract class Base6809Platform extends BaseZ80Platform {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuStateToLongString(c:CpuState) {
|
cpuStateToLongString(c:CpuState) {
|
||||||
return cpuStateToLongString_6809(c);
|
return cpuStateToLongString_6809(c);
|
||||||
}
|
}
|
||||||
disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {
|
disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {
|
||||||
|
@ -535,7 +535,7 @@ export class Toolbar {
|
|||||||
icon = '<span class="glyphicon ' + icon + '" aria-hidden="true"></span>';
|
icon = '<span class="glyphicon ' + icon + '" aria-hidden="true"></span>';
|
||||||
}
|
}
|
||||||
btn.html(icon);
|
btn.html(icon);
|
||||||
btn.prop("title", alttext + " (" + key + ")");
|
btn.prop("title", key ? (alttext+" ("+key+")") : alttext);
|
||||||
btn.click(fn);
|
btn.click(fn);
|
||||||
this.grp.append(btn);
|
this.grp.append(btn);
|
||||||
}
|
}
|
||||||
|
@ -60,103 +60,108 @@ const JSNES_KEYCODE_MAP = makeKeycodeMap([
|
|||||||
[Keys.VK_D, 1, 7],
|
[Keys.VK_D, 1, 7],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const _JSNESPlatform = function(mainElement) {
|
class JSNESPlatform extends Base6502Platform implements Platform {
|
||||||
|
|
||||||
var nes;
|
mainElement;
|
||||||
var rom;
|
nes;
|
||||||
var video, audio, timer;
|
video;
|
||||||
const audioFrequency = 44030; //44100
|
audio;
|
||||||
var frameindex = 0;
|
timer;
|
||||||
var ntvideo;
|
audioFrequency = 44030; //44100
|
||||||
var ntlastbuf;
|
frameindex = 0;
|
||||||
|
ntvideo;
|
||||||
|
ntlastbuf;
|
||||||
|
|
||||||
class JSNESPlatform extends Base6502Platform implements Platform {
|
constructor(mainElement) {
|
||||||
|
super();
|
||||||
|
this.mainElement = mainElement;
|
||||||
|
}
|
||||||
|
|
||||||
getPresets() { return JSNES_PRESETS; }
|
getPresets() { return JSNES_PRESETS; }
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
this.debugPCDelta = 1;
|
this.debugPCDelta = 1;
|
||||||
var debugbar = $("<div>").appendTo(mainElement);
|
var debugbar = $("<div>").appendTo(this.mainElement);
|
||||||
audio = new SampleAudio(audioFrequency);
|
this.audio = new SampleAudio(this.audioFrequency);
|
||||||
video = new RasterVideo(mainElement,256,224,{overscan:true});
|
this.video = new RasterVideo(this.mainElement,256,224,{overscan:true});
|
||||||
video.create();
|
this.video.create();
|
||||||
// debugging view
|
// debugging view
|
||||||
ntvideo = new RasterVideo(mainElement,512,480,{overscan:false});
|
this.ntvideo = new RasterVideo(this.mainElement,512,480,{overscan:false});
|
||||||
ntvideo.create();
|
this.ntvideo.create();
|
||||||
$(ntvideo.canvas).hide();
|
$(this.ntvideo.canvas).hide();
|
||||||
ntlastbuf = new Uint32Array(0x1000);
|
this.ntlastbuf = new Uint32Array(0x1000);
|
||||||
// toggle buttons
|
// toggle buttons (TODO)
|
||||||
$('<button>').text("Video").appendTo(debugbar).click(() => { $(video.canvas).toggle() });
|
$('<button>').text("Video").appendTo(debugbar).click(() => { $(this.video.canvas).toggle() });
|
||||||
$('<button>').text("Nametable").appendTo(debugbar).click(() => { $(ntvideo.canvas).toggle() });
|
$('<button>').text("Nametable").appendTo(debugbar).click(() => { $(this.ntvideo.canvas).toggle() });
|
||||||
|
|
||||||
var idata = video.getFrameData();
|
var idata = this.video.getFrameData();
|
||||||
nes = new jsnes.NES({
|
this.nes = new jsnes.NES({
|
||||||
onFrame: (frameBuffer : number[]) => {
|
onFrame: (frameBuffer : number[]) => {
|
||||||
for (var i=0; i<frameBuffer.length; i++)
|
for (var i=0; i<frameBuffer.length; i++)
|
||||||
idata[i] = frameBuffer[i] | 0xff000000;
|
idata[i] = frameBuffer[i] | 0xff000000;
|
||||||
video.updateFrame();
|
this.video.updateFrame();
|
||||||
frameindex++;
|
this.frameindex++;
|
||||||
this.updateDebugViews();
|
this.updateDebugViews();
|
||||||
},
|
},
|
||||||
onAudioSample: (left:number, right:number) => {
|
onAudioSample: (left:number, right:number) => {
|
||||||
if (frameindex < 10)
|
if (this.frameindex < 10)
|
||||||
audio.feedSample(0, 1); // avoid popping at powerup
|
this.audio.feedSample(0, 1); // avoid popping at powerup
|
||||||
else
|
else
|
||||||
audio.feedSample(left+right, 1);
|
this.audio.feedSample(left+right, 1);
|
||||||
},
|
},
|
||||||
onStatusUpdate: function(s) {
|
onStatusUpdate: function(s) {
|
||||||
console.log(s);
|
console.log(s);
|
||||||
},
|
},
|
||||||
//TODO: onBatteryRamWrite
|
//TODO: onBatteryRamWrite
|
||||||
});
|
});
|
||||||
//nes.ppu.clipToTvSize = false;
|
//this.nes.ppu.clipToTvSize = false;
|
||||||
nes.stop = () => {
|
this.nes.stop = () => {
|
||||||
// TODO: trigger breakpoint
|
// TODO: trigger breakpoint
|
||||||
console.log(nes.cpu.toJSON());
|
console.log(this.nes.cpu.toJSON());
|
||||||
throw new EmuHalt("CPU STOPPED @ PC $" + hex(nes.cpu.REG_PC));
|
throw new EmuHalt("CPU STOPPED @ PC $" + hex(this.nes.cpu.REG_PC));
|
||||||
};
|
};
|
||||||
// insert debug hook
|
// insert debug hook
|
||||||
nes.cpu._emulate = nes.cpu.emulate;
|
this.nes.cpu._emulate = this.nes.cpu.emulate;
|
||||||
nes.cpu.emulate = () => {
|
this.nes.cpu.emulate = () => {
|
||||||
var cycles = nes.cpu._emulate();
|
var cycles = this.nes.cpu._emulate();
|
||||||
this.evalDebugCondition();
|
this.evalDebugCondition();
|
||||||
return cycles;
|
return cycles;
|
||||||
}
|
}
|
||||||
timer = new AnimationTimer(60, this.nextFrame.bind(this));
|
this.timer = new AnimationTimer(60, this.nextFrame.bind(this));
|
||||||
// set keyboard map
|
// set keyboard map
|
||||||
setKeyboardFromMap(video, [], JSNES_KEYCODE_MAP, (o,key,code,flags) => {
|
setKeyboardFromMap(this.video, [], JSNES_KEYCODE_MAP, (o,key,code,flags) => {
|
||||||
if (flags & KeyFlags.KeyDown)
|
if (flags & KeyFlags.KeyDown)
|
||||||
nes.buttonDown(o.index+1, o.mask); // controller, button
|
this.nes.buttonDown(o.index+1, o.mask); // controller, button
|
||||||
else if (flags & KeyFlags.KeyUp)
|
else if (flags & KeyFlags.KeyUp)
|
||||||
nes.buttonUp(o.index+1, o.mask); // controller, button
|
this.nes.buttonUp(o.index+1, o.mask); // controller, button
|
||||||
});
|
});
|
||||||
//var s = ''; nes.ppu.palTable.curTable.forEach((rgb) => { s += "0x"+hex(rgb,6)+", "; }); console.log(s);
|
//var s = ''; nes.ppu.palTable.curTable.forEach((rgb) => { s += "0x"+hex(rgb,6)+", "; }); console.log(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
advance(novideo : boolean) {
|
advance(novideo : boolean) {
|
||||||
nes.frame();
|
this.nes.frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDebugViews() {
|
updateDebugViews() {
|
||||||
// don't update if view is hidden
|
// don't update if view is hidden
|
||||||
if (! $(ntvideo.canvas).is(":visible"))
|
if (! $(this.ntvideo.canvas).is(":visible"))
|
||||||
return;
|
return;
|
||||||
var a = 0;
|
var a = 0;
|
||||||
var attraddr = 0;
|
var attraddr = 0;
|
||||||
var idata = ntvideo.getFrameData();
|
var idata = this.ntvideo.getFrameData();
|
||||||
var baseTile = nes.ppu.regS === 0 ? 0 : 256;
|
var baseTile = this.nes.ppu.regS === 0 ? 0 : 256;
|
||||||
for (var row=0; row<60; row++) {
|
for (var row=0; row<60; row++) {
|
||||||
for (var col=0; col<64; col++) {
|
for (var col=0; col<64; col++) {
|
||||||
a = 0x2000 + (col&31) + ((row%30)*32);
|
a = 0x2000 + (col&31) + ((row%30)*32);
|
||||||
if (col >= 32) a += 0x400;
|
if (col >= 32) a += 0x400;
|
||||||
if (row >= 30) a += 0x800;
|
if (row >= 30) a += 0x800;
|
||||||
var name = nes.ppu.mirroredLoad(a) + baseTile;
|
var name = this.nes.ppu.mirroredLoad(a) + baseTile;
|
||||||
var t = nes.ppu.ptTile[name];
|
var t = this.nes.ppu.ptTile[name];
|
||||||
attraddr = (a & 0x2c00) | 0x3c0 | (a & 0x0C00) | ((a >> 4) & 0x38) | ((a >> 2) & 0x07);
|
attraddr = (a & 0x2c00) | 0x3c0 | (a & 0x0C00) | ((a >> 4) & 0x38) | ((a >> 2) & 0x07);
|
||||||
var attr = nes.ppu.mirroredLoad(attraddr);
|
var attr = this.nes.ppu.mirroredLoad(attraddr);
|
||||||
var tag = name ^ (attr<<9) ^ 0x80000000;
|
var tag = name ^ (attr<<9) ^ 0x80000000;
|
||||||
if (tag != ntlastbuf[a & 0xfff]) {
|
if (tag != this.ntlastbuf[a & 0xfff]) {
|
||||||
ntlastbuf[a & 0xfff] = tag;
|
this.ntlastbuf[a & 0xfff] = tag;
|
||||||
var i = row*64*8*8 + col*8;
|
var i = row*64*8*8 + col*8;
|
||||||
var j = 0;
|
var j = 0;
|
||||||
var attrshift = (col&2) + ((a&0x40)>>4);
|
var attrshift = (col&2) + ((a&0x40)>>4);
|
||||||
@ -165,7 +170,7 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
for (var x=0; x<8; x++) {
|
for (var x=0; x<8; x++) {
|
||||||
var color = t.pix[j++];
|
var color = t.pix[j++];
|
||||||
if (color) color += coloradd;
|
if (color) color += coloradd;
|
||||||
var rgb = nes.ppu.imgPalette[color];
|
var rgb = this.nes.ppu.imgPalette[color];
|
||||||
idata[i++] = rgb | 0xff000000;
|
idata[i++] = rgb | 0xff000000;
|
||||||
}
|
}
|
||||||
i += 64*8-8;
|
i += 64*8-8;
|
||||||
@ -173,13 +178,13 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ntvideo.updateFrame();
|
this.ntvideo.updateFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadROM(title, data) {
|
loadROM(title, data) {
|
||||||
var romstr = byteArrayToString(data);
|
var romstr = byteArrayToString(data);
|
||||||
nes.loadROM(romstr);
|
this.nes.loadROM(romstr);
|
||||||
frameindex = 0;
|
this.frameindex = 0;
|
||||||
}
|
}
|
||||||
newCodeAnalyzer() {
|
newCodeAnalyzer() {
|
||||||
return new CodeAnalyzer_nes(this);
|
return new CodeAnalyzer_nes(this);
|
||||||
@ -190,42 +195,42 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
getDefaultExtension() { return ".c"; };
|
getDefaultExtension() { return ".c"; };
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
//nes.cpu.reset(); // doesn't work right, crashes
|
//this.nes.cpu.reset(); // doesn't work right, crashes
|
||||||
nes.cpu.requestIrq(nes.cpu.IRQ_RESET);
|
this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);
|
||||||
}
|
}
|
||||||
isRunning() {
|
isRunning() {
|
||||||
return timer.isRunning();
|
return this.timer.isRunning();
|
||||||
}
|
}
|
||||||
pause() {
|
pause() {
|
||||||
timer.stop();
|
this.timer.stop();
|
||||||
audio.stop();
|
this.audio.stop();
|
||||||
}
|
}
|
||||||
resume() {
|
resume() {
|
||||||
timer.start();
|
this.timer.start();
|
||||||
audio.start();
|
this.audio.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
runToVsync() {
|
runToVsync() {
|
||||||
var frame0 = frameindex;
|
var frame0 = this.frameindex;
|
||||||
this.runEval((c) => { return frameindex>frame0; });
|
this.runEval((c) => { return this.frameindex>frame0; });
|
||||||
}
|
}
|
||||||
|
|
||||||
getRasterScanline() : number {
|
getRasterScanline() : number {
|
||||||
return nes.ppu.scanline;
|
return this.nes.ppu.scanline;
|
||||||
}
|
}
|
||||||
readVRAMAddress(addr : number) : number {
|
readVRAMAddress(addr : number) : number {
|
||||||
return nes.ppu.vramMem[addr & 0x7fff];
|
return this.nes.ppu.vramMem[addr & 0x7fff];
|
||||||
}
|
}
|
||||||
|
|
||||||
getCPUState() {
|
getCPUState() {
|
||||||
var c = nes.cpu.toJSON();
|
var c = this.nes.cpu.toJSON();
|
||||||
this.copy6502REGvars(c);
|
this.copy6502REGvars(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
// TODO don't need to save ROM?
|
// TODO don't need to save ROM?
|
||||||
saveState() {
|
saveState() {
|
||||||
//var s = $.extend(true, {}, nes);
|
//var s = $.extend(true, {}, this.nes);
|
||||||
var s = nes.toJSON();
|
var s = this.nes.toJSON();
|
||||||
s.c = s.cpu;
|
s.c = s.cpu;
|
||||||
this.copy6502REGvars(s.c);
|
this.copy6502REGvars(s.c);
|
||||||
s.b = s.cpu.mem = s.cpu.mem.slice(0);
|
s.b = s.cpu.mem = s.cpu.mem.slice(0);
|
||||||
@ -235,28 +240,28 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
loadState(state) {
|
loadState(state) {
|
||||||
nes.fromJSON(state);
|
this.nes.fromJSON(state);
|
||||||
//nes.cpu.fromJSON(state.cpu);
|
//this.nes.cpu.fromJSON(state.cpu);
|
||||||
//nes.mmap.fromJSON(state.mmap);
|
//this.nes.mmap.fromJSON(state.mmap);
|
||||||
//nes.ppu.fromJSON(state.ppu);
|
//this.nes.ppu.fromJSON(state.ppu);
|
||||||
nes.cpu.mem = state.cpu.mem.slice(0);
|
this.nes.cpu.mem = state.cpu.mem.slice(0);
|
||||||
nes.ppu.vramMem = state.ppu.vramMem.slice(0);
|
this.nes.ppu.vramMem = state.ppu.vramMem.slice(0);
|
||||||
nes.ppu.spriteMem = state.ppu.spriteMem.slice(0);
|
this.nes.ppu.spriteMem = state.ppu.spriteMem.slice(0);
|
||||||
this.loadControlsState(state.ctrl);
|
this.loadControlsState(state.ctrl);
|
||||||
//$.extend(nes, state);
|
//$.extend(this.nes, state);
|
||||||
}
|
}
|
||||||
saveControlsState() {
|
saveControlsState() {
|
||||||
return {
|
return {
|
||||||
c1: nes.controllers[1].state.slice(0),
|
c1: this.nes.controllers[1].state.slice(0),
|
||||||
c2: nes.controllers[2].state.slice(0),
|
c2: this.nes.controllers[2].state.slice(0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
loadControlsState(state) {
|
loadControlsState(state) {
|
||||||
nes.controllers[1].state = state.c1;
|
this.nes.controllers[1].state = state.c1;
|
||||||
nes.controllers[2].state = state.c2;
|
this.nes.controllers[2].state = state.c2;
|
||||||
}
|
}
|
||||||
readAddress(addr) {
|
readAddress(addr) {
|
||||||
return nes.cpu.mem[addr] & 0xff;
|
return this.nes.cpu.mem[addr] & 0xff;
|
||||||
}
|
}
|
||||||
copy6502REGvars(c) {
|
copy6502REGvars(c) {
|
||||||
c.T = 0;
|
c.T = 0;
|
||||||
@ -277,7 +282,7 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDebugCategories() {
|
getDebugCategories() {
|
||||||
return super.getDebugCategories().concat(['PPU', 'Mapper']);
|
return super.getDebugCategories().concat(['PPU','Mapper']);
|
||||||
}
|
}
|
||||||
getDebugInfo(category, state) {
|
getDebugInfo(category, state) {
|
||||||
switch (category) {
|
switch (category) {
|
||||||
@ -347,6 +352,9 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
mapperStateToLongString(mmap, mem) {
|
mapperStateToLongString(mmap, mem) {
|
||||||
//console.log(mmap, mem);
|
//console.log(mmap, mem);
|
||||||
var s = "";
|
var s = "";
|
||||||
|
if (this.nes.rom) {
|
||||||
|
s += "Mapper " + this.nes.rom.mapperType + "\n";
|
||||||
|
}
|
||||||
if (mmap.irqCounter !== undefined) {
|
if (mmap.irqCounter !== undefined) {
|
||||||
s += "\nIRQ Counter: " + mmap.irqCounter;
|
s += "\nIRQ Counter: " + mmap.irqCounter;
|
||||||
s += "\n IRQ Latch: " + mmap.irqLatchValue;
|
s += "\n IRQ Latch: " + mmap.irqLatchValue;
|
||||||
@ -358,8 +366,6 @@ const _JSNESPlatform = function(mainElement) {
|
|||||||
s += "\n";
|
s += "\n";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return new JSNESPlatform();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MAME support
|
/// MAME support
|
||||||
@ -384,8 +390,8 @@ class NESMAMEPlatform extends BaseMAMEPlatform implements Platform {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// look at iNES header for PRG and CHR ROM lengths
|
// look at iNES header for PRG and CHR ROM lengths
|
||||||
var prgromlen = data[4] * 0x2000;
|
var prgromlen = data[4] * 0x4000;
|
||||||
var chrromlen = data[5] * 0x1000;
|
var chrromlen = data[5] * 0x2000;
|
||||||
this.loadROMFile(data);
|
this.loadROMFile(data);
|
||||||
this.loadRegion(":nes_slot:cart:prg_rom", data.slice(0x10, 0x10+prgromlen));
|
this.loadRegion(":nes_slot:cart:prg_rom", data.slice(0x10, 0x10+prgromlen));
|
||||||
this.loadRegion(":nes_slot:cart:chr_rom", data.slice(0x10+prgromlen, 0x10+prgromlen+chrromlen));
|
this.loadRegion(":nes_slot:cart:chr_rom", data.slice(0x10+prgromlen, 0x10+prgromlen+chrromlen));
|
||||||
@ -400,6 +406,6 @@ class NESMAMEPlatform extends BaseMAMEPlatform implements Platform {
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
PLATFORMS['nes'] = _JSNESPlatform;
|
PLATFORMS['nes'] = JSNESPlatform;
|
||||||
PLATFORMS['nes.mame'] = NESMAMEPlatform;
|
PLATFORMS['nes.mame'] = NESMAMEPlatform;
|
||||||
|
|
||||||
|
@ -742,6 +742,7 @@ function uiDebugCallback(state) {
|
|||||||
lastDebugState = state;
|
lastDebugState = state;
|
||||||
showDebugInfo(state);
|
showDebugInfo(state);
|
||||||
projectWindows.refresh(true);
|
projectWindows.refresh(true);
|
||||||
|
debugTickPaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupDebugCallback(btnid? : string) {
|
function setupDebugCallback(btnid? : string) {
|
||||||
|
15
src/views.ts
15
src/views.ts
@ -861,9 +861,10 @@ export class ProfileView implements ProjectView {
|
|||||||
var l = f.lines[row];
|
var l = f.lines[row];
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
var lastsym = '';
|
var lastsym = '';
|
||||||
for (var i=l.start; i<=l.end; i++) {
|
var canDebug = platform.runToFrameClock;
|
||||||
var pc = f.iptab[i];
|
for (let i=l.start; i<=l.end; i++) {
|
||||||
var sym = this.symcache[pc];
|
let pc = f.iptab[i];
|
||||||
|
let sym = this.symcache[pc];
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = lookupSymbol(platform, pc, false);
|
sym = lookupSymbol(platform, pc, false);
|
||||||
this.symcache[pc] = sym;
|
this.symcache[pc] = sym;
|
||||||
@ -873,7 +874,13 @@ export class ProfileView implements ProjectView {
|
|||||||
if (sym.startsWith('_')) cls = "profiler-cident";
|
if (sym.startsWith('_')) cls = "profiler-cident";
|
||||||
else if (sym.startsWith('@')) cls = "profiler-local";
|
else if (sym.startsWith('@')) cls = "profiler-local";
|
||||||
else if (/^\d*[.]/.exec(sym)) cls = "profiler-local";
|
else if (/^\d*[.]/.exec(sym)) cls = "profiler-local";
|
||||||
div.appendChild(createTextSpan(' '+sym, cls));
|
var span = createTextSpan(' '+sym, cls);
|
||||||
|
if (canDebug) {
|
||||||
|
$(span).click(() => {
|
||||||
|
platform.runToFrameClock(i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
div.appendChild(span);
|
||||||
lastsym = sym;
|
lastsym = sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user