diff --git a/emulator.c b/emulator.c index bd944e0..9e665dd 100644 --- a/emulator.c +++ b/emulator.c @@ -80,7 +80,7 @@ u16 *dcpu_opr(struct dcpu *d, u16 code) { } } -static u8 skiptable[32] = { /* operand forms that advance pc */ +static u8 skiptable[64] = { /* operand forms that advance pc */ [0x10] = 1, [0x11] = 1, [0x12] = 1, [0x13] = 1, [0x14] = 1, [0x15] = 1, [0x16] = 1, [0x17] = 1, [0x1E] = 1, [0x1F] = 1, @@ -89,8 +89,8 @@ static u8 skiptable[32] = { /* operand forms that advance pc */ void dcpu_skip(struct dcpu *d) { u16 op = d->m[d->pc++]; d->pc += skiptable[op >> 10]; - if ((op & 15) == 0) - d->pc += skiptable[(op >> 4) & 31]; + if ((op & 15) != 0) + d->pc += skiptable[(op >> 4) & 63]; } void dcpu_step(struct dcpu *d) { @@ -133,8 +133,11 @@ void dcpu_step(struct dcpu *d) { d->m[--(d->sp)] = d->pc; d->pc = a; return; + case 0x3F: + fprintf(stderr, "< ILLEGAL OPCODE (success code)>\n"); + exit(0); default: fprintf(stderr, "< ILLEGAL OPCODE >\n"); - exit(0); + exit(1); } } diff --git a/tests/testskip.s b/tests/testskip.s new file mode 100644 index 0000000..aa62937 --- /dev/null +++ b/tests/testskip.s @@ -0,0 +1,21 @@ +; Skip test. Assumes skipping a 3-word instruction may be faulty, but +; skipping a 2-word instruction works. + + SET A, 0x10 ; c001 + SET [0x1000], A ; 01e1, 1000 + SET [0xEEE0], 0 ; 81e1, eee0 + IFN A, 0x10 ; c00d + SET [0x1000], [0xEEE0] ; 79e1, 1000, eee0 + SET A, [0x1000] ; 7801, 1000 + ; A should still be 0x10 + + IFN A, 0x10 ; c00d + SET PC, fail ; 7dc1, 000f + +:pass + WORD 0x3FF0 ; 3ff0 + +:fail + WORD 0xEEE0 ; eee0 + + diff --git a/tests/testskip3.s b/tests/testskip3.s new file mode 100644 index 0000000..db3133c --- /dev/null +++ b/tests/testskip3.s @@ -0,0 +1,168 @@ + SET A, 0x10 + + IFN A, 0x10 + SUB A, 0 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 1 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 2 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 3 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 4 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 5 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 6 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 7 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 8 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 9 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 10 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 11 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 12 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 13 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 14 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 15 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 16 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 17 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 18 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 19 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 20 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 21 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 22 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 23 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 24 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 25 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 26 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 27 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 28 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 29 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 30 + IFN A, 0x10 + SET PC, fail + + IFN A, 0x10 + SUB A, 31 + IFN A, 0x10 + SET PC, fail + +:pass + WORD 0x3FF0 + +:fail + WORD 0xEEE0 +