Happy new year everyone !
Regarding configuration files for SegaDecrypt, I decided to give libconfig a go as a replacement for my big clumsy xml file. I went for version 1.5 as the last version (1.6) has some problems preventing it to compile on my dev setup.
Now each set has its own configuration file, as you can see in the following example, extracted from a real set :
//--------------------------------
// Super Hang On Sitdown 317-0039
//--------------------------------
name = Super Hang On Sitdown;
version = 317-0039;
protection = FD1094;
program:
{
files = [
epr-10857.25,
epr-10859.31
];
key = 317-0039.key;
size = 0x20000;
};
override:
{
process_data_manually = true;
irq_vector_lower_bound = 0x108a;
irq_vector_upper_bound = 0x108a;
post_decryption_copy = (
(0x400, 0x1000, DATA ),
(0x1A22, 0x20000, DATA )
);
};
crc:
{
type = outrun ;
storage_address = 0xFF0;
start_address = 0x1000;
initial_block_size = 0x1F000;
};
Almost everything can be overridden, allowing to handle specific cases required for some sets.
Now that the configuration problem is solved, I started working on the MC8123 decryption. The MC8123 is a Z80 with built-in encryption, Program opcodes and data are encrypted differently, which explains why bootleggers used doubled eproms back in the days : one half was used for the decrypted program, the other half for the decrypted data, and the correct addressing was chosen at runtime.
Using the same technique I used to decrypt FD1094 files, I should be able to generate decrypted files for MC8123.
There are some difficulties though :
- Opcodes operands are considered as data, and they don’t have a fixed size → a pass to check opcode type and operand size has to be done.
- There are data chunks interleaved with Z80 encrypted code, and unlike FD1094 encrypted code, there are no data markers allowing to know their boundaries → solution will be to consider everything as data first, and then to follow code flow from interrupts start vectors, jumps, branches, etc. in order to get the program code.
- Previous point has some weaknesses though : some opcodes (like JP (HL) for instance) are supposed to do an unconditional jump, which destination is based on a processor register. Problem is, the register content is set up at runtime, meaning that you can’t know its value without effectively running the code.
Time to get my hands dirty !