Tuesday, 2 June 2020

A ghost from the past!

Well here we are 18 months on from my last "I'm going to get back into it" post with another optimistic post not worth the electrons it was transmitted with.

This time I make no claims but will report that tonight, for the first time since the abovementioned post, I have actually cracked open one of my unfinished projects.

Of course it took me about 2 hrs to locate the latest source and put together a working development environment that allowed me to simply build the project. At least I took steps to document the process; a lesson I learned in projects subsequent to me starting this one a few years back.

I also got time tonight to take a look at where I was at, refresh my memory on how things work, and start to progress on finishing it off. One bug squashed, but ultimately little effect on progress.

The project in question is the 6809 port of Space Invaders to the TRS-80 Color Computer 3 (aka CoCo3). I have transcoded the original 8080 code to 6809 and have it fully playable on the CoCo3, albeit rotated (sideways).

I had started rotating the graphics by hand, then abandoned that to attempt to do it programmatically on-the-fly, then ultimately backed all that out and continued with my first plan. But I got to the point where most of the graphics were at least rotated, if not displaying in exactly the right location, but the game was crashing after drawing all the aliens. And this is where I picked it up tonight.

As I mentioned, I did find one bug which was sending it off into la-la land but unfortunately fixing it didn't improve the situation to any discernable degree. Another hour or two of debugging and I can see what is going wrong, but not why at this point.

I'll update if/when I make any significant progress.

As an aside, in the last 18 months my transcode (port) of Knight Lore to the CoCo3 has seen a physical release on both floppy disk and cartridge by Neil Blanchard of the CoCo Crew Podcast fame. They look pretty snazzy and I'd post a photo of them here but I can't locate one atm.

Friday, 25 January 2019

A new year, a new promise... yada yada...

It has been several months since I posted that I was getting interested in picking up my retro projects again, yet there has been next-to-no updates since then. And not the first time I have posted with some optimism about resuming and/or finishing some project only to have it all grind to a halt again within days.

My last post in this vein was in good faith but then work suddenly got really, really busy; I was even working some nights to get through it all. Then of course holiday season was upon us and I had family visiting from inter-city and overseas and then finally went away on holidays myself. And here we are, months later.

So, where do I sit now?

Work is a bit more sane now, although I can't say for certain that it will stay that way for long. I'm also trying to allocate more time to physical activities, so that isn't conducive to sitting at a keyboard either. And, almost on a whim, I've decided to study up for my HAM licence, so that will also eat into my spare time. However, I am slowly drifting back into my retro gaming hobbies, possibly spurred on by the fact that I picked up a Nintendo Switch for Xmas.

[An aside: I've been playing Lode Runner Legacy on the Switch and was disappointed to see the "classic" mode game graphics weren't from the Apple II. In fact the animation of the player and guards is absolutely horrid!]

I should also note that one of my New Year's resolutions was to simply "get things done"; things that have been on my to-do list for, in some case, several years. Those 'things' comprise projects around the house (including my man cave / games room), things I need to build like my rocker plate (if you don't know, it won't interest you), and of course my retro ports.

So now that the year is starting to settle into a routine again (school is back next week) I can sit down and formulate some sort of plan.

As far as retro ports are concerned, I'm determined to finish off Asteroids on the Coco3 first and then revisit it on the Apple II/IIc/IIGS. I also have another target in mind. Also languishing are Space Invaders for the Coco3, Lode Runner for the Coco3 and Neo Geo, Knight Lore for the Amiga and Neo Geo and, finally, Donkey Kong for the Neo Geo.

To top it all off, I've decided on my next retro port - after the above are done of course. It's an arcade game suited only for 16-bit targets, and is going to be a mammoth task to reverse-engineer in the first place. It was originally further down on my to-do list (after, for example, Karateka and Prince Of Persia), but I've decided to attack a more ambitious project. Go big or go home!

To be continued in my next post... the 2019 wrap-up! ;)

Monday, 26 November 2018

Still a bug, and circular wipe again

First task tonight was to try to understand why the Apple II Lode Runner attract screens were non-deterministic. I think I've found the answer, and it was even semi-documented in the 6809 source code. However there are still inconsistencies between the Apple and C versions I can't explain at this point so it would appear I still have a bug somewhere, perhaps not even in the AI as such. It needs further investigation.

Second task was to determine if the "circular wipe" that was part of the Apple II version (and very few other ports) is feasible on the Neo Geo. I had the idea to employ the sprite shrinking capabilities of the Neo Geo hardware in order to "get it for free".

However the "free" solution requires setting sprite positions outside the visible display, which is not possible unfortunately. So I set about trying to devise another, necessarily more complex, scheme that would be workable.

I think I have worked something out - on paper at least. It's not too complex and doesn't require much in the way of run-time calculations and does employ sprite shrinking. The only caveat is that I'm not sure how it's going to look when it's actually animated.

There are two ways forward from here. One is of course to simply implement what I have devised and run it. The down side is that I have to re-learn everything I have forgotten about sprite formats and sprite manipulation, and then write code to create the requisite sprite tiles and the code to assemble and control them properly. And if that looks naff, it's all a wasted effort.

The other is to simply "emulate" the Neo Geo's sprite shrinking in a suitable development environment (my go-to has always been Allegro on the PC) and code a pre-canned animation. There is I believe sufficient information on the NeoDev Wiki to do exactly this. It's probably less work, and requires less mental effort on my part, until it comes time to implement it on the Neo Geo itself. The only caveat is that it may look different on Neo Geo hardware if I get something wrong.

One other option of course is to give up on the circular wipe altogether. As I mentioned, not many of the other Lode Runner ports include it, though I'm not convinced that the reason isn't the rather annoying pause whilst it was rendered, rather than technical reasons (on the bit-mapped platforms at least). Some ports chose a different "wipe" animation whilst some didn't bother with anything at all.

But I would like to keep the port as close to the Apple II original as possible; it serves to reinforce the origin and the accuracy of the port. So I might give the "emulation" approach a go when I next get to work on it.

Saturday, 24 November 2018

When a bug is not a bug

Tonight I thought I'd see if I could find the AI bug in the C code.

[To explain, the benchmark for the AI has been to run the attract screens on the target port side-by-side with the Apple II original. If the outcome for all attract screens are exactly the same as the Apple II version, it's a pretty safe bet that the AI is spot-on, as it is likely that all execution paths are thoroughly exercised across the multiple levels.]

I started comparing the 6809 and C code side-by-side for the guard AI routines. I did find one minor discrepancy (a pair of while loops that should have been do-while loops) but that didn't make any visible difference to the outcome. Also a few red herrings which turned out not to be differences at all, but I'd obviously done some optimisations in the C code that obfuscated the transcoding somewhat.

After spending a few hours not getting anywhere, and about to wrap it all up for the night, I was watching the Apple II and Coco 3 attract modes side-by-side (again) just for a sanity check and - to my horror - noticed that they actually differed!?! This can't be right - I thoroughly tested the Coco 3 version against the Apple II version all those years ago!!!

So I fired up the Neo Geo (C) version again so that all three were running in parallel, and to my surprise it corresponded with the Apple II version - for the first time. How could it be that I fixed a bug in the C code by comparing it against inaccurate 6809 code? This warranted further experimentation, so I ran the first attract level on the Apple II over and over again until...

... I discovered that there are two possible outcomes on the first attract screen! I had never noticed this before, and right now I can't imagine how that happens, as I thought it was completely deterministic!

[UPDATE] I've noticed that on the first run you get one particular outcome, and on all subsequent runs (eg warm boot) you get the other outcome. So likely an uninitialised variable or variable corruption.

The outcome on the first run from a cold boot

The outcome on subsequent runs (eg. warm boot)

But the good news is that both the CoCo 3 version and the Neo Geo versions behave the same way as the Apple II version or rather, at this point, both the CoCo 3 version and the Neo Geo versions don't behave unlike the Apple II version; and by that I mean that I haven't confirmed at this point whether the C version results in two different outcomes. (It's late, that's for another time).

To satisfy my curiosity, I'll probably have a go at trying to find the source of the non-deterministic outcomes, and then confirm that the behaviour is faithfully reproduced in the C version.

Then I think I'll FINALLY finish off the Neo Geo port, hopefully adding the circular wipe and maybe a few bells and whistles (eg. high score save to memory card) to give it some polish and release it for MAME and the NeoSD.

From there, who knows? Maybe I should design a cart for the CoCo 3 version...

Tuesday, 20 November 2018

Coming full circle

Last night whilst getting ready for bed I was subconsciously pondering the circular wipe for Lode Runner on the Neo Geo, and I had a "Eureka" moment! My memory of certain Neo Geo technical details is a little hazy after a year or more of absence, but I think I have hit upon an easy way to implement it, thanks mainly to the hardware functionality of the Neo Geo sprite engine!

I'm tempted to pick up Lode Runner again and see if I can finally fix the AI bug and just knock off the project, sans sound. I did have Asteroids on the top of the to-do list, but at the end of the day, it's still another project that needed finishing off.

Watch this space...

Return to an old project (briefly)

Tonight, prompted by postings on other forums, I returned to an old porting project in part upon request and in part to satisfy my own curiosity.

The project in question was Apple II Lode Runner, and the target platform was the Neo Geo.

Quite a while back I invested in a flash cart for the Neo Geo (AES) called the NeoSD. Aside from allowing you to play any and all Neo Geo titles on the console, it also allows you to play homebrew titles; something which was hitherto impossible without building and programming your own cartridge. As you can imagine, this was quite a serious impediment to any potential Neo Geo homebrew scene.

Anyway, I had never tried programming any of my ports - or any homebrew games for that matter - into the NeoSD. And since someone had asked about Lode Runner, it prompted me to pull the console out of my unfinished games room and finally learn how to do it.

After some research (detailed information is sorely lacking) and a little experimentation, I managed to get my Lode Runner ROMs into the correct format and loaded onto the SD card.

Apple II Title Screen
Attract mode game play





















Bearing in mind that I had burned a CD for the NGCD in the past, I was confident it would actually run. But it's still pretty cool to see your project running on the AES after all this time!

Apologies for the potato camera. Aside from the obvious fuzziness, the colours are pretty washed out, in particular the orange which in actuality looks pretty much how it does look on the Apple II.

To re-cap, there was one last AI bug in the C port that I hadn't tracked down. It was evident only when comparing the attract mode game play, where the second screen exhibits slightly different behaviour from the guards near the end of the demo. It's lacking the "circular wipe" transition screen (problematic to implement on the sprite-only Neo Geo) and no sound. Those issues aside, completely playable.

We will now return to our regular programming.

Sunday, 18 November 2018

Baby Steps

The lack of activity after my last optimistic post has actually been due more to a hectic work schedule than anything else.

A few nights ago I started looking at Asteroids (CoCo3) again, trying to understand where I got to, and also battle a very uncooperative revision control system (which still isn't working).

And tonight I actually did a few simple optimisations to the erase routines. Nothing particularly spectacular, and partly temporary, but at least it got the juices flowing again.

Hopefully more to follow soon...

[UPDATE]

Here's a snippet of the code to erase an object. Originally I had a simple loop, which I unrolled last night. But looking at the cycle counts, I noticed that 16-bit offsets require 8/9 cycles as opposed to 5/6 for 8-bit offsets. Doing the math, I found it was quicker to adjust Y (8 cycles) so that only 8-bit offsets were required. And somewhat annoyingly, coding an instruction with a '0' offset was assembled into a (slower) 5-bit constant-offset instruction, rather than a zero-offset.

ldd #0
std     ,y
sta     2,y
std     1*32,y
sta     1*32+2,y
std     2*32,y
sta     2*32+2,y
std     3*32,y
sta     3*32+2,y
leay    4*32,y
std     ,y
sta     2,y
std     1*32,y
sta     1*32+2,y
std     2*32,y
sta     2*32+2,y
std     3*32,y
sta     3*32+2,y
leay    4*32,y
std     ,y
sta     2,y
std     1*32,y
sta     1*32+2,y
std     2*32,y
sta     2*32+2,y
std     3*32,y
sta     3*32+2,y
leay    4*32,y
std     ,y
sta     2,y
std     1*32,y
sta     1*32+2,y
std     2*32,y
sta     2*32+2,y
std     3*32,y
sta     3*32+2,y