mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-28 00:16:55 +00:00
133 lines
3.2 KiB
C
133 lines
3.2 KiB
C
/* radare - LGPL - Copyright 2015-2016 - shengdi */
|
|
|
|
#include <r_bin.h>
|
|
|
|
typedef struct gen_hdr {
|
|
ut8 HeaderID[8];
|
|
ut8 ReservedWord[2];
|
|
ut16 CheckSum;
|
|
ut8 ProductCode[2];
|
|
ut8 Version; //Low 4 bits version, Top 4 bits ProductCode
|
|
ut8 RegionRomSize; //Low 4 bits RomSize, Top 4 bits Region
|
|
} SMS_Header;
|
|
|
|
#define CMP8(o,x) strncmp((const char*)bs+o,x,8)
|
|
#define CMP4(o,x) strncmp((const char*)bs+o,x,4)
|
|
static bool check_bytes(const ut8 *bs, ut64 length) {
|
|
if (length > 0x2000 && !CMP8(0x1ff0, "TMR SEGA")) {
|
|
return true;
|
|
}
|
|
if (length > 0x4000 && !CMP8(0x3ff0, "TMR SEGA")) {
|
|
return true;
|
|
}
|
|
if (length > 0x8000 && !CMP8(0x7ff0, "TMR SEGA")) {
|
|
return true;
|
|
}
|
|
if (length > 0x9000 && !CMP8(0x8ff0, "TMR SEGA")) {
|
|
return true;
|
|
}
|
|
if (length > 0x8000 && !CMP4(0x7fe0, "SDSC")) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
|
|
check_bytes (buf, sz);
|
|
return R_NOTNULL;
|
|
}
|
|
|
|
static RBinInfo* info(RBinFile *arch) {
|
|
const char *bs;
|
|
SMS_Header *hdr = NULL;
|
|
RBinInfo *ret = R_NEW0 (RBinInfo);
|
|
if (!ret || !arch || !arch->buf) {
|
|
free (ret);
|
|
return NULL;
|
|
}
|
|
ret->file = strdup (arch->file);
|
|
ret->type = strdup ("ROM");
|
|
ret->machine = strdup ("SEGA MasterSystem");
|
|
ret->os = strdup ("sms");
|
|
ret->arch = strdup ("z80");
|
|
ret->has_va = 1;
|
|
ret->bits = 8;
|
|
bs = (const char*)arch->buf->buf;
|
|
// TODO: figure out sections/symbols for this format and move this there
|
|
// also add SDSC headers..and find entry
|
|
if (!CMP8(0x1ff0, "TMR SEGA")) {
|
|
hdr = (SMS_Header*)(bs + 0x1ff0);
|
|
} else if (!CMP8(0x3ff0, "TMR SEGA")) {
|
|
hdr = (SMS_Header*)(bs + 0x3ff0);
|
|
} else if (!CMP8(0x7ff0, "TMR SEGA")) {
|
|
hdr = (SMS_Header*)(bs + 0x7ff0);
|
|
} else if (!CMP8(0x8ff0, "TMR SEGA")) {
|
|
hdr = (SMS_Header*)(bs + 0x8ff0);
|
|
} else {
|
|
eprintf ("Cannot find magic SEGA copyright\n");
|
|
free (ret);
|
|
return NULL;
|
|
}
|
|
|
|
eprintf ("Checksum: 0x%04x\n", (ut32)hdr->CheckSum);
|
|
eprintf ("ProductCode: %02d%02X%02X\n", (hdr->Version >> 4), hdr->ProductCode[1],
|
|
hdr->ProductCode[0]);
|
|
switch (hdr->RegionRomSize >> 4) {
|
|
case 3:
|
|
eprintf ("Console: Sega Master System\n");
|
|
eprintf ("Region: Japan\n");
|
|
break;
|
|
case 4:
|
|
eprintf ("Console: Sega Master System\n");
|
|
eprintf ("Region: Export\n");
|
|
break;
|
|
case 5:
|
|
eprintf ("Console: Game Gear\n");
|
|
eprintf ("Region: Japan\n");
|
|
break;
|
|
case 6:
|
|
eprintf ("Console: Game Gear\n");
|
|
eprintf ("Region: Export\n");
|
|
break;
|
|
case 7:
|
|
eprintf ("Console: Game Gear\n");
|
|
eprintf ("Region: International\n");
|
|
break;
|
|
}
|
|
int romsize = 0;
|
|
switch (hdr->RegionRomSize & 0xf) {
|
|
case 0xa: romsize = 8; break;
|
|
case 0xb: romsize = 16; break;
|
|
case 0xc: romsize = 32; break;
|
|
case 0xd: romsize = 48; break;
|
|
case 0xe: romsize = 64; break;
|
|
case 0xf: romsize = 128; break;
|
|
case 0x0: romsize = 256; break;
|
|
case 0x1: romsize = 512; break;
|
|
case 0x2: romsize = 1024; break;
|
|
}
|
|
eprintf ("RomSize: %dKB\n", romsize);
|
|
return ret;
|
|
}
|
|
|
|
|
|
RBinPlugin r_bin_plugin_sms = {
|
|
.name = "sms",
|
|
.desc = "SEGA MasterSystem/GameGear",
|
|
.license = "LGPL3",
|
|
.load_bytes = &load_bytes,
|
|
.check_bytes = &check_bytes,
|
|
.info = &info,
|
|
.minstrlen = 10,
|
|
.strfilter = 'U'
|
|
};
|
|
|
|
#ifndef CORELIB
|
|
RLibStruct radare_plugin = {
|
|
.type = R_LIB_TYPE_BIN,
|
|
.data = &r_bin_plugin_sms,
|
|
.version = R2_VERSION
|
|
};
|
|
#endif
|
|
|