CHIP8 thread

Discussion in 'Web development / Programming' started by Dax, Nov 21, 2008.

  1. xneoangel

    xneoangel New Member

    Messages:
    8
    Likes Received:
    0
    Ok this is kinda embarassing and i certainly didn't expect to see this result when testing my emu... must have inverted some matrix indexes on the drawing opcode >.<

    Other than the fact that the screen is inverted and that the bullet gets glitched when it gets accross the screen... it seems to be working

    i guess it's time for some debugging :D
  2. runawayprisoner

    runawayprisoner Level 9998

    Messages:
    9,384
    Likes Received:
    0
    Looks like you may be looping screen array inversely. If it's a double loop, see if you didn't call the other index by accident.
  3. xneoangel

    xneoangel New Member

    Messages:
    8
    Likes Received:
    0
    yeah i thought my problem was on the drawing opcode, turns out it was on my paint method >.<

    Although i still have a problem... if i shoot and miss an enemy the bullet just keeps looping all over the screen until it happens to hit something o_O... i believe there's something wrong with my drawing opcode as i have double checked all of my code and everything seems fine... my emu also passes all of tronix's tests except for the s-chip ones because well that isn't implemented as of right now...

    Anyway would you mind taking a look at this code and tell me if you see anything wrong? i believe it has something to do with the fact that i'm using mod32 on my y coordinate and mod64 on my x coordinate... the thing is if don't do that i get an index out of bounds exception... and if i put an if there to ignore coordinates that are offscreen well my graphics get heavily corrupted :(

    Code:
    X = (char)((opCode&0xF00)>>8);
    Y = (char)((opCode&0xF0)>>4);
    registers[15] = 0;
    for (int i = 0; i < (opCode&0xF); i++)
    {
        char line = memory[address+i];
        char pos = 0x80;
        for (int j = 0; j < 8; j++)
        {
            if (((line&pos)>>(7-j)) == 1)
            {
                if (screen[(registers[Y]+i)%32][(registers[X]+j)%64])
                    registers[15] = 1;
                screen[(registers[Y]+i)%32][(registers[X]+j)%64] ^= true;
            }
            pos >>= 1;
        }
    }
    
    Edit: I got it... i decided to recheck all of my opcodes yet again and i found the glitch, it actually was on 7XKK...
    Code:
    X = (char)((opCode&0xF00)>>8);
    registers[X] = (char)((registers[X]+(opCode&0xFF))&0xFF);
    
    I had forgotten to do that last AND to ensure that my registers stay at 8-bits... it was causing some weird errors, but now i think my emu is working almost if not perfectly... now what i need to do is find a way to output my graphics using the video hardware instead of the CPU... because the emu is getting kinda slow at some points, and for a chip8 emu running on a core i7 laptop that's BAD T_T...

    Then i also need to implement the s-chip instructions :p
    Last edited: Mar 2, 2011
  4. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    Which graphics backend do you use to render? I use OpenGL and I had to flip the projection.

    as for Super Chip 8 Opcodes, I have implemented them.


    Code:
            [OpcodeTag(ChipOpCode.Ld_F_75)]
            void Load_F75(ChipInstruction inst)
            {
                for (int i = 0; i <= inst.X; i++)
                    m_RPLFlags[i] = m_VRegs[i];
            }
    
            [OpcodeTag(ChipOpCode.Ld_F_85)]
            void Load_F85(ChipInstruction inst)
            {
                for (int i = 0; i <= inst.X; i++)
                    m_VRegs[i] = m_RPLFlags[i];
            }
    
            [OpcodeTag(ChipOpCode.extOn)]
            void ExtOn(ChipInstruction inst)
            {
                OnSuperModeChange(true);
            }
    
            [OpcodeTag(ChipOpCode.extOff)]
            void ExtOff(ChipInstruction inst)
            {
                OnSuperModeChange(false);
            }
    
            [OpcodeTag(ChipOpCode.exit)]
            void Exit(ChipInstruction inst)
            {
                return;
            }
    
            [OpcodeTag(ChipOpCode.Ld_F_30)]
            void Load_F30(ChipInstruction inst)
            {
                m_IReg = (ushort)(80 + (m_VRegs[inst.X] * 10));
            }
    
            [OpcodeTag(ChipOpCode.scrollN)]
            private void ScrollDown(ChipInstruction inst)
            {
                OnPixelScroll(2, inst.N);
            }
    
            [OpcodeTag(ChipOpCode.scrollL)]
            private void ScrollLeft(ChipInstruction inst)
            {
                OnPixelScroll(1, 4);
            }
    
            [OpcodeTag(ChipOpCode.scrollR)]
            private void ScrollRight(ChipInstruction inst)
            {
                OnPixelScroll(3, 4);
            }
    
            protected void OnPixelSet(ChipInstruction inst)
            {
                if (PixelSet != null)
                {
                    m_VRegs[0xF] = 0;
                    byte x = m_VRegs[inst.X];
                    byte y = m_VRegs[inst.Y];
                    byte read = 0;
    
                    if (inst.N > 0)
                    {
                        for (byte i = 0; i < inst.N; i++)
                        {
                            read = m_Memory.GetByte(m_IReg + i);
    
                            for (byte j = 0; j < 8; j++)
                            {
                                if ((read & (0x80 >> j)) != 0)
                                {
                                    PixelSet(this, new PixelSetEventArgs((x + j), (y + i)));
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int k = 0; k < 0x10; k++)
                        {
                            ushort data = Tools.Create16(m_Memory.GetByte(m_IReg + (k << 1)), m_Memory.GetByte(m_IReg + (k << 1) + 1));
    
                            for (int m = 0; m < 0x10; m++)
                            {
                                if ((data & (((int)0x8000) >> m)) != 0)
                                {
                                    PixelSet(this, new PixelSetEventArgs((x + m), (y + k)));
                                }
                            }
                        }
                    }
                }
    
                Thread.Sleep(8);
            }
    
  5. xneoangel

    xneoangel New Member

    Messages:
    8
    Likes Received:
    0
    I'm not really using any fancy API to do the graphics, just the regular Graphics class which is kinda like java's equivalent to c# GDI. So it's really slow :(
  6. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    You should try OGL for Java.
  7. Bill_gates

    Bill_gates Linux's worst nightmare..

    Messages:
    1,510
    Likes Received:
    0
    unchecked the chip 8 emulator I developed in java runs so fast its hardly useable
    I had to use Thread.Sleep() to slow it down to playable speeds
    and thats running on my core 2 duo laptop.

    I dont think the use of java's graphics class is your issue
  8. xneoangel

    xneoangel New Member

    Messages:
    8
    Likes Received:
    0
    Yeah maybe i should try JOGL... it's just that i didn't wanna get involved with OGL on simple emulator as this one >.<

    And about the slowdowns... it's only noticeable on space invaders... all the games (that i have tested) run fine but when i run invaders it starts well but when i get to about the 5th stage (if they can be called stages) when the ships start coming down faster i start to get some noticeable slowdown...
  9. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    I know some are using Direct3D for chip8 :p
  10. Hatorijr

    Hatorijr Emu Author

    Messages:
    613
    Likes Received:
    1
    my new framework will be using slimdx for direct3d, might do a benchmark when its finished to see if the speed is improved or not.
  11. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    @hator: I think if you use WPF, it has a control for a D3D Surface, maybe better than SlimDx.
  12. LoRd_SnOw

    LoRd_SnOw Member

    Messages:
    177
    Likes Received:
    2
    My chip-8/schip emulator also uses gdi for a plugin, but it runs about as fast as fish n' chips. I believe your problem is how you are using gdi in java. Perhaps it has to do with the way you're managing the screen refresh rate, try putting the refresh rate into a seperate thread, a more viable way would be a timer for 1ms.
  13. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    Well I have managed to get a chip8 hybrid game called Bingo working. Using my CDP1802 hybrid IL dyanrec, it will make the game happier. One of bingo's 1802 functions is pixel scrolling and it works with some little pixel garbage at the last pixel row. The only bug I see there and it doesn't seem to grab the key values but reacts to the keys. I am trying to get BlackJack to work as well, which where the compiled functions seem to be working fine but the chip8 PC is somehow off somewhere so I think one of the compiled 1802 functions is a culprit and its causing the PC to be off. Using a hack that corrects the PC value makes the game show the 200 at the bottom screen but still breaks probably because of the same issue, but I am close finding out why the bug happens.

    EDIT: I fixed the graphics bug by letting the game exactly set the X and Y pixel pointers (R6, R7)

    Bingo Hybrid Chip8 Game showing the entries scrolling up every round
    [​IMG]
    Last edited: Apr 14, 2011
  14. LoRd_SnOw

    LoRd_SnOw Member

    Messages:
    177
    Likes Received:
    2
    I'm rather confused, isn't Bingo originally a rom meant for chip-8, i just tested this on FNC and my own emu, doesn't seem to show anything. Would you care to explain more about this and what direction did you take to get it to where you are now?
  15. Hatorijr

    Hatorijr Emu Author

    Messages:
    613
    Likes Received:
    1
    some games require the hardware side of the chip-8 interpreter to be emulated, these are generally called hybrid games. so if you manage to emulate the hardware than you should be able to get that game to run. i currently have yet to emulate the 1802 in my chip8 and instead working on another project but the document that has been found should make it relatively easy to do. not sure if its been put up on this thread, if not i can include it in another post.
  16. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    Hybrid games need support of the syscall chip8 opcode which points to a block of CDP1802 instructions loaded in memory by the chip8 rom, my emulator supports recompiling the CDP1802 code functions and then executing it. All CDP1802 code blocks are required to end with SEP 04 as the VIP doc says, and makes it easy for me to find the end point of each syscall.

    Also, the Add_7 chip8 opcode uses carry, so I assume all addition operations in chip8 uses 0xF for carry. Supporting the carry gets blackjack hybrid game to show the 200 score at the bottom of the screen else its all black screen.

    Edit: I think somehow V register 7 is also used as a carry flag, blackjack is happy with that and almost works, but the input still doesn't function right for hybrid games:

    Docs on 1802 CPU and VIP:

    http://www.cosmacelf.com/shortcourse.htm
    RCA 1802 - Wikipedia, the free encyclopedia
    The 1802 Instruction Set
    http://mess.redump.net/sysinfo:vip
    RCA Cosmac VIP - Instruction manual for VP-111
    RCA COS/MAC Microprocessor Trainers
    RCA 1802
    http://www.hobbylabs.org/files/1802/RCA1802UserManual1976.pdf


    Blackjack
    [​IMG]
    [​IMG]
    Last edited: Apr 27, 2011
  17. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    Ok, news update about hybrids, as I have gotten Blackjack and Bingo to fully work. ;)

    First to support to the syscalls for chip8 programs, you need to understand some CDP1802 instructions that are in the chip8 rom. The syscall instruction has an address that points to CDP1802 code to execute. Second, all CDP1820 code should end with SEP 04 code.

    Note: Add7 doesn't do carry and Vreg 7 isn't used as one either. My hypothesis was wrong.

    The 1802 code needs the following in memory access:

    - Font Ram in current interpreters, prolly not important though
    - The chip memory
    - the stack memory of the chip8 interpreter, I haven't implemented this yet
    - the registers and memory of the chip8 interpreter itself, mine only allows I/O of the Vregs so far
    - the video memory with an address like 0xXX00, the low byte has to always be zero, the 1802 code always AND's the HI part of the video pointer address with an offset and then stores in register A (the chip I address on the VIP).

    I always generate a syscall method where registers P is set to 2, and X is set to 3 and there are some other default register values you need and how it should be setup since we are doing a hybrid mode.

    CDP1802 General Registers
    R0: let the game set this value, its used for DMA pointers
    R1: Some Interrupt pointer, I let the game do anything with it
    R2: Pointer to stack memory, I left this at 0
    R3: This should always return the routine address alas the syscall address
    R4: This is normally used as the VIP PC, let the game set it to anything
    R5: Must return the chip8 PC value, and let the game set it
    R6: must be set to the pointer of the chip8 core values such as vregs and let the game set it
    R7: same as R6
    R8: chip8 timer data: ((DT << 8) & ST), and let the game set it
    R9: return the last random value generated in chip8 core
    RA: Must return the value of the chip8 I register, and let the game set it too
    RB: return pointer to video memory, don't let game change it
    RC: scratch register
    RD: scratch register
    RE: scratch register
    RF: set to the video pointer address, let game change it



    Here are some screenshots
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]
    Last edited: May 1, 2011
  18. BestCoder

    BestCoder Member

    Messages:
    46
    Likes Received:
    0
    Chip 8 TestRom by BestCoder

    Hello,

    Here is a test rom for Chip 8 that I have made. You can find how to use it in the readme file. Hope that it will be helpfull.
    Edit: add informations to readme
    Last edited: Jul 4, 2011
  19. Dax

    Dax ライチュウ|タオ

    Messages:
    4,016
    Likes Received:
    20
    Updated the first post with Bestcoder's test rom and Omega's links to docs on the 1802 CPU. Some day I'll come back to this thread and make a list of all your guys' emulators, too. I'm too lazy at the moment to do it now, though. :p
  20. omegadox

    omegadox Code it the hard way :P

    Messages:
    1,267
    Likes Received:
    0
    Well thanks dax :)

Share This Page