aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/cpu.ts
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cpu/cpu.ts30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/cpu/cpu.ts b/src/cpu/cpu.ts
index 4065b0a..6da0fee 100644
--- a/src/cpu/cpu.ts
+++ b/src/cpu/cpu.ts
@@ -59,6 +59,21 @@ export class CPU {
*/
readonly pc22Bits = this.progBytes.length > 0x20000;
+ /**
+ * Offset applied to data-space addresses in readData/writeData.
+ * Classic AVR (ATmega): 0 — data addresses map 1:1 to the data array.
+ * Modern AVR (AVR-Dx, avrxmega3): 32 — data addresses are shifted by 32
+ * to avoid collision with R0-R31 which occupy data[0..31].
+ */
+ readonly dataMemoryOffset: number;
+
+ /**
+ * Offset added to I/O addresses for IN/OUT/SBI/CBI/SBIS/SBIC instructions.
+ * Classic AVR (ATmega): 32 — I/O space starts at data address 0x20.
+ * Modern AVR (AVR-Dx): 0 — readData applies dataMemoryOffset instead.
+ */
+ readonly ioOffset: number;
+
readonly gpioPorts = new Set<AVRIOPort>();
readonly gpioByPort: AVRIOPort[] = [];
@@ -71,6 +86,14 @@ export class CPU {
};
/**
+ * This function is called by the SLEEP instruction. The sleep controller peripheral
+ * attaches to it to handle sleep modes (e.g., fast-forwarding to the next clock event).
+ */
+ onSleep = () => {
+ /* empty by default */
+ };
+
+ /**
* Program counter
*/
pc: u32 = 0;
@@ -86,7 +109,10 @@ export class CPU {
constructor(
public progMem: Uint16Array,
private sramBytes = 8192,
+ { dataMemoryOffset = 0, ioOffset = 32 }: { dataMemoryOffset?: number; ioOffset?: number } = {},
) {
+ this.dataMemoryOffset = dataMemoryOffset;
+ this.ioOffset = ioOffset;
this.reset();
}
@@ -99,13 +125,15 @@ export class CPU {
}
readData(addr: number) {
- if (addr >= 32 && this.readHooks[addr]) {
+ addr += this.dataMemoryOffset;
+ if (this.readHooks[addr]) {
return this.readHooks[addr](addr);
}
return this.data[addr];
}
writeData(addr: number, value: number, mask = 0xff) {
+ addr += this.dataMemoryOffset;
const hook = this.writeHooks[addr];
if (hook) {
if (hook(value, this.data[addr], addr, mask)) {