From 236c4bd0dd1176f13c872fb4fe55216920a5da29 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Tue, 27 Aug 2019 13:26:25 -0400 Subject: [PATCH] 7800: TIA/RIOT wastes a cycle; fixed NES probe; messed with views --- css/ui.css | 2 +- src/machine/atari7800.ts | 43 ++++++++++++++--------------- src/platform/nes.ts | 9 ++++--- src/views.ts | 58 ++++++++++++++++++++++++++++++---------- 4 files changed, 72 insertions(+), 40 deletions(-) diff --git a/css/ui.css b/css/ui.css index 8fcf8a31..dab533f4 100644 --- a/css/ui.css +++ b/css/ui.css @@ -51,7 +51,7 @@ .tooltiptrack { background-color: #666; color: #fff; - text-align: center; + text-align: left; border: 2px solid #999; border-radius: 8px; padding: 5px; diff --git a/src/machine/atari7800.ts b/src/machine/atari7800.ts index 31c68919..5e2c8e2f 100644 --- a/src/machine/atari7800.ts +++ b/src/machine/atari7800.ts @@ -1,6 +1,6 @@ import { MOS6502, MOS6502State } from "../cpu/MOS6502"; -import { BasicMachine, Bus, ProbeAll } from "../devices"; +import { BasicMachine, RasterFrameBased, Bus, ProbeAll } from "../devices"; import { KeyFlags, newAddressDecoder, padBytes, Keys, makeKeycodeMap, newKeyboardHandler, EmuHalt, dumpRAM } from "../emu"; import { TssChannelAdapter, MasterAudio, POKEYDeviceChannel } from "../audio"; import { hex, rgb2bgr } from "../util"; @@ -201,7 +201,6 @@ class MARIA { let dlofs = this.dlstart & 0xff; do { // read DL entry - //profiler && profiler.logRead(dlhi + ((dlofs+0) & 0x1ff)); let b0 = bus.read(dlhi + ((dlofs+0) & 0x1ff)); let b1 = bus.read(dlhi + ((dlofs+1) & 0x1ff)); if (b1 == 0) break; // end of DL @@ -293,7 +292,7 @@ class MARIA { // Atari 7800 -export class Atari7800 extends BasicMachine { +export class Atari7800 extends BasicMachine implements RasterFrameBased { cpuFrequency = 1789772; canvasWidth = 320; @@ -312,6 +311,7 @@ export class Atari7800 extends BasicMachine { audioadapter; lastFrameCycles = 0; + xtracyc = 0; read : (a:number) => number; write : (a:number, v:number) => void; @@ -322,26 +322,26 @@ export class Atari7800 extends BasicMachine { super(); this.cpu = new MOS6502(); this.read = newAddressDecoder([ - [0x0008, 0x000d, 0x0f, (a) => { return this.readInput(a); }], - [0x0000, 0x001f, 0x1f, (a) => { return this.tia.read(a); }], - [0x0020, 0x003f, 0x1f, (a) => { return this.maria.read(a); /*this.profiler && this.profiler.logRead(a+0x20);*/ }], + [0x0008, 0x000d, 0x0f, (a) => { this.xtracyc++; return this.readInput(a); }], + [0x0000, 0x001f, 0x1f, (a) => { this.xtracyc++; return this.tia.read(a); }], + [0x0020, 0x003f, 0x1f, (a) => { return this.maria.read(a); }], [0x0040, 0x00ff, 0xff, (a) => { return this.ram[a + 0x800]; }], [0x0100, 0x013f, 0xff, (a) => { return this.read(a); }], // shadow [0x0140, 0x01ff, 0x1ff, (a) => { return this.ram[a + 0x800]; }], - [0x0280, 0x02ff, 0x3, (a) => { return this.inputs[a]; }], + [0x0280, 0x02ff, 0x3, (a) => { this.xtracyc++; return this.inputs[a]; }], [0x1800, 0x27ff, 0xffff, (a) => { return this.ram[a - 0x1800]; }], [0x2800, 0x3fff, 0x7ff, (a) => { return this.read(a | 0x2000); }], // shadow [0x4000, 0xffff, 0xffff, (a) => { return this.rom ? this.rom[a - 0x4000] : 0; }], [0x0000, 0xffff, 0xffff, (a) => { return 0; }], // TODO ]); this.write = newAddressDecoder([ - [0x0015, 0x001A, 0x1f, (a,v) => { this.pokey1.setTIARegister(a, v); }], - [0x0000, 0x001f, 0x1f, (a,v) => { this.tia.write(a,v); /*this.profiler && this.profiler.logWrite(a);*/ }], - [0x0020, 0x003f, 0x1f, (a,v) => { this.maria.write(a,v); /*this.profiler && this.profiler.logWrite(a+0x20);*/ }], + [0x0015, 0x001A, 0x1f, (a,v) => { this.xtracyc++; this.pokey1.setTIARegister(a, v); }], + [0x0000, 0x001f, 0x1f, (a,v) => { this.xtracyc++; this.tia.write(a,v); }], + [0x0020, 0x003f, 0x1f, (a,v) => { this.maria.write(a,v); }], [0x0040, 0x00ff, 0xff, (a,v) => { this.ram[a + 0x800] = v; }], [0x0100, 0x013f, 0xff, (a,v) => { this.write(a,v); }], // shadow [0x0140, 0x01ff, 0x1ff, (a,v) => { this.ram[a + 0x800] = v; }], - [0x0280, 0x02ff, 0x3, (a,v) => { this.regs6532[a] = v; /*TODO*/ }], + [0x0280, 0x02ff, 0x3, (a,v) => { this.xtracyc++; this.regs6532[a] = v; /*TODO*/ }], [0x1800, 0x27ff, 0xffff, (a,v) => { this.ram[a - 0x1800] = v; }], [0x2800, 0x3fff, 0x7ff, (a,v) => { this.write(a | 0x2000, v); }], // shadow [0xbfff, 0xbfff, 0xffff, (a,v) => { }], // TODO: bank switching? @@ -357,7 +357,6 @@ export class Atari7800 extends BasicMachine { readConst(a) { return this.read(a); } //TODO? readInput(a:number) : number { - //this.profiler && this.profiler.logRead(a+0x20); switch (a) { case 0xc: return ~this.inputs[0x8] & 0x80; //INPT4 case 0xd: return ~this.inputs[0x9] & 0x80; //INPT5 @@ -365,8 +364,15 @@ export class Atari7800 extends BasicMachine { } } - //TODO this.bios = new Uint8Array(0x1000); - // TODO: TIA access wastes a cycle + advanceCPU() : number { + var clk = super.advanceCPU(); + if (this.xtracyc) { + clk += this.xtracyc; + this.probe.logClocks(this.xtracyc); + this.xtracyc = 0; + } + return clk; + } advanceFrame(maxClocks, trap) : number { var idata = this.pixels; @@ -446,11 +452,7 @@ export class Atari7800 extends BasicMachine { if (data.length == 0xc080) data = data.slice(0x80); // strip header this.rom = padBytes(data, this.defaultROMSize, true); } -/* - loadBIOS(data) { - this.bios = padBytes(data, 0x1000); - } -*/ + reset() { super.reset(); this.tia.reset(); @@ -458,10 +460,9 @@ export class Atari7800 extends BasicMachine { this.inputs.fill(0x0); this.inputs[SWCHA] = 0xff; this.inputs[SWCHB] = 1+2+8; - //this.cpu.advanceClock(); // TODO: needed for test to pass? + //this.cpu.advanceClock(); // needed for test to pass? } - // TODO: don't log if profiler active readAddress(addr : number) { return this.read(addr) | 0; } diff --git a/src/platform/nes.ts b/src/platform/nes.ts index cbabace3..59c6ccbc 100644 --- a/src/platform/nes.ts +++ b/src/platform/nes.ts @@ -222,7 +222,7 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable { this.nes.loadROM(romstr); this.frameindex = 0; // intercept bus calls, unless we did it already - if (!this.nes.mmap.load) { + 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); @@ -247,6 +247,7 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable { oldregWrite(addr, val); } */ + this.nes.mmap.haveProxied = true; } } newCodeAnalyzer() { @@ -281,9 +282,6 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable { getRasterScanline() : number { return this.nes.ppu.scanline; } - readVRAMAddress(addr : number) : number { - return this.nes.ppu.vramMem[addr & 0x7fff]; - } getCPUState() { var c = this.nes.cpu.toJSON(); @@ -328,6 +326,9 @@ class JSNESPlatform extends Base6502Platform implements Platform, Probeable { readAddress(addr) { return this.nes.cpu.mem[addr] & 0xff; } + readVRAMAddress(addr : number) : number { + return this.nes.ppu.vramMem[addr & 0x7fff] & 0xff; + } copy6502REGvars(c) { c.T = 0; c.PC = c.REG_PC; diff --git a/src/views.ts b/src/views.ts index 6ab67aed..f22320a7 100644 --- a/src/views.ts +++ b/src/views.ts @@ -940,7 +940,7 @@ abstract class ProbeViewBase { canvas.height = height; canvas.classList.add('pixelated'); canvas.style.width = '100%'; - canvas.style.height = '100vh'; // i hate css + canvas.style.height = '90vh'; // i hate css canvas.style.backgroundColor = 'black'; canvas.style.cursor = 'crosshair'; canvas.onmousemove = (e) => { @@ -998,14 +998,12 @@ abstract class ProbeViewBase { ctx.globalAlpha = 1.0; ctx.globalCompositeOperation = 'lighter'; } - - tick() { + + redraw( eventfn:(op,addr,col,row) => void ) { var p = this.probe; if (!p || !p.idx) return; // if no probe, or if empty var row=0; var col=0; - var ctx = this.ctx; - this.clear(); for (var i=0; i { + if (col == x && row == y) { + s += "\n" + this.opToString(op, addr); + } + } ); + return '(' + x + ',' + y + ')' + s; + } + opToString(op:number, addr:number) { + var s = ""; + switch (op) { + case ProbeFlags.EXECUTE: s = "Exec"; break; + case ProbeFlags.MEM_READ: s = "Read"; break; + case ProbeFlags.MEM_WRITE: s = "Write"; break; + case ProbeFlags.IO_READ: s = "IO Read"; break; + case ProbeFlags.IO_WRITE: s = "IO Write"; break; + case ProbeFlags.VRAM_READ: s = "VRAM Read"; break; + case ProbeFlags.VRAM_WRITE: s = "VRAM Write"; break; + case ProbeFlags.INTERRUPT: s = "Interrupt"; break; + default: s = ""; break; + } + return s + " $" + hex(addr); + } + refresh() { this.tick(); this.datau32.fill(0xff000000); @@ -1115,6 +1146,7 @@ export class AddressHeatMapView extends ProbeBitmapViewBase implements ProjectVi } } +/* export class RasterHeatMapView extends ProbeBitmapViewBase implements ProjectView { drawEvent(op, addr, col, row) { @@ -1123,22 +1155,20 @@ export class RasterHeatMapView extends ProbeBitmapViewBase implements ProjectVie if (!rgb) return; var iofs = col + row * this.canvas.width; var data = this.datau32[iofs]; - data = (data & 0x7f7f7f) << 1; data = data | rgb | 0xff000000; this.datau32[iofs] = data; } } +*/ export class RasterPCHeatMapView extends ProbeBitmapViewBase implements ProjectView { drawEvent(op, addr, col, row) { -// if (op != ProbeFlags.EXECUTE) return; var iofs = col + row * this.canvas.width; - //var rgb = addr << 8; - var rgb = this.getOpRGB(op) << 1; + var rgb = this.getOpRGB(op); + if (!rgb) return; var data = this.datau32[iofs]; - rgb |= addr & 0x3f3f; data = data | rgb | 0xff000000; this.datau32[iofs] = data; }