💦 CREATE AND FUCK YOUR OWN AI CUMSLUT 🔥 TRY NOW ♥
Create AI Cumsluts 💦
August 15, 2026

Coin-Op Collection Updates: G.I. Joe - A Real American Hero (Konami GX069)

Today's update marks the public beta of G.I. Joe on MiSTerFPGA. The core released for the Analogue Pocket on July 4th as a public beta, and the post that went with it laid out what was left to do, the MiSTer version needed a memory architecture of its own, the sprite pipeline was struggling, and the K054539 had not been settled by hardware validation.

Those shortcomings and others are covered in this post. Everything below is work done on the core since that release, most of it in the video and memory path, and it is why the MiSTer core is coming out public rather than as a licensed beta.

The initial release covering the hardware in detail is here:

https://www.patreon.com/posts/162913259


Development Challenges:

DE10-Nano Memory Architecture:

Memory is where the MiSTer version of this core had to be rethought. G.I. Joe reads its program, sound program, samples, tiles and sprites all at the same time, and the two platforms do not offer the same memory architecture to place them in.

What is common to both is the tile fetch. Four independent ports, one per tile layer, each returning a single 32-bit word per fetch, which is exactly one 8-pixel row of one tile. That is the granularity the tilemap consumes, so nothing is fetched that gets thrown away, and every port has a cache of its own in front of the consumer.

What differs is which memory those ports read from. One consumer cannot carry tiles and sprites together while the line is being drawn, because there is not enough bandwidth for both on a dense line, so sprites need a consumer of their own.

The Pocket has two separately addressable PSRAM chips, so tiles read from one and sprites from the other at the same time, with short, predictable round trips due to the GFX layers being 8x8, and its SDRAM is left holding the program and sample ROMs. MiSTer has a share of the DE-10 Nano's DDR3, which carries far more bandwidth but answers slowly, because the FPGA and the HPS both share it. I chose DDR as the second consumer over an additional SDRAM slot.

For MiSTer I put the program, sound program, sample, and sprite ROMs in DDR, leaving SDRAM to the tiles. Each of the four reads through a read ahead line cache I wrote for this core specifically. A line is 512 bits, so one DDR read brings back 32 program words, or 64 bytes of samples or sprite graphics, and a loop that fits inside the cache never goes back to DDR at all.

Arbitration on the DDR bus matters as much as the cache. The program fetch goes first, then sprites, the Z80, and the samples, so the 68000 always finishes its sprite list inside the frame. The caches also have to fit the device, so a cache line no longer carries its own valid flip-flop; a 4-bit stamp stored beside each tag does the same job, and invalidating a cache is a single increment rather than thousands of clears.


K056832 - Tile Generator:

The tile memory was designed as a single shared pool like the PCB functions in the initial release. How it works is the 68000 wrote into the shared VRAM pool while the display read out of it, and the two waited on each other.

Doing research, I was able to determine each of the four tile layers stays inside its own fixed area of the shared VRAM pool and never moves outside it, so I gave each one its own independent VRAM to save resources.

This cut wait times and resource allocations as nothing waits now, and the tilemaps use about a third of the block RAM they did before, which is what freed the space the rest of this release needed to push the GFX pipeline over the line.

I resolved the remaining line map effects for tiles by implementing per-line scroll. This corrects the tile flicker when linemap effects are drawn. A few examples are the COBRA platform when fighting Baroness and the water when fighting Destro. The lower left hand side showed tile flicker prior to this adjustment.

Another example is in the video below; one of the line map effects that was not functioning properly for the initial release, the laser didn't track the player sprite during the fight with Major Bludd.


K053246 and K053247A - Sprite DMA/Sprite Generator:

The K053246 copies the sprite list (DMA) out of work RAM into its own buffer once a frame during vertical blank, and the K053247 draws from that copy. In the initial release the DMA was also being started by the sprite ROM read-back register, which the 68000 writes during play, so a full re-copy of the list fired in the middle of a frame that was already being drawn.

The list is ordered by priority, so re-copying it mid-frame moves sprites into different slots. A sprite drawn at the top of the screen could shift or disappear further down, and which ones did it changed frame to frame with the CPU's timing. I've adjusted the design Pramod made to copy the DMA only in vertical blanking.

The interrupt was adjusted to match. The 68000 rebuilds the sprite list in its level 6 handler, and the board raises that interrupt once the DMA finishes, which is what keeps the CPU from writing the list while the chip is still reading it. I moved it to fire on the DMA completing rather than on vertical blank alone. Attract screens run with the DMA switched off and still need that interrupt to advance the game's frame counter, so on those frames it falls back to a deadline in vertical blanking.

The remaining issues were due to the renderer running out of time. Each scanline gives the sprite hardware 6144 clocks. Run past that and it misses the horizontal sync, the previous line is shown a second time, and the finished line arrives one line late, which is the blur seen on the initial pocket release.

Once I resolved the blur, I had to keep the sprite pixel count under or else horizontal sprite line drops would occur. On the worst frame measured, the pixel loop alone was using 6089 of the 6144 clocks before doing anything else, so trimming anything else would not have fixed it.

What I did was widen the draw itself. The line buffer is split into even and odd halves and two pixels are written per clock, the next tile column is set up and fetched while the current one is still drawing, and sprite graphics are read 64 bits at a time so one fetch returns a full 16 pixel row instead of one single 8 pixel row.

Clearing the line buffer initially cost 512 clocks on every line and now costs a single clock cycle. Sprites that do not touch the line are dropped before their attributes are read, and columns that fall entirely off screen are never fetched at all. Finished lines go into a ring buffer of 14 lines so the renderer can work ahead when a line runs long instead of losing the one behind it. This structure allowed for me to fix the most dense sprite scenes.

Everything here is drawn live into line buffers (RAM), the same as the board does it. There is no frame buffer between the renderer and the screen. There is no sub-pixel buffering, adding additional frames. This is how Konami games from other developers have been handled recently. The clock budget matters, the line either fits in the time the hardware gives it, or the drop shows up on screen. This is due to Konami's design choice of rendering 8x8 for tiles and sprites.

The video below demonstrates both tile (top left corner) and sprite overrun (blur only):

The video below demonstrates the final GFX pipeline with no overrun on tiles or sprites:


K053251 - Compositor:

The K053251 resolves layer priority and decides where a sprite's shadow is allowed to darken what sits behind it. The chip holds three shadow priority registers. G.I. Joe writes register 6, with 0x10 during boot from program address 0x000356, and leaves registers 7 and 8 at zero.

Going back through Pramod's implementation I found the core was handing the mixer a plain on or off shadow bit rather than that register number. Read that way it selected register 7, which the game never writes, so every shadow was compared against zero even though it appeared to be correct.

The schematics Pramod provided me with along with his PCB settled the rest of it. The chip's two shadow outputs, SDO1 on pin 86 and SDO0 on pin 87, are ORed at U107, inverted at U102, and land on a single 470R tap into pin 7 of all three 052535 video DACs, so any non-zero shadow code darkens and the board has exactly one shadow intensity.

The core now passes the register number through the way the chip expects and reads both shadow outputs instead of the low bit alone.


K054539 - PCM Audio:

The K054539 is the entire sound section on this board, eight channels of samples with its own panning and reverb. I ripped every sample out of the sound ROM and built a testbench for our K054539, so each one can be rendered and put directly next to a recording of the same sound sample taken off the PCB.

During analysis of the samples it showed registers no emulator touches. Every sound effect the driver plays writes the block from 0x21D to 0x223, seven registers, each sourced from that effect's own entry in the sound table. MAME and FBNeo ignore all seven. There is also a per-voice control bit that decides where that voice sits in the stereo field, set on every SFX sample and clear on every BGM sample, and neither of them reads it.

Two more blocks carry a question mark in MAME's own source. 0x228 through 0x22B are written as a group of four and only ever during music. 0x224 and 0x225 are written as a pair, with 0x225 also given a value during boot. I traced where the sound program writes each of them and what it builds them from, and they are wired into the core.

With those in place the stereo difference between the core and the PCB recordings dropped from 0.0410 to 0.0144. The samples included with this post are the comparison: the same command rendered from the core and captured from the board and a comparison from MAME.

The rest is what the chip sounds like. The output level was high enough that loud scenes hit the top of the mixer and flattened out, so it sits lower now with headroom to two thirds of full scale, which also makes the four volume steps in the menu exact rather than rounded.

A voice that is keyed off ramps down instead of being cut straight out of the mix, which is what the clicking was. The driver also rewrites a playing voice's position registers in the middle of a note, and those are now held and applied at the next key on rather than jumping the sample pointer, which is what the static was. Below is an example of stereo SFX audio playback from the PCB, core, and MAME:

I am still working on missing register functions, reverb decay, key-on flags, and internal mixing of the K054539, but have fixed the panning and reverb for SFX in G.I. Joe. I'm currently waiting on a Rigol DSA815-TG spectrum analyzer and some other audio equipment to arrive so I can continue work on K054539 PCM audio playback.


Video Timings, ER5911 EEPROM, VRAM Tests, & Service Menu Functions:

With the initial release I had stated the PCB ran at 59.185 Hz and was incorrect. MAME's refresh rate isn't wrong, it's right. I remeasured the PCB off the CSYNC line and it matches the timings provided by MAME. The line rate is 15.625 kHz on a 64.00 µs line, with a 2.48 µs horizontal sync pulse and a vertical sync that holds low for roughly 509 µs, near enough to eight lines. That is 262 lines to a frame and a 16.768 ms frame period, which puts the refresh at 59.64 Hz, and that is what MAME's raster produces. The core was running 264 lines and is at 262 now, so the two agree.

The ER5911 was not implemented in the initial release, I've modeled it and it's now functional in the core. The ER5911 is a serial EEPROM, 128 bytes, wired to the 68000 across three lines, a chip select, a clock, and a data line the CPU shifts commands and data through one bit at a time. G.I. Joe keeps everything the operator sets in the service menu there, coinage, difficulty, cabinet type, along with the high score table. The game reads it during boot and writes back the bytes that changed when the menu is closed or a score is set. Once you've selected the settings in the Service Menu or obtained a high score, remember to use Save Settings in the MiSTer OSD to write them to the device.

The VRAM test is one of the eight tests performed at boot. The patterns run through tile memory while the display is still scanning that same memory out, so what the test writes lands on screen as it is written and the check screen disappears behind it.

The core reads VRAM live, the same as the board does, but I am still working on when VRAM is fetched and in what order so it aligns with the PCB. So far, I've got the blue/tan palette check functional. I have yet to determine how it draws the CRAM dots. The character alignment is based on when VRAM is read, that will require a measurement from the PCB.

MAME redraws its tilemaps once per frame from whatever is in memory when the frame ends, so it never shows what the board shows.

In the service menu, running the MASK ROM CHECK corrupts the display while it runs, the same as it does on the board. The game sets a bit in the tilemap chip at the start of the test and clears it at the end, and while it is held all four layers are redirected to a sweep of the ROM bank being checked, each painting raw ROM data in its own colors. The checksum read goes through a path of its own, so the numbers the test reports are the real ones. I need to measure the tile VRAM on the PCB when running the MRC to find the correct fetch order so everything lines up. These fixes will come in a future update.

Another feature missing from the service menu in emulation is volume control, I've not started looking at it yet but will in the next release. On the PCB, when you adjust the slider the volume lowers and raises.


Core Options:

The MiSTer core includes video settings for aspect ratio, vertical scaling and cropping, scandoubler effects, refresh rate, and H/V positioning and sync adjustments. Audio settings cover the mix, mono or stereo, an enable for the K054539's PCM output, and a volume control with four steps from 100% to 175%. Arcade dip switches are directly accessible from the OSD, and the service menu has an entry of its own beside them. Stereo is enabled by default in the dip switch settings, to enable the stereo mix, toggle it in audio settings. I recommend increasing the PCM volume to 150%-175% as mixed stereo will always drop gain levels.

Game settings carry mapping for all four players, a synced mapping mode that mirrors Player 1's layout across two, three, or four players, and per-player auto-fire covering either button or both, each with its own rate.

Cheats are accessible from the OSD and include infinite credits, invincibility, a stage select covering the game's three missions, and per-player infinite lives, energy, and rockets for all four players. The stage select is a custom addition, derived from the program code as this cheat did not exist previously. The invincibility addresses were also wrong for two of the sets in the existing cheat files and are corrected here.

The core supports six sets, two World releases including the EB8 prototype, two US releases, an Asia release, and the Japanese release.


Updates:

A good bit of the work done for the MiSTer version of G.I. Joe is already live on the Pocket. The timings are fixed, the tile VRAM is split per layer, and each PSRAM is addressable on its own now, so tiles and sprites aren't fighting over the same bus. What's left on the Pocket side is device utilization and bus arbitration, and that means reworking parts of the design. I'm in the middle of planning it and there'll be a Pocket update once the work is completed.

Based on the amount of time and effort put into G.I. Joe, requests and support from patrons, I've decided to continue on with additional Konami titles. I recently ordered more equipment to help with the development and acquired Mystic Warriors and Metamorphic Force PCBs. This is possible because of supporters like you! We'll see a beta for Mystic Warriors in the next few days and Metamorphic Force will follow after. By then, I should have proper structure for the Pocket versions.

I've pushed the files to GitHub and update_all, or you can grab them from the attachments below. Give the updater time to sync. There are other released planned for the weekend / week from my backlog too. Hope everyone has a good weekend!

Disclaimer: All product names, trademarks, and registered trademarks mentioned are the property of their respective owners. "Analogue", "Analogue Pocket", "OpenFPGA", "MiSTer", "MiSTerFPGA", "MAME", "FBNeo", "Konami", "Hasbro", "G.I. Joe", "Terasic", "DE10-Nano", "Motorola", "Zilog", "Rigol", and all derivative works are trademarks, registered trademarks, or copyrighted materials of their respective holders. Use of these names does not imply endorsement or association with this post. All rights reserved to their respective owners. This post is for educational and research purposes only.

Comments (5)

C
Christopher Brown · August 18, 2026

Amazing work! Love the detailed posts on the sound etc

B
Brian Bradley · August 17, 2026

I am absolutely stoked for Metamorphic Force.

D
Dr. Manga · August 16, 2026

More 4 players goodies! And Mystic Warriors next! My 4 player pedestal is getting a lot of attention. Thanks team as always!

T
Tetra · August 16, 2026

Nice work that you are doing! I try to read and check out as much of the technical side as I can for edification purposes. Appreciate the work you do. I don't post a ton here but know that it's really interesting to see the progression of how a core is made. Cheers.

A
Alex J Panchen · August 15, 2026

Wow! Alot of info you have given on the development of this core and thanks as I for one love this info. As i said as well on discord "superb thanks!!!"