Add mappings; Move oam_mapid into GBDMA
This commit is contained in:
parent
da49a72631
commit
326006255a
|
@ -88,6 +88,7 @@ typedef struct gb_dma_t {
|
|||
int dma_fd; //fd representing the dma register
|
||||
int dma_bus_fd; //fd representing the memory bus while dma occupies it
|
||||
int oam_fd; //fd representing oam
|
||||
ut32 oam_mapid;
|
||||
ut32 dma_bank_id;
|
||||
ut32 default_bank_id;
|
||||
// ut16 bus_occupancy_size;
|
||||
|
@ -103,10 +104,10 @@ typedef struct gb_dma_t {
|
|||
#define GB_DMA_ACTIVE 0x60000
|
||||
#define GB_DMA_CGB_MODE 0x80000
|
||||
|
||||
GBDMA *gb_dma_open(RIO *io);
|
||||
bool gb_dma_init(GBDMA *dma, RIO *io);
|
||||
//void gb_dma_enable_cgb(GBDMA *dma);
|
||||
void gb_dma_continue(GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec);
|
||||
void gb_dma_close(GBDMA *dma, RIO *io);
|
||||
void gb_dma_fini(GBDMA *dma, RIO *io);
|
||||
|
||||
enum {
|
||||
GB_PPU_LCDC = 0, //0xff40
|
||||
|
@ -221,7 +222,6 @@ typedef struct gb_dmg_ppu_t {
|
|||
int reg_fd;
|
||||
int vram_fd;
|
||||
ut32 vram_mapid;
|
||||
ut32 oam_mapid;
|
||||
} GBPPU;
|
||||
|
||||
enum {
|
||||
|
@ -239,7 +239,7 @@ typedef struct gameboy_t {
|
|||
GBTimers timers;
|
||||
GBJoypad joypad;
|
||||
GBInterrupts interrupts;
|
||||
GBDMA *dma;
|
||||
GBDMA dma;
|
||||
GBPPU *ppu;
|
||||
ut64 addr;
|
||||
int cartrigde_fd;
|
||||
|
|
67
io/dma.c
67
io/dma.c
|
@ -172,53 +172,77 @@ RIOPlugin r_io_plugin_gb_dma = {
|
|||
.write = __write,
|
||||
};
|
||||
|
||||
GBDMA *gb_dma_open (RIO *io) {
|
||||
GBDMA *dma = R_NEW0 (GBDMA);
|
||||
if (!dma) {
|
||||
return NULL;
|
||||
|
||||
bool gb_dma_init (GBDMA *dma, RIO *io) {
|
||||
if (!dma || !io) {
|
||||
return false;
|
||||
}
|
||||
dma[0] = (const GBDMA) {0};
|
||||
dma->default_bank_id = io->bank;
|
||||
RIOBank *bank = r_io_bank_new ("dma bus");
|
||||
if (!bank) {
|
||||
free (dma);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
if (!r_io_bank_add (io, bank)) {
|
||||
r_io_bank_free (bank);
|
||||
free (dma);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
dma->dma_bank_id = bank->id;
|
||||
// strcpy (uri, "malloc://0xa0");
|
||||
dma->oam_fd = r_io_fd_open (io, "malloc://0xa0", R_PERM_RWX, 0);
|
||||
if (dma->oam_fd < 0) {
|
||||
r_io_bank_del (io, bank->id);
|
||||
r_io_bank_free (bank);
|
||||
free (dma);
|
||||
return NULL;
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
return false;
|
||||
}
|
||||
RIOMap *oam_map = r_io_map_add (io, dma->oam_fd, R_PERM_RWX, 0, 0xffe0, 0xa0);
|
||||
if (!oam_map) {
|
||||
r_io_bank_del (io, bank->id);
|
||||
r_io_bank_free (bank);
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
return false;
|
||||
}
|
||||
dma->oam_mapid = oam_map->id;
|
||||
char uri[64];
|
||||
memset (uri, 0x00, sizeof (char) * 64);
|
||||
sprintf (uri, "gb_dma://%p", dma);
|
||||
RIODesc *desc = r_io_desc_open_plugin (io, &r_io_plugin_gb_dma,
|
||||
uri, R_PERM_RWX, 0);
|
||||
if (!desc) {
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
r_io_bank_del (io, bank->id);
|
||||
r_io_bank_free (bank);
|
||||
free (dma);
|
||||
return NULL;
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
return false;
|
||||
}
|
||||
if (!r_io_map_add (io, dma->dma_fd, R_PERM_RWX, 0, 0xff46, 1)) {
|
||||
r_io_bank_del (io, bank->id);
|
||||
r_io_bank_free (bank);
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
r_io_desc_close (desc);
|
||||
}
|
||||
dma->dma_fd = desc->fd;
|
||||
sprintf (uri, "gb_dma_bus://%p", dma);
|
||||
desc = r_io_desc_open_plugin (io, &r_io_plugin_gb_dma_bus, uri, R_PERM_RWX, 0);
|
||||
if (!desc) {
|
||||
r_io_bank_del (io, dma->dma_bank_id);
|
||||
r_io_bank_free (bank);
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
r_io_fd_close (io, dma->dma_fd);
|
||||
r_io_bank_free (bank);
|
||||
free (dma);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
r_io_bank_use (io, dma->dma_bank_id);
|
||||
if (!r_io_map_add (io, desc->fd, R_PERM_RWX, 0, 0, 0xff80)) {
|
||||
r_io_bank_use (io, dma->default_bank_id);
|
||||
r_io_bank_del (io, dma->dma_bank_id);
|
||||
r_io_bank_free (bank);
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
r_io_fd_close (io, dma->dma_fd);
|
||||
r_io_desc_close (desc);
|
||||
return false;
|
||||
}
|
||||
r_io_bank_use (io, dma->default_bank_id);
|
||||
dma->dma_bus_fd = desc->fd;
|
||||
return dma;
|
||||
return true;
|
||||
}
|
||||
|
||||
void gb_dma_continue (GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec) {
|
||||
|
@ -264,14 +288,15 @@ void gb_dma_continue (GBDMA *dma, RIO *io, ut32 cycles, bool pre_exec) {
|
|||
}
|
||||
}
|
||||
|
||||
void gb_dma_close (GBDMA *dma, RIO *io) {
|
||||
void gb_dma_fini (GBDMA *dma, RIO *io) {
|
||||
if (!dma || !io) {
|
||||
return;
|
||||
}
|
||||
r_io_bank_use (io, dma->default_bank_id);
|
||||
r_io_bank_del (io, dma->dma_bank_id);
|
||||
r_io_fd_close (io, dma->dma_bus_fd);
|
||||
r_io_fd_close (io, dma->dma_fd);
|
||||
r_io_fd_close (io, dma->oam_fd);
|
||||
free (dma);
|
||||
RIOBank *bank = r_io_bank_get (io, dma->dma_bank_id);
|
||||
r_io_bank_del (io, dma->dma_bank_id);
|
||||
r_io_bank_free (bank);
|
||||
}
|
||||
|
|
|
@ -107,6 +107,17 @@ bool gb_interrupts_init(GBInterrupts *ints, RIO *io, RReg *reg) {
|
|||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
//map IF register
|
||||
if (!r_io_map_add (io, desc->fd, R_PERM_RWX, 0, 0xff0f, 1)) {
|
||||
r_io_desc_close (desc);
|
||||
return false;
|
||||
}
|
||||
//map IE register
|
||||
if (!r_io_map_add (io, desc->fd, R_PERM_RWX, 1, 0xffff, 1)) {
|
||||
r_io_desc_close (desc);
|
||||
//r_io will automatically remove the map for IF register
|
||||
return false;
|
||||
}
|
||||
ints->fd = desc->fd;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,10 @@ bool gb_joypad_init (GBJoypad *joypad, RIO *io) {
|
|||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
if (!r_io_map_add (io, desc->fd, R_PERM_RWX, 0, 0xff00, 1)) {
|
||||
r_io_desc_close (desc);
|
||||
return false;
|
||||
}
|
||||
joypad->fd = desc->fd;
|
||||
const ut8 *keys = SDL_GetKeyboardState (NULL);
|
||||
memcpy (&joypad->keys, &keys, sizeof (ut8 *));
|
||||
|
|
16
io/ppu.c
16
io/ppu.c
|
@ -139,7 +139,7 @@ static ut32 gb_ppu_oam_scan_continue (GB *gb, ut32 cycles) {
|
|||
if (cycles & 0x1) {
|
||||
R_LOG_WARN ("Odd amount of cycles");
|
||||
}
|
||||
if (gb->dma->seek & GB_DMA_ACTIVE) {
|
||||
if (gb->dma.seek & GB_DMA_ACTIVE) {
|
||||
const ut8 running_cycles = R_MIN (cycles, (0xa0 - gb->ppu->ost.addr) >> 1);
|
||||
//every oam entry costs 2 cycles
|
||||
gb->ppu->ost.addr += running_cycles << 1;
|
||||
|
@ -152,7 +152,7 @@ static ut32 gb_ppu_oam_scan_continue (GB *gb, ut32 cycles) {
|
|||
if (gb->ppu->ost.n_entries < 10) {
|
||||
ut8 yx[2];
|
||||
//this is probably inaccurate
|
||||
r_io_fd_read_at (gb->io, gb->dma->oam_fd, (ut64)gb->ppu->ost.addr, yx, 2);
|
||||
r_io_fd_read_at (gb->io, gb->dma.oam_fd, (ut64)gb->ppu->ost.addr, yx, 2);
|
||||
if ((yx[0] <= ly) && (ly < (yx[0] + height))) {
|
||||
gb->ppu->ost.data[gb->ppu->ost.n_entries] =
|
||||
(gb->ppu->ost.addr << 16) | (yx[0] << 8) | yx[1];
|
||||
|
@ -253,7 +253,7 @@ static void gb_pixel_fifo_fetch_continue (GB *gb) {
|
|||
fifo->fetcher[0].addr += (gb->ppu->buf[GB_PPU_LY] & 0x7) * 2;
|
||||
}
|
||||
} else {
|
||||
read_obj_data (gb->ppu, gb->io, &tile, gb->dma->oam_fd);
|
||||
read_obj_data (gb->ppu, gb->io, &tile, gb->dma.oam_fd);
|
||||
fifo->fetcher[1].addr = tile;
|
||||
}
|
||||
case 1:
|
||||
|
@ -262,7 +262,7 @@ static void gb_pixel_fifo_fetch_continue (GB *gb) {
|
|||
if (fetch_obj) {
|
||||
ut8 addr = (fifo->obj >> 16) & 0xff;
|
||||
//read object attributes
|
||||
r_io_fd_read_at (gb->io, gb->dma->oam_fd, (ut64)(addr + 3), &tile, 1);
|
||||
r_io_fd_read_at (gb->io, gb->dma.oam_fd, (ut64)(addr + 3), &tile, 1);
|
||||
fifo->obj = (fifo->obj & 0xffffff) | (tile << 24);
|
||||
//tile idx
|
||||
tile = fifo->fetcher[1].addr & 0xff;
|
||||
|
@ -526,7 +526,7 @@ static ut32 gb_ppu_vblank_continue (GB *gb, ut32 cycles) {
|
|||
void gb_ppu_continue (GB *gb, ut32 cycles) {
|
||||
if (gb->ppu->fifo.flags1 & GB_PIXEL_FIFO_LCDC_SWITCH) {
|
||||
gb->ppu->fifo.flags1 ^= GB_PIXEL_FIFO_LCDC_SWITCH;
|
||||
RIOMap *map = r_io_map_get (gb->io, gb->ppu->oam_mapid);
|
||||
RIOMap *map = r_io_map_get (gb->io, gb->dma.oam_mapid);
|
||||
if (gb->ppu->buf[GB_PPU_LCDC] & GB_PPU_LCDC_ENABLE) {
|
||||
//lcd was switched on
|
||||
//launch oam scan
|
||||
|
@ -568,7 +568,7 @@ void gb_ppu_continue (GB *gb, ut32 cycles) {
|
|||
case GB_PPU_STAT_MODE_RENDER:
|
||||
cycles = gb_ppu_render_continue (gb, cycles);
|
||||
if ((gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) == GB_PPU_STAT_MODE_HBLANK) {
|
||||
RIOMap *map = r_io_map_get (gb->io, gb->ppu->oam_mapid);
|
||||
RIOMap *map = r_io_map_get (gb->io, gb->dma.oam_mapid);
|
||||
map->perm = R_PERM_RWX;
|
||||
map = r_io_map_get (gb->io, gb->ppu->vram_mapid);
|
||||
map->perm = R_PERM_RWX;
|
||||
|
@ -577,7 +577,7 @@ void gb_ppu_continue (GB *gb, ut32 cycles) {
|
|||
case GB_PPU_STAT_MODE_HBLANK:
|
||||
cycles = gb_ppu_hblank_continue (gb, cycles);
|
||||
if ((gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) == GB_PPU_STAT_MODE_OAM_SCAN) {
|
||||
RIOMap *oam = r_io_map_get (gb->io, gb->ppu->oam_mapid);
|
||||
RIOMap *oam = r_io_map_get (gb->io, gb->dma.oam_mapid);
|
||||
oam->perm = 0;
|
||||
if (gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_INTR_OAM) {
|
||||
gb_interrupts_request (gb, GB_INTERRUPT_STAT);
|
||||
|
@ -594,7 +594,7 @@ void gb_ppu_continue (GB *gb, ut32 cycles) {
|
|||
cycles = gb_ppu_vblank_continue (gb, cycles);
|
||||
if ((gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) == GB_PPU_STAT_MODE_OAM_SCAN) {
|
||||
gb->ppu->buf[GB_PPU_LY] = 0;
|
||||
RIOMap *oam = r_io_map_get (gb->io, gb->ppu->oam_mapid);
|
||||
RIOMap *oam = r_io_map_get (gb->io, gb->dma.oam_mapid);
|
||||
oam->perm = 0;
|
||||
if (gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_INTR_OAM) {
|
||||
gb_interrupts_request (gb, GB_INTERRUPT_STAT);
|
||||
|
|
|
@ -112,7 +112,11 @@ bool gb_timers_init (GBTimers *timers, RIO *io) {
|
|||
RIODesc *desc = r_io_desc_open_plugin (io, &r_io_plugin_gb_timers,
|
||||
uri, R_PERM_RWX, 0);
|
||||
if (!desc) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
if (!r_io_map_add (io, desc->fd, R_PERM_RWX, 0, 0xff04, 4)) {
|
||||
r_io_desc_close (desc);
|
||||
return false;
|
||||
}
|
||||
timers->fd = desc->fd;
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue
Block a user