Saturday 29 May 2021

Scrambling for time atm!

Stars are still WIP, I've been coding the algorithm to produce the tile data and also the data for optimal palette cycling. However work has gotten very busy (plus the Giro d'Italia is currently running) so I haven't done a lot lately. Work will still be busy for another work or two, but then it should quieten down and I'll knock off the last piece of the puzzle.

I haven't put it aside and am keen to start on Galaxian next...

Wednesday 19 May 2021

A star is... coded.

 So I have a plan for the stars.

There are 124 stars, and using 16x16 tiles would require 103 tiles to contain them. Tiles have no more than 3 stars in them. Tiles will also have their own palette (16 colour entries).

There are 4 blink cycles. Rather than use 4 layers of sprites, I plan to use just one layer, with all stars rendered, and use palette cycling to turn stars on and off. At most, the states of 61 stars change in a blink cycle, though some of them may be on the same tile. So worst case, I need to update 61x3=183 words in the palette map. That should still be pretty insignificant as far as processing time for a frame.

In theory, I can replicate the exact star pattern, colours and behaviour - at least as implemented in MAME.

Just need to finish off writing the code to generate the tile and palette data, and some extra data to assist in optimising the updates.

UPDATE: After revisiting the star generator in MAME, it seems worst case is only 47 stars changing state, which is 47x3=141 words written. So a bit quicker again. Tile generation code next...

Tuesday 18 May 2021

Star gazing

Have to admit I had a few days off doing much on Scramble. I did a little with non-tate mode on the Neo Geo but not enough to have anything worth blogging about.

Curiously there is some sort of 'glitch' in the rendering but I don't even understand the nature of the glitch at this point so I can't explain it. It manifests itself as an occasional dark flicker in a bottom tile of the landscape, which only happens whilst the draw_landscape() function is executing. But the landscape is only ever drawn off the visible area to the right, and once scrolled into the screen, is not updated. Furthermore, if I remove the code that clears the columns before rendering, the flickering seems to disappear. So I'm more inclined to conclude at this stage that it's specifically related to the Neo Geo implementation rather than the race conditions I saw earlier.

Moving on from there, I've been looking at the implementation of the stars in MAME. I should be able to mimic the distribution and the colour set; the precise blinking pattern may be another matter. It does cycle through 4 patterns of different stars being enabled/disabled. I think a close approximation will suffice.

It'll be a matter of generating a set of 16x16 tiles with the star patterns and using palette cycling to control them, perhaps even to enable/disable them as well. Like the tilemap, the stars will require a set of chained sprites in a fixed location. And being at the back in the priority order, I'll have to shuffle the existing sprites up a bit.

That leaves tweaking sprite positions, fixing Neo Geo-related implementation issues (controllers and coin-up)  and maybe look at sound, before I revisit non-tate mode.

I'm still undecided about attempting an Amiga port just now. I did just see reference to a video setting up gcc for Amiga development. I'm no Amiga expert so not sure how difficult scrolling a portion of the display is... but maybe that's a good excuse to learn.


UPDATE: I've fixed sprite and bullet position relative to the tilemap. Still have to tweak tilemap position on the Neo Geo though, so will likely require more tweaking. However I think I've got a bug in the bullet/rocket collision detection routine; occasionally the bullets appear to pass straight through rockets.

UPDATE #2: Had a quick play this morning and can see there's definitely an issue with bullet collision-detection at least, and it's not limited to rockets. Occasionally the bullet will pass straight through objects. A quick look at the code doesn't give any hints.

UPDATE #3: Had a look at the star generation for Galaxian in MAME. Scramble is slightly simpler as it doesn't scroll, but mapping the hardware implementation to the software framework of MAME convolutes the algorithm somewhat. In short, an LFSR generates the star positions and colour index (from a palette of 64), whilst further combinatorial logic controls the 4 cycles of blinking. There are a total of (just) 124 stars on the screen, not all visible at the same time due to the blinking effect.

All 124 stars generated for Scramble

I have actually implemented the same LFSR in the code to generate the star tiles for the Neo Geo, but there are a few unsolved issues that remain. Sprites are limited to 16 colours, whilst stars have 64. There are a number of approaches to that issue, including (effectively) assigning each star its own palette. Then there's the blinking; do I use palette cycling, or have 4 layers of sprites? Food for thought...

Saturday 15 May 2021

Running at full tilt!

Great result! By updating 96 entries in the (memory-mapped) palette map rather than the palette index in 1024 (effectively port-mapped) sprite registers, the entire ISR now runs for signifcantly less than 1/4 of a frame and the landscape drawing is finished well before the next VBLANK interrupt.

Palette update finished before the visible area of the frame is rendered

This gives plenty of head-room for the code to run and any potential race conditions should now be alleviated. The game should run at 100% now with no glitches.

One thing I did (also) change is move the scrolling to the start of the ISR (before palette change) to eliminate the screen tearing I noticed on MAME. I'll do the same for the sprites.

And the background colour; I was thinking I'd need another layer of sprites but of course you can control the background colour directly on the Neo Geo (as I have been doing to profile the ISR) so that was a one-line implementation!

Blue background. All that is missing are the stars


Next up stars (which will need their own layer - just another 32 sprites and some tiles created for stars) and maybe use palette to blink them.

Finally, I need to tweak some Neo Geo-specific features, such as coining up and playing a game. At the moment I can only read the SELECT button running as an AES. Not sure how to handle coin-up on MVS just yet as it's handled by the BIOS depending on what mode the game is running in. If I get time today, I'd like to copy the ROM to my NeoSD and try it on my real AES console!

UPDATE: Scramble running on my Neo Geo AES!

Washed out colour due to the phone camera/flash


Profiling and palette manipulation?

I was thinking more about the glitches I saw and race conditions in the code which also reared their heads in the prototype PC port. There are two areas of the code which could, under certain conditions, cause issues. The one relevant here occurs when the mainline code is (still) drawing the landscape and gets interrupted by the next VBLANK. Not that this should never happen on the original machine.

So a few profiling experiments tonight to see how much time is spent doing what.

I thought of using the background colour to indicate which area of code was being executed. I was shocked to see how much time was spent in the ISR - not actually running Scramble code but updating the Neo Geo display hardware or, more specifically, the tilemap palette (there's 1024 tiles to update every frame).

The background is set to RED in the ISR during the video hardware update, YELLOW when the Scramble ISR code is running, and BLUE when the mainline code is updating the landscape (drawing the right-most 2 columns).

Everything enabled

As you can see, it spends about two-thirds of the time in the ISR, and more than half of that is just updating the video hardware (red). When the ISR queues a few commands to be executed by the mainline code, the landscape draw function (blue) extends to the right-hand edge of the screen. This is where you'd see glitches before I disabled interrupts around the VRAM accesses.

I halved the number of tilemap palette updates and saw a correspondingly shorter red area. And after eliminating all tilemap palette updates, the red isn't even visible which means the (Scramble) sprite updates are taking very little time at all.

Updating only half the tilemap palette

Although the blue area sometimes moves a little towards the right-hand edge, I never saw it actually get there. What this tells me is that there's sufficient time to execute all the Scramble code on the 68K; it's just the VRAM accesses that are causing issues. So there's little point trying to optimise the generate ASM code any further I don't think.

So what can I do from here? Ideally the landscape drawing (blue) should be finished before the next VBLANK interrupt, otherwise it's possible some object can be drawn in the wrong column - even with the interrupt protection. That's because the ISR changes some variables used by the landscape drawing function.

One option is to update the palette only when the palette actually changes, and only for those tiles that have changed, rather than each and every tile every frame. But that doesn't actually change the worse-case scenario, and will only reduce the problem, not eliminate it. And the extra code could push the landscape update further into the next VBLANK.

The landscape draw function is also surprisingly slow, though it requires quite a few VRAM accesses as well. I could take a copy of the variables updated in the ISR at the start of the function which means it would only be critical that the ISR start before the next VBLANK...

Something I need to ponder further... feel free to provide suggestions.

Actually I just had a thought - how about updating the palette entries instead of updating all the tilemap entries!?! This might have merit... stay tuned!

UPDATE: I'm yet to try it, but I think this will work! On Scramble there's a colour (palette index) for each column (32 tiles) - so 32 index entries. I can simply assign each of the columns to its own Neo Geo palette, and then update the three words for each column every frame - a total of 32x3=96 writes and no VRAM address register slowing it down ever more!

Friday 14 May 2021

So it's down to looking at gcc code generation...

The good news is that I've sorted all the issues with race conditions. I learned how to generate extended inline ASM in gcc, refreshed my memory on Neo Geo interrupts, took a look at the ngdevkit crt0.S code, rediscovered how to generate assembler and symbol listings in gcc, and confirmed the findings in the MAME debugger.

In a nutshell, all I had to do is disable the VBLANK interrupt in the function that updates the tilemap, where it sets REG_VRAMADDR and then writes the tile number to REG_VRAMRW. This eliminates all the glitches where tiles would occasionally be written to the wrong location on the tilemap.

Note that this function is (also) called from the VBLANK interrupt, so I had to save/restore the 68K status register rather than simply re-enable interrupts.

The only other critical function that accesses the Neo Geo VRAM is called from the ngdevkit VBLANK rom callback routine, after the interrupt has been acknowledged (so I don't have to do it after all) and in the context of an ISR (interrupts are already disabled). So nothing to do there.

I also did a preliminary optimisation of the code that updates the tilemap attribute (colour) and scroll registers, and all the sprite registers. On the original arcade hardware, this is done in the NMI and is a simple 128-byte LDIR. Not so simple on the Neo Geo, and quite slow with the REG_VRAMADDR mechanism.

So onto the bad news.

The NMI (VBLANK interrupt) code is taking too much CPU time and although it does finish before the next interrupt, the mainline code is starved of CPU. So you can coin up and play the game but tasks like updating the text and so-called head-up display, and drawing some of the landscape isn't being done.

Taking a look at some of the code being generated was an eye-opener to say the least. There are snippets of code that are inexplicably inefficient and complex. It seems that any code involving a structure member variable is just ridiculously inefficient, and that's a static structure so there's no member offset calculations involved at all.

Check out this snippet that contrasts a simple member update...

1604:src/scramble/scramble.c **** wram.score_table_text_ptr = score_table_text;
4554 .loc 1 1604 0
4555 1d86 203C 0000 move.l #score_table_text,%d0
4555 0000
4556 1d8c 2200 move.l %d0,%d1
4557 1d8e 4241 clr.w %d1
4558 1d90 4841 swap %d1
4559 1d92 E049 lsr.w #8,%d1
4560 1d94 1439 0000 move.b wram+1113,%d2
4560 0000
4561 1d9a 0202 0000 and.b #0,%d2
4562 1d9e 8202 or.b %d2,%d1
4563 1da0 13C1 0000 move.b %d1,wram+1113
4563 0000
4564 1da6 2200 move.l %d0,%d1
4565 1da8 4241 clr.w %d1
4566 1daa 4841 swap %d1
4567 1dac 7400 moveq #0,%d2
4568 1dae 4602 not.b %d2
4569 1db0 C481 and.l %d1,%d2
4570 1db2 2F42 000C move.l %d2,12(%sp)
4571 1db6 1239 0000 move.b wram+1114,%d1
4571 0000 4572 1dbc 0201 0000 and.b #0,%d1
4573 1dc0 822F 000F or.b 15(%sp),%d1
4574 1dc4 13C1 0000 move.b %d1,wram+1114
4574 0000
4575 1dca 2200 move.l %d0,%d1
4576 1dcc E089 lsr.l #8,%d1
4577 1dce 7400 moveq #0,%d2
4578 1dd0 4602 not.b %d2
4579 1dd2 C481 and.l %d1,%d2
4580 1dd4 2F42 0008 move.l %d2,8(%sp)
4581 1dd8 1239 0000 move.b wram+1115,%d1
4581 0000
4582 1dde 0201 0000 and.b #0,%d1
4583 1de2 822F 000B or.b 11(%sp),%d1
4584 1de6 13C1 0000 move.b %d1,wram+1115
4584 0000
4585 1dec 7200 moveq #0,%d1
4586 1dee 4601 not.b %d1
4587 1df0 C280 and.l %d0,%d1
4588 1df2 2F41 0004 move.l %d1,4(%sp)
4589 1df6 1039 0000 move.b wram+1116,%d0
4589 0000
4590 1dfc 0200 0000 and.b #0,%d0
4591 1e00 802F 0007 or.b 7(%sp),%d0
4592 1e04 13C0 0000 move.b %d0,wram+1116
4592 0000

  ...with that of a discrete static variable:

1605:src/scramble/scramble.c **** bananas = score_table_text;
4593 .loc 1 1605 0
4594 1e0a 23FC 0000 move.l #score_table_text,bananas

That's quite a difference! There are other instances throughout the code, even for simple uint16_t variables. I'm sure it all adds up. So one option is to move all the variables out of the structure and see what sort of savings I get.

The not so bad news is that it seems to not be too far from the tipping point as-is. If I remove the code that updates the tilemap attributes for example, which comprises a mere 32 writes to VRAM, then the game appears to run just fine.

So a bit of experimentation in optimsation still to be done.

UPDATE: The structure issue could rather be an alignment issue... more to come...

UPDATE #2: Removing #pragma pack(1) from the wram structure produced code akin to the 2nd snippet above. It also decreased the code size from 0xB28C to 0x98F0. However it didn't seem to have any effect on the NMI execution time... hmm...

UPDATE #3: Almost there! Some more optimisation of the tilemap update code together with eliminating most of the structure packing and the game is almost glitch-free. Occasionally on the ufo stage the landscape isn't drawn correctly (more on this later).

Thursday 13 May 2021

About to bite the bullet...

It's time to book the fat lady who sings. After consulting my Donkey Kong code, I copied the "magic" algorithm for transforming the sprite Y coordinate and viola - sprites appeared! Still perhaps not pixel-perfect due to the placement of the underlying tilemap, but close enough for now.

Score table with sprites

It runs slow, there are glitches, but most of the implementation is done. Bullets are missing but everything else is in place. It's actually playable now.

Scramble, on the Neo Geo in tate mode

The game really slowed down when I got the sprite update code working. Not sure why because there wasn't a lot I added but maybe just enough to tip the NMI execution time over the 16ms mark. It could also be because of the brute-force hack I did to minimise glitches (still) caused by a race condition with the Neo Geo VRAM registers. So there's still a bit of optmisation that can be done. I have no doubt I can ultimately get it running at 60fps.

The scrolling was trivial to implement on the Neo Geo. Initially I defined the tilemap as a single 32x32 tile (scaled to 50%) chained sprite, with a single origin. But today I divided it into 3 chained sprites, the middle sprite being the scrolling portion of the display. So scrolling the playfield now requires an update to just a single sprite Y coordinate register - too easy.

I'll need to go back and create a tile for the bullet sprite; on the arcade game the bullets are not rendered from ROM data like other sprites but rather a dedicated circuit on the PCB. Then I can add the code to assign another 4 Neo Geo sprites to the bullets and the functionality should then be complete.

From there it's a matter of handling the race conditions (I think I just need to disable interrupts briefly) and optimise the VRAM access code and that should be it. I might look into adding sound if I can find some samples as there seems to be resources around to get a sound driver up and running.

I'm also thinking of options and strategies for rotating the display. I already have rotated tiles and sprites in the CROM.

UPDATE: added bullets.

My progress has been... interrupted.

After such rapid progress early on it has all come to a crashing halt. I've spent way too much time attempting to get sprites displayed, only to make matters worse. I did, however, manage to fix the background colour and get the tilemap palette working.

Proper tilemap palette

There seems to be either some corruption on the tilemap, or some sprites that haven't been cleared that are causing issues. The attract mode text screens are minimally affected but when the demo/game starts, all hell breaks loose.

Looks OK except the missing '0' in the high score

In theory the sprites should be almost trivial, especially given the tilemap was relatively straightforward. I'm using the same technique I used in Donkey Kong almost a decade ago; the tilemap consists of 32 vertical sprites each 32 tiles high, with sticky bits set. And the sprites are, well, just single-tile Neo Geo sprites.

I have discovered what I strongly believe is a contribuing factor. But right now, I don't know the best way to solve it. It's actually going to be a little horrible, I think.

The Neo Geo has a VRAM address register (REG_VRAMADDR) that determines where in memory you write VRAM data. Routines that update the tilemap and the sprites need to set this register before any VRAM accesses. The trouble is, these routines are called from both the main code, and the NMI, which means the NMI can preempt the call from the main code, changing REG_VRAMADDR and causing the wrong address to be subsequently written.

One fix is to mask the interrupt whenever the code is writing to VRAM, though I'm not sure if it's even possible on the Neo Geo. Another fix would be to shadow all writes to VRAM and have the NMI write them through to the hardware - in fact I think that's what I'm doing on Donkey Kong.

But there also seems to be a similar issue with the command queue - implemented as a circular buffer - which is pushed by the NMI and popped by the main code. I can only foresee an issue though, when the queue is actually full; so maybe right now the background is getting no CPU...

Either way, some ugly issues to solve.

UPDATE: All is not as bad as it seems! I wasn't ACKing the VBLANK interrupt properly! Still some work to do, and still no sprites, but looking much better already!

Coined up and playing the game!


Wednesday 12 May 2021

Finding my way around ngdevkit

I spent some time this morning trying to build Scramble with my old makefile to no avail. I'm yet to understand how pkg-config actually works but I wasn't able to resolve all references and there were also differences in the startup code and vector table for the cart. Ideally I want a common makefile for all targets but the investment in time and effort isn't warranted at this point.

The built-in eye-catcher

As a result I finally cut my losses and started instead with one of the examples included with ngdevkit. I don't understand at this point how to configure certain cart header items like game name and eye-catcher settings, but at least I have a project building now with the Scramble core code and NMI handler running off the ngdevkit VBLANK interrupt call-back.

In theory scramble is running but with no osd layer there's nothing to see. For now all I'm doing is defining the dipswitch for lives, initialising the palette and printing some text on the FIX layer. Not sure where the blue background comes from; it's not in the Scramble palette and it doesn't appear to be on the FIX layer, so...

It's a start...

I've converted the actual palette from the arcade and next up is to create the data for the tiles and sprites in the C1,C2 ROMs. That should be relatively straightforward as I hope to simply adapt conversion code from earlier projects.

UPDATE: Well I can confirm the game is running, including the NMI. Here is a snapshot from MAME with only the tilemap (sans scrolling) implemented, albeit with a funny palette. Note that the Neo Geo display is rotated using the -rol option. I must admit I didn't expect to get this far so easily.

Scramble running on the Neo Geo in MAME


ngdevkit to the rescue!

I've done about as much as I can do on the PC platform, and added the map generator, so I started to look at the Neo Geo port.

I've been using the old NEODEV toolkit which is based on the rather ancient gcc 2.95.2 for my past projects (Lode Runner, Knight Lore). It has its quirks but generally works pretty well. However it doesn't support the newer C standards whose features have inevitably crept into my Scramble code as I haven't developed for it for years, and an initial compile threw up literally hundreds of errors.

I started to fix the errors but then wondered whether there was a more modern option for building Neo Geo software in C. I came across Damien Ciabrini's ngdevkit which is (currently) based on gcc 5.5.0 and looks the business, shipped with several examples that build out of the box and run under MAME. Admittedly it took me a while to build the windows (MSYS2) toolchain correctly, but when I actually followed all of the instructions, it built and installed without a hitch.

The example project makefiles bear absolutely no resemblance to my old Knight Lore makefile - so learning a new way to do things will be interesting - but with some quick hacking of my old makefile, compiling the scramble core module actually results in zero errors, so I may yet get away with my anonymous unions and structures...

Of course I can't generate a ROM file just yet, as the operating system dependent wrapper hasn't been modified for the Scramble core, so that's a task for next session. But it's very promising that I've gotten this far with so little effort.


Tuesday 11 May 2021

Preliminary map.

As usual not a lot of time on the weekends and today (Monday) was no different. I did however have a chance to play around with some map generating code.

Here's a preliminary map. I need to add background colour and I'll also throw in some stars just to indicate where they are/aren't visible. I should add level markers and I could also add the ufo and fireballs to their respective areas. I might also throw in some counts of the various objects, and maybe total points value.

Preliminary map of Scramble

It's 1,430 characters or 11,440 pixels wide (approximately 51 screens) including the flat strip at the start which technically isn't part of the landscape meta data, but rather tacked on to the start of each area when you're starting over with a new ship. The landscape scrolls 1 pixel every VBLANK interrupt and the colour changes every 512 interrupts/pixels. There are 7 colour palettes for the landscape (colour set 1 isn't used for some reason, although it is cycled in an explosion).

UPDATE: Added stage markers

Added title screen text and stage markers

UPDATE #2: Added background colour, stars, ufos and fireballs

Release candidate



Friday 7 May 2021

Scramble the movie

 All bugs (AFAICT) have been fixed, transoded C listing has been tidied up, and I'm ready to start on the Neo Geo port next session.

There'll be a bit of a ramp-up as I haven't touched Neo Geo development for a few years now. But I should have enough examples from my past projects to get things up and running relatively quickly.

For now, a video of the C code in action on the PC. Scaling x2, but bullets not scaled properly.


Still haven't quite worked out how the scrolling will work on the Neo Geo, but I'm sure I'll figure it out. Plenty of scrolling games on the Neo Geo...

Go big or go home!

 The two bomb-related bugs were related, and they've been fixed.

In the mean-time, I was getting sick of squinting at the small screen and thought I'd look into how difficult it would be to upscale the display on the PC. Turns out it was trivial (except for the bullets) using the Allegro5 bitmap scaling functions and the whole process, including research, took about 10 minutes.

Scale factor x2

It actually looks more accurate using 4:3 scaling but again, the point of this exercise is not about playing it on the PC.

So this last bug has me really scratching my head. The symptoms are (mostly) missing vertical strips from the landscape. Occasionally the strips will filled with erroneous landscape graphics, rather than being missing (black)...

Vertical bars missing from the lndscape

The odd thing is, although it happens quite frequently, it only seems to happen after you crash your ship into the landscape. It doesn't happen if your ship is destroyed by any in-flight enemies such as rockets.

I do know that it's not corrupting any ROM data structures (in this case static C arrays), because subsequent plays do not exhibit the corruption. That would suggest perhaps it's a corruption in RAM. But I have seen the case where it renders the flat landscape correctly, only to have it (the flat part) corrupted as soon as it starts scrolling. Once rendered, landscape should not be rewritten until it scrolls off the screen.

That left me wondering whether it was a bug in my Allegro-layer routines. But the fact it only happens when you hit the landscape doesn't quite fit with that theory either. But typing all this out has got me thinking...

UPDATE: I've just confirmed it's the character RAM (tilemap) that is being corrupted. I suspect the code to render two columns right of screen is writing to the wrong area, either because there's a bug in the routine itself, or some area of RAM is being corrupted or not initialised properly (more likely).

UPDATE #2: Not just landscape collisions that cause the issue.

UPDATE #3: Solved! That was a tough one. Turned out to be a race condition between the main routine and the NMI only because in my prototype implementation I don't have a pre-emptive NMI but rather just 2 threads running simultaneously. I was thinking that the landscape was drawn from the NMI, but I was wrong. I noticed a pointer was changing in the draw_landscape routine between the start and the end of the function and then it twigged.

Now just a little more play testing before I can announce the transcoding is officially done!



Thursday 6 May 2021

Transcode complete; 3 bugs remain (that I know of).

I can now say the transcode is 100% complete in that all routines have been coded and all data transcribed. The only things missing are actual audio output and background stars.

Blue background supported

Sound routines have been coded short of banging hardware to communicate with the audio CPU. Of course on a port those routines will be highly dependent on the audio implementation chosen for that platform. I suspect that will consist of another process playing audio samples.

I fixed a few bugs today including the segmentation fault as I mentioned in the previous post. Three (3) bugs remain that I have seen; some bombs freeze mid-air until you drop a subsequent bomb, some bomb explosions freeze, and occasionally - much less freqently now - there are strips of landscape missing.

Of course my next task is to continue play testing one- and two-player games and finding and fixing these bugs. There's also some minor sprite alignment issues (with bullets for example) that will require some trial-and-error tweaking.

I've got a few build options in the code to facilitate testing such as invincibility, infinite fuel, starting level etc. So I already know playing through and destroying the base starts a new mission just fine.

Once I've fixed the bugs and thoroughly tested I can start on the Neo Geo port...

Wednesday 5 May 2021

It's Da Bomb!

Lack of updates because of lack of progress only because of lack of time.

I can see the light at the end of the tunnel. You can shoot and destroy all objects - on the ground and in the air - and you can launch bombs, though the latter do not have any collision detection routines implemented as yet.

Shooting and bombing

So it's getting very close now; I'd estimate at the very least 95% complete. Aside from the bomb collisions and associated animations, there's a couple of minor routines like displaying mission flags and checking for extra lives and then just testing of the high score table to go.

I haven't implemented any of the sound routines, except adding calls to sound routines wrapped in a macro that nulls them out. The missing routines involve queuing and passing commands to the sound CPU, so there's not actual sound generation done in the code. I will implemement those to facilitate sound on any ports.

Most approriate for any port would, I suspect, be adding 'simulation' of the sound CPU that simply played samples. I'll leave that until later. Likely a lot later.

I haven't added emulation of cocktail mode either, which comprises flipping the screen and reading alternate controller inputs (although the calls are there). There's likely no need for this in any port at all.

I also haven't implemented the starfield or coloured background (blue/black) as of yet. The calls are there in the code, so it's a matter of writing some Allegro code to suit. I just haven't done it yet.

I have recently introduced a rather nasty bug, or perhaps more correctly, triggered it reliably - namely a segmentation fault whenver the player is destroyed and the game is about to restart. I suspect it is related to the landscape corruption I saw earlier. I'll leave this until the transcode is done and hopefully it won't be too difficult to find. Unfortunately I haven't had much luck getting the game to run in GDB thus far.

It'll probably be a few days before I can finish the transcode, sort the segmentation fault and tidy up the rest of the code. There are the odd inefficiences that I've purposefully left in the code, I don't think they'll have any significant impact on the performance on target hardware.

UPDATE: I've added support for the blue background and fixed the segmentation fault. I had a quick look at the MAME source for the stars and I don't think there's any good reason at all to attempt an accurate implementation. In fact not sure I'll even bother with stars on the Allegro prototype, at least not unless I need to prototype something for the other platforms.

There's still a few bugs introduced with the bombs but hopefully they won't be too hard to find. Hope to be able to start on the Neo Geo port in the next few days.