Super HuCard (Over 100 HuCard Games On CD) For Super CDRom [MultiBoot!/2000]


12 Δεκ 2006
Για τους τυχερούς κατόχους του SuperCDROM και της Super System Card v3.00... (ναι είμαι από αυτούς :D )

Πρόκειται για ένα CD (unofficial) στο οποίο υπάρχουν περί τα 100 παιχνίδια (HuCard versions) για Turbo Grafx-16/ PC Engine.

H Super System HuCard v3.00 είναι κάτι σαν memory expansion για την κονσόλα, διαθέτει μνήμη την οποία η κονσόλα χρησιμοποιεί σαν buffer για τη μεταφορά δεδομένων από τη CDROM συσκευή. Αυτό το CD είναι φτιαγμένο έτσι ώστε αντί για buffer να χρησιμοποιεί την Super System HuCard σαν εγγράψιμη Hucard.

Δηλαδή, επιλέγουμε από τη λίστα το παιχνίδι που θέλουμε και αυτό αναλαμβάνει να μεταφέρει τη rom στη μνήμη της Super System card v.3 και να το διαβάσει από εκεί σαν να ήταν μια κλασική Hucard ενός παιχνιδιού....

Το image αυτού του CD υπάρχει στον υπόγειο αλλά και σε http.

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).
Τελευταία επεξεργασία από έναν συντονιστή:


11 Οκτ 2008
υπάρχει κάποια αντίστοιχη συλλογή που να λειτουργεί και με system card 2?


26 Απρ 2007
δεν υπάρχει άλλη συλλογή...μόνο αυτή...

πάντως, καλή η συλλογή αλλά δεν αξίζει να καταπονείς τόσο πολύ το cdrom σου.

Την έβαλα μια φορά έτσι για να τη δοκιμάσω και μόλις άκουσα το αγκομαχητό από το καημένο το duo μου...το έκλεισα και δεν το δοκίμασα ξανά.

Δεν ξέρω ακριβώς για ποιο λόγο, αλλά το drive έκανε σαν τρελό....