Gngeo NEOGEO emulation [W.I.P.]



       sudo apt install --no-install-recommends git build-essential libsd1.2-dev 

       mkdir ~/.gngeo ~/neogeo

       wget -O ~/.gngeo/gngeorc

       git clone ~/ng

       cd ~/ng/gngeo

       export CFLAGS="-mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon"

       ./configure --host=arm-linux --target=arm-linux --disable-i386asm --prefix=/usr

       make && sudo make install

Place your NeoGeo BIOS uncompressed in /home/chip/neogeo and the games WITHOUT uncompressing in the same folder. To run the games:

       ~/ng/gngeo/gngeo ~/neogeo/


cursor keys = joystick
3 = Insert Coin
1 = Start Player 1
h = A
u = B
k = C
i = D

I said [W.I.P.] because from now it runs, but when I load a game, it crashes, maybe it can be because memory allocation, I am not sure.

Fast SNES emulation on the PocketC.H.I.P

While debugging the error, I see problem is at OPNWritereg in ym2610.c, at the line 1606.

The NeoGeo’s sound chip code implementation.

"bt show" 

#0  OPNWriteReg (OPN=0x10c1d0 <YM2610+512>, v=<optimized out>, r=328790) at ym2610.c:1606
#1  ym2610_mkstate (
    gzf=<error reading variable: Cannot access memory at address 0xbf004414>, 
    mode=<optimized out>) at ym2610.c:3149


Oh wow… I suddenly want to play Metal Slug on my Pocket C.H.I.P.! My poor dearly departed NEO-GEO Pocket Color would be soooo jealous! lol


Mednafen emulates that, too. And the instruction on that Mednafen thread work similarly for the NGP engine.

Search for “ngp.” on the config file.

About Metal Slug, if anyone fixes gngeo without crashing, it would be glorious.


You are one step ahead, but anyway something weird is going on in the sound thread. Any change in ym2610.c, even a bogus line such as “r = r;” results in the segfault moving to a completely different part of the code.
It’s like a thread is overwriting the static YM2610 instance while a different thread tries to read it.


The default emulation cores seem a bit dodgy.
If you run configure with these flags:

--with-m68kcore=gen68k --with-z80core=mamez80

it will go a bit further, but then it crashes while copying ROM regions in memory.c…


What about this fork?


Oh, that looks promising! Can’t wait to try it, but that will have to wait until Monday :frowning:


I built it, the same damn error.

I think gngeo needed dumpgfx used on the biggest roms and then copy the resulting file to the roms folder, but dumpgfx crashes too due to pointers to illegal accesses or whatever.

It crashes too in my X86 OpenBSD machine, so I am out of luck :frowning:

ander:/home/ander/dev/dumpgfx>./dumpgfx /home/ander/neogeo/            
e/ander/neogeo/                                                      <
dumpgfx(86142) in free(): error: bogus pointer (double free?) 0x7f7ffffdc6da
Abort trap 

Tried with gcc, egcc, tcc, pcc, and clang. No luck.

Starting program: /home/ander/dev/dumpgfx/dumpgfx /home/ander/neogeo/
dumpgfx(56659) in free(): error: bogus pointer (double free?) 0x7f7ffffbb7d0

Program received signal SIGABRT, Aborted.
0x000009adca41325a in thrkill () at <stdin>:2
2       <stdin>: No such file or directory.
        in <stdin>
Current language:  auto; currently asm
(gdb) bt
#0  0x000009adca41325a in thrkill () at <stdin>:2
#1  0x000009adca3df8c9 in *_libc_abort ()
    at /usr/src/lib/libc/stdlib/abort.c:52
#2  0x000009adca4300c9 in wrterror (d=0x9ada8aa17c0, 
    msg=0x9adca57d4a8 "bogus pointer (double free?)", p=0x7f7ffffbb7d0)
    at /usr/src/lib/libc/stdlib/malloc.c:306
#3  0x000009adca43138a in ofree (argpool=0x9ada8aa17c0, p=0x7f7ffffbb7d0)
    at /usr/src/lib/libc/stdlib/malloc.c:1367
#4  0x000009adca43158b in free (ptr=0x7f7ffffbb7d0)
    at /usr/src/lib/libc/stdlib/malloc.c:1399
#5  0x000009ab2ac020bf in dr_load_game (dr=0x9ad45b9d800, 
    name=0x7f7ffffbb7d0 "/home/ander/neogeo/") at driver.c:620
#6  0x000009ab2ac02912 in main (argc=2, argv=0x7f7ffffbb5c8) at main.c:18

Dumpgfx compiled from


Ok, that’s a bit easier to debug than gngeo’s 68k cores :smiley:

The free(zip) at line 620 in driver.c shouldn’t be there. It is trying to free argv[1], thus the error.
Very likely a leftover from when line 617 was still in place, as “zip” used to be allocated with malloc at line 446.

Delete line 620 and it should work.


". It is trying to free argv[1], "

That’s why I was getting mad. Why does it had to free() an argument?

I commented the line, now it works. It gave me a mslug.gfx which I think it could be used by gngeo.


Still nothing with gngeo, but dumpgfx at least works.


I was thinking this may be a linker / relocation issue. The reason is that the problem seems to occur when a function is called that was compiled from assembly.

Execution jumps all over the place and even gdb gets confused. In fact, the call stack showed an error in the sound emulation code long before the sound had started, and the function where the exception happened had not been called at all.
This is like a jump instruction has been buggered up with a wrong jump address.

To further confirm this, if I replace the m68k assembly core with a C core, the error moves to the z80 core (assembly only).

When I have time I want to try a different version of my toolchain and see if that makes a difference.


Try to compile it with an older version of GCC.


Yeah, backwards seems to be the way to go. So far I’ve tried 4.8, 4.9, 5.2 and 5.4 without success.
Might be a bug introduced in a recent version.


Well, compiled with gcc 4.4 and now I get an initialisation error so it doesn’t even start :frowning:
This is tougher than expected! I wonder if it would be easier to use one of the many FBAlpha forks.