jsbeeb 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+
3
+ // MC6847 internal character ROM data (PAL square pixel variant, 8x12).
4
+ // Derived from the MAME project's MC6847 VDG emulation:
5
+ // https://github.com/mamedev/mame/blob/master/src/devices/video/mc6847.cpp
6
+ // Copyright Nathan Woods, licensed under BSD-3-Clause.
7
+ // See https://github.com/mamedev/mame/blob/master/LICENSE.md
8
+ export function makeCharsAtom() {
9
+ return new Uint8Array([
10
+ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x02, 0x1a, 0x2a, 0x2a, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22,
11
+ 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x12, 0x12, 0x1c, 0x12, 0x12, 0x3c, 0x00, 0x00,
12
+ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x12, 0x12,
13
+ 0x12, 0x12, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e, 0x00, 0x00,
14
+ 0x00, 0x00, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x20, 0x20,
15
+ 0x26, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x00,
16
+ 0x00, 0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,
17
+ 0x02, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00, 0x00,
18
+ 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x36, 0x2a,
19
+ 0x2a, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x22, 0x00, 0x00,
20
+ 0x00, 0x00, 0x00, 0x3e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22,
21
+ 0x3c, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a, 0x00, 0x00,
22
+ 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x10,
23
+ 0x08, 0x04, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
24
+ 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
25
+ 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00, 0x00,
26
+ 0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x14,
27
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x00,
28
+ 0x00, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x10,
29
+ 0x08, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e, 0x00, 0x00,
30
+ 0x00, 0x00, 0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
31
+ 0x3e, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14,
33
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x36, 0x00, 0x36, 0x14, 0x14, 0x00, 0x00,
34
+ 0x00, 0x00, 0x00, 0x08, 0x1e, 0x20, 0x1c, 0x02, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x32, 0x04,
35
+ 0x08, 0x10, 0x26, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x00,
36
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20,
37
+ 0x20, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00, 0x00,
38
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x3e, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
39
+ 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00,
40
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00, 0x00,
42
+ 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x24, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x08,
43
+ 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x20, 0x3e, 0x00, 0x00,
44
+ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x02, 0x0c, 0x02, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x14,
45
+ 0x3e, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x00,
46
+ 0x00, 0x00, 0x00, 0x1c, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x02, 0x04,
47
+ 0x08, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x00,
48
+ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
49
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00,
50
+ 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
51
+ 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
52
+ 0x00, 0x00, 0x00, 0x18, 0x24, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00,
53
+
54
+ // graphics
55
+
56
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57
+ 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0,
58
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f,
59
+ 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
60
+ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f,
61
+ 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00,
62
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0,
63
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff,
64
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
65
+ 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
66
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00,
67
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f,
68
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00,
69
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
70
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
71
+ 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff,
72
+ 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0,
73
+ 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
74
+ 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
75
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f,
76
+ 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff,
77
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78
+ 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00,
79
+ 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
80
+ 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f,
81
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0,
82
+ 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
83
+ 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f,
84
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
85
+ 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
86
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff,
87
+ 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
89
+ 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0,
90
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f,
91
+ 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
92
+ 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f,
93
+ 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00,
94
+ 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0,
95
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff,
96
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
97
+ 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
98
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99
+
100
+ /* Lower case */
101
+ 0x00, 0x00, 0x00, 0x0c, 0x12, 0x10, 0x38, 0x10, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
102
+ 0x02, 0x1e, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x00,
103
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x20, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x1e,
104
+ 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x20, 0x1c, 0x00, 0x00,
105
+ 0x00, 0x00, 0x00, 0x0c, 0x12, 0x10, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
106
+ 0x22, 0x22, 0x22, 0x1e, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00,
107
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c,
108
+ 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x00, 0x00, 0x20, 0x20, 0x24, 0x28, 0x38, 0x24, 0x22, 0x00, 0x00,
109
+ 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
110
+ 0x2a, 0x2a, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00,
111
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
112
+ 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x03,
113
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
114
+ 0x20, 0x1c, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x12, 0x0c, 0x00, 0x00,
115
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x26, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22,
116
+ 0x22, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x1c, 0x14, 0x00, 0x00,
117
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22,
118
+ 0x22, 0x22, 0x22, 0x1e, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x04, 0x08, 0x10, 0x3e, 0x00, 0x00,
119
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x20, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
120
+ 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x02, 0x04, 0x04, 0x08, 0x00, 0x00,
121
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x3e,
122
+ 0x04, 0x08, 0x00, 0x00, 0x00, 0x00,
123
+ ]);
124
+ }
package/src/app/app.js CHANGED
@@ -242,7 +242,7 @@ const template = [
242
242
  const result = await dialog.showOpenDialog(browserWindow, {
243
243
  title: "Load emulator state",
244
244
  filters: [
245
- { name: "Snapshot files", extensions: ["gz", "json", "snp"] },
245
+ { name: "Snapshot files", extensions: ["gz", "json", "snp", "uef"] },
246
246
  { name: "All files", extensions: ["*"] },
247
247
  ],
248
248
  properties: ["openFile"],
@@ -55,11 +55,11 @@ function init(args) {
55
55
 
56
56
  // Save settings when they change
57
57
  if (config) {
58
- config.on("settings-changed", (settings) => {
59
- api.saveSettings(settings);
58
+ config.addEventListener("settings-changed", (e) => {
59
+ api.saveSettings(e.detail);
60
60
  });
61
- config.on("media-changed", (media) => {
62
- api.saveSettings(media);
61
+ config.addEventListener("media-changed", (e) => {
62
+ api.saveSettings(e.detail);
63
63
  });
64
64
  }
65
65
  }
@@ -5,6 +5,8 @@ import { decompress } from "./utils.js";
5
5
  // v1 (BEMSNAP1): Fixed-size 327,885 byte packed struct. Reference: beebjit state.c
6
6
  // v3 (BEMSNAP3): Section-based with key+size headers, zlib-compressed memory. Reference: b-em savestate.c
7
7
 
8
+ import { volumeTable, buildVideoState, buildSnapshot } from "./snapshot-helpers.js";
9
+
8
10
  const BemV1Size = 327885;
9
11
 
10
12
  // v1 struct offsets
@@ -114,7 +116,7 @@ function convertViaState(bemVia, ic32) {
114
116
  t2l: bemVia.t2l,
115
117
  t1c: bemVia.t1c,
116
118
  t2c: bemVia.t2c,
117
- t1hit: !!bemVia.t1hit,
119
+ t1hit: bemVia.acr & 0x40 ? false : !!bemVia.t1hit,
118
120
  t2hit: !!bemVia.t2hit,
119
121
  portapins: 0xff,
120
122
  portbpins: 0xff,
@@ -135,17 +137,6 @@ function convertViaState(bemVia, ic32) {
135
137
  return result;
136
138
  }
137
139
 
138
- // Volume lookup table matching soundchip.js
139
- const volumeTable = new Float32Array(16);
140
- (() => {
141
- let f = 1.0;
142
- for (let i = 0; i < 15; ++i) {
143
- volumeTable[i] = f / 4;
144
- f *= Math.pow(10, -0.1);
145
- }
146
- volumeTable[15] = 0;
147
- })();
148
-
149
140
  function convertSoundState(snLatch, snCount, snStat, snVol, snNoise, snShift) {
150
141
  const registers = new Uint16Array(4);
151
142
  const counter = new Float32Array(4);
@@ -181,178 +172,6 @@ function convertSoundState(snLatch, snCount, snStat, snVol, snNoise, snShift) {
181
172
  };
182
173
  }
183
174
 
184
- function buildVideoState(ulaControl, ulaPalette, crtcRegs, nulaCollook, crtcCounters) {
185
- const regs = new Uint8Array(32);
186
- regs.set(crtcRegs.slice(0, 18));
187
- const actualPal = new Uint8Array(16);
188
- for (let i = 0; i < 16; i++) actualPal[i] = ulaPalette[i] & 0x0f;
189
-
190
- // Use NULA collook if provided, otherwise use default BBC palette
191
- const collook =
192
- nulaCollook ||
193
- new Int32Array([
194
- 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff, 0xff000000,
195
- 0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
196
- ]);
197
-
198
- // Compute ulaPal from actualPal + collook, matching jsbeeb's Ula._recomputeUlaPal
199
- const flashEnabled = !!(ulaControl & 1);
200
- const defaultFlash = new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1]);
201
- const flash = defaultFlash;
202
- const ulaPal = new Int32Array(16);
203
- for (let i = 0; i < 16; i++) {
204
- const palVal = actualPal[i];
205
- let colour = collook[(palVal & 0xf) ^ 7];
206
- if (palVal & 8 && flashEnabled && flash[(palVal & 7) ^ 7]) {
207
- colour = collook[palVal & 0xf];
208
- }
209
- ulaPal[i] = colour;
210
- }
211
-
212
- return {
213
- regs,
214
- bitmapX: 0,
215
- bitmapY: 0,
216
- oddClock: false,
217
- frameCount: 0,
218
- doEvenFrameLogic: false,
219
- isEvenRender: true,
220
- lastRenderWasEven: false,
221
- firstScanline: true,
222
- inHSync: false,
223
- inVSync: false,
224
- hadVSyncThisRow: false,
225
- checkVertAdjust: false,
226
- endOfMainLatched: false,
227
- endOfVertAdjustLatched: false,
228
- endOfFrameLatched: false,
229
- inVertAdjust: false,
230
- inDummyRaster: false,
231
- hpulseWidth: regs[3] & 0x0f,
232
- vpulseWidth: (regs[3] & 0xf0) >>> 4,
233
- hpulseCounter: 0,
234
- vpulseCounter: 0,
235
- dispEnabled: 0x3f,
236
- horizCounter: crtcCounters ? crtcCounters.hc : 0,
237
- vertCounter: crtcCounters ? crtcCounters.vc : 0,
238
- scanlineCounter: crtcCounters ? crtcCounters.sc : 0,
239
- vertAdjustCounter: 0,
240
- addr: crtcCounters ? crtcCounters.ma : (regs[13] | (regs[12] << 8)) & 0x3fff,
241
- lineStartAddr: crtcCounters ? crtcCounters.maback : (regs[13] | (regs[12] << 8)) & 0x3fff,
242
- nextLineStartAddr: crtcCounters ? crtcCounters.maback : (regs[13] | (regs[12] << 8)) & 0x3fff,
243
- ulactrl: ulaControl,
244
- pixelsPerChar: ulaControl & 0x10 ? 8 : 16,
245
- halfClock: !(ulaControl & 0x10),
246
- ulaMode: (ulaControl >>> 2) & 3,
247
- teletextMode: !!(ulaControl & 2),
248
- displayEnableSkew: Math.min((regs[8] & 0x30) >>> 4, 2),
249
- ulaPal,
250
- actualPal,
251
- cursorOn: false,
252
- cursorOff: false,
253
- cursorOnThisFrame: false,
254
- cursorDrawIndex: 0,
255
- cursorPos: (regs[15] | (regs[14] << 8)) & 0x3fff,
256
- interlacedSyncAndVideo: (regs[8] & 3) === 3,
257
- screenSubtract: 0,
258
- ula: {
259
- collook: collook.slice(),
260
- flash: new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1]),
261
- paletteWriteFlag: false,
262
- paletteFirstByte: 0,
263
- paletteMode: 0,
264
- horizontalOffset: 0,
265
- leftBlank: 0,
266
- disabled: false,
267
- attributeMode: 0,
268
- attributeText: 0,
269
- },
270
- crtc: { curReg: 0 },
271
- teletext: {
272
- prevCol: 0,
273
- col: 7,
274
- bg: 0,
275
- sep: false,
276
- dbl: false,
277
- oldDbl: false,
278
- secondHalfOfDouble: false,
279
- wasDbl: false,
280
- gfx: false,
281
- flash: false,
282
- flashOn: false,
283
- flashTime: 0,
284
- heldChar: 0,
285
- holdChar: false,
286
- dataQueue: [0, 0, 0, 0],
287
- scanlineCounter: 0,
288
- levelDEW: false,
289
- levelDISPTMG: false,
290
- levelRA0: false,
291
- nextGlyphs: "normal",
292
- curGlyphs: "normal",
293
- heldGlyphs: "normal",
294
- },
295
- };
296
- }
297
-
298
- const DefaultAcia = {
299
- sr: 0x02,
300
- cr: 0x00,
301
- dr: 0x00,
302
- rs423Selected: false,
303
- motorOn: false,
304
- tapeCarrierCount: 0,
305
- tapeDcdLineLevel: false,
306
- hadDcdHigh: false,
307
- serialReceiveRate: 19200,
308
- serialReceiveCyclesPerByte: 0,
309
- txCompleteTaskOffset: null,
310
- runTapeTaskOffset: null,
311
- runRs423TaskOffset: null,
312
- };
313
-
314
- const DefaultAdc = { status: 0x40, low: 0x00, high: 0x00, taskOffset: null };
315
-
316
- function buildSnapshot(modelName, cpuState, ram, roms, sysvia, uservia, video, soundChip) {
317
- return {
318
- format: "jsbeeb-snapshot",
319
- version: 1,
320
- model: modelName,
321
- timestamp: new Date().toISOString(),
322
- importedFrom: "b-em",
323
- state: {
324
- a: cpuState.a,
325
- x: cpuState.x,
326
- y: cpuState.y,
327
- s: cpuState.s,
328
- pc: cpuState.pc,
329
- p: cpuState.flags | 0x30,
330
- nmiLevel: !!cpuState.nmi,
331
- nmiEdge: false,
332
- halted: false,
333
- takeInt: false,
334
- romsel: cpuState.fe30 ?? 0,
335
- acccon: cpuState.fe34 ?? 0,
336
- videoDisplayPage: 0,
337
- currentCycles: 0,
338
- targetCycles: 0,
339
- cycleSeconds: 0,
340
- peripheralCycles: 0,
341
- videoCycles: 0,
342
- music5000PageSel: 0,
343
- ram,
344
- roms,
345
- scheduler: { epoch: 0 },
346
- sysvia,
347
- uservia,
348
- video,
349
- soundChip,
350
- acia: { ...DefaultAcia },
351
- adc: { ...DefaultAdc },
352
- },
353
- };
354
- }
355
-
356
175
  // ── V1 parser (BEMSNAP1, fixed struct) ──────────────────────────────
357
176
 
358
177
  function parseBemV1(buffer) {
@@ -402,6 +221,7 @@ function parseBemV1(buffer) {
402
221
  const snShift = view.getUint16(soundOff + 53, true);
403
222
 
404
223
  return buildSnapshot(
224
+ "b-em",
405
225
  "B",
406
226
  cpuState,
407
227
  ram,
@@ -637,6 +457,7 @@ function finishV3Parse(modelName, cpuState, ram, roms, sections) {
637
457
  }
638
458
 
639
459
  return buildSnapshot(
460
+ "b-em",
640
461
  modelName,
641
462
  cpuState,
642
463
  ram,
package/src/config.js CHANGED
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
- import EventEmitter from "event-emitter-es6";
3
- import { findModel } from "./models.js";
2
+ import { allModels, findModel } from "./models.js";
4
3
  import { getFilterForMode } from "./canvas.js";
5
4
 
6
- export class Config extends EventEmitter {
5
+ export class Config extends EventTarget {
7
6
  constructor(onChange, onClose) {
8
7
  super();
9
8
  this.onChange = onChange;
@@ -25,16 +24,28 @@ export class Config extends EventEmitter {
25
24
  configuration.addEventListener("hide.bs.modal", () => {
26
25
  this.onClose(this.changed);
27
26
  if (Object.keys(this.changed).length > 0) {
28
- this.emit("settings-changed", this.changed);
27
+ this.dispatchEvent(new CustomEvent("settings-changed", { detail: this.changed }));
29
28
  }
30
29
  });
31
30
 
32
- for (const link of document.querySelectorAll(".model-menu a")) {
33
- link.addEventListener("click", (e) => {
34
- this.changed.model = e.target.dataset.target;
35
- this.setDropdownText(e.target.textContent);
36
- });
31
+ const modelMenu = document.querySelector(".model-menu");
32
+ for (const model of allModels) {
33
+ if (model.synonyms.length === 0) continue; // skip non-selectable models (e.g. Tube65C02)
34
+ const li = document.createElement("li");
35
+ const a = document.createElement("a");
36
+ a.href = "#";
37
+ a.className = "dropdown-item";
38
+ a.dataset.target = model.synonyms[0];
39
+ a.textContent = model.name;
40
+ li.appendChild(a);
41
+ modelMenu.appendChild(li);
37
42
  }
43
+ modelMenu.addEventListener("click", (e) => {
44
+ const link = e.target.closest("a[data-target]");
45
+ if (!link) return;
46
+ this.changed.model = link.dataset.target;
47
+ this.setDropdownText(link.textContent);
48
+ });
38
49
 
39
50
  document.getElementById("65c02").addEventListener("click", () => {
40
51
  this.changed.coProcessor = document.getElementById("65c02").checked;
package/src/disc.js CHANGED
@@ -1,25 +1,7 @@
1
1
  // Translated from beebjit by Chris Evans.
2
2
  // https://github.com/scarybeasts/beebjit
3
3
 
4
- import * as utils from "./utils.js";
5
-
6
- /**
7
- * Compute CRC32 of a Uint8Array.
8
- * @param {Uint8Array} data
9
- * @returns {number} CRC32 as a signed 32-bit integer
10
- */
11
- export function crc32(data) {
12
- let crc = 0xffffffff;
13
- for (let i = 0; i < data.length; ++i) {
14
- crc ^= data[i];
15
- for (let j = 0; j < 8; ++j) {
16
- const doEor = crc & 1;
17
- crc = crc >>> 1;
18
- if (doEor) crc ^= 0xedb88320;
19
- }
20
- }
21
- return ~crc;
22
- }
4
+ import { hexbyte, crc32 } from "./utils.js";
23
5
  class TrackBuilder {
24
6
  /**
25
7
  * @param {Track} track
@@ -482,7 +464,7 @@ class Track {
482
464
  }
483
465
  break;
484
466
  default:
485
- console.log(`Unknown marker byte ${utils.hexbyte(dataByte)} ${this.description}`);
467
+ console.log(`Unknown marker byte ${hexbyte(dataByte)} ${this.description}`);
486
468
  }
487
469
  }
488
470
  return sectors;
package/src/fake6502.js CHANGED
@@ -6,7 +6,7 @@ import { FakeSoundChip } from "./soundchip.js";
6
6
  import { findModel, TEST_6502, TEST_65C02, TEST_65C12 } from "./models.js";
7
7
  import { FakeDdNoise } from "./ddnoise.js";
8
8
  import { FakeRelayNoise } from "./relaynoise.js";
9
- import { Cpu6502 } from "./6502.js";
9
+ import { Cpu6502, AtomCpu6502 } from "./6502.js";
10
10
  import { Cmos } from "./cmos.js";
11
11
  import { FakeMusic5000 } from "./music5000.js";
12
12
 
@@ -20,7 +20,8 @@ export function fake6502(model, opts) {
20
20
  opts = opts || {};
21
21
  model = model || TEST_6502;
22
22
  if (opts.tube) model.tube = findModel("Tube65c02");
23
- return new Cpu6502(model, {
23
+ const CpuClass = model.isAtom ? AtomCpu6502 : Cpu6502;
24
+ return new CpuClass(model, {
24
25
  dbgr,
25
26
  video: opts.video || fakeVideo,
26
27
  soundChip: opts.soundChip || soundChip,
package/src/jsbeeb.css CHANGED
@@ -188,6 +188,29 @@ div.led {
188
188
  background-image: url(/images/yellow-on-16.png);
189
189
  }
190
190
 
191
+ .tape-btn {
192
+ background: #333;
193
+ color: #ccc;
194
+ border: 1px solid #666;
195
+ border-radius: 3px;
196
+ font-size: 10px;
197
+ width: 20px;
198
+ height: 18px;
199
+ padding: 0;
200
+ line-height: 18px;
201
+ cursor: pointer;
202
+ text-align: center;
203
+ }
204
+
205
+ .tape-btn:hover {
206
+ background: #555;
207
+ color: #fff;
208
+ }
209
+
210
+ .tape-btn.playing {
211
+ color: #4c4;
212
+ }
213
+
191
214
  #pages {
192
215
  margin-top: 10px;
193
216
  }