jsbeeb 1.7.0 → 1.8.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.
- package/package.json +1 -1
- package/tests/test-machine.js +58 -3
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"name": "jsbeeb",
|
|
8
8
|
"description": "Emulate a BBC Micro",
|
|
9
9
|
"repository": "git@github.com:mattgodbolt/jsbeeb.git",
|
|
10
|
-
"version": "1.
|
|
10
|
+
"version": "1.8.0",
|
|
11
11
|
"//": "If you change the version of Node, it must also be updated at the top of the Dockerfile.",
|
|
12
12
|
"engines": {
|
|
13
13
|
"node": "22"
|
package/tests/test-machine.js
CHANGED
|
@@ -102,6 +102,22 @@ export class TestMachine {
|
|
|
102
102
|
this.processor.fdc.loadDisc(0, fdc.discFor(this.processor.fdc, "", data));
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Load a disc image from raw data (Uint8Array or Buffer).
|
|
107
|
+
* @param {Uint8Array|Buffer} data - raw disc image bytes
|
|
108
|
+
*/
|
|
109
|
+
loadDiscData(data) {
|
|
110
|
+
this.processor.fdc.loadDisc(0, fdc.discFor(this.processor.fdc, "", data));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Reset the machine.
|
|
115
|
+
* @param {boolean} hard - true for power-on reset, false for soft reset
|
|
116
|
+
*/
|
|
117
|
+
reset(hard) {
|
|
118
|
+
this.processor.reset(hard);
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
async loadBasic(source) {
|
|
106
122
|
const tokeniser = await Tokeniser.create();
|
|
107
123
|
const tokenised = tokeniser.tokenise(source);
|
|
@@ -186,8 +202,19 @@ export class TestMachine {
|
|
|
186
202
|
return { code: utils.keyCodes.K4, shift: true };
|
|
187
203
|
case "%":
|
|
188
204
|
return { code: utils.keyCodes.K5, shift: true };
|
|
189
|
-
default:
|
|
190
|
-
|
|
205
|
+
default: {
|
|
206
|
+
const upper = ch.toUpperCase();
|
|
207
|
+
const isLetter = (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
|
|
208
|
+
if (isLetter) {
|
|
209
|
+
const wantUpper = ch >= "A" && ch <= "Z";
|
|
210
|
+
const capsOn = this.processor.sysvia.capsLockLight;
|
|
211
|
+
// CAPS LOCK on: unshifted = upper, shifted = lower
|
|
212
|
+
// CAPS LOCK off: unshifted = lower, shifted = upper
|
|
213
|
+
const needShift = capsOn ? !wantUpper : wantUpper;
|
|
214
|
+
return { code: upper.charCodeAt(0), shift: needShift };
|
|
215
|
+
}
|
|
216
|
+
return { code: ch.charCodeAt(0), shift: false };
|
|
217
|
+
}
|
|
191
218
|
}
|
|
192
219
|
}
|
|
193
220
|
|
|
@@ -201,7 +228,7 @@ export class TestMachine {
|
|
|
201
228
|
async type(text) {
|
|
202
229
|
const fullText = text + "\n"; // append RETURN
|
|
203
230
|
const keys = fullText.split("").map((ch) => this._charToKey(ch));
|
|
204
|
-
const holdCycles = 40000;
|
|
231
|
+
const holdCycles = 40000;
|
|
205
232
|
let index = 0;
|
|
206
233
|
let phase = "idle"; // "idle" → "down" → "idle"
|
|
207
234
|
let nextEventCycle = 0;
|
|
@@ -246,6 +273,34 @@ export class TestMachine {
|
|
|
246
273
|
}
|
|
247
274
|
}
|
|
248
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Press a key on the BBC keyboard.
|
|
278
|
+
* @param {number} code - BBC key code (e.g. utils.keyCodes.SPACE)
|
|
279
|
+
*/
|
|
280
|
+
keyDown(code) {
|
|
281
|
+
this.processor.sysvia.keyDown(code);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Release a key on the BBC keyboard.
|
|
286
|
+
* @param {number} code - BBC key code
|
|
287
|
+
*/
|
|
288
|
+
keyUp(code) {
|
|
289
|
+
this.processor.sysvia.keyUp(code);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Load a ROM image directly into a sideways RAM slot.
|
|
294
|
+
* @param {number} slot - slot number (0-15, typically 4-7 for SWRAM)
|
|
295
|
+
* @param {Uint8Array|Buffer} data - ROM data (up to 16384 bytes)
|
|
296
|
+
*/
|
|
297
|
+
loadSidewaysRam(slot, data) {
|
|
298
|
+
const offset = this.processor.romOffset + slot * 16384;
|
|
299
|
+
for (let i = 0; i < data.length && i < 16384; i++) {
|
|
300
|
+
this.processor.ramRomOs[offset + i] = data[i];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
249
304
|
writebyte(addr, val) {
|
|
250
305
|
this.processor.writemem(addr, val);
|
|
251
306
|
}
|