diff options
| author | Uri Shaked | 2019-11-20 21:46:13 +0200 |
|---|---|---|
| committer | Uri Shaked | 2019-11-20 21:46:13 +0200 |
| commit | b7965c83e7e09590e746d8f5cac7cbacab1173ba (patch) | |
| tree | 254108e2aa7295bfdd28e42ce581a9e0e6006e21 /src/instruction.spec.ts | |
| parent | feat: LPM, LSR, MOV, MOVW, MUL, MULS, MULSU, NEG (diff) | |
| download | avr8js-b7965c83e7e09590e746d8f5cac7cbacab1173ba.tar.gz avr8js-b7965c83e7e09590e746d8f5cac7cbacab1173ba.tar.bz2 avr8js-b7965c83e7e09590e746d8f5cac7cbacab1173ba.zip | |
feat: implement most instructions
Diffstat (limited to '')
| -rw-r--r-- | src/instruction.spec.ts | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/instruction.spec.ts b/src/instruction.spec.ts index 9ab4a75..ccf8676 100644 --- a/src/instruction.spec.ts +++ b/src/instruction.spec.ts @@ -76,6 +76,15 @@ describe('avrInstruction', () => { expect(cpu.cycles).toEqual(1); }); + it('should execute `CBI 0x0c, 5`', () => { + loadProgram('6598'); + cpu.data[0x2c] = 0b11111111; + avrInstruction(cpu); + expect(cpu.pc).toEqual(1); + expect(cpu.cycles).toEqual(1); + expect(cpu.data[0x2c]).toEqual(0b11011111); + }); + it('should execute `CALL` instruction', () => { loadProgram('0e945c00'); cpu.data[93] = 150; // SP <- 50 @@ -105,6 +114,61 @@ describe('avrInstruction', () => { expect(cpu.data[95]).toEqual(0b00110101); // SREG: HSNC }); + it('should execute `CPSE r2, r3` when r2 != r3', () => { + loadProgram('2310'); + cpu.data[2] = 10; // r2 <- 10 + cpu.data[3] = 11; // r3 <- 11 + avrInstruction(cpu); + expect(cpu.pc).toEqual(1); + expect(cpu.cycles).toEqual(1); + }); + + it('should execute `CPSE r2, r3` when r2 == r3', () => { + loadProgram('23101c92'); + cpu.data[2] = 10; // r2 <- 10 + cpu.data[3] = 10; // r3 <- 10 + avrInstruction(cpu); + expect(cpu.pc).toEqual(2); + expect(cpu.cycles).toEqual(2); + }); + + it('should execute `CPSE r2, r3` when r2 == r3 and followed by 2-word instruction', () => { + loadProgram('23100e945c00'); + cpu.data[2] = 10; // r2 <- 10 + cpu.data[3] = 10; // r3 <- 10 + avrInstruction(cpu); + expect(cpu.pc).toEqual(3); + expect(cpu.cycles).toEqual(3); + }); + + it('should execute `ICALL` instruction', () => { + loadProgram('0995'); + cpu.data[93] = 0x80; + cpu.dataView.setUint16(30, 0x2020, true); // Z <- 0x2020 + avrInstruction(cpu); + expect(cpu.cycles).toEqual(3); + expect(cpu.pc).toEqual(0x2020); + expect(cpu.data[0x80]).toEqual(1); // Return address + expect(cpu.data[93]).toEqual(0x7e); + }); + + it('should execute `IJMP` instruction', () => { + loadProgram('0994'); + cpu.dataView.setUint16(30, 0x1040, true); // Z <- 0x1040 + avrInstruction(cpu); + expect(cpu.cycles).toEqual(2); + expect(cpu.pc).toEqual(0x1040); + }); + + it('should execute `IN r5, 0xb` instruction', () => { + loadProgram('5bb0'); + cpu.data[0x2b] = 0xaf; + avrInstruction(cpu); + expect(cpu.cycles).toEqual(1); + expect(cpu.pc).toEqual(1); + expect(cpu.data[5]).toEqual(0xaf); + }); + it('should execute `INC r5` instruction', () => { loadProgram('5394'); cpu.data[5] = 0x7f; @@ -453,6 +517,49 @@ describe('avrInstruction', () => { expect(cpu.data[0x5f]).toEqual(0x5a); }); + it('should execute `POP r26` instruction', () => { + loadProgram('af91'); + cpu.data[93] = 0xff; // SP <- 0xff + cpu.data[0x100] = 0x1a; + avrInstruction(cpu); + expect(cpu.pc).toEqual(0x1); + expect(cpu.cycles).toEqual(2); + expect(cpu.data[26]).toEqual(0x1a); + expect(cpu.dataView.getUint16(93, true)).toEqual(0x100); // SP + }); + + it('should execute `PUSH r11` instruction', () => { + loadProgram('bf92'); + cpu.data[11] = 0x2a; + cpu.data[93] = 0xff; // SP <- 0xff + avrInstruction(cpu); + expect(cpu.pc).toEqual(0x1); + expect(cpu.cycles).toEqual(2); + expect(cpu.data[0xff]).toEqual(0x2a); + expect(cpu.dataView.getUint16(93, true)).toEqual(0xfe); // SP + }); + + it('should execute `RCALL .+6` instruction', () => { + loadProgram('03d0'); + cpu.data[93] = 0x80; // SP <- 0x80 + avrInstruction(cpu); + expect(cpu.pc).toEqual(4); + expect(cpu.cycles).toEqual(4); + expect(cpu.dataView.getUint16(0x80, true)).toEqual(1); // RET address + expect(cpu.data[93]).toEqual(0x7e); // SP + }); + + it('should execute `RCALL .-4` instruction', () => { + loadProgram('0000fedf'); + cpu.data[93] = 0x80; // SP <- 0x80 + avrInstruction(cpu); + avrInstruction(cpu); + expect(cpu.pc).toEqual(0); + expect(cpu.cycles).toEqual(5); // 1 for NOP, 4 for RCALL + expect(cpu.dataView.getUint16(0x80, true)).toEqual(2); // RET address + expect(cpu.data[93]).toEqual(0x7e); // SP + }); + it('should execute `RET` instruction', () => { loadProgram('0895'); cpu.data[93] = 0x90; // SP <- 0x90 @@ -491,6 +598,39 @@ describe('avrInstruction', () => { expect(cpu.data[95]).toEqual(0b00011001); // SREG: SVI }); + it('should execute `SBI 0x0c, 5`', () => { + loadProgram('659a'); + cpu.data[0x2c] = 0b00001111; + avrInstruction(cpu); + expect(cpu.pc).toEqual(1); + expect(cpu.cycles).toEqual(2); + expect(cpu.data[0x2c]).toEqual(0b00101111); + }); + + it('should execute `SBIS 0x0c, 5` when bit is clear', () => { + loadProgram('659b1c92'); + cpu.data[0x2c] = 0b00001111; + avrInstruction(cpu); + expect(cpu.pc).toEqual(1); + expect(cpu.cycles).toEqual(1); + }); + + it('should execute `SBIS 0x0c, 5` when bit is set', () => { + loadProgram('659b1c92'); + cpu.data[0x2c] = 0b00101111; + avrInstruction(cpu); + expect(cpu.pc).toEqual(2); + expect(cpu.cycles).toEqual(2); + }); + + it('should execute `SBIS 0x0c, 5` when bit is set and followed by 2-word instruction', () => { + loadProgram('659b0e945c00'); + cpu.data[0x2c] = 0b00101111; + avrInstruction(cpu); + expect(cpu.pc).toEqual(3); + expect(cpu.cycles).toEqual(3); + }); + it('should execute `ST X, r1` instruction', () => { loadProgram('1c92'); cpu.data[1] = 0x5a; // r1 <- 0x5a @@ -611,4 +751,16 @@ describe('avrInstruction', () => { expect(cpu.data[0x51]).toEqual(0xcc); expect(cpu.data[30]).toEqual(0x50); // verify that Z was unchanged }); + + it('should execute `XCH r21` instruction', () => { + loadProgram('5493'); + cpu.data[21] = 0xa1; // r21 <- 0xa1 + cpu.data[30] = 0x50; // Z <- 0x50 + cpu.data[0x50] = 0xb9; + avrInstruction(cpu); + expect(cpu.pc).toEqual(1); + expect(cpu.cycles).toEqual(1); + expect(cpu.data[21]).toEqual(0xb9); // r21 + expect(cpu.data[0x50]).toEqual(0xa1); + }); }); |
