Chirpy - Chip8 Interpreter *completed*

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.
User avatar
Punch
Posts: 375
Joined: Sat Feb 16, 2013 11:52 am

Chirpy - Chip8 Interpreter *completed*

Post by Punch »

Here's something that was inspired by the Game Genie Jam and its restrictive tileset. A Chip-8 Interpreter, made just for fun.

It supports all opcodes! Maybe it needs more robust tests but it all seems to work correctly right now.

There's a little problem though... I must have gotten confused reading documentation at some point, because I previously believed programs were at most 0x600 bytes large, which is not true, since the actual program RAM for chip8 programs goes from 0x0200 to 0x0fff. This means right now my interpreter can only run games limited in size, but this is not as limiting as it looks, just annoying if you want to test random games off the web.

I might use a mapper that allows for more work RAM later on, who knows.

Current build has Outlaw by John Earnest loaded into the ROM. https://johnearnest.github.io/chip8Arch ... l?p=outlaw

https://www.youtube.com/watch?v=s5Aaw91JXVc

---------------------------------------
Some tech details:
This uses no mapper, and could theoretically have some logic gates in place of Character ROM just like the Game Genie... but I might want to implement custom user selectable tilesets later.

A full chip8 program, to my understanding, sits between 0x200 and 0x7ff, which fits the Famicom RAM. <- edit: it's actually 0xfff so only games that use half RAM can be loaded now lol
-0000 to 007f is used for interpreter variables.
-A 54-byte area of that is reserved for an intermediate stage buffer with 4 pixels per byte in a format to make blitting easier, and with pixels shifted right and down if they're misaligned with the framebuffer tiles. (3 byte per row * 16 rows plus 6 extra bytes for easier vertical alignment -- there's 3 leftover bytes because I initially thought n=0 meant a 16 pixels high sprite)
-0080 to 017f is used for a 256 byte framebuffer, each byte represents a 4x2 area of the drawable area in the nametable.
-32 bytes are reserved for the interpreter soft stack.
-font data USED to follow the framebuffer immediately after but I'm electing to point the Chip-8 Ix register out of bounds and into the NES ROM space when using the built-in 0~f character sprites to save on memory. HW stack space was becoming dangerously cramped.

Dxyn (draw sprite) is complex but it spends 4300 or so cycles, which is a lot but not that much in the grand scheme of things. Unbounded I could probably blit a handful of sprites to the framebuffer in a single frame. Other instructions are negligible in comparison.

Dxyn right now is PPU vBlank bound, the most straightforward way of dealing with screen updates. The PPU handler only updates the screen in relation to where the sprite was drawn on the framebuffer.

The ROM loads a program off address 0xe000 of any size (limit 0x5ff bytes, if you try to load more it'll crash due to lack of ram). You can technically poke your own program into ROM/RAM if you want to, if anyone out there wants to play with the current build.
Things I want to implement:
  • A user menu to choose which program to load from ROM
  • User selectable settings, such as palettes, alternate tilesets (maybe), some interpreter quirks that vary between implementations online
  • Controller to button remap screen
  • An option to wait for vBlank every time a sprite is drawn (60 Dxyn ops per second), OR redraw the whole screen as fast as possible, maybe extending vblank for good framerates -- this is a must!
  • Simple code monitor to input your own Chip8 program
  • User selectable animations with sprites to fill the empty space with - although I have no idea how I would handle hardware sprites without space for an OAM shadow buffer in RAM.
You do not have the required permissions to view the files attached to this post.
Last edited by Punch on Tue Oct 07, 2025 6:31 pm, edited 1 time in total.
This is a block of text that can be added to posts you make. There is a 255 character limit.
User avatar
Punch
Posts: 375
Joined: Sat Feb 16, 2013 11:52 am

Re: Chirpy - Chip8 Interpreter *completed*

Post by Punch »

Everything needed to be implemented is done! (except, admittedly, for beeps with the timer counter). I've included a CC0 game on the new ROM to represent it being fully functional, but feel free to play around with a hex editor!

No source code yet as some code is quite ugly, I'll clean it up first :p
This is a block of text that can be added to posts you make. There is a 255 character limit.
User avatar
Memblers
Posts: 4150
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis

Re: Chirpy - Chip8 Interpreter *completed*

Post by Memblers »

It's really cool. I would definitely enjoy viewing the source, if it's available later.

A while back when I worked on my JIT recompiler, I explored the possibility of trying Chip8 to 6502. But I was doubtful that games are typically using much "CPU power", and the video emulation would probably be the main performance issue. Do you think there would be much benefit if it were native code though?
User avatar
Punch
Posts: 375
Joined: Sat Feb 16, 2013 11:52 am

Re: Chirpy - Chip8 Interpreter *completed*

Post by Punch »

Memblers wrote: Sat Oct 11, 2025 12:18 pm It's really cool. I would definitely enjoy viewing the source, if it's available later.

A while back when I worked on my JIT recompiler, I explored the possibility of trying Chip8 to 6502. But I was doubtful that games are typically using much "CPU power", and the video emulation would probably be the main performance issue. Do you think there would be much benefit if it were native code though?
Thanks! I’ll definitely post source later. I fixed a few more bugs but since games aren’t user selectable there hasn’t been any point to post a new rom here yet. When I implement the monitor and menus I’ll probably publish source code.

Most instructions are fairly straightforward to implement and the challenge comes from the graphics writes IMO, and yeah due to the Famicom architecture that’s usually the main CPU bottleneck. Right now I wait for vblank to redraw on VRAM the part of the frame buffer that got altered by a Dxyn sprite write but when I implement a full or smart screen refresh, a couple of sprite writes are all I’m gonna be able to fit on a single frame.

Most interpreters on PCs implement a instructions per frame limit so games that don’t use the timer counter don’t become unplayable fast, and this could have been the case on mine if it wasn’t for the graphics calls which successfully throttle speeds in every game I tested. CPU time seems plentiful otherwise so I don’t know if native code recompilation would have any benefits.
This is a block of text that can be added to posts you make. There is a 255 character limit.