aboutsummaryrefslogtreecommitdiff
path: root/src/instruction.ts
diff options
context:
space:
mode:
authorUri Shaked2019-11-19 14:35:39 +0200
committerUri Shaked2019-11-19 14:35:39 +0200
commita47e21cf3f5c2968eb2afd0ae9cd1453d0011ed8 (patch)
treece8a9be31e6898f3dc456dd1e49a8c8558b1b519 /src/instruction.ts
parentInitial commit - project skeleton (diff)
downloadavr8js-a47e21cf3f5c2968eb2afd0ae9cd1453d0011ed8.tar.gz
avr8js-a47e21cf3f5c2968eb2afd0ae9cd1453d0011ed8.tar.bz2
avr8js-a47e21cf3f5c2968eb2afd0ae9cd1453d0011ed8.zip
feat: implement some AVR instructions + tests
Diffstat (limited to 'src/instruction.ts')
-rw-r--r--src/instruction.ts501
1 files changed, 501 insertions, 0 deletions
diff --git a/src/instruction.ts b/src/instruction.ts
new file mode 100644
index 0000000..2b56def
--- /dev/null
+++ b/src/instruction.ts
@@ -0,0 +1,501 @@
+import { ICPU } from './cpu';
+
+export function avrInstruction(cpu: ICPU) {
+ const opcode = cpu.progMem[cpu.pc];
+
+ /* ADC */
+ if ((opcode & 0xfc00) === 0x1c00) {
+ /* not implemented */
+ }
+
+ /* ADD */
+ if ((opcode & 0xfc00) === 0xc00) {
+ /* not implemented */
+ }
+
+ /* ADIW */
+ if ((opcode & 0xff00) === 0x9600) {
+ /* not implemented */
+ }
+
+ /* AND */
+ if ((opcode & 0xfc00) === 0x2000) {
+ /* not implemented */
+ }
+
+ /* ANDI */
+ if ((opcode & 0xf000) === 0x7000) {
+ /* not implemented */
+ }
+
+ /* ASR */
+ if ((opcode & 0xfe0f) === 0x9405) {
+ /* not implemented */
+ }
+
+ /* BCLR */
+ if ((opcode & 0xff8f) === 0x9488) {
+ /* not implemented */
+ }
+
+ /* BLD */
+ if ((opcode & 0xfe08) === 0xf800) {
+ /* not implemented */
+ }
+
+ /* BRBC */
+ if ((opcode & 0xfc00) === 0xf400) {
+ /* not implemented */
+ }
+
+ /* BRBS */
+ if ((opcode & 0xfc00) === 0xf000) {
+ /* not implemented */
+ }
+
+ /* BSET */
+ if ((opcode & 0xff8f) === 0x9408) {
+ /* not implemented */
+ }
+
+ /* BST */
+ if ((opcode & 0xfe08) === 0xfa00) {
+ /* not implemented */
+ }
+
+ /* CALL */
+ if ((opcode & 0xfe0e) === 0x940e) {
+ /* not implemented */
+ }
+
+ /* CBI */
+ if ((opcode & 0xff00) === 0x9800) {
+ /* not implemented */
+ }
+
+ /* COM */
+ if ((opcode & 0xfe0f) === 0x9400) {
+ /* not implemented */
+ }
+
+ /* CP */
+ if ((opcode & 0xfc00) === 0x1400) {
+ /* not implemented */
+ }
+
+ /* CPC */
+ if ((opcode & 0xfc00) === 0x400) {
+ const arg1 = cpu.data[(opcode & 0x1f0) >> 4];
+ const arg2 = cpu.data[(opcode & 0xf) | ((opcode & 0x200) >> 5)];
+ let sreg = cpu.data[95];
+ const r = arg1 - arg2 - (sreg & 1);
+ sreg = (sreg & 0xfd) | (0 === r && (sreg >> 1) & 1 ? 2 : 0);
+ sreg = (sreg & 0xfb) | (128 & r ? 4 : 0);
+ sreg = (sreg & 0xf7) | ((arg1 ^ arg2) & (arg1 ^ r) & 128 ? 8 : 0);
+ sreg = (sreg & 0xef) | (((sreg >> 2) & 1) ^ ((sreg >> 3) & 1) ? 0x10 : 0);
+ sreg = (sreg & 0xfe) | (arg2 + (sreg & 1) > arg1 ? 1 : 0);
+ sreg = (sreg & 0xdf) | (1 & ((~arg1 & arg2) | (arg2 & r) | (r & ~arg1)) ? 0x20 : 0);
+ cpu.data[95] = sreg;
+ }
+
+ /* CPI */
+ if ((opcode & 0xf000) === 0x3000) {
+ const arg1 = cpu.data[((opcode & 0xf0) >> 4) + 16];
+ const arg2 = (opcode & 0xf) | ((opcode & 0xf00) >> 4);
+ const r = arg1 - arg2;
+ let sreg = cpu.data[95];
+ sreg = (sreg & 0xfd) | (0 === r ? 2 : 0);
+ sreg = (sreg & 0xfb) | (128 & r ? 4 : 0);
+ sreg = (sreg & 0xf7) | ((arg1 ^ arg2) & (arg1 ^ r) & 128 ? 8 : 0);
+ sreg = (sreg & 0xef) | (((sreg >> 2) & 1) ^ ((sreg >> 3) & 1) ? 0x10 : 0);
+ sreg = (sreg & 0xfe) | (arg2 > arg1 ? 1 : 0);
+ sreg = (sreg & 0xdf) | (1 & ((~arg1 & arg2) | (arg2 & r) | (r & ~arg1)) ? 0x20 : 0);
+ cpu.data[95] = sreg;
+ }
+
+ /* CPSE */
+ if ((opcode & 0xfc00) === 0x1000) {
+ /* not implemented */
+ }
+
+ /* DEC */
+ if ((opcode & 0xfe0f) === 0x940a) {
+ /* not implemented */
+ }
+
+ /* EOR */
+ if ((opcode & 0xfc00) === 0x2400) {
+ /* not implemented */
+ }
+
+ /* FMUL */
+ if ((opcode & 0xff88) === 0x308) {
+ /* not implemented */
+ }
+
+ /* FMULS */
+ if ((opcode & 0xff88) === 0x380) {
+ /* not implemented */
+ }
+
+ /* FMULSU */
+ if ((opcode & 0xff88) === 0x388) {
+ /* not implemented */
+ }
+
+ /* ICALL */
+ if (opcode === 0x9509) {
+ /* not implemented */
+ }
+
+ /* IJMP */
+ if (opcode === 0x9409) {
+ /* not implemented */
+ }
+
+ /* IN */
+ if ((opcode & 0xf800) === 0xb000) {
+ /* not implemented */
+ }
+
+ /* INC */
+ if ((opcode & 0xfe0f) === 0x9403) {
+ /* not implemented */
+ }
+
+ /* JMP */
+ if ((opcode & 0xfe0e) === 0x940c) {
+ cpu.pc = (cpu.progMem[cpu.pc + 1] | ((opcode & 1) << 16) | ((opcode & 0x1f0) << 13)) - 1;
+ cpu.cycles += 2;
+ }
+
+ /* LAC */
+ if ((opcode & 0xfe0f) === 0x9206) {
+ /* not implemented */
+ }
+
+ /* LAS */
+ if ((opcode & 0xfe0f) === 0x9205) {
+ /* not implemented */
+ }
+
+ /* LAT */
+ if ((opcode & 0xfe0f) === 0x9207) {
+ /* not implemented */
+ }
+
+ /* LDI */
+ if ((opcode & 0xf000) === 0xe000) {
+ cpu.data[((opcode & 0xf0) >> 4) + 16] = (opcode & 0xf) | ((opcode & 0xf00) >> 4);
+ }
+
+ /* LDS */
+ if ((opcode & 0xfe0f) === 0x9000) {
+ /* not implemented */
+ }
+
+ /* LDX */
+ if ((opcode & 0xfe0f) === 0x900c) {
+ /* not implemented */
+ }
+
+ /* LDX */
+ if ((opcode & 0xfe0f) === 0x900d) {
+ /* not implemented */
+ }
+
+ /* LDX */
+ if ((opcode & 0xfe0f) === 0x900e) {
+ /* not implemented */
+ }
+
+ /* LDY */
+ if ((opcode & 0xfe0f) === 0x8008) {
+ /* not implemented */
+ }
+
+ /* LDY */
+ if ((opcode & 0xfe0f) === 0x9009) {
+ /* not implemented */
+ }
+
+ /* LDY */
+ if ((opcode & 0xfe0f) === 0x900a) {
+ /* not implemented */
+ }
+
+ /* LDY */
+ if ((opcode & 0xd208) === 0x8008) {
+ /* not implemented */
+ }
+
+ /* LDZ */
+ if ((opcode & 0xfe0f) === 0x8000) {
+ /* not implemented */
+ }
+
+ /* LDZ */
+ if ((opcode & 0xfe0f) === 0x9001) {
+ /* not implemented */
+ }
+
+ /* LDZ */
+ if ((opcode & 0xfe0f) === 0x9002) {
+ /* not implemented */
+ }
+
+ /* LDZ */
+ if ((opcode & 0xd208) === 0x8000) {
+ /* not implemented */
+ }
+
+ /* LPM */
+ if (opcode === 0x95c8) {
+ /* not implemented */
+ }
+
+ /* LPM */
+ if ((opcode & 0xfe0f) === 0x9004) {
+ /* not implemented */
+ }
+
+ /* LPM */
+ if ((opcode & 0xfe0f) === 0x9005) {
+ /* not implemented */
+ }
+
+ /* LSR */
+ if ((opcode & 0xfe0f) === 0x9406) {
+ /* not implemented */
+ }
+
+ /* MOV */
+ if ((opcode & 0xfc00) === 0x2c00) {
+ /* not implemented */
+ }
+
+ /* MOVW */
+ if ((opcode & 0xff00) === 0x100) {
+ /* not implemented */
+ }
+
+ /* MUL */
+ if ((opcode & 0xfc00) === 0x9c00) {
+ /* not implemented */
+ }
+
+ /* MULS */
+ if ((opcode & 0xff00) === 0x200) {
+ /* not implemented */
+ }
+
+ /* MULSU */
+ if ((opcode & 0xff88) === 0x300) {
+ /* not implemented */
+ }
+
+ /* NEG */
+ if ((opcode & 0xfe0f) === 0x9401) {
+ /* not implemented */
+ }
+
+ /* NOP */
+ if (opcode === 0) {
+ /* NOP */
+ }
+
+ /* OR */
+ if ((opcode & 0xfc00) === 0x2800) {
+ /* not implemented */
+ }
+
+ /* SBR */
+ if ((opcode & 0xf000) === 0x6000) {
+ /* not implemented */
+ }
+
+ /* OUT */
+ if ((opcode & 0xf800) === 0xb800) {
+ cpu.writeData(((opcode & 0xf) | ((opcode & 0x600) >> 5)) + 32, cpu.data[(opcode & 0x1f0) >> 4]);
+ }
+
+ /* POP */
+ if ((opcode & 0xfe0f) === 0x900f) {
+ /* not implemented */
+ }
+
+ /* PUSH */
+ if ((opcode & 0xfe0f) === 0x920f) {
+ /* not implemented */
+ }
+
+ /* RCALL */
+ if ((opcode & 0xf000) === 0xd000) {
+ /* not implemented */
+ }
+
+ /* RET */
+ if (opcode === 0x9508) {
+ /* not implemented */
+ }
+
+ /* RETI */
+ if (opcode === 0x9518) {
+ /* not implemented */
+ }
+
+ /* RJMP */
+ if ((opcode & 0xf000) === 0xc000) {
+ cpu.pc = cpu.pc + ((opcode & 0x7ff) - (opcode & 0x800 ? 0x800 : 0));
+ cpu.cycles++;
+ }
+
+ /* ROR */
+ if ((opcode & 0xfe0f) === 0x9407) {
+ /* not implemented */
+ }
+
+ /* SBC */
+ if ((opcode & 0xfc00) === 0x800) {
+ /* not implemented */
+ }
+
+ /* SBCI */
+ if ((opcode & 0xf000) === 0x4000) {
+ /* not implemented */
+ }
+
+ /* SBI */
+ if ((opcode & 0xff00) === 0x9a00) {
+ /* not implemented */
+ }
+
+ /* SBIC */
+ if ((opcode & 0xff00) === 0x9900) {
+ /* not implemented */
+ }
+
+ /* SBIS */
+ if ((opcode & 0xff00) === 0x9b00) {
+ /* not implemented */
+ }
+
+ /* SBIW */
+ if ((opcode & 0xff00) === 0x9700) {
+ /* not implemented */
+ }
+
+ /* SBRC */
+ if ((opcode & 0xfe08) === 0xfc00) {
+ /* not implemented */
+ }
+
+ /* SBRS */
+ if ((opcode & 0xfe08) === 0xfe00) {
+ /* not implemented */
+ }
+
+ /* SLEEP */
+ if (opcode === 0x9588) {
+ /* not implemented */
+ }
+
+ /* SPM */
+ if (opcode === 0x95e8) {
+ /* not implemented */
+ }
+
+ /* SPM */
+ if (opcode === 0x95f8) {
+ /* not implemented */
+ }
+
+ /* STS */
+ if ((opcode & 0xfe0f) === 0x9200) {
+ /* not implemented */
+ }
+
+ /* STX */
+ if ((opcode & 0xfe0f) === 0x920c) {
+ /* not implemented */
+ }
+
+ /* STX */
+ 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);
+ }
+
+ /* STX */
+ if ((opcode & 0xfe0f) === 0x920e) {
+ /* not implemented */
+ }
+
+ /* STY */
+ if ((opcode & 0xfe0f) === 0x8208) {
+ /* not implemented */
+ }
+
+ /* STY */
+ if ((opcode & 0xfe0f) === 0x9209) {
+ /* not implemented */
+ }
+
+ /* STY */
+ if ((opcode & 0xfe0f) === 0x920a) {
+ /* not implemented */
+ }
+
+ /* STY */
+ if ((opcode & 0xd208) === 0x8208) {
+ /* not implemented */
+ }
+
+ /* STZ */
+ if ((opcode & 0xfe0f) === 0x8200) {
+ /* not implemented */
+ }
+
+ /* STZ */
+ if ((opcode & 0xfe0f) === 0x9201) {
+ /* not implemented */
+ }
+
+ /* STZ */
+ if ((opcode & 0xfe0f) === 0x9202) {
+ /* not implemented */
+ }
+
+ /* STZ */
+ if ((opcode & 0xd208) === 0x8200) {
+ /* not implemented */
+ }
+
+ /* SUB */
+ if ((opcode & 0xfc00) === 0x1800) {
+ /* not implemented */
+ }
+
+ /* SUBI */
+ if ((opcode & 0xf000) === 0x5000) {
+ /* not implemented */
+ }
+
+ /* SWAP */
+ if ((opcode & 0xfe0f) === 0x9402) {
+ /* not implemented */
+ }
+
+ /* WDR */
+ if (opcode === 0x95a8) {
+ /* not implemented */
+ }
+
+ /* XCH */
+ if ((opcode & 0xfe0f) === 0x9204) {
+ /* not implemented */
+ }
+
+ cpu.pc = (cpu.pc + 1) % cpu.progMem.length;
+ cpu.cycles++;
+}