Skip to content

Commit 9942351

Browse files
committed
Improve test-suite
1 parent dacc75c commit 9942351

File tree

1 file changed

+121
-77
lines changed

1 file changed

+121
-77
lines changed

tests/test-suite.js

Lines changed: 121 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,107 +4,151 @@ import * as utils from "../utils.js";
44
import { fake6502 } from "../fake6502.js";
55

66
const processor = fake6502();
7-
const irqRoutine = [
8-
0x48, 0x8a, 0x48, 0x98, 0x48, 0xba, 0xbd, 0x04, 0x01, 0x29, 0x10, 0xf0, 0x03, 0x6c, 0x16, 0x03, 0x6c, 0x14, 0x03,
7+
const IRQ_ROUTINE_START = 0xff48;
8+
const RTS_OPCODE = 0x60;
9+
const NOP_OPCODE = 0xea;
10+
const IRQ_ROUTINE = [
11+
0x48, // PHA
12+
0x8a, // TXA
13+
0x48, // PHA
14+
0x98, // TYA
15+
0x48, // PHA
16+
0xba, // TSX
17+
0xbd,
18+
0x04,
19+
0x01, // LDA $0104,X
20+
0x29,
21+
0x10, // AND #$10
22+
0xf0,
23+
0x03, // BEQ $03
24+
0x6c,
25+
0x16,
26+
0x03, // JMP ($0316)
27+
0x6c,
28+
0x14,
29+
0x03, // JMP ($0314)
930
];
1031

11-
function setup(filename) {
32+
async function setup(filename) {
33+
try {
34+
initializeMemory();
35+
await loadTest(filename);
36+
setupIRQRoutine();
37+
setupProcessor();
38+
} catch (error) {
39+
console.error(`Error in setup: ${error.message}`);
40+
}
41+
}
42+
43+
function initializeMemory() {
1244
for (let i = 0x0000; i < 0xffff; ++i) processor.writemem(i, 0x00);
13-
return utils.loadData("tests/suite/bin/" + filename).then(function (data) {
14-
const addr = data[0] + (data[1] << 8);
15-
console.log(">> Loading test '" + filename + "' at " + utils.hexword(addr));
16-
for (let i = 2; i < data.length; ++i) processor.writemem(addr + i - 2, data[i]);
17-
for (let i = 0; i < irqRoutine.length; ++i) processor.writemem(0xff48 + i, irqRoutine[i]);
18-
19-
processor.writemem(0x0002, 0x00);
20-
processor.writemem(0xa002, 0x00);
21-
processor.writemem(0xa003, 0x80); // Docs say put zero here, but this works better.
22-
processor.writemem(0x01fe, 0xff);
23-
processor.writemem(0x01ff, 0x7f);
24-
25-
// Put RTSes in some of the stubbed calls
26-
processor.writemem(0xffd2, 0x60);
27-
processor.writemem(0x8000, 0x60);
28-
processor.writemem(0xa474, 0x60);
29-
// NOP the loading routine
30-
processor.writemem(0xe16f, 0xea);
31-
// scan keyboard is LDA #3: RTS
32-
processor.writemem(0xffe4, 0xa9);
33-
processor.writemem(0xffe5, 0x03);
34-
processor.writemem(0xffe6, 0x60);
35-
processor.writemem(0xfffe, 0x48);
36-
processor.writemem(0xffff, 0xff);
37-
38-
processor.s = 0xfd;
39-
processor.p.reset();
40-
processor.p.i = true;
41-
processor.pc = 0x0801;
42-
});
45+
}
46+
47+
async function loadTest(filename) {
48+
const data = await utils.loadData(`tests/suite/bin/${filename}`);
49+
const addr = data[0] + (data[1] << 8);
50+
console.log(`>> Loading test '${filename}' at ${utils.hexword(addr)}`);
51+
for (let i = 2; i < data.length; ++i) processor.writemem(addr + i - 2, data[i]);
52+
}
53+
54+
function setupIRQRoutine() {
55+
for (let i = 0; i < IRQ_ROUTINE.length; ++i) processor.writemem(IRQ_ROUTINE_START + i, IRQ_ROUTINE[i]);
56+
}
57+
58+
function setupProcessor() {
59+
processor.writemem(0x0002, 0x00);
60+
processor.writemem(0xa002, 0x00);
61+
processor.writemem(0xa003, 0x80);
62+
processor.writemem(0x01fe, 0xff);
63+
processor.writemem(0x01ff, 0x7f);
64+
processor.writemem(0xffd2, RTS_OPCODE);
65+
processor.writemem(0x8000, RTS_OPCODE);
66+
processor.writemem(0xa474, RTS_OPCODE);
67+
processor.writemem(0xe16f, NOP_OPCODE);
68+
processor.writemem(0xffe4, 0xa9);
69+
processor.writemem(0xffe5, 0x03);
70+
processor.writemem(0xffe6, RTS_OPCODE);
71+
processor.writemem(0xfffe, 0x48);
72+
processor.writemem(0xffff, 0xff);
73+
processor.s = 0xfd;
74+
processor.p.reset();
75+
processor.p.i = true;
76+
processor.pc = 0x0801;
4377
}
4478

4579
let curLine = "";
4680

4781
function petToAscii(char) {
48-
if (char === 14) return ""; // text mode
49-
if (char === 145) return ""; // up arrow
50-
if (char === 147) return "\n-------\n"; // Clear
51-
if (char >= 0xc1 && char <= 0xda) char = char - 0xc1 + 65;
52-
else if (char >= 0x41 && char <= 0x5a) char = char - 0x41 + 97;
53-
else if (char < 32 || char >= 127) {
54-
char = 46;
55-
}
82+
if (char === 14 || char === 145) return "";
83+
if (char === 147) return "\n-------\n";
84+
if (char >= 0xc1 && char <= 0xda) return String.fromCharCode(char - 0xc1 + 65);
85+
if (char >= 0x41 && char <= 0x5a) return String.fromCharCode(char - 0x41 + 97);
86+
if (char < 32 || char >= 127) return ".";
5687
return String.fromCharCode(char);
5788
}
5889

59-
processor.debugInstruction.add(function (addr) {
90+
processor.debugInstruction.add((addr) => {
6091
switch (addr) {
6192
case 0xffd2:
62-
if (processor.a === 13) {
63-
console.log(curLine);
64-
curLine = "";
65-
} else {
66-
curLine += petToAscii(processor.a);
67-
}
68-
processor.writemem(0x030c, 0x00);
93+
handlePrint();
6994
break;
70-
case 0xe16f: {
71-
const filenameAddr = processor.readmem(0xbb) | (processor.readmem(0xbc) << 8);
72-
const filenameLen = processor.readmem(0xb7);
73-
let filename = "";
74-
for (let i = 0; i < filenameLen; ++i) filename += petToAscii(processor.readmem(filenameAddr + i));
75-
if (filename === "trap17") {
76-
console.log("All tests complete");
77-
process.exit(0);
78-
}
79-
80-
setup(filename).then(anIter);
81-
processor.pc--; // Account for the instruction fetch
82-
return true; // Break out of the 'anIter' loop
83-
}
95+
case 0xe16f:
96+
handleLoad();
97+
return true;
8498
case 0x8000:
85-
case 0xa474: // Fail
86-
if (curLine.length) console.log(curLine);
87-
throw "Test failed";
88-
99+
case 0xa474:
100+
handleError();
101+
break;
89102
default:
90103
break;
91104
}
92105
return false;
93106
});
94107

108+
function handlePrint() {
109+
if (processor.a === 13) {
110+
console.log(curLine);
111+
curLine = "";
112+
} else {
113+
curLine += petToAscii(processor.a);
114+
}
115+
processor.writemem(0x030c, 0x00);
116+
}
117+
118+
function handleLoad() {
119+
const filenameAddr = processor.readmem(0xbb) | (processor.readmem(0xbc) << 8);
120+
const filenameLen = processor.readmem(0xb7);
121+
let filename = "";
122+
for (let i = 0; i < filenameLen; ++i) filename += petToAscii(processor.readmem(filenameAddr + i));
123+
if (filename === "trap17") {
124+
console.log("All tests complete");
125+
process.exit(0);
126+
}
127+
setup(filename).then(anIter);
128+
processor.pc--;
129+
return true;
130+
}
131+
132+
function handleError() {
133+
if (curLine.length) console.log(curLine);
134+
throw new Error("Test failed");
135+
}
136+
95137
function anIter() {
96138
for (;;) {
97139
if (!processor.execute(10 * 1000 * 1000)) return;
98140
}
99141
}
100142

101-
processor
102-
.initialise()
103-
.then(function () {
104-
if (process.argv.length === 3) {
105-
return setup(process.argv[2]);
106-
} else {
107-
return setup(" start");
108-
}
109-
})
110-
.then(anIter);
143+
async function main() {
144+
try {
145+
await processor.initialise();
146+
const filename = process.argv.length === 3 ? process.argv[2] : " start";
147+
await setup(filename);
148+
anIter();
149+
} catch (error) {
150+
console.error(`Error in main: ${error.message}`);
151+
}
152+
}
153+
154+
main().then(() => {});

0 commit comments

Comments
 (0)