debug prints
This commit is contained in:
parent
3ed0bed61c
commit
fb0d9a9cc4
|
@ -24,7 +24,7 @@ GBTimers *gb_timers_open(RIO *io);
|
||||||
void gb_timers_close(RIO *io, GBTimers *timers);
|
void gb_timers_close(RIO *io, GBTimers *timers);
|
||||||
void gb_timers_update(GBTimers *timers, ut32 cycles);
|
void gb_timers_update(GBTimers *timers, ut32 cycles);
|
||||||
|
|
||||||
int gb_mbc1_open(RIO *io, char *path);
|
//int gb_mbc1_open(RIO *io, char *path);
|
||||||
|
|
||||||
extern RIOPlugin r_io_plugin_gb_timers;
|
extern RIOPlugin r_io_plugin_gb_timers;
|
||||||
extern RIOPlugin r_io_plugin_gb_mbc1;
|
extern RIOPlugin r_io_plugin_gb_mbc1;
|
||||||
|
|
207
io/mbc1.c
207
io/mbc1.c
|
@ -8,22 +8,46 @@ typedef struct gb_mbc1_data {
|
||||||
ut32 *rombank_to_io_map;
|
ut32 *rombank_to_io_map;
|
||||||
ut32 *rambank_to_io_map;
|
ut32 *rambank_to_io_map;
|
||||||
ut64 seek;
|
ut64 seek;
|
||||||
ut32 size;
|
|
||||||
int file_fd;
|
int file_fd;
|
||||||
int mem_fd;
|
int mem_fd;
|
||||||
|
ut32 rombank0_map;
|
||||||
ut8 n_rombanks;
|
ut8 n_rombanks;
|
||||||
ut8 n_rambanks;
|
ut8 n_rambanks;
|
||||||
ut8 rombank_mask;
|
ut8 rombank_mask;
|
||||||
ut8 rombank;
|
ut8 rombank_high;
|
||||||
|
ut8 rombank_low;
|
||||||
union {
|
union {
|
||||||
ut8 high_rombank;
|
ut8 high_rombank;
|
||||||
ut8 rambank;
|
ut8 rambank;
|
||||||
};
|
};
|
||||||
bool ram_enable;
|
bool ram_enable;
|
||||||
|
bool mode;
|
||||||
bool small_ram;
|
bool small_ram;
|
||||||
} MBC1;
|
} MBC1;
|
||||||
|
|
||||||
ut8 mbc1_mask[] = { 0x1, 0x3, 0x7, 0xf, 0x1f, 0x1f, 0x1f };
|
static void disable_ram (MBC1 *mbc) {
|
||||||
|
ut32 i;
|
||||||
|
for (i = 0; i < mbc->n_rambanks; i++) {
|
||||||
|
RIOMap *map = r_io_map_get (mbc->io, mbc->rambank_to_io_map[i]);
|
||||||
|
map->perm = 0;
|
||||||
|
}
|
||||||
|
mbc->ram_enable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enable_ram (MBC1 *mbc) {
|
||||||
|
ut32 i;
|
||||||
|
for (i = 0; i < mbc->n_rambanks; i++) {
|
||||||
|
RIOMap *map = r_io_map_get (mbc->io, mbc->rambank_to_io_map[i]);
|
||||||
|
map->perm = R_PERM_RW;
|
||||||
|
}
|
||||||
|
mbc->ram_enable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __check(RIO *io, const char *pathname, bool many) {
|
||||||
|
return r_str_startswith (pathname, "gb_mbc1://");
|
||||||
|
}
|
||||||
|
|
||||||
|
ut8 mbc1_mask[] = { 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f };
|
||||||
|
|
||||||
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
if (!r_str_startswith (pathname, "gb_mbc1://")) {
|
if (!r_str_startswith (pathname, "gb_mbc1://")) {
|
||||||
|
@ -54,6 +78,7 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
free (mbc);
|
free (mbc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
eprintf ("%d rombanks\n", mbc->n_rombanks);
|
||||||
mbc->rombank_mask = mbc1_mask[mbc_info[1]];
|
mbc->rombank_mask = mbc1_mask[mbc_info[1]];
|
||||||
if (mbc_info[0] != 1) {
|
if (mbc_info[0] != 1) {
|
||||||
switch (mbc_info[2]) {
|
switch (mbc_info[2]) {
|
||||||
|
@ -72,6 +97,9 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
free (mbc);
|
free (mbc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
eprintf ("%d rambanks\n", mbc->n_rambanks);
|
||||||
|
} else {
|
||||||
|
eprintf ("no external ram\n", mbc->n_rombanks);
|
||||||
}
|
}
|
||||||
mbc->io = r_io_new ();
|
mbc->io = r_io_new ();
|
||||||
if (!mbc->io) {
|
if (!mbc->io) {
|
||||||
|
@ -80,30 +108,38 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
free (mbc);
|
free (mbc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
mbc->io->va = true;
|
||||||
mbc->file_fd = r_io_fd_open (mbc->io, &pathname[10], R_PERM_R, 0);
|
mbc->file_fd = r_io_fd_open (mbc->io, &pathname[10], R_PERM_R, 0);
|
||||||
{
|
if (mbc->n_rambanks) {
|
||||||
char *malloc_uri = r_str_newf ("malloc://0x%"PFMT64x,
|
char *malloc_uri = r_str_newf ("malloc://0x%"PFMT64x,
|
||||||
mbc->small_ram? 0x800: (0x2000 * mbc->n_rambanks));
|
mbc->small_ram? 0x800: (0x2000 * mbc->n_rambanks));
|
||||||
mbc->mem_fd = r_io_fd_open (mbc->io, malloc_uri, R_PERM_RW, 0);
|
mbc->mem_fd = r_io_fd_open (mbc->io, malloc_uri, R_PERM_RW, 0);
|
||||||
free (malloc_uri);
|
free (malloc_uri);
|
||||||
}
|
if (mbc->mem_fd < 0) {
|
||||||
if ((mbc->file_fd < 0) || (mbc->mem_fd < 0)) {
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
RIOMap *map = r_io_map_add (mbc->io, mbc->file_fd, R_PERM_R, 0ULL, 0ULL, 0x4000);
|
}
|
||||||
if (!map) {
|
if (mbc->file_fd < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
mbc->rombank_to_io_map[0] = map->id;
|
RIOMap *map;
|
||||||
ut32 i;
|
ut32 i;
|
||||||
for (i = 1; i < mbc->n_rombanks; i++) {
|
for (i = 0; i < mbc->n_rombanks; i++) {
|
||||||
map = r_io_map_add_bottom (mbc->io, mbc->file_fd, R_PERM_R,
|
map = r_io_map_add_bottom (mbc->io, mbc->file_fd, R_PERM_R,
|
||||||
0x4000 * i, 0x4000, 0x4000);
|
0x4000 * i, (i & 0x1f)? 0x4000: 0ULL, 0x4000);
|
||||||
if (!map) {
|
if (!map) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
mbc->rombank_to_io_map[i] = map->id;
|
mbc->rombank_to_io_map[i] = map->id;
|
||||||
}
|
}
|
||||||
|
if (mbc->n_rombanks < 32) {
|
||||||
|
map = r_io_map_add_bottom (mbc->io, mbc->file_fd, R_PERM_R,
|
||||||
|
0ULL, 0x4000, 0x4000);
|
||||||
|
if (!map) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
mbc->rombank0_map = map->id;
|
||||||
|
}
|
||||||
if (mbc->small_ram) {
|
if (mbc->small_ram) {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
map = r_io_map_add (mbc->io, mbc->mem_fd, R_PERM_RW,
|
map = r_io_map_add (mbc->io, mbc->mem_fd, R_PERM_RW,
|
||||||
|
@ -113,7 +149,7 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
}
|
}
|
||||||
mbc->rambank_to_io_map[i] = map->id;
|
mbc->rambank_to_io_map[i] = map->id;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mbc->n_rambanks) {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
map = r_io_map_add_bottom (mbc->io, mbc->mem_fd, R_PERM_RW,
|
map = r_io_map_add_bottom (mbc->io, mbc->mem_fd, R_PERM_RW,
|
||||||
0x2000 * i, 0xa000, 0x2000);
|
0x2000 * i, 0xa000, 0x2000);
|
||||||
|
@ -123,10 +159,15 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||||
mbc->rambank_to_io_map[i] = map->id;
|
mbc->rambank_to_io_map[i] = map->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mbc->rombank = 1;
|
mbc->rombank_high = 1;
|
||||||
mbc->io->cache.mode = 0;
|
mbc->io->cache.mode = 0;
|
||||||
desc = r_io_desc_new (io, &r_io_plugin_gb_mbc1, pathname,
|
desc = r_io_desc_new (io, &r_io_plugin_gb_mbc1, pathname,
|
||||||
R_PERM_RWX, mode, mbc);
|
R_PERM_RWX, mode, mbc);
|
||||||
|
mbc->io->va = true;
|
||||||
|
if (!desc) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
disable_ram (mbc);
|
||||||
return desc;
|
return desc;
|
||||||
fail:
|
fail:
|
||||||
r_io_free (mbc->io);
|
r_io_free (mbc->io);
|
||||||
|
@ -135,3 +176,143 @@ fail:
|
||||||
free (mbc);
|
free (mbc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool __close(RIODesc *desc) {
|
||||||
|
MBC1 *mbc = (MBC1 *)desc->data;
|
||||||
|
r_io_free (mbc->io);
|
||||||
|
free (mbc->rombank_to_io_map);
|
||||||
|
free (mbc->rambank_to_io_map);
|
||||||
|
R_FREE (desc->data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ut64 __lseek(RIO* io, RIODesc *desc, ut64 offset, int whence) {
|
||||||
|
MBC1 *mbc = (MBC1 *)desc->data;
|
||||||
|
switch (whence) {
|
||||||
|
case R_IO_SEEK_SET:
|
||||||
|
return mbc->seek = R_MIN (0xc000, offset);
|
||||||
|
case R_IO_SEEK_CUR:
|
||||||
|
return mbc->seek = R_MIN (0xc000, mbc->seek + offset);
|
||||||
|
case R_IO_SEEK_END:
|
||||||
|
return mbc->seek = 0xc000;
|
||||||
|
}
|
||||||
|
return mbc->seek;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __write(RIO *io, RIODesc *desc, const ut8 *buf, int len) {
|
||||||
|
MBC1 *mbc = (MBC1 *)desc->data;
|
||||||
|
len = R_MIN (len, 0xc000 - mbc->seek);
|
||||||
|
r_io_write_at (mbc->io, mbc->seek, buf, len);
|
||||||
|
ut64 endseek = mbc->seek + len;
|
||||||
|
ut8 rombank;
|
||||||
|
while ((mbc->seek < 0x8000) && (mbc->seek < endseek)) {
|
||||||
|
const ut32 i = mbc->seek - (endseek - len);
|
||||||
|
switch (mbc->seek & 0x6000) {
|
||||||
|
case 0ULL:
|
||||||
|
if ((buf[i] & 0x0f) == 0x0a) {
|
||||||
|
eprintf ("enabling external ram\n");
|
||||||
|
enable_ram (mbc);
|
||||||
|
} else {
|
||||||
|
eprintf ("disabling external ram\n");
|
||||||
|
disable_ram (mbc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x2000:
|
||||||
|
eprintf ("switching banks (low bits)\n");
|
||||||
|
rombank = buf[i] & 0x1f;
|
||||||
|
if (!rombank) {
|
||||||
|
rombank++;
|
||||||
|
}
|
||||||
|
rombank |= (mbc->high_rombank & 0x3) << 5;
|
||||||
|
rombank &= mbc->rombank_mask;
|
||||||
|
if (!rombank) {
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank0_map);
|
||||||
|
mbc->rombank_high = 0;
|
||||||
|
} else if (R_LIKELY (rombank < mbc->n_rombanks)) {
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank_to_io_map[rombank]);
|
||||||
|
mbc->rombank_high = rombank;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x4000: //rambank switch/high rombank bits switch
|
||||||
|
eprintf ("switching banks (high bits)\n");
|
||||||
|
mbc->rambank = buf[i] & 0x3;
|
||||||
|
rombank = mbc->rombank_high & 0x1f;
|
||||||
|
rombank |= (mbc->high_rombank & 0x3) << 5;
|
||||||
|
rombank &= mbc->rombank_mask;
|
||||||
|
if (!rombank) {
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank0_map);
|
||||||
|
mbc->rombank_high = 0;
|
||||||
|
} else if (R_LIKELY (rombank < mbc->n_rombanks)) {
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank_to_io_map[rombank]);
|
||||||
|
mbc->rombank_high = rombank;
|
||||||
|
}
|
||||||
|
if (mbc->mode) {
|
||||||
|
if (!mbc->small_ram && mbc->n_rambanks > 1) {
|
||||||
|
r_io_map_priorize (mbc->io,
|
||||||
|
mbc->rambank_to_io_map[mbc->rambank]);
|
||||||
|
}
|
||||||
|
rombank = (mbc->high_rombank << 5) & mbc->rombank_mask;
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank_to_io_map[rombank]);
|
||||||
|
mbc->rombank_low = rombank;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x6000:
|
||||||
|
eprintf ("switching mode\n");
|
||||||
|
mbc->mode = !!(buf[i] & 0x1);
|
||||||
|
if (!mbc->mode) {
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank_to_io_map[0]);
|
||||||
|
mbc->rombank_low = 0;
|
||||||
|
if (!mbc->small_ram && mbc->n_rambanks > 1) {
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rambank_to_io_map[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!mbc->small_ram && mbc->n_rambanks > 1) {
|
||||||
|
r_io_map_priorize (mbc->io,
|
||||||
|
mbc->rambank_to_io_map[mbc->rambank]);
|
||||||
|
}
|
||||||
|
rombank = (mbc->high_rombank << 5) & mbc->rombank_mask;
|
||||||
|
r_io_map_priorize (mbc->io, mbc->rombank_to_io_map[rombank]);
|
||||||
|
mbc->rombank_low = rombank;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mbc->seek++;
|
||||||
|
}
|
||||||
|
mbc->seek = endseek;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __read(RIO *io, RIODesc *desc, ut8 *buf, int len) {
|
||||||
|
MBC1 *mbc = (MBC1 *)desc->data;
|
||||||
|
len = R_MIN (len, 0xc000 - mbc->seek);
|
||||||
|
if (!r_io_read_at (mbc->io, mbc->seek, buf, len)) {
|
||||||
|
eprintf ("r_io_read_at failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
eprintf ("read @ 0x%"PFMT64x" %d bytes\n", mbc->seek, len);
|
||||||
|
mbc->seek += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
RIOPlugin r_io_plugin_gb_mbc1 = {
|
||||||
|
.meta = {
|
||||||
|
.name = "gb_mbc1",
|
||||||
|
.desc = "gb_mbc1",
|
||||||
|
.license = "LGPL",
|
||||||
|
},
|
||||||
|
.uris = "gb_mbc1://",
|
||||||
|
.open = __open,
|
||||||
|
.close = __close,
|
||||||
|
.read = __read,
|
||||||
|
.check = __check,
|
||||||
|
.seek = __lseek,
|
||||||
|
.write = __write,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef R2_PLUGIN_INCORE
|
||||||
|
R_API RLibStruct radare_plugin = {
|
||||||
|
.type = R_LIB_TYPE_IO,
|
||||||
|
.data = &r_io_plugin_gb_mbc1,
|
||||||
|
.version = R2_VERSION
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user