What's new

Chip 8

refraction

PCSX2 Coder
ChaosBlade said:
Hmm, ignoring overflowing pixels. Dunno, ill try that, im a bit confused as to why games attempt to draw out of the screen on purpose.

Refraction: then how does blitz works for you guys ? it draws the last line of the towers in y32, if you did that y = 0 then it would appear at the top of the screen.


yes, goes out the bottom, comes in the top, just like good old Asteroids :p

other solution make the array slightly bigger than its suppose to be, should stop it crashing
 

ChaosBlade

My Heart Chose.. Revenge.
It doesnt crash, actully. It just draws things oddly..

Doomulation: Then i must be doing something wrong, Pong tries to draw at Y = 32 when the paddle goes off-screen, and blitz tries to draw the last line of the towers at 32 aswell (afaik even the machine uses 0-31 and not 1-32).

Anyway, ignoring drawing at 32 seems to work but i think its wrong - the paddle at pong now completely disappears before going back at the top again.

Here's my current source code, zip format, for anyone who wants to take a look.
 
Last edited:

bcrew1375

New member
I tried changing the Y modulation to 33 a while back, and I said it felt like a quickfix. The thing is, most every Chip-8 interpreter I've seen does this.
 

Doomulation

?????????????????????????
First thing I see is that you read one byte at a time. That's waste of time. I see you use fstream. I never used that so I can't help you with what to do. All I basically do is use fopen, seek to end, get file size, seek to start, use fread and close it.

Hmm... let's see what more there is...
Ah yes, instead of looping through and clearing each element of an array, why don't you use ZeroMemory? Goes for Reset and ClearScreen.
A nice optimization to the DrawSprite routine that one could remember (although it doesn't make it slow!) is to aquire the X and Y coordinates at the beginning and increment them. Like such:

Code:
X = some_coord;
Y = some_coord;
for(...)
{
...
Y++;
}
For example. Just a note.

Hmmm... I think I see a problem... your I register should not increment with these opcodes. Beware!

Code:
void SaveRegisters()
{
	for (int nIndex = 0; nIndex <= REG_X; nIndex++)
	{
		arrcMemory[sI++] = arrcRegisters[nIndex]; // I does NOT increment!
	}

	sI += 1;
}

void LoadRegisters()
{
	for (int nIndex = 0; nIndex <= REG_X; nIndex++)
	{
		arrcRegisters[nIndex] = arrcMemory[sI++]; // I does NOT increment!
	}

	sI += 1;
}

Btw, you can try to use jump tables =) They're pretty neat and faster than switches.
Oh and I love your code! Very clean =)

Here's a doc I compiled some time ago. It should be accurate:
http://www.emutalk.net/attachment.php?attachmentid=17220
 

ChaosBlade

My Heart Chose.. Revenge.
Heh, thanks. Standard Code Writing is checked on every piece of code we write at the army (im an army programmer), so i got used to that efficient and readable standard :)

About the jump tables, afaik VS.NET's copiler turns switchs into jump tables instead of if-else lines, so it should not matter much.

As for the I Incarments, Winter's Document doesnt say anything about this,
but the other document someone attached here that includes only the opcode listing specificly says that I needs to point to the next free space after saving the registers.

Ill look into fixing those little mistakes and optimize a bit. I think ill leave the drawing modulation issue as it is right now, it seems to as good a solution as the other 'quickfix' as bcrew calls it.
 
Last edited:

ChaosBlade

My Heart Chose.. Revenge.
Sorry for double post, but the other post was long enough already xD

what is connect4 suppose to do ? in mine it just alternates between a few shapes at the bottom right now (where the paddle had stopped), so im guessing my drawing is wrong again.
 

Doomulation

?????????????????????????
ChaosBlade said:
Heh, thanks. Standard Code Writing is checked on every piece of code we write at the army (im an army programmer), so i got used to that efficient and readable standard :)
:) :D

About the jump tables, afaik VS.NET's copiler turns switchs into jump tables instead of if-else lines, so it should not matter much.
Yes, it optimizes them. But you can erase additional overhead with jump tables.

As for the I Incarments, Winter's Document doesnt say anything about this,
but the other document someone attached here that includes only the opcode listing specificly says that I needs to point to the next free space after saving the registers.
Believe me, it's wrong. I should definetly NOT be incremented. Those docs are lying. I fell for that once, too, and I know it should not.

Ill look into fixing those little mistakes and optimize a bit. I think ill leave the drawing modulation issue as it is right now, it seems to as good a solution as the other 'quickfix' as bcrew calls it.
Hmmmm... if you fix some of the errors, I bet you don't need modulating. I never needed it.
 

ChaosBlade

My Heart Chose.. Revenge.
Could be right, im trying to figure out why connect4 isnt working right now,
it keeps drawing odd shapes that disappear a second later.
 

refraction

PCSX2 Coder
Doomulation said:
Believe me, it's wrong. I should definetly NOT be incremented. Those docs are lying. I fell for that once, too, and I know it should not.

erm, you do increment I on FX55 and FX65, you just dont increment it on the BCD op.

if you werent suppose to how come both neochip8 and my emu used it and still had pretty much 100% compatability without graphical errors?
 

Doomulation

?????????????????????????
Dunno. I do not increment these, as I found it to be an error. Take a look at the source. Our emus are pretty much the same in terms of compability and graphical errors.
 

refraction

PCSX2 Coder
i dont think it makes much of a difference, im thinking after FX55 or 65 is called the game repoints I anyway, so i spose it wouldnt make much difference
 

Doomulation

?????????????????????????
No, but values can be saved at incorrect position. After saving, say, 4 registers, the game would call the opcode add 4 to some register and then save more. This would cause inaccuracy.
In any case, I suggest you test what's best for you. I say, do not increment it, but it's up to you.
 

ChaosBlade

My Heart Chose.. Revenge.
The thing is, it creates an entirely different behavior in games.

Check connect4 for example, without increments, it simply draws whole rows of shapes that seem to do absolutly NOTHING (NeoCHIP8 & Mine Without ++'s). Add increments again, and look what you get - Now it seems to be some sort of matching game (4 in a row didnt do anything, so ive no idea what the game does :p).

Now im confused as to if my emulator is correct or not. Its odd.
 

Doomulation

?????????????????????????
Lemme check...
I'll just get my hands on my emulator and run the game.
EDIT: Argh. Can't get my hands on the game. Can't be bothered to google. Sigh...
 
Last edited:

refraction

PCSX2 Coder
hmm that also might cause a problem, on the FX55 and FX65, you are incrementing I twice when the for loop has finished, that will cause problems, it only increments after writing each value, but on the last one it writes and increments, breaks the for loop, increments I again, thats bad lol.


apart from that your emu looks pretty spot on, altho itd be a lot neater if you made the jump table, half the file is just a switch with void calls in, so you may as well make a jump table and do like

jumptable[sOpcode]();

be much neater, the op table isnt very big neway lol

oh and one thing, if you're gonna have a switch put a "default:" case at the bottom of it, just in case you have a miss jump/opcode call you can then see where it went wrong.
 

ChaosBlade

My Heart Chose.. Revenge.
Actully, i dont think i messed with jump tables alot. I vaguely remember using it once or twice. Care to give a simple example i could follow ? i really dont remember.

I also noticed and removed the sI += 1 lines in both opcodes, not sure why i put them in the first place :p

And about the default, you're right, its a standard thing to use the default case & im proud at following standard code writing ;)
 

Doomulation

?????????????????????????
Jump tables are pretty basic. It's pretty much arrays of function pointers.
You can do it something like this:

Code:
void (*JumpTable)()[] = { some_func, some_func2 };
void ExecuteOpcode()
{
JumpTable[ opcode >> 12 ]();
}

First we declare an array of function pointers. Then we shift the opcode, so that the "main" part of it (if it's 0x8000, then the value is 0x8) to specify the index to jump to. As simple as that.
 
Last edited:

ChaosBlade

My Heart Chose.. Revenge.
Yup, Pretty simple. Ill see about converting the switchs to jump tables, since it seems the emulator is doing its job allright, as far as we know =p

One odd thing - I switched the the .NET2003 IDE recently, and after getting the iostream and fstream includes to be recognized (stupid managed C++, i hate you bill gates =p),
fstream files just wont work anymore. any file open operation, no matter which mode or path is it in, fails.
 

Top