mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-01 09:32:31 +00:00
started on SMS; got rid of BaseFrameBasedPlatform; more tests
This commit is contained in:
parent
4bbef9365c
commit
c0f97458aa
@ -29,6 +29,7 @@
|
||||
"test-one": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000",
|
||||
"test-node": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli",
|
||||
"test-worker": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli/testworker.js",
|
||||
"test-platforms": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli/testplatforms.js",
|
||||
"test-profile": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 --prof test/cli"
|
||||
},
|
||||
"repository": {
|
||||
|
109
presets/sms-sms-libcv/fonts.s
Normal file
109
presets/sms-sms-libcv/fonts.s
Normal file
@ -0,0 +1,109 @@
|
||||
|
||||
.area _CODE
|
||||
.globl _font_bitmap_a
|
||||
.globl _font_bitmap_0
|
||||
|
||||
;Character cell data for default font
|
||||
;;{w:8,h:8,brev:1,count:224};;
|
||||
Font_Space:
|
||||
.DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;32
|
||||
.DB 0x10,0x38,0x38,0x10,0x10,0x00,0x10,0x00 ;33
|
||||
.DB 0x6c,0x6c,0x48,0x00,0x00,0x00,0x00,0x00 ;34
|
||||
.DB 0x00,0x28,0x7c,0x28,0x28,0x7c,0x28,0x00 ;35
|
||||
.DB 0x20,0x38,0x40,0x30,0x08,0x70,0x10,0x00 ;36
|
||||
.DB 0x64,0x64,0x08,0x10,0x20,0x4c,0x4c,0x00 ;37
|
||||
.DB 0x20,0x50,0x50,0x20,0x54,0x48,0x34,0x00 ;38
|
||||
.DB 0x30,0x30,0x20,0x00,0x00,0x00,0x00,0x00 ;39
|
||||
.DB 0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x00 ;40
|
||||
.DB 0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x00 ;41
|
||||
.DB 0x00,0x28,0x38,0x7c,0x38,0x28,0x00,0x00 ;42
|
||||
.DB 0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x00 ;43
|
||||
.DB 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20 ;44
|
||||
.DB 0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00 ;45
|
||||
.DB 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00 ;46
|
||||
.DB 0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00 ;47
|
||||
Font_0:
|
||||
_font_bitmap_0:
|
||||
.DB 0x38,0x44,0x4c,0x54,0x64,0x44,0x38,0x00 ;48
|
||||
.DB 0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00 ;49
|
||||
.DB 0x38,0x44,0x04,0x18,0x20,0x40,0x7c,0x00 ;50
|
||||
.DB 0x38,0x44,0x04,0x38,0x04,0x44,0x38,0x00 ;51
|
||||
.DB 0x08,0x18,0x28,0x48,0x7c,0x08,0x08,0x00 ;52
|
||||
.DB 0x7c,0x40,0x40,0x78,0x04,0x44,0x38,0x00 ;53
|
||||
.DB 0x18,0x20,0x40,0x78,0x44,0x44,0x38,0x00 ;54
|
||||
.DB 0x7c,0x04,0x08,0x10,0x20,0x20,0x20,0x00 ;55
|
||||
.DB 0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00 ;56
|
||||
.DB 0x38,0x44,0x44,0x3c,0x04,0x08,0x30,0x00 ;57
|
||||
.DB 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00 ;58
|
||||
.DB 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x20 ;59
|
||||
.DB 0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00 ;60
|
||||
.DB 0x00,0x00,0x7c,0x00,0x00,0x7c,0x00,0x00 ;61
|
||||
.DB 0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x00 ;62
|
||||
.DB 0x38,0x44,0x04,0x18,0x10,0x00,0x10,0x00 ;63
|
||||
.DB 0x38,0x44,0x5c,0x54,0x5c,0x40,0x38,0x00 ;64
|
||||
Font_A:
|
||||
_font_bitmap_a:
|
||||
.DB 0x38,0x44,0x44,0x44,0x7c,0x44,0x44,0x00 ;65
|
||||
.DB 0x78,0x44,0x44,0x78,0x44,0x44,0x78,0x00 ;66
|
||||
.DB 0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00 ;67
|
||||
.DB 0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00 ;68
|
||||
.DB 0x7c,0x40,0x40,0x78,0x40,0x40,0x7c,0x00 ;69
|
||||
.DB 0x7c,0x40,0x40,0x78,0x40,0x40,0x40,0x00 ;70
|
||||
.DB 0x38,0x44,0x40,0x5c,0x44,0x44,0x3c,0x00 ;71
|
||||
.DB 0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x00 ;72
|
||||
.DB 0x38,0x10,0x10,0x10,0x10,0x10,0x38,0x00 ;73
|
||||
.DB 0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00 ;74
|
||||
.DB 0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00 ;75
|
||||
.DB 0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00 ;76
|
||||
.DB 0x44,0x6c,0x54,0x44,0x44,0x44,0x44,0x00 ;77
|
||||
.DB 0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x00 ;78
|
||||
.DB 0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00 ;79
|
||||
.DB 0x78,0x44,0x44,0x78,0x40,0x40,0x40,0x00 ;80
|
||||
.DB 0x38,0x44,0x44,0x44,0x54,0x48,0x34,0x00 ;81
|
||||
.DB 0x78,0x44,0x44,0x78,0x48,0x44,0x44,0x00 ;82
|
||||
.DB 0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00 ;83
|
||||
.DB 0x7c,0x10,0x10,0x10,0x10,0x10,0x10,0x00 ;84
|
||||
.DB 0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00 ;85
|
||||
.DB 0x44,0x44,0x44,0x44,0x44,0x28,0x10,0x00 ;86
|
||||
.DB 0x44,0x44,0x54,0x54,0x54,0x54,0x28,0x00 ;87
|
||||
.DB 0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00 ;88
|
||||
.DB 0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x00 ;89
|
||||
.DB 0x78,0x08,0x10,0x20,0x40,0x40,0x78,0x00 ;90
|
||||
.DB 0x38,0x20,0x20,0x20,0x20,0x20,0x38,0x00 ;91
|
||||
.DB 0x00,0x40,0x20,0x10,0x08,0x04,0x00,0x00 ;92
|
||||
.DB 0x38,0x08,0x08,0x08,0x08,0x08,0x38,0x00 ;93
|
||||
.DB 0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00 ;94
|
||||
.DB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc ;95
|
||||
.DB 0x30,0x30,0x10,0x00,0x00,0x00,0x00,0x00 ;96
|
||||
.DB 0x00,0x00,0x38,0x04,0x3c,0x44,0x3c,0x00 ;97
|
||||
.DB 0x40,0x40,0x78,0x44,0x44,0x44,0x78,0x00 ;98
|
||||
.DB 0x00,0x00,0x38,0x44,0x40,0x44,0x38,0x00 ;99
|
||||
.DB 0x04,0x04,0x3c,0x44,0x44,0x44,0x3c,0x00 ;100
|
||||
.DB 0x00,0x00,0x38,0x44,0x78,0x40,0x38,0x00 ;101
|
||||
.DB 0x18,0x20,0x20,0x78,0x20,0x20,0x20,0x00 ;102
|
||||
.DB 0x00,0x00,0x3c,0x44,0x44,0x3c,0x04,0x38 ;103
|
||||
.DB 0x40,0x40,0x70,0x48,0x48,0x48,0x48,0x00 ;104
|
||||
.DB 0x10,0x00,0x10,0x10,0x10,0x10,0x18,0x00 ;105
|
||||
.DB 0x08,0x00,0x18,0x08,0x08,0x08,0x48,0x30 ;106
|
||||
.DB 0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00 ;107
|
||||
.DB 0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x00 ;108
|
||||
.DB 0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x00 ;109
|
||||
.DB 0x00,0x00,0x70,0x48,0x48,0x48,0x48,0x00 ;110
|
||||
.DB 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00 ;111
|
||||
.DB 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40 ;112
|
||||
.DB 0x00,0x00,0x3c,0x44,0x44,0x44,0x3c,0x04 ;113
|
||||
.DB 0x00,0x00,0x58,0x24,0x20,0x20,0x70,0x00 ;114
|
||||
.DB 0x00,0x00,0x38,0x40,0x38,0x04,0x38,0x00 ;115
|
||||
.DB 0x00,0x20,0x78,0x20,0x20,0x28,0x10,0x00 ;116
|
||||
.DB 0x00,0x00,0x48,0x48,0x48,0x58,0x28,0x00 ;117
|
||||
.DB 0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x00 ;118
|
||||
.DB 0x00,0x00,0x44,0x44,0x54,0x7c,0x28,0x00 ;119
|
||||
.DB 0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00 ;120
|
||||
.DB 0x00,0x00,0x48,0x48,0x48,0x38,0x10,0x60 ;121
|
||||
.DB 0x00,0x00,0x78,0x08,0x30,0x40,0x78,0x00 ;122
|
||||
.DB 0x18,0x20,0x20,0x60,0x20,0x20,0x18,0x00 ;123
|
||||
.DB 0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x00 ;124
|
||||
.DB 0x30,0x08,0x08,0x0c,0x08,0x08,0x30,0x00 ;125
|
||||
.DB 0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00 ;126
|
||||
.DB 0x10,0x38,0x6c,0x44,0x44,0x7c,0x00,0x00 ;127
|
||||
;;
|
@ -196,8 +196,22 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: what's the diff? why z80 not use? unify these things
|
||||
export abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
|
||||
////// 6502
|
||||
|
||||
export function getToolForFilename_6502(fn:string) : string {
|
||||
if (fn.endsWith(".pla")) return "plasm";
|
||||
if (fn.endsWith(".c")) return "cc65";
|
||||
if (fn.endsWith(".h")) return "cc65";
|
||||
if (fn.endsWith(".s")) return "ca65";
|
||||
if (fn.endsWith(".ca65")) return "ca65";
|
||||
if (fn.endsWith(".dasm")) return "dasm";
|
||||
if (fn.endsWith(".acme")) return "acme";
|
||||
return "dasm"; // .a
|
||||
}
|
||||
|
||||
// TODO: can merge w/ Z80?
|
||||
export abstract class Base6502Platform extends BaseDebugPlatform {
|
||||
|
||||
debugPCDelta = -1;
|
||||
|
||||
evalDebugCondition() {
|
||||
@ -274,22 +288,6 @@ export abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
////// 6502
|
||||
|
||||
export function getToolForFilename_6502(fn:string) : string {
|
||||
if (fn.endsWith(".pla")) return "plasm";
|
||||
if (fn.endsWith(".c")) return "cc65";
|
||||
if (fn.endsWith(".h")) return "cc65";
|
||||
if (fn.endsWith(".s")) return "ca65";
|
||||
if (fn.endsWith(".ca65")) return "ca65";
|
||||
if (fn.endsWith(".dasm")) return "dasm";
|
||||
if (fn.endsWith(".acme")) return "acme";
|
||||
return "dasm"; // .a
|
||||
}
|
||||
|
||||
export abstract class Base6502Platform extends BaseFrameBasedPlatform {
|
||||
|
||||
newCPU(membus : MemoryBus) {
|
||||
var cpu = new jt.M6502();
|
||||
|
@ -76,8 +76,6 @@ const _ColecoVisionPlatform = function(mainElement) {
|
||||
class ColecoVisionPlatform extends BaseZ80Platform implements Platform {
|
||||
|
||||
getPresets() { return ColecoVision_PRESETS; }
|
||||
getToolForFilename = getToolForFilename_z80;
|
||||
getDefaultExtension() { return ".c"; };
|
||||
|
||||
start() {
|
||||
ram = new RAM(1024);
|
||||
@ -179,15 +177,11 @@ const _ColecoVisionPlatform = function(mainElement) {
|
||||
};
|
||||
}
|
||||
loadControlsState(state) {
|
||||
inputs[0] = state.in0;
|
||||
inputs[1] = state.in1;
|
||||
inputs[2] = state.in2;
|
||||
inputs.set(state.in);
|
||||
}
|
||||
saveControlsState() {
|
||||
return {
|
||||
in0:inputs[0],
|
||||
in1:inputs[1],
|
||||
in2:inputs[2],
|
||||
in:inputs.slice(0)
|
||||
};
|
||||
}
|
||||
getCPUState() {
|
||||
|
@ -58,8 +58,6 @@ const _MSXPlatform = function(mainElement) {
|
||||
class MSXPlatform extends BaseZ80Platform implements Platform {
|
||||
|
||||
getPresets() { return MSX_PRESETS; }
|
||||
getToolForFilename = getToolForFilename_z80;
|
||||
getDefaultExtension() { return ".c"; };
|
||||
|
||||
start() {
|
||||
ram = new RAM(0x10000);
|
||||
|
@ -4,7 +4,7 @@ import { Platform, BaseMAMEPlatform, BaseZ80Platform, getToolForFilename_z80 } f
|
||||
import { PLATFORMS, RAM, newAddressDecoder, padBytes, noise, setKeyboardFromMap, AnimationTimer, RasterVideo, Keys, makeKeycodeMap } from "../emu";
|
||||
import { hex, lzgmini, stringToByteArray } from "../util";
|
||||
import { MasterAudio, SN76489_Audio } from "../audio";
|
||||
import { TMS9918A } from "../video/tms9918a";
|
||||
import { TMS9918A, SMSVDP } from "../video/tms9918a";
|
||||
import { ColecoVision_PRESETS } from "./coleco";
|
||||
|
||||
// http://www.smspower.org/Development/Index
|
||||
@ -49,7 +49,7 @@ var SG1000_KEYCODE_MAP = makeKeycodeMap([
|
||||
|
||||
/// standard emulator
|
||||
|
||||
const _SG1000Platform = function(mainElement) {
|
||||
const _SG1000Platform = function(mainElement, isSMS:boolean) {
|
||||
|
||||
const cpuFrequency = 3579545; // MHz
|
||||
const canvasWidth = 304;
|
||||
@ -63,28 +63,30 @@ const _SG1000Platform = function(mainElement) {
|
||||
var inputs = new Uint8Array(4);
|
||||
|
||||
class SG1000Platform extends BaseZ80Platform implements Platform {
|
||||
|
||||
currentScanline;
|
||||
|
||||
getPresets() { return SG1000_PRESETS; }
|
||||
getToolForFilename = getToolForFilename_z80;
|
||||
getDefaultExtension() { return ".c"; };
|
||||
|
||||
start() {
|
||||
ram = new RAM(1024);
|
||||
var ramSize = isSMS ? 0x2000 : 0x400;
|
||||
ram = new RAM(ramSize);
|
||||
membus = {
|
||||
read: newAddressDecoder([
|
||||
[0xc000, 0xdfff, 0x3ff, function(a) { return ram.mem[a]; }],
|
||||
[0x0000, 0xbfff, 0xffff, function(a) { return rom ? rom[a] : 0; }],
|
||||
[0xc000, 0xffff, ramSize-1, function(a) { return ram.mem[a]; }],
|
||||
[0x0000, 0xbfff, 0xffff, function(a) { return rom ? rom[a] : 0; }],
|
||||
]),
|
||||
write: newAddressDecoder([
|
||||
[0xc000, 0xdfff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
|
||||
[0xc000, 0xffff, ramSize-1, function(a,v) { ram.mem[a] = v; }],
|
||||
]),
|
||||
isContended: function() { return false; },
|
||||
};
|
||||
iobus = {
|
||||
read: function(addr) {
|
||||
read: (addr:number) => {
|
||||
addr &= 0xff;
|
||||
//console.log('IO read', hex(addr,4));
|
||||
switch (addr & 0xc1) {
|
||||
case 0x40: return isSMS ? this.currentScanline : 0;
|
||||
case 0x80: return vdp.readData();
|
||||
case 0x81: return vdp.readStatus();
|
||||
case 0xc0: return inputs[0] ^ 0xff;
|
||||
@ -92,7 +94,7 @@ const _SG1000Platform = function(mainElement) {
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
write: function(addr, val) {
|
||||
write: (addr:number, val:number) => {
|
||||
addr &= 0xff;
|
||||
val &= 0xff;
|
||||
//console.log('IO write', hex(addr,4), hex(val,2));
|
||||
@ -118,7 +120,8 @@ const _SG1000Platform = function(mainElement) {
|
||||
}
|
||||
}
|
||||
};
|
||||
vdp = new TMS9918A(video.canvas, cru, true); // true = 4 sprites/line
|
||||
var vdpclass = isSMS ? SMSVDP : TMS9918A;
|
||||
vdp = new vdpclass(video.canvas, cru, true); // true = 4 sprites/line
|
||||
setKeyboardFromMap(video, inputs, SG1000_KEYCODE_MAP);
|
||||
timer = new AnimationTimer(60, this.nextFrame.bind(this));
|
||||
}
|
||||
@ -129,6 +132,7 @@ const _SG1000Platform = function(mainElement) {
|
||||
|
||||
advance(novideo : boolean) {
|
||||
for (var sl=0; sl<numTotalScanlines; sl++) {
|
||||
this.currentScanline = sl;
|
||||
this.runCPU(cpu, cpuCyclesPerLine);
|
||||
if (sl < numVisibleScanlines)
|
||||
vdp.drawScanline(sl);
|
||||
@ -156,15 +160,11 @@ const _SG1000Platform = function(mainElement) {
|
||||
};
|
||||
}
|
||||
loadControlsState(state) {
|
||||
inputs[0] = state.in0;
|
||||
inputs[1] = state.in1;
|
||||
inputs[2] = state.in2;
|
||||
inputs.set(state.in);
|
||||
}
|
||||
saveControlsState() {
|
||||
return {
|
||||
in0:inputs[0],
|
||||
in1:inputs[1],
|
||||
in2:inputs[2],
|
||||
in:inputs.slice(0)
|
||||
};
|
||||
}
|
||||
getCPUState() {
|
||||
@ -207,4 +207,11 @@ const _SG1000Platform = function(mainElement) {
|
||||
|
||||
///
|
||||
|
||||
const _SMSPlatform = function(mainElement) {
|
||||
this.__proto__ = new (_SG1000Platform as any)(mainElement, true);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
PLATFORMS['sms-sg1000-libcv'] = _SG1000Platform;
|
||||
PLATFORMS['sms-sms-libcv'] = _SMSPlatform;
|
||||
|
@ -356,7 +356,78 @@ export class TMS9918A {
|
||||
updateCanvas() {
|
||||
this.canvasContext.putImageData(this.imageData, 0, 0);
|
||||
}
|
||||
|
||||
setReadAddress(i:number) {
|
||||
this.addressRegister = ((i & 0x3f) << 8) | (this.addressRegister & 0x00FF);
|
||||
this.prefetchByte = this.ram[this.addressRegister++];
|
||||
this.addressRegister &= 0x3FFF;
|
||||
}
|
||||
|
||||
setWriteAddress(i:number) {
|
||||
this.addressRegister = ((i & 0x3f) << 8) | (this.addressRegister & 0x00FF);
|
||||
}
|
||||
|
||||
setVDPWriteRegister(i:number) {
|
||||
var regmask = this.registers.length-1;
|
||||
this.registers[i & regmask] = this.addressRegister & 0x00FF;
|
||||
switch (i & regmask) {
|
||||
// Mode
|
||||
case 0:
|
||||
this.updateMode(this.registers[0], this.registers[1]);
|
||||
break;
|
||||
case 1:
|
||||
this.ramMask = (this.registers[1] & 0x80) !== 0 ? 0x3FFF : 0x1FFF;
|
||||
this.displayOn = (this.registers[1] & 0x40) !== 0;
|
||||
this.interruptsOn = (this.registers[1] & 0x20) !== 0;
|
||||
this.updateMode(this.registers[0], this.registers[1]);
|
||||
break;
|
||||
// Name table
|
||||
case 2:
|
||||
this.nameTable = (this.registers[2] & 0xf) << 10;
|
||||
break;
|
||||
// Color table
|
||||
case 3:
|
||||
if (this.bitmapMode) {
|
||||
this.colorTable = (this.registers[3] & 0x80) << 6;
|
||||
}
|
||||
else {
|
||||
this.colorTable = this.registers[3] << 6;
|
||||
}
|
||||
this.updateTableMasks();
|
||||
break;
|
||||
// Pattern table
|
||||
case 4:
|
||||
if (this.bitmapMode) {
|
||||
this.charPatternTable = (this.registers[4] & 0x4) << 11;
|
||||
}
|
||||
else {
|
||||
this.charPatternTable = (this.registers[4] & 0x7) << 11;
|
||||
}
|
||||
this.updateTableMasks();
|
||||
break;
|
||||
// Sprite attribute table
|
||||
case 5:
|
||||
this.spriteAttributeTable = (this.registers[5] & 0x7f) << 7;
|
||||
break;
|
||||
// Sprite pattern table
|
||||
case 6:
|
||||
this.spritePatternTable = (this.registers[6] & 0x7) << 11;
|
||||
break;
|
||||
// Background
|
||||
case 7:
|
||||
this.fgColor = (this.registers[7] & 0xf0) >> 4;
|
||||
this.bgColor = this.registers[7] & 0x0f;
|
||||
break;
|
||||
}
|
||||
// this.logRegisters();
|
||||
// this.log.info("Name table: " + this.nameTable.toHexWord());
|
||||
// this.log.info("Pattern table: " + this.charPatternTable.toHexWord());
|
||||
}
|
||||
|
||||
setVDPWriteCommand3(i:number) {
|
||||
this.setVDPWriteRegister(i);
|
||||
}
|
||||
|
||||
writeAddress(i:number) {
|
||||
if (!this.latch) {
|
||||
this.addressRegister = (this.addressRegister & 0xFF00) | i;
|
||||
@ -365,70 +436,18 @@ export class TMS9918A {
|
||||
switch ((i & 0xc0) >> 6) {
|
||||
// Set read address
|
||||
case 0:
|
||||
this.addressRegister = ((i & 0x3f) << 8) | (this.addressRegister & 0x00FF);
|
||||
this.prefetchByte = this.ram[this.addressRegister++];
|
||||
this.addressRegister &= 0x3FFF;
|
||||
this.setReadAddress(i);
|
||||
break;
|
||||
// Set write address
|
||||
case 1:
|
||||
this.addressRegister = ((i & 0x3f) << 8) | (this.addressRegister & 0x00FF);
|
||||
this.setWriteAddress(i);
|
||||
break;
|
||||
// Write register
|
||||
case 2:
|
||||
this.setVDPWriteRegister(i);
|
||||
break;
|
||||
case 3:
|
||||
this.registers[i & 0x7] = this.addressRegister & 0x00FF;
|
||||
switch (i & 0x7) {
|
||||
// Mode
|
||||
case 0:
|
||||
this.updateMode(this.registers[0], this.registers[1]);
|
||||
break;
|
||||
case 1:
|
||||
this.ramMask = (this.registers[1] & 0x80) !== 0 ? 0x3FFF : 0x1FFF;
|
||||
this.displayOn = (this.registers[1] & 0x40) !== 0;
|
||||
this.interruptsOn = (this.registers[1] & 0x20) !== 0;
|
||||
this.updateMode(this.registers[0], this.registers[1]);
|
||||
break;
|
||||
// Name table
|
||||
case 2:
|
||||
this.nameTable = (this.registers[2] & 0xf) << 10;
|
||||
break;
|
||||
// Color table
|
||||
case 3:
|
||||
if (this.bitmapMode) {
|
||||
this.colorTable = (this.registers[3] & 0x80) << 6;
|
||||
}
|
||||
else {
|
||||
this.colorTable = this.registers[3] << 6;
|
||||
}
|
||||
this.updateTableMasks();
|
||||
break;
|
||||
// Pattern table
|
||||
case 4:
|
||||
if (this.bitmapMode) {
|
||||
this.charPatternTable = (this.registers[4] & 0x4) << 11;
|
||||
}
|
||||
else {
|
||||
this.charPatternTable = (this.registers[4] & 0x7) << 11;
|
||||
}
|
||||
this.updateTableMasks();
|
||||
break;
|
||||
// Sprite attribute table
|
||||
case 5:
|
||||
this.spriteAttributeTable = (this.registers[5] & 0x7f) << 7;
|
||||
break;
|
||||
// Sprite pattern table
|
||||
case 6:
|
||||
this.spritePatternTable = (this.registers[6] & 0x7) << 11;
|
||||
break;
|
||||
// Background
|
||||
case 7:
|
||||
this.fgColor = (this.registers[7] & 0xf0) >> 4;
|
||||
this.bgColor = this.registers[7] & 0x0f;
|
||||
break;
|
||||
}
|
||||
// this.logRegisters();
|
||||
// this.log.info("Name table: " + this.nameTable.toHexWord());
|
||||
// this.log.info("Pattern table: " + this.charPatternTable.toHexWord());
|
||||
this.setVDPWriteCommand3(i);
|
||||
break;
|
||||
}
|
||||
this.redrawRequired = true;
|
||||
@ -579,7 +598,7 @@ export class TMS9918A {
|
||||
s += lpad("Screen Mode",w) + ": " + this.screenMode + "\n";
|
||||
s += lpad("Display On",w) + ": " + this.displayOn + "\n";
|
||||
if (this.ramMask != 0x3fff)
|
||||
s += lpad("RAM Mask",w) + ": " + this.ramMask + "\n";
|
||||
s += lpad("RAM Mask",w) + ": $" + hex(this.ramMask) + "\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -628,8 +647,8 @@ export class TMS9918A {
|
||||
|
||||
getState() {
|
||||
return {
|
||||
ram: this.ram,
|
||||
registers: this.registers,
|
||||
ram: this.ram.slice(0),
|
||||
registers: this.registers.slice(0),
|
||||
addressRegister: this.addressRegister,
|
||||
statusRegister: this.statusRegister,
|
||||
latch: this.latch,
|
||||
@ -654,8 +673,8 @@ export class TMS9918A {
|
||||
}
|
||||
|
||||
restoreState(state) {
|
||||
this.ram = state.ram;
|
||||
this.registers = state.registers;
|
||||
this.ram.set(state.ram);
|
||||
this.registers.set(state.registers);
|
||||
this.addressRegister = state.addressRegister;
|
||||
this.statusRegister = state.statusRegister;
|
||||
this.latch = state.latch;
|
||||
@ -679,3 +698,45 @@ export class TMS9918A {
|
||||
this.redrawRequired = true;
|
||||
}
|
||||
};
|
||||
|
||||
export class SMSVDP extends TMS9918A {
|
||||
|
||||
writeToCRAM : boolean;
|
||||
cram = new Uint8Array(32); // color RAM
|
||||
registers = new Uint8Array(16); // 8 more registers
|
||||
|
||||
setReadAddress(i:number) {
|
||||
super.setReadAddress(i);
|
||||
this.writeToCRAM = false;
|
||||
}
|
||||
setWriteAddress(i:number) {
|
||||
super.setWriteAddress(i);
|
||||
this.writeToCRAM = false;
|
||||
}
|
||||
setVDPWriteRegister(i:number) {
|
||||
super.setVDPWriteRegister(i);
|
||||
this.writeToCRAM = false;
|
||||
}
|
||||
setVDPWriteCommand3(i:number) {
|
||||
this.writeToCRAM = true;
|
||||
}
|
||||
writeData(i:number) {
|
||||
if (this.writeToCRAM) {
|
||||
this.cram[this.addressRegister++ & (this.cram.length-1)] = i;
|
||||
this.addressRegister &= this.ramMask;
|
||||
this.redrawRequired = true;
|
||||
} else {
|
||||
super.writeData(i);
|
||||
}
|
||||
}
|
||||
getState() {
|
||||
var state = super.getState();
|
||||
state['cram'] = this.cram.slice(0);
|
||||
return state;
|
||||
}
|
||||
restoreState(state) {
|
||||
super.restoreState(state);
|
||||
this.cram.set(state.cram);
|
||||
}
|
||||
};
|
||||
|
||||
|
1
src/worker/lib/sms-sms-libcv
Symbolic link
1
src/worker/lib/sms-sms-libcv
Symbolic link
@ -0,0 +1 @@
|
||||
sms-sg1000-libcv
|
@ -191,6 +191,7 @@ var PLATFORM_PARAMS = {
|
||||
};
|
||||
|
||||
PLATFORM_PARAMS['coleco.mame'] = PLATFORM_PARAMS['coleco'];
|
||||
PLATFORM_PARAMS['sms-sms-libcv'] = PLATFORM_PARAMS['sms-sg1000-libcv'];
|
||||
|
||||
var _t1;
|
||||
function starttime() { _t1 = new Date(); }
|
||||
|
@ -43,6 +43,7 @@ var _sound_williams = require('gen/platform/sound_williams.js');
|
||||
var _astrocade = require('gen/platform/astrocade.js');
|
||||
var _atari8 = require('gen/platform/atari8.js');
|
||||
var _coleco = require('gen/platform/coleco.js');
|
||||
var _sms = require('gen/platform/sms.js');
|
||||
|
||||
//
|
||||
|
||||
@ -59,16 +60,26 @@ global.navigator = {};
|
||||
var keycallback;
|
||||
|
||||
emu.RasterVideo = function(mainElement, width, height, options) {
|
||||
var buffer;
|
||||
var datau8;
|
||||
var datau32;
|
||||
this.create = function() {
|
||||
datau32 = new Uint32Array(width*height);
|
||||
buffer = new ArrayBuffer(width*height*4);
|
||||
datau8 = new Uint8Array(buffer);
|
||||
datau32 = new Uint32Array(buffer);
|
||||
}
|
||||
this.setKeyboardEvents = function(callback) {
|
||||
keycallback = callback;
|
||||
}
|
||||
this.getFrameData = function() { return datau32; }
|
||||
this.getImageData = function() { return {data:datau8, width:width, height:height}; }
|
||||
this.updateFrame = function() {}
|
||||
this.setupMouseEvents = function() { }
|
||||
this.canvas = this;
|
||||
this.getContext = function() { return this; }
|
||||
this.fillRect = function() { }
|
||||
this.fillStyle = '';
|
||||
this.putImageData = function() { }
|
||||
}
|
||||
|
||||
emu.VectorVideo = function(mainElement, width, height, options) {
|
||||
@ -224,7 +235,6 @@ describe('Platform Replay', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
/*
|
||||
it('Should run coleco', () => {
|
||||
var platform = testPlatform('coleco', 'shoot.c.rom', 92, (platform, frameno) => {
|
||||
if (frameno == 62) {
|
||||
@ -232,7 +242,13 @@ describe('Platform Replay', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
*/
|
||||
it('Should run sms-sg1000-libcv', () => {
|
||||
var platform = testPlatform('sms-sg1000-libcv', 'shoot.c.rom', 92, (platform, frameno) => {
|
||||
if (frameno == 62) {
|
||||
keycallback(Keys.VK_SPACE.c, Keys.VK_SPACE.c, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
/* TODO
|
||||
it('Should run atari8-5200', () => {
|
||||
var platform = testPlatform('atari8-5200', 'hello.a.rom', 92, (platform, frameno) => {
|
||||
|
BIN
test/roms/atari8-5200/hello.a.rom
Normal file
BIN
test/roms/atari8-5200/hello.a.rom
Normal file
Binary file not shown.
BIN
test/roms/sms-sg1000-libcv/shoot.c.rom
Normal file
BIN
test/roms/sms-sg1000-libcv/shoot.c.rom
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user