aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/instruction.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/instruction.ts')
-rw-r--r--src/cpu/instruction.ts25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/cpu/instruction.ts b/src/cpu/instruction.ts
index 40ff71f..223a320 100644
--- a/src/cpu/instruction.ts
+++ b/src/cpu/instruction.ts
@@ -1,9 +1,13 @@
/**
* AVR-8 Instruction Simulation
* Part of AVR8js
+ *
* Reference: http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf
*
- * Copyright (C) 2019, Uri Shaked
+ * Instruction timing is currently based on ATmega328p (see the Instruction Set Summary at the end of
+ * the datasheet)
+ *
+ * Copyright (C) 2019, 2020 Uri Shaked
*/
import { ICPU } from './cpu';
@@ -350,6 +354,7 @@ export function avrInstruction(cpu: ICPU) {
} else if ((opcode & 0xfe0f) === 0x900c) {
/* LDX, 1001 000d dddd 1100 */
cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(cpu.dataView.getUint16(26, true));
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x900d) {
/* LDX(INC), 1001 000d dddd 1101 */
const x = cpu.dataView.getUint16(26, true);
@@ -361,10 +366,11 @@ export function avrInstruction(cpu: ICPU) {
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;
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x8008) {
/* LDY, 1000 000d dddd 1000 */
cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(cpu.dataView.getUint16(28, true));
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x9009) {
/* LDY(INC), 1001 000d dddd 1001 */
const y = cpu.dataView.getUint16(28, true);
@@ -376,7 +382,7 @@ export function avrInstruction(cpu: ICPU) {
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;
+ cpu.cycles++;
} else if (
(opcode & 0xd208) === 0x8008 &&
(opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)
@@ -386,10 +392,11 @@ export function avrInstruction(cpu: ICPU) {
cpu.dataView.getUint16(28, true) +
((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8))
);
- cpu.cycles += 2;
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x8000) {
/* LDZ, 1000 000d dddd 0000 */
cpu.data[(opcode & 0x1f0) >> 4] = cpu.readData(cpu.dataView.getUint16(30, true));
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x9001) {
/* LDZ(INC), 1001 000d dddd 0001 */
const z = cpu.dataView.getUint16(30, true);
@@ -401,7 +408,7 @@ export function avrInstruction(cpu: ICPU) {
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;
+ cpu.cycles++;
} else if (
(opcode & 0xd208) === 0x8000 &&
(opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)
@@ -411,7 +418,7 @@ export function avrInstruction(cpu: ICPU) {
cpu.dataView.getUint16(30, true) +
((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8))
);
- cpu.cycles += 2;
+ cpu.cycles++;
} else if (opcode === 0x95c8) {
/* LPM, 1001 0101 1100 1000 */
cpu.data[0] = cpu.progBytes[cpu.dataView.getUint16(30, true)];
@@ -666,11 +673,13 @@ export function avrInstruction(cpu: ICPU) {
} else if ((opcode & 0xfe0f) === 0x920c) {
/* STX, 1001 001r rrrr 1100 */
cpu.writeData(cpu.dataView.getUint16(26, true), cpu.data[(opcode & 0x1f0) >> 4]);
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x920d) {
/* STX(INC), 1001 001r rrrr 1101 */
const x = cpu.dataView.getUint16(26, true);
cpu.writeData(x, cpu.data[(opcode & 0x1f0) >> 4]);
cpu.dataView.setUint16(26, x + 1, true);
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x920e) {
/* STX(DEC), 1001 001r rrrr 1110 */
const i = cpu.data[(opcode & 0x1f0) >> 4];
@@ -681,12 +690,14 @@ export function avrInstruction(cpu: ICPU) {
} else if ((opcode & 0xfe0f) === 0x8208) {
/* STY, 1000 001r rrrr 1000 */
cpu.writeData(cpu.dataView.getUint16(28, true), cpu.data[(opcode & 0x1f0) >> 4]);
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x9209) {
/* STY(INC), 1001 001r rrrr 1001 */
const i = cpu.data[(opcode & 0x1f0) >> 4];
const y = cpu.dataView.getUint16(28, true);
cpu.writeData(y, i);
cpu.dataView.setUint16(28, y + 1, true);
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x920a) {
/* STY(DEC), 1001 001r rrrr 1010 */
const i = cpu.data[(opcode & 0x1f0) >> 4];
@@ -708,11 +719,13 @@ export function avrInstruction(cpu: ICPU) {
} else if ((opcode & 0xfe0f) === 0x8200) {
/* STZ, 1000 001r rrrr 0000 */
cpu.writeData(cpu.dataView.getUint16(30, true), cpu.data[(opcode & 0x1f0) >> 4]);
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x9201) {
/* STZ(INC), 1001 001r rrrr 0001 */
const z = cpu.dataView.getUint16(30, true);
cpu.writeData(z, cpu.data[(opcode & 0x1f0) >> 4]);
cpu.dataView.setUint16(30, z + 1, true);
+ cpu.cycles++;
} else if ((opcode & 0xfe0f) === 0x9202) {
/* STZ(DEC), 1001 001r rrrr 0010 */
const i = cpu.data[(opcode & 0x1f0) >> 4];