What's new

Chip 8

smcd

Active member
[MENTION=113507]marco9999[/MENTION] interesting! I never got around to trying that myself (had same idea, very simple instruction set for a first attempt at translating instructions to native code)
 

]-[ D X

New member
Any gurus of Chip8 still left over here. My counter on pong is refusiong to go up
Now... My call font memory address opcode is good as it shows LEVEL 01 correctly on BLITZ

I think my culprit could be at the fill registers or store in registers from I, but comparing my source to other projects it looks the same

My next darts are for the BCD opcode FX33

now... My way of doing is pretty awful basically truncating variables
Number / 100 stored on an INT type variable should give me the hundredth, (Number - hundredth var ) / 10
should give me the Dec and the rest is the Unity number

Am I assuming this wrong? is there a prettier/cleaener way of doing it? haha
 

marco9999

New member
Hi, truncating values is ok (if it makes sense to do it) - most emulators will do this at some point.

The BCD formula should look like this, check this first. I noticed that you said for the tens you use (number - hundreds variable). This probably works but try using the modulo operator (%) to get the remainder (see example below), in case you have an error in your code.

hundreds at address I = number / 100
tens at address I+1 = number % 100 / 10
ones at address I+2 = number % 100 % 10 / 1 (<-- omit the divide by 1 if you wish.)

If you want to get the tens by (number - hundreds variable), the BCD formula should look like this:

hundreds at address I = number / 100
tens at address I+1 = (number - hundreds * 100) / 10
ones at address I+2 = ((number - hundreds * 100) - tens * 10) / 1 (<-- omit the divide by 1 if you wish.)

From memory, I points to a single byte of data (ie: storing the BCD takes 3 bytes). If I remember correctly, the I value should not be changed after the opcode has run.

The BCD is then used by the draw sprite opcode (from the wikipedia article):

"Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels. Each row of 8 pixels is read as bit-coded starting from memory location I; I value doesn’t change after the execution of this instruction. As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that doesn’t happen", but since you said you can display level 1 correctly, it shouldn't be this.

If you cant find the problem in any of these areas, maybe try posting the source code if you can and I'll take a look.:D
 

]-[ D X

New member
oh!!! yOU SOLVED IT! ahahha I totally forgot about multiplying back the hundredth and tens variable for calculations. Whooops! Thanks a lot Marco!
 

CyanPrime

New member
Hey, guys. I have a interesting project I'm working on that's a continuation of my CHIP-8 emulator. I'll try to have something on github soon.
 

]-[ D X

New member
Cool Idea Cyan. Sadly my current schedule doesn't allow me to participate.

A little update on my project:

After a couple rides on the morning train, i've finally implemented some touch buttons, and a rudimentary register debugger. Now my question is... How should i go about advancing one step at a time. Most of my cases control the flow of the program with Pc+=2 or 4 and I can't really figure a way of advancing only one instruction at a given time.

So far I've tried Hi-jacking the opcode fetching instruction and linking it to a boolean activation of one of my on screen buttons, but that doesn't seem to cut it...
Sorry, but that's as far as I have went... Morning rides are a bit on the short side and i don't have much time to code (I exclusively code on my phone using C4droid)

So that's that... Behold Chip4droid running on an overkill One plus 3 phone haha


Edit** HOHO figured it out I isolated the whole opcode fetcher + decoder method behind an if state to check for a boolean variable controlled by the touch of the button :D
//Editing in case anyone ever (unlikely) finds himself in the same spot
 
Last edited:

Okabe

New member
Hi everyone.

I'm trying to make a chip8 emulator with processing, my first goal is to run MAZE since it's the most simple rom that I found.

Unfortunetly, I'm stuck with this result.

Untitled.png


As you can see, I get to draw the two sprite well but one of them is draw much more frequently.

As much as I checked my code, I couldn't find what I did wrong.

Your help will be appreciated.

Here's my code : https://github.com/Okarin85/Chip8-Processing/blob/master/Chip8/Chip8.pde
 

]-[ D X

New member
thats a pretty simple maze if you ask me haha. i'll take a look

- - - Updated - - -

look at your 0x3000 case
if the condition is met it should skip the next instruction so... pc+=4
this should be changed anywhere it directs you to skip
good luck =)
 
Last edited:

Okabe

New member
Thank you for your quick reply ]-[ D X :)

At the end of my switch, I have another pc+=2.

So if the condition is met, it already increase the pc by 4.

I tried your solution anyway and got this result.

Untitled.png
 
Last edited:

]-[ D X

New member
Sorry didnt see your other +2 one thing that has been bothering me is your implementation of 0x7000
case 0x7000:
V[x] = char((V[x] + kk) & 0xFF);
//println("Add kk to V[x] : ", hex(V[x]));
break;

it should be V[x] += kk
try that please (and roll back that awful suggestion xD)
 

Okabe

New member
I got the same result as before.

Untitled.png


- - - Updated - - -

I should note that the least frequent sprite appears randomly.

Sometimes there are 4 of them, sometimes 3, sometimes 2 and even none of them sometimes.

But they always appear at the beginning of the MAZE (in the top-left corner)
 

]-[ D X

New member
As you embraced the HLE path (implementing only the opcodes for an specific game) and seeing that your other opcodes are correct. The only thing that remains is your randomizer.
in your 0xC000 when you step one instruction at a time... what does your randomNumber variable looks like?
 

Okabe

New member
I also think the problem comes from my randomizer.

The value of the variable randomNumber alternates between 0 and 1 regularly.

It seems correct
 
Last edited:

]-[ D X

New member
That doesn't seem right... your random number AFAIK should be between 0 and FF 0-255
Set Vx = random byte AND kk.

Description of the opcode
The interpreter generates a random number from 0 to 255, which is then ANDed with the value kk. The results are stored in Vx
on my end it looks like this for 0xC000


Vx = (rand() % 255 & kk);
out of sheer exaustion of other options hahha this should be your culprit
 

Okabe

New member
I'm sorry, I didn't explain well.

The value of randomNumber is either 0 or 1 after it's been compare with kk.

Before that, the value of randomNumber is between 0 and 255.

I just checked it.
 

]-[ D X

New member
thats pretty weird... I've been through your code line by line and apart of type casting that i didn't do it seems good. Can you update your git so i can take a look at your updated efforts?
btw at this point it would be wise to dump your registers and opcodes on a file to see if they are been called in the same order as other emulators

Mine:

a21e - Set I (0) = NNN (21e)
c201 - Randomizer Code Vx = 0
3201 - Skip if Vx(1) == NN(1) - True
d014 - Drawing sprites
7004 - Add Vx(0) += NN (4)
3040 - Skip if Vx(4) == NN(40) - False
1200 - Jump to Address - 1NNN(200)
a2e1 - Set I (21e) = NNN(21e)
c201 - Randomizer Code Vx = 1
3201 - Skip if Vx(1) == NN(1) - True
d014 - Drawing sprites

That's mine maybe your randomizer will be different but, this is the order for 2 frames of mine

I'm thinking maybe your vX variables are been overwriten at runtime so your Vx is always adding 0
 
Last edited:

Okabe

New member
The type casting comes from processing.

I didn't update my git since I haven't made any progress so far.

About the registers and opcodes, I compared them with other emulators (you can see all the println everywhere in my code)

I was getting nervous since it's only the second program that I'm coding but you reassured me since you do seem to believe my reasoning is correct.

This can't come from a subtlety of processing that we don't get ?

I'm not a fan of processing, I feel like trying with c and SDL.

What do you think ? Is it worth a try on something else that processing ?

- - - Updated - - -

I replied before seeing your updated post.

I just checked the order of my opcodes, they're exactly like yours.

I also checked the value of Vx, (I haven't thought about it at all) it alternates between 0 and 1 regularly.
 
Last edited:

]-[ D X

New member
But you are getting output on a console window. Please verify you are getting different values for V[x] on your 0x7000 case
get rid of those (char) casts and post your results please also on the

case 0x7000:
V[x] = char((V[x] + kk) & 0xFF);
//println("Add kk to V[x] : ", hex(V[x]));
break;

//Already told you what bothered me with this one.. i hope you changed it to V[x] += V[x] + kk;

case 0xC000:
int randomNumber = int(random(255)) & kk;
V[x] = char(randomNumber);
println(randomNumber);
//println(hex(kk));
break;

This one... I'm not familiar with random() used like that, maybe is your own function... and I don't know how it work but you strictly define it as int. try including <stdlib,h>
and just using

V[x] = (rand() % 255) & kk);
let's see if that fix your issue

It's remarkable this is only your second coding project keep it up.
 
Last edited:

Okabe

New member
I didn't know the console wasn't 100% reliable. Thank you for the info :)

I've never heard about "dump" before, after a little research with the terms "dump java" on google I see "thread dump" and "heap dump" appearing a lot.

Is that what you're talking about ?

All the char cast are definitely a pain in the ass but the console of processing specificly told me to do so and won't "compile" if I don't.

You are right about " V[x] += V[x] + kk;" I should have kept it, my bad :p

The random() function comes from processing, I tried to include <stdlib,h> but the console give me the error "unexpected token: class"

I really feel like my problem comes from my misunderstanding of processing.

- - - Updated - - -

Everytime I'm using bit shift or the & operator, it seems to come out as a int by default.

For instance, if I try :

char x = (opcode & 0x0F00) >> 8;

the console says "Type mismatch, "int" doesn't match with "char"

But I think I have to use "char" with registrers, memory and all of that since it's the only unsigned type in Java.

Am I wrong ?
 
Last edited:

Top