Sunday, 23 July 2017

IIC, or not IIC, that is the question:

Whether 'tis nobler in the mind to suffer
The Apple II hires video memory map,
...

Due to an SOS call from my wife whilst I was en-route to WozFest (car trouble) I ended up missing the brief link-up with KFest and people had well and truly broken off into small groups to work on their own projects by the time I arrived, which meant I didn't get the chance to see it running on real hardware.

I did get a chance to do a little more work on it though (despite heckling from the Peanut Gallery - you know who you are) and have now got pixel-shifted graphics rendering. Although somewhat hampered by the flickering graphics, on close inspection it is definitely animating more smoothly now.

I also decided to go down the path of so-called compiled sprites, reasoning that it wouldn't be very difficult to write a C program to parse my ASM bitmap data file to produce the requisite code. I've got one or two minor optimisations to effect first, and then I'll give it a spin. If that doesn't make a marked improvement, I'll be at a bit of a loss in terms of how to proceed further. As a first-pass I'll opt not to use stack-blasting and see where that gets me.

After chatting to a few learned fellow attendees at WOzFest it became apparent that the 4MHz IIC+ would be another good candidate for a port - even more capable than the IIGS in fact - with a faster CPU (same video memory bandwidth) but with a monochrome graphics mode meaning only 1/4 of the graphics data to push around. I'm fast running out of excuses to keep avoiding the legacy Apple II hires video display...

Thursday, 20 July 2017

Game On!

Excellent progress today - in fact it's in good enough shape to demo at WOzFest now although it would be nice to take it along even further if I get the chance!

The bulk of the rendering (sans exploding ship and thrust) and the erasing has been done. I've also managed to pilfer the joystick read routine from Lode Runner and as a result the game is actually playable, albeit slightly slower than the arcade original at this point.

video


I've still got some optimisations up my sleeve, from simple changes to the display list entry format through to stack-blasting hand-compiled sprites, so I'm still holding out hope that I can get it running fast enough to require being throttled by a IIGS interrupt. And I still haven't worked out the whole video shadowing mechanism; a bug in my code meant that I was never shadowing the SHR screen in the first place - and now when I turn it on, it can't read the keyboard... so there's that to play with as well.

I guess if all else fails I can revert to the legacy hires screen which is a lot less data to move.

From the video it's obvious I've got some graphics tweaks to do, including bit-shifting plus offsets from CUR for each object. There's flickering of course, and the odd glitch and then the minor matter of a complete crash at the end of the game.

As an aside, I got stuck on the joystick not working in the IIGS emulation under MAME. I could move left/up, but centering the joystick read back as $FF, so I couldn't move right/down. That forced my hand in trying to get the disk booting in GSPort, and I eventually realised the floppy disk image should be in slot 5, not slot 7. However GSPort had the same issue...

Then it finally twigged; the routine was written for a 1MHz machine and was running on a 2.8MHz machine. The counter was overflowing before even the centre position was detected! After slowing down the CPU it all started working!

So - finish off the graphics, tweak the display positions, optimise the erase/rendering, fix the Game Over bug. Then add sound, title screen, and release! I've got - realistically - only one more night to work on it before its debut.

Wednesday, 19 July 2017

IIGS Take 2

The experimental work I'd done on the IIGS port prior to starting on the port proper has certainly paid off; as of tonight it's rendering the characters, lives, copyright, asteroids and player ship (and the latter only when it should be). I should note that I'm yet to generate or code for the bit-shifted graphics.

It may look no different to the previous version, but the display list is greatly simplified - effectively tokenised - and all the dead code has been removed from the 6502 core, giving me more headroom on the IIGS. And I've still got a little more optimisation to do in my rendering routines.

IIGS Asteroids Take 2 - optimal display list

When I next get the chance I'll continue with the saucer, the shots and the shrapnel which should be as straightforward as the other objects have been until now.  That'll just leave the exploding ship, which I am yet to work on at all.

I think that'll be a good point to research reading the IIGS keyboard; I've been encouraged by reading vague suggestions that it's possible to read the IIGS keyboard directly from the ADB. If that pans out I'll be able to make the game playable, if slow.

Then it'll be time to work on the bit-shifted graphics and erase logic (right now it's clearing the entire screen every frame). That should bring the game back up to speed and I'm hoping it'll actually then be too fast!

I'll be happy if I get to this point by the weekend for WOzFest Slot 7!

Beyond that, there'll be the addition of the exploding ship, sound (samples), support for variable beam brightness, and spit & polish and bells & whistles, such as a title screen, joystick/paddle support etc etc.

Tuesday, 18 July 2017

A token effort

I have to admit, I haven't been able to tear myself away from the C port to make any further progress on the IIGS port. However, it hasn't all been for nought as it has definitely reinforced my understanding of the arcade code, and cemented my decision regarding tokenising (optimising) the display list for the 8-bit ports.

Before I get to that; most of the work on the C code has been 'infrastructure work' and low-level DVG interface routines, which necessarily support both the new abstract display list and the original in parallel - to facilitate debugging and development. What that leaves, then, is the game logic and housekeeping code which generally tends to be easier to translate to C; the upshot of all this is that I don't think the C port is going to take very long to complete at all!

[Just for the record, I have the C port rendering all the text, including scores, and rendering and animating the asteroids themselves. The pseudo-random number generator is also in lock-step with the arcade machine and produces the same output at the appropriate times].

Keep in mind that the arcade code is only 6KB of 6502 - a lot of that munging 16-bit numbers - and it's not surprising that the C port isn't huge. From memory, Knight Lore was ~12KB of Z80 code and translated to ~5K lines of C. I'm around 1,300 lines for Asteroids already, and you could estimate it'll be in the vicinity of 2,500 lines.

Getting back to the IIGS (and 8-bit) ports; aside from the existing CUR (which sets the current beam coordinates) and HALT display list commands, there'll be a distinct command for the rendering of each object in the game, comprising character, extra ship, copyright, asteroid, ship, saucer, shot, shrapnel and exploding ship. I may add one last command to set the brightness - something the arcade code does but Norbert doesn't bother with - simply because the IIGS has the palette to support some variance in brightness.

Some of those commands will have one or two parameters, but all will render at the current beam position. The parameters will be succinct and optimised for the bitmap display routines. What this means is that I can actually remove a lot of code that generates the display list content that is irrelevant for the port, such as DVG subroutine calls or component vector commands. This is one area where I'll be able to improve performance over Norbert's emulators, only because I effectively have the arcade 6502 source that I can modify and re-assemble at will.

I've also identified which of the bitmaps will and won't require bit-shifting, and which will require an extra byte's width to do so. Because, for example, all of the game's text message coordinates are fixed, specified on a 0-255 grid (before being scaled-up in the display list), and also happen to have even X coordinates, I don't have to bit-shift any of the character set for the IIGS 2BPP SHR graphics!

Most of the remaining bitmaps will require bit-shifting, and a few - not all - of those will require an additional byte's width to facilitate it. But that simply boils down to an extra compare and load for each object rendering, unless I need to really wring the performance out of the rendering routines.

My next task now is to generate shifted bitmap data, which is trivial, and essentially start over from scratch with the IIGS port. I'll probably have to stub out all the routines that write to the display list, and then begin work on the so-called tokenising version. None of that should be too difficult...

[UPDATE: I've regenerated the 6502 ASM file from my disassembly, starting the IIGS port from scratch. All of the DVG write routines have been stubbed-out so that only the CUR command is now written to display list. Next is tokenising the character command and then rendering it on the IIGS.]

As for the erasure; I'm planning on (eventually) making use of the ping-pong display list buffer. Immediately before rendering the new list, I'll simply re-parse the old buffer and use it essentially as dirty rectangles. I do have more sophisticated optimisation possibilities up my sleeve; it's useful to know, for example, that all objects are written to the display list in a fixed order. I'll leave all that, however, until I need it - if ever.

Wednesday, 12 July 2017

Asteroids with a 'C'

On Friday nights my wife & I traditionally watch a show together with which I've become rather bored in recent times. Rather than waste that hour last week I decided to set up the laptop in front of the TV and work on some aspect of Asteroids that required a minimum level of concentration. Ultimately I decided to start work on the C port of Asteroids, mainly because it required a lot of crank-the-handle type coding up front before any real work was required. Like defining data structures for zero page variables and player RAM.

Aside from the aforementioned, I manage to also code the main routine and stubs for all the subroutines called from there. Then over the next few nights I was keen to take it a little further; implementing a rather more 'abstract' display list to aid not only in development and debugging, but also to facilitate the so-called tokenising I'd be doing in the 8-bit ports. That entailed a DVG 'disassembler' of sorts which subsequently morphed itself into a DVG interpreter/emulator which was soon rendering a few vectors on the display.

Of course time is ticking for WOzFest and I do need to bite the bullet on the tokenised display list and optimisations for the IIGS. However it has been a very useful exercise and I've discovered a few subtleties of the DVG which had escaped me until now. Regardless, I really need to put it aside for now and continue on with the IIGS port. In the mean-time, here's a sample rendering of what I have thus far.

Asteroids C port (Win7, GCC, Allegro)

Like my other C ports (Lode Runner and Knight Lore), the C code is as faithful to the original assembler source as practical, whilst optimising aspects of the original code such as using 16- and 32-bit variables rather than multiple bytes for things like addresses, scores, coordinates, etc. I retain all the same subroutines with the same names, albeit adding parameters for values passed in registers, etc. The logic within each routine is representative of the assembly code, differing only to accommodate the aforementioned optimisations and/or clarify the intent, without changing the underlying algorithm or compromising accuracy.

The end result is the same as the 8-bit assembler ports; a game that plays exactly - and looks as far as practical on the target hardware - the same as the original. And as I've discovered in the past, I've even been able to debug aspects of the assembler ports on the C version! In the case of Asteroids, I think the ability to inspect the display list so easily will come in handy down the track.

The C version should be portable to the Amiga and the Neo Geo at the very least. For Lode Runner the C port was an after-thought of the Coco3 (6809) port, but for Knight Lore, I developed it in parallel the with Coco3 port and it was, as I mentioned, very helpful. This time 'round, I'm undecided how I'll proceed once the IIGS port is finished...

Friday, 7 July 2017

To SNES or not to SNES?

No opportunity for any development today but time to ponder random aspects of the project. I was also prompted by gp2000 to look a little further into specific aspects of the code, and discovered something that should have been obvious from the start, but escaped me until today - so thanks George for that inadvertent trigger!

I did tweak some of the coordinate transformation and video address calculations today, converting my 6502 code into 65816 and improving the resolution of some of the calculations. Always good to see a half-page of 8-bit code reduce to a few lines of 16-bit code!

And in the comments of a previous post I pondered the feasibility of porting this to the TRS-80 Model 4. Aside from the effort of porting to yet another CPU (Z80) there's also the fact that the hires board is all-but-crippled by not only port-mapping the hires video memory, but also restricting access to (vertical?) blanking periods. George suggested a hybrid mode mixing the text and hires graphics screens... very interesting but a lot of work none-the-less. I'll put this in the 'maybe' basket.

And on the subject of alternate ports, the SNES sprung to mind! I know little about the technical specifications except for the fact that it is powered by a 65816 (clone). A quick Google reveals it supports 256x224 resolution, allows 128 sprites (up to 32/line) and has the usual tilemap(s).

I'm thinking this would be a no-brainer; text would appear on the tilemap layer, with 27 asteroids, player ship, saucer and 6 shots making up a maximum of 35 sprites on-screen. Extremely unlikely that they'd all appear on the same scan line, but if I was really pedantic about it I could implement a software priority scheme. But with all the arcade 6502 code running, plus the bulk of the IIGS 65816 code available, it wouldn't be a lot of work at all. I'm going to put this in the 'almost certainly' basket, and I might be tempted to tackle it immediately after the IIGS port is done.

EDIT: Doh! It's already been ported to the SNES by Digital Eclipse!

[Makes me wonder if I should be porting that version to IIGS!?!]

That's about it for random musings. A parting fact: whilst the vector display coordinates range from 0-1023, the game's virtual playfield coordinates actually range from 0-8191. Somehow that escaped me... now consider it's all scaled down to 256x192... or in the case of the TRS-80 text mode graphics, 128x48 (128x72 if I get really tricky).

Thursday, 6 July 2017

Use the source, Luke!

In my third blog update for the day, I can report that I've all-but-finished the reverse-engineering of the arcade Asteroids 6502 code.

Aside from temporary storage, all zero page and player RAM variables have been documented. There are no variable addresses remaining for which I do not know the purpose.

About 95% of the code has been commented. There's some particularly nasty code in a few places throughout the ROM that remains uncommented at this stage; aside from some physics there's the exploding ship routine - which seems unnecessarily complex in my opinion - for example.

Importantly, I know what all the code is meant to achieve, even if I don't understand the nitty-gritty of every line in some isolated cases. It's something I'll probably have to rectify once I start transcoding to 6809 and/or C, but for now I'm satisfied that I have a well-enough commented source file on which to base my official Apple IIGS port.

From here I need to re-generate the core .ASM file and re-apply my patches for running on the IIGS. Since I annotated those patches in IDAPro, it should only take about 10 minutes before it's running again with the new source. And thereafter, I can start modifying the code 'for real' this time, including optimising for performance and incorporating pixel-shifted bitmaps.

It'll probably be a few days before I have anything rendering again, and the still screen shots will probably look no different to those I have posted already. The video should look a lot better though...

Wednesday, 5 July 2017

Great minds think alike (or fools never differ).

Interesting to dissect Norbert's Atari800XL Asteroids emulator.

The aforementioned patches to the rendering routines actually implement an alternate display list, of sorts. For all the (alpha-numeric) characters and the extra ships, Norbert adds an entry to his own display list, using the character code directly (no reverse-lookup on JSR address required). He also assigns character code $FF for the DVG CUR command, and inserts the pre-scaled Atari display coordinates. This is essentially what I had in mind for 'tokenising' the display list to optimise for the Apple IIGS.

As described in my last post, the emulator hooks the main loop and calls out to three (3) subroutines.

The first routine is (as I subsequently discovered) the rendering routine and it only renders the display every 3rd call. It does something with self-modifying code that I'm yet to reverse-engineer, before rendering the asteroids directly from the player status RAM area. Next is rendering the player ship or explosion, depending again on the player status - something I'm actually doing now as a 'quick hack'... not so much of a hack as it turns out! And as I suspected, the relative coordinates (offset) of the thrust pixel is stored in a lookup table and plotted discretely. After that, the saucer is rendered, and then the shots (saucer and player), before the alternate display list (characters) is finally rendered. At the end of the routine it appears to handle the high score entry, and then mess with ANTIC registers - and I'm way out of my depth here!

I've missed the copyright message in there somewhere, but perhaps it's done at startup and never deleted from the ANTIC display list? Not worth pursuing further since it's not relevant to the IIGS or likely any other hardware I'll be porting to.

The second hook routine emulates the inputs, and the third the sound.

And as I suspected, when the player status RAM bank switch is hit (changed), the emulator simply swaps 256 bytes between $200 and $300.

So what will I be taking away from this?

I like the idea of the alternate display list, though perhaps with the arcade 'source' it'll be easier for me to simply re-purpose the DVG shared RAM. Certainly it would appear that 'tokenising' the display list is the way to go. I would also eliminate all the dead code that makes up the current display list. And not having to iterate over player status RAM - essentially for the 2nd time each frame - should speed things up a little too.

I'll use Norbert's lookup table for the thrust, but instead use it to pre-render a 2nd set of bitmaps for the player ship. Again, not having the extra look-up and calculations to render a single pixel will increase performance further.

I should also be able to find the ship explosion bitmap(s) in there somewhere, if I can navigate the eccentricities of the Atari 800XL display hardware!

Standing on the shoulders of giants...

Undecided on how best to proceed with the remaining rendering tasks, today at lunchtime I downloaded Norbert's (Atari 800XL) emulator and fired it up in MAME, intending to plot the 'thrust' pixel in each of the 24 player ship bitmaps based purely on observation.

I've documented 12/24 but not surprisingly, it got old pretty quickly and, curiosity getting the better of me, I dumped the first 16KB of the Atari's memory into a binary file and loaded it up into IDAPro.

Before transferring control to the arcade code, Norbert's emulator patches a bunch of addresses in the ROM. Aside from those critical for running on non-Asteroids hardware (ie. the same patches I made) it also patches routines such as the 'CUR' (current) DVG command, character display, display of extra ships, etc.

It also installs a hook in the main game loop. The hook itself calls three subroutines; one to read the Atari joystick inputs and seed the memory-mapped Asteroids inputs, one to play the sounds based on the memory-mapped outputs, and the third I'm yet to ascertain.

Most importantly though, I'm still yet to determine how the emulator goes about rendering the display. From what little I've seen, the display list is somewhat 'corrupted' by the patched routines. However there are other unpatched routines that must still provide data to the emulator via the display list - so I'm not sure how it all works just yet. The waters could also be further muddied by the Atari 800XL's unique display hardware... I'm sure I'll work it all out next session.

Tuesday, 4 July 2017

Ship-shape!

I converted Norbert's ship data to my IIGS format and checked out exactly what he has rendered. There are 24 bitmaps in total, covering 360 degrees of rotation.

That is contrasted with 64 different renderings of the player ship in the arcade game. However again, at this resolution, it'd be pointless to attempt to render that many different bitmaps.

One interesting thing to note is that the player ship direction is stored as a single byte, the value varying the full range of 0-255 to represent 360 degrees. Each tap of the rotation changes the direction by +/-3, which means that coming full circle, you don't actually end up at 0 again, but rather at 255 or 2 first time 'round, and 254 or 1 next time. Not terribly important, because your direction is effectively right-shifted by 2 bits to determine which ship to render - IOW each tap of the rotation button does not necessarily change the ship rendering.

In the IIGS case, the direction needs to be divided by 24, which is equivalent to right-shifting by 4 and 5 and adding the results, although the resolution of the operation needs to be increased (easily done in 16-bit mode using the XBA instruction) to get all 24 outcomes.

Unfortunately identifying the ship in the display list is practically impossible. Rather than work out how/where to patch the arcade code, as a quick hack I simply added a routine at the end of the DVG emulation code to (always) render the player ship. Fortunately the arcade code always ends the display list with a CUR command corresponding to the center of the screen, so at least it's always rendered there and the game can be 'played' (more-or-less) as long as you don't use the thrust button!

Player ship is now rendered... sort of...

I should add that I'm yet to implement the 'thrust' indicator on the player ship; Norbert hasn't supplied me with any rendering details for this but from a quick look at his emulator video, it looks like a single pixel is illuminated for each bitmap - I just need to work out exactly which pixel!

That really just leaves the player ship explosion, another list of component vectors patched by the arcade code as it is copied to the display list. Again, there won't be any way to identify it in the display list, so I'll likely extend my quick hack to detect when the ship is exploding and render it there; enough to ensure my rendering algorithm is correct.

And that should be everything that needs to be rendered! From that point on, it's a matter of producing pixel-shifted bitmaps where required, updating the rendering routines to use them, and then finally optimise it all to eliminate the flicker and get it running at full frame rate. There'll be some use of the IIGS interrupts to throttle the frame rate, and of course hooking up proper keyboard/joystick/paddle controls and adding a fancy menu. Unlikely it'll all happen before WOzFest, but I should have a decent demo by then at least!?!

(C)1979 ATARI INC

Picked some low-hanging fruit in my lunch break today; rendering the copyright message at a more appropriate size.

Although Norbert didn't supply the source data for the copyright message, it was a trivial matter to load a screen shot from his emulator page into a graphics editor, crop the message, reduce the colour depth and save it as a Portable Bitmap File - a text-based format perfectly suited to turning into assembler source data statements.

And while I was at it, I centered the screen on the IIGS display. Again, trivial, since screen accesses are all performed via an index register relative to the start of SHR memory - a constant defined in my IIGS .inc file. Simply adjusting the constant by 4 lines and 32 pixels ($290) was sufficient to center the display for each and every rendering routine.

Centered and a less obtrusive copyright message

Now for the player ship...

Monday, 3 July 2017

A shot in the dark

Shots, as it turns out, are rendered in the display list as zero-length vectors with scale=7 and maximum brightness and thus can be uniquely identified.

So I simply added a check for such in my DVG emulation code and now have shots being displayed for both player and saucer. I added some crude keyboard mappings for fire and left/right rotate, and I can coin up, start a game and take aim at asteroids and destroy them.

Player's ship is yet to be rendered, but asteroids can still be destroyed

That leaves player ship and player explosion. The latter consists of component vector commands copied and patched from the DVG ROM routine. In theory, they are the only two remaining objects in the display list, and it may yet be possible to distinguish between the two... something I need to experiment with in order to confirm. It would be really, really nice if I didn't have to patch the original game - even if just for this exercise - and be able to render all the game graphics!

But next task is to get Norbert's player ship bitmaps converted and displayed in the correct orientation.

Sunday, 2 July 2017

Where's the kaboom? There was supposed to be an earth-shattering kaboom!

It turns out that, as suggested on the Computer Archeology page on the DVG ROM, Asteroids does indeed use the global scale in the animation of the explosion. In fact all-up there are 21 different frames of animation of the explosion, all based on the 4 shrapnel pattern routines in the ROM.

Understandably though, Norbert appears to make do without scaling at all, using 4 patterns as-is. In truth, at 256x192 resolution 21 frames of animation of exploding particles is overkill, and half the frames would probably look the same anyway. The shrapnel bitmaps, like the other objects, are confined to 16x16 pixels and likely don't render quite as large as the shrapnel on the original, but it's not noticeable at all except perhaps for the number of frames each pattern persists for. Either way it doesn't affect game play in any way.

Throughout the original animation, the global scale is changed in 6 steps from 11 thru 15 and finally to 0. What I do is simply ignore the shrapnel pattern number and instead use the global scale to display pattern 0, 1, 2, 2, 3 & 3 since the latter scales are displayed for more frames (somewhat realistically the explosion slows down).

Kaboom! A saucer hits an asteroid.

Next I'll look at the (saucer) shots, and see if they can be unambiguously identified in the display list... perhaps via their brightness and/or vector length??? If not, it's time for some 'less benign' changes to the original code!

Friday, 30 June 2017

Asteroids come in all shapes and sizes

I added the code for the various asteroid sizes; that was a simple matter of checking the global scale value in effect and adjusting the asteroid bitmap table index accordingly. That entailed 12/19 'rocks' in Norbert's source file.

As for the remainders, turns out they actually comprise the small/large saucer, 4 shrapnel (explosion) patterns, and one bitmap of the player ship at '0 degrees' rotation. Since there only appears to be a single function in the DVG ROM to display the saucer, I'm assuming that the global scale is used for the 2nd saucer - but I need to verify that.

But for now, I've added the large saucer and now I'm at the exact point where I left off the text version. But it's a good indication of how the final game will look on the IIGS. I'll likely retain the 256x192 display area, but center it on the IIGS 320x200 SHR display.

All 3 sizes of asteroids and large saucer

It should be straightforward to render the shrapnel patterns next. Although the DVG notes online suggest the global scaling factor may also be used for explosions, I can't see where that's the case when I run the arcade emulation, and certainly Norbert is not scaling them at all.

I think that just leaves the ship, shots and ship explosion. As I've mentioned in a previous entry, these (mostly) manifest themselves in the display list as component vectors, and it's not possible to differentiate the actual objects from them alone. Again, at this point I will need to decide how to optimise the process - either tokenising the display list or bypassing the list altogether.

I've also had a few more thoughts on the erasure. I'm thinking dirty rectangles is going to be easiest to implement and I'm hoping fast enough. Each time I render an object, I'll add the coordinates and dimensions of the bounding rectangle to a list. When it's time to wipe the frame, I'll iterate through the list and wipe the rectangles. After all, this is what Knight Lore did...

Wednesday, 28 June 2017

Shifty operations and bitmaps!

Graphics! Norbert Kehrer was kind enough to send me some of the graphics data from his emulator - notably the character set, the player ship, and the asteroids. Given that his emulators run in 256x192 mode, I thought I'd start with the same to enable me to use his bitmaps as-is. Well, I did have to convert from 1BPP to 4BPP mode, writing a small C program to process Norbert's ASM source file.

At this stage I haven't bothered with bit-shifted data - being 4BPP there's only 2 copies anyway - it's enough to see what it's going to look like. Since the arcade Asteroids works with a 1024x1024 coordinate system, I first had to scale down to 256x192. And it's worth noting here that 192=128+64, which means scaling down Y can be done with shift & add operations only.

And somewhat inconveniently, the IIGS SHR screen is 160 bytes wide, so to find the video address of a coordinate, you need (Y*160 + X/2). Fortunately, 160=128+32, so again shift & add operations are sufficient. These calculations are generally only required when the display list contains a command to set the current coordinate (CUR). And at the risk of bragging, my scale and address calculation routine actually worked first go! Of course that's more than offset by all the stupid bugs I had doing trivial stuff.

First task was getting the characters displayed. Rather than use more calculations to find the character data address, I simply use a table of addresses. The routine simply renders 7 lines of 2 words at the current address, then adds 4 bytes to that. It's not perfect because there's no shifted data, but it's close.

It's worth noting that Asteroids uses several different font sizes by changing the global scale factor in the DVG. However Norbert hasn't emulated this behaviour, evidenced by the relative sizes of the score and high score text. Presumably his copyright text is a single purpose-rendered bitmap. I'm undecided at this point whether I'll follow suit.

Next task was getting some sort of representation of the asteroids themselves on the screen. Norbert's file had 19 bitmaps labelled as 'rocks'; I was expecting 4 asteroids in 3 sizes each, or a total of 12 asteroids. But for the moment I'm only rendering each of the 4 asteroids as the largest size and I'll have to investigate what the last 7 bitmaps actually represent at a later date (perhaps shrapnel?)

Lastly, there needs to be some sort of mechanism to wipe data from the previous frame. At 4BPP the SHR screen is 32KB and too big to wipe completely every frame. However, for now, that will have to suffice, so the video is very flickery, and quite slow, atm. Exactly how I optimise this, I'm undecided. It's worth noting here that in 1BPP mode, Norbert would have had to contend with 'only' 6KB of video memory...

Here's a still of the attract mode, showing 4 asteroids.

Yes, the asteroids are the correct shape too!

Next task is handling the different-sized asteroids, which should actually be quite trivial. That's about as far as I took the text version because after that, it all starts to get tricky!

And a 65816 trap-for-young-players - the MVP & MVN instructions change the data bank register! That wasn't documented in the first reference I was using, and I couldn't work out why my code was going into la-la land after using them.

Monday, 26 June 2017

65C816... Meh!

Another first today - my first 65C816 program. I purposefully omitted the exclamation mark from that last sentence because it really is nothing to get excited about. In fact, if you've never written 65C816 code before, don't rush to change that.

I've replaced the apple.asm file in the Asteroids project with another named iigs.asm. Currently the startup code enables the Super High Resolution (SHR) display, sets linear mapping mode, enables shadowing, and then switches to full 16-bit mode to initialise the palette (all 2 colours in one of 16 palettes) and the SCB. The frame rendering code simply switches to 16-bit mode, then immediately back to 8-bit mode before returning to the Asteroids code.

Booting the disk under IIGS emulation eventually - after the machine boots itself and the floppy disk image - results in a black screen. I've also verified that the game is running and the frame renderer is repeatedly being called. And writing values to the SHR memory from the MAME debugger results in pixels appearing on the display. So no crashes so far...

As for the 65C816; no 8-bit memory accesses in 'full' 16-bit mode? OK, perhaps not so much of an issue if the machine is designed from the ground up around the CPU, but when you're running on an architecture with byte-wide softswitches... and interfacing to 8-bit code and data structures... you're in for a bad time.

Then there's the issue, for example, with the assembler not unambiguously knowing whether to load the accumulator with an 8-bit or 16-bit immediate value - because the mnemonics (and, incidentally, the opcode values) are identical. You have to give it hints, and hope it gets it right. A recipe for frustrating bugs if ever I've seen one.

Anyway, as a first pass, I'll be replicating the logic in the text version, and parsing the VDG display list in the same way. I suspect all the parsing code will remain (8-bit) 6502, and I'll only switch into 16-bit mode to render the bitmaps to the SHR. But first I need to prepare said bitmaps for the IIGS display.

Sunday, 25 June 2017

2600 for a day and IIGS video

A little diversion; someone posted on an Atari-related FB group about tinkering with Ms Pacman and not having much luck getting it 'loaded into a disassembler' for more in-depth hacking. I couldn't help myself and started asking questions, and of course ended up doing it myself to satisfy my own curiosity, having never done anything with 2600 before.

The complication is this case is that the 2600 only maps 4KB of cartridge space, and Ms Pacman is 8KB. There are a handful of different banking schemes implemented in various cartridges, Ms Pacman being one of the simplest. Despite that, DiStella for example, doesn't support banked cartridges though it is forgivable and not really surprising. Also worth nothing that Dan Boris is one of the authors, and there's bound to be a good reason if he elected not to support banking.

After another wildly unsuccessful attempt to understand if/how banking is supported in IDAPro, I forged ahead with Ms Pacman only to discover that the first code bank actually executes at $D000, and not $1000-$1FFF as is documented as the reserved cartridge address space. Of course with the higher address lines missing from the 2600's 6507 CPU, the machine's 8KB of addressable device/memory space is mirrored every $2000.

I then turned my attention to the second bank, loading it into a second IDAPro session - until it was revealed that this bank actually executed at $F000! No doubt making development much, much less painful, it also allowed both banks to be loaded into the same IDAPro disassembly and the banking issue all-but-ignored. I added a few other segments, notably the TIA registers, the zero page area and the PIA registers, and as a result have a ready-to-go base for reverse-engineering.

However, I should note that there's very little chance I'll be tempted to work on this at the expense of Asteroids, or even anytime soon after I'm done! From what very little perusing I did of the source, it really didn't look enticing at all, especially in light of my limited knowledge (having read Racing The Beam) that suggests programming the 2600 is just as much about coding a video hardware controller as it is about coding game logic. And although I briefly mused about porting a 2600 title to another platform, I also quickly realised that much of the code wouldn't resemble the original in the slightest.

So about Asteroids; I've done further reading on the subject of IIGS architecture, and the video memory in particular. At best it looks like you can only write to the video memory at 1MHz, though you can read back at 2.8MHz. I've also read a few interesting articles on optimisation techniques - some specifically for the IIGS - and suspect I'll be employing at least some of them down the track. But for now, I think I'm across the technical aspects enough to choose a tact and begin work on it next session.

So it's time to fire up the 65816 assembler - or rather, 65816 switch on CA65 - and see if I can manage not to crash the IIGS in 4 lines or less...

Tuesday, 20 June 2017

Insert Coin. Press Start. Player 1.

Ordinarily I wouldn't have another update yet, but my 2 yr old came into our bed this morning at 4am and shortly before 5:30am, not having had a minute of sleep since then, I gave up and went out do some more Asteroids.

The plan was to use the MAME debugger to ascertain which DVG ROM subroutines were yet to be implemented. As I expected, the first to reveal itself was the copyright message at the bottom of the screen. The routine itself draws some discrete vectors (presumably for the © symbol) before calling the character routines for the remainder of the message.

I had two choices here; simply do the same and explicitly call my own character routines in sequence for the entire message, or implement some mechanism to allow me to simply point to the DVG ROM routine and recursively execute DVG instructions. I figured the latter wasn't worth the effort - and would be slower - so I implemented the former.

Someone had also 'complained' about the flickering graphics after I posted my last video. Of course this being purely a development aid I wasn't concerned, but knowing the Apple II had two text pages, curiosity got the better of me. And I'm not claiming to be breaking any new ground here, but I did manage to implement double buffering without any conditional logic involved in the process at all.

There's not a lot more to see in attract mode alone, so I decided it was time to properly initalise some dipswitches and hook up some crude control panel inputs. I settled on two hook routines, apple_reset and apple_start, that get called at the end of the original reset and start routines respectively.

In apple_reset, the hardware I/O locations - such as dipswitches - can be initialised. Since they map to normal Apple II RAM locations, all that is required is to write the appropriate value to the respective address. Thus far I set the coinage and the number of starting lives.

In apple_start, the Apple-specific initialisation code is run. Here I'm currently setting up the page flipping logic, and clearing both text pages.

As I've mentioned in the past, the NMI routine in the arcade code handles the coin switch inputs. Other inputs are read in the main game loop, once per frame. For the moment though, I simply added a few lines to read the Apple II keyboard at the end of my frame rendering routine. Pressing <5> will insert a coin by simply incrementing a zero page shadow value, and pressing <1> will start a game by setting a bit in the hardware I/O location (mapped to Apple II RAM) - for 1 frame. That's enough to get a game started and running.

I then added the display of the remaining ships, mainly because it was trivial. Unfortunately with only 16 lines on the screen, they overwrite the score, but the point is that it's more evidence that things are running as expected. The next obvious object to implement was the player ship...

video


...and here is where things start to get more complicated. The DVG ROM indeed has a table of 17 subroutines for drawing the ship (and optionally the thrust), not unlike other objects. However, these 17 ships only cover 90 degrees of rotation. As a result, the 6502 can't simply add a JSR to the player ship routines into the display list.

Instead, the 6502 copies the component instructions (vectors) from the above-mentioned DVG ROM routines into the display list, adjusting each on-the-fly for the current direction. So when the Apple II rendering code comes to the player ship, it's simply a list of CUR and VEC instructions - nothing decidedly identifiable as the player ship object!

So how do we solve this? In a rare coincidence, the solution is actually an optimisation as far as an Apple port goes - and there are also a few options. The most straightforward is to replace the 6502 routine for the player ship entirely, bypassing the display list and directly rendering the appropriate bitmap on the Apple display. One step removed from that is to 'tokenise' the display list entry; rather than add the component vectors, simply add a 'token' command to display the player ship that the Apple rendering engine can parse. Both have pro's and con's.

At this point though, I think I've taken the text-based proof-of-concept engine as far as I need to. It's time to make the switch to the 2.8MHz IIGS, consider writing the rendering engine in native 65816, start working in graphics mode, and decide how best to solve the latest issue.

Monday, 19 June 2017

ASCIIroids

I've managed to avoid it for 40 years now, but there was no putting it off any longer; today I wrote my first 6502 code ever (I don't think I'll ever be the same again!) 😮

The first task though was to add another source file to the project and have it link to the main Asteroids code. Thus all the Apple-specific code is contained within the one source file, leaving the original code more-or-less untainted. This code ends up residing at $8000.

Aside from the previously mentioned two (2) simple patches, today I added a subroutine call at the end of the main loop, after the display list for the frame has been generated, to my Apple-specific rendering function in the second source file.

Now the exercise today was to implement something as quickly (easily) as possible in order to see something rendered on the display. To this end, I decided to brave the Apple II video memory mapping, stick to 8-bit mode and render (only) the characters on the text screen.

The rendering routine clears the Apple display, and then iterates through the display list, interpreting the Digital Video Generator (DVG) instructions and updating the Apple video display accordingly. I chose to implement a jump table for the DVG opcode handler routines, and after musing on how this could be done on the 6502, I concluded that one could make use of RTS; and I was subsequently pleased to discover it wasn't a silly idea.

With stub routines in place, the rendering routine iterates through the display list until it encounters the HALT instruction, which the 6502 code places on the end of every frame. It then returns control to the arcade 6502 code to update the game logic and render the next frame.

I'll reiterate something I posted earlier in this blog; I've no intention of - and there's no real need to - render individual component vectors for all the objects. The DVG ROM contains subroutines for drawing each of the objects, so it is sufficient - for the most part - to simply ascertain which object is being drawn, and render it as a whole on the Apple II display. Note that this extends to characters as well as graphics objects.

As far as the DVG emulation goes for today's exercise, I need only implement the CUR instruction (which sets the current beam position) and the JSR routine (which jumps to a DVG ROM routine). For the CUR opcode I simply extract the (10-bit) operands and store them in zero page memory for future reference. At the same time I also create 5-bit (0-31) and 4-bit (0-15) equivalent values for X, Y respectively to represent the Apple text mode coordinates.

For the JSR opcode, it will penultimately be a huge look-up table of object-drawing subroutine addresses and their corresponding Apple equivalents. As it transpires, the DVG ROM already has such a table for the 37 characters, so my JSR opcode handler checks against this table to see if it's a character. If not, it ignores it and returns, otherwise it converts the subroutine address into the corresponding Apple II character code, and then displays it at the aforementioned 'CUR' address on the screen. (I also cheat a little here; ordinarily the current position will have to be updated after displaying a character, but for today's exercise I simply increment the text mode X coordinate).

The end result is a recognisable display, with Player 1, Player 2 and High Scores, and a flashing "PUSH START". For those wondering, the copyright message at the bottom of the screen has its own DVG subroutine, and will therefore have to be handled explicitly in the DVG emulation.

video

Not bad for a few hours work, and my first 6502 program!

UPDATE: Added all three sizes of asteroids (#,*,+) and the UFO (@). In attract mode you can now see the asteroids getting hit by the UFO and breaking into smaller rocks!

Sunday, 18 June 2017

Asteroids on the Apple II - coming soon to a screen near you!

I was woken at 4:30am this morning with the knees of my 2 yr old son wedged against my back. As you do at my age and you're woken through the night, I stumbled to the bathroom and, still half asleep, took a seat.

Why am I telling you this? Because this blog is all about the process, as well as the technical details, and to this day I still marvel at the circumstances under which my brain still manages to have epiphanies. I'm not sure I even consciously realised I was thinking about Asteroids, but at that moment it came to me that the Digital Vector Generator (DVG) ROM was (also) mapped into the 6502 address space, and that the 6502 code was reading it whilst generating the display list. And of course that ROM was conspicuously absent from the Apple II binary image.

Well tonight I rectified that situation and, after battling IDAPro for a while getting a second binary file loaded into the correct segment at the correct address, was soon able to generate a now-12KB binary that included both the DVG ROM image and (patched) 6502 ROM image.

[As an aside, it only occurred to me during all this that the Apple II .BIN file format is woefully crude, lacking not only the ability to load a single file into a non-contiguous address spaces, but also lacking an explicit execution address.]

Anyway, first order of business was again comparing the display list of the first frame with that generated on arcade hardware. Gone were the large groups of zero bytes; it looked roughly the same size now, and a lot of the data was the same, but it still differed.

Before going further I needed to confirm that the contents of the display list are completely deterministic. Asteroids explicitly zeroes working RAM, so that wasn't the issue. It also makes many calls to a pseudo RNG routine - it's a 16-bit single-tap (IIRC maximal-length) LFSR for those interested - but thankfully none from the NMI, which isn't running (yet) on the Apple version. I couldn't see any other reason to suggest it wouldn't be deterministic. And to be sure, I ran the arcade emulation twice, and the 600th frame on each occasion was identical.

Since the first byte differed, I set a breakpoint in the MAME debugger where it was written to the shared (display list) memory. Not surprisingly, it was a low-level routine that revealed nothing of the origin. Here's where the trace command in MAME comes to the fore; I was able to manually trace back through the code, and see where either the data, or the execution path, differed between the two platforms.

In this case it happened to be the value read back from a coinage dipswitch (or rather shadow zero page value to be precise) that differed. The Apple II version was, not surprisingly, reading back as zero which was freeplay!

I simply fired up the arcade emulation, changed the dipswitch to read back as zero, and compared the first frame of each again. Identical! Then I compared the 600th frame from the arcade version with the Apple version. Eureka!

So now I have the arcade Asteroids 6502 code executing on the Apple II, producing identical output!

To be honest, the whole process has actually been a little less painful than I had expected. All that is required to get this far is patching 4 bytes in the 6502 ROM. I guess like the old joke about the X on the pipe; it's not the value of the 4 bytes that's the hard bit, it's knowing which 4 bytes to patch!

So what's required now to get a playable game?

My next step is (probably) going to be building the code to render the display list to the Apple II video every frame. At this point it'll be a simple matter of calling the routine once from the main loop once it has rendered the display list, immediately before it returns back to the start of the loop. At least I'll get to see the attract mode running.

I should note that the game on the Apple is currently not throttled in any way at all - it simply generates frames as fast as the 6502 code runs before looping back for the next frame. On the arcade hardware, the NMI provided a periodic 'interrupt' to drive the timing of the main loop (now patched out). So at some stage I'll have to add that back into the Apple build.

The NMI also had the task of reading all the hardware, debouncing controls, and formatting it all into shadow variables in 6502 RAM. This is where the Apple II code will differ quite a bit, reading keyboard, joysticks and possibly menu settings.

I'll touch on the sound at a later date.

It's quite neat that the core 6502 code will be running pretty much untouched. I can see now why Norbert simply loads the original arcade ROM images into his emulators and (likely) patches a handful of bytes. The Apple II-specific code will be confined to the NMI and display hook routine.

Of course it also allows alternate display hook routines; different video modes and/or even different platforms. Interesting possibilities...

Friday, 16 June 2017

Furphies, running Asteroids code and corrupt display lists!

The undocumented instructions were a bit of a furphy in the end; as George rightly suspected both instances were a result of a bad disassembly. A single byte immediately following a BEQ instruction turned out not to be code, and ignoring that byte produces a more sane disassembly. Unlike the Z80, a good portion of the 6502 instructions affect the Z flag, and in this case the branch will always be taken. A symptom of me not finishing the RE process completely.

On to more interesting developments; simply commenting out two (2) conditional branches in the main loop allows the code to run though unimpeded. FTR the 1st branch is waiting for the 60Hz 'VBLANK' interrupt and the 2nd is waiting for the DVG to finish rendering the previous frame.

As a result, the game code is running in (I'm assuming) attract mode, continually writing display lists to the shared RAM for each frame. And that's actually what I'm seeing in the MAME debugger!

However it's not all good news; although the first frame renders correctly (all of 4 bytes), the second and subsequent frames (in the order of 128 bytes) do not. The data starts off OK, then differs for a bit and then leaves a large gap of zero bytes, before continuing. However the last group of bytes also appear to be correct. And just to cover all bases, I replaced the above-mentioned conditional branches with NOP instructions so that the rest of the code was identical - same result.

Anyway, I only got a very brief period to work on this tonight, so haven't had the chance to investigate further. And as of right now, I have no concrete theory. Perhaps it's not running attract mode at all, but rather going into Service Mode? But why the zeroes? My next course of action is to feed the display list generated on the Apple II into a DVG emulator, and see what pops out!

Thursday, 15 June 2017

Assemblers, undocumented instructions, and assumed addressing modes.

First order of the day; a helpful fellow developer has pointed me towards c2d, a command-line executable that creates a 'quick booting' Apple II .DSK file from a .BIN. So now simply typing 'make' assembles all my source and subsequently produces - in less than 1 second - an image I can boot in MAME.

Next: getting the arcade Asteroids source listing assembling in CA65. Not surprisingly IDAPro doesn't have direct support for the CA65 assembler. I briefly investigated the option of adding support via the IDAPro SDK, but it requires modifying and rebuilding the processor support module and I haven't have much success in doing so in the past.

Fortunately the supported SVENSON ELECTRONICS 6502/65C02 ASSEMBLER - V.1.0 - MAY, 1988 turns out to be a pretty close match; in fact, ultimately a single search-and-replace is sufficient to fix the pure syntax issues. [This is important since I will need to re-generate the source from IDAPro at some point in the future when I complete the reverse-engineering]. And once I explicitly defined the ZEROPAGE segment, only one syntax error remained.

The assembler had barfed on a DCP instruction. That didn't sound familiar to me, so I consulted my trusty ZAKS 6502 bible. No mention of it. Perhaps it has an alternate mnemonic? Google quickly revealed the problem - it's an undocumented opcode! After some further reading of the CA65 manual, I discovered a command-line switch to enable (some of) these opcodes. With relatively little effort, I now had the arcade Asteroids source code assembling under CA65!

I noticed, however, that the assembly was not producing the same number of bytes as the original, evident by the address of the last (IDAPro auto-generated) label in the assembler output listing. Somewhat fortuitously as it turns out in this case, IDAPro (by default) auto-generates labels that contain the address, making it easy to spot a mismatch against the assembled address.

Tracing back through it, I found the first instance of a mismatch; the code was referencing a zero-page variable via absolute (16-bit) addressing. Since the syntax of CA65 doesn't make a distinction between the two, it was assuming zero-page addressing and generating a different (length) opcode. As it turns out, this is the case in no less than 7 instances throughout the code (most in the same subroutine). I suspect the original assembler did make a distinction, and the programmer simply used the wrong addressing mode a few times, or possibly moved a variable from RAM to the zero-page at a latter stage of development.

After some further Googling I found the solution - forcing absolute addressing for an instruction - buried in a post on the NESDEV forums.

Either way it makes no difference to the outcome, but I do (first) want to verify that I am able to produce an exact binary using CA65. And for authenticity, I would prefer it does run the exact same code as far as possible.

One last mismatch was another undocumented instruction - SKW - this time, unsupported by both IDAPro and CA65. IDAPro disassembled the 3 bytes into a single NOP, which of course CA65 in turn assembled to the single byte $EA. No choice in this case but to define three constant bytes in place of the instruction.

Finally, CA65 appears to produce the same number of bytes as the Asteroids ROM. Indeed, after some further munging I have been able to confirm, via binary file compare, that the output is identical.

The issue now is getting the segments and .ORG statements in order to load at the correct address in Apple DOS (right now it produces a contiguous binary that loads at $0000). For that I need to so some more reading, and experimenting. But decent progress thus far.

UPDATE: The binary produced by CA65 now contains only the Asteroids (ROM) code and loads at $6800 in the Apple IIe emulation under MAME. The initialisation code runs, and it loops waiting for the 'VBLANK' (NMI x4) interrupt - as you would expect on non-Asteroids hardware!

Insert naughty words about CiderPress here!

Most of tonight was spent banging my head against a press. CiderPress to be specific.

Tonight started well as I managed to discover an Apple II 6502 assembly hello world project that actually used make and CA65/LD65 as the toolchain - exactly what I was after! This was going to be easy...

Building the example was trivial, and that left me with a .BIN file. The makefile, however, used a utility called dos33 to write to the .DSK file which I do not possess, so I simply INIT'd a new disk with a simple HELLO program (I'm becoming quite the DOS 3.3 guru), loaded it into CiderPress, and after selecting the right options imported the .BIN file. Couldn't be simpler, right?

Except I couldn't execute my .BIN file in DOS 3.3 under MAME. Or more specifically, it would crash to the monitor. Hmm...

After the obligatory delete and try again, I researched how to produce .LST and .MAP files, took a quick look at the .BIN file (noticed a 4-byte header), and then tried to locate my program in Apple II memory under MAME. It simply wasn't being loaded at the correct spot, or indeed anywhere I could ascertain.

I initially suspected it was being overwritten by BASIC as soon as it was loaded ($0803); tried changing that to no avail, but then soon decided this track was a red herring after all.

Time to research Apple II DOS 3.3 .BIN file formats. Somewhat frustratingly, it didn't appear within the first few Google hits, or even the next few. I finally found a paragraph detailing the 4-byte prefix in a text file at the bottom of a locked filing cabinet in a disused lavatory with a sign on the door saying "BEWARE OF THE LEOPARD!" My .BIN file looked good so far.

Then I noticed a column heading in the Ciderpress disk viewer called Aux, and wondered what it meant. After taking a little too long to find in the help file, I finally discovered it was supposed to be the execution address of binary files. Mine showed $0000 instead of $0803. Hmm....

Time to grab a random .DSK file from the net and see what CiderPress displays in this column. Apple Panic seemed a good candidate - and each of the several binary files in the image had non-zero addresses. So what was I doing wrong with the import process?

All this had taken a few hours now, and in my desperation - before I succumbed to posting questions on forums - I tried Googling for answers. What I did find was another Apple II hello world tutorial, using what looked like the same source, but this time using CiderPress to transfer the binary to a .DSK file. Bingo!

Let me just say that CiderPress's (seeming) inability to import a standard (adorned) DOS 3.3 .BIN file onto a .DSK image file is, well, simply preposterous! So much so in fact, that I'm not even sure I believe it can't be done! Regardless, as the link infers, I needed to strip off the 4-byte prefix (using dd in my makefile) and then rename the file with the numeric filetype and execution address in the filename. I am speechless. I am without speech.

After all that, I quickly changed a few filenames, modified the example and here we have the very first build of Apple IIGS Asteroids.

My first Apple II program - ever!

Next task is to find a command-line utility that allows me to write my .BIN file to a .DSK image file. There seem to be a few options out there. That's going to be essential as I'll be building this hundreds of times over the next few weeks & months. Right now the biggest bottleneck is waiting for DOS to boot on the Apple II emulation.

Once that's done, I'll need to convert the arcade Asteroids source code to the format that CA65 uses; I'm hoping that won't be too painful as I'll likely have to do it a few times as I finalise the reverse-engineering at a later date.

Wednesday, 14 June 2017

Apple II cross-development 101

My initial task tonight was to set up an emulation environment for the II/IIGS and ensure that I could boot arbitrary disk images; ultimately that will be my Asteroids disk. My emulator of choice is MAME and for this exercise I downloaded the latest version, v0186.

Knowing next-to-nothing about Apple II DOS variants, I did some quick reading of some historical and high-level technical details and decided that it would be useful to be able to boot and work with both DOS (v3.3) and ProDOS 8 (v2.0.3 & v2.4.1) disks. It may interest some to know that only last year, ProDOS 8 received an (unofficial) update, the first since 1993!

Now that I was able to boot both DOS and ProDOS in Apple IIe & IIGS emulations under MAME, the next issue was getting Apple II executable files from the host OS (Win7) into the aforementioned .DSK files. Two options that revealed themselves with little effort on my part were CiderPress and MAME's own imgtool, although the latter only seems to support ProDOS disk images. Though I haven't actually performed an import just yet, I'm satisfied that this process will be straightforward enough.

The last - or rather first - step in the chain is producing the executable itself. Given past experience with retro development there's no question that I will be cross-assembling, and there's a handful of solutions in this regard. Initially I was keen to stick with AS6500, even if it meant writing my own utility to convert the binary output to an Apple II executable file (as I have done in the past for the TRS-80), or even extending ASLINK to do so as Boisy Pitre has done for the Coco, but after further deliberation and considering time constraints I've decided to at least start with AS65/LD65, the assembler and linker respectively from the now defunct CC65 package.

So that ties down the first iteration of my development environment.

Hopefully next session I can write a simple hello world program for the Apple II, assemble and link it with AS65 & LD65, copy it to a DOS 3.3 .DSK image file with CiderPress, and boot it under Apple IIe emulation on MAME.

Then I'll be half-way there, right?

Saturday, 10 June 2017

A tale of two CPUs

Not much progress... well, none to be exact... on the reverse-engineering front but I have been researching IIGS architecture and development.

The plan for a first-pass demonstration is to leave the 6502 code more-or-less intact, changing only what is required to get it running on the IIGS. Aside from possibly changing some addressing, the only other changes that come to mind immediately are the interrupt, and handshaking with the digital vector generator (aka DVG).

The result of the above should be an area of IIGS memory that is periodically updated with a new display list for the DVG.

The intention then is to implement a crude emulation of the DVG, or more precisely, an emulation of what the DVG is doing on Asteroids, that reads the display list and renders to the IIGS super hires display. I'm not planning on drawing vectors on the screen, but rather using a crude lookup to determine what the DVG is supposed to draw, and then display pre-rendered bitmaps at the appropriate screen location. This is possible only because most of the objects are actually rendered via subroutines in the DVG ROM; once I know the subroutine address, I know what object is being rendered.

Once all that is going, there's plenty of work to do to optimise the whole process by more tightly integrating the main code with the rendering code. I have some ideas about that already.

My conundrum now is whether to develop the rendering routines in native 65C816, or remain in emulated 6502 mode. I'm leaning towards the former, but it does introduce some complexities to the process, such as assembling effectively two completely separate programs, for different CPUs. And likely different assemblers, as I'd probably stick to AS6502. OTOH, it will avoid the addressing limitations, and some of the slowdowns, of remaining in 6502 mode. Not to mention, well, 6502...

Time is ticking towards WOzFest so I'd like to get a start on this sooner rather than later. I still need to sort out the emulator I'll be using (preferably MAME), and exactly how to go about executing a binary built from a generic assembler on an emulated IIGS. Guessing I'll be learning something about Ciderpress soon enough.

Tuesday, 30 May 2017

Between a rock and a hard place

OK, without further ado, the mystery project is... Asteroids - the arcade version of course!

Image from playertheory.com

Nobert Kehrer did much the same first for the Atari 800XL, then for the Commodore 64. So I won't be breaking any new ground, but rather leveraging off the work done by Lonnie Howell in the original reverse-engineering effort and of course Norbert's so-called emulators. I've managed to advance Lonnie's work so that - as it stands - a good portion of the code is now commented, and Norbert has been kind enough to answer technical questions and even permit me to use his rasterized graphics data.

I'm confident now that I know enough already about Asteroids itself to port to other platforms; the task now is to learn enough about each of the target machines to effect the ports.

I've decided that I'll tackle the Apple IIGS first - a machine I currently know very little about. I've done some reading up on it tonight, and learned at least that it's possible to use the enhanced graphics modes (with sane memory maps) with the CPU in 'emulation' (6502) mode at 2.8MHz. 6502 mode does, however, place some restrictions on both resources and performance, so it remains to be seen whether or not I do indeed need to switch to native 65816 mode.

I was hoping to keep the code as legacy 6502 for two reasons. One, it negates the need to port the bulk of the code to a new CPU and two, it would leave an option to produce a version for Apple II/+/e machines with an accelerator card, requiring only rework of the graphics routines. Only time will tell...

The main impetus behind doing the IIGS port first is the fact that the next WOzFest meeting is slated for a IIGS theme and will coincide with the 2017 KansasFest (possibly with a live hookup). So I thought being able to demonstrate a new IIGS game on the day would be pretty cool.

As for Coco3, that's probably a lot more straightforward for me as I've done three ports to it now (Lode Runner, Knight Lore and Space Invaders), but of course requires translation from 6502 to 6809.

At first glance, having a 6809 version would make the Vectrex an obvious target, but unfortunately the stock console has insufficient RAM. However there exist several multi-carts that include additional system RAM, so a port may yet be worthwhile. The technical challenge there is to squeeze out enough performance from the 1.5MHz 6809 to emulate both the 1.5MHz 6502 and the Atari Digital Vector Generator (DVG). Perhaps a tall ask, but relatively little effort for a proof-of-concept demo at the least.

Monday, 29 May 2017

The home stretch on the reverse-engineering

Good progress tonight now that all-but-a-few variables have been labelled!

If I had to guess, I'd say the code annotation is now 75-80% complete. Hopefully only a few more sessions until it's done. There's a few details I need to confirm via experimentation with MAME but it all seems to make sense for the most part.

Even right now, there's easily enough information to start on any of the ports.

And more good news; the author of the original 'emulator' has supplied and given me permission to use his graphics data in my ports, which will only make my job easier!

Friday, 26 May 2017

Variables disclosed as I reconsider the Vectrex

After some discussion with jmk (which can be seen in the comments of the previous post) I'm now reconsidering a Vectrex port. Given there exist a few multi-carts with RAM expansions, I think there's still enough of an audience to make the port worthwhile, especially considering I'll have a 6809 core for the Coco3 - even if it is just a 'proof of concept' playable demo.

That decision aside, just as I was getting bogged down trying to determine the usage of the player data RAM blocks, I notice that much of the work has (recently?) been done for me on a well-known reverse-engineering website. It really is getting to the point where I should reveal the project...

But for now, I'll take this new information and persist with the reverse-engineering whilst the code is relatively self-explanatory. If and when I do hit another brick wall, I'll turn my hand to starting one or more of the ports. I have a deadline for the IIGS port at least...

Wednesday, 17 May 2017

No Vectrex port this time 'round.

Well, that'll teach me - again - not to get too far into a project without checking all the details for intended porting projects! Turns out the Vectrex isn't going to have enough RAM for this port, even in 1 player mode. Wondering if it's possible to design a cart with some SRAM - the connector does have a RW# signal... oh well, it was never the primary target anyway...

As I mentioned, reverse-engineering is getting to the nasty stuff (nitty gritty) and I'm considering commencing the actual porting. My targets now include Coco3 (6809) and Apple IIGS (6502/65816), so I now need to decide which avenue to take. Would be nice to have the IIGS version at least running - if not finished - for the next WOzFest, but given my limited time recently it's a tall order!

Monday, 15 May 2017

Slow going, time to start porting?

Slowly, slowly chipping away at the code; not that I've had much time to spend on it lately, but it's also slow going as all the low-hanging fruit has been... commented!

I'm starting to think that it's time to start on the port, and perhaps work in parallel with the rest of the reverse-engineering. This approach worked reasonably well with Knight Lore, and I've certainly got all the hardware figured out to a point to allow me to do so.

If so, then I'll start with the 6809 port - but not for the Coco3!

Monday, 17 April 2017

Update 'tweet'

The 'new project' continues - more reverse-engineering tonight.

I'm in two minds as to whether or not I should reveal what it is. On the one hand, I don't want to preempt something that may never happen; on the other, why the big mystery?

If I haven't mentioned already, I'm thinking of porting to the Apple IIGS (as well as the Coco3).

Wednesday, 12 April 2017

Not Space Invaders

After more-or-less finishing off Invasion Force, work has kicked up another notch and I've had very little time for anything else. And unfortunately, retro ports is pretty low on the list of priorities at the best of times.

Tonight, however, I had a spare hour or so and returned to reverse-engineering the new project. Yes, I have neglected Space Invaders yet again, but the ramp-up time alone on that project exceeds my spare time atm. At least I was able to comment a few more routines (eg. scoring) and a data table.

At this point if I had to make a guess, I would say I'm about 25% of the way through the reverse-engineering process. But working haphazardly on the project isn't conducive to making quick progress, and if I continued at tonight's pace it would take me several years to get it done. To work efficiently it all needs to be fresh in your head which of course means regular sessions.

I'd like to think I can find some small amount of time each evening in the coming weeks to work on this, but I know from past experiences it's usually feast or famine... all I can do is try.

Thursday, 30 March 2017

Star Trekkin' Across The Universe...

No-one will be surprised that I've been side-tracked... again.

This time, it was Dan's fault for asking on one of the TRS-80 groups if anyone had fond memories of Invasion Force, as he was re-coding it in some modern scripting language, or something like that. And if that wasn't dangling the carrot tantalisingly enough, he even posted a screen shot of his progress!

Invasion Force was a machine language 'real-time' version of the classic Star Trek games that was sold by Tandy for the TRS-80 Model I. Although in my opinion not as good as Time Trek, I did play it back in the day and do recall enjoying it.
 
Invasion Force on the TRS-80 Model I

A bit of research yielded some surprising information; the game was first written for the SOL-20 microcomputer, and released as TREK 80. With the demise of the company Tandy somehow got hold of the source code, ported it to the TRS-80 Model I, and released it as Invasion Force.

The original SOL-20 version, TREK 80

Anyway, I decided to dig it out and, as any retro porter worth his salt would do, immediately start disassembling it. If nothing else I'd be able to provide Dan with some "inside information" should he ask.

In the end, it was a pretty straightforward task. It's not the most elegant or efficient Z80/TRS-80 code that I've ever seen either, but to be fair it was written in 1977. After completely reverse-engineering the TRS-80 version, I went back and named all the labels in the SOL-20 version. It's clear minimal changes were made to the code when porting to the TRS-80.

CORRECTION: It was, of course, 8080 code, rather than Z80.

When reverse-engineering the TRS-80 version I discovered two bugs.

The first bug has been ported from the SOL-20 version. Not worth the long-winded explanation but it's basically a table-lookup that extends beyond the table bounds during a delay routine when you run into a star - it's quite benign when all is said and done.

The second bug was introduced into the TRS-80 version. One of the experimental ray (random) outcomes is supposed to render all Jovian vessels in the quadrant invisible; instead it renders all Space Stations invisible. Because the SOL-20 and TRS-80 versions use different characters for their short-range scanner displays, the value(s) representing the Jovian vessels in the code had to change, and it was changed to the wrong value.

There are remnants of code in the TRS-80 version that isn't called that appears to be debug code. There's extra code - in the same spot - in the SOL-20 version that I haven't looked at yet. There are also some very minor tweaks to the TRS-80 version, some of which result in "dead code" from the original. And one hidden command not documented in the TRS-80 manual is the "L" command to leave the game, which jumps to the Level II BASIC entry point. Somewhat confusingly, the TRS-80 manual implies there is an "L" command for Long Range Sensors - so I expect people tried this and had the game subsequently 'crash'!?!

I now have a TRS-80 version that is fully relocatable, builds and runs. Someone suggested changing the directional controls (0-7) to more sensibly map those on the numeric keypad, which I might do. It's also tempting to convert the text to mixed-case, and fix the experimental ray bug.

And what about porting it to another platform? Aside from the Microbee, which could be done in a single afternoon, I doubt there'd be sufficient interest to warrant the effort. Every platform under the sun already has several Star Trek clones, and Invasion Force doesn't offer anything exceptional.

A fully-commented disassembly listing for the TRS-80, a fully-labelled listing for the SOL-20, plus the relocatable TRS-80 source, can be found on the Project List & Downloads page to the right.

UPDATE: I've added a few enhancements to the TRS-80 version, each of which can be individually enabled/disabled in the build. These comprise:
  • ORG $5200 for compatibility with disk systems (source is fully relocatable)
  • Mixed-case messages throughout the game
  • Fixed the Experimental Ray bug that makes Space Stations invisible instead of Jovians that was introduced in the TRS-80 port (untested)
  • Modified direction controls to map to more intuitive numeric keypad layout
Full source and binary in the zip archive.

Monday, 20 February 2017

time=950 billion ms

Well, unexpectedly I received responses from both programmers on the same day, and both were supportive and helpful which is great!

There was some confusion about which revision of the game ROMs I should be using as my starting point, but that's now sorted. Fortuitously (although not critical to my needs) both the reverse-engineering effort and the port/emulator are based on the same revision!

After the feedback I received I've officially decided on the next Coco3 port.

But back to Space Invaders for now...

Thursday, 16 February 2017

Ping timed out.

Just a quick note to say that I am still working on Space Invaders. Slow going as I'm still coming up to speed with how it all works again, but at least now the shields are in approximate position, albeit yet to be rotated.

Interestingly a thread in an Apple II programming group led to a brief discussion on Apple Invader. Now that was an impressive home conversion back in the day, and would have been a little easier to port to the Coco3 than the arcade original... but not quite as cool?


Still been thinking about the next Coco3 project. It would be fair to say that this game is an unlikely candidate for a Coco3 port due mainly to the hardware used, and that's a big part of the attraction for me. Surprisingly it has actually been ported to other 8-bit machines! I've approached two different programmers that have worked on either reverse-engineering or porting the original, but neither have deigned to respond thus far.

Never mind, I think I have the technical details worked out. Just would have been nice to compare notes and perhaps get some insight into the performance I could expect on the Coco3 without having to employ further trickery...

Tuesday, 7 February 2017

The Space (Invaders) - Time Continuum

With Lode Runner and Knight Lore in a holding pattern for very different reasons, as promised I turned my attention back to Space Invaders tonight. It wasn't easy as the temptation is there to start on a new port altogether, but I'm resolved to finishing off the existing ports before starting any more.

[On that note: not-so-good news for Coco fans is that the C port of Lode Runner (Neo Geo plus other platforms) will be next on the list and then finally I intend to return to Donkey Kong on the Neo Geo now that my NeoSD AES should soon be shipped! However I still have at least another two, and possibly more, Coco3 projects in mind that I'm keen to start!]

Nothing terribly exciting to report but tonight I have reverted all my on-the-fly rotation code and gone back to 12th May 2016. Somewhat prophetically, I last backed out these changes on... Friday 13th May 2016! I do, however, need to review some fixes I did subsequently after moving the video RAM base address.

As it stands attract mode runs (with rotated text) and the alien rack is displayed (also rotated) before the game appears to crash with small areas of corruption on the screen. Encouragingly, this is exactly what the SVN log describes!

Attract Mode (crash)

For latecomers: I should note that (behind the display) the Coco3 port is actually completely finished; you can coin up and play a game on a rotated monitor. What I'm in the process of doing now is modifying the code (and sprite data) to display in the correct orientation on the Coco3. Essentially, I'm (simply) rewriting all the rendering routines. It's a bit more complicated than that, but (hopefully) not terribly so.

No doubt it'll take a bit of time to come up to speed with where I was at and in the process I'll probably remind myself of why I opted for the on-the-fly tack... but ultimately this is unquestionably going to run fast enough (with enough headroom to add sampled sound), and the alternate wasn't looking quite so good.