aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/instruction.spec.ts37
-rw-r--r--src/instruction.ts22
2 files changed, 50 insertions, 9 deletions
diff --git a/src/instruction.spec.ts b/src/instruction.spec.ts
index 8d3ac3d..0cfaf03 100644
--- a/src/instruction.spec.ts
+++ b/src/instruction.spec.ts
@@ -58,6 +58,39 @@ describe('avrInstruction', () => {
expect(cpu.data[28]).toEqual(0xff);
});
+ it('should execute `LD r1, X` instruction', () => {
+ loadProgram('1c90');
+ cpu.data[0xc0] = 0x15;
+ cpu.data[26] = 0xc0; // X <- 0xc0
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[1]).toEqual(0x15);
+ expect(cpu.data[26]).toEqual(0xc0); // verify that X was unchanged
+ });
+
+ it('should execute `LD r17, X+` instruction', () => {
+ loadProgram('1d91');
+ cpu.data[0xc0] = 0x15;
+ cpu.data[26] = 0xc0; // X <- 0x9a
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0xc0]).toEqual(0x15);
+ expect(cpu.data[26]).toEqual(0xc1); // verify that X was incremented
+ });
+
+ it('should execute `LD r1, -X` instruction', () => {
+ loadProgram('1e90');
+ cpu.data[0x98] = 0x22;
+ cpu.data[26] = 0x99; // X <- 0x99
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(3);
+ expect(cpu.data[1]).toEqual(0x22);
+ expect(cpu.data[26]).toEqual(0x98); // verify that X was decremented
+ });
+
it('should execute `RJMP 2` instruction', () => {
loadProgram('01c0');
avrInstruction(cpu);
@@ -87,7 +120,7 @@ describe('avrInstruction', () => {
expect(cpu.data[26]).toEqual(0x9b); // verify that X was incremented
});
- it('should execute `ST X-, r17` instruction', () => {
+ it('should execute `ST -X, r17` instruction', () => {
loadProgram('1e93');
cpu.data[17] = 0x88; // r17 <- 0x88
cpu.data[26] = 0x99; // X <- 0x99
@@ -95,6 +128,6 @@ describe('avrInstruction', () => {
expect(cpu.pc).toEqual(1);
expect(cpu.cycles).toEqual(2);
expect(cpu.data[0x98]).toEqual(0x88);
- expect(cpu.data[26]).toEqual(0x98); // verify that X was unchanged
+ expect(cpu.data[26]).toEqual(0x98); // verify that X was decremented
});
});
diff --git a/src/instruction.ts b/src/instruction.ts
index 1d016aa..8e52a80 100644
--- a/src/instruction.ts
+++ b/src/instruction.ts
@@ -204,17 +204,23 @@ export function avrInstruction(cpu: ICPU) {
/* LDX, 1001 000d dddd 1100 */
if ((opcode & 0xfe0f) === 0x900c) {
- /* not implemented */
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(cpu.dataView.getUint16(26, true));
}
/* LDX, 1001 000d dddd 1101 */
if ((opcode & 0xfe0f) === 0x900d) {
- /* not implemented */
+ const x = cpu.dataView.getUint16(26, true);
+ cpu.data[(opcode & 0x1f0) >> 4] = x;
+ cpu.dataView.setUint16(26, x + 1, true);
+ cpu.cycles++;
}
/* LDX, 1001 000d dddd 1110 */
if ((opcode & 0xfe0f) === 0x900e) {
- /* not implemented */
+ const x = cpu.dataView.getUint16(26, true) - 1;
+ cpu.dataView.setUint16(26, x, true);
+ cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(x);
+ cpu.cycles += 2;
}
/* LDY, 1000 000d dddd 1000 */
@@ -430,15 +436,17 @@ export function avrInstruction(cpu: ICPU) {
/* STX, 1001 001r rrrr 1101 */
if ((opcode & 0xfe0f) === 0x920d) {
- cpu.writeData(cpu.dataView.getUint16(26, true), cpu.data[(opcode & 0x1f0) >> 4]);
- cpu.dataView.setUint16(26, cpu.dataView.getUint16(26, true) + 1, true);
+ const x = cpu.dataView.getUint16(26, true);
+ cpu.writeData(x, cpu.data[(opcode & 0x1f0) >> 4]);
+ cpu.dataView.setUint16(26, x + 1, true);
}
/* STX, 1001 001r rrrr 1110 */
if ((opcode & 0xfe0f) === 0x920e) {
const i = cpu.data[(opcode & 0x1f0) >> 4];
- cpu.dataView.setUint16(26, cpu.dataView.getUint16(26, true) - 1, true);
- cpu.writeData(cpu.dataView.getUint16(26, true), i);
+ const x = cpu.dataView.getUint16(26, true) - 1;
+ cpu.dataView.setUint16(26, x, true);
+ cpu.writeData(x, i);
cpu.cycles++;
}