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,
|
||||
};
|
||||
|
||||
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 {
|
||||
GBPixBuf *pixbuf;
|
||||
ut64 seek;
|
||||
ut8 buf[GB_PPU_N_REGS];
|
||||
OAMScanTable ost;
|
||||
int reg_fd;
|
||||
int vram_fd;
|
||||
} 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 {
|
||||
RIO *io;
|
||||
RArch *arch;
|
||||
|
@ -114,6 +120,7 @@ typedef struct gameboy_t {
|
|||
GBPPU *ppu;
|
||||
ut64 addr;
|
||||
int cartrigde_fd;
|
||||
bool double_speed;
|
||||
} GB;
|
||||
|
||||
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));
|
||||
// memcpy (buf, &dma->buf[dma->dst + dma->frontrun], _len);
|
||||
dma->frontrun += _len;
|
||||
#if 0
|
||||
#if 1
|
||||
if (len != _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
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user