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