forked from mattgodbolt/jsbeeb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
basic-tokenise.js
67 lines (65 loc) · 2.64 KB
/
basic-tokenise.js
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
define(['utils', 'models', 'fake6502', 'promise'],
function (utils, models, Fake6502) {
"use strict";
function create() {
var cpu = Fake6502.fake6502(models.basicOnly);
var callTokeniser = function (line) {
// With thanks to http://8bs.com/basic/basic4-8db2.htm
cpu.pc = 0x8db2;
cpu.s = 0xf0;
var offset = 0x1000;
cpu.writemem(0x3b, 0x00);
cpu.writemem(0x3c, 0x00);
cpu.writemem(0x37, offset & 0xff);
cpu.writemem(0x38, (offset >>> 8) & 0xff);
cpu.writemem(0xfe30, 12);
for (var i = 0; i < line.length; ++i) {
cpu.writemem(offset + i, line.charCodeAt(i));
}
cpu.writemem(offset + line.length, 0x0d);
var safety = 20 * 1000 * 1000;
while (cpu.s <= 0xf0) {
cpu.execute(1);
if (--safety === 0) {
break;
}
}
var endOffset = cpu.readmem(0x37) | (cpu.readmem(0x38) << 8);
var result = "";
for (i = offset; i < endOffset; ++i) {
result += String.fromCharCode(cpu.readmem(i));
}
if (safety === 0) {
throw new Error("Unable to tokenize '" + line + "' - got as far as '" + result + "' pc=" + utils.hexword(cpu.pc));
}
return result;
};
var lineRe = /^([0-9]+)?(.*)/;
var tokeniseLine = function (line, lineNumIfNotSpec) {
var lineSplit = line.match(lineRe);
var lineNum = lineSplit[1] ? parseInt(lineSplit[1]) : lineNumIfNotSpec;
var tokens = callTokeniser(lineSplit[2]);
return '\r' +
String.fromCharCode((lineNum >>> 8) & 0xff) +
String.fromCharCode(lineNum & 0xff) +
String.fromCharCode(tokens.length + 4) + tokens;
};
var tokenise = function (text) {
var result = "";
text.split("\n").forEach(function (line, i) {
if (line) {
result += tokeniseLine(line, 10 + i * 10);
}
});
return result + "\r\xff";
};
return cpu.initialise().then(function () {
return Promise.resolve({
tokenise: tokenise
});
});
}
return {
create: create
};
});