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.

Sound advice

Recently I've been looking at the Lode Runner sound issue (sound is all-but-muted when you enable the joystick) and last night I managed to solve it.

It took a bit to wrap my head around the correct configuration of the two PIAs for joystick and audio support, further muddied by the fact that the Coco has both 1-bit and 6-bit DAC sound generation. Fortunately I found a rather helpful block diagram that Tim Lindner put together that finally enabled me to visualise how all the bits work together.

I had originally assumed that my joystick sampling was inadvertently muting the sound. What should have tipped me off though was the fact that the sound was still there, just very much lower when joysticks were enabled. It turns out, however, that my problem was that I was not muting the sound; the circuit was mixing the 1-bit sound (which FTR can't be muted at all) with whatever state the joystick sampling left the DAC in and the result was barely audible sound from the game.

Once I muted the (DAC) sound during initialisation,the rather basic beeps and boops that are Lode Runner sound were perfectly audible, joystick or no (new release available on the download page linked to the right).

And since I had used the same routines for Knight Lore, it had the same issue - which has subsequently been fixed.

I have been thinking more about the release of Lode Runner (in particular) in the past week or so. When I first ported it I really wanted it to be a cartridge release; not to make any money but just to have at least one tangible Coco product to my name. My thinking was to create a flash cartridge with Lode Runner on it, that the buyer could also use for any other purpose.

However Jim Brain over at RETRO Innovations recently designed an 8MB Flash Cartridge for the Coco line of computers which also includes (and I may have suggested this) a serial EEPROM and (I definitely didn't suggest this) Orchestra 90 emulation.

Although this product is certainly overkill for Lode Runner, it's also - I feel - too expensive to sell as a game cartridge. I'd also like the Lode Runner cartridge to be housed in one of the new shells recently produced for the Coco, with its own "Lode Runner" label.

At the same time I don't want to re-invent the wheel, so in the last day or so I've had the idea to produce an EPROM-based cartridge with a small CPLD for banking and a small serial EEPROM for high score saves etc. Ideally such a cartridge would accept up to, say, 256KB EPROMs (although 1MB would be better) and would be suitable for my other current and future porting projects. The primary design objective is keeping it simple and cheap.

If that gets off the ground then Knight Lore should follow suit soon after.

Shortly I'll turn my attention back to Space Invaders, and finish off the coding for the hand-rotated version, which should have no trouble running at speed on the Coco3. I hope then to be able to add sampled sound, and I have always intended to release it - with source code - for free. Perhaps there'll even be a cartridge release for people that really want one?

Monday, 30 January 2017

Knight Lore all-but-complete!

Today/tonight I fixed the RNG seeded by the ZX Spectrum FRAMES system variable, which determines starting location, amongst other things. Now, at least, the starting location is actually random.

The final fix was the sun/moon graphics glitch on the left/right sides of the frame, invisible on the ZX Spectrum because of the video attributes in use. For the Coco3 port the easiest fix turned out to be simply manually extending the frame sprites, with respective masks, which (IIRC) is what the Amstrad CPC port (and likely others) do.

No more sun/moon graphics glitch left/right of the frame!

The only thing left is to tweak the ballast code in the main loop to slow down 'empty' screens. I've made a quick attempt but will probably spend more time comparing against the ZX Spectrum version before it is finally released.

I've sent out a few copies for testing and review... so hopefully it'll appear on YouTube at some point in the near future!?!

Still undecided on release options...

Sunday, 29 January 2017

A (K)Night of Random (Number) Thoughts

It actually took a couple of more sessions but I've finally got joystick support working in Lode Runner. Thankfully there don't appear to be any key ghosting issues. I've packaged up a release which is available from the download page (link to the right).

I need to talk to a few people about cartridge hardware, but I'm leaning towards simply releasing a floppy disk version for free, rather than have it sitting on my hard disk for another 3 years! It was never about the money, but rather the satisfaction of releasing something tangible for the Coco3.

I also did some further work on Knight Lore tonight, in preparation for another release to a tester and a reviewer. I beefed up the random number generator which 'emulates' the Z80 R register. Research indicates that the register is incremented every M1 cycle, which can be once or twice per instruction fetch. That's certainly beyond software emulation, so instead I implemented a 16-bit maximal Galois LFSR which is very efficient to implement in assembler. The LFSR is clocked every 1/20th of a second, using the GIME TMR function and 6809 FIRQ, and the Z80 R register 'emulated' by reading the LSB of the LFSR value. Plenty random enough for the purposes of Knight Lore.

One more seed in the original code is read from $5C78, and is used to generate (amongst other things) a random starting location in the map. Tonight I discovered that this is in fact the LSB of the FRAME (frame counter) system variable on the ZX Spectrum - so when loading manually from disk, relatively random. Right now I don't have a good substitute, so the start location tends to be, well, not so random.

Once I fix the seed above, I need to fix the sun/moon frame glitch in the panel, which is invisible on the ZX Spectrum courtesy of the video memory attribute bytes. On the Amiga/Neo Geo C ports I used the panel graphics from the Amstrad CPC version, which overcomes this issue. However on the Coco3, the easiest solution (I think) will be to implement a hack.

Then I will be able to release for beta testing & review; and then subsequently decide whether to release it (again) for free on floppy, or have a cartridge produced. I'm leaning towards the former, with the possibility of releasing the CPC graphics version on cartridge, possibly together with Alien 8 and Pentagram!?! That's a longer term project though...

For now I just want to tick off all outstanding incomplete projects.

Tuesday, 24 January 2017

I've forgotten more than I know...

The perils of leaving a project for months - or even years - is that it takes some time to come back up to speed, and even then for a while you're subsequently discovering plenty of details that you've completely forgotten - most of which, unfortunately, result in head-scratching bugs.

A case in point is the joystick support for Lode Runner, which would have been trivial had I implemented it back when I first released it. Now, however, it has taken two sessions and I still don't have it working correctly.

I've spent the last hour or more trying to make sense of the crash I introduced when adding the joystick read routines. For at least 20 minutes nothing at all was making sense; the disassembly in MESS wasn't matching the 6809 assembler listing. Finally I figured out that I was specifying the wrong file as a cartridge image. What made it more elusive was the fact that it actually displayed the (corrupt) splash screen...

That stupid mistake finally sorted, it wasn't getting much easier as the code still crashed, albeit in a different manner. Cutting out code line-by-line I finally got it running again, and then narrowed it down to a single call to the joystick read routine. I couldn't see anything wrong there... but then noticed the length of the ROM image in the makefile output was suspiciously pushed over a 256-byte boundary when crashing. Further analysis revealed that the code was now too long and as a result I was overwriting high memory. Easily fixed by removing the 10th level from the image.

Unfortunately after all this I don't have the time or the energy to muck about with getting analogue joystick emulation to work in MESS and finalise the joystick support. I am however, reasonably confident it'll only take one more session.

I'm now leaning towards releasing both Lode Runner and Knight Lore for free as disk images. The latter could also be programmed into an EPROM or FLASH cartridge as it doesn't require any special banking support or otherwise... I simply don't have the time to dedicate to getting the cartridge productions under way.

Thursday, 19 January 2017

Joystick 'routine'

Now that our holidays are over and we are settling into the routine for the new year, I've allocated some time to working on outstanding projects that need to be finished before I start any others. The freshest in my mind is the addition of joystick support to the Coco3 port of Lode Runner.

So tonight I did exactly that, and implemented routines to read the Coco3 joystick and buttons in the same manner as the original code (as far as possible). The good news is that the joystick axes are only read in a single place in the code, and the buttons only a handful of places - which I've coded. I had it starting a game and digging left/right with the joystick buttons.

The bad news is that after configuring the PIA to read the axes, it subsequently crashes when you start a game. I haven't had a chance to look into this any further, but presumably it won't be too difficult to track down. I still suspect ghosting will be an issue though...

Then there's the '86 GIME crash issue to get to the bottom of...

I also need to reconsider holding off on a release until I design a cartridge. It's been an embarrassingly long time since I released the demo, and I have to question whether or not I will ever get around to producing a cartridge for it. If not, I need to code DOS routines so that the game will load the level data from the floppy disk and just get it out there.

Next task should be to release Knight Lore. All it requires is tweaking the speed against the Spectrum original - and confirming it runs no slower - and it's good to go. It also requires nothing more than a standard cartridge, so it could be released with minimal effort.

I suspect once I release Knight Lore on cartridge I'll be able to make up my mind on whether or not I want to release Lode Runner on cartridge as well, or simply release it for free on disk.