From 768253751a2b60d82abc378007044a3929188919 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Sun, 25 Aug 2019 09:25:26 -0400 Subject: [PATCH] cleaned up atari7800 platform (still have to log DMA via bus) --- src/devices.ts | 17 +++-- src/machine/apple2.ts | 4 +- src/machine/atari7800.ts | 143 +++++++++++++++++---------------------- 3 files changed, 75 insertions(+), 89 deletions(-) diff --git a/src/devices.ts b/src/devices.ts index 78e717cc..3d03f203 100644 --- a/src/devices.ts +++ b/src/devices.ts @@ -248,8 +248,6 @@ export abstract class BasicMachine implements HasCPU, Bus, SampledAudioSource, A abstract read(a:number) : number; abstract write(a:number, v:number) : void; - abstract startScanline() : void; - abstract drawScanline() : void; getAudioParams() : SampledAudioParams { return {sampleRate:this.sampleRate, stereo:false}; @@ -293,12 +291,12 @@ export abstract class BasicMachine implements HasCPU, Bus, SampledAudioSource, A inputs:this.inputs.slice(0) }; } - advanceMultiple(cycles : number) : number { - for (var i=0; i, SavesInputState { +export class Atari7800 extends BasicMachine { + + cpuFrequency = 1789772; + canvasWidth = 320; + numTotalScanlines = 262; + numVisibleScanlines = 258-16; + defaultROMSize = 0xc000; + cpuCyclesPerLine = 113.5; + sampleRate = audioSampleRate; cpu : MOS6502; ram : Uint8Array = new Uint8Array(0x1000); - rom : Uint8Array; - bios : Uint8Array; - inputs = new Uint8Array(16); regs6532 = new Uint8Array(4); - scanline : number = 0; tia : TIA = new TIA(); maria : MARIA = new MARIA(); pokey1; //TODO: type + audioadapter; - pixels : Uint32Array; - audio : SampledAudioSink; handler; // TODO: type, or use ControllerPoller - lastFrameCycles : number = 0; + lastFrameCycles = 0; read : (a:number) => number; write : (a:number, v:number) => void; constructor() { + super(); this.cpu = new MOS6502(); this.read = newAddressDecoder([ [0x0008, 0x000d, 0x0f, (a) => { return this.readInput(a); }], @@ -349,11 +350,10 @@ export class Atari7800 implements HasCPU, Bus, RasterFrameBased, SampledAudioSou [0xbfff, 0xbfff, 0xffff, (a,v) => { }], // TODO: bank switching? [0x0000, 0xffff, 0xffff, (a,v) => { throw new EmuHalt("Write @ " + hex(a,4) + " " + hex(v,2)); }], ]); - this.cpu.connectMemoryBus(this); + this.connectCPUMemoryBus(this); this.handler = newKeyboardHandler(this.inputs, Atari7800_KEYCODE_MAP); this.pokey1 = new POKEYDeviceChannel(); - this.pokey1.setBufferLength(oversampling*2); - this.pokey1.setSampleRate(this.getAudioParams().sampleRate); + this.audioadapter = new TssChannelAdapter(this.pokey1, audioOversample, audioSampleRate); } readConst(a) { return this.read(a); } //TODO? @@ -367,19 +367,6 @@ export class Atari7800 implements HasCPU, Bus, RasterFrameBased, SampledAudioSou } } - getVideoParams() { - return {width:320, height:numVisibleLines, overscan:true}; - } - getAudioParams() { - return {sampleRate:linesPerFrame*60*oversampling, stereo:false}; - } - connectVideo(pixels:Uint32Array) { - this.pixels = pixels; - } - connectAudio(audio:SampledAudioSink) { - this.audio = audio; - } - //TODO this.bios = new Uint8Array(0x1000); // TODO: TIA access wastes a cycle @@ -391,43 +378,32 @@ export class Atari7800 implements HasCPU, Bus, RasterFrameBased, SampledAudioSou var idata = this.pixels; var iofs = 0; var rgb; - var mariaClocks = colorClocksPreDMA; // 7 CPU cycles until DMA - var frameClocks = 0; + var mc = 0; + var fc = 0; + this.probe.logNewFrame(); //console.log(hex(this.cpu.getPC()), hex(this.maria.dll)); // visible lines for (var sl=0; sl 0) { - // wait for WSYNC? (end of line) - if (this.maria.WSYNC) { - if (mariaClocks >= colorClocksPreDMA) { - this.maria.WSYNC--; - mariaClocks = colorClocksPreDMA; // 7 CPU cycles until DMA - // TODO: frameClocks - } else { - break; - } - } - // next CPU clock - if (trap && (this.lastFrameCycles=frameClocks)>=0 && trap()) { + this.maria.WSYNC = 0; + // pre-DMA clocks + while (mc < colorClocksPreDMA) { + if (this.maria.WSYNC) break; + if (trap && trap()) { trap = null; sl = 999; - break; + break; // TODO? } - mariaClocks -= 4; - frameClocks += 4; - this.cpu.advanceClock(); + mc += this.advanceCPU() << 2; } - mariaClocks += colorClocksPerLine; // is this scanline visible? if (visible) { // do DMA for scanline? let dmaClocks = this.maria.doDMA(this); - mariaClocks -= dmaClocks; - frameClocks += dmaClocks; + this.probe.logClocks(dmaClocks >> 2); + mc += dmaClocks; // copy line to frame buffer if (idata) { for (var i=0; i<320; i++) { @@ -437,27 +413,36 @@ export class Atari7800 implements HasCPU, Bus, RasterFrameBased, SampledAudioSou } // do interrupt? (if visible or before 1st scanline) if ((visible || sl == linesPerFrame-1) && this.maria.doInterrupt()) { - //this.profiler && this.profiler.logInterrupt(0); + this.probe.logInterrupt(1); // TODO? this.cpu.NMI(); - //console.log("NMI", hex(this.cpu.getPC()), hex(this.maria.dll)); + //console.log("NMI", hex(this.cpu.getPC()), hex(this.maria.dll)); + } + // post-DMA clocks + while (mc < colorClocksPerLine) { + if (this.maria.WSYNC) { + this.probe.logClocks((colorClocksPerLine - mc) >> 2); + mc = colorClocksPerLine; + break; + } + if (trap && trap()) { + trap = null; + sl = 999; + break; + } + mc += this.advanceCPU() << 2; } // audio - if (this.audio) { - const audioGain = 1.0 / 8192; - this.pokey1.generate(oversampling*2); - for (let i=0; i