This commit is contained in:
1 parent
2127f5f459
commit
8b80d05ca2
56 files changed
+6910
-1
No files matched your search
@@ -0,0 +1,54 @@
|
||||
/** Bounds-checked access to the user's cartridge. No CPU or hardware state. */
|
||||
export class RomReader {
|
||||
constructor(readonly bytes: Uint8Array) {}
|
||||
byte(offset: number): number {
|
||||
this.check(offset, 1);
|
||||
return this.bytes[offset];
|
||||
}
|
||||
word(offset: number): number {
|
||||
return this.byte(offset) | (this.byte(offset + 1) << 8);
|
||||
}
|
||||
slice(offset: number, length: number): Uint8Array {
|
||||
this.check(offset, length);
|
||||
return this.bytes.slice(offset, offset + length);
|
||||
}
|
||||
address(bank: number, address: number): number {
|
||||
if (
|
||||
!Number.isInteger(bank) ||
|
||||
bank < 0 ||
|
||||
bank >= this.bytes.length / 0x4000 ||
|
||||
!Number.isInteger(address) ||
|
||||
address < 0 ||
|
||||
address >= 0x8000
|
||||
) {
|
||||
throw new Error("Invalid ROM bank or address.");
|
||||
}
|
||||
const offset =
|
||||
address < 0x4000 ? address : bank * 0x4000 + address - 0x4000;
|
||||
this.check(offset, 1);
|
||||
return offset;
|
||||
}
|
||||
near(pointer: number, bank: number): number {
|
||||
return this.address(bank, this.word(pointer));
|
||||
}
|
||||
far(pointer: number): number {
|
||||
return this.near(pointer + 1, this.byte(pointer));
|
||||
}
|
||||
bank(offset: number): number {
|
||||
this.check(offset, 1);
|
||||
return Math.floor(offset / 0x4000);
|
||||
}
|
||||
private check(offset: number, length: number) {
|
||||
if (
|
||||
!Number.isInteger(offset) ||
|
||||
!Number.isInteger(length) ||
|
||||
offset < 0 ||
|
||||
length < 0 ||
|
||||
offset + length > this.bytes.length
|
||||
) {
|
||||
throw new Error(
|
||||
"Cartridge data is truncated or contains an invalid pointer.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user