fixed b/w vector graphics

This commit is contained in:
Steven Hugg 2018-08-18 09:52:17 -04:00
parent 9688e801b8
commit 6b1e09a835
2 changed files with 51 additions and 104 deletions

View File

@ -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);

View File

@ -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;