sunnuntai 7. heinäkuuta 2013

MORPH Gets Ported Over to an Another 8-Bit!

Greetings, dear readers!

It has been some time since I last posted here in my blog of mostly techy stuff. Some weeks ago, I got the strange idea to teach myself Z80 coding. Having played some games on the legendary ZX Spectrum, I thought it would be cool to create my own games for that platform. Although I didn't own a Speccy as a kid, there's something oddly cool about that 8-bit.

Like the 6502, the Z80 is an 8-bit CPU, just a bit more powerful in some ways. With this in mind, I assumed that the Z80 instruction set would be as easy to learn as the 6502 instruction set. And how right I was! After just a few days of practising, I was already coding something for the Speccy. That something would eventually evolve into a complete game:

MORPH.

But before talking about MORPH ZX, I'd like to say a few words about the Z80 CPU which the Speccy uses.

Z80

The Z80 is actually a very fun CPU to code for, despite what some people might tell you. Although the Z80 doesn't quite have an equivalent of the following opcodes,

LDA $01
LDA $01,X
LDA (ADDRESS,X)
STA (ADDRESS),Y
INC MEMORY_DIRECTLY
ASL MEMORY_DIRECTLY

there are some other powerful opcodes in the instructions set that make up for it. Such as:

LDIR

This two byte instruction would copy a block of memory from one location to another, in just 21 CPU cycles!

With the Z80 CPU, you can load 16-bit values easily with just one opcode, instead of two opcodes as it is on the 6502.

The Z80 has conditional jumps, conditional relative jumps, conditional jumps to subroutines and conditional returns, something I would love to have on the 6502.

The Z80 has 6 registers: AF, BC, DE, HL, IX, IY. The 6502 has only 3 of them: A, X and Y! The IX and IY registers of the Z80 are always 16-bit registers.

What's more, there's a copy of the AF, BC, DE and HL registers. You can easily exchange the two copies of the registers with the EXX opcode. To be exact, you have to use EXX and EX AF,AF' in order to swap all of the registers, including AF which is left intact by the EXX opcode.

When you have done 6502 coding previously, it is quite likely that you'll make some mistakes with the Z80 syntax now and then. I've lost count of how many times I've been about to type:

LDA #$05

when typing Z80 code, even though the Z80 equivalent of that opcode is:

LD A, $05

Another thing that might confuse 6502 coders is that there doesn't seem to be a "store" instruction on the Z80. For example, you would use the following instruction on the 6502 to store the A register to memory:

STA $8000

But on the Z80, we don't "store" values into memory... we "load" them into memory. So, the opcode for storing A into memory looks similar to the opcode for loading a value into A but it is subtly different. The Z80 equivalent of storing A to memory is:

LD ($8000),A

I also like the fact that you can add to the A register without carry if you want to, by using the ADD opcode. The Carry flag does not affect this opcode in any way. However, the good old ADC (Add with Carry) from the 6502 does also exist when needed, so you have them both at your disposal.

The Speccy

The Speccy was fairly easy in general to code for. The only thing that seemed initially quite difficult to handle was the bitmap of the Speccy.

The resolution of the Speccy is 256 x 192. This means that there are 32 x 24 = 768 colour cells on the bitmap.

Each 8x8 cell can have only 2 colours. If you ever wondered why Speccy games look the way they do, this is the explanation for that. That, and the fact that the Speccy has no hardware sprites.

Anyway, the bitmap memory of the Speccy is located at $4000 - 57FF.
The "colour RAM" of the Speccy is located at $5800 - 5AFF. I put "colour RAM" in quotes because it's called something else in the Speccy world. Namely, "attributes".

The way the Speccy bitmap works seems highly confusing at first. On the C64, the bitmap is pretty straight forward. For example, if our VIC2 bitmap is located at $4000 then the appearance of the top left 8x8 bitmap cell would be defined at $4000 - 4007. The next 8x8 cell would be defined at $4008 - 400F. And so on.

On the Speccy, however, the bitmap cells are defined in a different way. To give a shape to the top left 8x8 bitmap cell of the Speccy, you should load values into the following addresses:

$4000, $4100, $4200, $4300, $4400, $4500, $4600, $4700

Because, you know,

$
4000 - LINE 1
4100 - LINE 2
4200 - LINE 3
4300 - LINE 4
4400 - LINE 5
4500 - LINE 6
4600 - LINE 7
4700 - LINE 8

As you would discover from experimenting, the Speccy bitmap is kind of "divided in three":
The first third of the bitmap is at $4000 - 47FF.
The second third of the bitmap is at $4800 - 4FFF.
The third third of the bitmap is at $5000 - 57FF.

And there actually is a pretty good reason for this. Let's suppose that you have a bitmap address, such as $43EA. You would like to colour this area of the bitmap 07 (grey) for instance. How can you find where in the attribute memory the colour cell for this area of the bitmap is located?
Quite easily: you take the low byte of the known bitmap address, $EA. Then you inspect the high byte: The high byte is within $40 - 47, so we are on the first third of the Speccy bitmap, therefore the high byte of the attribute location is $58. So, the location of the colour cell is $58EA! Woohoo! :)

Porting the game

Now that I had learned all I needed, it was time to start actually porting MORPH into the Speccy.

I started out by taking the graphics from the C64 version and modifying them to suit the Speccy port.

First I would take the guy:

Then I would take the Morph ball:
And finally I would take the wall:

There! Now I would have all the needed gfx objects for the game. Well, nearly all of them. The next thing that I decided to do was create a 16 x 8 font for the game. It would be used in the scroll text on the title screen and in the text windows that appear between levels.


Creating the code for the game didn't take too long, something like a week or so. It was pretty easy to port something for which I already had the level data and graphics.

I made some slight changes to the gameplay on the Speccy version of the game. In the Speccy version, all of the 30 puzzles have a password so you can load whichever puzzle you want by pressing Enter on the title screen and giving the password of the puzzle.

Also, I removed the time limit from the Speccy version. I thought that it would be more enjoyable for the players to spend as much time as they want with the puzzles and take their time with solving them. Judging from the feedback that I got on the WOS forum, it was a good move. :)

Very shortly after registering onto the WOS forum and announcing my first Speccy game I already started receiving lots and lots of positive feedback. The people over there greatly liked my game, and they also asked me when my next Speccy game will be coming out. It's difficult to say at this point, but my answer is: Hopefully soon! :) MORPH was such a fun game to port and the Speccy was so fun to code for that I look forward to creating more games for it.

Some guys at WOS thought that I have shifted allegiance from the C64 to the Speccy. But unfortunately for them, I haven't changed sides at all. ;) Instead, from now on I will focus on the Speccy as well as the C64. However, I'd like to finish my upcoming Shiver Me Timbers game before returning to the world of Speccy coding.

All right. I'll now end my blog with screenshots of the game. If you'd like to actually try out the game on a Speccy emulator, you can download it from here: rapidshare.com/files/803069018/MORPH.SNA

See you later! TMS signing out!



The title screen
The info window which shows the level number and the number of lives

The second puzzle of MORPH