What's new

Chip 8

bcrew1375

New member
Yeah, SDL is definitely good for people that want to bypass the gritty stuff, and get right to coding the actual program.
 

Redjack

Banned
Zenogais : I beginning my own chip8 emulator and it advances well.
i programmed almost all opcodes instructions but in debug mode with a Chip8 rom, there rom is repeat at instructions "Exec_JP()".

here an extract of my source code :
Code:
void InterpreterOpcode()
{
    switch((Chip8.Opcode)&0xF000>>12)
    {
        case 0x00:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0xE0: EXEC_CLS(); break;
                case 0xEE: EXEC_RET(); break;
            }

        case 0x01: EXEC_JP(); break;
        case 0x02: EXEC_CALL(); break;
        case 0x03: EXEC_SE_byte(); break;
        case 0x04: EXEC_SNE(); break;
        case 0x05: EXEC_SE_vy(); break;
        case 0x06: EXEC_LD_byte(); break;
        case 0x07: EXEC_ADD_byte(); break;

        case 0x08:
            switch((Chip8.Opcode)&0x000F)
            {
                case 0x00: EXEC_LD_vy(); break;
                case 0x01: EXEC_OR(); break;
                case 0x02: EXEC_AND(); break;
                case 0x03: EXEC_XOR(); break;
                case 0x04: EXEC_ADD_vy(); break;
                case 0x05: EXEC_SUB(); break;
                case 0x06: EXEC_SHR(); break;
                case 0x07: EXEC_SUBN(); break;
                case 0x0E: EXEC_SHL(); break;
            }
            break;

        case 0x09: EXEC_SNE_vy(); break;
        case 0x0A: EXEC_LD_adress(); break;
        case 0x0B: EXEC_JP_adress(); break;
        case 0x0C: EXEC_RND(); break;
        case 0x0D: EXEC_DRW(); break;
        case 0x0E:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0x9E: EXEC_SKP(); break;
                case 0xA1: EXEC_SKNP(); break;
            }
            break;

        case 0x0F:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0x07: EXEC_LD_dt(); break;
                case 0x0A: EXEC_LD_k(); break;
                case 0x15: EXEC_LD_vx(); break;
                case 0x18: EXEC_LD_st(); break;
                case 0x1E: EXEC_ADD_vx(); break;
                case 0x29: EXEC_LD_f(); break;
                case 0x33: EXEC_LD_b(); break;
                case 0x55: EXEC_LD_i(); break;
                case 0x65: EXEC_LD_vxi(); break;
            }
            break;

        default:
            break;
    }
}

void EXEC_RET()
{
     Chip8.SP--;
     Chip8.PC=Chip8.Pile[Chip8.SP];
     Chip8.PC+=2;
     
     cout << "opcode RET" << endl;
}

void EXEC_JP()
{
    Chip8.PC=Chip8.Opcode & 0x0FFF;
    
    cout << "opcode JP" << endl;
}

void EXEC_CALL()
{
     Chip8.SP++;
     Chip8.PC=Chip8.Pile[Chip8.SP];
     Chip8.PC=Chip8.Opcode & 0x0FFF;
     
     cout << "opcode CALL" << endl;
}

void EXEC_SE_byte()    // SE Vx,Bytes
{
     if(Chip8.Registre[(Chip8.Opcode & 0x0F00)>>8]==(Chip8.Opcode & 0x00FF)) Chip8.PC+=2;
     
     cout << "opcode SE 1" << endl;
}
please, somebody has an idea of the problem ?:(
 
Last edited:

Garstyciuks

New member
Maybe I didn't understand your problem, but jmp instruction is used to jump to another location (it may be a few bytes before, so it would repeat the code or some chip8 games jumps 2 bytes back and repeat the jump instruction when the game ends, since it doesn't have quit opcode, like super chip does) If that isn't what you wanted to hear maybe you can restate your problem, because it's hard to understand.
 
Last edited:

ector

Emulator Developer
Not sure if this is your problem, but:
Code:
        case 0x00:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0xE0: EXEC_CLS(); break;
                case 0xEE: EXEC_RET(); break;
            }
       !!!!!!!!!!!you need a break; here!!!!!!!!
 

Redjack

Banned
thanks ector. I need a break.
Now, i not sure but it's normal that my interpreter repeat it ?

i always CLS instructions in my debug mode.
i not never seem others instructions running!

In the CLS instructions, i do :

Chip8.PC += 2;

it's good ?
 

Redjack

Banned
i beginning has to have different instructions !
here an extract of my source code modified :

Start Emulation function :
Code:
void DemarrerEmulation()
{
    Chip8.Opcode=(Chip8.Opcode<<8)|Chip8.MemoireRom[Chip8.PC+1];
    
    InterpreterOpcode();
    
    if(Chip8.RegDelayTimer > 0) Chip8.RegDelayTimer--;
    if(Chip8.RegSoundTimer > 0)
    {
        if(Chip8.RegSoundTimer==1) Beep(150,30);
        Chip8.RegSoundTimer--;
    }
    Chip8.PC+=1;
}

here, opcode Interpreter function
Code:
void InterpreterOpcode()
{
    switch((Chip8.Opcode)&0xF000>>12)
    {
        case 0x00:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0xE0: EXEC_CLS(); break;
                case 0xEE: EXEC_RET(); break;
            }
            break;

        case 0x01: EXEC_JP(); break;
        case 0x02: EXEC_CALL(); break;
        case 0x03: EXEC_SE_byte(); break;
        case 0x04: EXEC_SNE(); break;
        case 0x05: EXEC_SE_vy(); break;
        case 0x06: EXEC_LD_byte(); break;
        case 0x07: EXEC_ADD_byte(); break;

        case 0x08:
            switch((Chip8.Opcode)&0x000F)
            {
                case 0x00: EXEC_LD_vy(); break;
                case 0x01: EXEC_OR(); break;
                case 0x02: EXEC_AND(); break;
                case 0x03: EXEC_XOR(); break;
                case 0x04: EXEC_ADD_vy(); break;
                case 0x05: EXEC_SUB(); break;
                case 0x06: EXEC_SHR(); break;
                case 0x07: EXEC_SUBN(); break;
                case 0x0E: EXEC_SHL(); break;
            }
            break;

        case 0x09: EXEC_SNE_vy(); break;
        case 0x0A: EXEC_LD_adress(); break;
        case 0x0B: EXEC_JP_adress(); break;
        case 0x0C: EXEC_RND(); break;
        case 0x0D: EXEC_DRW(); break;
        case 0x0E:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0x9E: EXEC_SKP(); break;
                case 0xA1: EXEC_SKNP(); break;
            }
            break;

        case 0x0F:
            switch((Chip8.Opcode)&0x00FF)
            {
                case 0x07: EXEC_LD_dt(); break;
                case 0x0A: EXEC_LD_k(); break;
                case 0x15: EXEC_LD_vx(); break;
                case 0x18: EXEC_LD_st(); break;
                case 0x1E: EXEC_ADD_vx(); break;
                case 0x29: EXEC_LD_f(); break;
                case 0x33: EXEC_LD_b(); break;
                case 0x55: EXEC_LD_i(); break;
                case 0x65: EXEC_LD_vxi(); break;
            }
            break;

        default:
            break;
    }
}

this instructions (Chip8.Opcode=(Chip8.Opcode<<8)|Chip8.MemoireRom[Chip8.PC+1]; ) i copy from CrazyShip8 source code of emulator.
but I don't understand why " Chip8.Ocpode << 8".
Why shift of 8 bit Left ??
 
Last edited:

Garstyciuks

New member
I think that it is wrong. It should be Chip8.Opcode = (Chip8.MemoireRom[Chip8.PC]<<8) + (Chip8.MemoireRom[Chip8.PC+1]);
And you should add 2 to the pc, because chip8 opcodes are 16 bit size. And the sound speaker beeps, when it's timer value is larger than zero, not only when it is one.
 
Last edited:

rockytrh

New member
I have a question for ya. I will be a first year comp sci student next year, but i have already learned c++ (too much time on my hands). I would like to program a chip8 emu, and have some questions. First off, is it possible to program a chip8 with MFC, or even stricty oop for that matter? I ask, because i don't know C, only know C++ form an oop standpoint. Secondly, i an new to programming graphics, and would like to know where i can get a handle on that.

Thanks all,
Rocky
 

Doomulation

?????????????????????????
Yes, it is possible to program an emulator with MFC.
You don't need to program anything in C, and if you know C++ then you will understand C.
Graphics can be done many different APIs, such as DirectDraw, Direct3D, SDL, GDI, OpenGL. Pick one you feel is the best and see some tutorials and you should be able to make it work. Note that Direct3D and DirectDraw are the same in newer versions of DirectX, so you can only use d3d and you'll automatically use ddraw.
 

hap

New member
If you're not familiar with any of those graphics APIs like most beginning programmers mentioned by Doomulation, don't worry, you can always use good old 'cout' or 'printf', it has been done before and posted in this thread, but don't expect anything spectacular. Also, if you don't know how to read from the keyboard, though it's much easier than graphics programming, you could use GUI buttons... Hey, you could even use GUI buttons (or labels) for the graphics, a novelty :p
 

Garstyciuks

New member
rockytrh said:
I have a question for ya. I will be a first year comp sci student next year, but i have already learned c++ (too much time on my hands). I would like to program a chip8 emu, and have some questions. First off, is it possible to program a chip8 with MFC, or even stricty oop for that matter? I ask, because i don't know C, only know C++ form an oop standpoint. Secondly, i an new to programming graphics, and would like to know where i can get a handle on that.

Thanks all,
Rocky
If you are interested, I have written a chip8/schip8 emulator in MFC and OpenGL, you can find a link to it in my signature. (source code available)
 

hap

New member
Check carry generation, it's easy to make mistakes with it, examples:

16 bit shift:
ld v1 #80
ld v0 1
shl v0
shl v1: vf will be set to 1 here, because bit 7 was set and shifted out
or v0,vf: v0 will be 3

16 bit add:
ld v1,#ff
ld v0,1
ld v2,1
add v1,v2: v1 will be 0, and vf will be 1 because there was an overflow
add v0,vf: v0 will become 2: note that you'll have to update vf after the addition and not before, that wouldn't make sense

achieved perfect chip8 compat? :p
I did think that with previous releases, but now, after finding/fixing silly bugs that have been there since day one, I won't anymore :p
 

Garstyciuks

New member
The only flaw with carries I found is when you would add any register with the flag register. But it still can't run your rom :/
 

hap

New member
Your SHL carry calculation is incorrect:
memory.reg[15] = memory.reg[(opcode&0x0F00)>>8] & 0x80;
change to something like:
memory.reg[15] = (memory.reg[(opcode&0x0F00)>>8] & 0x80)>>7;

Also, carry calculation for every math opcode should be done after register calculation, and not before, because vf may be used in maths, eg:
ld vf,1
shr vf
vf will be 1 again
 

Top