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!

No comments:

Post a Comment