-
Notifications
You must be signed in to change notification settings - Fork 4
/
bankswitcher.js
59 lines (52 loc) · 1.63 KB
/
bankswitcher.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
/** Sets up bank switching for the upper half of the RAM. */
export default class BankSwitcher {
/**
* @param {!Memory} mem
* @param {boolean} fds Whether to set up FDS bank switching.
*/
constructor(mem, fds) {
/** @private @const {!Memory} */
this.mem_ = mem;
/** @private @const {!Array<!Uint8Array>} */
this.pages_ = [];
for (let i = fds ? 6 : 8; i < 16; i++) {
mem.listen(0x5FF0 + i, page => this.swap_(i, page));
}
}
get pages() {
return this.pages_.length;
}
/**
* Loads the banks.
* @param {!Uint8Array} data
* @param {number} padding Padding, only the low 12 bits are used.
*/
load(data, padding) {
padding &= 0xfff;
let bufferSize = padding + data.length;
if (bufferSize & 0xfff) bufferSize = ((bufferSize & ~0xfff) + 0x1000);
let buffer;
if (data.length < bufferSize) {
buffer = new Uint8Array(bufferSize);
buffer.set(data, padding);
} else {
buffer = data;
}
for (let i = 0; i < (bufferSize >>> 12); i++) {
this.pages_[i] = new Uint8Array(buffer.buffer, i << 12, 0x1000);
}
console.log('Loaded ' + this.pages_.length + ' pages from ' + data.length);
}
/**
* @param {number} bank The bank index to fill.
* @param {number} page The page number to load from.
* @private
*/
swap_(bank, page) {
console.log('BANK SWITCH: ' + bank + ' <= ' + page);
if (!this.pages_.length) return; // bank switching not loaded/enabled
if (page >= this.pages_.length) throw new Error('invalid bank index');
this.mem_.load(this.pages_[page], (bank & 0xf) << 12);
console.log(' ==> done');
}
}