VCS now supports replay; can test too

This commit is contained in:
Steven Hugg 2018-08-23 18:27:07 -04:00
parent 1ba3d621ce
commit caf56e14e3
7 changed files with 63 additions and 10 deletions

View File

@ -56,6 +56,7 @@ TODO:
- intro/help text for each platform - intro/help text for each platform
- make sure controls work with replay feature (we'll have to save control state every frame) - make sure controls work with replay feature (we'll have to save control state every frame)
- vscode/atom extension? - vscode/atom extension?
- navigator.getGamepads
FYI: Image links for the books on http://8bitworkshop.com/ are broken FYI: Image links for the books on http://8bitworkshop.com/ are broken
On the website the additional grey spacing next to the program line numbers is not dynamically resized when the web browser window size is changed. Intentional? On the website the additional grey spacing next to the program line numbers is not dynamically resized when the web browser window size is changed. Intentional?

@ -1 +1 @@
Subproject commit 500c33f4e8b854ddacaa588c47c23983feb27c24 Subproject commit 67d15ccb4940c0049fcd6444a72316148056e5b3

12
package-lock.json generated
View File

@ -85,6 +85,12 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true "dev": true
}, },
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
"aws-sign2": { "aws-sign2": {
"version": "0.7.0", "version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@ -129,6 +135,12 @@
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
"dev": true "dev": true
}, },
"btoa": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
"integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==",
"dev": true
},
"caseless": { "caseless": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",

View File

@ -6,6 +6,8 @@
"devDependencies": { "devDependencies": {
"@types/bootstrap": "^3.x", "@types/bootstrap": "^3.x",
"@types/jquery": "^2.x", "@types/jquery": "^2.x",
"atob": "^2.1.2",
"btoa": "^1.2.1",
"heapdump": "^0.3.9", "heapdump": "^0.3.9",
"jsdom": "^12.0.0", "jsdom": "^12.0.0",
"mocha": "^5.2.0", "mocha": "^5.2.0",

View File

@ -62,8 +62,8 @@ class VCSPlatform {
// intercept clockPulse function // intercept clockPulse function
Javatari.room.console.oldClockPulse = Javatari.room.console.clockPulse; Javatari.room.console.oldClockPulse = Javatari.room.console.clockPulse;
Javatari.room.console.clockPulse = function() { Javatari.room.console.clockPulse = function() {
this.oldClockPulse();
self.updateRecorder(); self.updateRecorder();
this.oldClockPulse();
} }
this.paused = false; this.paused = false;
} }
@ -109,6 +109,10 @@ class VCSPlatform {
advance() { advance() {
Javatari.room.console.clockPulse(); Javatari.room.console.clockPulse();
} }
// for unit test
nextFrame() {
Javatari.room.console.clockPulse();
}
step() { Javatari.room.console.debugSingleStepCPUClock(); } step() { Javatari.room.console.debugSingleStepCPUClock(); }
stepBack() { Javatari.room.console.debugStepBackInstruction(); } stepBack() { Javatari.room.console.debugStepBackInstruction(); }
@ -145,6 +149,12 @@ class VCSPlatform {
loadState(state) { loadState(state) {
return Javatari.room.console.loadState(state); return Javatari.room.console.loadState(state);
} }
saveControlsState() {
return Javatari.room.console.saveControlsState();
}
loadControlsState(state) {
Javatari.room.console.loadControlsState(state);
}
// TODO: load/save controls state // TODO: load/save controls state
readAddress(addr) { readAddress(addr) {
return this.current_output[addr & 0xfff]; // TODO: use bus to read return this.current_output[addr & 0xfff]; // TODO: use bus to read

View File

@ -8,12 +8,14 @@ const jsdom = require('jsdom');
const { JSDOM } = jsdom; const { JSDOM } = jsdom;
const { window } = new JSDOM(); const { window } = new JSDOM();
const dom = new JSDOM(`<!DOCTYPE html><div id="emulator"></div>`); const dom = new JSDOM(`<!DOCTYPE html><div id="emulator"><div id="javatari-screen"></div></div>`);
global.window = dom.window; global.window = dom.window;
global.document = dom.window.document; global.document = dom.window.document;
dom.window.Audio = null; dom.window.Audio = null;
global.Image = function() { } global.Image = function() { }
global.btoa = require('btoa');
global.atob = require('atob');
global['$'] = require("jquery/jquery-2.2.3.min.js");
includeInThisContext("javatari.js/release/javatari/javatari.js"); includeInThisContext("javatari.js/release/javatari/javatari.js");
Javatari.AUTO_START = false; Javatari.AUTO_START = false;
includeInThisContext('src/cpu/z80fast.js'); includeInThisContext('src/cpu/z80fast.js');
@ -28,17 +30,31 @@ var jsnes = require("jsnes/jsnes.min.js");
var emu = require('gen/emu.js'); var emu = require('gen/emu.js');
var audio = require('gen/audio.js'); var audio = require('gen/audio.js');
var recorder = require('gen/recorder.js'); var recorder = require('gen/recorder.js');
var vicdual = require('gen/platform/vicdual.js'); var _vicdual = require('gen/platform/vicdual.js');
var apple2 = require('gen/platform/apple2.js'); var _apple2 = require('gen/platform/apple2.js');
var _vcs = require('gen/platform/vcs.js');
// //
dom.window.HTMLCanvasElement.prototype.getContext = function() {
return {
getImageData: function(x,y,w,h) { return {data: new Uint32Array(w*h) }; },
fillRect: function(x,y,w,h) { },
drawImage: function(img,x,y,w,h) { },
putImageData: function(data,w,h) { }
};
}
global.navigator = {};
var keycallback;
emu.RasterVideo = function(mainElement, width, height, options) { emu.RasterVideo = function(mainElement, width, height, options) {
var datau32; var datau32;
this.create = function() { this.create = function() {
datau32 = new Uint32Array(width*height); datau32 = new Uint32Array(width*height);
} }
this.setKeyboardEvents = function(callback) { this.setKeyboardEvents = function(callback) {
keycallback = callback;
} }
this.getFrameData = function() { return datau32; } this.getFrameData = function() { return datau32; }
this.updateFrame = function() { } this.updateFrame = function() { }
@ -53,7 +69,7 @@ function testPlatform(platid, romname, maxframes, callback) {
platform.start(); platform.start();
var rom = fs.readFileSync('./test/roms/' + platid + '/' + romname); var rom = fs.readFileSync('./test/roms/' + platid + '/' + romname);
rom = new Uint8Array(rom); rom = new Uint8Array(rom);
platform.loadROM(rom); platform.loadROM("ROM", rom);
platform.resume(); // so that recorder works platform.resume(); // so that recorder works
platform.setRecorder(rec); platform.setRecorder(rec);
for (var i=0; i<maxframes; i++) { for (var i=0; i<maxframes; i++) {
@ -71,14 +87,26 @@ function testPlatform(platid, romname, maxframes, callback) {
} }
describe('Platform Replay', () => { describe('Platform Replay', () => {
it('Should run apple2', () => { it('Should run apple2', () => {
var platform = testPlatform('apple2', 'cosmic.c.rom', 70, (platform, frameno) => { var platform = testPlatform('apple2', 'cosmic.c.rom', 70, (platform, frameno) => {
if (frameno == 60) { if (frameno == 60) {
var cstate = platform.saveControlsState(); keycallback(32, 32, 1); // space bar
cstate.kbd = 0x80 | 0x20;
platform.loadControlsState(cstate);
} }
}); });
assert.equal(platform.saveState().kbd, 0x20); // strobe cleared assert.equal(platform.saveState().kbd, 0x20); // strobe cleared
}); });
it('Should run vcs', () => {
var platform = testPlatform('vcs', 'brickgame.rom', 70, (platform, frameno) => {
if (frameno == 60) {
var cstate = platform.saveControlsState();
cstate.SA = 0xff ^ 0x40; // stick left
platform.loadControlsState(cstate);
}
});
assert.equal(platform.saveState().p.SA, 0xff ^ 0x40);
});
}); });

BIN
test/roms/vcs/brickgame.rom Normal file

Binary file not shown.