Reviving the Neo Geo: My Custom ASM Dev Setup
Le but étant de pouvoir me servir de la PROM pour injecter mon code et recompiler tout l'aof.zip.
Mais très vite, si je voulais récupérer des infos graphiques déjà présentes dans le jeu, je devais pouvoir aller regarder du côté des sprites et du fix layer.
Il existe des outils basiques en ligne, et je voulais vérifier si une police de caractères était présente dans la cartouche.
J'avais trouvé ma police de caractères : elle commençait à la tile 30303, et dans le désordre, s'il vous plaît !
----------------------------------------------------
The goal being to use the PROM to inject my own code and recompile the entire aof.zip.
But very quickly, I realized that if I wanted to pull graphical assets already present in the game, I needed to dig through the sprites and the fix layer.
There are some basic tools available online, and I wanted to check whether a font was hiding somewhere on the cartridge.
I found my font: it started at tile 30303 — and scattered completely out of order, if you please!
C'était la découverte parfaite pour s'essayer à un petit sine scroll avec ce texte, avec une palette définie à la main.
--------------------------------------
It was the perfect find to try my hand at a small sine scroll effect using that text, with a hand-defined palette.
Uhhh, ça marche ! Ça scroll sur une table sinus à 256 entrées.
Prochain entraînement : l'affichage d'un sprite de personnage complet. Mais comment chercher dans les CROMs ? Tant qu'on y est, autant essayer de faire, en Python, mon propre éditeur de sprites, relié à ce setup de dev.
Python, ce n'est pas du bas niveau, mais pour faire de petits projets, c'est largement suffisant.
-----------------------------------------------
Uhhh, it works! It scrolls along a 256-entry sine table.
Next training exercise: displaying a full character sprite. But how do you even search through the CROMs? While I'm at it, I might as well build my own sprite editor in Python, hooked up to this dev setup.
Python isn't exactly low-level, but for small projects, it's more than enough.
Mais c'est toujours pareil : et si on faisait ci, et si on faisait ça...
Du coup, l'idée me vient de pouvoir travailler sur un savestate de MAME, et d'essayer de reconstruire l'image sauvegardée dans le savestate à partir des informations qu'il contient (sprites, fix layer et palettes).
Du coup, j'ajoute une fonction qui ouvre une nouvelle fenêtre pour reconstruire l'affichage à partir d'un savestate pris en cours de jeu.
-------------------------------------------
But it's always the same thing: what if I did this, what if I did that...
So the idea comes to me: what if I could work on a MAME savestate and try to reconstruct the saved image from the information it contains (sprites, fix layer, and palettes)?
So I add a feature that opens a new window to rebuild the display from a savestate taken mid-game.
Mouais, on peut mieux faire : le fix layer est absent, les sprites des persos aussi.
Du coup, grâce au Neo Wiki et à ses fondateurs, on récupère beaucoup d'infos sur les palettes, les registres vidéo, la structure des sprites, et plein d'autres renseignements obscurs.
Les persos, c'était n'importe quoi : j'ai repéré un problème de byteswap qui me faisait chercher les sprites des persos à deux fois l'emplacement mémoire où ils se trouvaient réellement.
Après corrections, les persos sont là, et le fix, entre-temps, a été « fixé ».
Mais pas de décor quand l'image est en taille normale (j'entends : sans dézoomer).
-----------------------------------------------------
Meh, could do better: the fix layer is missing, and so are the character sprites.
So, thanks to the Neo Wiki and its founders, I picked up a ton of info on palettes, video registers, sprite structure, and plenty of other obscure details.
The characters were a total mess: I spotted a byteswap issue that was sending me to look for the character sprites at exactly twice the memory address where they actually lived.
After fixing that, the characters showed up — and in the meantime, the fix layer got "fixed" too.
But still no background when the image is at normal size (meaning: without zooming out).
Problème du bit de shrink, qui permet de gérer les « zooms » sur la machine : il manque toujours un morceau.
Ce petit logiciel est pratique, car il permet de récupérer les 256 palettes du jeu. Mais comment savoir quelle palette correspond à quelle image, et surtout à quel sprite ?
---------------------------------------------
There's an issue with the shrink bit, which handles "zoom" effects on the machine — there's still a piece missing.
This little tool is handy since it lets me pull out the game's 256 palettes. But how do you figure out which palette matches which image, and especially which sprite?
Les jambes sont manquantes.
Une erreur de paramétrage sur les sticky bits, qui permettent de coller les sprites ensemble, et les jambes reviennent.
J'ai aussi fixé la bande du haut sur le décor dézoomé, en allant chercher, dans l'éditeur de CROM, où commençaient les décors de cette bande.
Mais j'ai aussi changé de stratégie pour la récupération des données. Le savestate me posant trop de soucis, et grâce aux conseils du talentueux Aurélien, je me suis fait un script qui va directement sauvegarder le contenu de la VRAM quand je fais une pause dans MAME, et ça vient écrire le dump directement dans le dossier de mon setup de programmation.
-----------------------------------------------
The legs are missing.
A parameter error on the sticky bits — which glue sprites together — and the legs are back.
I also fixed the top strip on the zoomed-out background by digging through the CROM editor to find where the backgrounds for that strip started.
But I also changed my strategy for grabbing the data. The savestate was causing me too much trouble, so — thanks to the talented Aurélien's advice — I built myself a script that saves the VRAM content directly whenever I pause MAME, writing the dump straight into my dev setup's folder.
Petite précision : j'ai lu « des vrai » comme "la VRAM" (mémoire vidéo), vu le contexte technique — dis-moi si tu voulais dire autre chose.
J'essaye sur d'autres, dans différents stages, pour voir si la structure est bien recomposée. Et la réponse est : vvvooouuiiiii !
----------------------------------------
I try it on others, across different stages, to see if the structure gets rebuilt correctly. And the answer is: yyyeeeaahhh!
Alors, je me dis : est-ce que l'on pourrait ajouter des fonctions supplémentaires qui quadrilleraient la reconstruction, et qu'avec notre souris, en survolant une zone, nous aurions les infos sur l'adresse du sprite ou de l'élément du fix layer, ainsi que sa palette, avec la palette de 16 couleurs qui s'affiche à côté pour en avoir un aperçu ?
Fonction supplémentaire : en balayant avec deux doigts (Mac oblige), on déclenche un zoom/dézoom sur la zone qui nous intéresse, pour être sûr de bien sélectionner le bon sprite.
Bien sûr, on peut aussi extraire les palettes dans un fichier.
English version
So I start wondering: could I add some extra functions that would grid out the reconstruction, so that hovering the mouse over an area would show info on the sprite's address, or the fix layer element, along with its palette — with the 16-color palette displayed alongside for a quick preview?
Extra feature: swiping with two fingers (Mac life) triggers a zoom/unzoom on the area of interest, to make sure I'm selecting the right sprite.
And of course, you can also export the palettes to a file.
Il est 23h50... du matin. Ça fait une journée que je bosse dessus, ma femme ne me parle plus, mes enfants m'appellent tonton !!!!
Et une idée satanique d'Aurélien : griser les zones et ne laisser en couleur que la zone survolée.
Ça marche un peu, mais pas tout le temps.
Bref, à peaufiner, mais l'idée est très bonne (de toute façon, quand t'es proche du soleil, t'as que des bonnes idées).
--------------------------------
It's 11:50pm... in the morning. I've been at this for a full day straight — my wife isn't talking to me anymore, and my kids are calling me "uncle" !!!!
And then a diabolical idea from Aurélien: grey out all the zones and only leave the hovered-over zone in color.
It kind of works, but not all the time.
Anyway, needs polishing, but it's a really good idea (then again, when you're that close to the sun, all your ideas are good ones).
Et au final, l'identification m'a permis de faire mon sine scroll text depuis mon setup de dev, avec MAME, VS Code et VASM pour la compilation.
Je bosse sur des raster bars (vive les interruptions), des starfields avec des sprites d'AOF, l'affichage de personnages, et plein d'autres trucs.
Le but est de sortir une demo à l'ancienne l'année prochaine, et peut-être, pourquoi pas, un jeu... On m'a déjà proposé, mais je n'étais pas prêt.
Pourquoi faire ça en 2026, alors que la console a plus de 30 ans ??? Et pourquoi pas ? Il y en a bien qui font une réédition de la console avec un nouveau hardware, 30 ans après, et apparemment les gens sont super hypés.
--------------------------------------------------
And in the end, that identification work let me build my sine scroll text right from my dev setup, with MAME, VS Code, and VASM for compiling.
I'm working on raster bars (long live interrupts), starfields with AOF sprites, character display, and plenty of other stuff.
The goal is to release an old-school demo next year, and maybe — why not — a game one day... I've already had an offer, but I wasn't ready.
Why do this in 2026, when the console is over 30 years old??? Well, why not? Plenty of people are releasing reissues of the console with new hardware, 30 years later, and apparently people are super hyped about it.
/image%2F0533879%2F20260725%2Fob_494c5f_capture-d-ecran-2026-07-23-a-19-25.png)
/image%2F0533879%2F20260725%2Fob_719629_capture-d-ecran-2026-07-23-a-04-55.jpeg)
/image%2F0533879%2F20260725%2Fob_1dc6d6_capture-d-ecran-2026-07-25-a-11-12.jpeg)
/image%2F0533879%2F20260725%2Fob_c2679f_capture-d-ecran-2026-07-23-a-12-12.png)
/image%2F0533879%2F20260725%2Fob_867186_capture-d-ecran-2026-07-24-a-08-35.png)
/image%2F0533879%2F20260725%2Fob_fde58b_scene1.png)
/image%2F0533879%2F20260725%2Fob_498232_scene3.png)
/image%2F0533879%2F20260725%2Fob_ca8bd7_scene4.png)
/image%2F0533879%2F20260725%2Fob_6b9f93_scene6.png)
/image%2F0533879%2F20260725%2Fob_985ec5_scene10.png)
/image%2F0533879%2F20260725%2Fob_0c1032_capture-d-ecran-2026-07-25-a-06-35.png)
/image%2F0533879%2F20260725%2Fob_a86880_capture-d-ecran-2026-07-24-a-23-58.png)
/image%2F0533879%2F20260725%2Fob_53ef30_capture-d-ecran-2026-07-24-a-23-55.png)
/image%2F0533879%2F20260725%2Fob_45aa2e_capture-d-ecran-2026-07-25-a-06-35.png)
/image%2F0533879%2F20260725%2Fob_0e9636_capture-d-ecran-2026-07-25-a-06-35.png)
/image%2F0533879%2F20260725%2Fob_6bc4d3_capture-d-ecran-2026-07-25-a-06-35.png)
/image%2F0533879%2F20260725%2Fob_5e12e0_capture-d-ecran-2026-07-25-a-11-11.png)
/image%2F0533879%2F20260725%2Fob_a0fdbe_capture-d-ecran-2026-07-25-a-11-12.jpeg)