The other half of the compare family tests two registers against each other. Today you implement 5XY0 (skip if VX equals VY) and 9XY0 (skip if they differ).
Implement 5XY0 and 9XY0 so they skip based on comparing VX and VY.
5XY0 and 9XY0 complete the compare family by testing two registers against each other instead of against a constant: 5XY0 skips when VX equals VY, 9XY0 skips when they differ. The skip mechanic is identical to the last lesson - a fired skip adds an extra two to PC - so the only new idea is reading a second register operand, y, from the third nibble.
The low nibble is fixed at 0 in both (hence 5XY0, not 5XYn); that 0 is part of the opcode’s identity, distinguishing these from the arithmetic 8XY_ family you are about to build, which reuses the same x/y layout with a meaningful low nibble. With these four skip instructions plus the jumps and subroutine calls, the machine now has the complete control-flow vocabulary a real program needs: loop, branch, and call.
case 0x5000:x, y := byte(op>>8&0x0F), byte(op>>4&0x0F)if v.V[x] == v.V[y] { v.pc += 2 }return nilcase 0x9000:x, y := byte(op>>8&0x0F), byte(op>>4&0x0F)if v.V[x] != v.V[y] { v.pc += 2 }return nil