mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2026-10-25 15:05:25 +00:00
45 lines
1.9 KiB
TypeScript
45 lines
1.9 KiB
TypeScript
import assert from "assert";
|
|
import { Atari800 } from "../../src/machine/atari8";
|
|
|
|
// build an XEX from [start, bytes] chunks
|
|
function xex(...chunks: [number, number[]][]): Uint8Array {
|
|
let out = [0xff, 0xff];
|
|
for (let [start, data] of chunks) {
|
|
let end = start + data.length - 1;
|
|
out.push(start & 0xff, start >> 8, end & 0xff, end >> 8, ...data);
|
|
}
|
|
return new Uint8Array(out);
|
|
}
|
|
|
|
describe('Atari 800 XEX loader', function () {
|
|
before(function () {
|
|
// the POKEY audio chain needs TSS's MasterChannel, which isn't loaded under node
|
|
(global as any).MasterChannel = class { addChannel() { } };
|
|
});
|
|
it('runs INIT before loading the next chunk', function () {
|
|
let m = new Atari800();
|
|
// chunk 1 is overwritten by chunk 2; its INIT must run first
|
|
let file = xex(
|
|
[0x2e00, [0x60]], // rts
|
|
[0x2e2, [0x00, 0x2e]], // INITAD = $2E00
|
|
[0x2000, new Array(0xe00).fill(0xea)], // overlaps $2E00
|
|
[0x2e0, [0x01, 0x20]]); // RUNAD = $2001
|
|
m.loadXEX(file);
|
|
// first chunk loaded, second not yet
|
|
assert.strictEqual(m.ram[0x2e00], 0x60);
|
|
assert.strictEqual(m.ram[0x2000], 0);
|
|
assert.deepStrictEqual(Array.from(m.d500.slice(0, 6)), [0x20, 0x00, 0x2e, 0x8d, 0xf2, 0xd5]);
|
|
// the stub's STA $D5F2 loads the rest
|
|
m.writeMapper(0xf2, 0);
|
|
assert.strictEqual(m.ram[0x2000], 0xea);
|
|
assert.deepStrictEqual(Array.from(m.d500.slice(6, 14)), [0xa9, 0xa0, 0x8d, 0xff, 0xd5, 0x4c, 0x01, 0x20]);
|
|
assert.strictEqual(m.run_address, 0xd500);
|
|
});
|
|
it('loads a plain XEX without INIT in one go', function () {
|
|
let m = new Atari800();
|
|
m.loadXEX(xex([0x2000, [1, 2, 3]], [0x2e0, [0x00, 0x20]]));
|
|
assert.strictEqual(m.ram[0x2002], 3);
|
|
assert.deepStrictEqual(Array.from(m.d500.slice(0, 8)), [0xa9, 0xa0, 0x8d, 0xff, 0xd5, 0x4c, 0x00, 0x20]);
|
|
});
|
|
});
|