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.
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.
Monday, 26 November 2018
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.
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...
[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...
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.
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.
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
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
Monday, 29 October 2018
There was movement at the station...
Well, I'm happy to report that I've been thinking increasingly about getting back to my retro projects lately. I've been motivated by a number of diverse factors, and (dangerously) a hankering to start a new project but I've promised myself that I need to finish off a few others before going down that path.
Tonight I actually took preliminary steps towards playing around with FPGA implementations again; not directly Retro Ports but at least in the sphere of retro computing. The impetus for that particular exercise was the fact that I'm back doing FPGA designs for work again. That said, I didn't get far before deciding that what I was researching wasn't feasible at this point.
Nevertheless, I'm still motivated to do something and am intending on redirecting that motivation to finishing off the CoCo3 implementation of Asteroids. It will take me a session or two to ramp up again, but from memory I was about to optimise the graphics rendering, which required some C code to generate the hand-compiled sprites. I would also like to complete the C implementation, which would allow me to port it relatively easily to the Neo Geo.
And I have further plans for Asteroids, but at this point undecided what aspect I'll work on next.
But hopefully I'll be back to regular updates soon.
Tonight I actually took preliminary steps towards playing around with FPGA implementations again; not directly Retro Ports but at least in the sphere of retro computing. The impetus for that particular exercise was the fact that I'm back doing FPGA designs for work again. That said, I didn't get far before deciding that what I was researching wasn't feasible at this point.
Nevertheless, I'm still motivated to do something and am intending on redirecting that motivation to finishing off the CoCo3 implementation of Asteroids. It will take me a session or two to ramp up again, but from memory I was about to optimise the graphics rendering, which required some C code to generate the hand-compiled sprites. I would also like to complete the C implementation, which would allow me to port it relatively easily to the Neo Geo.
And I have further plans for Asteroids, but at this point undecided what aspect I'll work on next.
But hopefully I'll be back to regular updates soon.
Thursday, 11 October 2018
False Alarm!
Heh! Before you read any further, there hasn't been any more progress on any of my projects.
I thought I'd write a quick update on the status regardless. The upside is that these projects are not far from my consciousness and I still have an interest in finishing them off.
Just a few weeks ago I bundled up the latest version of Knight Lore for the TRS-80 Color Computer 3 and sent it off to someone who is going to be releasing it on cartridge for sale. Hopefully. I thought for a brief moment that it would motivate me to resume my projects, but alas it hasn't been the case thus far. Perhaps when I see it announced for sale...
I recently sold a few retro bits 'n' pieces - mainly manuals & microcomputer software - and my favourite arcade cabinet, to fund the purchase of something else completely unrelated to retro gaming. Yes, it was my favourite cabinet but the reality of it was that it was rarely turned on, it was just too big for my (rather small) games room, and I have designs on building a Viewlix cabinet one day. I still have two (2) cabinets so I let it go for the cash I needed.
On the flip side, I've recently purchased a video demodulator, video/rgb scaler and CFFA3000 card - and have plans to buy another video demodulator - so it's not like I've lost interest in retro gaming.
So back to the projects. Usually around this time I think of another project I want to start and then focus on that instead of finishing the previous one(s). This time however, that's not the case. So first cab off the rank will be to finish optimising Asteroids for the Coco3, then back-port it to the Apple IIC+ and the IIGS. I also want to port it to another platform - TBA.
I've been thinking again about the Neo Geo, and finally picking up Donkey Kong again. Especially now that the NeoSD, and whatever DarkSoft's equivalent is, are well established in the marketplace.
Just a matter of when I get the urge again...
I thought I'd write a quick update on the status regardless. The upside is that these projects are not far from my consciousness and I still have an interest in finishing them off.
Just a few weeks ago I bundled up the latest version of Knight Lore for the TRS-80 Color Computer 3 and sent it off to someone who is going to be releasing it on cartridge for sale. Hopefully. I thought for a brief moment that it would motivate me to resume my projects, but alas it hasn't been the case thus far. Perhaps when I see it announced for sale...
I recently sold a few retro bits 'n' pieces - mainly manuals & microcomputer software - and my favourite arcade cabinet, to fund the purchase of something else completely unrelated to retro gaming. Yes, it was my favourite cabinet but the reality of it was that it was rarely turned on, it was just too big for my (rather small) games room, and I have designs on building a Viewlix cabinet one day. I still have two (2) cabinets so I let it go for the cash I needed.
On the flip side, I've recently purchased a video demodulator, video/rgb scaler and CFFA3000 card - and have plans to buy another video demodulator - so it's not like I've lost interest in retro gaming.
So back to the projects. Usually around this time I think of another project I want to start and then focus on that instead of finishing the previous one(s). This time however, that's not the case. So first cab off the rank will be to finish optimising Asteroids for the Coco3, then back-port it to the Apple IIC+ and the IIGS. I also want to port it to another platform - TBA.
I've been thinking again about the Neo Geo, and finally picking up Donkey Kong again. Especially now that the NeoSD, and whatever DarkSoft's equivalent is, are well established in the marketplace.
Just a matter of when I get the urge again...
Monday, 25 June 2018
From beyond the grave
Well, perhaps that's a little dramatic.
Thought I might post a quick status of the project(s)...
The simple fact is that over the last 6 months or more, I just haven't felt motivated to work on any retro projects at all. And to a degree my interests in other (non-development) areas of the retro hobby have diminished as well. I can't offer any concrete explanation as to why, other than my priorities have of late moved away from the computer keyboard and into other areas of my life.
Having said that however, I haven't felt any urge to give up the hobby altogether, or even to scale back my collections or range of interests in retro video games and microcomputers. To the contrary I've actually picked up a couple of books and a few new pieces of hardware in that time, and have my eye on yet another. Not that I've read or used any of those recent acquisitions.
So I'm confident that, when the time is right, I'll resume my retro hobby and - more to the point for this blog - my porting projects. My resolve is to finish off the projects that have languished, most (but not all) incomplete, for an embarrassing length of time and just release them to the public. And although I had previously earmarked the next few projects, I'll likely reconsider those when the time comes.
For now, I can't offer any further insights nor when I'm likely to resume my porting projects. I won't really know until I'm actually ready to do so. But perhaps the very fact that I've been inclined to update this blog is a good sign?!?
Thought I might post a quick status of the project(s)...
The simple fact is that over the last 6 months or more, I just haven't felt motivated to work on any retro projects at all. And to a degree my interests in other (non-development) areas of the retro hobby have diminished as well. I can't offer any concrete explanation as to why, other than my priorities have of late moved away from the computer keyboard and into other areas of my life.
Having said that however, I haven't felt any urge to give up the hobby altogether, or even to scale back my collections or range of interests in retro video games and microcomputers. To the contrary I've actually picked up a couple of books and a few new pieces of hardware in that time, and have my eye on yet another. Not that I've read or used any of those recent acquisitions.
So I'm confident that, when the time is right, I'll resume my retro hobby and - more to the point for this blog - my porting projects. My resolve is to finish off the projects that have languished, most (but not all) incomplete, for an embarrassing length of time and just release them to the public. And although I had previously earmarked the next few projects, I'll likely reconsider those when the time comes.
For now, I can't offer any further insights nor when I'm likely to resume my porting projects. I won't really know until I'm actually ready to do so. But perhaps the very fact that I've been inclined to update this blog is a good sign?!?
Subscribe to:
Posts (Atom)