diff --git a/src/platform/sms.ts b/src/platform/sms.ts index 94d23706..71b0f809 100644 --- a/src/platform/sms.ts +++ b/src/platform/sms.ts @@ -10,6 +10,7 @@ import { ColecoVision_PRESETS } from "./coleco"; // http://www.smspower.org/Development/Index // http://www.smspower.org/uploads/Development/sg1000.txt // http://www.smspower.org/uploads/Development/richard.txt +// http://www.smspower.org/uploads/Development/msvdp-20021112.txt // TODO: merge w/ coleco export var SG1000_PRESETS = [ @@ -68,8 +69,8 @@ class SG1000Platform extends BaseZ80Platform { inputs = new Uint8Array(4); mainElement : HTMLElement; - isSMS = false; // TODO: remove currentScanline : number; + startLineTstates : number; constructor(mainElement : HTMLElement) { super(); @@ -96,13 +97,19 @@ class SG1000Platform extends BaseZ80Platform { }; } + getVCounter() : number { return 0; } + getHCounter() : number { return 0; } + setMemoryControl(v:number) { } + setIOPortControl(v:number) { } + newIOBus() { return { read: (addr:number) => { addr &= 0xff; //console.log('IO read', hex(addr,4)); switch (addr & 0xc1) { - case 0x40: return this.isSMS ? this.currentScanline : 0; + case 0x40: return this.getVCounter(); + case 0x41: return this.getHCounter(); case 0x80: return this.vdp.readData(); case 0x81: return this.vdp.readStatus(); case 0xc0: return this.inputs[0] ^ 0xff; @@ -115,10 +122,12 @@ class SG1000Platform extends BaseZ80Platform { val &= 0xff; //console.log('IO write', hex(addr,4), hex(val,2)); switch (addr & 0xc1) { - case 0x80: return this.vdp.writeData(val); - case 0x81: return this.vdp.writeAddress(val); + case 0x00: return this.setMemoryControl(val); + case 0x01: return this.setIOPortControl(val); case 0x40: case 0x41: return this.psg.setData(val); + case 0x80: return this.vdp.writeData(val); + case 0x81: return this.vdp.writeAddress(val); } } }; @@ -159,6 +168,7 @@ class SG1000Platform extends BaseZ80Platform { advance(novideo : boolean) { for (var sl=0; sl>2)&3)<<6, ((i>>4)&3)<<6); + this.prefetchByte = i; this.addressRegister &= this.ramMask; this.redrawRequired = true; } else { @@ -722,16 +731,6 @@ export class SMSVDP extends TMS9918A { } this.latch = false; } - readData() : number { - if (this.writeToCRAM) { - var palindex = this.addressRegister++ & (this.cram.length-1); - this.addressRegister &= this.ramMask; - return this.cram[palindex]; - } else { - return super.readData(); - } - } - writeTwiddled(vdp_addr:number, val:number) { var planarBase = vdp_addr & 0x3ffc; var twiddledBase = planarBase * 2; @@ -934,25 +933,24 @@ export class SMSVDP extends TMS9918A { count = count | 0; const borderIndex = 16 + (this.registers[7] & 0xf); const borderRGB = this.cpalette[borderIndex]; - for (var i = 0; i < count; i++) - this.fb32[lineAddr + i] = borderRGB; + this.fb32.fill(borderRGB, lineAddr, lineAddr+count); } rasterize_line(line:number) { + line |= 0; var vdp_regs = this.registers; - var drawHeight = 192; // TODO? - var hBorder = (this.width - 256) >> 1; - var vBorder = (this.height - 192) >> 1; // TODO? - line = (line - vBorder*0) | 0; // TODO? - const startAddr = (line * this.width) | 0; + var drawWidth = 256; + var drawHeight = this.numVisibleLines; // TODO? + var hBorder = (this.width - drawWidth) >> 1; + var vBorder = (this.height - drawHeight) >> 1; // TODO? + const startAddr = ((line + vBorder) * this.width) | 0; const lineAddr = (startAddr + hBorder) | 0; - if (!(line >= 0 && line < 224 && this.displayOn)) { - this.border_clear(startAddr, this.width); - } - else if ((vdp_regs[1] & 64) === 0) { - this.border_clear(startAddr, this.width); - } - else { + if (!this.displayOn || line < 0 || line >= drawHeight) { + if (line < this.height) + this.border_clear(startAddr, this.width); + else if (line >= 262-vBorder) + this.border_clear((line-262+vBorder)*this.width, this.width); + } else { var effectiveLine = line + vdp_regs[9]; if (effectiveLine >= 224) { effectiveLine -= 224; @@ -973,12 +971,29 @@ export class SMSVDP extends TMS9918A { this.border_clear(lineAddr, 8); } } + // frame interrupts if (line == drawHeight) { this.statusRegister |= 0x80; if (this.interruptsOn) { this.cru.setVDPInterrupt(true); } } + // line interrupts + if (line <= drawHeight) { + if (this.lineCounter > 0) { + this.lineCounter--; + } else { + this.lineCounter = this.registers[0xa]; + this.lineInterruptPending = true; + } + } else { + this.lineCounter = this.registers[0xa]; + } + if (this.lineInterruptPending) { + if (this.registers[0] & 0x10) { + // TODO this.cru.setVDPInterrupt(true); + } + } } getDebugTables() {