show = () => {
const size = Math.floor(width / 64);
const ctx = DOM.context2d(64 * size, 64 * size, 1);
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 64 * size, 64 * size);
let memory = [];
let videoOffset = -1;
for (let i = 0; i < kaleidoscope.length; i += 2) {
let byte = parseInt(kaleidoscope.substr(i, 2), 16);
memory[i / 2] = byte;
}
function memoryTo(addr, value) {
memory[addr] = value;
if (addr >= videoOffset) {
let memOffset = addr - videoOffset;
let quad = (memOffset / 512) | 0;
let i = (quad % 2) * 32;
let j = ((quad / 2) | 0) * 32;
memOffset = memOffset % 512;
i += (memOffset % 16) * 2;
j += (memOffset / 16) | 0;
drawPixel(i, j, value);
drawPixel(i + 1, j, value >> 4);
}
}
function drawPixel(i, j, data) {
let style = "#";
let intensity = data & 0x8 ? "ff" : "7f";
style += data & 0x1 ? intensity : "00";
style += data & 0x2 ? intensity : "00";
style += data & 0x4 ? intensity : "00";
ctx.fillStyle = style;
ctx.fillRect(i * size + 2, j * size + 2, size - 4, size - 4);
}
function memoryAt(addr) {
return memory[addr];
}
function ticker(T) {}
function portTo(addr, value) {
switch (addr) {
case 14:
videoOffset = (value & 0x7f) << 9;
break;
case 15:
break;
default:
throw new Error("unexpected portTo");
}
}
function portAt(addr) {
throw new Error("unexpected portAt");
}
CPU8080.init(memoryTo, memoryAt, ticker, portTo, portAt);
let frame;
function go() {
CPU8080.steps((viewof clockSpeed.value * 1e6) / 60);
return (frame = window.requestAnimationFrame(go));
}
go();
invalidation.then(() => cancelAnimationFrame(frame));
return ctx.canvas;
}