Chip8 emulator

Show off your games, demos and other (playable) creations.
Post Reply
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Chip8 emulator

Post by retrotails »

v0.5 screenshot
v0.5 screenshot
2013-09-15-14-28-15.png (6.29 KiB) Viewed 7095 times
Controls:
Menu:
Arrow keys:
Make a selection

Enter/"Return":
Skip an entry (make default)

Escape:
Close

Code: Select all

1234
QWER
ASDF
ZXCV
on a QWERTY keyboard maps to

Code: Select all

123C
456D
789E
A0BF
on the Chip8

Also supports Dvorak keyboards

History:
v0.1 -
Initial upload
v0.2 -
Fixes many bugs and crashes, increases efficiency (sounds like a Sony update to stop pirates)
Requires canvas support for the time being!
Adds sound!
v0.3 -
Fixes major binary bug, game graphics no longer garbled mess.
Inverts screen colors because I stupidly had them backwards.
v0.4
Quick fix, 7XNN now wraps (so 64 + 255 = 63) instead of clamping (64 + 255 = 256)
Tetris works but tries to clear a new line infinitely when you clear 1 line.
Pong works flawlessly now, some other games might, too.
QWERTY by default.
v0.5
Adds menu with lots of options
Improves compatibility significantly

Applies to v0.5:
Near-perfect games:
BREAKOUT
BRIX
HIDDEN
MAZE
MISSILE
TETRIS

Near-working games:
BLINKY
BLITZ
INVADERS
PONG --Balls suddenly missing?
PONG2
TICTAC
WIPEOFF

Totally fucked games:
KALEID
SQUASH
VBRIX

I don't know how they're supposed to work:
15PUZZLE
CONNECT4
GUESS
MERLIN
PUZZLE
SYZYGY
TANK
VERS
WALL


I really want KALEID ("Snafu") to work.
Snafu and Shark! Shark! are the best Intellivision games ever.

Planned features:
Complete Chip8 support including RCA 1802 emulation
SuperChip8 support
Add 'Shader' render mode - Sends screen as matrix to GPU to render. Should be stupidly fast.
Implement LuaJIT optimizations
Last edited by retrotails on Sun Sep 15, 2013 6:33 pm, edited 7 times in total.
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Chip8 emulator

Post by retrotails »

Updated - Now somewhat plays a game, except the controls are broken.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Chip8 emulator

Post by Roland_Yonaba »

I rememer having tried once a Chip8 emulator too, and I just messed it up for some reason, and never got back to that.
Anyway, you did a pretty good job on this. Excellent.
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Chip8 emulator

Post by retrotails »

Roland_Yonaba wrote:I rememer having tried once a Chip8 emulator too, and I just messed it up for some reason, and never got back to that.
Anyway, you did a pretty good job on this. Excellent.
Thanks! There are so many stupid things that can go wrong, one undocumented bit (like the fact that sprites wrap across the screen, which was my major issue thus far) will mess absolutely everything up.

Anyway, new version with some fixes. Space invaders at least shows a proper title screen, it's the most impressive thing it can do so far so that's what it shows by default. If you want to, extract the .love and change main.lua:90 to some other game in the list, for example

Code: Select all

game = love.filesystem.read('games/TETRIS')
which is a totally broken game, I believe because of opcode 7XNN. But at least you can see it do some stuff and debug it (somewhat)
gamax92
Prole
Posts: 3
Joined: Thu Sep 12, 2013 12:29 am

Re: Chip8 emulator

Post by gamax92 »

Have you tried using Tronix's test rom? It test a bunch of different opcodes and makes sure that registers are what they should be.

http://www.cyberforum.ru/post919567.html

Its attached on that post, sctest_12.zip
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Chip8 emulator

Post by retrotails »

gamax92 wrote:Have you tried using Tronix's test rom? It test a bunch of different opcodes and makes sure that registers are what they should be.

http://www.cyberforum.ru/post919567.html

Its attached on that post, sctest_12.zip
That is a serious help, thanks! It fixed my BCD implementation and FX65, but it called 0102, which is either an exclusive to the SuperChip8 or one of those, or an RCA 1802 instruction, neither of which will be supported until the rest is as close to 100% as possible.
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Chip8 emulator

Post by retrotails »

Update, now has a menu and some other stuff.
gamax92
Prole
Posts: 3
Joined: Thu Sep 12, 2013 12:29 am

Re: Chip8 emulator

Post by gamax92 »

I suggest using the modulo operator for your 7XNN opcode instead of manually removing 256

Code: Select all

V[nib[2]] = (v2 + nn) % 256
In 8XY4, Even if it does carry or not, you never modulo or manually remove 256 from the result
Again in 8XY5, If it does go negative, It isn't fixed.
In 8XY6, the result must be math.floor to make sure odd numbers don't become numbers with .5's on them.
In 8XY7, same problem with 8XY5. You also are setting the Register of Nibble 3, not Nibble 2.
In BNNN, I'm not sure if this is a big deal, but it can potentially overflow past 0xFFF.
In CXNN, you can merge that rand variable directly into the bit.band, saving making and destroying the variable.
In DXYN, the usage of V[15] can be simplified to 0 and 1 instead of 0x00 and 0x01
In FX15 and FX18, the print message is slightly misleading, it conveys that the register is being set, not vice versa.
In FX1E, Register F should be set if I overflows.
In FX33, the BCD should always be 3 chars long, yet tostring does not guarentee this.
In FX55 and FX65, "On the original interpreter, when the operation is done, I=I+X+1."

I'm not sure whether there is some magical "Put registers in 0-255" code but it's better to make sure its fixed, i couldn't find one.

EDIT: Ohh, math.clamp? From what i understand math.clamp usage is to essentially min and max a number, not subtract and add, you want math.wrap instead. And even then, it seems like math.wrap has an issue.
User avatar
retrotails
Party member
Posts: 212
Joined: Wed Apr 18, 2012 12:37 am

Re: Chip8 emulator

Post by retrotails »

gamax92 wrote:I suggest using the modulo operator for your 7XNN opcode instead of manually removing 256

Code: Select all

V[nib[2]] = (v2 + nn) % 256
Well, it can't really go over.
gamax92 wrote: In 8XY4, Even if it does carry or not, you never modulo or manually remove 256 from the result
Again in 8XY5, If it does go negative, It isn't fixed.
7XNN had that issue but I never fixed the others. Fixed for v0.6.
gamax92 wrote: In 8XY6, the result must be math.floor to make sure odd numbers don't become numbers with .5's on them.
I never thought of that after switching it from bit.brshift() to a simpler '/2'
gamax92 wrote: ... You also are setting the Register of Nibble 3, not Nibble 2.
Fixed the main issue, but what do you mean by that?
gamax92 wrote: In BNNN, I'm not sure if this is a big deal, but it can potentially overflow past 0xFFF.
Wrapped it just in case... it might need clamp instead, idk.
Who knows, maybe VF needs set if it wraps, maybe it wraps to 0x200...
gamax92 wrote: In CXNN, you can merge that rand variable directly into the bit.band, saving making and destroying the variable.
Yeah, leftover from when I used to print what the number was before the & operation.
gamax92 wrote: In DXYN, the usage of V[15] can be simplified to 0 and 1 instead of 0x00 and 0x01
Really, it just looks better... I suppose when it's bytecode in the Lua VM it doesn't matter.
gamax92 wrote: In FX15 and FX18, the print message is slightly misleading, it conveys that the register is being set, not vice versa.
That's just because I didn't want to calculate the result twice.
gamax92 wrote: In FX1E, Register F should be set if I overflows.
Haven't seen that in documentation but I implemented it.
Does that apply to 7XNN as well?
gamax92 wrote: In FX33, the BCD should always be 3 chars long, yet tostring does not guarentee this.
There was already a function after it that fixes that.
gamax92 wrote: In FX55 and FX65, "On the original interpreter, when the operation is done, I=I+X+1."
I suppose it makes sense because it has to increment I to get an address. Implemented.
gamax92 wrote: I'm not sure whether there is some magical "Put registers in 0-255" code but it's better to make sure its fixed, i couldn't find one.
You mean making absolute sure the registers are 1 byte?
I considered merging all of the registers, the program counter etc. into 0x000-0x200, but the ones that go up to 0xFFF would suck because manipulating nibbles would be a pain with a string of bytes.
EDIT: Also, I have a question - When a sprite is drawn at, say, 0 x 33, does the entire sprite get drawn at 0x0, or does each pixel wrap around?
gamax92
Prole
Posts: 3
Joined: Thu Sep 12, 2013 12:29 am

Re: Chip8 emulator

Post by gamax92 »

When i suggested modulo for 7XNN i meant it would be simpler and in one line instead of an if line and essentially the same base code twice.

By "You also are setting the Register of Nibble 3, not Nibble 2." I meant this:

8XY7:
8 = Nibble 1
X = Nibble 2
Y = Nibble 3
7 = Nibble 4

Code: Select all

V[nib[3]] = V[nib[3]] - V[nib[2]]
should be

Code: Select all

V[nib[2]] = V[nib[3]] - V[nib[2]]
In 7XNN Register F is not changed if it overflows. I also find it odd why in certain opcodes F is changed and F is ignored.

Also regarding the off screen drawing, from what i understand its based on each pixel and not the sprite itself. And 0x33 wraps to 0x1 btw :P

EDIT: Just noticed something about FX55, why does it start from V1 and go to VX?
EDIT2: mem.write is broken, attempting to fix.

The reason that SCTest failed is because mem.write ends up destroying some program code and then it goes to execute that bad code, and errors on a 0102 which is an invalid 0NNN code.

Code: Select all

function mem.write(address, byte)
    byte = string.char(byte)
    RAM = string.sub(RAM, 1, address) .. byte .. string.sub(RAM, address + 2)
end
This works correctly according to my testing and my scratch sheet of paper.

EDIT3:
8XY5 and 8XY7 both need a logic checking of a >= and not a >

With all the changes that I've mentioned so far, the emulator should error at F775, thats good because FX75 is a Super Chip instruction and it has passed all of the normal Chip 8 operations.
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests