javascriptc++chip-8

My chip8 implementation according to specification is different than open source code on internet. Need a clarification


I am working on CHIP8 implementation and I am reading

    Cowgod's
    Chip-8
    Technical Reference v1.0
http://web.archive.org/web/20130401182240/http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#3.0

as a reference. I am sure this is a percise specification because it was recommended by several blogs that talks about CHIP8 as well. My question is, I have implemented my opcode for handling a code "7xkk"

7xkk - ADD Vx, byte
Set Vx = Vx + kk.

Adds the value kk to the value of register Vx, then stores the result in Vx. 

And this is my code

 case 0x7:
   log(this.logging, "0x7xkk: Setting Vx = Vx + kk.");

   var result = this.registers.V[(opcode & 0x0F00) >> 8] + (opcode & 0x00FF);
   this.registers.V[(opcode & 0x0F00) >> 8] = result;

 break;

but other open source CHIP8 has a completely different implementation of it

case 0x7000:
            // Set Vx = Vx + kk.
            this.register[vX] += opcode & 0x00FF;

            if(this.register[vX] > 255){
                this.register[vX] -= 256;
            }
            break;

//This person checks if Vx is bigger than 255 as well, which is not described in the specificaiton.

link- https://github.com/loktar00/chip8/blob/master/chip8.js#L181

and a C++ implementation I have found online

case 0x7: {
  V[opCode2] = (char)((V[opCode2] + opCode & 0x00FF) & 0x00FF);
  IP = IP + 2;
  break;
}

//This person adds "opCode & 0x00FF" and apply and operation with "0x00FF" as well.

I am confused if I am looking at a specification that is too old or I am doing it correctly.


Solution

  • Chip-8 registers only contain a single 8-bit byte. A single byte can only hold values between 0 and 255 inclusive.

    If an operation gives you a value which is outside the range of an 8-bit byte, you need to only preserve the lower 8 bits. That's what both of those implementations are doing, although in slightly different ways: the Javascript implementation explicitly checks for values greater than 255, while the C++ implementation simply discards any extra bits (that's the & 0x00FF at the end).

    Your implementation is incorrect because you do not take this into account: if V[0] contains the value 255 and you have the opcode 0x7001 (add 1 to register 0), then your implementation will give 256, which cannot be stored in an 8-bit byte - the correct value is 0, which is the lower 8 bits of 256. This would, for example, cause problems for opcode 0xB, which takes V[0] as a jump offset, since it would jump much further than it was supposed to.