Diesel-Net / kiwi-8

CHIP-8 interpreter for Windows and MacOS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ROM compatibility (tentative)

tomdaley92 opened this issue · comments

Here is an incomplete list of known CHIP-8 programs that require special settings to run properly, those that have unresolved issues with my emulator, or those that simply have issues in general. Some of these settings or "quirks" will apply to other CHIP-8 emulators as well so I wanted to take this chance to document something that should've been documented a long time ago. Hopefully this will shed some light on the discrepancies between the various CHIP-8 documents and opcode implementations that you will find all over the web.

  • Astro Dodge [Revival Studios, 2008]
    • Problem: Garbage on sides of screen, score won't increment.
    • Fix: load_store_quirk = 1
  • Tic-Tac-Toe [David Winter]
    • Problem: Score won't increment.
    • Fix: load_store_quirk = 1
  • Animal Race [Brian Astle]
    • Problem: Rendered Garbage, text unreadable.
    • Fix:
    • Problem: Animal sprites are all messed up.
    • Fix: load_store_quirk = 0
  • BMP Viewer - Hello (C8 example) [Hap, 2005]
    • Problem: Renders jumbled garbage on a single row at the top of the screen.
    • Fix: shift_quirk = 1
  • Space Invaders [David Winter]
    • Problem: Aliens disappear and reappear in pairs when you hit only one.
    • Fix: shift_quirk = 1
  • Blinky [Hans Christian Egeberg, 1991]
    • Problem: map is rendered improperly, unplayable.
    • Fix: shift_quirk = 1
    • Problem: Game freezes (ends) as soon as you hit a wall
    • Fix: load_store_quirk = 1
  • Stars [Sergey Naydenov, 2010]
    • Problem: Stars don't start flashing, only dots appear.
    • Fix: load_store_quirk = 1
  • Missile [David Winter]
    • Problem: Sprite disappears when it start moving too fast.
    • Fix: Run the interpreter at anything <=720 instr/sec.
  • Space Intercept [Joseph Weisbecker, 1978]
    • Problem: Ship flickers and goes away for a few seconds at a time.
    • Fix: Run the interpreter at anything <=600 instr/sec.
  • Connect 4 [David Winter]
    • Problem: Game pieces overwrite each other and only stack diagonally.
    • Fix: load_store_quirk = 1
  • Keypad Test [Hap, 2006]
    • Problem: keypad does not render properly
    • Fix: shift_quirk = 1
  • Hidden [David Winter, 1996]
    • Problem: The last two tiles left are different, so you can't beat the game.
    • Fix: load_store_quirk = 1

Two known quirks of the CHIP-8 CPU:

Some games require these quirks to be ENABLED or DISABLED to run correctly.

Load/Store quirks - Instructions 0xFX55 and 0xFX65 increments value of I register but some CHIP-8 programs assume that they don't. Enabling this quirk causes I register to become unchanged after the instruction.

Shift quirks - Shift instructions 0x8XY6 and 0x8XYE originally shift register VY and store results in register VX. Some CHIP-8 programs incorrectly assume that the VX register is shifted by this instruction, and VY remains unmodified. Enabling this quirk causes VX to become shifted and VY remain untouched.

Enabling load_store_quirk is recommended for:

  • Astro Dodge [Revival Studios, 2008]
  • Tic-Tac-Toe [David Winter]
  • Stars [Sergey Naydenov, 2010]
  • Connect 4 [David Winter]
  • Hidden [David Winter, 1996]

Enabling shift_quirk is recommended for:

  • BMP Viewer - Hello (C8 example) [Hap, 2005]
  • Space Invaders [David Winter]
  • Keypad Test [Hap, 2006]

Enabling both shift_quirk AND load_store_quirk is recommended for:

  • Blinky [Hans Christian Egeberg, 1991]

Thanks for putting this together it helped me fix issues with Blinky. There are a couple of issues with the quirk explanations though. (This is based on my own analysis and I am by no means an expert, I could be wrong)

Load/Store quirks - You say that the quirk versions of 0xFX55 and 0xFX65 should leave the I register unchanged, but that is actually the intended functionality of those opcodes as outlined in the documentation on wikipedia. My implementation of the quirk functionality of these opcodes DOES increment the I register.

Shift quirks - This explanation is just a bit sparse for my tastes if you wouldn't mind elaborating. 0x8XY6 and 0x8XYE also store the least/most significant bit of VY in VF before shifting. Should this be the least/most bit from VX instead? That is how I implemented it.

Specifically on 0x8XY6 - The wikipedia documentation says that VY is shifted and the result is stored in VX but VY is unmodified. In the case of the quirk should it be that we shift VX and store in VX therefore modifying VX? This is how I implemented it.

Thanks again!

A little late here, but I just wanted to clear this stuff up.

History lesson first for context, skip this if you're not interested: CHIP-8 was first introduced on RCA's 1802-based microcomputers COSMAC VIP and Telmac 1800 in 1977. It appeared on a number of other computers in the early 80s. Then, in 1990, it got a renaissance when it was ported to HP48 graphing calculators, first as CHIP48 and then with some new features (including a high resolution mode) as SUPER-CHIP/SCHIP. SCHIP was later heavily rewritten, and released with scrolling functionality as SCHIP 1.1

However, the HP48 ports introduced some changes to the way some opcodes worked, probably unintentionally. Here are the relevant behavior:

  • FX55/FX65:
    • Original CHIP-8: The I register is incremented.
    • CHIP48 and SCHIP 1.0: The I register is incremented, but one less than it should (!).
    • SCHIP 1.1: The I register is not incremented.
  • 8XY6/8XYE:
    • Original CHIP-8: VY is shifted, and the result is put in VX. The bit that was shifted out is put in VF.
    • CHIP48 and SCHIP: VX is shifted in place, and the bit that was shifted out into VF. VY is not touched and the Y nibble is ignored.

So the answer is that the default behavior should really be what the original CHIP-8 interpreter from 1977 did, and the "quirk" behavior should be what SCHIP 1.1 did. However, I'll bet there are a lot more games using the "incorrect" behavior out there, since the internet existed when people started making SCHIP compatible games and emulators (like David Winter). Therefore it might be sensible to make the "new" behavior the default instead.

Hope this clears up some stuff. I updated the Wikipedia article the other day with some clarifications regarding these quirks.

I've done a fair bit of research on this, and have written a lengthy document here with all quirks and differences I know of. For just the differences between CHIP-8 and the HP48 interpreters, which is probably more relevant, this document has done some great research.

Someone found a fix to text unreadable in Animal Race?

Thanks!

@cassianoperin Hmm, it works well in Octo, so I believe it must be due to some bug in Kiwi-8 perhaps. I opened a separate issue #22.

@cassianoperin It was solved in #22, but to sum up: The problem with the text in Animal Race is due to FX1E. It shouldn't set VF depending on overflow, even though the opcode table in the CHIP-8 Wikipedia article claimed it should (I have edited the article). This seems to have been a behavior specific to the Amiga CHIP-8 interpreter. See research in Chromatophore/HP48-Superchip#2.