mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-06-12 03:29:31 +00:00
refactoring; xasm6809
This commit is contained in:
parent
f696f22b5a
commit
a82accf060
|
@ -193,7 +193,7 @@ canvas.pixelated {
|
||||||
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
|
<li><a class="dropdown-item" href="?platform=vcs" id="item_platform_vcs">Atari VCS</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
|
<li><a class="dropdown-item" href="?platform=apple2" id="item_platform_apple2">Apple ][</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
|
<li><a class="dropdown-item" href="?platform=atarivec" id="item_platform_atarivec">Asteroids</a></li>
|
||||||
<li><a class="dropdown-item" href="?platform=spaceinv" id="item_platform_spaceinv">Space Invaders</a></li>
|
<li><a class="dropdown-item" href="?platform=mw8080bw" id="item_platform_mw8080bw">Midway 8080 B/W</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run test-node && npm run test-browser",
|
"test": "npm run test-node && npm run test-browser",
|
||||||
"test-node": "mocha --recursive test/cli",
|
"test-node": "mocha --recursive --timeout 5000 test/cli",
|
||||||
"test-browser": "mocha-phantomjs ./testemu.html"
|
"test-browser": "mocha-phantomjs ./testemu.html"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
45
src/emu.js
45
src/emu.js
|
@ -8,10 +8,6 @@ function noise() {
|
||||||
return (Math.random() * 256) & 0xff;
|
return (Math.random() * 256) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _metakeyflags(e) {
|
|
||||||
return (e.shiftKey?2:0) | (e.ctrlKey?4:0) | (e.altKey?8:0) | (e.metaKey?16:0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function __createCanvas(mainElement, width, height) {
|
function __createCanvas(mainElement, width, height) {
|
||||||
// TODO
|
// TODO
|
||||||
var fsElement = document.createElement('div');
|
var fsElement = document.createElement('div');
|
||||||
|
@ -55,6 +51,7 @@ var RasterVideo = function(mainElement, width, height, options) {
|
||||||
datau32 = new Uint32Array(buf);
|
datau32 = new Uint32Array(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: make common
|
||||||
this.setKeyboardEvents = function(callback) {
|
this.setKeyboardEvents = function(callback) {
|
||||||
canvas.onkeydown = function(e) {
|
canvas.onkeydown = function(e) {
|
||||||
callback(e.which, 0, 1|_metakeyflags(e));
|
callback(e.which, 0, 1|_metakeyflags(e));
|
||||||
|
@ -131,7 +128,7 @@ var VectorVideo = function(mainElement, width, height) {
|
||||||
var persistenceAlpha = 0.5;
|
var persistenceAlpha = 0.5;
|
||||||
var jitter = 1.0;
|
var jitter = 1.0;
|
||||||
|
|
||||||
this.start = function() {
|
this.create = function() {
|
||||||
canvas = __createCanvas(mainElement, width, height);
|
canvas = __createCanvas(mainElement, width, height);
|
||||||
ctx = canvas.getContext('2d');
|
ctx = canvas.getContext('2d');
|
||||||
}
|
}
|
||||||
|
@ -666,7 +663,7 @@ var Base6809Platform = function() {
|
||||||
// TODO: 6809 opcodes
|
// TODO: 6809 opcodes
|
||||||
if (op == 0x9d || op == 0xad || op == 0xbd) // CALL
|
if (op == 0x9d || op == 0xad || op == 0xbd) // CALL
|
||||||
depth++;
|
depth++;
|
||||||
else if (op == 0x3b || op == 0x39) // RET (TODO?)
|
else if (op == 0x3b || op == 0x39) // RET
|
||||||
--depth;
|
--depth;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -675,11 +672,8 @@ var Base6809Platform = function() {
|
||||||
return cpuStateToLongString_6809(c);
|
return cpuStateToLongString_6809(c);
|
||||||
}
|
}
|
||||||
this.getToolForFilename = function(fn) {
|
this.getToolForFilename = function(fn) {
|
||||||
if (fn.endsWith(".c")) return "sdcc";
|
return "xasm6809";
|
||||||
if (fn.endsWith(".s")) return "sdasz80";
|
|
||||||
return "z80asm";
|
|
||||||
}
|
}
|
||||||
// TODO
|
|
||||||
this.disassemble = function(pc, read) {
|
this.disassemble = function(pc, read) {
|
||||||
// TODO: don't create new CPU
|
// TODO: don't create new CPU
|
||||||
return new CPU6809().disasm(read(pc), read(pc+1), read(pc+2), read(pc+3), read(pc+4), pc);
|
return new CPU6809().disasm(read(pc), read(pc+1), read(pc+2), read(pc+3), read(pc+4), pc);
|
||||||
|
@ -794,6 +788,32 @@ var Keys = {
|
||||||
VK_NUMPAD_CENTER: {c: 12, n: "Num Cntr"}
|
VK_NUMPAD_CENTER: {c: 12, n: "Num Cntr"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function _metakeyflags(e) {
|
||||||
|
return (e.shiftKey?2:0) | (e.ctrlKey?4:0) | (e.altKey?8:0) | (e.metaKey?16:0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setKeyboardFromMap(video, switches, map, func) {
|
||||||
|
video.setKeyboardEvents(function(key,code,flags) {
|
||||||
|
var o = map[key];
|
||||||
|
if (o && func) {
|
||||||
|
func(o, key, code, flags);
|
||||||
|
}
|
||||||
|
if (o) {
|
||||||
|
//console.log(key,code,flags,o);
|
||||||
|
var mask = o.mask;
|
||||||
|
if (mask < 0) { // negative mask == active low
|
||||||
|
mask = -mask;
|
||||||
|
flags ^= 1;
|
||||||
|
}
|
||||||
|
if (flags & 1) {
|
||||||
|
switches[o.index] |= mask;
|
||||||
|
} else {
|
||||||
|
switches[o.index] &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function makeKeycodeMap(table) {
|
function makeKeycodeMap(table) {
|
||||||
var map = {};
|
var map = {};
|
||||||
for (var i=0; i<table.length; i++) {
|
for (var i=0; i<table.length; i++) {
|
||||||
|
@ -810,10 +830,13 @@ function padBytes(data, len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: better performance, check values
|
// TODO: better performance, check values
|
||||||
function AddressDecoder(table) {
|
function AddressDecoder(table, options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
function makeFunction(lo, hi) {
|
function makeFunction(lo, hi) {
|
||||||
var s = "";
|
var s = "";
|
||||||
|
if (options && options.gmask) {
|
||||||
|
s += "a&=" + options.gmask + ";";
|
||||||
|
}
|
||||||
for (var i=0; i<table.length; i++) {
|
for (var i=0; i<table.length; i++) {
|
||||||
var entry = table[i];
|
var entry = table[i];
|
||||||
var start = entry[0];
|
var start = entry[0];
|
||||||
|
|
|
@ -286,9 +286,6 @@ var Apple2Platform = function(mainElement) {
|
||||||
lc:{s:auxRAMselected,b:auxRAMbank,w:writeinhibit},
|
lc:{s:auxRAMselected,b:auxRAMbank,w:writeinhibit},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return ram.mem;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,19 @@ var AtariVectorPlatform = function(mainElement) {
|
||||||
|
|
||||||
this.__proto__ = new Base6502Platform();
|
this.__proto__ = new Base6502Platform();
|
||||||
|
|
||||||
|
var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([
|
||||||
|
[Keys.VK_SHIFT, 3, 0xff],
|
||||||
|
[Keys.VK_SPACE, 4, 0xff],
|
||||||
|
[Keys.VK_5, 8, 0xff],
|
||||||
|
[Keys.VK_6, 9, 0xff],
|
||||||
|
[Keys.VK_7, 10, 0xff],
|
||||||
|
[Keys.VK_1, 11, 0xff],
|
||||||
|
[Keys.VK_2, 12, 0xff],
|
||||||
|
[Keys.VK_UP, 13, 0xff],
|
||||||
|
[Keys.VK_RIGHT, 14, 0xff],
|
||||||
|
[Keys.VK_LEFT, 15, 0xff],
|
||||||
|
]);
|
||||||
|
|
||||||
this.getPresets = function() {
|
this.getPresets = function() {
|
||||||
return ATARIVEC_PRESETS;
|
return ATARIVEC_PRESETS;
|
||||||
}
|
}
|
||||||
|
@ -28,38 +41,24 @@ var AtariVectorPlatform = function(mainElement) {
|
||||||
//switches[7] = 0xff;
|
//switches[7] = 0xff;
|
||||||
// bus
|
// bus
|
||||||
bus = {
|
bus = {
|
||||||
read: function(address) {
|
|
||||||
address &= 0x7fff;
|
read: new AddressDecoder([
|
||||||
if (address >= 0x6800 && address <= 0x7fff) {
|
[0x0, 0x3ff, 0x3ff, function(a) { return cpuram.mem[a]; }],
|
||||||
return rom[address - 0x6800];
|
[0x2001, 0x2001, 0, function(a) { return ((clock/500) & 1) ? 0xff : 0x00; }],
|
||||||
} else if (address <= 0x3ff) {
|
[0x2000, 0x2007, 0x7, function(a) { return switches[a]; }],
|
||||||
return cpuram.mem[address];
|
[0x2400, 0x2407, 0x7, function(a) { return switches[a+8]; }],
|
||||||
} else if (address >= 0x5000 && address <= 0x5fff) {
|
[0x4000, 0x4fff, 0xfff, function(a) { return dvgram.mem[a]; }],
|
||||||
return vecrom[address - 0x5000];
|
[0x5000, 0x5fff, 0xfff, function(a) { return vecrom[a]; }],
|
||||||
} else if (address >= 0x4000 && address <= 0x5fff) {
|
[0x6800, 0x7fff, 0, function(a) { return rom[a - 0x6800]; }],
|
||||||
return dvgram.mem[address - 0x4000];
|
], {gmask:0x7fff}),
|
||||||
} else if (address >= 0x2000 && address <= 0x3fff) {
|
|
||||||
if (address == 0x2001)
|
write: new AddressDecoder([
|
||||||
return ((clock/500) & 1) ? 0xff : 0x00;
|
[0x0, 0x3ff, 0x3ff, function(a,v) { cpuram.mem[a] = v; }],
|
||||||
else if (address >= 0x2000 && address <= 0x2007)
|
[0x3000, 0x3000, 0, function(a,v) { dvg.runUntilHalt(); }],
|
||||||
return switches[address - 0x2000];
|
// TODO: draw asynchronous or allow poll of HALT ($2002)
|
||||||
else if (address >= 0x2400 && address <= 0x2407)
|
[0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }],
|
||||||
return switches[address - 0x2400 + 8];
|
], {gmask:0x7fff})
|
||||||
}
|
|
||||||
return 0xff;
|
|
||||||
},
|
|
||||||
write: function(address, val) {
|
|
||||||
address &= 0x7fff;
|
|
||||||
if (address < 0x3ff) {
|
|
||||||
cpuram.mem[address] = val;
|
|
||||||
} else if (address >= 0x4000 && address <= 0x5fff) {
|
|
||||||
dvgram.mem[address - 0x4000] = val;
|
|
||||||
} else if (address >= 0x3000 && address <= 0x3fff) {
|
|
||||||
//console.log(address.toString(16), val);
|
|
||||||
if (address == 0x3000) dvg.runUntilHalt();
|
|
||||||
// TODO: draw asynchronous or allow poll of HALT ($2002)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
cpu.connectBus(bus);
|
cpu.connectBus(bus);
|
||||||
// create video/audio
|
// create video/audio
|
||||||
|
@ -89,25 +88,7 @@ var AtariVectorPlatform = function(mainElement) {
|
||||||
}
|
}
|
||||||
self.restartDebugState();
|
self.restartDebugState();
|
||||||
});
|
});
|
||||||
video.setKeyboardEvents(function(key,code,flags) {
|
setKeyboardFromMap(video, switches, ASTEROIDS_KEYCODE_MAP);
|
||||||
var KEY2ADDR = {
|
|
||||||
16: 3, // shift
|
|
||||||
32: 4, // space
|
|
||||||
53: 8+0, // 5
|
|
||||||
54: 8+1, // 6
|
|
||||||
55: 8+2, // 7
|
|
||||||
49: 8+3, // 1
|
|
||||||
50: 8+4, // 2
|
|
||||||
38: 8+5,
|
|
||||||
39: 8+6,
|
|
||||||
37: 8+7,
|
|
||||||
};
|
|
||||||
var addr = KEY2ADDR[key];
|
|
||||||
//console.log(key,flags,addr);
|
|
||||||
if (addr >= 0) {
|
|
||||||
switches[addr] = (flags&1) ? 0xff : 0x00;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadROM = function(title, data) {
|
this.loadROM = function(title, data) {
|
||||||
|
@ -154,9 +135,6 @@ var AtariVectorPlatform = function(mainElement) {
|
||||||
nmic:nmicount
|
nmic:nmicount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return state.cb;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,18 @@ var GalaxianPlatform = function(mainElement) {
|
||||||
for (var i=0; i<256; i++)
|
for (var i=0; i<256; i++)
|
||||||
stars[i] = noise();
|
stars[i] = noise();
|
||||||
|
|
||||||
|
var GALAXIAN_KEYCODE_MAP = makeKeycodeMap([
|
||||||
|
[Keys.VK_SPACE, 0, 0x10], // P1
|
||||||
|
[Keys.VK_LEFT, 0, 0x4],
|
||||||
|
[Keys.VK_RIGHT, 0, 0x8],
|
||||||
|
[Keys.VK_S, 1, 0x10], // P2
|
||||||
|
[Keys.VK_A, 1, 0x4],
|
||||||
|
[Keys.VK_D, 1, 0x8],
|
||||||
|
[Keys.VK_5, 0, 0x1],
|
||||||
|
[Keys.VK_1, 1, 0x1],
|
||||||
|
[Keys.VK_2, 1, 0x2],
|
||||||
|
]);
|
||||||
|
|
||||||
function drawScanline(pixels, sl) {
|
function drawScanline(pixels, sl) {
|
||||||
if (sl < 16 && !showOffscreenObjects) return; // offscreen
|
if (sl < 16 && !showOffscreenObjects) return; // offscreen
|
||||||
if (sl >= 240 && !showOffscreenObjects) return; // offscreen
|
if (sl >= 240 && !showOffscreenObjects) return; // offscreen
|
||||||
|
@ -127,18 +139,6 @@ var GalaxianPlatform = function(mainElement) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var KEYCODE_MAP = {
|
|
||||||
32:{i:0,b:4}, // space bar (P1)
|
|
||||||
37:{i:0,b:2}, // left arrow (P1)
|
|
||||||
39:{i:0,b:3}, // right arrow (P1)
|
|
||||||
0x53:{i:1,b:4}, // S (P2)
|
|
||||||
0x41:{i:1,b:2}, // A (P2)
|
|
||||||
0x44:{i:1,b:3}, // D (P2)
|
|
||||||
53:{i:0,b:0}, // 5
|
|
||||||
49:{i:1,b:0}, // 1
|
|
||||||
50:{i:1,b:1}, // 2
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getPresets = function() {
|
this.getPresets = function() {
|
||||||
return GALAXIAN_PRESETS;
|
return GALAXIAN_PRESETS;
|
||||||
}
|
}
|
||||||
|
@ -187,16 +187,7 @@ var GalaxianPlatform = function(mainElement) {
|
||||||
audio = new SampleAudio(cpuFrequency);
|
audio = new SampleAudio(cpuFrequency);
|
||||||
video.create();
|
video.create();
|
||||||
var idata = video.getFrameData();
|
var idata = video.getFrameData();
|
||||||
video.setKeyboardEvents(function(key,code,flags) {
|
setKeyboardFromMap(video, inputs, GALAXIAN_KEYCODE_MAP);
|
||||||
var o = KEYCODE_MAP[key];
|
|
||||||
if (o) {
|
|
||||||
if (flags & 1) {
|
|
||||||
inputs[o.i] |= (1<<o.b);
|
|
||||||
} else {
|
|
||||||
inputs[o.i] &= ~(1<<o.b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pixels = video.getFrameData();
|
pixels = video.getFrameData();
|
||||||
timer = new AnimationTimer(60, function() {
|
timer = new AnimationTimer(60, function() {
|
||||||
if (!self.isRunning())
|
if (!self.isRunning())
|
||||||
|
@ -295,9 +286,6 @@ var GalaxianPlatform = function(mainElement) {
|
||||||
in2:inputs[2],
|
in2:inputs[2],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return ram.mem;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,9 +123,6 @@ var KonamiSoundPlatform = function(mainElement) {
|
||||||
b:ram.mem.slice(0),
|
b:ram.mem.slice(0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return ram.mem;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// http://www.computerarcheology.com/Arcade/SpaceInvaders/Hardware.html
|
// http://www.computerarcheology.com/Arcade/
|
||||||
|
|
||||||
var SPACEINV_PRESETS = [
|
var MW8080BW_PRESETS = [
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: global???
|
// TODO: global???
|
||||||
|
@ -10,7 +10,7 @@ window.buildZ80({
|
||||||
applyContention: false
|
applyContention: false
|
||||||
});
|
});
|
||||||
|
|
||||||
var SpaceInvadersPlatform = function(mainElement) {
|
var Midway8080BWPlatform = function(mainElement) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.__proto__ = new BaseZ80Platform();
|
this.__proto__ = new BaseZ80Platform();
|
||||||
|
|
||||||
|
@ -26,20 +26,20 @@ var SpaceInvadersPlatform = function(mainElement) {
|
||||||
var PIXEL_ON = 0xffeeeeee;
|
var PIXEL_ON = 0xffeeeeee;
|
||||||
var PIXEL_OFF = 0xff000000;
|
var PIXEL_OFF = 0xff000000;
|
||||||
|
|
||||||
var KEYCODE_MAP = {
|
var SPACEINV_KEYCODE_MAP = makeKeycodeMap([
|
||||||
32:{i:1,b:4}, // space bar (P1)
|
[Keys.VK_SPACE, 1, 0x10], // P1
|
||||||
37:{i:1,b:5}, // left arrow (P1)
|
[Keys.VK_LEFT, 1, 0x20],
|
||||||
39:{i:1,b:6}, // right arrow (P1)
|
[Keys.VK_RIGHT, 1, 0x40],
|
||||||
0x53:{i:2,b:4}, // S (P2)
|
[Keys.VK_S, 2, 0x10], // P2
|
||||||
0x41:{i:2,b:5}, // A (P2)
|
[Keys.VK_A, 2, 0x20],
|
||||||
0x44:{i:2,b:6}, // D (P2)
|
[Keys.VK_D, 2, 0x40],
|
||||||
53:{i:1,b:0}, // 5
|
[Keys.VK_5, 1, 0x1],
|
||||||
49:{i:1,b:2}, // 1
|
[Keys.VK_1, 1, 0x4],
|
||||||
50:{i:1,b:1}, // 2
|
[Keys.VK_2, 1, 0x2],
|
||||||
}
|
]);
|
||||||
|
|
||||||
this.getPresets = function() {
|
this.getPresets = function() {
|
||||||
return SPACEINV_PRESETS;
|
return MW8080BW_PRESETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.start = function() {
|
this.start = function() {
|
||||||
|
@ -111,16 +111,7 @@ var SpaceInvadersPlatform = function(mainElement) {
|
||||||
console.log(x, y, hex(addr,4), "PC", hex(displayPCs[addr],4));
|
console.log(x, y, hex(addr,4), "PC", hex(displayPCs[addr],4));
|
||||||
});
|
});
|
||||||
var idata = video.getFrameData();
|
var idata = video.getFrameData();
|
||||||
video.setKeyboardEvents(function(key,code,flags) {
|
setKeyboardFromMap(video, inputs, SPACEINV_KEYCODE_MAP);
|
||||||
var o = KEYCODE_MAP[key];
|
|
||||||
if (o) {
|
|
||||||
if (flags & 1) {
|
|
||||||
inputs[o.i] |= (1<<o.b);
|
|
||||||
} else {
|
|
||||||
inputs[o.i] &= ~(1<<o.b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pixels = video.getFrameData();
|
pixels = video.getFrameData();
|
||||||
timer = new AnimationTimer(60, function() {
|
timer = new AnimationTimer(60, function() {
|
||||||
if (!self.isRunning())
|
if (!self.isRunning())
|
||||||
|
@ -183,9 +174,6 @@ var SpaceInvadersPlatform = function(mainElement) {
|
||||||
in2:inputs[2],
|
in2:inputs[2],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return ram.mem;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
@ -209,4 +197,4 @@ var SpaceInvadersPlatform = function(mainElement) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PLATFORMS['spaceinv'] = SpaceInvadersPlatform;
|
PLATFORMS['mw8080bw'] = Midway8080BWPlatform;
|
|
@ -57,14 +57,14 @@ var VicDualPlatform = function(mainElement) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var KEYCODE_MAP = {
|
var CARNIVAL_KEYCODE_MAP = makeKeycodeMap([
|
||||||
37:{i:1,m:0x10,a:0}, // left arrow (P1)
|
[Keys.VK_SPACE, 2, -0x20], // P1
|
||||||
39:{i:1,m:0x20,a:0}, // right arrow (P1)
|
[Keys.VK_LEFT, 1, -0x10],
|
||||||
49:{i:2,m:0x10,a:0}, // 1
|
[Keys.VK_RIGHT, 1, -0x20],
|
||||||
32:{i:2,m:0x20,a:0}, // space bar (P1)
|
[Keys.VK_1, 2, -0x10],
|
||||||
53:{i:3,m:0x08,a:1}, // 5
|
[Keys.VK_2, 3, -0x20],
|
||||||
50:{i:3,m:0x20,a:0}, // 2
|
[Keys.VK_5, 3, 0x8],
|
||||||
}
|
]);
|
||||||
|
|
||||||
this.getPresets = function() {
|
this.getPresets = function() {
|
||||||
return VICDUAL_PRESETS;
|
return VICDUAL_PRESETS;
|
||||||
|
@ -100,18 +100,10 @@ var VicDualPlatform = function(mainElement) {
|
||||||
audio = new SampleAudio(cpuFrequency);
|
audio = new SampleAudio(cpuFrequency);
|
||||||
video.create();
|
video.create();
|
||||||
var idata = video.getFrameData();
|
var idata = video.getFrameData();
|
||||||
video.setKeyboardEvents(function(key,code,flags) {
|
setKeyboardFromMap(video, inputs, CARNIVAL_KEYCODE_MAP, function(o) {
|
||||||
var o = KEYCODE_MAP[key];
|
// reset when coin inserted
|
||||||
if (o) {
|
if (o.index==3 && o.mask==0x8) cpu.reset();
|
||||||
if ((flags^o.a) & 1) {
|
});
|
||||||
inputs[o.i] &= ~o.m;
|
|
||||||
} else {
|
|
||||||
inputs[o.i] |= o.m;
|
|
||||||
}
|
|
||||||
// reset CPU when coin inserted
|
|
||||||
if (o.i==3 && o.m==0x8) cpu.reset();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pixels = video.getFrameData();
|
pixels = video.getFrameData();
|
||||||
timer = new AnimationTimer(60, function() {
|
timer = new AnimationTimer(60, function() {
|
||||||
if (!self.isRunning())
|
if (!self.isRunning())
|
||||||
|
@ -160,9 +152,6 @@ var VicDualPlatform = function(mainElement) {
|
||||||
in3:inputs[3],
|
in3:inputs[3],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return ram.mem;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var WILLIAMS_PRESETS = [
|
var WILLIAMS_PRESETS = [
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -277,17 +277,7 @@ var WilliamsPlatform = function(mainElement) {
|
||||||
console.log(x, y, hex(addr,4), "PC", hex(displayPCs[addr],4));
|
console.log(x, y, hex(addr,4), "PC", hex(displayPCs[addr],4));
|
||||||
});
|
});
|
||||||
var idata = video.getFrameData();
|
var idata = video.getFrameData();
|
||||||
video.setKeyboardEvents(function(key,code,flags) {
|
setKeyboardFromMap(video, pia6821, ROBOTRON_KEYCODE_MAP);
|
||||||
var o = ROBOTRON_KEYCODE_MAP[key];
|
|
||||||
if (o) {
|
|
||||||
//console.log(key,code,flags,o);
|
|
||||||
if (flags & 1) {
|
|
||||||
pia6821[o.index] |= o.mask;
|
|
||||||
} else {
|
|
||||||
pia6821[o.index] &= ~o.mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pixels = video.getFrameData();
|
pixels = video.getFrameData();
|
||||||
timer = new AnimationTimer(60, function() {
|
timer = new AnimationTimer(60, function() {
|
||||||
if (!self.isRunning())
|
if (!self.isRunning())
|
||||||
|
@ -356,9 +346,6 @@ var WilliamsPlatform = function(mainElement) {
|
||||||
ps:portsel,
|
ps:portsel,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.getRAMForState = function(state) {
|
|
||||||
return ram.mem;
|
|
||||||
}
|
|
||||||
this.getCPUState = function() {
|
this.getCPUState = function() {
|
||||||
return cpu.saveState();
|
return cpu.saveState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -463,7 +463,7 @@ l_main00101 = 0003, L: test
|
||||||
}
|
}
|
||||||
|
|
||||||
var PLATFORM_PARAMS = {
|
var PLATFORM_PARAMS = {
|
||||||
'spaceinv': {
|
'mw8080bw': {
|
||||||
code_start: 0x0,
|
code_start: 0x0,
|
||||||
code_size: 0x2000,
|
code_size: 0x2000,
|
||||||
data_start: 0x2000,
|
data_start: 0x2000,
|
||||||
|
@ -611,6 +611,53 @@ function compileSDCC(code, platform) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assembleXASM6809(code, platform) {
|
||||||
|
load("xasm6809");
|
||||||
|
var origin = 0; // TODO: configurable
|
||||||
|
var alst = "";
|
||||||
|
var lasterror = null;
|
||||||
|
msvc_errors = [];
|
||||||
|
function match_fn(s) {
|
||||||
|
alst += s;
|
||||||
|
alst += "\n";
|
||||||
|
if (lasterror) {
|
||||||
|
var line = parseInt(s.slice(0,5));
|
||||||
|
msvc_errors.push({
|
||||||
|
line:line,
|
||||||
|
msg:lasterror
|
||||||
|
});
|
||||||
|
lasterror = null;
|
||||||
|
}
|
||||||
|
else if (s.startsWith("***** ")) {
|
||||||
|
lasterror = s.slice(6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var Module = xasm6809({
|
||||||
|
noInitialRun:true,
|
||||||
|
//logReadFiles:true,
|
||||||
|
print:match_fn,
|
||||||
|
printErr:print_fn
|
||||||
|
});
|
||||||
|
var FS = Module['FS'];
|
||||||
|
//setupFS(FS);
|
||||||
|
FS.writeFile("main.asm", code);
|
||||||
|
Module.callMain(["-c", "-l", "-s", "-y", "-o=main.bin", "main.asm"]);
|
||||||
|
console.log(alst);
|
||||||
|
try {
|
||||||
|
var aout = FS.readFile("main.bin", {encoding:'binary'});
|
||||||
|
// 00001 0000 [ 2] 1048 asld
|
||||||
|
var asmlines = parseListing(alst, /^\s*([0-9A-F]+)\s+([0-9A-F]+)\s+\[([0-9 ]+)\]\s+(\d+) (.*)/i, 1, 2, 4, 5, 3);
|
||||||
|
return {
|
||||||
|
output:aout,
|
||||||
|
errors:msvc_errors,
|
||||||
|
lines:asmlines,
|
||||||
|
intermediate:{listing:alst},
|
||||||
|
};
|
||||||
|
} catch(e) {
|
||||||
|
return {errors:msvc_errors}; // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var TOOLS = {
|
var TOOLS = {
|
||||||
'dasm': assembleDASM,
|
'dasm': assembleDASM,
|
||||||
'acme': assembleACME,
|
'acme': assembleACME,
|
||||||
|
@ -620,6 +667,7 @@ var TOOLS = {
|
||||||
'z80asm': assembleZ80ASM,
|
'z80asm': assembleZ80ASM,
|
||||||
'sdasz80': assemblelinkSDASZ80,
|
'sdasz80': assemblelinkSDASZ80,
|
||||||
'sdcc': compileSDCC,
|
'sdcc': compileSDCC,
|
||||||
|
'xasm6809': assembleXASM6809,
|
||||||
}
|
}
|
||||||
|
|
||||||
onmessage = function(e) {
|
onmessage = function(e) {
|
||||||
|
|
23
src/worker/xasm6809.js
Normal file
23
src/worker/xasm6809.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -102,21 +102,24 @@ describe('Worker', function() {
|
||||||
compile('cc65', 'int main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', 'apple2', done, 0, 0, 1);
|
compile('cc65', 'int main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', 'apple2', done, 0, 0, 1);
|
||||||
});
|
});
|
||||||
it('should assemble Z80ASM', function(done) {
|
it('should assemble Z80ASM', function(done) {
|
||||||
compile('z80asm', '\tMODULE test\n\tXREF _puts\n\tld hl,$0000\n\tret\n', 'spaceinv', done, 4, 2, 0);
|
compile('z80asm', '\tMODULE test\n\tXREF _puts\n\tld hl,$0000\n\tret\n', 'mw8080bw', done, 4, 2, 0);
|
||||||
});
|
});
|
||||||
it('should NOT assemble Z80ASM', function(done) {
|
it('should NOT assemble Z80ASM', function(done) {
|
||||||
compile('z80asm', 'ddwiuweq', 'none', done, 0, 0, 1);
|
compile('z80asm', 'ddwiuweq', 'none', done, 0, 0, 1);
|
||||||
});
|
});
|
||||||
it('should assemble SDASZ80', function(done) {
|
it('should assemble SDASZ80', function(done) {
|
||||||
compile('sdasz80', '\tld hl,#0\n\tret\n', 'spaceinv', done, 8192, 2);
|
compile('sdasz80', '\tld hl,#0\n\tret\n', 'mw8080bw', done, 8192, 2);
|
||||||
});
|
});
|
||||||
it('should NOT assemble SDASZ80', function(done) {
|
it('should NOT assemble SDASZ80', function(done) {
|
||||||
compile('sdasz80', '\txxx hl,#0\n\tret\n', 'spaceinv', done, 0, 0, 1);
|
compile('sdasz80', '\txxx hl,#0\n\tret\n', 'mw8080bw', done, 0, 0, 1);
|
||||||
});
|
});
|
||||||
it('should compile SDCC', function(done) {
|
it('should compile SDCC', function(done) {
|
||||||
compile('sdcc', 'int foo=0;\nint main(int argc) {\nint x=1;\nint y=2+argc;\nreturn x+y+argc;\n}', 'spaceinv', done, 8192, 3, 0);
|
compile('sdcc', 'int foo=0;\nint main(int argc) {\nint x=1;\nint y=2+argc;\nreturn x+y+argc;\n}', 'mw8080bw', done, 8192, 3, 0);
|
||||||
});
|
});
|
||||||
it('should NOT compile SDCC', function(done) {
|
it('should NOT compile SDCC', function(done) {
|
||||||
compile('sdcc', 'foobar', 'spaceinv', done, 0, 0, 1);
|
compile('sdcc', 'foobar', 'mw8080bw', done, 0, 0, 1);
|
||||||
|
});
|
||||||
|
it('should compile XASM6809', function(done) {
|
||||||
|
compile('xasm6809', '\tasld\n\tasld\n', 'mw8080bw', done, 4, 2, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe('Test VCS emulator', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Test Space Invaders emulator', function() {
|
describe('Test Space Invaders emulator', function() {
|
||||||
var platform = new SpaceInvadersPlatform($('#emulator')[0]);
|
var platform = new Midway8080BWPlatform($('#emulator')[0]);
|
||||||
it('Should start', function(done) {
|
it('Should start', function(done) {
|
||||||
platform.start();
|
platform.start();
|
||||||
assert(!platform.isRunning());
|
assert(!platform.isRunning());
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<script src="src/util.js"></script>
|
<script src="src/util.js"></script>
|
||||||
<script src="src/disasm.js"></script>
|
<script src="src/disasm.js"></script>
|
||||||
<script src="src/platform/vcs.js"></script>
|
<script src="src/platform/vcs.js"></script>
|
||||||
<script src="src/platform/spaceinv.js"></script>
|
<script src="src/platform/mw8080bw.js"></script>
|
||||||
|
|
||||||
<script src="test/ui/testemus.js"></script>
|
<script src="test/ui/testemus.js"></script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user