commit b268be4f7c3fa4f744c62afbb410e58655abcc28 from: Sven M. Hallberg date: Sun Oct 09 14:16:11 2022 UTC fix jump semantics Use as destination the value of A as it was at the start of the cycle, before possibly updating it with the ALU result. commit - 5261f2c888037eaeb65e345bac5e0dd2deac1874 commit + b268be4f7c3fa4f744c62afbb410e58655abcc28 blob - 4cd01a83f40f2978d90d7269132e5443657caaea blob + bae1962a2ae432d4efc08de5504c6107c513845c --- hackem.c +++ hackem.c @@ -176,7 +176,7 @@ int cpu(uint16_t instr) { uint16_t a, comp, ddd, jjj; /* instruction parts */ - uint16_t result, y; + uint16_t dest, result, y; if (bit(instr, 15)) { /* C-instruction */ /* decode instruction */ @@ -185,6 +185,9 @@ cpu(uint16_t instr) comp = bits(instr, 6, 6); a = bits(instr, 12, 1); + /* save jump destination before updating A */ + dest = A; + /* switch ALU input between A and M */ if (a) y = readmem(A); @@ -213,14 +216,14 @@ cpu(uint16_t instr) * 0;JMP 0;JMP */ if (ddd == 0 && jjj == 7 && - (A == PC || (A == PC - 1 && rom[A] == A))) + (dest == PC || (dest == PC - 1 && rom[dest] == dest))) return 0; /* stop */ /* perform jump if required */ if ((bit(jjj, 0) && positive(result)) || (bit(jjj, 1) && result == 0) || (bit(jjj, 2) && negative(result))) - PC = A - 1; + PC = dest - 1; } else /* A-instruction */ A = instr; PC++;