What's new

Chip 8

weston

New member
I found something else that I may be doing wrong but I'm not sure how to handle it. I don't have access to an 8-bit unsigned data type in java, so I just stick what should be unsigned bytes int signed ints which as far as I know should be fine since the most significant bit will never be set to one. What I'm wondering about is when I have 0 in a register and a program adds -1 to it, should the new value be 255? if not, how should I handle this?
 

zenogais

New member
mm, Not quite sure on your problem. Could have something to do with java's lack of unsigned types. Here's how you should be handling those signed integers:

Code:
int byte = 0;

byte += -1;

// Too small
if(byte < 0x00) { byte = 0xFF; }
if(byte > 0xFF) { byte &= 0xFF; }
 

weston

New member
looking at the source for tetris, I noticed this line:

skne v3, -1

I'm sure I've seen this many times before but I hadn't really thought about it until now. The CHIP-8's registers are unsigned, so they can store values 0-255, but then again they are also just a place for storing 8-bits of data so 0x00 - 0xFF. What I'm wondering is if the registers are meant to be holding data in excess 127 in order to represent negative numbers or something else perhaps. When a program wishes to compare the contents of register v3 with -1, are they looking for 0xFF in register v3?
 

hap

New member
A chip8 program doesn't compare anything with -1, the chip8 doesn't know about the existence of 'negative' (like you said, chip8 registers are unsigned), so it's probably a bug in the disassembler you're using, and tetris is probably comparing with 0xff.

And if you're wondering how a program would subtract if the chip8 doesn't know negative numbers, it just adds 256-[subtract value] to subtract, eg. add 0xff to subtract 1.
 

weston

New member
I got the schip stuff working and fixed most everything with regular chip8 games (tictac and tetris still don't exactly work correctly). Here are some screens:

screen4.png


screen5.png


screen6.png


The only problem I've seen with the schip games is with Car and Race, the roads don't 'curve' as they should. In Car just the right side does and not as much as it should and the road in Race is completely straight. There is one other little thing, the title on Alien is supposed to scroll off the screen when you start, but you can see the top row of pixels from the title during gameplay. I don't see how this could be a scrolling issue though since Alien scrolls one row at a time and if that weren't working than the title wouldn't move at all... So my guess is that there is another (still not found) broken instruction that Alien is using to determine how many lines to scroll. I would look at the code for this but I can't seem to find the point where scrolling takes place using the disassembler DC.exe because the scrolldown opcode (00Cx) doesn't show up in the source. Can anyone recommend a better disassembler (one that supports schip instructions)?

I guess the problem could be with my scrolldown code, I'd appreciate it if someone could take a look:

Code:
  public void scrollDown(int lines)
  {
    int elements = width*lines; //pixels to clear
    
    for (int i = data.length-elements-1; i > -1; i--) 
    {
                 //index     ,value
      setPixel(i+elements, data[i]);
    }

    //clear the top line
    for (int i = 0; i < elements; i++) 
    {
      setPixel(i, 0);
    }
  }

Thanks!
 

hap

New member
I don't see anything wrong with your scrolldown code. Does the scrolling in Car work correctly ?

For Car, Race, Tetris, take a look at your random opcode. Make sure the random number max value is at least 255, and min is 0, and it should be ANDed with the low byte of the opcode.
 

weston

New member
Wow, great suggestions. Fixing the random opcode did indeed fix tetris, race, and car. I think every game except tictac works correctly now. Not sure how its possible for everything else to work and for tictac to just stick all the pieces at 0,0 but that appears to be whats happening. Doomulation, you were also correct about displaying one row too many, that problem is gone.

Thanks for the help guys, I think I should be able to finish this emulator and start on a gameboy or nes today :D
 
Last edited:

truth2

New member
Meh... Tried to this chip8 emulator thingy, spent around 8-10 hours on it, and didn't see any good results. only the chip8 (not schip) opcodes are emulated, and their emulation is so full of bugs that almost nothing works. Input only works half off the time (the bad half), there's no sound, the graphics flicker and blink...
I used C, by the way and the allegro library because i'm not very good with the windows' library stuff yet...
I tried 2 games : HIDDEN (a memory game) plays fine except up and down are reversed for some reason and there is no score at the end. I also thing the speed is inaccurate...
PONG flickers like crazy and the input doesn't work >_<

MEH...
 

smcd

Active member
I'm in a graphics course (opengl intro) this semester so I might actually get around to completing mine, woo. :)
 

refraction

PCSX2 Coder
wow there's been a lot of people working on emus!

weston, i totally love how your chip8 emu looks! makes me jealous ;p
 

Doomulation

?????????????????????????
truth2 said:
Meh... Tried to this chip8 emulator thingy, spent around 8-10 hours on it, and didn't see any good results. only the chip8 (not schip) opcodes are emulated, and their emulation is so full of bugs that almost nothing works. Input only works half off the time (the bad half), there's no sound, the graphics flicker and blink...
I used C, by the way and the allegro library because i'm not very good with the windows' library stuff yet...
I tried 2 games : HIDDEN (a memory game) plays fine except up and down are reversed for some reason and there is no score at the end. I also thing the speed is inaccurate...
PONG flickers like crazy and the input doesn't work >_<

MEH...
That pong flickers is a known issue. It's the game itself the causes the flickering, as many other games on chip8.
 

weston

New member
Seems like its more the machine's fault than the game's... if you want something moving on screen then it has to be erased after its drawn because of the xor rendering. So if you have a moving object that isn't moving at the time, its going to be flickering (or if its moving a distance less than its width in the time it takes to clear and redraw it).

I managed to get rid of the flicker by keeping two sets of data for the screen. The first stores the actual states of the pixels and can be used reliably for collision detection. The second is used as render data. The difference between the two is that when a pixel is drawn onto another (causing a pixel clear), it is instantly moved from the first screen state while a count-down timer is only started for that pixel in the second screen state (buffer?). If the timer for that pixel gets to zero before another pixel is drawn in that position, then it will be clear. Since this screen state is used for rendering, it will avoid the flicker by not clearing right away because chances are the sprite will be drawn on top of it again. There is a slight graphical artifact caused by this: a trail of a pixel or two following fast moving sprites. There are ways to make that less noticeable like changing the alpha value of the pixel depending on the state of its timer.
 

zAlbee

Keeper of The Iron Tail
hrm, isn't this what things like OpenGL double buffering are used for? sounds like a very easy fix. sounds at least.

(one day i will get off my ass and actually work on one of these chip8 emus :p)
 

weston

New member
opengl's double buffering can't solve the problem. Double buffering eliminates a different kind of flickering that becomes visible because if you don't use a form of it then you are writing directly to the front screen buffer. Also, the problem isn't as simple as its seems because the screen contents is used for collision detection, so you have to keep a record of it as it actually was on the original machine. From there, other options appear to show up like rendering only every other frame so you don't display the sprites when they are cleared, but this won't work either because different programs clear and draw sprites at different times. I'm pretty sure there isn't a very simple solution...
 

Doomulation

?????????????????????????
The problem is mainly that the game draws a pixel at location x, then the next frame it draws a pixel at location x again, hence erasing it.
As each frame is presented to the screen, it will result in flicker, because it's drawn and erased all the time.
Double buffering if I'm correct is that it draws on a seperate buffer than the one displayed, so the eye cannot notice what it draws. When the scene is done, it flips the buffers, presenting a perfect image, which it can then manipulate on the buffer that is not seen in the background.
 

zAlbee

Keeper of The Iron Tail
Well, I said I would do one of these, and now I am. woot. Thanks to boredom and no work last night, i have now started the world's 4,534th Chip8 emulator :p. Just a console program now with ASCII graphics. Got most opcodes implemented (no scrolling), and subroutines seem to work fine. I didn't want to look at any source code (that just ruins the fun ;)), so I had a heck of a time figuring out just how the sprites were drawn from the vague David Winters documentation... argh.

Anyway, putting in fonts are up next (Doom, your document was very helpful, and probably the only one on this), collision detection bit, and perhaps eventually OpenGL, GUI, and key input. Yippee!
 
Last edited:

Top