This commit is contained in:
Steven Hugg 2018-12-01 11:53:40 -05:00
parent 2dd5d88d55
commit 403b4264fc
2 changed files with 79 additions and 33 deletions

View File

@ -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<this.numTotalScanlines; sl++) {
this.currentScanline = sl;
this.startLineTstates = this.cpu.getTstates();
this.runCPU(this.cpu, this.cpuCyclesPerLine);
this.vdp.drawScanline(sl);
}
@ -232,22 +242,43 @@ class SG1000Platform extends BaseZ80Platform {
class SMSPlatform extends SG1000Platform {
isSMS = true;
cartram : RAM = new RAM(0);
pagingRegisters = new Uint8Array(4);
romPageMask : number;
// TODO: add to state
latchedHCounter = 0;
ioControlFlags = 0;
// TODO: hide bottom scanlines
reset() {
super.reset();
this.pagingRegisters.set([0,0,1,2]);
}
newVDP(frameData, cru, flicker) {
return new SMSVDP(frameData, cru, flicker);
}
getVCounter() {
var y = this.currentScanline;
return (y <= 0xda) ? (y) : (y - 6);
}
getHCounter() {
return this.latchedHCounter;
}
computeHCounter() {
var t0 = this.startLineTstates;
var t1 = this.cpu.getTstates();
return (t1-t0) & 0xff; // TODO
}
setIOPortControl(v:number) {
if ((v ^ this.ioControlFlags) & 0xa0) { // either joystick TH pin
this.latchedHCounter = this.computeHCounter();
//console.log("H:"+hex(this.latchedHCounter)+" V:"+hex(this.getVCounter()));
}
this.ioControlFlags = v;
}
newRAM() { return new RAM(0x2000); }
getPagedROM(a:number, reg:number) {

View File

@ -43,8 +43,8 @@ export class TMS9918A {
latch : boolean;
prefetchByte : number;
displayOn = null;
interruptsOn = null;
displayOn : boolean = false;
interruptsOn : boolean = false;
screenMode : number;
bitmapMode : boolean;
textMode : boolean;
@ -493,6 +493,7 @@ export class TMS9918A {
writeData(i:number) {
this.ram[this.addressRegister++] = i;
this.prefetchByte = i;
this.addressRegister &= this.ramMask;
this.latch = false;
this.redrawRequired = true;
@ -674,6 +675,9 @@ export class SMSVDP extends TMS9918A {
cpalette = new Uint32Array(32); // color RAM (RGBA)
registers = new Uint8Array(16); // 8 more registers (actually only 5)
vramUntwiddled = new Uint8Array(0x8000);
numVisibleLines = 192;
lineCounter = 0; // TODO: state
lineInterruptPending = false; // TODO: state
reset() {
super.reset();
@ -682,6 +686,10 @@ export class SMSVDP extends TMS9918A {
this.cpalette.fill(0);
this.vramUntwiddled.fill(0);
}
readStatus() {
this.lineInterruptPending = false;
return super.readStatus();
}
updateMode(reg0:number, reg1:number) {
if (reg0 & 0x04) {
this.screenMode = TMS9918A_Mode.MODE4;
@ -713,6 +721,7 @@ export class SMSVDP extends TMS9918A {
var palindex = this.addressRegister++ & (this.cram.length-1);
this.cram[palindex] = i;
this.cpalette[palindex] = RGBA((i&3)<<6, ((i>>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() {