в общем как то так
#define ROM_CARTRIDGE 0x000000
#define VDP_DATA 0xC00000
#define VDP_CONTROL 0xC00004
#define VDP_HWCOUNTER 0xC00008
#define VDP_PSG76489 0xC00010
#define SYSTEM_IO_UNK0 0xA13000
#define SYSTEM_IO_CART 0xA16106
#define SYSTEM_IO_UNK1 0xA16302
#define SYSTEM_IO_UNK2 0xA16304
#define SYSTEM_IO_UNK3 0xA16306
void main() // sub_400
{
reset_VDP();
write_cram(0, &dword_754);
sub_6A2(1, 0x3122, &dword_764);
sub_6D6(1, 0x870000, &dword_3886);
*(uint16_t *) VDP_CONTROL = 0x8144;
sub_540();
delay(16);
uint16_t *src = word_47C;
uint16_t *dst = (uint16_t *) 0xFF0000; // RAM
/* Copy SUBROUTINE to RAM*/
for (int i = 0; i < 98; i++)
{
dst[i] = src[i];
}
typedef void (*function)(void);
function start_from_ram = dst;
start_from_ram();
}
void sub_540()
{
*(uint16_t *) SYSTEM_IO_UNK1 = 0x3000;
*(uint16_t *) SYSTEM_IO_UNK2 = 0xF0CC;
*(uint16_t *) SYSTEM_IO_UNK3 = 0x7813;
}
void delay(int cnt) // sub_574
{
do
{
for (int i = 0; i <= 0xFFFF; i++);
}
while (cnt--)
}
void reset_VDP() // sub_58A
{
clear_vram();
clear_vsram();
clear_cram();
sub_622();
}
void clear_cram() // sub_5A4
{
*(uint16_t *) VDP_CONTROL = 0x8F02;
*(uint32_t *) VDP_CONTROL = 0xC0000000;
for (int i = 0; i < 32; i++)
{
*(uint32_t *) VDP_DATA = 0;
}
}
void clear_vram() // sub_5CE
{
*(uint16_t *) VDP_CONTROL = 0x8F02;
*(uint32_t *) VDP_CONTROL = 0x40000000;
for (int i = 0; i < 0x4000; i++)
{
*(uint32_t *) VDP_DATA = 0;
}
}
void clear_vsram() // sub_5F8
{
*(uint16_t *) VDP_CONTROL = 0x8F02;
*(uint32_t *) VDP_CONTROL = 0x40000010;
for (int i = 0; i < 20; i++)
{
*(uint32_t *) VDP_DATA = 0;
}
}
void sub_622()
{
uint16_t val = 0x8000;
for (int i = 0; i < 24; i++)
{
val = (val & 0xFF00) | byte_64A[i];
*(uint16_t *) VDP_CONTROL = val;
val += 0x100;
}
}
uint8_t byte_64A[24] =
{
0x04, 0x04, 0x38, 0x34, 0x06, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x02,
0x01, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x80
};
void write_cram(uint32_t d0, uint32_t *a0) // sub_662
{
uint32_t *data = (uint32_t *) ((d0 << 5) & 0x60) + a0;
d0 = (((d0 >> 3) & 0x60) | 0xC000) << 16;
*(uint16_t *) VDP_CONTROL = 0x8F02;
*(uint32_t *) VDP_CONTROL = d0;
for (int i = 0; i < 8; i++)
{
*(uint32_t *) VDP_DATA = data[i];
}
}
void sub_6A2(uint16_t d0, uint16_t d1, uint16_t *a0)
{
uint32_t val = (((d0 << 5) & 0xFFFE) << 2);
val = (((uint16_t) val) >> 2) | 0x4000;
val = (val >> 16) | (val << 16);
*(uint32_t *) VDP_CONTROL = val;
uint16_t cnt = (d1 / 2) - 1;
uint16_t *data = a0 + 2;
for (int i = 0; i < cnt; i++)
{
*(uint16_t *) VDP_DATA = data[i];
}
}
void sub_6D6(uint16_t d0, uint32_t d1, uint16_t *a0)
{
uint16_t tmp; // d2
int cnt; // d3
uint16_t orval; // d4
int cnt2; // d5
tmp = (d1 & 0x3F) << 1;
d1 = (((d1 & 0x1F00) >> 1) + tmp) | (d1 & 0xFFFF0000);
d1 = (d1 << 16) | (d1 >> 16);
orval = (uint16_t) d1;
orval = (orval << 7) & 0x8000;
d1 = (d1 & 7) | (d1 & 0xFFFF0000);
tmp = (uint16_t) d1;
tmp = (tmp & 1) | (tmp & 0xFF00);
tmp = (tmp >> 3) | (tmp << 13);
d1 = ((d1 >> 1) & 0xFF) | (d1 & 0xFFFFFF00);
d1 += ((tmp + 0x4000) << 16);
*(uint16_t *) VDP_CONTROL = 0x8F02;
*(uint32_t *) VDP_CONTROL = d1;
tmp = *a0++;
cnt = *a0++;
cnt = (cnt >> 8) | (cnt << 8);
cnt2 = (tmp >> 8) | (tmp << 8);
for (int i = 0; i < cnt; i++)
{
for (int n = 0; n < cnt2; n++)
{
*(uint16_t *) VDP_DATA = (((d0 + *a0++) & 0x7FFF) | orval);
}
d1 += 0x800000;
*(uint32_t *) VDP_CONTROL = d1;
}
}
uint32_t dword_764 = 0x40000L;
void start_from_ram() // sub_FF0000
{
(void) *(uint16_t *) SYSTEM_IO_UNK0;
*(uint16_t *) SYSTEM_IO_CART = 0x20; // FIXME switch from internal ROM to cartridge ROM
*(uint16_t *) SYSTEM_IO_CART = 0xA0; // FIXME reset cartridge ROM
for (int i = 0; i < 0x10000; i++) // simple delay
{
asm("nop\n");
asm("nop\n");
}
if (((uint8_t *) ROM_CARTRIDGE)[0x100] != 'S')
{
/* cartridge not present */
while(1); // infinite loop
}
*(uint16_t *) VDP_CONTROL = 0x8104;
reg[SR] = 0x2700;
*(uint16_t *) VDP_CONTROL = 0x8F02;
*(uint32_t *) VDP_CONTROL = 0xC0000000;
for (int i = 0; i < 32; i++)
{
*(uint32_t *) VDP_DATA = 0;
}
*(uint32_t *) VDP_CONTROL = 0x40000000;
for (int i = 0; i < 0x4000; i++)
{
*(uint32_t *) VDP_DATA = 0;
}
*(uint16_t *) VDP_CONTROL = 0x8104;
*(uint16_t *) SYSTEM_IO_CART = 0xA0; // FIXME reset cartridge ROM
asm("nop\n"); asm("nop\n"); asm("nop\n"); asm("nop\n");
reg[SP] = reg[USP] = ((uint32_t *) ROM_CARTRIDGE)[0];
typedef void (*function)(void);
function run_from_cartridge = ((uint32_t *) ROM_CARTRIDGE)[1];
run_from_cartridge();
}