Fixed and scaled CHIP-8/SCHIP interpreter
Wednesday, 24th September 2008
The CHIP-8/SCHIP interpreter now seems happy enough to run games, though the lack of settings to control how fast or slow they run makes things rather interesting.

First of all, I've hacked together a painfully simple read-only file system. Each file is prefixed with a 13-byte header; 8 bytes for the filename (padded with spaces), 3 bytes for the extension (padded with spaces) and two bytes for the file size. The above file listing can be generated by typing *. at the BASIC prompt.
I've written a new sprite drawing routine that scales sprites up to double size when in CHIP-8 mode; this allows CHIP-8 games to fill the entire screen. Unlike the existing sprite code, which I've retained for SCHIP games, it runs entirely from ROM; the existing sprite code has to be copied to RAM as it uses some horrible self-modifying code tricks. I should probably rewrite that bit next.
As for the bug I mentioned in the last post, it was because of this:
; --- snip --- ; Group 9: ; * 9XY0 - Skips the next instruction if VX doesn't equal VY. InstructionGroup.9 call GetRegisterX ld b,a call GetRegisterY cp b jp nz,SkipNextInstruction ; Group A: ; * ANNN - Sets I to the address NNN. InstructionGroup.A call GetLiteralNNN ld (DataPointer),hl jp ExecutedInstruction ; --- snip ---
If an instruction in the form 9XY0 is executed and VX == VY, rather than jumping to ExecutedInstruction the code runs on and executes the instruction as if it had been an ANNN as well, which ended up destroying the data pointer. Adding a jp ExecutedInstruction after the jp nz,SkipNextInstruction fixed the bug.
One other advantage of the zoomed sprites is that "half-pixel" scrolls also work correctly:

...not that I've seen any game that uses them.






The last two screenshots show two versions of the game Blinky, one as a regular CHIP-8 program and the other taking advantages of the SCHIP extensions.