What's new

My PotatoChipAte

glVertex3f

Crap Cracker
Ive been trying to make one of these things... and after reading throught the "Chip8" thread, I still have a few questions. Mainly I want to know if im on the right track, and if im doing any "no no's" in my code.

Please keep in mind that this is my first emu project and I just started this yesterday. Also that I am completely selftaught and the only time I learn new things about coding is when I happen to need it for my program. <- Thats why my code might seem n00bish.

EDIT: also, I am a bit slow... I cant seem to figure out how to put the "Memory" at position "I" without messing up the other drawing code (such as finding the x and y).
 
Last edited:

Doomulation

?????????????????????????
Ah, nice work for a first project. Pretty good, yes, but also some errors...
Opcodes are missing (I guess you'll add them later? ;))
After the jump opcode, PC is NOT incremented (0x1000).
A subroutine is like a function. You jump to the address for the function, and then execute code until you get the op 0x00EE (return from subroutine). The emulator jumps back to where it jumped to the subroutine and continues to execute ops after it.

Btw, lots of your math ops with carry are wrong.
Here, I'll attach my experimental doc for n00bs. Some info may be inaccurate, but still... hope this helps :)
 
OP
glVertex3f

glVertex3f

Crap Cracker
THANK YOU!

Being the self proclaimed n00b that I am, those docs are exactly what i need.

At the risk of making my n00by-ness supreme.... I cant really understand the whol font thing...

0xF0, 0x90, 0x90, 0x90, 0xF0 <<-- Like how is this zero?
 

refraction

PCSX2 Coder
glVertex3f said:
THANK YOU!

Being the self proclaimed n00b that I am, those docs are exactly what i need.

At the risk of making my n00by-ness supreme.... I cant really understand the whol font thing...

0xF0, 0x90, 0x90, 0x90, 0xF0 <<-- Like how is this zero?

convert it into binary ;) cos thats how chip8 draws it, you get something like this

0xF0 = 11110000
0x90 = 10010000
0x90 = 10010000
0x90 = 10010000
0xF0 = 11110000

look at what shape the 1's make ;) if you cant see ill replace the 0's with .'s

0xF0 = 1111....
0x90 = 1. .1....
0x90 = 1. .1....
0x90 = 1. .1....
0xF0 = 1111....

also the bcd command in his document

FX33 Store BCD representation of VX in I...I+2 (*****)

do NOT increment I when doing it do like it says there, I, I+1, I+2

and if his bcd code doesnt work try this

memory = i/100;
memory + 1 = (i%100)/10;
memory + 2 = i%10;
 
Last edited:

refraction

PCSX2 Coder
also the subroutine code this is a good way to do it


assign a new unsigned char array in your header 16 spaces big called stack, and an integer called Subcall or something (this will be used to point to the right place in the array.

then when it calls the subroutine do something like this

if (Subcall < 16){
stack[Subcall] = PC;
PC = opcode&0x0FFF;
Subcall++;
}

then when you return from it
(if Subcall>0){
Subcall--;
PC = stack[Subcall];
stack[Subcall] = NULL;
}
 
OP
glVertex3f

glVertex3f

Crap Cracker
I updated the file at the top...
Now what im wanting to know is
A) Shouldnt this at least draw SOMETHING to the screen...
and
B) Are there any crucial opcodes I am missing. I am only wanting to get something on the screen, like the PONG Paddles or what not.

The reason is, I am trying to grasp the basic concepts of what each opcode does and for what reason. Then I am going to recode all of it, and put in timers and sound and user input and make the code overall neater.
 

refraction

PCSX2 Coder
well at the moment the emu doesnt run for me now, it just crashes :p

but one problem ive seen, in a few opcodes (like 0x7000) youve put in PC+=2; and youve put it at the end as well so it basically does PC+=4; every cycle, which you dont want if you dont want to skip an instruction.

the display buffer should be [64][32] as its 64 across and 32 down.. so youll need to swap it round in your drawsprite opcode call as well, plus remember its drawn in a XOR form as it uses the opcode to remove sprites as well as plot them. so itd be better having it as an 8bit array rather than boolean.

plus you need to check for collision too. so youd need something like

if (DisplayBuffer[Display.x + loopX][Display.y + loopY] = 1) V[F] = 0x1;
DisplayBuffer[Display.x + loopX][Display.y + loopY] ^= 1;


and for missing opcodes, id add the rest of the 0xF000 opcodes as well, theyre pretty crucial :)

the second line being the drawing line end the first line checking for collision.


but remember to set V[F] to 0x0 at the beginning of the opcode (and nowhere else) otherwise you will get a few problems with collision detection.
 
OP
glVertex3f

glVertex3f

Crap Cracker
would this draw?

Code:
void DrawSprite()
{
  int height;
  int x, y;
  int loopX, loopY;
  unsigned char Data;

  height = OpCode&0x000F;
  x = vRegister[OpCode&0x0F00 >> 8];
  y = vRegister[OpCode&0x00F0 >> 4];

  for(loopY = 0; loopY < height; loopY++)
  {
    Data = Memory[loopY + iRegister];
    for(loopX = 0; loopX < 8; loopX++)
    {
      if((Data&(0x80 >> loopX)) != 0)
      {
        if(DisplayBuffer[y + loopY][x + loopX] == 1) vRegister[0xF] = 1;
        DisplayBuffer[y + loopY][x + loopX] ^= 1;
      }
    }
  }
}

I am currently in the middle of rewriting the EMU so I cant exactly test it....

and as for the whole Display[x][y] as to Diaply[y][x]... in the past.. (on tilemaps and mapeditors) ive had to do the y/x instead of x/y... maybe its just the way i do my aray?... i'll see when i get this code fixed
 

zenogais

New member
glVertex3f said:
would this draw?

Code:
void DrawSprite()
{
  int height;
  int x, y;
  int loopX, loopY;
  unsigned char Data;

  height = OpCode&0x000F;
  x = vRegister[OpCode&0x0F00 >> 8];
  y = vRegister[OpCode&0x00F0 >> 4];

  for(loopY = 0; loopY < height; loopY++)
  {
    Data = Memory[loopY + iRegister];
    for(loopX = 0; loopX < 8; loopX++)
    {
      if((Data&(0x80 >> loopX)) != 0)
      {
        if(DisplayBuffer[y + loopY][x + loopX] == 1) vRegister[0xF] = 1;
        DisplayBuffer[y + loopY][x + loopX] ^= 1;
      }
    }
  }
}

I am currently in the middle of rewriting the EMU so I cant exactly test it....

and as for the whole Display[x][y] as to Diaply[y][x]... in the past.. (on tilemaps and mapeditors) ive had to do the y/x instead of x/y... maybe its just the way i do my aray?... i'll see when i get this code fixed

That looks exactly correct.
 
OP
glVertex3f

glVertex3f

Crap Cracker
Ok I just completely rewrote the main cpu code.... The zip is updated at the top up there...

Now, why wont it run anything...

btw.. I will crash on your PC unless you have a direcoty called C:\Chip8 with the BRIX game in it lol

EDIT:
Unless im doing it wrong... my log file shows it not even sending commands to the Cpu emulation...
 
Last edited:

zenogais

New member
Code:
void ReturnFromSub()
{
  if(SubCall > 0)
  {
    SubCall--;
    MemoryIndex = Stack[SubCall];
    Stack[SubCall] = 0;
  }
}

Well a first look shows that this function isn't quite right. I would change it to smth like this:

Code:
void ReturnFromSub()
{
  if(SubCall > 0)
  {
    MemoryIndex = Stack[SubCall];
    Stack[SubCall] = 0;
    SubCall--;
  }
}

Also alot of your opcodes aren't even completed.
 
OP
glVertex3f

glVertex3f

Crap Cracker
I was hoping to see a little progress before I finished all the OpCodes...
And i'll try that function!


EDIT:
I fixed that function.

And shouldnt this show SOMETHING.... anything!?
 
Last edited:

refraction

PCSX2 Coder
hmm well looking at the debug file your emu generated, it doesnt look like its looping properly, seems to do the first loop then thats it (as it came up as 200:0)

im not too sure on that tho im not very good with interfacing with windows :p

it would be an idea to finish off all the commands if you can, then try the emu, its amazing how many of the op codes are used, or maybe rig it up to a different game like space invaders or tetris n see if they work.
 
OP
glVertex3f

glVertex3f

Crap Cracker
I had it set up to write to a log file every time an instruction was passed throught the Emu... And it does nothing.. if I writ the OpCode to the log every loop... the first code is always 0x9090 with every rom I try.. then it does a 0x6xxx... and thats it.
 

refraction

PCSX2 Coder
glVertex3f said:
I had it set up to write to a log file every time an instruction was passed throught the Emu... And it does nothing.. if I writ the OpCode to the log every loop... the first code is always 0x9090 with every rom I try.. then it does a 0x6xxx... and thats it.


hmm i dunno why its doing that. only 2 things i can suggest..

1. try removing the else statement from around CpuEmulation(); and RenderScreen(); in the main.c file.

2. finish off the F000 opcodes, especially the memory access ones.
 

Doomulation

?????????????????????????
Note #1: In clear, a simple ZeroMemory(DisplayBuffer,128*64); should do the trick.
Other than that, I see no big errors in your code.
It should loop on forever it seems, unless something breaks the loop. Try step debugging, it should do the trick.
 
OP
glVertex3f

glVertex3f

Crap Cracker
FX0A: This literally means halt the program until a key is pressed THEN store it...
or just store a key if it is pressed...
 

refraction

PCSX2 Coder
halt the program til the key is pressed. in englishC (my screwed up language i just made up off the top of my head)

check keyarray to is if any keys pressed keypressed

if key was pressed
store in vx and proceed with program.
else
pc-=2

both same effect but gets rid of having to do a for loop.

Edit: if you saw my second optionit was wrong :p and i had to redescribe the first one
 
Last edited:
OP
glVertex3f

glVertex3f

Crap Cracker
Code:
void StoreKey()
{
  if(KeyPress() < 16)
  {
    GetRegValue = KeyPress();
    MemoryIndex += 2;
  }

  else MemoryIndex -= 2;
}

Like that...?
 

Top