aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/instruction.spec.ts92
-rw-r--r--src/instruction.ts43
2 files changed, 123 insertions, 12 deletions
diff --git a/src/instruction.spec.ts b/src/instruction.spec.ts
index 0cfaf03..f804a85 100644
--- a/src/instruction.spec.ts
+++ b/src/instruction.spec.ts
@@ -43,7 +43,7 @@ describe('avrInstruction', () => {
it('should execute `OUT 0x3f, r1` instruction', () => {
loadProgram('1fbe');
- cpu.data[1] = 0x5a; // put the value 5a in r1
+ cpu.data[1] = 0x5a; // r1 <- 0x5a
avrInstruction(cpu);
expect(cpu.pc).toEqual(0x1);
expect(cpu.cycles).toEqual(1);
@@ -111,7 +111,7 @@ describe('avrInstruction', () => {
it('should execute `ST X+, r1` instruction', () => {
loadProgram('1d92');
- cpu.data[1] = 0x5a; // r1 <- 5a
+ cpu.data[1] = 0x5a; // r1 <- 0x5a
cpu.data[26] = 0x9a; // X <- 0x9a
avrInstruction(cpu);
expect(cpu.pc).toEqual(1);
@@ -130,4 +130,92 @@ describe('avrInstruction', () => {
expect(cpu.data[0x98]).toEqual(0x88);
expect(cpu.data[26]).toEqual(0x98); // verify that X was decremented
});
+
+ it('should execute `ST Y, r2` instruction', () => {
+ loadProgram('2882');
+ cpu.data[2] = 0x5b; // r2 <- 0x5b
+ cpu.data[28] = 0x9a; // Y <- 0x9a
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ 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[28] = 0x9a; // Y <- 0x9a
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[0x9a]).toEqual(0x5a);
+ expect(cpu.data[28]).toEqual(0x9b); // verify that Y was incremented
+ });
+
+ it('should execute `ST -Y, r1` instruction', () => {
+ loadProgram('1a92');
+ cpu.data[1] = 0x5a; // r1 <- 5a
+ cpu.data[28] = 0x9a; // Y <- 0x9a
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0x99]).toEqual(0x5a);
+ expect(cpu.data[28]).toEqual(0x99); // verify that Y was decremented
+ });
+
+ it('should execute `STD Y+17, r0` instruction', () => {
+ loadProgram('098a');
+ cpu.data[0] = 0xba; // r0 <- ba
+ cpu.data[28] = 0x9a; // Y <- 0x9a
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0x9a + 17]).toEqual(0xba);
+ expect(cpu.data[28]).toEqual(0x9a); // verify that Y was unchanged
+ });
+
+ it('should execute `ST Z, r16` instruction', () => {
+ loadProgram('0083');
+ cpu.data[16] = 0xdf; // r2 <- 0xdf
+ cpu.data[30] = 0x40; // Z <- 0x40
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0x40]).toEqual(0xdf);
+ expect(cpu.data[30]).toEqual(0x40); // verify that Z was unchanged
+ });
+
+ it('should execute `ST Z+, r0` instruction', () => {
+ loadProgram('0192');
+ cpu.data[0] = 0x55; // r0 <- 0x55
+ cpu.dataView.setUint16(30, 0x155, true); // Z <- 0x155
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(1);
+ expect(cpu.data[0x155]).toEqual(0x55);
+ expect(cpu.dataView.getUint16(30, true)).toEqual(0x156); // verify that Z was incremented
+ });
+
+ it('should execute `ST -Z, r16` instruction', () => {
+ loadProgram('0293');
+ cpu.data[16] = 0x5a; // r16 <- 0x5a
+ cpu.data[30] = 0xff; // Z <- 0xff
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0xfe]).toEqual(0x5a);
+ expect(cpu.data[30]).toEqual(0xfe); // verify that Z was decremented
+ });
+
+ it('should execute `STD Z+1, r0` instruction', () => {
+ loadProgram('0182');
+ cpu.data[0] = 0xcc; // r0 <- 0xcc
+ cpu.data[30] = 0x50; // Z <- 0x50
+ avrInstruction(cpu);
+ expect(cpu.pc).toEqual(1);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.data[0x51]).toEqual(0xcc);
+ expect(cpu.data[30]).toEqual(0x50); // verify that Z was unchanged
+ });
});
diff --git a/src/instruction.ts b/src/instruction.ts
index 8e52a80..6eafb19 100644
--- a/src/instruction.ts
+++ b/src/instruction.ts
@@ -452,42 +452,65 @@ export function avrInstruction(cpu: ICPU) {
/* STY, 1000 001r rrrr 1000 */
if ((opcode & 0xfe0f) === 0x8208) {
- /* not implemented */
+ cpu.writeData(cpu.dataView.getUint16(28, true), cpu.data[(opcode & 0x1f0) >> 4]);
}
/* STY, 1001 001r rrrr 1001 */
if ((opcode & 0xfe0f) === 0x9209) {
- /* not implemented */
+ 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);
}
/* STY, 1001 001r rrrr 1010 */
if ((opcode & 0xfe0f) === 0x920a) {
- /* not implemented */
+ const i = cpu.data[(opcode & 0x1f0) >> 4];
+ const y = cpu.dataView.getUint16(28, true) - 1;
+ cpu.dataView.setUint16(28, y, true);
+ cpu.writeData(y, i);
+ cpu.cycles++;
}
- /* STY, 10q0 qq1r rrrr 1qqq */
+ /* STDY, 10q0 qq1r rrrr 1qqq */
if ((opcode & 0xd208) === 0x8208) {
- /* not implemented */
+ cpu.writeData(
+ cpu.dataView.getUint16(28, true) +
+ ((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)),
+ cpu.data[(opcode & 0x1f0) >> 4]
+ );
+ cpu.cycles++;
}
/* STZ, 1000 001r rrrr 0000 */
if ((opcode & 0xfe0f) === 0x8200) {
- /* not implemented */
+ cpu.writeData(cpu.dataView.getUint16(30, true), cpu.data[(opcode & 0x1f0) >> 4]);
}
/* STZ, 1001 001r rrrr 0001 */
if ((opcode & 0xfe0f) === 0x9201) {
- /* not implemented */
+ const z = cpu.dataView.getUint16(30, true);
+ cpu.writeData(z, cpu.data[(opcode & 0x1f0) >> 4]);
+ cpu.dataView.setUint16(30, z + 1, true);
}
/* STZ, 1001 001r rrrr 0010 */
if ((opcode & 0xfe0f) === 0x9202) {
- /* not implemented */
+ const i = cpu.data[(opcode & 0x1f0) >> 4];
+ const z = cpu.dataView.getUint16(30, true) - 1;
+ cpu.dataView.setUint16(30, z, true);
+ cpu.writeData(z, i);
+ cpu.cycles++;
}
- /* STZ, 10q0 qq1r rrrr 0qqq */
+ /* STDZ, 10q0 qq1r rrrr 0qqq */
if ((opcode & 0xd208) === 0x8200) {
- /* not implemented */
+ cpu.writeData(
+ cpu.dataView.getUint16(30, true) +
+ ((opcode & 7) | ((opcode & 0xc00) >> 7) | ((opcode & 0x2000) >> 8)),
+ cpu.data[(opcode & 0x1f0) >> 4]
+ );
+ cpu.cycles++;
}
/* SUB, 0001 10rd dddd rrrr */