aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/instruction.spec.ts102
-rw-r--r--src/instruction.ts62
2 files changed, 142 insertions, 22 deletions
diff --git a/src/instruction.spec.ts b/src/instruction.spec.ts
index f804a85..29c9a49 100644
--- a/src/instruction.spec.ts
+++ b/src/instruction.spec.ts
@@ -72,11 +72,11 @@ describe('avrInstruction', () => {
it('should execute `LD r17, X+` instruction', () => {
loadProgram('1d91');
cpu.data[0xc0] = 0x15;
- cpu.data[26] = 0xc0; // X <- 0x9a
+ cpu.data[26] = 0xc0; // X <- 0xc0
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
expect(cpu.cycles).toEqual(2);
- expect(cpu.data[0xc0]).toEqual(0x15);
+ expect(cpu.data[17]).toEqual(0x15);
expect(cpu.data[26]).toEqual(0xc1); // verify that X was incremented
});
@@ -91,6 +91,94 @@ describe('avrInstruction', () => {
expect(cpu.data[26]).toEqual(0x98); // verify that X was decremented
});
+ it('should execute `LD r8, Y` instruction', () => {
+ loadProgram('8880');
+ cpu.data[0xc0] = 0x15;
+ cpu.data[28] = 0xc0; // Y <- 0xc0
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[8]).toEqual(0x15);
+ expect(cpu.data[28]).toEqual(0xc0); // verify that Y was unchanged
+ });
+
+ it('should execute `LD r3, Y+` instruction', () => {
+ loadProgram('3990');
+ cpu.data[0xc0] = 0x15;
+ cpu.data[28] = 0xc0; // Y <- 0xc0
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[3]).toEqual(0x15);
+ expect(cpu.data[28]).toEqual(0xc1); // verify that Y was incremented
+ });
+
+ it('should execute `LD r0, -Y` instruction', () => {
+ loadProgram('0a90');
+ cpu.data[0x98] = 0x22;
+ cpu.data[28] = 0x99; // Y <- 0x99
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(3);
+ expect(cpu.data[0]).toEqual(0x22);
+ expect(cpu.data[28]).toEqual(0x98); // verify that Y was decremented
+ });
+
+ it('should execute `LDD r4, Y+2` instruction', () => {
+ loadProgram('4a80');
+ cpu.data[0x82] = 0x33;
+ cpu.data[28] = 0x80; // Y <- 0x80
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(3);
+ expect(cpu.data[4]).toEqual(0x33);
+ expect(cpu.data[28]).toEqual(0x80); // verify that Y was unchanged
+ });
+
+ it('should execute `LD r5, Z` instruction', () => {
+ loadProgram('5080');
+ cpu.data[0xcc] = 0xf5;
+ cpu.data[30] = 0xcc; // Z <- 0xcc
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[5]).toEqual(0xf5);
+ expect(cpu.data[30]).toEqual(0xcc); // verify that Z was unchanged
+ });
+
+ it('should execute `LD r7, Z+` instruction', () => {
+ loadProgram('7190');
+ cpu.data[0xc0] = 0x25;
+ cpu.data[30] = 0xc0; // Z <- 0xc0
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[7]).toEqual(0x25);
+ expect(cpu.data[30]).toEqual(0xc1); // verify that Y was incremented
+ });
+
+ it('should execute `LD r0, -Z` instruction', () => {
+ loadProgram('0290');
+ cpu.data[0x9e] = 0x66;
+ cpu.data[30] = 0x9f; // Z <- 0x9f
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(3);
+ expect(cpu.data[0]).toEqual(0x66);
+ expect(cpu.data[30]).toEqual(0x9e); // verify that Y was decremented
+ });
+
+ it('should execute `LDD r15, Z+31` instruction', () => {
+ loadProgram('f78c');
+ cpu.data[0x9f] = 0x33;
+ cpu.data[30] = 0x80; // Z <- 0x80
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(3);
+ expect(cpu.data[15]).toEqual(0x33);
+ expect(cpu.data[30]).toEqual(0x80); // verify that Z was unchanged
+ });
+
it('should execute `RJMP 2` instruction', () => {
loadProgram('01c0');
avrInstruction(cpu);
@@ -137,14 +225,14 @@ describe('avrInstruction', () => {
cpu.data[28] = 0x9a; // Y <- 0x9a
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
- expect(cpu.cycles).toEqual(2);
+ expect(cpu.cycles).toEqual(1);
expect(cpu.data[0x9a]).toEqual(0x5b);
expect(cpu.data[28]).toEqual(0x9a); // verify that Y was unchanged
});
it('should execute `ST Y+, r1` instruction', () => {
loadProgram('1992');
- cpu.data[1] = 0x5a; // r1 <- 5a
+ cpu.data[1] = 0x5a; // r1 <- 0x5a
cpu.data[28] = 0x9a; // Y <- 0x9a
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
@@ -155,7 +243,7 @@ describe('avrInstruction', () => {
it('should execute `ST -Y, r1` instruction', () => {
loadProgram('1a92');
- cpu.data[1] = 0x5a; // r1 <- 5a
+ cpu.data[1] = 0x5a; // r1 <- 0x5a
cpu.data[28] = 0x9a; // Y <- 0x9a
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
@@ -166,7 +254,7 @@ describe('avrInstruction', () => {
it('should execute `STD Y+17, r0` instruction', () => {
loadProgram('098a');
- cpu.data[0] = 0xba; // r0 <- ba
+ cpu.data[0] = 0xba; // r0 <- 0xba
cpu.data[28] = 0x9a; // Y <- 0x9a
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
@@ -181,7 +269,7 @@ describe('avrInstruction', () => {
cpu.data[30] = 0x40; // Z <- 0x40
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
- expect(cpu.cycles).toEqual(2);
+ expect(cpu.cycles).toEqual(1);
expect(cpu.data[0x40]).toEqual(0xdf);
expect(cpu.data[30]).toEqual(0x40); // verify that Z was unchanged
});
diff --git a/src/instruction.ts b/src/instruction.ts
index 6eafb19..7eaa105 100644
--- a/src/instruction.ts
+++ b/src/instruction.ts
@@ -210,7 +210,7 @@ export function avrInstruction(cpu: ICPU) {
/* LDX, 1001 000d dddd 1101 */
if ((opcode & 0xfe0f) === 0x900d) {
const x = cpu.dataView.getUint16(26, true);
- cpu.data[(opcode & 0x1f0) >> 4] = x;
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(x);
cpu.dataView.setUint16(26, x + 1, true);
cpu.cycles++;
}
@@ -225,42 +225,68 @@ export function avrInstruction(cpu: ICPU) {
/* LDY, 1000 000d dddd 1000 */
if ((opcode & 0xfe0f) === 0x8008) {
- /* not implemented */
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(cpu.dataView.getUint16(28, true));
}
/* LDY, 1001 000d dddd 1001 */
if ((opcode & 0xfe0f) === 0x9009) {
- /* not implemented */
+ const y = cpu.dataView.getUint16(28, true);
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(y);
+ cpu.dataView.setUint16(28, y + 1, true);
+ cpu.cycles++;
}
/* LDY, 1001 000d dddd 1010 */
if ((opcode & 0xfe0f) === 0x900a) {
- /* not implemented */
+ const y = cpu.dataView.getUint16(28, true) - 1;
+ cpu.dataView.setUint16(28, y, true);
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(y);
+ cpu.cycles += 2;
}
- /* LDY, 10q0 qq0d dddd 1qqq */
- if ((opcode & 0xd208) === 0x8008) {
- /* not implemented */
+ /* LDDY, 10q0 qq0d dddd 1qqq */
+ if (
+ (opcode & 0xd208) === 0x8008 &&
+ (opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)
+ ) {
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(
+ cpu.dataView.getUint16(28, true) +
+ ((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8))
+ );
+ cpu.cycles += 2;
}
/* LDZ, 1000 000d dddd 0000 */
if ((opcode & 0xfe0f) === 0x8000) {
- /* not implemented */
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(cpu.dataView.getUint16(30, true));
}
/* LDZ, 1001 000d dddd 0001 */
if ((opcode & 0xfe0f) === 0x9001) {
- /* not implemented */
+ const z = cpu.dataView.getUint16(30, true);
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(z);
+ cpu.dataView.setUint16(30, z + 1, true);
+ cpu.cycles++;
}
/* LDZ, 1001 000d dddd 0010 */
if ((opcode & 0xfe0f) === 0x9002) {
- /* not implemented */
+ const z = cpu.dataView.getUint16(30, true) - 1;
+ cpu.dataView.setUint16(30, z, true);
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(z);
+ cpu.cycles += 2;
}
- /* LDZ, 10q0 qq0d dddd 0qqq */
- if ((opcode & 0xd208) === 0x8000) {
- /* not implemented */
+ /* LDDZ, 10q0 qq0d dddd 0qqq */
+ if (
+ (opcode & 0xd208) === 0x8000 &&
+ (opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)
+ ) {
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(
+ cpu.dataView.getUint16(30, true) +
+ ((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8))
+ );
+ cpu.cycles += 2;
}
/* LPM, 1001 0101 1100 1000 */
@@ -473,7 +499,10 @@ export function avrInstruction(cpu: ICPU) {
}
/* STDY, 10q0 qq1r rrrr 1qqq */
- if ((opcode & 0xd208) === 0x8208) {
+ if (
+ (opcode & 0xd208) === 0x8208 &&
+ (opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)
+ ) {
cpu.writeData(
cpu.dataView.getUint16(28, true) +
((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)),
@@ -504,7 +533,10 @@ export function avrInstruction(cpu: ICPU) {
}
/* STDZ, 10q0 qq1r rrrr 0qqq */
- if ((opcode & 0xd208) === 0x8200) {
+ if (
+ (opcode & 0xd208) === 0x8200 &&
+ (opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)
+ ) {
cpu.writeData(
cpu.dataView.getUint16(30, true) +
((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)),
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.