mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-07 19:30:43 +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-one": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000",
|
||||||
"test-node": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 test/cli",
|
"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-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"
|
"test-profile": "NODE_PATH=$(pwd) mocha --recursive --timeout 60000 --prof test/cli"
|
||||||
},
|
},
|
||||||
"repository": {
|
"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
|
////// 6502
|
||||||
export abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
|
|
||||||
|
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;
|
debugPCDelta = -1;
|
||||||
|
|
||||||
evalDebugCondition() {
|
evalDebugCondition() {
|
||||||
@ -274,22 +288,6 @@ export abstract class BaseFrameBasedPlatform extends BaseDebugPlatform {
|
|||||||
return false;
|
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) {
|
newCPU(membus : MemoryBus) {
|
||||||
var cpu = new jt.M6502();
|
var cpu = new jt.M6502();
|
||||||
|
@ -76,8 +76,6 @@ const _ColecoVisionPlatform = function(mainElement) {
|
|||||||
class ColecoVisionPlatform extends BaseZ80Platform implements Platform {
|
class ColecoVisionPlatform extends BaseZ80Platform implements Platform {
|
||||||
|
|
||||||
getPresets() { return ColecoVision_PRESETS; }
|
getPresets() { return ColecoVision_PRESETS; }
|
||||||
getToolForFilename = getToolForFilename_z80;
|
|
||||||
getDefaultExtension() { return ".c"; };
|
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
ram = new RAM(1024);
|
ram = new RAM(1024);
|
||||||
@ -179,15 +177,11 @@ const _ColecoVisionPlatform = function(mainElement) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
loadControlsState(state) {
|
loadControlsState(state) {
|
||||||
inputs[0] = state.in0;
|
inputs.set(state.in);
|
||||||
inputs[1] = state.in1;
|
|
||||||
inputs[2] = state.in2;
|
|
||||||
}
|
}
|
||||||
saveControlsState() {
|
saveControlsState() {
|
||||||
return {
|
return {
|
||||||
in0:inputs[0],
|
in:inputs.slice(0)
|
||||||
in1:inputs[1],
|
|
||||||
in2:inputs[2],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
getCPUState() {
|
getCPUState() {
|
||||||
|
@ -58,8 +58,6 @@ const _MSXPlatform = function(mainElement) {
|
|||||||
class MSXPlatform extends BaseZ80Platform implements Platform {
|
class MSXPlatform extends BaseZ80Platform implements Platform {
|
||||||
|
|
||||||
getPresets() { return MSX_PRESETS; }
|
getPresets() { return MSX_PRESETS; }
|
||||||
getToolForFilename = getToolForFilename_z80;
|
|
||||||
getDefaultExtension() { return ".c"; };
|
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
ram = new RAM(0x10000);
|
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 { PLATFORMS, RAM, newAddressDecoder, padBytes, noise, setKeyboardFromMap, AnimationTimer, RasterVideo, Keys, makeKeycodeMap } from "../emu";
|
||||||
import { hex, lzgmini, stringToByteArray } from "../util";
|
import { hex, lzgmini, stringToByteArray } from "../util";
|
||||||
import { MasterAudio, SN76489_Audio } from "../audio";
|
import { MasterAudio, SN76489_Audio } from "../audio";
|
||||||
import { TMS9918A } from "../video/tms9918a";
|
import { TMS9918A, SMSVDP } from "../video/tms9918a";
|
||||||
import { ColecoVision_PRESETS } from "./coleco";
|
import { ColecoVision_PRESETS } from "./coleco";
|
||||||
|
|
||||||
// http://www.smspower.org/Development/Index
|
// http://www.smspower.org/Development/Index
|
||||||
@ -49,7 +49,7 @@ var SG1000_KEYCODE_MAP = makeKeycodeMap([
|
|||||||
|
|
||||||
/// standard emulator
|
/// standard emulator
|
||||||
|
|
||||||
const _SG1000Platform = function(mainElement) {
|
const _SG1000Platform = function(mainElement, isSMS:boolean) {
|
||||||
|
|
||||||
const cpuFrequency = 3579545; // MHz
|
const cpuFrequency = 3579545; // MHz
|
||||||
const canvasWidth = 304;
|
const canvasWidth = 304;
|
||||||
@ -63,28 +63,30 @@ const _SG1000Platform = function(mainElement) {
|
|||||||
var inputs = new Uint8Array(4);
|
var inputs = new Uint8Array(4);
|
||||||
|
|
||||||
class SG1000Platform extends BaseZ80Platform implements Platform {
|
class SG1000Platform extends BaseZ80Platform implements Platform {
|
||||||
|
|
||||||
|
currentScanline;
|
||||||
|
|
||||||
getPresets() { return SG1000_PRESETS; }
|
getPresets() { return SG1000_PRESETS; }
|
||||||
getToolForFilename = getToolForFilename_z80;
|
|
||||||
getDefaultExtension() { return ".c"; };
|
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
ram = new RAM(1024);
|
var ramSize = isSMS ? 0x2000 : 0x400;
|
||||||
|
ram = new RAM(ramSize);
|
||||||
membus = {
|
membus = {
|
||||||
read: newAddressDecoder([
|
read: newAddressDecoder([
|
||||||
[0xc000, 0xdfff, 0x3ff, function(a) { return ram.mem[a]; }],
|
[0xc000, 0xffff, ramSize-1, function(a) { return ram.mem[a]; }],
|
||||||
[0x0000, 0xbfff, 0xffff, function(a) { return rom ? rom[a] : 0; }],
|
[0x0000, 0xbfff, 0xffff, function(a) { return rom ? rom[a] : 0; }],
|
||||||
]),
|
]),
|
||||||
write: newAddressDecoder([
|
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; },
|
isContended: function() { return false; },
|
||||||
};
|
};
|
||||||
iobus = {
|
iobus = {
|
||||||
read: function(addr) {
|
read: (addr:number) => {
|
||||||
addr &= 0xff;
|
addr &= 0xff;
|
||||||
//console.log('IO read', hex(addr,4));
|
//console.log('IO read', hex(addr,4));
|
||||||
switch (addr & 0xc1) {
|
switch (addr & 0xc1) {
|
||||||
|
case 0x40: return isSMS ? this.currentScanline : 0;
|
||||||
case 0x80: return vdp.readData();
|
case 0x80: return vdp.readData();
|
||||||
case 0x81: return vdp.readStatus();
|
case 0x81: return vdp.readStatus();
|
||||||
case 0xc0: return inputs[0] ^ 0xff;
|
case 0xc0: return inputs[0] ^ 0xff;
|
||||||
@ -92,7 +94,7 @@ const _SG1000Platform = function(mainElement) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
write: function(addr, val) {
|
write: (addr:number, val:number) => {
|
||||||
addr &= 0xff;
|
addr &= 0xff;
|
||||||
val &= 0xff;
|
val &= 0xff;
|
||||||
//console.log('IO write', hex(addr,4), hex(val,2));
|
//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);
|
setKeyboardFromMap(video, inputs, SG1000_KEYCODE_MAP);
|
||||||
timer = new AnimationTimer(60, this.nextFrame.bind(this));
|
timer = new AnimationTimer(60, this.nextFrame.bind(this));
|
||||||
}
|
}
|
||||||
@ -129,6 +132,7 @@ const _SG1000Platform = function(mainElement) {
|
|||||||
|
|
||||||
advance(novideo : boolean) {
|
advance(novideo : boolean) {
|
||||||
for (var sl=0; sl<numTotalScanlines; sl++) {
|
for (var sl=0; sl<numTotalScanlines; sl++) {
|
||||||
|
this.currentScanline = sl;
|
||||||
this.runCPU(cpu, cpuCyclesPerLine);
|
this.runCPU(cpu, cpuCyclesPerLine);
|
||||||
if (sl < numVisibleScanlines)
|
if (sl < numVisibleScanlines)
|
||||||
vdp.drawScanline(sl);
|
vdp.drawScanline(sl);
|
||||||
@ -156,15 +160,11 @@ const _SG1000Platform = function(mainElement) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
loadControlsState(state) {
|
loadControlsState(state) {
|
||||||
inputs[0] = state.in0;
|
inputs.set(state.in);
|
||||||
inputs[1] = state.in1;
|
|
||||||
inputs[2] = state.in2;
|
|
||||||
}
|
}
|
||||||
saveControlsState() {
|
saveControlsState() {
|
||||||
return {
|
return {
|
||||||
in0:inputs[0],
|
in:inputs.slice(0)
|
||||||
in1:inputs[1],
|
|
||||||
in2:inputs[2],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
getCPUState() {
|
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-sg1000-libcv'] = _SG1000Platform;
|
||||||
|
PLATFORMS['sms-sms-libcv'] = _SMSPlatform;
|
||||||
|
@ -356,7 +356,78 @@ export class TMS9918A {
|
|||||||
updateCanvas() {
|
updateCanvas() {
|
||||||
this.canvasContext.putImageData(this.imageData, 0, 0);
|
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) {
|
writeAddress(i:number) {
|
||||||
if (!this.latch) {
|
if (!this.latch) {
|
||||||
this.addressRegister = (this.addressRegister & 0xFF00) | i;
|
this.addressRegister = (this.addressRegister & 0xFF00) | i;
|
||||||
@ -365,70 +436,18 @@ export class TMS9918A {
|
|||||||
switch ((i & 0xc0) >> 6) {
|
switch ((i & 0xc0) >> 6) {
|
||||||
// Set read address
|
// Set read address
|
||||||
case 0:
|
case 0:
|
||||||
this.addressRegister = ((i & 0x3f) << 8) | (this.addressRegister & 0x00FF);
|
this.setReadAddress(i);
|
||||||
this.prefetchByte = this.ram[this.addressRegister++];
|
|
||||||
this.addressRegister &= 0x3FFF;
|
|
||||||
break;
|
break;
|
||||||
// Set write address
|
// Set write address
|
||||||
case 1:
|
case 1:
|
||||||
this.addressRegister = ((i & 0x3f) << 8) | (this.addressRegister & 0x00FF);
|
this.setWriteAddress(i);
|
||||||
break;
|
break;
|
||||||
// Write register
|
// Write register
|
||||||
case 2:
|
case 2:
|
||||||
|
this.setVDPWriteRegister(i);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
this.registers[i & 0x7] = this.addressRegister & 0x00FF;
|
this.setVDPWriteCommand3(i);
|
||||||
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());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.redrawRequired = true;
|
this.redrawRequired = true;
|
||||||
@ -579,7 +598,7 @@ export class TMS9918A {
|
|||||||
s += lpad("Screen Mode",w) + ": " + this.screenMode + "\n";
|
s += lpad("Screen Mode",w) + ": " + this.screenMode + "\n";
|
||||||
s += lpad("Display On",w) + ": " + this.displayOn + "\n";
|
s += lpad("Display On",w) + ": " + this.displayOn + "\n";
|
||||||
if (this.ramMask != 0x3fff)
|
if (this.ramMask != 0x3fff)
|
||||||
s += lpad("RAM Mask",w) + ": " + this.ramMask + "\n";
|
s += lpad("RAM Mask",w) + ": $" + hex(this.ramMask) + "\n";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,8 +647,8 @@ export class TMS9918A {
|
|||||||
|
|
||||||
getState() {
|
getState() {
|
||||||
return {
|
return {
|
||||||
ram: this.ram,
|
ram: this.ram.slice(0),
|
||||||
registers: this.registers,
|
registers: this.registers.slice(0),
|
||||||
addressRegister: this.addressRegister,
|
addressRegister: this.addressRegister,
|
||||||
statusRegister: this.statusRegister,
|
statusRegister: this.statusRegister,
|
||||||
latch: this.latch,
|
latch: this.latch,
|
||||||
@ -654,8 +673,8 @@ export class TMS9918A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
restoreState(state) {
|
restoreState(state) {
|
||||||
this.ram = state.ram;
|
this.ram.set(state.ram);
|
||||||
this.registers = state.registers;
|
this.registers.set(state.registers);
|
||||||
this.addressRegister = state.addressRegister;
|
this.addressRegister = state.addressRegister;
|
||||||
this.statusRegister = state.statusRegister;
|
this.statusRegister = state.statusRegister;
|
||||||
this.latch = state.latch;
|
this.latch = state.latch;
|
||||||
@ -679,3 +698,45 @@ export class TMS9918A {
|
|||||||
this.redrawRequired = true;
|
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['coleco.mame'] = PLATFORM_PARAMS['coleco'];
|
||||||
|
PLATFORM_PARAMS['sms-sms-libcv'] = PLATFORM_PARAMS['sms-sg1000-libcv'];
|
||||||
|
|
||||||
var _t1;
|
var _t1;
|
||||||
function starttime() { _t1 = new Date(); }
|
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 _astrocade = require('gen/platform/astrocade.js');
|
||||||
var _atari8 = require('gen/platform/atari8.js');
|
var _atari8 = require('gen/platform/atari8.js');
|
||||||
var _coleco = require('gen/platform/coleco.js');
|
var _coleco = require('gen/platform/coleco.js');
|
||||||
|
var _sms = require('gen/platform/sms.js');
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -59,16 +60,26 @@ global.navigator = {};
|
|||||||
var keycallback;
|
var keycallback;
|
||||||
|
|
||||||
emu.RasterVideo = function(mainElement, width, height, options) {
|
emu.RasterVideo = function(mainElement, width, height, options) {
|
||||||
|
var buffer;
|
||||||
|
var datau8;
|
||||||
var datau32;
|
var datau32;
|
||||||
this.create = function() {
|
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) {
|
this.setKeyboardEvents = function(callback) {
|
||||||
keycallback = callback;
|
keycallback = callback;
|
||||||
}
|
}
|
||||||
this.getFrameData = function() { return datau32; }
|
this.getFrameData = function() { return datau32; }
|
||||||
|
this.getImageData = function() { return {data:datau8, width:width, height:height}; }
|
||||||
this.updateFrame = function() {}
|
this.updateFrame = function() {}
|
||||||
this.setupMouseEvents = 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) {
|
emu.VectorVideo = function(mainElement, width, height, options) {
|
||||||
@ -224,7 +235,6 @@ describe('Platform Replay', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
it('Should run coleco', () => {
|
it('Should run coleco', () => {
|
||||||
var platform = testPlatform('coleco', 'shoot.c.rom', 92, (platform, frameno) => {
|
var platform = testPlatform('coleco', 'shoot.c.rom', 92, (platform, frameno) => {
|
||||||
if (frameno == 62) {
|
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
|
/* TODO
|
||||||
it('Should run atari8-5200', () => {
|
it('Should run atari8-5200', () => {
|
||||||
var platform = testPlatform('atari8-5200', 'hello.a.rom', 92, (platform, frameno) => {
|
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