Juraj's Blog

23 Dec 2020

CHIP-8 emulators inconsistent behavior

CHIP-8 arithmetic behavior and VF variable

I’ve been fiddling with CHIP-8 and writing a sample program in Octo - a CHIP-8 IDE/assembler with a nicer scripting language than raw opcodes.

I wanted to make a demo to try out various opcodes and while doing that found a bug in my CHIP-8 emulator within the arithmetic operations.

The demo (and its source code )

VF as a destination

I’ve encountered a different behavior between my emulator emuchip8 and Octo (which I use as a reference) and got somewhat. Octo implements the >= pseudo-operation as by using the subtraction instructions -= and =- and querying vf - this was broken on my emulator.

Given the following program:


What should be the value of vf after the 8F07 opcode executes? (so vf = v0 - vf; vf = 0x08 - 0x20 = 0xe8).

I think it should it be 0 because the borrow flag has a priority over the subtraction result, but several emulators online seem to take the opposite priority (in comparison to Octo) .

The original documentation COSMAC_VIP_Instruction_Manual_1978.pdf (archive.org) says the VF is used for overflow in the arithmetic operations, but I didn’t get around to disassembling the original interpreter :).

So the result should be saved in VX first, then the flag in VF.

VF when vx == vy

In addition, the VF subtraction behavior seems to be wrong in one other edge case as well in these open-source emulators - the original docs say that (for 8XY5): VX = VX - VY (VF= 0 if vx < vx; VF = 1 if vx >= vy).

Again, found emulators online that implements it as:

vf = vx > vy ? 1 : 0;

The code above yields incorrect result in the case when vx equals vy.

If vx == vy the result in VF should be 1 according to RCA COSMAC VIP manual. Wikipedia is right as well, specifying that VF is set to 0 when there’s a borrow, and 1 when there isn’t. - there is no borrow when you do 9-9, so it’s not wrong either.

This can be tested with the following ROM :

0x6004   # v0 := 4
0x8005   # v0 -= v0
0xFF29   # set i to sprite 0 or 1 based on the value of vf
0xD005   # should draw sprite of 1