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.

Sunday, 29 June 2014

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.

Thursday, 26 June 2014

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...

Saturday, 21 June 2014

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!

Friday, 20 June 2014

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!

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.

Thursday, 19 June 2014

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.

Wednesday, 18 June 2014

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.

Tuesday, 17 June 2014

Today lunchtime and tonight I tackled the circular wipe function. I'm pleased to say that it's working in both 1BPP and 2BPP mode. Again, somewhat paradoxically, it's (slightly) faster in 2BPP mode.

It's not enough to simply draw concentric circles; that leaves gaps which give rise to the moiré patterns we so often marvelled at in our BASIC type-in listings. So you need to draw thicker circles to overwrite the gaps. Although three (3) pixels is sufficient in this case, in assembler it's a nightmare, and slow. So I settled on 4 pixels - or a whole byte in 2BPP mode - and I defy you to detect a difference with the original Apple version. In fact, I strongly suspect it's doing the same (I haven't reverse-engineered the actual function itself).

After some first-pass optimisations the 2BPP mode is about 15% faster than the Apple version, so I've left it at that. 1BPP mode is roughly the same speed. I won't bother throttling it at all because after a while it is actually a bit annoying (but all part of the experience).

That just leaves sound and high score load/save, before I add all the levels.

Memory is really tight; in fact the stack is perilously close to the data in the latest build. There's still a bit of shuffling and slight memory optimisation I can do, and I'm also considering revisiting the title screen compression. But all this can wait until after the beta.

Unfortunately I didn't get the chance to order my DriveWire cable components today. I'll endeavour to do so tomorrow.

Monday, 16 June 2014

Whilst I wait until I can get a DriveWire cable sorted, I've started looking at the circular wipe.

Tonight I was reacquainting myself with ECB (BASIC) graphics commands and prototyped the code, using Bresenham's circle algorithm (a.k.a. the midpoint circle algorithm). Straightforward stuff, and I don't see that it's going to be particularly troublesome in 6809 assembler. Looking forward to giving it a go, in fact!

Friday, 13 June 2014

After mucking about with 80 column text mode, the one last thing I wanted to do was grant myself the small honour of being the first to see Lode Runner running on a real Coco3 in glorious colour.

Given there are several ways to transfer a coco program to a real Coco - cassette, floppy or DriveWire to name a few - I figured it shouldn't be that difficult. So I gave myself a few hours off this afternoon and set up my Coco 3, which has been sitting on the shelf for a few years now.

The first hurdle was video display and, with no suitable monitors at hand, I hooked up my custom analogue RGB to DVI box that worked a few years ago. Except all I got out of it was a solid blue screen. With limited time, I abandoned that idea and instead hooked up the TV's composite input, a process that involved going out and buying some batteries for the remote since there was no other way to switch to AV mode. Finally, at least I had some manner of display.

Next step was the floppy disk drive. The drive I used last time - several years ago - clunked when selected but wouldn't spin up. Fortunately I had a stack of them on hand, but I was fast running out when the 4th one I tried finally sprung to life. Popped-in my (Sockmaster) Donkey Kong floppy that I wrote all those years ago, and it loaded! I had also acquired a pair of joysticks since then, and couldn't resist a quick play since I'd never been able to actually play it before - wow!

Last time I wrote Coco disks with a 5-1/4" floppy in my PC; that machine is now long-gone and the floppy drive whereabouts unknown at this point. I found a few PC floppy drives, but unknown capacities. A moot point though, because I soon discovered my office PC BIOS doesn't support floppy drives. Next option was to power-up a few of the old PC motherboards sitting out the back, but I was running short on monitors and the state of the few power supplies I'd found was dubious at best. It just wasn't looking like it was going to happen that way.

Next option, DriveWire,but I needed to boot-strap the driver. CLOADM (cassette) seemed to easiest option so I grabbed my cable and attempted to download via the WAV file from the PC. All I could manage was "BOOT FAILED", and gave up after 10 attempts. Then I remembered my custom cartridge PCB's; after powering-up the positively ancient laptop connected to the EPROM programmer and waiting 35 minutes for an erase, I managed to burn a copy into ROM (and subsequently found another with HDBDW (HDBDOS-DriveWire) written on it!). That resulted in "BOOT FAILED" again, though I suspected this time what I needed was a DriveWire server on the other end.

Unable now to find my DriveWire cable, I was scratching my head because I knew I'd used it before. In the end I gave up, and on the drive home I realised that I'd used it on Coco3FPGA running on the TerASIC DE1 board, so the cable was different anyway - Doh!

Last resort was converting the Lode Runner files to WAV files and then loading the via CLOADM. When I finally found a utility to convert Coco BIN files to cassette WAV, I was disappointed to discover that it wouldn't work with multi-segment BIN files, and Lode Runner is definitely multi-segment. As an experiment I tried one of my small files and it wouldn't work anyway. I was defeated.

So at this point I am unable to get Lode Runner across to my Coco3, without either setting up a PC with a floppy drive (my preferred option) or making up a DriveWire cable. So I'm afraid I'm going to take my bat and ball and go home (not release the Beta) until I've done so. Sorry!

Thursday, 12 June 2014

Found and fixed the 'last' bug! The demo runs through all three levels in lock-step, as far as I can ascertain with the naked eye. As I mentioned, it's pretty solid evidence that the game logic is spot-on.

The issue was an uninitialised zero-page register that is used in determining when to update (move) the guards. Not sure exactly where it's initialised in the Apple II code (perhaps the bootloader, or maybe not at all), but I had to add explicit initialisation to a single byte to bring it into sync with the Apple II version.

Interestingly, this byte is never re-initialised, so subsequent iterations of the demo mode - if interspersed with an actual game - may end with slightly differing results on the 3rd level. This has been confirmed on the Apple II version as well.

Right now the game is running slightly faster than the Apple II version, but still pretty close. I won't bother fine-tuning it yet because the sound code will change all of this again.

The 2nd beta release will likely be tomorrow (Friday AEST) now. Although I don't plan to do any more tweaks to the program itself, there are a few things I'd like to do before the release. One of those things is to get it up and running on my real Coco3 - something I haven't personally done yet.

That just leaves the circular wipe, sound, all 150 levels and (hopefully) high score load/save!

I found the bug I mentioned in the next-to-last post, namely the guard dropping the gold in the wrong place right at the end of the 3rd demo level. I actually found it quite quickly - yet another missing piece of code! Although guards always drop the gold when falling into a hole, they also drop them under other conditions - at least when the code to do so has actually been written! Doh!

So having fixed the "last" bug I fired up the demo's again side-by-side - only to notice that the guards were re-spawning in different places at the end of the 3rd level. Since the whole game is deterministic (otherwise the demo wouldn't run) this can only mean a bug in my port. Damn!

After an hour or two of debugging I've discovered that the game state is out of sync somewhere in the first demo level, between the time the 1st guard is killed to the time the 2nd is killed. I know this because the re-spawn column, which is incremented every main in-game loop, is wrong for the 2nd guard. This can only be the case if the guard movements (guard state update) are inaccurate. Further debugging reveals that the state of the 3rd guard is wrong by the time the 2nd guard is killed.

Further debugging has thus far been fruitless but I'm yet to exhaust all avenues - it's just very, very late now and time to get to bed. One area of possibility I've yet to explore is the AI... and I'm not looking forward to that. So I'll continue when I next get the chance.

The one positive to come out of all of this is that, by the time I've found this bug, I can be 99.9% sure that all of the game logic has been ported accurately. The demo mode has been an invaluable tool in that regard!

Wednesday, 11 June 2014

I thought I'd upload a quick video showing what I've been working on, including centering the display (thanks Jason) which I neglected to mention in the last post.

Note the centering of the display, the GAME OVER animation, and the high score initials entry.

And if for some reason you still prefer the monochrome graphics, they're still supported.

Hopefully I'll be in a position to release the final beta later tonight (AEST time).

EDIT: This morning I've been fine-tuning the 2BPP game speed and running it side-by-side with the Apple II. I've noticed that the demo seems to be running lock-step until right at the end of the 3rd level, just as the guards get to the top of the ladder... so there can't be too much amiss?!?

The most glaring was the fact that I was initialising the user stack, instead of the system stack (cut-and-paste error) which would eventually (due to the other bugs) overwrite the zero-page variable area and cause all sorts of issues - and almost certainly explains the crash and corruption reported by Keith! Yah!

I also noticed that the stack was ever growing downwards as I cycled through several games; by three (3) bytes if I obtained a high score, and two (2) if I didn't. In the high score entry routine I was pushing B onto the stack to juggle the 6502 registers, and branched over the pull in some instances. That explained the 3rd byte.

The other two bytes were a mystery, until I noticed that the high score entry routine was called from the main loop, but jumped back to it! A quick test on the Apple II version under the MESS debugger confirmed that the original version has the same bug! But because of the circular nature of the 6502 stack, I suspect it never manifests itself as an actual bug in the game. A different story of course on the 6809, hence the aforementioned overwriting of the zero-page area. I fixed it by pulling the extraneous two bytes from the stack before jumping back to the main loop.

All that remains now before the next beta release is a curious inconsistency that I noticed a week or so ago but ignored until now. It may occur elsewhere but where I noticed it was right at the end of the 3rd demo level, where the guard on the Coco3 version drops the gold on a different square than on the Apple II version. Perhaps related is the slightly different spawn-point of another guard and slightly different ending to the demo. I'm not sure at this point how difficult this will be to track down... it's subtle but of course does affect the accuracy of the game-play!

But the good news is that the only other features left incomplete are the circular wipe function, high score load/save, all 150 levels, and the sound. Everything else is there and running - and in 128KB (not 512KB as was required for the first beta)!

Taking another quick look at the circular wipe code today, I'm almost certain that I won't attempt to port it from the 6502 code, but rather write my own. And for the high score load/save, I've had an idea that utilises the task-switching capabilities of the Coco3 GIME that should allow me full access to the DECB ROM (and therefore the disk routines) relatively easily. That just leaves sound.

Monday, 9 June 2014

Tonight I finally got the colour mode working - or at least I think it's working with the limited testing I've had time to do. I've literally seen it running for about 4 minutes and it's time for bed!

Turns out the complexities of the Apple II artifacting introduce subtleties that aren't immediately apparent when you're trying to reproduce it on a 4-colour display. I first noticed this when I got to the stage where my 2BPP rendering routines should have produced a faithful static display - yet I had gaps between my brick tiles.

After chasing red-herrings for a while it occurred to me that the tile data I had imported wasn't quite right - the bricks, for example, were only 9 pixels wide, not 10. So I went back to the MESS algorithm in my import routine, and deduced that the root cause was the fact that the artifacting is dependent on the bytes following the pixel in question! Because I was rendering single tiles in isolation, the artifacting algorithm wasn't producing the 10th blue pixel on my bricks.

I subsequently modified my import routine to render two (2) of each tile next to one-another, and lo-and-behold the gap disappeared! After (eventually) realising that I had to wipe the 2nd tile before importing the tile data, I finally had no gaps in the bricks and the graphics all looked, as far as I could tell, correct.

On this point, it is actually impossible to 100% accurately render the artifacting, because bricks adjacent to gaps or ladders or ropes are actually rendered only 9 pixels wide on the Apple II, whilst adjacent bricks are 10 pixels wide. It's also somewhat evident via the gaps next to the ladders. However, the effects are so subtle that they're practically undetectable, and they certainly have no bearing on game-play what-so-ever.

Similarly, there's some fringing effects on the guard and player sprites; however for the most part they are identical to what gets produced on the Apple II (according to MESS at least), except for complex interactions with multiple guards and backgrounds etc, and even then, they're subtle and again, have no bearing on game-play.

Overall, I'm very happy with the colour version and it certainly captures the look and feel of the Apple II version. And after several months of play-testing the monochrome version which, incidentally is the version I'm traditionally familiar with, it does look quite a bit nicer!

I'll do a bit more testing, and I want to attempt to centre the screen and also add the high score initials entry (tedious but trivial) before I release the next beta demo. That will probably be the last beta before the full release, which will include sound.

This is also somewhat fortuitous because the title screen data has increased in 2BPP
mode, and now it fits without having to beef up the compression.

I've imported the 2BPP mode tile data and hacked the rendering routines just enough to get the left-most 16 pixels of each tile displayed. Results below:

WIP modification of the rendering routines for 2BPP mode

The remainder of the modifications to the rendering shouldn't take too much time - I've already been through this with the TRS-80 Model 4 (Z80) port when implementing the pixel-doubling, which is actually equivalent from a memory-usage perspective.

At this rate I might even have the next beta - in colour - available for release in a few days!

Friday, 6 June 2014

I took a look at the MESS Apple II video driver, and discovered that the artifact emulation (and there's no way of knowing exactly how accurate that is) is definitely more complicated than my quick 'n' dirty on-the-fly conversion.

So with this knowledge in mind, I hacked the MESS algorithm into my graphics conversion utility and managed to produce colourized versions of the title and tile graphics. Unfortunately the 2BPP title data is slightly larger than I bargained for, so I'll need to find a better compression algorithm, but that's for later. Here's the new colour title screen running on the Coco3, which in theory is identical to that rendered in the MESS Apple II driver:

4-colour title screen - in theory identical to Apple II display

And here is a screenshot from my utility, showing the original and colourized tile graphics:

The monochrome and 4-colour tiles, ready for import

So I now generate three (3) variations of the Lode Runner graphics; 1BPP and both monochrome and 4-colour 2BPP formats. I can build any variation simply by commenting (or not) each of a pair of .define statements.

The other area I've been working on today is the generation of the graphic data .BIN file. With thanks to Jason Law, I have a single .BIN file that contains the title and tile graphics data, that is generated not from binary data but in fact assembled from source .db statements. No more generating segments and binary data from a utility; Jason pointed out that it could all be done with .org statements in a single .ASM file! It also means that the memory map (including the graphics data addresses) can be defined in a single location in the source file - which of course is easy to tweak now!

Jason has also been hacking my code (in a good way) and has advised me on how to center the display on the Coco screen, and also get the code running on a 128KB machine. I'll be implementing his suggestions soon!

But for now, I need to finish the 4BPP tile import and then update the rendering routines to suit.

[And on this note, I've realised that the 4BPP mode will, in fact, affect the collision-detection algorithm used by Lode Runner. That's because I'm actually adding pixels to emulate the artifacting on the Apple. However, I would claim that it will not have any significant impact on the game-play.]

Firstly, I've ported the GAME OVER spinning animation. It was quite straightforward (although I had to convert the graphics format) but it looks pretty cool. Curiously enough, achieving a high score means you don't get to see the animation!

A few other fixes and enhancements; added support for the game freeze (pause) function, and fixed the key debounce on the extra life cheat and a few other CTRL key commands. I also added support for the Coco arrow keys, and also the Z & X keys for digging.

In preparation for colour mode, I've re-arranged the memory map to accommodate the larger screen memory required. To do so, I had to relocate the program code from $4000 to $8000, and the graphics data from $8000 to $C000. This presented a new challenge for me - how to load code at $8000, over the BASIC ROM.

I may have mentioned that you can load segments of a BIN file into arbitrary memory banks by having the previous segment load directly into the MMU bank registers to switch them into the 6809 address space. This is the method I've been using to load the graphics data into high memory, by writing a small utility to effectively wrap a custom .BIN file format around the raw binary data.

With the program code, however, the linker already produces a .BIN file which loads at $8000 - as I mentioned - directly over the BASIC ROM. So I wrote another small utility that relocates the .BIN file to an area of empty RAM, prepends a segment to set up the MMU bank registers accordingly, and finally appends a small loader that simply switches in the previously loaded memory pages and then jumps to the Lode Runner main program. The end result is a single binary that can load itself (effectively) over ROM.

With that working, I could turn my attention to implementing actual colours. Since I've been toying with the idea of reverting the title screen graphics data to the original 7-bit format to save some memory, I decided that I would (also) convert the graphics on-the-fly from 1bpp monochrome to 2bpp colour. After some preliminary investigation into how the Apple II colour artifacting actually works, I modified the (still 8-bit) title display routine to display 4 colours.

4-colour title screen generated on-the-fly from the original Apple II data

Not a bad result but the artifacting around the white characters is clearly emphasised, and doesn't gel with the results in MESS. I will probably need to do more thorough research, but it's a pretty good result for what amounts to a few dozen lines of assembler.

I should also note that I am preserving the ability to build 1bpp (mono), 2bpp (mono) and 2bpp (colour) versions of the game - all via .define directives. I could in theory use the same method to (inefficiently) generate the in-game graphics on-the-fly for the 4bpp modes, but there's probably little point. So my next task will be to produce 4bpp mono and colour versions of the tile data and update the rendering routines accordingly. I shouldn't imagine this will be particularly difficult, providing the colour generation falls out easily.

Once I have colour working I'll (hopefully) be able to add some more levels and release a new Beta.

Finally, there is a report of the game crashing (twice) in VCC. At this point I don't have a lot to go on so please, if you do get a crash under emulation, I'd be interested in a screenshot (if there's any corruption) at least. And if you happen to be running it under the debug build of MESS, a full dump (SAVE) of the memory space would be much appreciated!

Tuesday, 3 June 2014

The remaining 'collision-detection' bug turned out to be a typo and also missing code from the end of a routine! I normally add a place-marker for code that is yet to be ported, but I'd obviously neglected to do so in this case.

The missing code in question, which amounted to just a handful of lines, is particularly interesting because unlike the rest of the collision-detection code which uses the logical playfield, it actually inspects pixels rendered during the draw_player_sprite() routine. This will have ramifications for ports to sprite-only systems, like the Neo Geo, and will likely require that the port maintains the bitmap screens in system memory even though they aren't used for the actual display.

Here's a video of the demo mode running for the 1st level:

That aside, the end result is that Lode Runner is now complete in the sense that it is 100% playable on the Coco 3. There are a few bells and whistles that have yet to be ported, so whilst I work on those I thought I'd release a playable demo for beta testing.

Please read the included README.TXT file before submitting any comments, suggestions and/or bug reports, but feedback is most welcome.

Today I worked on implementing the game speed throttling accurately. The speed throttling is interleaved with the sound routines in order to maintain a constant speed; until I add the Coco 3 sound routines it's not going to be 100% accurate. But it's quite close anyway and certainly more than good enough for a beta release.

I also added a few of the easier-to-code missing features, such as high score table, update and (non-destructive) display. The only part missing is the initials entry - they stay blank for now - and of course load and save.

I also fixed the graphical glitch when digging is interrupted by a guard.

That just leaves one (that I'm aware of) niggly bug which I'll address next session; namely the 'collision detection' isn't consistent with the original. It's all done on the logical board, not the graphics screen, so it shouldn't be too difficult to track down.

Once I'm satisfied that there's no latent bugs, I'm intending on releasing a playable beta demo release that will feature the first 5 levels. The beta will otherwise be completely playable, albeit monochrome without the circular wipe and game over animations, sound and high score initials entry. The release will hopefully encourage people to help me play-test, and also whet people's appetite whilst I'm finishing up the port.

I've also tentatively added the scoring support for Championship Lode Runner which I believe is almost identical to the original, aside from the ability to enter messages on the high score list. I'll probably stay true to the original format and release the two variants separately.

I'm also seriously considering (again) releasing it in cartridge form. It would be nice to have something tangible for the Coco, but the cartridge case is the real stick-in-the-mud. Do I take the path that others have in the past for other platforms, and do a limited run using sacrificial carts?

Sunday, 1 June 2014

Fixed another 3 bugs; 2 in the AI and another in the guard re-spawn routine. In one case I hadn't flipped a BCS/BCC when translating, the other two I didn't realise that SEC, SBC actually performed a subtraction without borrow on the 6502! Why did they invert the Carry flag???

The guard AI is so close now I can't even say for sure that it's not complete and accurate. The game is certainly playable and seemingly just as challenging as the Apple II version.

What is throwing things a little off atm is the speed of the guards. It's telling on the demo screen that the guards do choose the correct path, but lag behind the Apple II somewhat and as a result the demo doesn't play properly. I implemented the guard speed logic in haste the other night so I guess it's time to go back and verify that.

Back to the 4-colour mode; I think I've deduced that it won't be possible to emulate both mono and colour modes with the same tile data. I've not sat down and thought it through properly either way yet, but I'm pretty sure I've reached the right conclusion here. No matter...