Wednesday 30 April 2014

Nothing to see here...

A severe lack of time and the arrival of new PCB's for my NGPACE project has seen very little progress on Lode Runner since my last post.

I have, however, spent a little time attempting to identify and isolate the player movement code but have only come to the conclusion that I really do need to invest more time on reverse-engineering the original code before I'm going to have much success on that front. So for now, those plans are on the back-burner until I have done exactly that.

What I may do in the mean-time, however, is take a look at porting the circular wipe function to the Coco3 (6809) at least. I'm still yet to implement the dual hires pages on either port, although on the Coco3 it should be quite straightforward, and I have already reserved the RAM for the 2nd page. At least it'll force me to do that much, and if it's not too much work, it'll look pretty cool!

Whilst my focus is primarily on the NGPACE project now that it's moving ahead, the beauty of this project is its suitability to working in small bursts that would otherwise be fruitless for work on the NGPACE designs. It's also easier to work on-the-go, and doesn't require the daily transport of hardware between home and the office.

I also feel a Neo Geo port is imminent... ;)

Saturday 26 April 2014

Level 1 - 6809 style

The Coco3 (6809) port is now up-to-date with the Z80 version.

Level 1 on the Coco3

I must admit that this exercise is a real eye-opener for me; a die-hard Z80 fan for 35 years! I'm starting to really appreciate the 6809, in particular the indexed addressing modes and the instructions that support them. A few table-lookups that are down-right painful in Z80 require just a few lines of 6809... I'm afraid that I'm starting to prefer it over the Z80. Add the fact that the Coco3 graphics are bit-mapped and interleaved with CPU accesses, and I'm starting to enjoy the Coco3 port a lot more than the TRS-80 Model 4. And to think it was an after-thought!

Now to start on the code to move the player around the screen. I'm fairly certain that the same code is used to move the baddies as well, as I recall that they're essentially the same graphic, but striped to display as different colours to the player. So that should be a reasonable chunk of the game-play mechanics!

Incidentally, that would also bring it up to the point that I had my own version 'complete' on the TRS-80 Model 4 about 25-30 years ago!

The idea of adding a Neo Geo port is still nagging at me, especially since we just received some PCB's for my Neo Geo hardware project (see my other blog)! It's especially attractive because it would be almost a direct line-by-line translation of the 6502 (if I decided to go that way) plus all the rendering logic would be irrelevant! It would take me some time to set up all the tiles, but once that was done the code to bring it up-to-speed with the TRS-80 & Coco3 ports would be almost trivial!

Wednesday 23 April 2014

Level 1

I've re-thought my porting strategy slightly, and decided to 'emulate' the 6502 zero-page registers using the Z80 index register (specifically, IX). This allows a more congruent line-by-line port without juggling Z80 registers with the accumulator for zero-page access; the indexed addressing instructions work with most of the Z80 registers. The only caveat is the signed offset; if I'm careful that shouldn't be an issue.

For the 6809 I'll use the DP register for the same purpose.

I've defined some macro's in the Z80 code in case the whole IX thing doesn't work out, however it's looking pretty good so far. It allows me to use (Z80) A, B & C for (6502) A, X & Y respectively for zero-page operations with a 1:1 correspondence between the code bases.

After adjusting for the above I started work on coding the level display routine(s). I've hard-coded the level 1 data in the 'disk buffer' and coded the unpack and display routine. The latter was cut-down just to get something on the screen, and after fixing a few bugs in the pixel-doubling routine which didn't reveal themselves when displaying alphanumeric characters (due to their striped nature) I was greeted with this:
Level 1 - TRS-80 Model 4

Between the convoluted 6502 code and the on-the-fly pixel-doubling, it's a bit slow but at least it looks the real deal! I'll stop at this point and bring the Coco3 (6809) code up-to-date.

Tuesday 22 April 2014

Double-buffered displays

I decided to press on with reverse-engineering the level display, with the intention of implementing it on the TRS-80 Model 4 (Z80), before bringing the Coco3 (6809) port up-to-date.

To this end, I have now commented the level display routine; from where it copies and then unpacks the data from the disk buffer, to the famous circular wipe as it renders the level to the display. I should note that I have identified, but not commented, the actual circular wipe routines (although I can tell you it draws a total of 170 concentric circles). I have also completely ignored the Apple II disk routines, as they are completely irrelevant to the port (and not very interesting either).

I did know that Lode Runner utilised both hires pages, and long suspected that this was integral to the circular wipe function. What I didn't know, but have now learned, is that the game itself uses both pages in a form of double-buffering. More specifically, it renders the level onto page 2, that gets copied to page 1 during the circular wipe, and then it subsequently wipes the players and enemies from page 2 so that only the background graphics remain. This scheme allows the 'sprites' to be rendered more efficiently during game-play, without the need to save background data on each sprite update.

As a result, there are actually a set of rendering routines; the first (used for the game status) simply over-writes the page data with the tile, a second which wipes said tile, and a third that OR's the tile onto the background. The first routine has a parameter that specifies which page is to be rendered onto, the latter work implicitly with both pages.

It's clear now that the TRS-80 and Coco3 ports will require a second screen buffer. Lode Runner does actually display from page 2 in some instances, but I believe that is restricted to the High Score screen and the level editor (which I may not bother porting), so hopefully I can work around that requirement. It's not an issue on the Coco3, but the TRS-80 will definitely not be able to display from the 2nd page.

I'm now coding the TRS-80 Model 4 level rendering routines. As part of the process I'll need to go back and implement the 2nd screen page; something I avoided up until now. Who knows, maybe I will decide to tackle the circular wipe, given that I'll need to copy the data between pages anyway.

Monday 21 April 2014

Score, Men, Level

With the tiles converted and message display routine implemented, the usual supporting routines for displaying various formats of integers was next. These were quite straightforward and offered little resistance to my reverse-engineering efforts. I worked my way through the 'Game Status' display quite quickly:

The 'Game Status' display on the TRS-80 Model 4 (Z80)

This exercise has, not surprisingly, revealed the memory locations for the score, number of men and level, which will come handy for later reverse-engineering exercises. Also, the display score routine actually adds a (4-digit) parameter value to the score before displaying, so that's one less routine that remains.

I now need to go back and optimise the character/tile data lookup; taking a leaf out of the Apple II version I'll need to create a couple of sets of look-up tables which will, unfortunately, add a few hundred more bytes to the tile data, but on average speed it up immensely.

The Z80 port currently supports both single-pixel and pixel-doubled display, with a simple .define. Because I'm pixel-doubling on-the-fly it is quite a bit slower than it could be. No doubt I'll ultimately need to optimise it to account for the limited graphics bandwidth on the uLabs Grafyx Solution board, but for now I prefer the flexibility that it offers. It provides a benchmark for performance, also serves as a template for the 6809 code, mitigates the need to support different tile data formats for now, and may even come in useful on another Z80 port one day!?! Regardless, all indications are that there are only a handful of routines that write to the display, so it's not a lot of code to optimise.

Once tile-lookup optimisation is done, I'll bring the 6809 version up-to-date and then go hunting for the level display routine(s). In the process I'll no doubt find the famous circular screen wipe, though I don't plan on implementing that until right at the end of the entire porting exercise.

Thursday 17 April 2014

display_message()

Wow! What is generally one of the simpler routines to reverse-engineer on most platforms turned out to be surprisingly complex in Lode Runner. The up-side is that I suspect that the routines that I had to reverse-engineer actually comprise the bulk of the graphics/display routines in the game! The only other routine I can foresee is the overlay of 'sprite' characters onto the display.

Not only are there 3 levels of table/data look-up involved in the rendering of a single character, there's more than a few instances of self-modifying code in the routine, and the character itself is rendered into a temporary buffer (in the zero-page area) before being copied to the screen. I suspect that's because of the above-mentioned sprite-masking required in some instances - which technically would have been possible directly within the rendering routine, but would've been a mammoth task to wrap one's head around!

I won't go into the gory details, but the character/tile graphic data is effectively 'tokenized' which requires a separate look-up table for every byte on every scan-line. And there's a set of these tables for each possible pixel-offset (7). The end result is that there's a lot more look-up table data than actual graphic (pixel) data!

The necessity behind all this is that - in raw form - pixel data for all 104 tiles would require at least 18,304 bytes, a good chunk of the available RAM in the Apple II. With this clever encoding scheme, tile look-up is a slow process but requires only 4,992 bytes of RAM.

Once I'd reverse-engineered the code, I modified my PC-based utility to render each and every tile for all possible shift values from the binary dump of the game.

The complete set of 104 tiles (shifted by 4 pixels)

Given the available tile-set, I now strongly suspect that the entire game is coded to render graphics purely via tiles, and that absolutely no independent bit-mapped graphic routines are used. That bodes very well for a Neo Geo port - or any other tile- and sprite-based system for that matter!

EDIT: Prior to this I have already encountered one routine that doesn't use the tiles - the straight line across the bottom of the screen - DOH! Regardless, this would be relatively simple to emulate with a system as powerful as the Neo Geo.

Next task is to convert the graphics to a more suitable - for 8-bit video systems - format, then code the Z80 and 6809 routines. I'll need less copies of the data - only 4 shifts (or even as few as 2 on the TRS-80 ) as opposed to 7 - and all tiles will require 22 bytes (as opposed to some tiles requiring 33 bytes on the Apple II). The rendering routines will also be a lot simpler!

EDIT: 8-bit tile data (4 shifts) is done - 9,152 bytes.

Monday 14 April 2014

Development environments and title screens

Now that I had reverse-engineered the title screen display routine, and hence knew the format of the title data, I decided to set up my development environments for the ports and code the routine to display the title.

The Apple II hires screen is unique in that video memory is in effect 7-bit - and line-interleaved at that! In fact, my mind still boggles at how anyone could have the patience to write any graphics software with that hardware architecture... it's simply horrid. Anyway, the title graphics data is stored as 7-bit data with the high bit used (quite effectively) for RLE encoding.

Original Apple II Title Screen (AppleWin)

It would be quite silly to attempt to retain that format simply for the sake of it. I coded up a small program in C using the allegro graphics library (my weapons of choice for little projects like this) that first displayed the title screen from the original data (fortunately the actual title screen data isn't line-interleaved; the code uses a look-up able to calculate the address of each scan line). Then I modified it to save 8-bit data in a standard C array (and re-display to verify), then RLE-encoded it (and again re-displayed) and finally output as ASM '.db' statements. This file can be .include'd in both projects as-is.

Next I set up my TRS-80 Model 4 (Z80) development project. A few weeks earlier I had finished porting a couple of games from the TRS-80 to the Microbee using the ASZ80 assembler; I'd chosen that primarily because IDAPro supported it. It has the added advantage of being part of a suite of assemblers that includes a 6809 assembler - whose linker could output a Coco RSDOS .BIN file natively - and they also have similar syntax to the GNU as68000 assembler I've been using for the Neo Geo. So there really was no contest when it came to choosing assemblers for the project.

Leveraging off the above-mentioned earlier projects, and also lifting code from my TRS-80 Space Invaders Bootleg project, it didn't take long to have something building which should, in theory, display the title screen on the TRS-80 Model 4. I also had the scripts and tools in place to create a CMD file from the binary output from ASLINK.

Next to choose an emulator (MESS is not an option as there's currently no Model 4 - let-alone hires - drivers), and George Phillip's trs80gp was a natural choice as it's geared towards developers, allowing you to launch the emulator and instruct it to execute a /CMD file directly from the command-line. I could build and run in seconds. After fixing a few bugs and pixel-doubling the display, I was greeted with the following:

TRS-80 Model 4/4P w/uLabs Grafyx Solution Hires Board (trs80gp)

Now it was the Coco's turn. I lifted my GIME initialisation routine straight from my Tutankham project (having to re-learn exactly what it did) and then managed to coax a version of the display routine out of the depths of my already-limited 6809 coding knowledge.

The assembler and build script was the easy part - the hard part was working out the best way to get the code running in an emulator, keeping in mind the fact that I will be doing this for hundreds of build-and-test cycles over the ensuing months. In the end I settled on the MESS emulator (always my preference for any development work anyway), and the File2DSK utility for injecting the BIN file into a DSK image from the command line.

Along the way I discovered that the .BIN file output from ASLINK doesn't seem to have the correct execution address, which is annoying but at least doesn't stop me from doing what I need to do - it's just more typing each time I want to run my code.


TRS-80 Color Computer 3 (MESS)
Initially I'll be programming the Coco3 in monochrome mode, to simplify the porting process and to defer having to learn about the Apple IIe artifact color mode. Ultimately the intention is to utilise the Coco's 4-colour mode to replicate the Apple II colour rendition of the game.

Now that I've set up the development environments, it's time to return to the disassembly. There's little point in porting anything more until I am able to render the level data at least, which is pretty much the next thing that the game does anyway when it enters the demo/attract mode. I don't really have much feel for how much time and effort that's going to take, so it could be a while before I get to post an update - unless I cave and set up a Neo Geo environment too!


Down to Business

The primary reason why I had put off this project in the past is my distinct lack of Apple II knowledge. That does sound like a pretty stupid reason when one of the goals of my retro projects is to learn more about the platforms I'm dealing with, but never-the-less it remains a fact.

Apple II Lode Runner was also a relatively heavily protected (multi-stage loader) disk-based game which suggested to me that the ramp-up time was going to be even longer than I otherwise feared. Fortunately I discovered some time back (though subsequently forgot about until recently) that French hackers had done a lot of the hard work in this respect, and produced an 'unprotected' version of the disk that was freely available for download - even documenting the boot code in detail! Even more fortunately, I had archived all of that information and the disk image, as it appears to be no longer available!

So the first task was to extract the program and data code from the disk image, into binary files that I could load into the IDAPro disassembler. That was a relatively simple process, comprising the zero page memory dump from MESS, data loaded during the booting phase (via MESS) and the main code/data block loaded into memory immediately before execution begins (again via MESS but also verified against the actual disk image sectors).

The data block occupies 4KB from $0F00-$1EFF, most of which is the title screen and associated data.

The main code/data block occupies 24KB from $6000-$BFFF, of which I estimate approximately 11KB is actual 6502 code. The remainder is most likely primarily graphics data, including the font used to render in-game text on the hires screen.

I should note that all the ASCII strings in the code have bit 7 set for all characters, so there is no text plainly visible in the binary dump at all. Once I deduced this fact I was able to produce an alternate dump for reference, but it is definitely a mild annoyance. I have no intention of retaining this 'feature' in the ports; there's simply no reason to do so as I suspect it was done only to hamper hacking attempts.

The next task was to dive into the disassembly, to at least get a feel for the overall code/data structure and to start to earn my Apple II stripes. I have to admit that the first few hours weren't particularly fruitful, and I began to wonder if this was going to be a very short-lived project. But once I realised that the data block at $0F00 was loaded during the boot process, things started to make more sense and I managed to reverse-engineer what turned out to be the title screen display routine.

One early plan-of-attack with this type of exercise is to identify and comment the message display routine(s). Generally that's relatively straightforward and also helps to identify different sections of the code. In this case, I was left scratching my head as I couldn't find a single reference to the address of any string in the program! I did eventually locate the display routine, and discovered that the messages immediately followed each call to the routine! So the display routine used the return address for the message, and then subsequently adjusted it to return execution to the byte immediately following the message itself. I suspect this sort of thing is quite common in 6502, where registers are at a premium...

One last note on what I've observed so far... there appears to be a reasonable amount of self-modifying code - mainly addresses poked into subsequent code blocks. Again, I suspect this is quite common in 6502.

That's about all I've reverse-engineered so far, and at this point I decided to stop and set up my development environments for both the TRS-80 and Coco3. More about that next post.



There are ports, and there are ports.

I thought I should point out that when I use the term 'port', I'm using it in the absolute strictest sense of the word.

What I will - in effect - be doing is translating the code line-for-line from 6502 assembler to Z80 & 6809. The result will be a pixel-perfect, 100% accurate rendition of the Apple II original on the target platform. All the graphics, all the game-play, all the AI will remain intact. Nothing less will suffice.

OK, technically I won't be translating line-for-line, but it won't be far off!

Sockmaster has proven that it is actually possible to take this approach; his port of Donkey Kong (arcade, Z80) to Coco 3 (6809) comprised literally that. Whilst he did have to modify the graphics slightly to accommodate hardware limitations on the Coco, the result is a completely authentic port of the arcade original. And nothing less than impressive!

As I've mentioned, I'm roughly 50% through porting arcade Donkey Kong to the Neo Geo and, although I'm taking a decidedly different approach to Sockmaster, the end result will be the same. I'm reverse-engineering the original Z80 code in order to understand exactly how it works, and then writing equivalent 68K code. And rather than waiting until the disassembly is complete, I'm writing each section as I reverse-engineer it.

So on the topic of pixel-perfect, 100% accurate ports - I'm not expecting to have any technical issues with either target platform. Perhaps the most limiting restriction will be the graphics bandwidth on the Model 4, although I'm sure the modest requirements for Lode Runner will not be an issue in the end.

The beauty of the Apple II original is that it was designed to be perfectly playable on both monochrome and colour monitors. In fact, I only ever played the Apple II version on a green-screen monitor back in the day. Lode Runner runs in 280x192 resolution, and sound is generated via the Apple II speaker.

For the TRS-80 Model 4/4P version, I'll be running it in 640x240 mode, and pixel-doubling horizontally, to utilise a 560x192 pixel area of the screen, which I'll ultimately center.

For the TRS-80 Color Computer (Coco) 3, I'll be running it in 320x192 mode, obviously utilising almost all of the screen. Initially I'll focus on a monochrome implementation, but ultimately I'll also support the Coco's 4-colour mode in order to replicate the Apple II's colour rendition.

That's about all I have to say on the matter of porting and accuracy.

I will add one last thought about a Neo Geo port, as it has been nagging at the back of my mind. There are plenty of ports of Lode Runner to tile-based systems, so it's obviously feasible. I'll reserve my final judgement until I know more about the game's rendering routines, but I strongly suspect that even the Apple II version emulates a tile-and-sprite system, and that porting to a ROM-based graphics system like the Neo Geo would be straightforward.

It's very, very tempting to set up a Neo Geo Lode Runner project right now...

Apple II Lode Runner

Check the link in my previous post for a low-down on my history with Lode Runner - and trying to get it running on the TRS-80 - but suffice it to say that I'm quite fond of the game! In particular, the original - and definitive - Apple II version.

So it is only very recently that I find myself, after all these years of talk, starting on the long road to porting the 6502-based Apple II version to the Z80-based TRS-80 Model 4/4P (utilising the uLabs Grafyx Solution hires board). Not content with one port, however, I also intend to port it simultaneously to the 6809-based TRS-80 Color Computer (Coco) 3.

And I'm also considering attempting a port to the 68K-based Neo Geo, but I'm yet to convince myself that it's technically possible on the ROM-based tile/sprite system. Perhaps I'll know more the further I get into the project, but at this point I'd have to say that it's unlikely I'll attempt it in parallel with the other two. The Amiga, OTOH, may have been more likely, but a port already exists.

As for my approach; although Sockmaster has proven that it is unnecessary to understand much of the original code in order to port it to another platform, I have every intention of producing a 100% complete reverse-engineering (i.e. commented disassembly) of Apple II Lode Runner. If nothing else, I'm interested in how the original program was coded, but I also believe it will make porting to another platform - and in particular multiple platforms - much easier.

Until my most recent project, I worked on the disassembly until it was as complete as I could get it before I started to port the code to another platform. That works well enough, but it's a hard slog and there's always a point in the process that requires a lot more work for little gain. And there it's difficult to keep motivated.

For my Donkey Kong Neo Geo port, I decided to start the port right from the beginning. That decision probably had more to do with the fact that I had absolutely no knowledge of programming the Neo Geo hardware, and I wasn't quite sure if I was going to be able to do it, so I started with a simple static screen rendering. It went from there and so far has worked out well, so I'm taking the same tact with Lode Runner. And a double dose, in fact.

Anyway, it's going to be an interesting process, and perhaps a good exercise in comparing the 6502, Z80 and 6809 processors. FTR my 6502 is very weak (I've done very little disassembly and certainly never written as much as a line of code), my 6809 perhaps a little less so (I've disassembled a few things and written some code), but my Z80 is far and away my strongest suit. I'll be curious to know if a relative novice 6809 coder can write more efficient code than an experienced Z80 coder!

Next post I'll touch on the Lode Runner code, the Apple II hardware in contrast to both of the TRS-80 machines, and perhaps document my current progress.

Welcome

I've decided to create a new blog specifically for one aspect of my retro computing/gaming hobby; namely porting software from one retro platform to another. So - Welcome!

I've done - or at least started - a few retro porting projects in the past, with varying degrees of success. And currently I've a couple of projects that are WIP, so I've decided to bore anyone unfortunate enough to stumble unwittingly onto this blog with my trials and tribulations along the way.

My past projects, in approximate chronological order, include:

  • Space Invaders (arcade) to TRS-80 Model 4/4P with uLabs Grafyx Solution hires board. This was more of a patch than a port, and I was mostly successful - at least under emulation. The TRS-80 is lacking the 120Hz interrupt required by SI, and I never quite got to chaining two 60Hz interrupts to emulate the effect. Unmodified, it ran at half-speed though. I really should go back and attempt to get it running full speed on real hardware.
  • Tutankham (arcade) to TRS-80 Color Computer (Coco) 3. Again, more of a patch, initially, and it was running and playable except for two issues; the screen was rotated, and scrolling wasn't implemented. I started to rotate the graphics but technical issues with the scrolling rendered it effectively dead-in-the-water.
  • Lode Runner (MSX) to TRS-80 Model 4/4P with uLabs Grafyx Solution hires board. Another patch, and 100% playable under emulation. However the required graphics bandwidth proved to be the game's undoing on real hardware, although George Phillips is currently attempting to rectify that problem.
  • Tandy Invaders (TRS-80) to the Microbee. 100% reverse-engineered to produce a relocatable ASM file that can be built for TRS-80 or Microbee with a simple '.define'.
  • Donut Dilemma (TRS-80) to the Microbee. 100% relocatable ASM file that can be built for the TRS-80 or Microbee with a simple '.define'. Thanks to Nick for the source!
And currently, I'm in the midst of two (2) ports - and this time they're ports more than patches.

The first is Donkey Kong (arcade) to the Neo Geo, and is documented in my NGPACE blog as it pertains to the subject of that blog - the Neo Geo. As of this entry, it's around 50% complete and looking very nice indeed! I've even run it on real hardware (NGCD).

The second, and the reason I decided to start this blog, is Lode Runner (Apple II) to the TRS-80 Model 4/4P with uLabs Grafyx Solution hires board - and the TRS-80 Color Computer (Coco) 3. That's right - I'm attempting to port it to two completely different machines simultaneously.

In my next post I'll give more of an introduction to this particular port, but in the mean-time you can read more about my history with Lode Runner on an old homepage of mine.