Main logo
Index : Goodies : Super Hucard

Super Hucard

This place can be thought as the public side of the project called Super Hucard and maintained by Benjamin Quinn.

The goal is to make a pc engine native cd application which compiles several roms on it so that they are playable on real pc engine systems.

To be able to enjoy it, you'll need a cd enabled pc engine system, either japanese or american. You'll then have to burn a cd based on the downloads below and play the resulting cd-r.

This project is just a technical demonstration of what we can now achieve on pc engine. Don't expect it to be usable for all games, nor bigger games, etc..
It's a just a proof of concept and a technical challenge that was fun to face.

So, now it's more or less useable, it's publicly available for pc engine fans. Of course you shouldn't sell it, claim it's ours nor blame anyone if your dog cites Socrate quotes every other minuts because of what you found here.


20030827 : First public release. About 75 games works.

200306 : First working version. About 60 games works.

How does it work ?

Without entering too much in details, here are the concepts applied here. First, the cd enabled pc engine systems have some RAM usable at runtime. This is the place where data coming from the cd are placed and used as code, graphics, etc... Starting from version 3.0 (hence Super Cd system 3.0 and the Arcade Cards), there are 2 Mega bits available. This room is enough for storing a whole hucard in it, making the system very close of the state where a hucard is inserted in the console.

What are the differences ?

Well, a hucard has data located from the physical bank 0 and all operations at runtime expect this mapping to be respected (to the exception of a few nice games). If we're loaded a hucard content in the cd system card ram, the data starts at bank 0x68. So when an operation saying "make bank 4 available in ram at location 0x4000" is executed, it makes the bank 4 of the cd system (the cd player, game booter, etc...) available at location 0x4000 and not the bank 4 of our hucard since it's located at 0x68 + 4.

How to make operations dealing with bank aware of this 0x68 bank offset ?

In our task, we have some luck, there's just one operation which is problematic. It's TAM, an operation which takes an argument, a field of bit, indicating the location in RAM where to map a physical bank (Actually, it could point at several locations at once, but the normal use makes such that there's only bit set at once). It uses the value of the register A to know the value of the physical bank. Well, ok, we only have to make sure that A got incremented by 0x68 before every TAM.
Easy ? Not really. You can't insert an instruction in a bytecode without breaking everything. The problem is that jumps, calls, etc... will be fooled if you insert extra data. The matter is that we can eventually alter the code but not changing the length of instructions. Now, we have to check how the value of the register A is set. Hopefully, it's mostly loaded with a fixed value just before a TAM. That's quite a perfect situation, we can simply add 0x68 to the argument in the code and A will be incremented of 0x68 at runtime. Sometimes, A is incremented from another value of physical bank. If we assume we managed to catch others TAM argument, the incrementation will retains the 0x68 offset, being a relative alteration of the argument. Still, there are a few tricky things, like values loaded dynamically from the memory where the location is also loaded from the memory at runtime. And eventually they are computation on the register A before having it used which makes this way of doing unusable (imagine "Load A with the physical bank at 0x4000 (normally 2), double A (4) and map the bank indicated by A (4) at 0x6000" with A been incremented by 0x68, the final value would be (0x68 + 2) * 2 instead of 0x68 + (2 * 2) ). On another hand, to detect the usual pattern (loading A with immediate value then apply TAM) we can only rely on a basic expression of 4 bytes such that 2 are fixes (opcode of the A loading and TAM), 1 is under a given value (the argument of the loading of A) and the last only have one bit set. As it's not very sharp, it was easy to be fooled and "patch" piece of data which aren't to be patched. It could lead to crashes or corruption in graphics, sound, etc...
While the static approach works in a few number of case, it shows its limits.
One day, by checking at pc engine internals stuff, Ben noticed that the BRK opcode, which is normally used to indicate an error but in fact is a software interruption, ie an operation which jumps to a subroutine, located via a fixed location in RAM. But unlike usual soft interruption opcodes, it takes an argument and set the return point of the interruption handler to the opcode after this argument, as if it was a 2-bytes long opcode. Hmm, doesn't it sounds like similar to our dear TAM opcode ? Of course.
Now what, we can replace all TAM occurence by a jump to a subroutine and have an argument handy for our subroutine (well, in a very tricky way, but still...). As this subroutine is normally an error one, or used to debug, in games, it's unused, we can safely put a custom handler in it. What will it do ? As you may guess, it will reconstruct a TAM from the BRK argument using self modifying code inline and alter the value of A by adding 0x68 when needed (yes, indeed, sometimes, it references absolute, system bank where we shouldn't add 0x68). We then call our custom TAM and we can even restore the old value of A if we want.
In order to catch all relevant TAM and only them, the best way is to detect them at runtime. So, as Hu-Go! is a working GPL pc engine emulator, the best was to integrate the code to detect TAM in it and convert all TAM opcode into BRK opcode. Before this, we had redirected statically the BRK handler to a subroutine we had inserted in some free space (found in almost every game, the handler is just about 40-50 bytes long).

Here is it, thanks to this dynamic handling of A incrementation, we don't have to worry about the way A is computed, as we're handling this at the very latest moment. Still, since TAM are patched at runtime, to be able to run the game fully, all TAM should have been catched when playing the special version of Hu-Go!. Still, using a light static detection along with this dynamic one should lead to a very large coverage of TAM with few efforts but it hasn't been done yet. Just a few minutes with Hu-Go! on each game generaly (which is often enough as many games reuses the same TAM operation all the time).


Schmorp proposed a mirror for all files on a high speed server in Europe. Big thanks to him.
Full version. This archive contains all what you want in a full cd dump.
Short cooked ISO file. This file is the bare minimum to enjoy Super Hucard. It can be complemented with the following file.
Audio track file. This file is the music track of the Super Hucard, which can be used along with the ISO file. The full version already includes this.

Areios offered a mirror for the full version, you can grab it here. Thanks a lot

Squaresoft74 is also hosting the files on his site.Thanks to him.

Download Super Hucard Iso - ed2k link (Direct link), OS : none added on 2003-09-02 Download Super Hucard Ogg - ed2k link (Direct link), OS : none added on 2003-09-02 Download Super Hucard Full - ed2k link (Direct link), OS : none added on 2003-09-02



No available sub topic


Popular pages
Hu-Go! download
HuC download
Homebrewn rom & iso download


Voir cette page en français French flag

This site is kindly hosted by

Turbo Turnpike
[Join Now | Ring Hub | Random | << Prev | Next >>]

Original design work by Nostromo