Tuesday, 21 February 2023

Audit of the MAIN CPU ROM complete!

A couple of big sessions today and I've finally finished the audit of the Xevious MAIN CPU ROM!!!

No more bugfixes - in fact I flagged a possible 5th outstanding bug - but a substantial task out of the way.

Next up is the audit of the SUB CPU ROM, but it is a lot smaller than the MAIN; only 1/6th the number of lines and almost half of that is data. The code tends to be a little simpler as well, so I'm not expecting it to take more than a couple of sessions to complete.

That'll then leave bug fixes, and adding sound!

jotd is progessing well with the Amiga port, it's all-but-playable as-is. He has released a video in the last few days on YouTube. I'm trying to knock over the audit ASAP so I can assist with some of the details.

Monday, 20 February 2023

A bug fixed, high score load/save finalised, and not much else.

As usual not a lot of progress over the weekend due to Real Life.

jotd did find another bug that I'd never actually noticed before; on the attract mode gameplay screen the ground objects were misaligned with respect to the map - how I missed that I have no idea! 😮

Upon closer inspection I noticed that it was the map that was offset (not the objects) and only after the title screen - not after the high score table screen. This made it easy to compare the values of the inputs to the map-rendering routine in each case, since the attract mode always plays Area 1 from the start. And it was only a handful of minutes before the difference was revealed and less than a minute later that the culprit was found.

Nothing even remotely interesting - just an unintialised register used as the index into the table that specifies the offset in the map data for each area. The Z80 code was clearing A to initialise a few other variables, and then using that as the index. In the transcode I was using the CLR instruction instead, then using an uninitialised D0 as the index.

Since this code is not time-critical at all, I reverted to clearing and then using D0 as per the Z80 code, keeper it closer to the original source.

The only other update was finalising the high score load/save on the Neo Geo. The only system to use BRAM (as BRAM) is the MVS; the other two systems (AES/NGCD) support memory card I/O, even though the AES implements a "virtual" memory card in BRAM. I decided to first read from BRAM on MVS systems, and then attempt to read from memory card (on all systems), overwriting any BRAM data if found. On saving high scores, MVS systems write to BRAM, and then all systems attempt to write to memory card.

Probably not how it's supposed to be done, but that's my preference.

Since the "known" list of bugs had grown by 2 (from 8 to 10), and I have fixed one of those, the outstanding list now stands at 4 (with 1 still yet to be confirmed as an actual bug). But for the week heading forward, I'll be spending my lunchtimes at work trying to finish the audit of the MAIN ROM.

Friday, 17 February 2023

Making a splash (screen)!

A diversion today - adding a splash screen to the Neo Geo target.

One of the reasons I want to add a splash screen - aside from advertising - was to display some sort of software version. After the first beta gets out into the wild, I want people to know exactly which version they're running. The plan is for the ultimate version to be released as v1.0.

The first task was rendering the Xevious foreground character set as Neo Geo FIX layer tiles. That was relatively straightforward, but I realised the character set as-is wasn't very convenient for rendering generic text. So I rendered a 2nd set with the alphanumeric and punctuation characters with their correct ASCII ordinals so I could simply use ASCII text in the source code.

Being 1 bit-per-pixel characters, they are nominally rendered with a transparent background. That may come in handy, but I also wanted the option for setting the background colour on a per-character basis. So I rendered a 3rd set - again in ASCII order - with non-transparent background pixels.

That's the beauty of the Neo Geo - oodles of characters/tiles/sprites to go around!

I've done up a quick splash screen. I'm not entirely happy with the aesthetics of it, and I actually can't reconcile the colours with the ones I thought I chose from the Xevious foreground palette, but it's a start.

Crude but conveys what I need to convey...

Back to the audit next session.

Thursday, 16 February 2023

Load/save to/from battery-backed RAM

Curiosity got the better of me and I started looking at saving to battery-backed RAM (aka BRAM, aka NVRAM). FTR MAME saves a copy for every ROM to the nvram directory.

Turned out to be trivial to implement.

First thing I discovered is that the BIOS loads the game data as specified in the header even before the cartridge executes any code. That means by simply setting the right header data the BIOS will automatically load save data from BRAM into my buffer (long before I hook to load from memory card). Half of the solution right there!

By using the same buffer as the memory card, and the same format - including the header - I can determine whether or not valid save data has been loaded, and skip patching the high scores if not. As for saving, I just copy data to my memcard buffer, and call $C12322 instead of saving to memory card. And that's all it takes!

I still need to work out a priority for reading/writing to BRAM/memory card, but that's also trivial.

UPDATE: seems not quite as trivial as I thought... calling the BRAM save routine is corrupting the title screen that follows the GAME OVER screen. I just can't see why... it's not calling any other function, and the registers are all saved in my routine...

UPDATE: the bug has nothing to do with the BRAM save routine; comment out the entire high score load/save routines and it still happens... another known bug (4)

Attract mode fixed, only to uncover more bugs in the process!

Well that opened a can of worms!

This morning I decided to fix the bug where the Solvalou moves very quickly in attract mode.

What I discovered wasn't great; I was treating the _dX,_dY values as bytes in some cases, and (correctly) as a word in other places! So first order of business was fixing all of those instances, and converting a dX,dY table for Solvalou movement from byte values to words.

That fixed the movement in attract mode, but I noticed it wasn't firing at all! Tracking that down uncovered another two (2) bugs; in some places I was reading the attract mode stage as a byte instead of a word, and in the case of generating a random shot to be fired, the random number was being treated as a byte instead of a word. So again, multiple instances that had to be fixed.

All byte/word issues. Makes me wonder how many more of these issues are waiting to be discovered?

Anyway, 5 from 8 bugs, 3 remaining. One of them may/may not be a bug - it was an observation when I was debugging the Neo Geo sprite implementation. I'll have to go back and recreate the conditions to see if it persists. The remaining 2 will be a bit more problematic I think; occasional bullets that just hang in the air, and extra Solvalou being awarded every hit.

But for now, on with the audit...

UPDATE: I've finished the 3rd device in the MAIN ROM, just one more to go...

Wednesday, 15 February 2023

Half-way through the MAIN program audit

Slow progress due to Real Life commitments, but progress none-the-less.

I'm now half-way through the MAIN program, working on all the flying object handlers now.

It has become apparent that the few small blocks of random data throughout the dump are simply padding to allow code to be modified/patched within a single device. Obvious now that I've noticed said blocks are right at the end of each device.

One of the remaining known bugs that I've noted in my note book is the observation that Jara morph into Toroids when they change direction. The problem is, I've just finished auditing the Jara handler code and I can't see any way this could happen. I originally suspected a simple transcode bug with the incorrect sprite code being set in the handler routine. It's not that though - in fact the Jara sprites come from a look-up table based off a timer value to animate them - and it's correct.

It's very unlikely that it's data corruption; once a handler is installed the object type in the object table is ignored. It would have to be the handler address being changed every time the Jara change direction, which isn't very likely.

Unfortunately the Jara aren't very common, so some creative patching might be required.

Something for lunchtime today...

UPDATE: Only 10 minutes to fix the Jara bug! Since Jara only appear later in the game, I simply patched the object table for the Toroids to jump to the Jara handler, so they appear immediately. Fortunately the morph bug was readily apparent; on Jara that started out moving to the left, then changed direction to move to the right (though curiously, not on Jara that started out moving right).

A simple transcode bug that went unnoticed during my audit - I was storing the sprite colour of any right-moving Jara in the _CODE offset rather then the _COLOUR offset in the object table.

So that's 3 of 8 down, 5 (known) bugs to go...

UPDATE: Another big fixed! Actually, it was 2 bugs which had the same ultimate effect - the Zakato wouldn't appear before it exploded. There are actually 4 different Zakato variants with slightly different behaviour. On one variant, the delta X value was inadvertantly written into the high byte, so it disappeared off the screen in 1 frame. On another variant, the instruction to set the sprite code was omitted completely.

So now that's 4 down, 4 (known) bugs to go...

Friday, 10 February 2023

High Score load/save!

Had an idea in the car on the way to work this morning - high score load/save.

At lunchtime I did more of the transcode audit; up to all the object routines now. They should be pretty quick to audit, except for the few which have known bugs.

Tonight at home I read up on the Neo Geo memory card routines. Fortunately they're pretty straightforward to understand and easy to use - it was harder working out how to use them with MAME.

Anyway the load/save has been implemented and tested! On startup the high scores will be read from the memory card (if the card is inserted and there is Xevious data on there of course). And whenever a new high score has been entered on the table, the table is written back to memory card. Easy as!

That's fine if you have a memory card, but some MVS systems supported battery-backed RAM instead. I can see MAME has automatically created it. I'll look at falling back to NVRAM if there is no memory card present.