I've been forging through all the code that is called as part of the demo and/or attract modes from the main line execution path. The only trouble is, I can't actually test any of it because it's all kicked off by events created in the ISR's which currently don't exist except for a simple countdown timer used for delay loops. But at least I know it assembles.
Along the way I coded the attract mode Easter Egg, which I'd completely forgotten about; if you haven't seen it, it's not very exciting at all. I did read that you can't actually trigger it in MAME due to the manner in which the input controls are sampled - so that's one thing the Coco3 port will have over MAME!
As others have noted before me, I would have to agree that Space Invaders doesn't exactly showcase the highest quality of 8080 coding. For example, some of the logic depends on variables being at particular addresses, so simply changing the .org statement in the .ASM file, or even adding or moving variables around, would actually break the code! The dilemma for me is, do I fix these issues, or faithfully reproduce them? Right now my memory map is purposefully identical right down to the byte level, so it makes no difference. But I still have half a mind to do it properly, even if I document the way it was done originally in the source.
It's pretty obvious the assembler they used was quite primitive - if indeed they used one at all! In fact, it wouldn't surprise me if they didn't use one. There's certainly evidence that at least some of the code was patched, rather than re-assembled, although that could have been done only to negate the need to re-image all of the discrete ROM chips.
Now to the interrupts...
UPDATE: You can add a coin. Just one coin for some reason atm...
This blog chronicles my progress porting various retro games to other retro platforms. The goal in each project - at least when targeting a new CPU - is to effectively replicate the original graphics and the original code line-by-line, to produce a 100% accurate port of the original game.
Wednesday, 20 April 2016
Tuesday, 19 April 2016
One timely interruption
Not a lot of time to work on Space Invaders over the last few days, but coming along nicely. I definitely think I'd like to finish it now before returning to Knight Lore.
As-is it loops through the attract screens, complete with punctuated text rendering, although the animations (involving the little invader) are yet to be coded. The demo displays the shields and the line across the bottom of the screen before continuing onto the attract mode.
Source, including data, is around 1,500 lines already. In comparison, the IDA disassembly of the arcade original Z80 code is around 4,200 lines. The translation from 8080 to 6809 has been quite straightforward thus far; I'm using a fairly strict register mapping convention and I've only been forced to use shadow memory registers (for BC) once or twice.
The game uses interrupts heavily, having two (60Hz) interrupts on specific scan lines which drive most of the game logic. I've only enabled one of them - line 224 which is effectively the VBLANK interrupt - and it simply decrements a timer counter (used in the attract mode) at this point.
Rather than attempt to use a HBLANK interrupt and count scan lines for the other interrupt, I'll start the timer in the VBLANK interrupt. The exact timing of the second interrupt isn't critical so it should be accurate enough for the code to run without any noticeable difference.
Once I finish the portions of the attract mode that aren't interrupt-driven, I'll have to start fleshing out the ISR's to see anything else happen.
As-is it loops through the attract screens, complete with punctuated text rendering, although the animations (involving the little invader) are yet to be coded. The demo displays the shields and the line across the bottom of the screen before continuing onto the attract mode.
Source, including data, is around 1,500 lines already. In comparison, the IDA disassembly of the arcade original Z80 code is around 4,200 lines. The translation from 8080 to 6809 has been quite straightforward thus far; I'm using a fairly strict register mapping convention and I've only been forced to use shadow memory registers (for BC) once or twice.
The game uses interrupts heavily, having two (60Hz) interrupts on specific scan lines which drive most of the game logic. I've only enabled one of them - line 224 which is effectively the VBLANK interrupt - and it simply decrements a timer counter (used in the attract mode) at this point.
Rather than attempt to use a HBLANK interrupt and count scan lines for the other interrupt, I'll start the timer in the VBLANK interrupt. The exact timing of the second interrupt isn't critical so it should be accurate enough for the code to run without any noticeable difference.
Once I finish the portions of the attract mode that aren't interrupt-driven, I'll have to start fleshing out the ISR's to see anything else happen.
Sunday, 17 April 2016
Space Invaders
And so it begins... with the Knight Lore ROM image emailed off to John for CocoFEST, I've decided to take a short break from filmation games until it's time to produce cartridges, in which case I'll need to look at code optimisation. However I've been in contact with another programmer who is in the final stages of porting Pentagram to the Atari 8-bit machines, and he's given me some invaluable insight into where the code can be improved. In fact, he has Pentagram running on the Atari slightly faster than the ZX Spectrum, and a lot of the code is still auto-generated from Z80 to 6502!
I was just playing around with the arcade version of Space Invaders, seeing how that would look on the Coco3. I fired up MAME and took a memory dump mid-game, played with the layout a bit, and then loaded it into the Coco3 under MESS.
It looks pretty good to me, and tonight I couldn't resist starting on an actual port. Whether or not I decide to see it through just now will depend on how quickly it proceeds in the initial stages, but if my experience with Knight Lore is any indication, it might not take long to get things well along.
I'll retain the original video memory mapping (including rotated screen) until the game is all-but-ported, to simplify the process. I've done rotation on-the-fly in my TRS-80 Model 4 'bootleg', so it's not a big deal. Running MESS with the 'rol' option will give me the correct display during development. One thing I do need to do though is bit-reverse all the graphics data, as the pixels are laid out in the reverse order within each video RAM byte.
I've also decided to work with the disassembly on Computer Archeology, rather than my own reverse-engineering, for reasons I won't bother to explain.
I'm hoping to knock this one over fairly quickly, given all the reverse-engineering has already been done and it's a relatively small - and simple - program. I'm not going to bother producing a cartridge for Space Invaders; rather I'll make disk and ROM images freely available for download.
I was just playing around with the arcade version of Space Invaders, seeing how that would look on the Coco3. I fired up MAME and took a memory dump mid-game, played with the layout a bit, and then loaded it into the Coco3 under MESS.
![]() |
| Space Invaders (mock up) on the Coco3 under MESS |
It looks pretty good to me, and tonight I couldn't resist starting on an actual port. Whether or not I decide to see it through just now will depend on how quickly it proceeds in the initial stages, but if my experience with Knight Lore is any indication, it might not take long to get things well along.
I'll retain the original video memory mapping (including rotated screen) until the game is all-but-ported, to simplify the process. I've done rotation on-the-fly in my TRS-80 Model 4 'bootleg', so it's not a big deal. Running MESS with the 'rol' option will give me the correct display during development. One thing I do need to do though is bit-reverse all the graphics data, as the pixels are laid out in the reverse order within each video RAM byte.
![]() |
| Space Invaders in 6809 (WIP) |
I've also decided to work with the disassembly on Computer Archeology, rather than my own reverse-engineering, for reasons I won't bother to explain.
I'm hoping to knock this one over fairly quickly, given all the reverse-engineering has already been done and it's a relatively small - and simple - program. I'm not going to bother producing a cartridge for Space Invaders; rather I'll make disk and ROM images freely available for download.
Friday, 15 April 2016
Bit Rot?
I thought I should bring all the C ports up-to-date today; Amiga is there and Neo Geo is all there bar the new (Mick Farrow graphics) sprite tiles being generated (ie. it has the dip-switch setting and the code just needs a simple tile bank offset to be added).
It wasn't all plain sailing though, the Neo Geo port gave me a bit of grief. Not having touched this in months, I just needed to add a few stubs for new palette routines so it would link and fire up MAME. I was a little surprised to be greeted by the cross-hatch screen. I generated a clean build, fired it up again, and same thing. The dreaded bit-rot... hmm...
After checking that the files were all being generated, and grasping at a few other straws, I decided to find out exactly what the cause of a cross-hatch screen is on the MVS. Turns out they're colour-coded, and my blue border meant that a cartridge could not be found! The only thing that could explain that under emulation would be a corrupt P1 (program) ROM.
Loading the P1 ROM into a hex editor revealed immediately that the file was all-but-blank! Time to go back and take a closer look at the compilation output. It's not easy to maintain a clean build on a multi-platform project, especially retro platforms with development toolchains that can be rather old, and as it turns out, the Neo Geo gcc (v2.95.2 circa 1999) complains quite a bit. So much so, that you tend to ignore it after a while. Examining the output more carefully revealed an assembler warning about incorrect attributes being set for .rodata in the newly-added Mick Farrow sprite graphics data arrays.
Without going into too much detail, I have needed to use section attributes to force gcc to place certain data structures into ROM - const just hasn't worked in some instances (yes I know the differences of placement). The confusing thing is, it was never an issue with the original ZX or CPC graphics arrays, and they're not significantly different to the new file. After using some Google Fu it seemed it was a known gcc bug at various times in the past, however the work-around didn't assemble in my toolchain. Again, grasping at straws, having noticed that the existing graphics files had additional arrays defined before the sprite arrays, I instantiated a dummy 1-byte array at the top of the new file and - viola - it worked! And for the record, exactly the same section attributes were still being set for the sprite data!
The whole process was probably a good hour or so.
I'm not about to ponder any further on this issue - it's not broke (anymore) so I won't fix it!
UPDATE: Mick Farrow's graphics on the Neo Geo port.
Incredibly the game now uses no less than six (6) sprite tile ROM's, not quite full but in the order of 40,000 tiles. In reality, at least half are never used by Knight Lore (ie. the VFLIP'ped versions, with the exception of a few border sprites) but at least the framework is there for the other filmation titles that may use them.
As a result, I had to find a larger host game, this time pspikes2. Basically each sprite tile ROM pair holds the sprites for an entire graphical variation. Note that Mick's panel graphics are not available (yet) as the panel is rendered on the FIX layer. I'd need to rip them and allocate another bank in the FIX ROM, which I will probably do soon.
UPDATE #2: Speaking of bit rot, in attempting to add another set of panel tiles for the Mick Farrow graphics, I've broken what was already there. I can't coax my tool into reproducing the existing panel data, let-alone a new one. Annoying...
It wasn't all plain sailing though, the Neo Geo port gave me a bit of grief. Not having touched this in months, I just needed to add a few stubs for new palette routines so it would link and fire up MAME. I was a little surprised to be greeted by the cross-hatch screen. I generated a clean build, fired it up again, and same thing. The dreaded bit-rot... hmm...
After checking that the files were all being generated, and grasping at a few other straws, I decided to find out exactly what the cause of a cross-hatch screen is on the MVS. Turns out they're colour-coded, and my blue border meant that a cartridge could not be found! The only thing that could explain that under emulation would be a corrupt P1 (program) ROM.
Loading the P1 ROM into a hex editor revealed immediately that the file was all-but-blank! Time to go back and take a closer look at the compilation output. It's not easy to maintain a clean build on a multi-platform project, especially retro platforms with development toolchains that can be rather old, and as it turns out, the Neo Geo gcc (v2.95.2 circa 1999) complains quite a bit. So much so, that you tend to ignore it after a while. Examining the output more carefully revealed an assembler warning about incorrect attributes being set for .rodata in the newly-added Mick Farrow sprite graphics data arrays.
Without going into too much detail, I have needed to use section attributes to force gcc to place certain data structures into ROM - const just hasn't worked in some instances (yes I know the differences of placement). The confusing thing is, it was never an issue with the original ZX or CPC graphics arrays, and they're not significantly different to the new file. After using some Google Fu it seemed it was a known gcc bug at various times in the past, however the work-around didn't assemble in my toolchain. Again, grasping at straws, having noticed that the existing graphics files had additional arrays defined before the sprite arrays, I instantiated a dummy 1-byte array at the top of the new file and - viola - it worked! And for the record, exactly the same section attributes were still being set for the sprite data!
The whole process was probably a good hour or so.
I'm not about to ponder any further on this issue - it's not broke (anymore) so I won't fix it!
UPDATE: Mick Farrow's graphics on the Neo Geo port.
![]() |
| Mick Farrow's modified graphics on the Neo Geo |
Incredibly the game now uses no less than six (6) sprite tile ROM's, not quite full but in the order of 40,000 tiles. In reality, at least half are never used by Knight Lore (ie. the VFLIP'ped versions, with the exception of a few border sprites) but at least the framework is there for the other filmation titles that may use them.
As a result, I had to find a larger host game, this time pspikes2. Basically each sprite tile ROM pair holds the sprites for an entire graphical variation. Note that Mick's panel graphics are not available (yet) as the panel is rendered on the FIX layer. I'd need to rip them and allocate another bank in the FIX ROM, which I will probably do soon.
UPDATE #2: Speaking of bit rot, in attempting to add another set of panel tiles for the Mick Farrow graphics, I've broken what was already there. I can't coax my tool into reproducing the existing panel data, let-alone a new one. Annoying...
I 'C' no more bugs!
Continuing on with testing the C port, and you can complete the game and see the end-of-game animation and messages. There were a few more bugs, but none too nasty. For the record, most bugs in the C port have been signed/unsigned issues.
I've also added Mick Farrow's modified graphics as a run-time option.
I need to propagate the changes through to the Amiga and Neo Geo ports. The latter will be more fiddly as it will require the generation of another few thousand sprite tiles, but the tool is already there.
I realised recently it would (probably) be relatively trivial to add an Atari ST port - then I could add another target platform to my CV! I'm also still deciding whether I have the motivation left in me to attempt a Sega Genesis port as well, or whether I'm well-and-truly over Knight Lore by now.
I've also added Mick Farrow's modified graphics as a run-time option.
I need to propagate the changes through to the Amiga and Neo Geo ports. The latter will be more fiddly as it will require the generation of another few thousand sprite tiles, but the tool is already there.
I realised recently it would (probably) be relatively trivial to add an Atari ST port - then I could add another target platform to my CV! I'm also still deciding whether I have the motivation left in me to attempt a Sega Genesis port as well, or whether I'm well-and-truly over Knight Lore by now.
Thursday, 14 April 2016
On optimisations
Over on the AtariAge forums, user mariuszw has been porting the ZX Spectrum version of Pentagram (the 3rd filmation title) to the 6502-based Atari 8-bit computers. He started with an automated translation of Z80 to 6502 which he got running but, not surprisingly, was too slow.
He has spent some time both profiling and analysing the code, and aside from actual pixel rendering has identified areas in the Z-order rendering logic that can be significantly optimised. I was aware that it took a rather brute force approach and that it spent quite a while in there, but was surprised to learn that the code can spend up to 40% of CPU time in that routine!
And to give some idea of the effect of these optimisations, one user observes that the code now runs as least as fast as the Spectrum version, if not slightly faster. And keep in mind that significant portions of the code are still implemented from the auto-translation process. Impressive!
The dilemma I face now is how far do I go with implementing any optimisations on the Coco3? The original intention was to port the game faithfully, warts-and-all. I have no issue rewriting the platform-specific portions of the game - such as rendering routines - but re-implementing the sorting logic encroaches on modifying the way the game works. You could argue that if it doesn't change the outcome (ie. the same objects are rendered each frame) then it's still the same, but the purist in me is struggling with that argument regardless.
Either way, I'll study the code for interest's sake, if nothing else, then make a judgement call. I guess more people are likely to play it if it runs smoothly, and won't really care what's going on underneath the hood.
He has spent some time both profiling and analysing the code, and aside from actual pixel rendering has identified areas in the Z-order rendering logic that can be significantly optimised. I was aware that it took a rather brute force approach and that it spent quite a while in there, but was surprised to learn that the code can spend up to 40% of CPU time in that routine!
And to give some idea of the effect of these optimisations, one user observes that the code now runs as least as fast as the Spectrum version, if not slightly faster. And keep in mind that significant portions of the code are still implemented from the auto-translation process. Impressive!
The dilemma I face now is how far do I go with implementing any optimisations on the Coco3? The original intention was to port the game faithfully, warts-and-all. I have no issue rewriting the platform-specific portions of the game - such as rendering routines - but re-implementing the sorting logic encroaches on modifying the way the game works. You could argue that if it doesn't change the outcome (ie. the same objects are rendered each frame) then it's still the same, but the purist in me is struggling with that argument regardless.
Either way, I'll study the code for interest's sake, if nothing else, then make a judgement call. I guess more people are likely to play it if it runs smoothly, and won't really care what's going on underneath the hood.
Wednesday, 13 April 2016
Back to C
I've managed to find and fix the three known bugs in the C port.
I expect there to be a few more as I continue testing.
I expect there to be a few more as I continue testing.
Subscribe to:
Posts (Atom)


