-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathvisualize-ops.html
More file actions
106 lines (90 loc) · 3.13 KB
/
visualize-ops.html
File metadata and controls
106 lines (90 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<!doctype html>
<html>
<head>
<title>Operation Visualization</title>
</head>
<body style="background-color: #fdd">
<textarea style="float:left;width:20%;height:768px;" readonly id="text"></textarea>
<div style="float:right;position:relative;width:768px;height:768px;">
<canvas style="position:absolute;top:0;left:0" id="c" width=768 height=768></canvas>
<canvas style="position:absolute;top:0;left:0;opacity:25%" id="c-overlay" width=768 height=768></canvas>
</div>
<hr style="clear:both"/>
<label>Choose bootstrap.bin and ops.out
<input type="file" id="files" multiple />
</label>
<button id="submit">Submit</button>
<script>
let c = document.getElementById('c');
let ctx = c.getContext('2d');
let overlay = document.getElementById('c-overlay');
let overlay_ctx = overlay.getContext('2d');
function setPixel(x, y, c) {
ctx.fillStyle = c;
ctx.fillRect(x*3, y*3, 3, 3);
}
overlay_ctx.fillStyle = 'red';
overlay_ctx.fillRect(0, 0, 256*3, 0x8*3);
overlay_ctx.fillStyle = 'gray';
overlay_ctx.fillRect(0, 8*3, 256*3, (0x40-8) * 3);
overlay_ctx.fillStyle = 'blue';
overlay_ctx.fillRect(0, 0x40*3, 256*3, 0x20*3);
overlay_ctx.fillStyle = 'red';
overlay_ctx.fillRect(0, 0x60*3, 256*3, 0x20*3);
let memoryState, ops;
function byte2Color(byte) {
const val = Math.floor(byte / 16).toString(16);
return '#' + val + val + val;
}
let op = 0;
let ops_per_frame = 4096;
let chars_per_frame = 16;
let source = "";
let textarea = document.getElementById('text');
function startAnimation() {
let chars = 0;
for (let i = 0; i < ops_per_frame && op < ops.length; i++) {
let [opType, addr, val] = ops[op++].split('\t')
if (opType == 'w') {
setPixel(addr % 256, Math.floor(addr / 256), byte2Color(val % 256));
} else if (opType == 'r') {
chars++;
const nextChar = String.fromCharCode(+addr);
source = source + nextChar;
textarea.innerHTML = source;
textarea.scrollTop = textarea.scrollHeight;
if (chars === chars_per_frame) break;
}
}
requestAnimationFrame(startAnimation);
}
function redraw() {
if (memoryState != null) {
for (let i = 0; i < memoryState.byteLength; i++) {
setPixel(i % 256, Math.floor(i / 256), byte2Color(memoryState[i]));
}
}
if (memoryState != null && ops != null) {
requestAnimationFrame(startAnimation);
}
}
document.getElementById("submit").onclick = function() {
let files = document.getElementById("files").files;
for (let f of files) {
let reader = new FileReader();
reader.onloadend = function () {
if (reader.result.byteLength === 65536) {
memoryState = new Uint8Array(reader.result);
console.log(memoryState[0]);
} else {
ops = new TextDecoder('utf-8').decode(reader.result).split('\n');
}
console.log(reader.result);
redraw();
}
reader.readAsArrayBuffer(f);
}
}
</script>
</body>
</html>