Immplement oam_scan
This commit is contained in:
parent
d1842269d4
commit
e88697c773
27
include/gb.h
27
include/gb.h
|
@ -87,24 +87,30 @@ enum {
|
||||||
GB_PPU_N_REGS,
|
GB_PPU_N_REGS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GB_PPU_STAT_MODE_HBLANK = 0,
|
||||||
|
GB_PPU_STAT_MODE_VBLANK,
|
||||||
|
GB_PPU_STAT_MODE_OAM_SCAN,
|
||||||
|
GB_PPU_STAT_MODE_RENDER,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GB_PPU_STAT_MODE_MASK 0x3
|
||||||
|
|
||||||
|
typedef struct oam_scan_table {
|
||||||
|
ut16 data[10]; //low byte is x coordinate of sprite; high byte is addr of entry (0xffe0 + high byte)
|
||||||
|
ut8 n_entries; //max 10
|
||||||
|
ut8 addr;
|
||||||
|
} OAMScanTable;
|
||||||
|
|
||||||
typedef struct gb_dmg_ppu_t {
|
typedef struct gb_dmg_ppu_t {
|
||||||
GBPixBuf *pixbuf;
|
GBPixBuf *pixbuf;
|
||||||
ut64 seek;
|
ut64 seek;
|
||||||
ut8 buf[GB_PPU_N_REGS];
|
ut8 buf[GB_PPU_N_REGS];
|
||||||
|
OAMScanTable ost;
|
||||||
int reg_fd;
|
int reg_fd;
|
||||||
int vram_fd;
|
int vram_fd;
|
||||||
} GBPPU;
|
} GBPPU;
|
||||||
|
|
||||||
//these are in STAT
|
|
||||||
#define GB_PPU_MODE0 0
|
|
||||||
#define GB_PPU_MODE1 1
|
|
||||||
#define GB_PPU_MODE2 2
|
|
||||||
#define GB_PPU_MODE3 3
|
|
||||||
#define GB_PPU_MODE_MASK 3
|
|
||||||
|
|
||||||
//this is in seek
|
|
||||||
#define GB_PPU_DOUBLE_SPEED 0x10000
|
|
||||||
|
|
||||||
typedef struct gameboy_t {
|
typedef struct gameboy_t {
|
||||||
RIO *io;
|
RIO *io;
|
||||||
RArch *arch;
|
RArch *arch;
|
||||||
|
@ -114,6 +120,7 @@ typedef struct gameboy_t {
|
||||||
GBPPU *ppu;
|
GBPPU *ppu;
|
||||||
ut64 addr;
|
ut64 addr;
|
||||||
int cartrigde_fd;
|
int cartrigde_fd;
|
||||||
|
bool double_speed;
|
||||||
} GB;
|
} GB;
|
||||||
|
|
||||||
GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer);
|
GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer);
|
||||||
|
|
4
io/dma.c
4
io/dma.c
|
@ -60,10 +60,10 @@ static int __bus_write(RIO *io, RIODesc *desc, const ut8 *buf, int len) {
|
||||||
int _len = R_MIN (len, 0xa0 - ((ut32)dma->dst + (st32)dma->frontrun));
|
int _len = R_MIN (len, 0xa0 - ((ut32)dma->dst + (st32)dma->frontrun));
|
||||||
// memcpy (buf, &dma->buf[dma->dst + dma->frontrun], _len);
|
// memcpy (buf, &dma->buf[dma->dst + dma->frontrun], _len);
|
||||||
dma->frontrun += _len;
|
dma->frontrun += _len;
|
||||||
#if 0
|
#if 1
|
||||||
if (len != _len) {
|
if (len != _len) {
|
||||||
ut64 vseek = r_io_p2v (io, seek + _len);
|
ut64 vseek = r_io_p2v (io, seek + _len);
|
||||||
r_io_bank_write_at (io, dma->default_bank_id, &buf[_len], len - _len)
|
r_io_bank_write_at (io, dma->default_bank_id, vseek, &buf[_len], len - _len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
seek += len;
|
seek += len;
|
||||||
|
|
51
io/ppu.c
51
io/ppu.c
|
@ -124,7 +124,58 @@ GBPPU *gb_ppu_open (RIO *io, SDL_Renderer *renderer) {
|
||||||
return ppu;
|
return ppu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ut32 gb_ppu_oam_scan_update (GB *gb, ut32 cycles) {
|
||||||
|
if (gb->ppu->ost.addr >= 0xa0) {
|
||||||
|
gb->ppu->ost.addr = 0;
|
||||||
|
gb->ppu->ost.n_entries = 0;
|
||||||
|
}
|
||||||
|
if (cycles & 0x1) {
|
||||||
|
R_LOG_WARN ("Odd amount of cycles");
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
cycles -= running_cycles;
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
const ut8 height = gb->ppu->buf[GB_PPU_LCDC] & 0x3? 16: 8;
|
||||||
|
const ut8 ly = gb->ppu->buf[GB_PPU_LY] + 16;
|
||||||
|
while (cycles && gb->ppu->ost.addr <= 0xa0) {
|
||||||
|
if (gb->ppu->ost.n_entries < 10) {
|
||||||
|
ut8 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 << 8) | yx[1];
|
||||||
|
gb->ppu->ost.n_entries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gb->ppu->ost.addr += 4;
|
||||||
|
cycles -= 2;
|
||||||
|
}
|
||||||
|
beach:
|
||||||
|
if (gb->ppu->ost.addr == 0xa0) {
|
||||||
|
//indicate next mode
|
||||||
|
gb->ppu->buf[GB_PPU_STAT] |= GB_PPU_STAT_MODE_RENDER;
|
||||||
|
}
|
||||||
|
return cycles;
|
||||||
|
}
|
||||||
|
|
||||||
void gb_ppu_update (GB *gb, ut32 cycles) {
|
void gb_ppu_update (GB *gb, ut32 cycles) {
|
||||||
|
while (cycles) {
|
||||||
|
switch (gb->ppu->buf[GB_PPU_STAT] & GB_PPU_STAT_MODE_MASK) {
|
||||||
|
case GB_PPU_STAT_MODE_OAM_SCAN:
|
||||||
|
cycles = gb_ppu_oam_scan_update (gb, cycles);
|
||||||
|
break;
|
||||||
|
case GB_PPU_STAT_MODE_RENDER:
|
||||||
|
break;
|
||||||
|
case GB_PPU_STAT_MODE_HBLANK:
|
||||||
|
break;
|
||||||
|
case GB_PPU_STAT_MODE_VBLANK:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user