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



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


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.