So, the adventure started in July has come to an end. How did the project go? Where can I get the game? Do I need a SuperGrafx CD with dual Arcade Cards to play it? Will this give me a totally accurate understanding of quantum field theory? All your questions and more will be answered! Plus, stay tuned for a follow-up on coding for the PC Engine!

It’s here!

The title screen of Space Ava 201, a female figure looming ominously over a flat earth

Like all of my games that I feel confident enough in to release there, Space Ava 201 is now available on my itch.io page, right here to be precise. You can download it freely in CUE/ISO/WAV format, or throw some pennies at the author if you really want. (She even has a Patreon! Okay, enough self-promotion)

An in-game screenshot of Space Ava 201, showing Ava on a space station

Any TurboGrafx-16 or PC Engine emulator that can play Super CD-ROM2 games can play Space Ava 201. You don’t need to configure things for the Arcade Card or the SuperGrafx; you can get a full gameplay experience with all levels, dialogue, and music still available without either of those. This goes for playing on hardware as well.

The cover of Space Ava 201, featuring a PC-SG logo

FAQ (and more screenshots!)

Will it run on a real console?

A screenshot of Space Ava 201, wherein Cindy Palisade insists that because she's the captain, she gets to be first author

I have personally tested this on my own PC Engine Duo R and SuperGrafx-CD setups using a burned CD-R, and found it worked successfully, if your console supports CD-Rs in general. (My Turbo Duo does not) I have also tested using the TerraOnion Super SD System 3 (an FPGA-based CD-ROM drive emulator) without issues.

I do not have any other systems to test on, but I see no reason they wouldn’t also work equally well. Of course, these systems being potentially over thirty years old, I can’t make any promises. Everything’s at your own risk, folks…

How does it handle composite/S-Video?

A screenshot of Space Ava 201, over composite video

Recently, the retro community has been rocked by the revelation that the PC Engine/TurboGrafx’s video output palette is in some cases noticeably different between RGB output and composite video. Since most systems only offered composite outputs, this has raised a lot of questions over what the “correct” way to play games is.

To set the record straight for this game: I designed all graphics and tested using primarily the more vivid RGB colors. But if you do prefer the more muted composite or S-Video color palette, it’ll look good there too, I’ve run through the game that way to make sure. Play it any way you want! Even use one of those smoothing filters if you want.

Do I need to have played Space Ava?

A screenshot of Space Ava 201, wherein Ava stands facing a villainous quantum goon

Hopefully, no. This game is predominately about gameplay, and therefore the story is primarily comedic and intended to provide a break between segments. While many characters from the first game reappear, they’re not heavily characterized and it should be possible to enjoy the game fully without having played the first one.

That being said, you could just play the first one. It’ll run in your web browser! And it has isometric.

What are the controls?

A screenshot of Space Ava 201, wherein Ava is confronted by Antonia, a woman in a blue beret

Space Ava 201 is predominately played with the directional pad. You’ll find no benefit from the Turbo Pad, Avenue Pad 6, Turbo Tap, or other specialty controllers, but you can use them if you want.

In standard gameplay:
D-PAD: Move Ava
RUN: Pause
SELECT: Kill Ava (restart level)

In dialogue screens:
Button I: Progress further in dialogue
RUN: Skip dialogue

In mirror puzzles:
D-PAD: Move cursor
Button I: Pick up and drop movable items
RUN: Attempt to solve puzzle

In side-scrolling segments:
D-PAD: Move Ava
Button I: Jump (can also use D-pad UP)
RUN: Pause

How long does the game take?

A screenshot of Space Ava 201, wherein Ava in an office building

Playing through it myself, it takes a little under an hour to complete. Of course, I’m already aware of the solutions to puzzles, so I would recommend leaving a little more time than that, but overall it’s not a very long game.

What do the SuperGrafx and Arcade Card do?

A screenshot of Space Ava 201 running with enhanced SuperGrafx features used to write SUPER behind the title

The SuperGrafx is primarily used to provide additional graphical layers in some game modes. These are used to create more interesting backgrounds. Nevertheless, it is not required for any action. You can see more details about this on my prior article about the SuperGrafx-CD.

A screenshot of Space Ava 201 running with the Arcade Card says 'Arcade' under the title

The Arcade Card, if available, is used to preload all graphics at the start of the game for faster loading. However, this is only faster if you’re doing a long play session that will actually use those graphics; should you decide you not want to sit through the preload, you can always press and hold RUN. Eventually, the images of the Arcade Card on-screen will change to Super System Cards, showing that you have skipped the pre-loading. The game will from then on run identically as if you hadn’t used the Arcade Card at all.

A screenshot of Space Ava 201 showing Lily sad that you aren't using the arcade card

All modes of the game, even the standard mode, will access the Backup RAM, if available, to save game progress. Only one game save is available.

What are the licenses?

A screenshot of Space Ava 201 showing a side-scrolling mode on a blue planet

Space Ava 201 is released in full under the Creative Commons CC-BY-SA 4.0 license. This means that you are free to make copies and distribute it, and modify it as well, as long as you release your changes in the same way, and provide attribution.

That being said, if you do take anything, let me know! My email is listed below, or you could just ping me on @nicole_express on Twitter.

Are there cheat codes?

A screenshot of Space Ava 201 showing more options on the title screen, because the cheat codes below were used

Of course there are! Press these on the title screen:

  • Up-Down-Left-Right: Access story mode (allows progress through dialogue without gameplay getting in the way)
  • Right-Down-Up-Right-Right-Down-Right-Right-Up-Up-Down-Down-Left-Right-Left-Right: Access the level select

That last code is a reference to something… might help you remember the code, if you speak Japanese anyway.

Are you going to make a physical release available?

A screenshot of Space Ava 201 showing mirror puzzle mode, which is aesthetically similar to Windows 95 for some reason

I am definitely going to get some CDs pressed at some point. (If for no other reason, then to run it on my Turbo Duo!) However, I have little interest in selling copies myself due to the logistics involved; if there is demand I might reconsider this, since CDs generally need to be pressed in bulk anyway.

A screenshot of Space Ava 201 showing a sidescrolling mode, enhanced to have a scrolling background using the SuperGrafx

Coding for the PC Engine, Part 2

So back in July I wrote up a blog post on coding for the PC Engine; deliberately, I did this before I had written much code at all. So let’s see how that turned out!

Errata

  • I claimed that the PC Engine used a shift register for the controller and is read serially (one-byte-at-a-time) like the NES controller. This isn’t accurate; the PC Engine can actually read four of the eight buttons at once.
  • I claimed the Sprite Attribute Table doesn’t live in VRAM; this is and isn’t true: there is actually a portion of VRAM attributed to sprites, which is DMA’d into the internal SATB. So if you go trampling around all of VRAM, you will overwrite your sprites. It’s a pretty small region, though.

Neither of these are huge errors, but they are worth pointing out.

Using HuC

I was very impressed with the HuC compiler. I ended up being able to write pretty much everything in a performant fashion without too much issues; in the end, the only things I needed to reach outside of HuC for were to use block transfer instructions (and more on those later)

Of course, the fact that Space Ava is not in any sense of the word an action game probably helps.

There are some oddities which are definitely worth noting. For one thing, I couldn’t get the included malloc implementation to work, but in the end I don’t think it’s necessary. I found it fine to declare all blocks of memory you need for the overlay up-front; after all, the best garbage collection method is to just leave it all lying around.

Additionally, in standard programming, global variables are generally to be avoided, but in HuC they’re very useful to use– local variables are kept on a stack kept in RAM. The downside of this is that this isn’t the processor stack (as a 6502-based processor, the HuC6280 inherits its very limited 8-bit stack), so there’s a lot of overhead involved. Global variables are directly mapped to RAM addresses and are very fast.

As I also noted in my original article, I pretty much entirely ignored HuC/Magic Kit’s image processing methods and wrote my own. They’re very heavily tied to my Terraformer homebrew graphics editor which as far as I know no one else uses, but my routines are included in the source code if you’d like to take a look, written in Python 3.

Since these processing routines put all the images in a single “overlay” (you can think of an overlay as a file on the disk), it was trivial to add Arcade Card support by uploading the entire overlay into the card, and doing a quick check whenever VRAM would be loaded to bypass the CD-ROM drive if the Arcade Card was populated.

A screenshot of Space Ava 201 showing data being loaded into the arcade card

Let’s talk about those “overlays” more. An overlay seems to be basically a rough placeholder for a file system; there are “data” overlays which basically are just a pointer to a place on the CD, and “executable” overlays that are programs that are designed to be loaded into the Super System Card. This is all a HuC system, and there’s no reason to assume all PC Engine CD games work this way. In general, though, I found this made it pretty easy to break out multiple game modes into their own programs in a much cleaner way than, say, Aspect Star “N”, where even the title screen was just another mode of the game.

The block transfer instructions

In my initial blog post, I neglected them entirely. In my SuperGrafx-CD blog post, I did block transfers using C! So what are these instructions?

  • tai - Transfer Alternate Increment
  • tia - Transfer Increment Alternate
  • tdd - Transfer Decrement Decrement
  • tii - Transfer Increment Increment
  • tin - Transfer Increment None

Sounds like a mess of alphabet soup, doesn’t it? I certainly thought so, which is why I just ignored them. But these are actually great for copying data back and forth. And what’s all this about Alternating? For example, let’s take this code sample from the SuperGrafx-CD article:

sgx_load_vram(int vaddr, int *data, int nb)
{
    int i;

    poke(0x10, 0x00);   // Initialize VRAM address
    pokew(0x12, vaddr);
    poke(0x10, 0x02);   // Enter write mode

    for (i = 0; i < (nb >> 1); i++)
    {
        pokew(0x12, data[i]);
    }

    return;
}

We could rewrite this as:

sgx_load_vram(int vaddr, int *data, int nb)
{
    int i;
    char flip;

    poke(0x10, 0x00);   // Initialize VRAM address
    pokew(0x12, vaddr);
    poke(0x10, 0x02);   // Enter write mode

    flip = 0;
    // Notice that i now covers all 8-bit bytes in data
    for (i = 0; i < nb; i++)
    {
        // Alternate between the two addresses
        if (flip == 0)
        {
            poke(0x12, data[i]);
            flip = 1;
        }
        else
        {
            poke(0x13, data[i]);
            flip = 0;
        }
    }

    return;
}

Writing to VRAM means that you need to write a 16-bit value. Since the CPU is 8-bit, it writes the first 8 bits to one address (0x12), and then the next 8 bits to another address (0x13). From the CPU’s perspective, it’s alternating back and forth between these two registers. And this is a common pattern on the PC Engine; you can also do it to write 16-bit values to the Arcade Card, for example. (The “increment” is easy enough to see; it’s the i++ in the for loop)

And using the block transfer instructions, we could replace that for loop with tia (data) 0x0012 (nb).

There’s just a little problem: the tia instruction doesn’t allow for any indirection. (Indirection, in this case, means that instead of passing the value, you pass something to the processor to let it know where to find the value, like a RAM address) You need to know the source address and the number of bytes directly, you can’t pass variables.

Remember, this sgx_load_vram function is called everywhere we want to load data into the SuperGrafx’s extra VRAM. So we don’t actually know what the length is or where the data will be. But it turns out that doesn’t matter. We can just execute code from RAM.

char tia_instruction[8];
sgx_load_vram(int vaddr, int *data, int nb)
{
    int i;

    // This function might not work if you try to transfer
    // more than $ffff bytes of data. But I never do

    // tia data, $0012, $0800
    // rts
    tia_instruction[0] = 0xe3; // processor opcode for TIA
    tia_instruction[1] = data & 0x00FF;
    tia_instruction[2] = (data & 0xFF00) >> 8;
    tia_instruction[3] = 0x12; // We can hardcode the value 0x0012
    tia_instruction[4] = 0x00; // the VDC register we want to write to
    tia_instruction[5] = nb & 0x00FF;
    tia_instruction[6] = (nb & 0xFF00) >> 8;
    tia_instruction[7] = 0x60; // RTS (return to code)

    poke(0x10, 0x00);
    pokew(0x12, vaddr);

    #asm
        pha

        sei ; disable interrupts
        lda #$02  ; These two lines are the
        sta $0010 ; same as poke(0x10, 0x02)
        jsr _tia_instruction
        cli ; set interrupts

        pla 
    #endasm
    return;
}

You can see that there is no tia instruction in the assembly section. Instead, it’s created in RAM, in the character array “tia_instruction”. It’s followed by a return statement, so we can just jump to it.

Sure, it seems weird if you’re used to modern coding practices. Today, for security reasons, you generally don’t want to write to and execute from the same RAM. But on 8-bit systems, this sort of thing is par for the course, and pretty much intended behavior. Remember, this is pretty much an embedded system; there’s no real OS and certainly no other processes, unless you count the CD BIOS. The worst a “hacker” could do is delete all saved games.

I ended up using this pattern both for the SuperGrafx transfer, and for the Arcade Card transfers. It made things a lot more bearable, and doing everything in C would’ve wiped out any speed benefit of having data in the Arcade Card vs. having it in RAM.

Would I do it again?

I enjoyed working on the PC Engine CD a lot. I’m not sure if my next game will be on this console, though. I really enjoyed working with the multiple background layers the SuperGrafx provided, so I might take a look into the Genesis (actual 16-bit CPU! but so few palettes) or the Super Nintendo (Another 6502-alike! But no CD add-on…). Or maybe even the Neo Geo?

I also promise I haven’t forgotten about Aspect Star 4; this may be my last JavaScript game, so I want to make sure it’s a good one.

That’s Space Ava 201! It’s definitely a sort of game that I made for an audience of one, but that shouldn’t stop you from enjoying it too :) Hopefully you enjoy it at least a tenth as much as I enjoyed making it!

A screenshot of Space Ava 201, with the text 'In the space criminal justice system, the space people are represented by two separate yet equally important space groups. The space police who investigate space crimes, and the space district attorneys who prosecute the space offenders. These are their space stories.'