mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-25 00:29:38 +00:00
fixed b/w vector graphics
This commit is contained in:
parent
9688e801b8
commit
6b1e09a835
111
src/emu.ts
111
src/emu.ts
@ -15,7 +15,9 @@ export function noise() {
|
||||
return (Math.random() * 256) & 0xff;
|
||||
}
|
||||
|
||||
function __createCanvas(mainElement:HTMLElement, width:number, height:number) {
|
||||
type KeyboardCallback = (which:number, charCode:number, flags:number) => void;
|
||||
|
||||
function __createCanvas(mainElement:HTMLElement, width:number, height:number) : HTMLElement {
|
||||
// TODO
|
||||
var fsElement = document.createElement('div');
|
||||
fsElement.classList.add("emubevel");
|
||||
@ -31,8 +33,19 @@ function __createCanvas(mainElement:HTMLElement, width:number, height:number) {
|
||||
return canvas;
|
||||
}
|
||||
|
||||
function _setKeyboardEvents(canvas:HTMLElement, callback:KeyboardCallback) {
|
||||
canvas.onkeydown = function(e) {
|
||||
callback(e.which, 0, 1|_metakeyflags(e));
|
||||
};
|
||||
canvas.onkeyup = function(e) {
|
||||
callback(e.which, 0, 0|_metakeyflags(e));
|
||||
};
|
||||
canvas.onkeypress = function(e) {
|
||||
callback(e.which, e.charCode, 1|_metakeyflags(e));
|
||||
};
|
||||
};
|
||||
|
||||
export var RasterVideo = function(mainElement:HTMLElement, width:number, height:number, options?) {
|
||||
var self = this;
|
||||
var canvas, ctx;
|
||||
var imageData, arraybuf, buf8, datau32;
|
||||
|
||||
@ -49,9 +62,9 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
}
|
||||
|
||||
this.create = function() {
|
||||
self.canvas = canvas = __createCanvas(mainElement, width, height);
|
||||
this.canvas = canvas = __createCanvas(mainElement, width, height);
|
||||
if (options && options.rotate) {
|
||||
self.setRotate(options.rotate);
|
||||
this.setRotate(options.rotate);
|
||||
}
|
||||
ctx = canvas.getContext('2d');
|
||||
imageData = ctx.createImageData(width, height);
|
||||
@ -64,24 +77,15 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
datau32 = new Uint32Array(imageData.data.buffer);
|
||||
}
|
||||
|
||||
// TODO: common function (canvas)
|
||||
this.setKeyboardEvents = function(callback) {
|
||||
canvas.onkeydown = function(e) {
|
||||
callback(e.which, 0, 1|_metakeyflags(e));
|
||||
};
|
||||
canvas.onkeyup = function(e) {
|
||||
callback(e.which, 0, 0|_metakeyflags(e));
|
||||
};
|
||||
canvas.onkeypress = function(e) {
|
||||
callback(e.which, e.charCode, 1|_metakeyflags(e));
|
||||
};
|
||||
};
|
||||
_setKeyboardEvents(canvas, callback);
|
||||
}
|
||||
|
||||
this.getFrameData = function() { return datau32; }
|
||||
|
||||
this.getContext = function() { return ctx; }
|
||||
|
||||
this.updateFrame = function(sx, sy, dx, dy, width, height) {
|
||||
this.updateFrame = function(sx:number, sy:number, dx:number, dy:number, width?:number, height?:number) {
|
||||
//imageData.data.set(buf8); // TODO: slow w/ partial updates
|
||||
if (width && height)
|
||||
ctx.putImageData(imageData, sx, sy, dx, dy, width, height);
|
||||
@ -89,51 +93,6 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
if (frameUpdateFunction) frameUpdateFunction(canvas);
|
||||
}
|
||||
|
||||
/*
|
||||
mainElement.style.position = "relative";
|
||||
mainElement.style.overflow = "hidden";
|
||||
mainElement.style.outline = "none";
|
||||
mainElement.tabIndex = "-1"; // Make it focusable
|
||||
|
||||
borderElement = document.createElement('div');
|
||||
borderElement.style.position = "relative";
|
||||
borderElement.style.overflow = "hidden";
|
||||
borderElement.style.background = "black";
|
||||
borderElement.style.border = "0 solid black";
|
||||
borderElement.style.borderWidth = "" + borderTop + "px " + borderLateral + "px " + borderBottom + "px";
|
||||
if (Javatari.SCREEN_CONTROL_BAR === 2) {
|
||||
borderElement.style.borderImage = "url(" + IMAGE_PATH + "screenborder.png) " +
|
||||
borderTop + " " + borderLateral + " " + borderBottom + " repeat stretch";
|
||||
}
|
||||
|
||||
fsElement = document.createElement('div');
|
||||
fsElement.style.position = "relative";
|
||||
fsElement.style.width = "100%";
|
||||
fsElement.style.height = "100%";
|
||||
fsElement.style.overflow = "hidden";
|
||||
fsElement.style.background = "black";
|
||||
|
||||
document.addEventListener("fullscreenchange", fullScreenChanged);
|
||||
document.addEventListener("webkitfullscreenchange", fullScreenChanged);
|
||||
document.addEventListener("mozfullscreenchange", fullScreenChanged);
|
||||
document.addEventListener("msfullscreenchange", fullScreenChanged);
|
||||
|
||||
borderElement.appendChild(fsElement);
|
||||
|
||||
canvas.style.position = "absolute";
|
||||
canvas.style.display = "block";
|
||||
canvas.style.left = canvas.style.right = 0;
|
||||
canvas.style.top = canvas.style.bottom = 0;
|
||||
canvas.style.margin = "auto";
|
||||
canvas.tabIndex = "-1"; // Make it focusable
|
||||
canvas.style.outline = "none";
|
||||
fsElement.appendChild(canvas);
|
||||
|
||||
setElementsSizes(jt.CanvasDisplay.DEFAULT_STARTING_WIDTH, jt.CanvasDisplay.DEFAULT_STARTING_HEIGHT);
|
||||
|
||||
mainElement.appendChild(borderElement);
|
||||
*/
|
||||
}
|
||||
|
||||
export var VectorVideo = function(mainElement:HTMLElement, width:number, height:number) {
|
||||
@ -146,22 +105,13 @@ export var VectorVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
var sy = height/1024.0;
|
||||
|
||||
this.create = function() {
|
||||
canvas = __createCanvas(mainElement, width, height);
|
||||
this.canvas = canvas = __createCanvas(mainElement, width, height);
|
||||
ctx = canvas.getContext('2d');
|
||||
}
|
||||
|
||||
// TODO: common function (canvas)
|
||||
this.setKeyboardEvents = function(callback) {
|
||||
canvas.onkeydown = function(e) {
|
||||
callback(e.which, 0, 1|_metakeyflags(e));
|
||||
};
|
||||
canvas.onkeyup = function(e) {
|
||||
callback(e.which, 0, 0|_metakeyflags(e));
|
||||
};
|
||||
canvas.onkeypress = function(e) {
|
||||
callback(e.which, e.charCode, 1|_metakeyflags(e));
|
||||
};
|
||||
};
|
||||
_setKeyboardEvents(canvas, callback);
|
||||
}
|
||||
|
||||
this.clear = function() {
|
||||
ctx.globalCompositeOperation = 'source-over';
|
||||
@ -184,8 +134,8 @@ export var VectorVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
'#ffffff'
|
||||
];
|
||||
|
||||
this.drawLine = function(x1, y1, x2, y2, intensity, color) {
|
||||
//console.log(x1, y1, x2, y2, intensity);
|
||||
this.drawLine = function(x1:number, y1:number, x2:number, y2:number, intensity:number, color:number) {
|
||||
//console.log(x1,y1,x2,y2,intensity,color);
|
||||
if (intensity > 0) {
|
||||
// TODO: landscape vs portrait
|
||||
var alpha = Math.pow(intensity / 255.0, gamma);
|
||||
@ -476,14 +426,17 @@ declare var addr2symbol; // address to symbol name map (TODO: import)
|
||||
|
||||
function lookupSymbol(addr) {
|
||||
var start = addr;
|
||||
var foundsym;
|
||||
while (addr >= 0) {
|
||||
var sym = addr2symbol[addr];
|
||||
// TODO: what about asm?
|
||||
if (sym && sym.startsWith('_')) {
|
||||
if (sym && sym.startsWith('_')) { // return first C symbol we find
|
||||
return addr2symbol[addr] + " + " + (start-addr);
|
||||
} else if (sym && !foundsym) { // cache first non-C symbol found
|
||||
foundsym = sym;
|
||||
}
|
||||
addr--;
|
||||
}
|
||||
return foundsym || "";
|
||||
}
|
||||
|
||||
export function dumpStackToString(mem:number[], start:number, end:number, sp:number) : string {
|
||||
@ -492,8 +445,10 @@ export function dumpStackToString(mem:number[], start:number, end:number, sp:num
|
||||
//s = dumpRAM(mem.slice(start,start+end+1), start, end-start+1);
|
||||
while (sp < end) {
|
||||
sp++;
|
||||
// see if there's a JSR on the stack here
|
||||
// TODO: make work with roms and memory maps
|
||||
var addr = mem[sp] + mem[sp+1]*256;
|
||||
var opcode = mem[addr-2];
|
||||
var opcode = mem[addr-2]; // might be out of bounds
|
||||
if (opcode == 0x20) { // JSR
|
||||
s += "\n$" + hex(sp) + ": ";
|
||||
s += hex(addr,4) + " " + lookupSymbol(addr);
|
||||
|
@ -53,12 +53,15 @@ function newPOKEYAudio() {
|
||||
|
||||
var AtariVectorPlatform = function(mainElement) {
|
||||
var self = this;
|
||||
var cpuFrequency = 1500000.0;
|
||||
var cpuCyclesPerNMI = 6000;
|
||||
var XTAL = 12096000;
|
||||
var cpuFrequency = XTAL/8;
|
||||
var cpuCyclesPer3khz = Math.round(cpuFrequency/(XTAL/4096)); // ~3 Khz
|
||||
var cpuCyclesPerNMI = Math.round(cpuFrequency*12/(XTAL/4096)); // ~250 Hz
|
||||
var cpuCyclesPerFrame = Math.round(cpuFrequency/60);
|
||||
var cpu, cpuram, dvgram, rom, vecrom, bus, dvg;
|
||||
var video, audio, timer;
|
||||
var clock;
|
||||
var watchdog = 0;
|
||||
var switches = new RAM(16).mem;
|
||||
var nmicount = cpuCyclesPerNMI;
|
||||
|
||||
@ -71,14 +74,14 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
this.start = function() {
|
||||
cpuram = new RAM(0x400);
|
||||
dvgram = new RAM(0x2000);
|
||||
switches[5] = 0xff;
|
||||
switches[7] = 0xff;
|
||||
//switches[5] = 0xff;
|
||||
//switches[7] = 0xff;
|
||||
// bus
|
||||
bus = {
|
||||
|
||||
read: newAddressDecoder([
|
||||
[0x0, 0x3ff, 0x3ff, function(a) { return cpuram.mem[a]; }],
|
||||
[0x2001, 0x2001, 0, function(a) { return ((clock/500) & 1) ? 0xff : 0x00; }],
|
||||
[0x2001, 0x2001, 0, function(a) { return ((clock / cpuCyclesPer3khz) & 1) ? 0xff : 0x00; }],
|
||||
[0x2000, 0x2007, 0x7, function(a) { return switches[a]; }],
|
||||
[0x2400, 0x2407, 0x7, function(a) { return switches[a+8]; }],
|
||||
[0x4000, 0x4fff, 0xfff, function(a) { return dvgram.mem[a]; }],
|
||||
@ -89,6 +92,7 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
write: newAddressDecoder([
|
||||
[0x0, 0x3ff, 0x3ff, function(a,v) { cpuram.mem[a] = v; }],
|
||||
[0x3000, 0x3000, 0, function(a,v) { dvg.runUntilHalt(0); }],
|
||||
[0x3400, 0x3400, 0, function(a,v) { watchdog = 0; }],
|
||||
// TODO: draw asynchronous or allow poll of HALT ($2002)
|
||||
[0x4000, 0x5fff, 0x1fff, function(a,v) { dvgram.mem[a] = v; }],
|
||||
], {gmask:0x7fff})
|
||||
@ -113,11 +117,11 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
var n = cpu.setNMIAndWait();
|
||||
clock += n;
|
||||
nmicount = cpuCyclesPerNMI - n;
|
||||
//console.log(n, clock, nmicount);
|
||||
}
|
||||
cpu.clockPulse();
|
||||
//cpu.executeInstruction();
|
||||
}
|
||||
//if (++watchdog == 256) { watchdog = 0; cpu.reset(); }
|
||||
self.restartDebugState();
|
||||
});
|
||||
setKeyboardFromMap(video, switches, ASTEROIDS_KEYCODE_MAP);
|
||||
@ -132,10 +136,6 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.getRasterPosition = function() {
|
||||
return {x:0, y:0}; // TODO
|
||||
}
|
||||
|
||||
this.isRunning = function() {
|
||||
return timer && timer.isRunning();
|
||||
}
|
||||
@ -154,7 +154,7 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
|
||||
this.loadState = function(state) {
|
||||
cpu.loadState(state.c);
|
||||
cpuram.mem.set(state.cb);
|
||||
cpuram.mem.set(state.b);
|
||||
dvgram.mem.set(state.db);
|
||||
switches.set(state.sw);
|
||||
nmicount = state.nmic;
|
||||
@ -162,7 +162,7 @@ var AtariVectorPlatform = function(mainElement) {
|
||||
this.saveState = function() {
|
||||
return {
|
||||
c:cpu.saveState(),
|
||||
cb:cpuram.mem.slice(0),
|
||||
b:cpuram.mem.slice(0),
|
||||
db:dvgram.mem.slice(0),
|
||||
sw:switches.slice(0),
|
||||
nmic:nmicount
|
||||
@ -275,10 +275,6 @@ var AtariColorVectorPlatform = function(mainElement) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.getRasterPosition = function() {
|
||||
return {x:0, y:0}; // TODO
|
||||
}
|
||||
|
||||
this.isRunning = function() {
|
||||
return timer && timer.isRunning();
|
||||
}
|
||||
@ -297,7 +293,7 @@ var AtariColorVectorPlatform = function(mainElement) {
|
||||
|
||||
this.loadState = function(state) {
|
||||
cpu.loadState(state.c);
|
||||
cpuram.mem.set(state.cb);
|
||||
cpuram.mem.set(state.b);
|
||||
dvgram.mem.set(state.db);
|
||||
switches.set(state.sw);
|
||||
nmicount = state.nmic;
|
||||
@ -305,7 +301,7 @@ var AtariColorVectorPlatform = function(mainElement) {
|
||||
this.saveState = function() {
|
||||
return {
|
||||
c:cpu.saveState(),
|
||||
cb:cpuram.mem.slice(0),
|
||||
b:cpuram.mem.slice(0),
|
||||
db:dvgram.mem.slice(0),
|
||||
sw:switches.slice(0),
|
||||
nmic:nmicount
|
||||
@ -402,10 +398,6 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.getRasterPosition = function() {
|
||||
return {x:0, y:0}; // TODO
|
||||
}
|
||||
|
||||
this.isRunning = function() {
|
||||
return timer && timer.isRunning();
|
||||
}
|
||||
@ -424,7 +416,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
|
||||
|
||||
this.loadState = function(state) {
|
||||
cpu.loadState(state.c);
|
||||
cpuram.mem.set(state.cb);
|
||||
cpuram.mem.set(state.b);
|
||||
dvgram.mem.set(state.db);
|
||||
switches.set(state.sw);
|
||||
mathram.set(state.mr);
|
||||
@ -432,7 +424,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) {
|
||||
this.saveState = function() {
|
||||
return {
|
||||
c:cpu.saveState(),
|
||||
cb:cpuram.mem.slice(0),
|
||||
b:cpuram.mem.slice(0),
|
||||
db:dvgram.mem.slice(0),
|
||||
sw:switches.slice(0),
|
||||
mr:mathram.slice(0),
|
||||
@ -515,7 +507,7 @@ var DVGBWStateMachine = function(bus, video, bofs) {
|
||||
var z = w2 >> 12;
|
||||
var x2 = x + ((decodeSigned(w2, 10) << 7) >> sc);
|
||||
var y2 = y + ((decodeSigned(w, 10) << 7) >> sc);
|
||||
video.drawLine(x, y, x2, y2, z, 255);
|
||||
video.drawLine(x, y, x2, y2, z*32, 7);
|
||||
//console.log(pc.toString(16), w.toString(16), w2.toString(16), gsc, sc, x, y, x2, y2);
|
||||
x = x2;
|
||||
y = y2;
|
||||
@ -545,7 +537,7 @@ var DVGBWStateMachine = function(bus, video, bofs) {
|
||||
var x2 = x + ((decodeSigned(w, 2) << 7) >> sc);
|
||||
var y2 = y + ((decodeSigned(w>>8, 2) << 7) >> sc);
|
||||
var z = (w >> 4) & 0xf;
|
||||
video.drawLine(x, y, x2, y2, z, 255);
|
||||
video.drawLine(x, y, x2, y2, z*32, 7);
|
||||
x = x2;
|
||||
y = y2;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user