Sorry George, couldn't come up with one tonight. :(
What I have been able to do, however, is finish porting the guard AI logic to C. It's finished in the sense that I have no more lines to port - not in the sense that I have finished debugging. That said, it looks close and I certainly found it challenging enough to play in my 2-minute test. There's a chance I guess that the AI is actually spot-on - it's symmetric to a degree and it's much easier to see inconsistencies and certain other types of bugs in C.
In the process I actually found a (subtle) bug in the AI logic of the 6809 port. In a nutshell this bug means that the Coco 3 version is ever so slightly easier to play than the original when the player is on the very top row of the screen. I've fixed it but am yet to perform any testing on the Coco itself.
Speaking of bugs; I had to go out of my way to implement the AI bug that I documented in my blog some time back, but it's there now so the C version is still faithful to the original.
Once I've sorted any AI bugs that leaves the high score entry (trivial), the GAME OVER animation (also trivial but somewhat tedious) and the oft-maligned circular wipe effect. It turns out that I tackled the C port in pretty much the same order as the 6809 translation.
I've decided to tackle the Neo Geo port (in C) next, if only to verify my hardware abstraction and also my proposed sprite hardware extensions to the code. If all goes well, I should be able to knock this over (at least implement a playable game) in a week or so. I'm not so concerned about the bells and whistles on the Neo Geo at this point.
Depending on how that goes, I might then look at another quick C port - the Amiga!
Finally then I'll return to the Coco 3 for a full-featured release before putting Lode Runner to bed for a while and starting on another game altogether.
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.
Thursday, 3 July 2014
Sunday, 29 June 2014
Quick Sunday night update
Nothing too exciting to report. Still working on the C version; working on it in blocks of 15 or 30 minutes when I get the chance. Just finished the guards moving around, which only leaves a bit more of the guard mechanics - getting trapped and re-spawning - before tackling the AI. That then just leaves the sundry bells and whistles to round out the finished product!
In the back of my mind I've been thinking of how to implement this on a tilemap/sprite system, and I think I've got a pretty good idea now. It should be a simple matter of passing through a sprite index - player or guard number - to the generic sprite render routines. Bitmap-only systems can ignore that index, whereas sprite-based systems will use it to update the appropriate hardware sprite. It definitely helps to write the logic in a (slightly) higher-level language to see things a little more clearly.
This all has me wondering now about the best approach for future ports. Early on in the 6809 port process the only option I'd considered was repeating the whole hand-translation exercise for the 68K. A colleague then suggested an automated static translation which piqued my interest. Now I'm wondering whether a direct C translation would do more to assist even in subsequent assembler ports?
Anyway, it remains to be seen how easily the C port can be adapted to, and how well it performs on, systems like the Neo Geo and/or the Amiga. I consider these more academic exercises than anything else; I'm not sure there's much interest in Lode Runner on either platform these days. What's more important for me is that I learn something from the process.
In the back of my mind I've been thinking of how to implement this on a tilemap/sprite system, and I think I've got a pretty good idea now. It should be a simple matter of passing through a sprite index - player or guard number - to the generic sprite render routines. Bitmap-only systems can ignore that index, whereas sprite-based systems will use it to update the appropriate hardware sprite. It definitely helps to write the logic in a (slightly) higher-level language to see things a little more clearly.
This all has me wondering now about the best approach for future ports. Early on in the 6809 port process the only option I'd considered was repeating the whole hand-translation exercise for the 68K. A colleague then suggested an automated static translation which piqued my interest. Now I'm wondering whether a direct C translation would do more to assist even in subsequent assembler ports?
Anyway, it remains to be seen how easily the C port can be adapted to, and how well it performs on, systems like the Neo Geo and/or the Amiga. I consider these more academic exercises than anything else; I'm not sure there's much interest in Lode Runner on either platform these days. What's more important for me is that I learn something from the process.
Thursday, 26 June 2014
C-ing things clearer
I've been working on the Lode Runner C port rather than tackle the disk issues on the Coco3... thought I'd let people do some beta-testing for me whilst I psych myself up to finish it.
My weapon of choice is the Allegro graphics library on Windows 7, only because I'm familiar with it. As it turns out, it's looking like it's not quite suited to the task - or perhaps more likely I can't drive it properly. Attempts to create a virtual screen for page flipping (yes, I know it's frowned upon) have resulted in crashes. But I can hack enough to see both screens at once. There are also sprite issues with ugly hacks atm.
As I am interested in preserving the 'style' of the original implementation, I've used more goto's in this one piece of code than I have in my entire history of C programming up until this point. Most of the code can be implemented in functions, but the higher-level routines are sufficiently convoluted that any attempt to structure them will invariably result in subtle differences in behaviour - not to mention no longer resemble the original code. In any case, there's only a few routines with goto's but each of those few use them quite liberally.
The rest of it hasn't been too painful up until this point. I know it's second-time around for me, but some of the routines that took me a few hours to port to 6809 have taken me a few minutes in C! Debugging with printf also tends to be quicker than setting breakpoints and watchpoints and inspecting memory dumps in the MESS debugger too!
The title and high score screens are there. I have the player running, swinging, climbing, falling & digging and the holes fill themselves in. The player can collect gold and progress to the next level. The demo runs too, but without the guards it doesn't get very far before the player is trapped. Deja vu.
Along the way I've attempted to implement an OS-dependent layer so that the core code should never have to be modified when porting to other platforms. Not surprisingly this entails the graphics, keyboard and sound routines.
I've probably got another week or two on this before it's finished. Aside from the mechanics of moving the guards, there's the guard AI on which I'll try to spend the most time crafting the C implementation. I'm hoping that this will serve to (better) document the core game implementation. I should also note that during the course of the C port, the purpose of both code & variables in a few places has become clearer; I'll have to go back and re-annotate the 6502 & 6809 code.
Once that's done I'll probably have a go at a Neo Geo implementation - or at least get the game running - before I get back to the final Coco3 release. At this point I'm not sure how I'm going to handle the bitwise collision-detection on that platform, but I'm sure I can conjure up something. A colleague has also thrown down the gauntlet, challenging me to get the circular wipe working on the Neo Geo. It won't be pretty, but I'll have a crack at it.
I'm also getting calls to resurrect my ill-fated arcade Tutankham port to the Coco3. The port consisted of patches to the original ROM image, which resulted in the game actually running on the Coco; you could coin up and play a game. Too bad the screen was rotated and there was no scrolling implemented. It's a tough call...
My weapon of choice is the Allegro graphics library on Windows 7, only because I'm familiar with it. As it turns out, it's looking like it's not quite suited to the task - or perhaps more likely I can't drive it properly. Attempts to create a virtual screen for page flipping (yes, I know it's frowned upon) have resulted in crashes. But I can hack enough to see both screens at once. There are also sprite issues with ugly hacks atm.
As I am interested in preserving the 'style' of the original implementation, I've used more goto's in this one piece of code than I have in my entire history of C programming up until this point. Most of the code can be implemented in functions, but the higher-level routines are sufficiently convoluted that any attempt to structure them will invariably result in subtle differences in behaviour - not to mention no longer resemble the original code. In any case, there's only a few routines with goto's but each of those few use them quite liberally.
The rest of it hasn't been too painful up until this point. I know it's second-time around for me, but some of the routines that took me a few hours to port to 6809 have taken me a few minutes in C! Debugging with printf also tends to be quicker than setting breakpoints and watchpoints and inspecting memory dumps in the MESS debugger too!
The title and high score screens are there. I have the player running, swinging, climbing, falling & digging and the holes fill themselves in. The player can collect gold and progress to the next level. The demo runs too, but without the guards it doesn't get very far before the player is trapped. Deja vu.
Along the way I've attempted to implement an OS-dependent layer so that the core code should never have to be modified when porting to other platforms. Not surprisingly this entails the graphics, keyboard and sound routines.
I've probably got another week or two on this before it's finished. Aside from the mechanics of moving the guards, there's the guard AI on which I'll try to spend the most time crafting the C implementation. I'm hoping that this will serve to (better) document the core game implementation. I should also note that during the course of the C port, the purpose of both code & variables in a few places has become clearer; I'll have to go back and re-annotate the 6502 & 6809 code.
Once that's done I'll probably have a go at a Neo Geo implementation - or at least get the game running - before I get back to the final Coco3 release. At this point I'm not sure how I'm going to handle the bitwise collision-detection on that platform, but I'm sure I can conjure up something. A colleague has also thrown down the gauntlet, challenging me to get the circular wipe working on the Neo Geo. It won't be pretty, but I'll have a crack at it.
I'm also getting calls to resurrect my ill-fated arcade Tutankham port to the Coco3. The port consisted of patches to the original ROM image, which resulted in the game actually running on the Coco; you could coin up and play a game. Too bad the screen was rotated and there was no scrolling implemented. It's a tough call...
Saturday, 21 June 2014
lode_runner.c
I've had enough of hardware bashing for one day so tonight I started work on writing a C implementation of Apple II Lode Runner. There will be a hardware abstraction layer so that it is as portable as possible. I'm hoping I'll be able to port this to the Amiga or the Neo Geo without going through the pain of producing a 68K assembler translation.
The purpose is two-fold; to assist in the understanding and documentation of the original implementation (specifically the guard AI) and also facilitate ease of porting to more platforms.
To this end, the aim (again) is to preserve the style and nuances of the original code as far as possible, to the extent that it doesn't cloud the more interesting aspects, such as the AI. For instance I'll be retaining the bulk of the zero-page variables - although some data types will be changed, such as the score, which will go from four (4) BCD bytes to a single uint32_t. Similarly the rendering routines are considered to be uninteresting and in any case will be abstracted away from the main code.
Thus far I have it displaying the title screen, waiting for a key, and then starting to render the game screen for the demo. All this in about an hour; a bit faster than writing - or even porting - assembler code!
The purpose is two-fold; to assist in the understanding and documentation of the original implementation (specifically the guard AI) and also facilitate ease of porting to more platforms.
To this end, the aim (again) is to preserve the style and nuances of the original code as far as possible, to the extent that it doesn't cloud the more interesting aspects, such as the AI. For instance I'll be retaining the bulk of the zero-page variables - although some data types will be changed, such as the score, which will go from four (4) BCD bytes to a single uint32_t. Similarly the rendering routines are considered to be uninteresting and in any case will be abstracted away from the main code.
Thus far I have it displaying the title screen, waiting for a key, and then starting to render the game screen for the demo. All this in about an hour; a bit faster than writing - or even porting - assembler code!
Friday, 20 June 2014
Apple II Lode Runner for the Coco 3 Beta 2 available
Today I finally got to see Lode Runner on my real Coco 3 - and not the way I expected to, either. Still waiting for the DriveWire cable 4-pin connector to turn up (I only ordered it yesterday), I realised late last night that I should be able to get it running from cartridge!
I spent a few hours last night re-arranging the memory map, getting it ready for cartridge release. After a few false starts, by today lunchtime I was able to get it running under MESS. The secret is to have the cartridge copy itself into RAM, and then switch into all-RAM mode, so that there's enough RAM to run the game. The added bonus is that the same build also runs from floppy disk!
Unfortunately I still don't have my analogue-to-DVI converter up-and-running, so I've had to make do with an old television set. After learning about RGB vs composite palettes and burning another EPROM, this is what I saw:
Along the way I've added enhancements to the graphics handling; you can switch between RGB and composite palettes for colour mode and green or white screens for monochrome mode, on-the-fly.
I should add that I haven't fine-tuned the game speed yet, but it should be close!
The beta archive comprises a floppy disk image that contains both monochrome and colour versions. I've also included the ROM image for anyone who wants to burn their own EPROM or flash it into a SuperIDE controller or similar - it requires 32KB cartridge emulation.
Now to the final release...
I spent a few hours last night re-arranging the memory map, getting it ready for cartridge release. After a few false starts, by today lunchtime I was able to get it running under MESS. The secret is to have the cartridge copy itself into RAM, and then switch into all-RAM mode, so that there's enough RAM to run the game. The added bonus is that the same build also runs from floppy disk!
![]() |
| The world's first Apple II Lode Runner for Coco 3 game cartridge! |
Unfortunately I still don't have my analogue-to-DVI converter up-and-running, so I've had to make do with an old television set. After learning about RGB vs composite palettes and burning another EPROM, this is what I saw:
![]() |
| Somewhere in the junk pile is a Coco 3 running Apple II Lode Runner from cartridge |
Along the way I've added enhancements to the graphics handling; you can switch between RGB and composite palettes for colour mode and green or white screens for monochrome mode, on-the-fly.
I should add that I haven't fine-tuned the game speed yet, but it should be close!
The beta archive comprises a floppy disk image that contains both monochrome and colour versions. I've also included the ROM image for anyone who wants to burn their own EPROM or flash it into a SuperIDE controller or similar - it requires 32KB cartridge emulation.
Now to the final release...
Thursday, 19 June 2014
Sound at the end of the tunnel
I squashed the aforementioned sound bug this lunchtime.
Phew! This brings me to a major milestone now - the port is basically complete! I need to add the rest of the levels, and the high score load/save, but these are more an exercise in memory management and interfacing with the Coco 3 disk I/O routines than a porting exercise.
And there is still an issue with DAC sound output affecting keyboard input I need to resolve, but for now the 1-bit sound output is perfectly adequate.
I've done a little more quick 'n' dirty hacking for the beta release, to support both monochrome and colour versions on the same disk, and also allow the choice of green or white (for NTSC artifacting via composite output). These will be tidied up for the real release.
I've been thinking about what to work on next. I have a few ideas for more games that can be ported to the Coco3 - including more Apple II and also some Spectrum titles - as well as an interesting proof-of-concept for the Coco3 that wouldn't necessarily result in a playable game in the short term, but is exciting none-the-less. I also have other targets in mind, and will probably work on both Donkey Kong and Lode Runner Neo Geo ports in the immediate future.
Stay tuned!
Phew! This brings me to a major milestone now - the port is basically complete! I need to add the rest of the levels, and the high score load/save, but these are more an exercise in memory management and interfacing with the Coco 3 disk I/O routines than a porting exercise.
And there is still an issue with DAC sound output affecting keyboard input I need to resolve, but for now the 1-bit sound output is perfectly adequate.
I've done a little more quick 'n' dirty hacking for the beta release, to support both monochrome and colour versions on the same disk, and also allow the choice of green or white (for NTSC artifacting via composite output). These will be tidied up for the real release.
I've been thinking about what to work on next. I have a few ideas for more games that can be ported to the Coco3 - including more Apple II and also some Spectrum titles - as well as an interesting proof-of-concept for the Coco3 that wouldn't necessarily result in a playable game in the short term, but is exciting none-the-less. I also have other targets in mind, and will probably work on both Donkey Kong and Lode Runner Neo Geo ports in the immediate future.
Stay tuned!
Wednesday, 18 June 2014
Sound advice
I've ported the sound code to 6809 and after deafening silence last night, managed to elicit sound from the Coco speaker today. Since I'm porting the Apple II's 1-bit sound, I actually have the choice of using the Coco's 1-bit sound output, or the 6-bit DAC. For now, I support either (at build time).
As it stands without any debugging, the sound of the player falling already sounds more-or-less correct. Since the PWM is done in a tight loop, it's all critically dependent on the CPU speed and cycle counts, and without tweaking the values (or the routine) it's invariably a different pitch - slightly higher on the Coco. When it's all debugged, I'll evaluate my options for fine tuning this and see where it goes. Other - more complex - sounds wreak havoc with the game speed atm, but I haven't even started debugging yet.
The sound routines consist of playing back a series of notes (frequencies) each with an associated duration. The durations are specified in absolute time, rather than multiples of the frequency, making 'composing' and game speed tweaking a little easier. And here-in lies a bug that had me scratching my head for a while until I worked out what was going on...
The duration is actually a multiple of 256 iterations of the sound bit-bash loop. The routine to play the sound uses the 6502 Y register to count these 256 iterations before decrementing the duration. The issue is, the Y register is not initialised in the routine and starts with what is effectively a random value. This means that the first count of the duration is - on average - shorter and results in a wrong sum duration for the note. Obviously the relative error is dependent on the note's duration.
Anyway, I decided to retain the bug in the 6809 port, although the randomness of the error will differ given the differences in implementation (Y register vs direct-page register) but you likely will never hear it.
Hopefully tonight I'll get a chance to debug the rest of the sound. The main difference between the falling sound and other sounds is that the former plays a single note at a time, whereas the latter queues a series of notes to be played in a sound buffer. Subsequently the latter implements a different algorithm to adjust the game speed for the sound and I would suspect that this is the source of the bug since the game 'stutters' when a sound (other than falling) is played.
UPDATE: The sound has been debugged, except for a start-up issue where the queued sound has an extraneous note on the end. It seems to disappear permanently as soon as a note (as opposed to a multi-note sound) is played. I suspect the sound queue isn't initialised properly, but it's too late to track it down. Tomorrow...
That aside, it's sounding pretty good. The Apple II Lode Runner sound was never going to win any awards - being little more than beeps and trills - so I'm happy enough with the port even without adjusting the pitch. So I guess the next beta will be the full release just without 150 levels or high score load/save. These have been left to last because they present a challenge, and also will have completely different solutions for floppy disk and (if it happens) cartridge releases.
It would then take me a day to do a Championship Lode Runner release.
As it stands without any debugging, the sound of the player falling already sounds more-or-less correct. Since the PWM is done in a tight loop, it's all critically dependent on the CPU speed and cycle counts, and without tweaking the values (or the routine) it's invariably a different pitch - slightly higher on the Coco. When it's all debugged, I'll evaluate my options for fine tuning this and see where it goes. Other - more complex - sounds wreak havoc with the game speed atm, but I haven't even started debugging yet.
The sound routines consist of playing back a series of notes (frequencies) each with an associated duration. The durations are specified in absolute time, rather than multiples of the frequency, making 'composing' and game speed tweaking a little easier. And here-in lies a bug that had me scratching my head for a while until I worked out what was going on...
The duration is actually a multiple of 256 iterations of the sound bit-bash loop. The routine to play the sound uses the 6502 Y register to count these 256 iterations before decrementing the duration. The issue is, the Y register is not initialised in the routine and starts with what is effectively a random value. This means that the first count of the duration is - on average - shorter and results in a wrong sum duration for the note. Obviously the relative error is dependent on the note's duration.
Anyway, I decided to retain the bug in the 6809 port, although the randomness of the error will differ given the differences in implementation (Y register vs direct-page register) but you likely will never hear it.
Hopefully tonight I'll get a chance to debug the rest of the sound. The main difference between the falling sound and other sounds is that the former plays a single note at a time, whereas the latter queues a series of notes to be played in a sound buffer. Subsequently the latter implements a different algorithm to adjust the game speed for the sound and I would suspect that this is the source of the bug since the game 'stutters' when a sound (other than falling) is played.
UPDATE: The sound has been debugged, except for a start-up issue where the queued sound has an extraneous note on the end. It seems to disappear permanently as soon as a note (as opposed to a multi-note sound) is played. I suspect the sound queue isn't initialised properly, but it's too late to track it down. Tomorrow...
That aside, it's sounding pretty good. The Apple II Lode Runner sound was never going to win any awards - being little more than beeps and trills - so I'm happy enough with the port even without adjusting the pitch. So I guess the next beta will be the full release just without 150 levels or high score load/save. These have been left to last because they present a challenge, and also will have completely different solutions for floppy disk and (if it happens) cartridge releases.
It would then take me a day to do a Championship Lode Runner release.
Subscribe to:
Posts (Atom)

