WEBVTT

00:00.000 --> 00:15.760
OK, so hi everyone, I'm Damien Chabrini and in this talk I'm going to discuss the famous

00:15.760 --> 00:22.080
very expensive piece of hardware from the 90s, the Neo Geo that was a console that was

00:22.080 --> 00:27.840
both a console and an arcade cabinet, it was super expensive at the time, it was doing

00:27.840 --> 00:33.200
wonders, a graphical speaking, and there's a backstory to that, I'm going to show you how to

00:33.200 --> 00:41.360
program in C in 2026, so way simpler than in assembler back in the days with a project that I

00:41.360 --> 00:49.280
call the NGDF kit, so the backstory behind that is that in the 90s when I was younger, I used to

00:49.280 --> 00:56.240
own the mega, which was crazy expensive at the time, but graphically speaking it was no as good as

00:56.240 --> 01:00.960
arcade machine, obviously, and I always found that at the time, how do I program those

01:00.960 --> 01:06.720
things? How is it possible that those things are way better, graphically speaking, and

01:06.720 --> 01:13.360
nine machines, which was hosting the same process all right, but that was in the 90s, I was

01:13.360 --> 01:24.480
young, no documentation whatsoever, so there you go, but as it turned out, in the early 2000s,

01:24.560 --> 01:31.680
internet was all over the place, and emulators started to kick in, and of course, the first thing

01:31.680 --> 01:39.520
to be emulated was the arcade machines, and so the Neo Geo was being emulated, and I

01:40.240 --> 01:44.720
this picked up my interest and I said, yeah, surely there has to be more documentation around,

01:44.720 --> 01:51.680
so maybe I could have a look, and I stumbled upon a demo, a humble demo by a guy called

01:51.840 --> 02:01.200
Charles Dotty, which was really a small thing with Sprite, movie, and saying hello world,

02:01.200 --> 02:06.880
but not, and I wondered, ah, that's good, maybe I could try to reverse engineer it and understand

02:06.880 --> 02:13.520
how it works finally, like 30 years after that, 20 years after that, so I started

02:14.480 --> 02:22.080
running it with a small emulator, that was called Neo Geo, that was a super simple emulator

02:22.080 --> 02:27.440
unlike name at the time, so you could end up figuring out quite easily what was going on,

02:28.560 --> 02:34.560
and here I kind of figured out the basics, how to start a program, how to build something, so

02:35.520 --> 02:42.000
I reused what was available at the time, like the classic GCC tool change, GCC cross compiling for

02:42.080 --> 02:48.000
the 6th K, I used the small standard libraries, open source standard libraries available,

02:48.000 --> 02:54.000
Neo lib package it all together, and call it Neo Geo there and push that on source-forge,

02:54.000 --> 03:01.680
anybody remembers source-forge? Yeah, well, that was not a super nice project, it didn't run

03:01.680 --> 03:08.080
the main, obviously, because it was really like the POC basically, but that was good enough for the

03:08.160 --> 03:15.360
GNGO emulator, so this nice, my interest was satisfied, but basically, so I ended up here,

03:17.280 --> 03:26.160
and fast forward a couple of years later, in 2015, I got contacted by a member of a community

03:26.160 --> 03:33.120
that was also called Neo Geo there, so what the hell? And the guy told me that they were in the

03:33.120 --> 03:39.040
process of setting up an entire weeky, like a massive trace of trove of documentation,

03:39.040 --> 03:44.640
repair guides, historical information about the Neo Geo, and I was like, oh yeah, that's my chance,

03:44.640 --> 03:53.840
maybe I could try to start again where I left and maybe do something a bit better, so I took back

03:53.840 --> 03:58.960
my code, implemented everything, and instead of calling it Neo Geo there, I call it then,

03:59.920 --> 04:09.120
yeah, so when you have a look at the Neo Geo Dev weeky, you have the whole picture of how

04:09.120 --> 04:16.640
this particular hardware works, so I don't know if you know that, but the Neo Geo arcade cabinet

04:16.640 --> 04:22.880
was the first arcade machine where the hardware board were using cartridges in games, so that was

04:22.960 --> 04:27.600
really handy for operators, because they just had to swap cartridges, and here they are, they could

04:29.440 --> 04:37.840
massive amount of coins, and basically, under the hood, what's working on the Neo Geo is the

04:37.840 --> 04:44.800
same basic Motorola 68000 that used to run on all the computers at the time, right? A bit faster

04:44.880 --> 04:54.320
but not much, and on the Neo Geo, the 68k runs both your game code and also buy your code,

04:54.320 --> 05:00.080
because the Neo Geo has to run with a bagus, it doesn't have a lot of memory, that's 64 kilobytes of

05:00.080 --> 05:06.720
memory, which at the time sounded really small for me, even with my meager, five hundred and twelve

05:06.720 --> 05:13.680
k of RAM on my meager, but you have the ability to run a massive program run, like the program is

05:13.760 --> 05:19.760
usually one megabyte, and it can go up to eight megabytes, if you do some nice tricks with

05:20.800 --> 05:27.280
banking and things like that, that I'm going to talk about later, specifically for the arcade

05:27.280 --> 05:32.960
version, that's called the MBS, and in the Neo Geo Lingo, you have the ability to save

05:34.560 --> 05:41.200
some of the RAM into a dedicated backup RAM, which is baked with power cell, never runs out,

05:41.280 --> 05:49.360
so that might be of some use, and like other consoles, like other arcade cabinets,

05:49.360 --> 05:55.520
you have the notion of the watchdog, so every couple of milliseconds, if you didn't tweak a particular

05:55.520 --> 06:01.280
either space in RAM, the code would freeze, the entire cabinet would reset, and the game would

06:01.280 --> 06:08.720
restart, that there was a means of easing the operations, but it makes coding on the machine a bit

06:08.800 --> 06:20.080
more complex, but anyway, your code runs inside the cartridge, it doesn't run, it's not stored

06:20.080 --> 06:28.800
into the mainboard, obviously, if you want to access the music chip, the audio chip, this is a

06:28.800 --> 06:36.000
classic Yamaha for the time, that's basically the same thing as what's the mega drive,

06:36.000 --> 06:45.360
Genesis console does, this has to go via another processor, the classic Z-log, Z-80, so you have an

06:45.360 --> 06:54.640
entire processor dedicated to accessing your chip, which sounds a bit too much, but that's how it works

06:54.640 --> 07:00.640
on the Neo Geo, the main processor, the 6-year-old kick, cannot access directly the audio chip,

07:00.640 --> 07:06.160
it has to go through the Z-80, and again, the Z-80 is a 8-bit processor, it doesn't have much

07:06.160 --> 07:15.680
advanced space, so you can only have a 62K of ROM, it can be extended a bit, but anyway,

07:15.680 --> 07:19.520
only has two kilobytes of RAM, it doesn't need merge to drive the audio chip anyway,

07:19.760 --> 07:31.040
the code that's driving the way in 2016, again, is stored on the cartridge ROM,

07:32.320 --> 07:38.640
and all the audio samples, because at the time, again, you could run wave files and code it into a

07:38.640 --> 07:44.640
specific format called the LEPCM, those are stored in a dedicated ROM in your cartridge,

07:45.040 --> 07:52.160
and the big piece that I'm not going to talk about in this talk is the video processor, right?

07:52.160 --> 07:58.880
So, unlike the big computers at the time, this is not a pixel-based video processor,

07:59.600 --> 08:05.440
it's a type-based renderer, that means that you have the ability to run on screen small

08:05.440 --> 08:10.880
ties of 8-bit 8 pixels, which are fixed text on screen, this is usually used for

08:10.880 --> 08:16.720
head-up display showing the bars, your energy, your health, the credits, whatever, and you're

08:16.720 --> 08:23.200
also have the ability to render a sprite-son screen, which are basically vertical stripes of ties

08:23.200 --> 08:30.880
of 16x16 pixels, the data information itself is not stored into a dedicated video ROM,

08:31.280 --> 08:37.040
what's stored in the video ROM is just the tile that you need to access to be rendered on screen,

08:37.120 --> 08:42.320
and the time themselves are stored into dedicated ROM into the cartridge, and this ROM can be

08:42.320 --> 08:49.360
super big because Neo Geo, super expensive, very nice graphics, so up to 64 megabytes of from,

08:49.360 --> 08:57.920
which at the time was a lot, and really that, come back to the question, why do I need another

08:57.920 --> 09:04.240
dev kit, and the basic premise, like remember, I wanted to program on the Neo Geo, and back then

09:04.320 --> 09:09.920
there was some cross compilers, but that was really it, like there was not many tools available,

09:09.920 --> 09:15.200
some of the tools like the cross compilers were there, but that was basically it,

09:15.760 --> 09:22.480
some functionalities like driving the audio was not available, or very weak, and most of the

09:22.480 --> 09:29.200
tools available were only available in Windows, so close source, no ability to change them,

09:29.200 --> 09:35.760
if you found a bug, whatever, mostly GUI, so that was super annoying, and clearly there was a

09:35.760 --> 09:44.080
room for improvement there, and yeah, basically what I wanted to do with a new dev kit was to give

09:44.080 --> 09:53.200
the ability to have very simple introduction to this hardware, very easy programming in CNC

09:53.280 --> 10:00.640
++, with a complete toolkit, which means not only the cross compiler, but also regular debugger,

10:00.640 --> 10:06.000
if you want to do source level debugging, shipping with an emulator for easy access, couple of tools

10:06.000 --> 10:13.440
to manage the graphical assets, the sound assets, I wanted this dev kit to be able to expose

10:13.440 --> 10:21.360
all the hardware capabilities of the platform, so yeah, most of all I wanted it to be usable on all

10:21.440 --> 10:26.080
the platforms that I could put my hands on at the time, so Linux of course, because I'm Linux

10:26.080 --> 10:32.640
user, macOS, and Windows, because at the time, a lot of people were using Windows, and I wanted it

10:32.640 --> 10:38.000
to be fully open source, clearly there was the possibilities to be that, the only restriction

10:38.000 --> 10:43.280
with that is the BIOS, because this console requires a BIOS for bootie, but whatever, it's code,

10:43.280 --> 10:47.360
so I'm just re-implementing the BIOS, it's small enough, that's an old console,

10:47.360 --> 10:54.320
the effort was not the end of the world, and to ease the access to that I wanted to provide

10:54.320 --> 11:00.000
pre-built binary speakers, anybody that has already pre-compiled an entire tool chain,

11:00.560 --> 11:06.080
that's a bay, nowadays it's fairly quick, but at the time when I started this effort to just

11:06.080 --> 11:11.840
was really a bay, and provided a couple of example room to get you started, and here that was

11:12.800 --> 11:20.480
basically, so in order to do that, the plan was just to reuse all the open source products

11:20.480 --> 11:26.160
that were available at the time, so I already had the cross-compiler, I already had small

11:26.160 --> 11:34.720
lip-c, I have a C-compiler and an Assembler Compiler for the ZAT, and emulators available,

11:34.720 --> 11:41.760
so that means that for this project I could concentrate on providing all the Neo Geo bits

11:42.320 --> 11:48.640
that was well-required to come up with complete depth kit basically, so dedicated links,

11:48.640 --> 11:56.400
scripts, the BIOS, a sound driver, all the missing bits from the existing tools basically.

11:58.080 --> 12:06.960
All right, so that was another talking to show you, if you were to do a simple

12:06.960 --> 12:12.480
Hello World on the Neo Geo, that would really look like a classic Hello World on PC, right?

12:13.600 --> 12:22.320
You would first include a standard header that would give you access to a couple of BIOS functions,

12:22.320 --> 12:27.760
just for instance, this one to initialize the screen, clear up all the text on the screen,

12:28.320 --> 12:34.320
it defines a couple of memory address, specifically this one is a memory address that allows you

12:34.320 --> 12:40.240
to set the palette, the color palettes that you want before calling your function.

12:40.240 --> 12:47.840
You can see that it's using standard integer, you have shortcuts if you want to specifically

12:49.280 --> 12:59.920
show you the integer size, yeah you have access to other helping functions,

13:00.000 --> 13:04.880
and then once you print the thing on the screen, you just wait idle in the loop,

13:04.880 --> 13:11.840
and you see here that you don't need to re-underwatch the depth kit does that for you,

13:11.840 --> 13:18.480
which is quite handy. Again, you compile your program like a regular C program with PKG config,

13:18.480 --> 13:24.720
you build it, link it with a basic copy, you need to convert it into a row file that it's suitable

13:24.720 --> 13:31.200
for being stored in a ROM, then you pack all that into a zip file that is suitable for

13:31.200 --> 13:38.800
your enulator and you run it and off you go. Now what's going on under the hood in order to do that?

13:38.800 --> 13:45.200
So on the right you have all the address space of the CCHK, and you can see that different parts

13:45.200 --> 13:51.440
of the system are available in different address space. For instance, all the BIOS code is available

13:51.440 --> 13:56.720
at the bottom of the address space of the CCHK, when the CCHK starts, the first thing that it's

13:56.720 --> 14:03.600
going to do is try to look at the very first bits of the address space to check which part of the

14:03.600 --> 14:08.880
program it has to execute first, so here it reads the scripto and jump directly into the

14:08.880 --> 14:17.520
address space where the BIOS relied, the BIOS code then sets up the stack, initialize a couple of

14:17.520 --> 14:25.680
things, it configures the hardware to move the address space to the game culture each address space,

14:26.880 --> 14:32.240
test a bunch of things, initialize the BIOS, the credits, the joystick states, whatever,

14:33.680 --> 14:41.920
restores data if your game used back and from, it configures the ZAT driver to initialize itself

14:42.000 --> 14:49.520
and wait for a sound command, and then it jumps to your game code which really is the CRT0

14:49.520 --> 14:55.920
like standard program, the CRT0 initialize global variables in your program if you run C++,

14:55.920 --> 15:00.880
it runs global constructors and then it jumps into your main program and there you have it.

15:03.120 --> 15:11.120
The dev kit has additional facilities, it comes with a custom link scripts which maps

15:11.200 --> 15:19.840
the various memory area of the system so that it is able to expose all the capabilities of the

15:19.840 --> 15:26.960
hardware for instance, all the BIOS functions that you saw earlier is automatically linked into a

15:26.960 --> 15:34.560
special address, if you want to use a backup RAM you can just use an additional design here that

15:34.640 --> 15:41.200
configures your variable to land into dedicated segments so that at linked time the variable

15:41.200 --> 15:47.440
results might be stored into the proper segments so it's really transparent from a C perspective,

15:47.440 --> 15:53.600
it has also sort of a fancy thing for instance, I'm using the latest version of

15:53.600 --> 15:59.840
being utility to allow linking non-contiguous memory address space because it turns out that the

15:59.840 --> 16:09.200
Neo Geo runs the first megabytes of code at a specific address space and then to megabytes further

16:09.200 --> 16:18.960
down the address space you can use another one megabyte of memory space which is a bit weird but

16:18.960 --> 16:24.160
thanks to being utility you have that for free you can do banking as well if you have if you use a

16:24.160 --> 16:30.800
special naming convention so yeah I don't want to spend too much detail too much time in the

16:30.800 --> 16:39.040
sound driver because I need to speed run it by the way but basically in order to talk to the

16:39.040 --> 16:46.640
audio chip the only option is to do so via the ZAT and you don't want to do that the dev kit itself

16:46.640 --> 16:51.920
is providing you with a sound driver and the way you communicate with the ZAT is sending

16:52.000 --> 16:59.200
one byte at a time there's the only way to do that in the Neo Geo hardware so basically when the

16:59.200 --> 17:05.840
68K wants to run a command it triggers a specific non-maskable interrupt on the ZAT the ZAT

17:05.840 --> 17:11.200
wakes up sees the bytes and depending on what you want to do in your code you can assign

17:12.080 --> 17:17.840
each byte to a specific command for instance reset the driver play this music play this sample

17:18.240 --> 17:26.400
you get the gist of it and yeah the the audio driver is basically there for you

17:26.400 --> 17:33.040
it supports all the audio capabilities of the YM26 10 chips which is a bit better than the

17:33.040 --> 17:39.680
original games that were launched on the Neo Geo platform specifically I can use the

17:39.680 --> 17:44.960
GSSG part of the chip which most of the official games can't which is pretty nice

17:45.600 --> 17:52.720
and the way it works is basically any open source tool you use for instance if you want to do

17:52.720 --> 17:58.720
your music you're using a tracker which is called furnace which is an open source music driver

17:58.720 --> 18:05.120
if you want to edit your sample you have yeah audacity I think in this case and then you just need

18:05.120 --> 18:12.560
to list all your audio assets into a fairly simple YMO file and then you give that to a tool

18:12.640 --> 18:19.760
from NGFK and it's going to take care of generating all the data for you so for instance for

18:19.760 --> 18:28.800
your music it's compiling that into a specific optimized byte code optimized for space storage

18:30.080 --> 18:39.920
those byte codes then land into your ROM into your game cartridge along with the audio driver

18:39.920 --> 18:51.040
part of the other code and the tools give you some see headers automatically so that you can

18:51.040 --> 18:57.920
call all your functions by name rather than by offset so it does all the ordering of those audio

18:57.920 --> 19:05.200
samples for you automatically which is quite handy last point that I want to discuss is the packaging

19:05.200 --> 19:13.040
so anytime you want to use a cross compiler it's fairly complicated here the goal is to be as

19:13.040 --> 19:19.520
easier to consume as possible so anytime I push a revision upstream in the GitHub repo

19:19.520 --> 19:25.040
there are CI actions to rebuild 90 packages so you have packages available for fedora

19:25.040 --> 19:32.240
for Ubuntu I'm using all the standard paying for fedora I'm using copper Ubuntu the packages are hosted

19:32.240 --> 19:38.880
on loan spot if you want microS you have brew packages and for Windows you even have a native

19:38.880 --> 19:45.200
MCs to package everything is fairly simple to consume and the packages themselves are split into

19:45.200 --> 19:50.480
different parts so let's say if you want to use the tool chain because I'm packaging a fairly

19:50.480 --> 19:57.920
up-to-date version of the GCC toolkit you can just install and if you want to use the full

19:58.880 --> 20:05.520
dev kit you can use and she dev kit itself but some users upstream just use the tool chain part

20:05.520 --> 20:14.080
and provide their own thing looks that means that I'm not certain and yeah right on time summary

20:14.080 --> 20:20.160
I'm super proud of it believe it or not there are already four new game official games

20:21.120 --> 20:27.120
that are using the project

20:30.000 --> 20:36.480
those old consoles they never die they never want to die and yeah next step I like to support the

20:36.480 --> 20:44.080
new GOCD because it's a bit simpler to use and it's the same architecture more dogs more tooling

20:44.240 --> 20:51.600
you know you always have big plans and then the real life comes back at you but yeah that's it

20:59.600 --> 21:04.320
we have time for two short question or one long question is that one question over there now we'd run

21:04.560 --> 21:17.360
hi thank you for your talk so I'm also doing M68k stuff a lot dev games M68k maintainer

21:18.240 --> 21:26.960
and I was wondering have you considered trying out the M68k backend and LLVM and the M68k backend

21:26.960 --> 21:32.720
and rust I mean it's not complete it's not fully working but the more people are using it we can

21:32.800 --> 21:40.000
maybe you know get out iron out the last box that's a good question I didn't know it exists

21:40.000 --> 21:47.200
it's also it's not but it's yeah that would be a good thing

21:49.040 --> 21:55.280
over there the question wait wait wait wait wait wait wait wait wait wait wait wait wait wait no

21:55.280 --> 21:57.880
because otherwise it's not on the recall.

21:57.880 --> 22:03.880
I saw that you managed LSP support, you managed,

22:03.880 --> 22:06.920
but I was thinking, wouldn't that just work with Clangdy

22:06.920 --> 22:09.880
and Compalkmans?

22:09.880 --> 22:11.680
I don't get it.

22:11.680 --> 22:16.280
Yeah, you mentioned LSP support in your last slide.

22:16.280 --> 22:20.280
But wouldn't get that just worked with Clangdy and Compalkmans?

22:20.280 --> 22:20.880
It would.

22:20.880 --> 22:21.680
Yeah, yeah, it would.

22:21.680 --> 22:27.800
But the idea is that I'd like to give enough examples

22:27.800 --> 22:31.920
with the deaf kids to allow you to set it up fairly easily.

22:31.920 --> 22:33.680
Because that's the cross compiler.

22:33.680 --> 22:36.880
So if you're familiar with Clangdy, that's fine.

22:36.880 --> 22:39.480
But if you're not, and again, this whole project

22:39.480 --> 22:44.280
is to lower the bar to try and work with those consoles.

22:44.280 --> 22:48.280
So if you give Clangdy support directly into the project,

22:48.280 --> 22:51.280
that's for the better.

22:51.280 --> 22:52.280
Time's up.

22:52.280 --> 22:53.280
Many thanks, Emya.

22:53.280 --> 22:54.280
Thank you.

