Since CoCo’s don’t have dedicated hardware sprites, I started writing my own library to handle this task. So in the future I won’t have to re-write this code again and again. I recently started reverse engineering the Amiga version of Rick Dangerous. This was a game my friends and I had such a blast playing when I was younger. I found out awhile ago that someone had disassembled the IBM and Atari ST version and made their own open source version called XRick. It’s written in C and will probably help me while I go through the Amiga version.
After the CoCo 3 my next computer was an Amiga 500 then an Amiga 3000 and an Amiga 1200. I never did do any programming on the Amiga, I used it for multimedia stuff and especially 3D modelling and of course for gaming. I thought it would be really cool to have Rick Dangerous on the CoCo 3 but not until I got my 2 Meg upgrade for my CoCo 3 did I think it would be possible. I still don’t know what I’ll end up with but I’m having a blast learning motorola 680000 assembly and exactly how the powerful chips inside the Amiga work. The 68000 CPU really is a lot like the 6809 but with more registers and accumulators and of course it’s all 32 bits. The processor runs at 7Mhz but a lot of the instructions take many cycles to perform. I think a good optimized version on a CoCo 3 with a 6309 CPU and 2 Megs of RAM could keep up…
So far, I’ve figured out how backgrounds in Rick Dangerous are drawn on the Amiga and also where and how the sprites are drawn on screen. I have all the audio samples located as well. Although it turns out Rick Dangerous has its own MOD player code built in for music. This will be difficult to emulate, but maybe a long sample will do.
If I want to make a version for the CoCo 3 I have most of the elements I need, some of the other things I need to do is figure out how enemies and traps are placed in each scene. The XRick source code might help here, but I’m not that great with ‘C’ source code. For now I’m writing some code to handle moving Rick Dangerous around the CoCo 3 screen.
For a fun comparison here’s the Amiga version (running on MAME):
Here’s my CoCo 3 version (so far, also running on MAME):
Now my point for writing the blog entry wasn’t to go into details about a game I’m disassembling but why the CoCo 3 screen with 256 x 200 x 16 colours is so awesome. The reason is, I figured out a really quick way to translate the X & Y co-ordinates of this specific screen dimensions to a memory location.
Rick Dangerous on the Amiga uses only even bytes for the X location of the sprites and even though it uses a 320 x 200 screen it only uses 256 pixels and has a black border around the screen. I think most games and demos stick to using only even bytes, this makes it easier for programming and takes half the graphics memory (since you don’t need one copy of the sprite at an even pixel and another at an odd pixel).
Sorry, I keep going off on tangents… Back to the CoCo 3 screen, I will be accessing the screen in RAM starting at $0000 to $63FF. A screen with 256 pixels across means each row is 128 bytes (2 pixels per byte). Therefore to get the memory location of an X co-ordinate of 28 and Y co-ordinate of 87 we need to do the following math:
Mem location = (Y *128) + (X / 2)
From our example = (87 * 128) + (28 / 2)
= 11,136 + 14
= 11,150 (Memory location to draw the sprite)
To do this in 6809/6309 assembly you need to do the following (takes 23 CPU cycles on a 6309):
LDU #SpriteXY * Stored as two bytes X, Y
LDB 1,U * B = Y value
ROLA * Rotate left 7 times to get D = D * 128
But we have a 6809/3809 CPU and have a multiply so let’s use that instead (takes 20 CPU cycles on a 6309):
LDU #SpriteXY * Stored as two bytes X, Y
LDA #128 * Multiply B with 128
LDB 1,U * B = Y value
MUL * D now has the Y value on screen calculated
Either way we still need code to take the X co-ordinate and Logical shift the value and add it to D. (takes 15 CPU cycles on a 6309)
PSHS B * Save it on the stack
LSRB * X co-ordinate / 2
ORB ,S+ * D now has the screen location
So at best using the above MUL method and then getting the X co-ordinate is 35 CPU cycles.
But what if instead of shifting left 7 times we load the value in A and shift D to the right once. That would save a lot of shifting. To do this you need to simply swap the X & Y values in your program so they’re always stored as Y,X in RAM. This way when loaded into the D register the Y value gets shifted right once instead of left 7 times and the X value gets shifted as well at the same time to change from a value in the range of 0 to 255 to 0 to 128, which is the byte location we need for our screen memory location. If you really want to handle even and odd pixels you still can, the carry bit at this point would indicate an odd pixel if it’s set, so a simple ( BCS DrawOddSprite) could handle it.
Since I’m using a 6309 and it has the LSRD instruction the code will be (takes 10 CPU cycles):
LSRD * D now has the value of Y = Y * 128 + X=X/2 (we now have our screen location)
It could be even faster if we use the same address for the Y&X value in direct page ram and load it from that location, that would only require 6 cycles. That’s why a resolution of 256 x 200 x 16 colours is so nice on the CoCo 3.
The important thing is to think differently and maybe you can get some nice speed increases in your code. See you in the next post,
mate, this game looks great so far on the coco 3 as the screen looks the same as the Amiga version… We are all backing you to succeed on this game. Btw, have to agree the 256 mode was a nice one shame most programmers never really pushed the graphical detail tho.. But this game you are working on shows how good it truly can be if done right.
Thanks briza1, I appreciate the encouragement as always. 🙂
I’m planning to use the CoCo 3 hardware to its limits on this version. It will definitely require a 6309 and Im pretty sure I’ll be playing audio streaming from a CoCoSDC ( so that will be necessary too). It may also require 2 Megs of RAM, I’m not putting any limitations on myself at all this time. In the past I was proving to myself what the CoCo 3 could have done back in the 1980’s. Now it’s just to see what the CoCo 3 can do in the 2020’s.
Us coconuts have encouragement in spades for you guys who keep the coco 3 programming alive… And it is games like this which show case just how good a coco 3 was even with all the crippled hardware by Tandy
You mentioned that trying to do the MOD player style music driver might be too taxing on the CPU (which I agree), but you also mentioned possibly using the CocoSDC streaming feature. If you pre-render the 4 voice MOD music as 6 (or 8) bit sound samples into files that are placed on the CocoSDC, you could stream that file and simply load a value, merge any sound effects, and then output to the DAC directly. You could even make it 2 byte/8 bit for the Orch-90 and make the music as optional stereo (or alternate stream file versions for 6 bit DAC and 8 bit Orch-90).
Hey Curtis, I was thinking of doing exactly that for the music scenes and I do have an CoCo flash which also emulates an Orchestra 90. I will definately try to get that working with stereo music just as the Amiga version had. We’ll see how this all goes, it’s still all up in the air… But I will be trying to push the CoCo 3 to its limits. 🙂
Thanks for the suggestions,