Monday, 31 October 2022

Do you want to play a game?

Not a lot of time spent on it today. Can now start a game after coining up. Scrolling is a bit screwed atm.

Gameplay mode!

Might be enough to fix the scrolling now before I attempt to bring (Xevious) sprites into the picture.

Coining up, but scrolling will need to be revisited.

Some good and some bad news.

First the good news; transcoding of the high level structure and attract mode screens has been fairly straightforward. It cycles through the 4 screens - sort of, no gameplay - and prints a handful of messages. I can also coin up for 1 or 2 players. They are by no means complete though.

Coined up on the Neo Geo

The bad news; I'm going to have to re-think the background scrolling. Not so much the mechanism on the Neo Geo, but rather how it keeps track of where it's reading the map and where in video RAM is currently visible.

Without checking properly, I assumed that the only place the background layer was being accessed (written) was the map. This (incorrect) assumption allowed me to all-but-ignore how Xevious was doing it and come up with something easier to code on the Neo Geo. Well, that all came crashing down when I (re)-discovered that portions of the Xevious logo are actually rendered on the background layer.

And in the process it needs to position the visible area at a fixed location, which is not a function that I currently support. But it's not a deal-breaker by any means; I just need to revisit it at some point and emulate the actual hardware more accurately. I will do so with a better understanding of the Neo Geo hardware in any case, after the recent experiments with scaled sprites.

For now I'll press on with the high level structure, and flesh it out so I can start a game. This will allow me to start adding (Xevious) sprite support, and then things will really get interesting!

Friday, 28 October 2022

Foreground and background tile layers complete

Tidied up the display (fixed a few bugs) and finished off the foreground tile layer.

Foreground and background tile layers functional

With both tile layers done (in theory) that just leaves sprites, inputs and - at a much later date - sound for the OSD layer. Undecided whether I'll tackle sprites next, or hook up inputs. Probably the latter as the sprites require quite a bit of infrastructure to be transcoded before I'll see anything of them. With inputs I can code the high level function structure, advance through the attract screens, coin up and start a game.

I was having some technical issues with the Neo Geo implementation of the tile layers using shrinking sprites. Turns out there is a rather unexpected limitation with sprite shrinking which has been confirmed by others. If I had known it would have saved me some frustration. For now I'm working around it, but can come back to that later.

The good thing is that once the OSD layer is in place, it's simply a matter of transcoding the game logic; arguably the hard work will be done.

Thinking more about the Amiga port it occurred to me that there may be issues supporting the rich palette of Xevious. Bugger...

Core transcode begun and the foreground tile layer WIP

Big tidy-up of the codebase today, with a better delineation of the core/OSD (OS-dependent aka host platform) interface. All the Neo Geo specific code has been moved from the Xevious core to the OSD (Neo Geo in this case) files.

I've implemented the foreground tile layer on the Neo Geo, and updated the palette to support it.

I started on the transcode of the Xevious core; very early days with little more than the main loop and the function tables in RAM but it's working nicely thus far. The immediate focus is to port some code that writes to the foreground tilemap layer so I can test it, and iron out the interface.

A quick hack in the end, but managed to get this...

NAMCO copyright message on the foreground layer (wrong palette)

It's a bit messy and there's still work to do but encouraging.

As with the background layer, I'm not going to replicate the mapping from video RAM to on-screen tiles; there's really no point and most if not all of the foreground video accesses are done with hard-coded screen offsets. I may be able to write a macro that converts the original offsets to linear addresses.

Wednesday, 26 October 2022

Cleaning up the display

Very quick update tonight.

Cleaned up the Eye Catcher screen (with my custom hack from earlier projects) and added masking sprites to the Xevious display. The screen width still isn't right... there's some behaviour I haven't quite understood with the Neo Geo sprites but hopefully I'll get that sorted soon.


As you can see, the scrolling looks a lot better without the jumping edges top and bottom. Any jerking you may see is an artifact of the MAME video recorder and/or Google playback. It's silky smooth on the emulator.

I also had a look at the VASM assembler which seems to be popular with some Neo Geo and Amiga developers. It all makes sense but none of the sample projects are set up to use a linker with multiple object files, and right now I don't want to look further into it, so it's gnu AS for now...

Tuesday, 25 October 2022

Scrolling, scrolling, scrolling... (I think I've used this one before)

Good progress over the last few days and the first real milestone achieved. The first half of the video doesn't show anything of interest, and I don't have the tools or the time to crop it, so I'd suggest you skip the playback to half way.


On arcade hardware, this is trivial, but the Neo Geo doesn't have tilemaps, let alone scrolling tilemaps, so it was necessary to emulate a scrolling tilemap using the sprites. Fortunately the Neo Geo has bucketloads of sprites (448 in fact) and they're pretty powerful; each one up to 32 tiles high and can be chained together to produce sprites as large as the screen.

Difficult to explain in a quick blog post, but each row of tiles is a Neo Geo sprite and every 8 pixels of scrolling the sprite at the bottom of the screen is re-positioned at the top with the tile data from the row about to scroll onto the screen. The sprite chaining needs to be updated during the process, so that there are essentially two (compound) sprites covering the screen. In between generating the new rows, the sprites are moved down a single pixel.

It's all running in the VBLANK interrupt, and as per the arcade, scrolled every 2nd interrupt.

Note that the distracting bouncing of the top and bottom rows are actually outside the visible area of the arcade screen and will ultimately be masked by opaque black sprites. The screen will also be narrowed from 32 tiles to match the arcade visible area of 28 tiles.

Part of the exercise here was to delineate the boundary between the Xevious core and the host (Neo Geo) layer, as I intend to use the same core on other target platforms. The trick is to have an interface that doesn't affect the (transcoded) core code, but is efficient to implement on the host.

I had started with the idea of the interface simply being the (background) tilemap video RAM, and had actually coded the prototype rendering routine with that in mind. But I found I was jumping through too many algorithmic hoops to produce what was simply a single row of tiles every 16th VBLANK interrupt, and for no good reason, as the access to the video RAM was confined to s single routine in the SUB CPU.

Instead, the video RAM is now essentially a linear row buffer, and where the arcade core calculated and updated a hardware scroll register, the 68K core calls out to the osd_update_scroll_hw() function with just the value of the core's software scroll_cntr variable. The OSD function uses the variable to find the new row in the video RAM and scroll the screen. Clean and as minimal and as optimal as I can make it.

Next I'll tidy up and re-size the screen as detailed above, and re-visit my allocation of Neo Geo sprite resources to fix the Neo Geo Eye Catcher screen and cater for the foreground tiles and sprites.

I should probably also try running this code on real hardware using my NeoSD cartridge, just to make sure I'm not doing anything that upsets real hardware (like I was initially on Donkey Kong).

Sunday, 23 October 2022

Emulating map circuitry!

Unexpectedly I got quite a bit of time to work on Xevious today and made the most of it.

Pretty good progress actually, as you can see from here...

Somewhere in Area 1

OK, maybe you can't see anything different, but there is some significant work behind it.

Yesterday's code rendered from a static dump of the background tile video RAM from MAME.

Today's code reads the map ROM data from an arbitrary point and copies it to video RAM. The interface to the MAP ROM data is (conceptually) the same as the arcade code - a pair of latches. The Neo Geo implementation emulates the glue logic between the 3 map ROMs on the PCB the same way MAME does.

I don't know if I'll keep it this way, but it reduces 64KB of map data down to 8KB.

Next step is to implement the scrolling, which won't be trivial with the Neo Geo sprites, but I've got a pretty good idea how to do it. I also vaguely recall reading an article on how to do it many years ago. Either way, I'm sure I'll work it out. But I wouldn't expect to have it finished for at least a few days.