Hey there!
I looked through your source code, and there are quite a few problems with your emulator. This might come off kind of rude (I'm not intending to), but a lot of them are rather basic syntax errors. The main issue being, you need to
use more brackets.
I can't stress something like that enough. It may be a bit of a pain, but using brackets in your switch, case and if then else statements can really help reduce bugs. I always use them, even though I don't necessarily have to. It just makes debugging your code and following the control flow easier.
For example (taken from your emulator, CPU.cpp line 12):
Code:
//decode opcode
switch(opcode & 0xF000)
{
case 0x0000:
switch(opcode & 0x000F)
{
case 0x0000: // 0x00E0: Clears the screen
// Execute opcode
break;
case 0x000E: // 0x00EE: Returns from subroutine
pc = sp;sp-=1;
break;
//case 0x8000 starts here...
The lack of brackets here is causing your issues. You're missing the closing bracket on your switch statement (ex. "switch(opcode & 0x000F)").
Your main case statement should also use brackets to enclose the code to be executed in that case, and should also be ended with a break. Otherwise your loops will act sporadically.
Like I said earlier, I'd also use more brackets, even on the statements that don't really need it. Doing this might be a good practice until you get a better grip on where they can and need to be placed. I'd personally use them to enclose the case statement's code too.
Here's what your code should look like, but before you check it, just think about what you think it should look like.
Code:
//decode opcode
switch(opcode & 0xF000)
{
case 0x0000:
{
switch(opcode & 0x000F)
{
case 0x0000: // 0x00E0: Clears the screen
{
// Execute opcode
break;
}
case 0x000E: // 0x00EE: Returns from subroutine
{
pc = sp; sp-=1;
break;
}
}
break;
}
//case 0x8000 starts here...
Hopefully that all makes sense. If it doesn't, you should search up some C++ tutorials online regarding switchs, break usage, brackets, etc.
I also just noticed this, but you're not checking to see if the opcode is $0XXX, the execute 1802 machine code opcode. You don't need to emulate this opcode (that would involve emulating the 1802 host CPU), but you should trap it (skip it, display an error message, etc.). Might get some funky behavior otherwise.
Also, to draw graphics, you need to emulate the opcode $DXYN, which is the draw sprite instruction. Basically, you're going to want to draw sprites to a buffer, then periodically draw this buffer on screen (after a certain number of cycles. There is no correct number of cycles, but I believe most people use a number around 300-400 clock cycles).
Since you're using SDL, you can simply use that to draw things. Check out
these tutorials for info setting it up and drawing things.
I think you might be a bit in over your head with this project, but feel free to prove me wrong. You do have a lot of code done, but you seem to be missing several basic concepts. Then again, C++ isn't exactly an easy programming language.
If you need anymore help, or whatever, feel free to ask.
Good luck!
- Chris