mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-24 09:30:45 +00:00
sms: fixed a few cases w/ http://www.smspower.org/Homebrew/SMSVDPTest-SMS
This commit is contained in:
parent
2dd5d88d55
commit
403b4264fc
@ -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,11 +242,12 @@ 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() {
|
||||
@ -248,6 +259,26 @@ class SMSPlatform extends SG1000Platform {
|
||||
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) {
|
||||
|
@ -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)) {
|
||||
if (!this.displayOn || line < 0 || line >= drawHeight) {
|
||||
if (line < this.height)
|
||||
this.border_clear(startAddr, this.width);
|
||||
}
|
||||
else if ((vdp_regs[1] & 64) === 0) {
|
||||
this.border_clear(startAddr, this.width);
|
||||
}
|
||||
else {
|
||||
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() {
|
||||
|
Loading…
Reference in New Issue
Block a user