aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cpu/instruction.spec.ts136
1 files changed, 103 insertions, 33 deletions
diff --git a/src/cpu/instruction.spec.ts b/src/cpu/instruction.spec.ts
index f257245..37f0bfd 100644
--- a/src/cpu/instruction.spec.ts
+++ b/src/cpu/instruction.spec.ts
@@ -115,6 +115,10 @@ describe('avrInstruction', () => {
expect(cpu.data[SREG]).toEqual(SREG_H | SREG_Z | SREG_C);
});
+ /**
+ * ADIW, AND, ANDI, ASR
+ */
+
it('should execute `BCLR 2` instruction', () => {
loadProgram('BCLR 2');
cpu.data[SREG] = 0xff;
@@ -176,14 +180,10 @@ describe('avrInstruction', () => {
expect(cpu.cycles).toEqual(1);
});
- it('should execute `CBI 0x0c, 5`', () => {
- loadProgram('CBI 0x0c, 5');
- cpu.data[0x2c] = 0b11111111;
- avrInstruction(cpu);
- expect(cpu.pc).toEqual(1);
- expect(cpu.cycles).toEqual(1);
- expect(cpu.data[0x2c]).toEqual(0b11011111);
- });
+ /**
+ * BRCC, BRCS, BREAK, BREQ, BRGE, BRHC, BRHS, BRID, BRIE, BRLO,
+ * BRLT, BRMI, BRNE, BRPL, BRSH, BRTC, BRTS, BRVC, BRVS, BSET, BST
+ */
it('should execute `CALL` instruction', () => {
loadProgram('CALL 0xb8');
@@ -208,6 +208,19 @@ describe('avrInstruction', () => {
expect(cpu.data[SP]).toEqual(147); // SP should be decremented by 3
});
+ it('should execute `CBI 0x0c, 5`', () => {
+ loadProgram('CBI 0x0c, 5');
+ cpu.data[0x2c] = 0b11111111;
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[0x2c]).toEqual(0b11011111);
+ });
+
+ /**
+ * CBR, CLC, CLH, CLI, CLN, CLR, CLS, CLT, CLV, CLZ, COM, CP
+ */
+
it('should execute `CPC r27, r18` instruction', () => {
loadProgram('CPC r27, r18');
cpu.data[r18] = 0x1;
@@ -265,6 +278,10 @@ describe('avrInstruction', () => {
expect(cpu.cycles).toEqual(3);
});
+ /**
+ * DEC, DES
+ */
+
it('should execute `EICALL` instruction', () => {
cpu = new CPU(new Uint16Array(0x20000));
loadProgram('EICALL');
@@ -336,6 +353,10 @@ describe('avrInstruction', () => {
expect(cpu.data[RAMPZ]).toEqual(0x0); // verify that RAMPZ was reset to zero
});
+ /**
+ * EOR, FMUL, FMULS, FMULSU
+ */
+
it('should execute `ICALL` instruction', () => {
loadProgram('ICALL');
cpu.data[SPH] = 0;
@@ -444,23 +465,6 @@ describe('avrInstruction', () => {
expect(cpu.data[0x80]).toEqual(0x55);
});
- it('should execute `LDI r28, 0xff` instruction', () => {
- loadProgram('LDI r28, 0xff');
- avrInstruction(cpu);
- expect(cpu.pc).toEqual(0x1);
- expect(cpu.cycles).toEqual(1);
- expect(cpu.data[Y]).toEqual(0xff);
- });
-
- it('should execute `LDS r5, 0x150` instruction', () => {
- loadProgram('LDS r5, 0x150');
- cpu.data[0x150] = 0x7a;
- avrInstruction(cpu);
- expect(cpu.pc).toEqual(0x2);
- expect(cpu.cycles).toEqual(2);
- expect(cpu.data[r5]).toEqual(0x7a);
- });
-
it('should execute `LD r1, X` instruction', () => {
loadProgram('LD r1, X');
cpu.data[0xc0] = 0x15;
@@ -582,6 +586,27 @@ describe('avrInstruction', () => {
expect(cpu.data[Z]).toEqual(0x80); // verify that Z was unchanged
});
+ it('should execute `LDI r28, 0xff` instruction', () => {
+ loadProgram('LDI r28, 0xff');
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(0x1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[Y]).toEqual(0xff);
+ });
+
+ it('should execute `LDS r5, 0x150` instruction', () => {
+ loadProgram('LDS r5, 0x150');
+ cpu.data[0x150] = 0x7a;
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(0x2);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[r5]).toEqual(0x7a);
+ });
+
+ /**
+ * LDS (16-bit)
+ */
+
it('should execute `LPM` instruction', () => {
loadProgram('LPM');
cpu.progMem[0x40] = 0xa0;
@@ -615,6 +640,10 @@ describe('avrInstruction', () => {
expect(cpu.data[Z]).toEqual(0x81); // verify that Z was incremented
});
+ /**
+ * LSL
+ */
+
it('should execute `LSR r7` instruction', () => {
loadProgram('LSR r7');
cpu.data[r7] = 0x45;
@@ -717,6 +746,10 @@ describe('avrInstruction', () => {
expect(cpu.cycles).toEqual(1);
});
+ /**
+ * OR, ORI
+ */
+
it('should execute `OUT 0x3f, r1` instruction', () => {
loadProgram('OUT 0x3f, r1');
cpu.data[r1] = 0x5a;
@@ -843,6 +876,10 @@ describe('avrInstruction', () => {
expect(cpu.cycles).toEqual(2);
});
+ /**
+ * ROL
+ */
+
it('should execute `ROR r0` instruction', () => {
loadProgram('ROR r0');
cpu.data[r0] = 0x11;
@@ -853,6 +890,18 @@ describe('avrInstruction', () => {
expect(cpu.data[SREG]).toEqual(SREG_S | SREG_V | SREG_C);
});
+ it('should execute `SBC r0, r1` instruction when carry is on and result overflows', () => {
+ loadProgram('SBC r0, r1');
+ cpu.data[r0] = 0;
+ cpu.data[r1] = 10;
+ cpu.data[95] = SREG_C;
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[r0]).toEqual(245);
+ expect(cpu.data[SREG]).toEqual(SREG_H | SREG_S | SREG_N | SREG_C);
+ });
+
it('should execute `SBCI r23, 3`', () => {
loadProgram('SBCI r23, 3');
cpu.data[r23] = 3;
@@ -872,6 +921,10 @@ describe('avrInstruction', () => {
expect(cpu.data[0x2c]).toEqual(0b00101111);
});
+ /**
+ * SBIC
+ */
+
it('should execute `SBIS 0x0c, 5` when bit is clear', () => {
loadProgram('SBIS 0x0c, 5');
cpu.data[0x2c] = 0b00001111;
@@ -896,14 +949,10 @@ describe('avrInstruction', () => {
expect(cpu.cycles).toEqual(3);
});
- it('should execute `STS 0x151, r31` instruction', () => {
- loadProgram('STS 0x151, r31');
- cpu.data[r31] = 0x80;
- avrInstruction(cpu);
- expect(cpu.pc).toEqual(2);
- expect(cpu.cycles).toEqual(2);
- expect(cpu.data[0x151]).toEqual(0x80);
- });
+ /**
+ * SBIW, SBR, SBRC, SBRS, SEC, SEH, SEI, SEN, SER, SES, SET, SEV, SEZ,
+ * SLEEP, SPM, SPM #2
+ */
it('should execute `ST X, r1` instruction', () => {
loadProgram('ST X, r1');
@@ -1026,6 +1075,19 @@ describe('avrInstruction', () => {
expect(cpu.data[Z]).toEqual(0x50); // verify that Z was unchanged
});
+ it('should execute `STS 0x151, r31` instruction', () => {
+ loadProgram('STS 0x151, r31');
+ cpu.data[r31] = 0x80;
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(2);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0x151]).toEqual(0x80);
+ });
+
+ /**
+ * STS (16-bit)
+ */
+
it('should execute `SUB r0, r1` instruction when result overflows', () => {
loadProgram('SUB r0, r1');
cpu.data[r0] = 0;
@@ -1037,6 +1099,10 @@ describe('avrInstruction', () => {
expect(cpu.data[SREG]).toEqual(SREG_S | SREG_N | SREG_C);
});
+ /**
+ * SUBI
+ */
+
it('should execute `SWAP r1` instruction', () => {
loadProgram('SWAP r1');
cpu.data[r1] = 0xa5;
@@ -1046,6 +1112,10 @@ describe('avrInstruction', () => {
expect(cpu.data[r1]).toEqual(0x5a);
});
+ /**
+ * TST
+ */
+
it('should execute `WDR` instruction and call `cpu.onWatchdogReset`', () => {
loadProgram('WDR');
cpu.onWatchdogReset = jest.fn();
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.