1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-28 08:41:30 +00:00

testplatforms writes PNG files to test/output; fixed astrocade minimal bios

This commit is contained in:
Steven Hugg 2018-12-01 15:00:17 -05:00
parent 4f0003fe76
commit 65a284388d
5 changed files with 57 additions and 16 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ blog
local local
release release
gen gen
test/output

View File

@ -14,6 +14,7 @@
"jsdom": "^12.0.x", "jsdom": "^12.0.x",
"lzg": "^1.0.x", "lzg": "^1.0.x",
"mocha": "^5.2.x", "mocha": "^5.2.x",
"pngjs": "^3.3.3",
"typescript": "^3.x", "typescript": "^3.x",
"wavedrom-cli": "^0.5.x" "wavedrom-cli": "^0.5.x"
}, },

View File

@ -5,6 +5,8 @@ import { PLATFORMS, RAM, newAddressDecoder, padBytes, noise, setKeyboardFromMap,
import { hex, lzgmini, stringToByteArray, rgb2bgr, clamp } from "../util"; import { hex, lzgmini, stringToByteArray, rgb2bgr, clamp } from "../util";
import { MasterAudio, AY38910_Audio } from "../audio"; import { MasterAudio, AY38910_Audio } from "../audio";
// http://metopal.com/projects/ballybook/doku.php
const ASTROCADE_PRESETS = [ const ASTROCADE_PRESETS = [
{id:'01-helloworlds.asm', name:'Hello World'}, {id:'01-helloworlds.asm', name:'Hello World'},
{id:'02-telephone.asm', name:'Telephone'}, {id:'02-telephone.asm', name:'Telephone'},
@ -86,14 +88,14 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
// default palette // default palette
for (var i=0; i<8; i++) for (var i=0; i<8; i++)
palette[i] = ASTROCADE_PALETTE[i]; palette[i] = ASTROCADE_PALETTE[i];
var refreshlines = 0; var refreshlines = 0;
function ramwrite(a:number, v:number) { function ramwrite(a:number, v:number) {
ram.mem[a] = v; ram.mem[a] = v;
ramupdate(a, v); ramupdate(a, v);
} }
function ramupdate(a:number, v:number) { function ramupdate(a:number, v:number) {
var ofs = a*4+3; // 4 pixels per byte var ofs = a*4+3; // 4 pixels per byte
for (var i=0; i<4; i++) { for (var i=0; i<4; i++) {
@ -102,13 +104,13 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
v >>= 2; v >>= 2;
} }
} }
function refreshline(y:number) { function refreshline(y:number) {
var ofs = y*swidth/4; var ofs = y*swidth/4;
for (var i=0; i<swidth/4; i++) for (var i=0; i<swidth/4; i++)
ramupdate(ofs+i, ram.mem[ofs+i]); ramupdate(ofs+i, ram.mem[ofs+i]);
} }
function magicwrite(a:number, v:number) { function magicwrite(a:number, v:number) {
// expand // expand
if (magicop & 0x8) { if (magicop & 0x8) {
@ -158,21 +160,21 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
// commit write to ram/screen // commit write to ram/screen
ramwrite(a, v); ramwrite(a, v);
} }
function setpalette(a:number, v:number) { function setpalette(a:number, v:number) {
palette[a&7] = ASTROCADE_PALETTE[v&0xff]; palette[a&7] = ASTROCADE_PALETTE[v&0xff];
refreshall(); refreshall();
} }
function setbordercolor() { function setbordercolor() {
var col = horcb >> 6; var col = horcb >> 6;
// TODO // TODO
} }
function refreshall() { function refreshall() {
refreshlines = sheight; refreshlines = sheight;
} }
class BallyAstrocadePlatform extends BaseZ80Platform implements Platform { class BallyAstrocadePlatform extends BaseZ80Platform implements Platform {
getPresets() { getPresets() {
@ -185,7 +187,7 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
if (lzgrom) if (lzgrom)
bios = new lzgmini().decode(stringToByteArray(atob(lzgrom))); bios = new lzgmini().decode(stringToByteArray(atob(lzgrom)));
else else
bios = padBytes([0xf3, 0x31, 0x00, 0x50, 0x21, 0x05, 0x20, 0x7e, 0x23, 0x66, 0x6f, 0xe9], 0x2000); // SP=$5000, jump to ($2005) bios = padBytes(ASTROCADE_MINIMAL_BIOS, 0x2000);
if (!arcade) { if (!arcade) {
// game console // game console
membus = { membus = {
@ -302,12 +304,12 @@ const _BallyAstrocadePlatform = function(mainElement, arcade) {
readAddress(addr) { readAddress(addr) {
return membus.read(addr); return membus.read(addr);
} }
loadControls() { loadControls() {
inputs[0x1c] = video.paddle_x & 0xff; inputs[0x1c] = video.paddle_x & 0xff;
inputs[0x1d] = video.paddle_y & 0xff; inputs[0x1d] = video.paddle_y & 0xff;
} }
advance(novideo : boolean) { advance(novideo : boolean) {
this.loadControls(); this.loadControls();
for (var sl=0; sl<sheight; sl++) { for (var sl=0; sl<sheight; sl++) {
@ -472,4 +474,27 @@ for (var i=0; i<256; i++) {
ASTROCADE_PALETTE[i] = rgb2bgr(x) | 0xff000000; ASTROCADE_PALETTE[i] = rgb2bgr(x) | 0xff000000;
} }
/*
0000 F3 [ 4] 196 DI ; disable interrupts
0001 21 00 20 [10] 197 LD HL,#0x2000
0004 7E [ 7] 198 LD A,(HL) ; A <- mem[0x2000]
0005 FE 55 [ 7] 199 CP #0x55 ; found sentinel byte? ($55)
0007 CA 0D 00 [10] 200 JP Z,FoundSentinel ; yes, load program
000A C3 AB 0E [10] 201 JP _main ; jump to test program
000D 202 FoundSentinel:
000D 31 CE 4F [10] 203 LD SP,#0x4fce ; position stack below BIOS vars
0010 CD 84 02 [17] 204 CALL _bios_init ; misc. bios init routines
0013 21 05 20 [10] 205 LD HL,#0x2005 ; cartridge start vector
0016 7E [ 7] 206 LD A,(HL)
0017 23 [ 6] 207 INC HL
0018 66 [ 7] 208 LD H,(HL)
0019 6F [ 4] 209 LD L,A
001A E9 [ 4] 210 JP (HL) ; jump to cart start vector
*/
var ASTROCADE_MINIMAL_BIOS = [
0xf3, 0x21, 0x00, 0x20, 0x7e, 0xfe, 0x55, 0xca, 0x0d, 0x00, 0xc3, 0xab, 0x0e,
0x31, 0xce, 0x4f, 0xcd, 0x84, 0x02, 0x21, 0x05, 0x20, 0x7e, 0x23, 0x66, 0x6f,
0xe9,
];
//var ASTROCADE_BIOS_LZG = decodeURIComponent(); //var ASTROCADE_BIOS_LZG = decodeURIComponent();

View File

@ -96,7 +96,7 @@ const _VicDualPlatform = function(mainElement) {
[Keys.VK_2, 3, -0x20], [Keys.VK_2, 3, -0x20],
[Keys.VK_5, 3, 0x8], [Keys.VK_5, 3, 0x8],
]); ]);
class VicDualPlatform extends BaseZ80Platform implements Platform { class VicDualPlatform extends BaseZ80Platform implements Platform {
getPresets() { getPresets() {

View File

@ -2,7 +2,7 @@
var assert = require('assert'); var assert = require('assert');
var fs = require('fs'); var fs = require('fs');
var wtu = require('./workertestutils.js'); var wtu = require('./workertestutils.js');
global.includeInThisContext('src/cpu/z80fast.js'); var PNG = require('pngjs').PNG;
const jsdom = require('jsdom'); const jsdom = require('jsdom');
const { JSDOM } = jsdom; const { JSDOM } = jsdom;
@ -16,6 +16,7 @@ global.Image = function() { }
global.btoa = require('btoa'); global.btoa = require('btoa');
global.atob = require('atob'); global.atob = require('atob');
global['$'] = require("jquery/jquery-2.2.3.min.js"); global['$'] = require("jquery/jquery-2.2.3.min.js");
global.includeInThisContext('src/cpu/z80fast.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');
@ -58,15 +59,19 @@ dom.window.HTMLCanvasElement.prototype.getContext = function() {
global.navigator = {}; global.navigator = {};
var keycallback; var keycallback;
var lastrastervideo;
emu.RasterVideo = function(mainElement, width, height, options) { emu.RasterVideo = function(mainElement, width, height, options) {
var buffer; var buffer;
var datau8; var datau8;
var datau32; var datau32;
this.create = function() { this.create = function() {
this.width = width;
this.height = height;
buffer = new ArrayBuffer(width*height*4); buffer = new ArrayBuffer(width*height*4);
datau8 = new Uint8Array(buffer); datau8 = new Uint8Array(buffer);
datau32 = new Uint32Array(buffer); datau32 = new Uint32Array(buffer);
lastrastervideo = this;
} }
this.setKeyboardEvents = function(callback) { this.setKeyboardEvents = function(callback) {
keycallback = callback; keycallback = callback;
@ -137,6 +142,17 @@ function testPlatform(platid, romname, maxframes, callback) {
assert.ok(dinfo.length < 80*24, dcat + " too long"); assert.ok(dinfo.length < 80*24, dcat + " too long");
assert.ok(dinfo.indexOf('undefined') < 0, dcat + " undefined"); assert.ok(dinfo.indexOf('undefined') < 0, dcat + " undefined");
} }
if (lastrastervideo) {
var png = new PNG({width:lastrastervideo.width, height:lastrastervideo.height});
png.data = lastrastervideo.getImageData().data;
var pngbuffer = PNG.sync.write(png);
assert(pngbuffer.length > 500); // make sure PNG is big enough
try { fs.mkdirSync("./test"); } catch(e) { }
try { fs.mkdirSync("./test/output"); } catch(e) { }
try {
fs.writeFileSync("./test/output/"+platid+"-"+romname+".png", pngbuffer);
} catch (e) { console.log(e) }
}
return platform; return platform;
} }
@ -259,5 +275,3 @@ describe('Platform Replay', () => {
}); });
*/ */
}); });