9 Comments - powered by utteranc.es

@cbreezier
cbreezier commented on Apr 24, 2021
Sign in to add your reaction.

This was a great write-up - I found that it provided a good level of detail while leaving enough of the implementation details for me to figure out.

Two things that were a little unclear to me, both in the DXYN instruction:

  1. While drawing the sprite, I wasn't sure whether I should be actually modifying I or just reading from successive memory locations. I ended up not modifying it, which seemed to work fine.
  2. The written explanation didn't say anything about setting the VF flag - I had to find that out from the pseudocode section which I had initially tried to avoid.

My attempt (seems to be working, sans sound) is in Rust: https://github.com/cbreezier/rchip8

@tobiasvl
tobiasvl commented on Sep 2, 2021
Owner
Sign in to add your reaction.

@cbreezier Hey, thanks for the feedback!

  1. Thanks, I've attempted to clarify this. You're correct, I should not be modified (and neither should VX and VY, for that matter).
  2. Hmm, the written explanation does have a bullet point about setting VF, though? It says "If the current pixel in the sprite row is on and the pixel at coordinates X,Y on the screen is also on, turn off the pixel and set VF to 1". Let me know if anything is unclear about this, or if you were talking about some other part of the tutorial.

Again, thanks for the feedback, and I'm glad you found it useful!

@DasStone
DasStone commented on Mar 10, 2022
Sign in to add your reaction.

Thanks for writing this great article! I’m sure it helped many people get into the topic of emulators, as it did with me.

But there is one thing I’m still not sure about (it has to do with FX0A Instruction). It says that the instruction β€œblocks” execution. Does this mean that the timers should stop decrementing as well or do they continue at their normal rate of 60Hz (I’ve scanned the Internet for any mention of this, but I haven’t found a clear, unambiguous answer. But it seems like that the timers should continue)?

Maybe this is something you find worth clarifying in your article.

Thanks for your time!

Here is my attempt in Rust for anyone interested: https://github.com/DasStone/chip8emu_rs

@tobiasvl
tobiasvl commented on Apr 13, 2022
Owner
Sign in to add your reaction.

@DasStone Thanks for the kind words and the feedback! You're right, this is definitely worth clarifying in the blog post. In the meantime, I can confirm that yes, you're correct, the timers should continue while the FX0A instruction is blocking for input.

In the CHIP-8 interpreter on the COSMAC VIP, FX0A was simply an infinite loop that ran until a key was pressed. The timers were decremented in the COSMAC VIP's built-in display interrupt routine, which is why they're decremented 60 times per second – the display interrupt occurs each frame drawn to the display, which refreshes at 60 Hz. You can read more about it here: https://laurencescotford.com/chip-8-on-the-cosmac-vip-interrupts/

@jakubito
jakubito commented on May 19, 2022
Sign in to add your reaction.

Hi @tobiasvl, thanks for posting this excellent guide. I referenced it many times while writing my own interpreter.

I have a question regarding one of your statements:

However, the actual drawing of the sprite should not wrap. If a sprite is drawn near the edge of the screen, it should be clipped, and not wrap. The sprite should be partly drawn near the edge, and the other part should not reappear on the opposite side of the screen.

But this reference says:

If the sprite is positioned so part of it is outside the coordinates of the display, it wraps around to the opposite side of the screen.

For example, paddles in Pong seem to wrap in other interpreters I tried (e.g. Octo IDE), but based on your instructions, they shouldn't. Am I missing something here?

Edit: Just found out Octo IDE has an option for wrapping/clipping sprites. I think I'll make it configurable too.

@tobiasvl
tobiasvl commented on May 21, 2022
Owner
Sign in to add your reaction.

@jakubito Thanks, interesting! I can confirm that my statement is correct – sprites shouldn't partially wrap in either the original CHIP-8 interpreter (source) or in CHIP-48/S-CHIP (source).

However! By "Pong", I assume you're referring to David Winter's Pong game. It was written for his own DOS interpreter, which was based on the CHIP-48 specification. This specification seems to be what Cowgod's reference is based on as well. It's possible David Winter introduced sprite wrapping himself, and this is the reason for the disparity.

@JamesWWalker
JamesWWalker commented on Jul 22, 2022
Sign in to add your reaction.

Thanks for this helpful post on creating a CHIP-8 emulator! I just developed an interest in emulator creation and, after a little research, discovered that writing a CHIP-8 emulator (/interpreter) is apparently a rite of passage. With the help of this guide, I put together a working CHIP-8 emulator in Java that passes the BonCoder test, and it only took around 8 hours. I'm planning to try to make an NES emulator next. I expect that to be a big step up in complexity!

@jasonnelson618
jasonnelson618 commented 3 months ago
Sign in to add your reaction.

Hello! Love the article and I've been working on my own interpreter, however I noted you said for the IBM logo program only the opcodes you mentioned were needed, but there are several opcodes starting with "F" in the versions of the IBM logo I can find, so I'm quite confused if more opcodes are needed or if I'm messing up something. Any clarity would be appreciated! Thanks in advance.

@tobiasvl
tobiasvl commented 3 months ago
Owner
Sign in to add your reaction.

Hello! Love the article and I've been working on my own interpreter, however I noted you said for the IBM logo program only the opcodes you mentioned were needed, but there are several opcodes starting with "F" in the versions of the IBM logo I can find, so I'm quite confused if more opcodes are needed or if I'm messing up something. Any clarity would be appreciated! Thanks in advance.

@jasonnelson618 Thanks for the kind words! There should be no FXXX opcodes in the IBM program. How are you reaching those opcodes? My guess is that you're reading the graphics data (for the IBM logo) as code somehow, ie. that you have a bug that has caused your Program Counter to point into the graphics, attempting to execute it.

If you push your code to GitHub, I could have a look at it and see if I spot the bug. Otherwise, good luck bug hunting! Might be a good idea to write some debug stuff to the terminal, such as the current PC and opcode at each step, so you see what's happening.

@anonymous