From c0f97458aa9e0026543fa1133ee4cdbc28c0d74a Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Fri, 30 Nov 2018 12:37:00 -0500 Subject: [PATCH] started on SMS; got rid of BaseFrameBasedPlatform; more tests --- package.json | 1 + presets/sms-sms-libcv/fonts.s | 109 +++++++++++++++ src/baseplatform.ts | 34 +++-- src/platform/coleco.ts | 10 +- src/platform/msx.ts | 2 - src/platform/sms.ts | 41 +++--- src/video/tms9918a.ts | 185 ++++++++++++++++--------- src/worker/lib/sms-sms-libcv | 1 + src/worker/workermain.ts | 1 + test/cli/testplatforms.js | 22 ++- test/roms/atari8-5200/hello.a.rom | Bin 0 -> 32768 bytes test/roms/sms-sg1000-libcv/shoot.c.rom | Bin 0 -> 49152 bytes 12 files changed, 296 insertions(+), 110 deletions(-) create mode 100644 presets/sms-sms-libcv/fonts.s create mode 120000 src/worker/lib/sms-sms-libcv create mode 100644 test/roms/atari8-5200/hello.a.rom create mode 100644 test/roms/sms-sg1000-libcv/shoot.c.rom diff --git a/package.json b/package.json index e444aa24..c40533b6 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/presets/sms-sms-libcv/fonts.s b/presets/sms-sms-libcv/fonts.s new file mode 100644 index 00000000..5cbf0f5c --- /dev/null +++ b/presets/sms-sms-libcv/fonts.s @@ -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 +;; diff --git a/src/baseplatform.ts b/src/baseplatform.ts index 13e8f8e9..70108c72 100644 --- a/src/baseplatform.ts +++ b/src/baseplatform.ts @@ -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(); diff --git a/src/platform/coleco.ts b/src/platform/coleco.ts index 63b66ea3..6c73fa6a 100644 --- a/src/platform/coleco.ts +++ b/src/platform/coleco.ts @@ -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() { diff --git a/src/platform/msx.ts b/src/platform/msx.ts index 1711efc4..9f2ae592 100644 --- a/src/platform/msx.ts +++ b/src/platform/msx.ts @@ -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); diff --git a/src/platform/sms.ts b/src/platform/sms.ts index f68cb6b1..b38e5269 100644 --- a/src/platform/sms.ts +++ b/src/platform/sms.ts @@ -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> 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); + } +}; + diff --git a/src/worker/lib/sms-sms-libcv b/src/worker/lib/sms-sms-libcv new file mode 120000 index 00000000..2e185fd2 --- /dev/null +++ b/src/worker/lib/sms-sms-libcv @@ -0,0 +1 @@ +sms-sg1000-libcv \ No newline at end of file diff --git a/src/worker/workermain.ts b/src/worker/workermain.ts index 693df21e..e1075ea0 100644 --- a/src/worker/workermain.ts +++ b/src/worker/workermain.ts @@ -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(); } diff --git a/test/cli/testplatforms.js b/test/cli/testplatforms.js index 47655638..2b4f4882 100644 --- a/test/cli/testplatforms.js +++ b/test/cli/testplatforms.js @@ -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) => { diff --git a/test/roms/atari8-5200/hello.a.rom b/test/roms/atari8-5200/hello.a.rom new file mode 100644 index 0000000000000000000000000000000000000000..fcc0814eff837fbb4f722c95e7116aaafe298301 GIT binary patch literal 32768 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%0D*86LjX85!o|FWHpRv zGPBGsO@<=xzIl8_Sn*$c(=&AP;+w0&%CP%)msY9Dl+8yC#C5V~6mP9o1|jjgzjQg? z{Uzcbi|<|S(4mu`?xD0SfvL6Tw9rpiCQqLx@1E{i05U%Va+x%n=e~X^Z6L8bE7gul z!)ju8(`PnOc-6@4TgT+U7=r};T|7NXrwT92s#~gqmpd>y`KSHEwWi|f*Gs}5RgB_S zy@a7h;NqKuA9@Wv!sbf-k}-gKH|rgC8L%IHY`}iBWAKM%gEM7ywpU*6Ir`FL(S5bH zR}Oa_{l|{jOXbOTT8&))XxZg=jK_})AY}yj7ZUbYmbgFqm<(x>ALy5U{`+_4uDyT8 z;wUmZ>#bs)$znFq%W^Pw`shhzXh`u6(M#F>df>*_s1chiRugW-Z2YD>q)fb{C_}Ff zd67r|%@)?)Znx0d$WvJRi3!xAY5c}mAXrOoHxu^5AR*$J+r;;OJ1UVg7FrA$h?q-q z1pIpCrPWn85sJy}A`ui55hQXOer+-nulaWTx?~d9kpeRGq8nSlH=ZVc zWt7aMO{S{CB8yp|KY)?mbq`#9^Xm2M*RMiOh%X2hv)yjC2!a`DvRo-s9PRC|fVPTHdVs|?27HdvnA+o$~x8j|c@G5S%m)59uOHSK< z_!~P-5km1!O#JlMziw}D^Rk@(L;tIoKr|^8mZvRHGA*a+9&*r|%a_X(qZt=3`hkch%*Otkt=xMj( zGA%gm7Cc_;x%H`fsCJq1M1ULasfD_;ZH~~(86W|0m0ZxDu-~>1UPJk2O1ULas zfD_;ZH~~(86W|0m0ZxDu-~>1UPJk2O1ULasfD_;ZH~~(86W|0m0ZxDu-~>1UPJk2O z1ULasfD_;ZH~~(86W|0m0ZxDu-~>1UPJk2O1ULasfD_;ZH~~(86W|0m0ZxDu-~>1U zPJk2O1ULasfD_;ZH~~(86W|0m0ZxDu-~>1UPJk2O1ULasfD_;ZH~~(86W|0m0ZxDu z-~>1UPJk2O1ULasfD_;ZH~~(86W|0m0ZxDu-~>1UPJk2O1ULasfD_;ZH~~(86W|0m q0ZxDu-~>1UPJk2O1ULasfD_;ZH~~(86W|0m0ZxDu-~|4k5cprG6@Eql literal 0 HcmV?d00001