diff options
| -rw-r--r-- | src/cpu.spec.ts | 8 | ||||
| -rw-r--r-- | src/cpu.ts | 13 | ||||
| -rw-r--r-- | src/instruction.spec.ts | 8 | ||||
| -rw-r--r-- | src/interrupt.spec.ts | 1 |
4 files changed, 28 insertions, 2 deletions
diff --git a/src/cpu.spec.ts b/src/cpu.spec.ts new file mode 100644 index 0000000..92df7ee --- /dev/null +++ b/src/cpu.spec.ts @@ -0,0 +1,8 @@ +import { CPU } from './cpu'; + +describe('cpu', () => { + it('should set initial value of SP to the last address of internal SRAM', () => { + const cpu = new CPU(new Uint16Array(1024), 0x1000); + expect(cpu.SP).toEqual(0x10ff); + }); +}); @@ -7,6 +7,8 @@ import { u16, u8 } from './types'; +const registerSpace = 0x100; + export interface ICPU { readonly data: Uint8Array; readonly dataView: DataView; @@ -25,7 +27,7 @@ export interface ICPUMemoryHooks { } export class CPU implements ICPU { - readonly data = new Uint8Array(16384); + readonly data: Uint8Array = new Uint8Array(this.sramBytes + registerSpace); readonly data16 = new Uint16Array(this.data.buffer); readonly dataView = new DataView(this.data.buffer); readonly progBytes = new Uint8Array(this.progMem.buffer); @@ -34,7 +36,14 @@ export class CPU implements ICPU { pc = 0; cycles = 0; - constructor(public progMem: Uint16Array) {} + constructor(public progMem: Uint16Array, private sramBytes = 8192) { + this.reset(); + } + + reset() { + this.data.fill(0); + this.SP = this.data.length - 1; + } readData(addr: number) { return this.data[addr]; diff --git a/src/instruction.spec.ts b/src/instruction.spec.ts index a63dc67..2ffbe3c 100644 --- a/src/instruction.spec.ts +++ b/src/instruction.spec.ts @@ -111,6 +111,7 @@ describe('avrInstruction', () => { it('should execute `CALL` instruction', () => { loadProgram('0e945c00'); + cpu.data[94] = 0; cpu.data[93] = 150; // SP <- 50 avrInstruction(cpu); expect(cpu.pc).toEqual(0x5c); @@ -178,6 +179,7 @@ describe('avrInstruction', () => { it('should execute `ICALL` instruction', () => { loadProgram('0995'); + cpu.data[94] = 0; cpu.data[93] = 0x80; cpu.dataView.setUint16(30, 0x2020, true); // Z <- 0x2020 avrInstruction(cpu); @@ -554,6 +556,7 @@ describe('avrInstruction', () => { it('should execute `POP r26` instruction', () => { loadProgram('af91'); + cpu.data[94] = 0; cpu.data[93] = 0xff; // SP <- 0xff cpu.data[0x100] = 0x1a; avrInstruction(cpu); @@ -566,6 +569,7 @@ describe('avrInstruction', () => { it('should execute `PUSH r11` instruction', () => { loadProgram('bf92'); cpu.data[11] = 0x2a; + cpu.data[94] = 0; cpu.data[93] = 0xff; // SP <- 0xff avrInstruction(cpu); expect(cpu.pc).toEqual(0x1); @@ -576,6 +580,7 @@ describe('avrInstruction', () => { it('should execute `RCALL .+6` instruction', () => { loadProgram('03d0'); + cpu.data[94] = 0; cpu.data[93] = 0x80; // SP <- 0x80 avrInstruction(cpu); expect(cpu.pc).toEqual(4); @@ -586,6 +591,7 @@ describe('avrInstruction', () => { it('should execute `RCALL .-4` instruction', () => { loadProgram('0000fedf'); + cpu.data[94] = 0; cpu.data[93] = 0x80; // SP <- 0x80 avrInstruction(cpu); avrInstruction(cpu); @@ -597,6 +603,7 @@ describe('avrInstruction', () => { it('should execute `RET` instruction', () => { loadProgram('0895'); + cpu.data[94] = 0; cpu.data[93] = 0x90; // SP <- 0x90 cpu.data[0x92] = 16; avrInstruction(cpu); @@ -607,6 +614,7 @@ describe('avrInstruction', () => { it('should execute `RETI` instruction', () => { loadProgram('1895'); + cpu.data[94] = 0; cpu.data[93] = 0xc0; // SP <- 0xc0 cpu.data[0xc2] = 200; avrInstruction(cpu); diff --git a/src/interrupt.spec.ts b/src/interrupt.spec.ts index 06979ed..cc54e3c 100644 --- a/src/interrupt.spec.ts +++ b/src/interrupt.spec.ts @@ -5,6 +5,7 @@ describe('avrInterrupt', () => { it('should execute interrupt handler', () => { const cpu = new CPU(new Uint16Array(0x8000)); cpu.pc = 0x520; + cpu.data[94] = 0; cpu.data[93] = 0x80; // SP <- 0x80 cpu.data[95] = 0b10000001; // SREG <- I------C avrInterrupt(cpu, 5); |
