use references for dc / rb

align ir locals when allocating
This commit is contained in:
Anthony Pesch 2016-03-23 00:45:08 -07:00
parent d234f630f1
commit 98ca25fecb
25 changed files with 166 additions and 192 deletions

View File

@ -92,13 +92,13 @@ void Emulator::Run(const char *path) {
}
bool Emulator::CreateDreamcast() {
dc_.sh4 = new SH4(&dc_);
dc_.aica = new AICA(&dc_);
dc_.gdrom = new GDROM(&dc_);
dc_.holly = new Holly(&dc_);
dc_.maple = new Maple(&dc_);
dc_.pvr = new PVR2(&dc_);
dc_.ta = new TileAccelerator(&dc_, window_.render_backend());
dc_.sh4 = new SH4(dc_);
dc_.aica = new AICA(dc_);
dc_.gdrom = new GDROM(dc_);
dc_.holly = new Holly(dc_);
dc_.maple = new Maple(dc_);
dc_.pvr = new PVR2(dc_);
dc_.ta = new TileAccelerator(dc_, window_.render_backend());
if (!dc_.Init()) {
DestroyDreamcast();

View File

@ -81,7 +81,7 @@ TextureHandle TraceTextureCache::GetTexture(hw::holly::TextureKey texture_key) {
Tracer::Tracer(Window &window)
: window_(window),
rb_(*window.render_backend()),
rb_(window.render_backend()),
tile_renderer_(rb_, texcache_),
hide_params_() {
window_.AddListener(this);

View File

@ -8,16 +8,16 @@ using namespace re::hw;
using namespace re::hw::aica;
using namespace re::hw::holly;
AICA::AICA(Dreamcast *dc)
: Device(*dc),
AICA::AICA(Dreamcast &dc)
: Device(dc),
MemoryInterface(this),
dc_(dc),
aica_regs_(nullptr),
wave_ram_(nullptr) {}
bool AICA::Init() {
aica_regs_ = dc_->memory->TranslateVirtual(AICA_REG_START);
wave_ram_ = dc_->memory->TranslateVirtual(WAVE_RAM_START);
aica_regs_ = dc_.memory->TranslateVirtual(AICA_REG_START);
wave_ram_ = dc_.memory->TranslateVirtual(WAVE_RAM_START);
return true;
}
@ -49,7 +49,7 @@ void AICA::MapPhysicalMemory(Memory &memory, MemoryMap &memmap) {
// // if (MCIEB || MCIPD) {
// // LOG_INFO("0x%x & 0x%x", MCIEB, MCIPD);
// // }
// // dc_->holly()->RequestInterrupt(HOLLY_INTC_G2AICINT);
// // dc_.holly()->RequestInterrupt(HOLLY_INTC_G2AICINT);
// return cycles;
// }

View File

@ -12,7 +12,7 @@ namespace aica {
class AICA : public Device, public MemoryInterface {
public:
AICA(Dreamcast *dc);
AICA(Dreamcast &dc);
bool Init() final;
@ -28,7 +28,7 @@ class AICA : public Device, public MemoryInterface {
template <typename T>
void WriteWave(uint32_t addr, T value);
Dreamcast *dc_;
Dreamcast &dc_;
uint8_t *aica_regs_;
uint8_t *wave_ram_;
};

View File

@ -13,8 +13,8 @@ using namespace re::hw::sh4;
#define SWAP_24(fad) \
(((fad & 0xff) << 16) | (fad & 0x00ff00) | ((fad & 0xff0000) >> 16))
GDROM::GDROM(Dreamcast *dc)
: Device(*dc),
GDROM::GDROM(Dreamcast &dc)
: Device(dc),
dc_(dc),
memory_(nullptr),
holly_(nullptr),
@ -35,9 +35,9 @@ GDROM::GDROM(Dreamcast *dc)
GDROM::~GDROM() { delete[] dma_buffer_; }
bool GDROM::Init() {
memory_ = dc_->memory;
holly_ = dc_->holly;
holly_regs_ = dc_->holly_regs;
memory_ = dc_.memory;
holly_ = dc_.holly;
holly_regs_ = dc_.holly_regs;
SetDisc(nullptr);
@ -196,12 +196,12 @@ void GDROM::WriteRegister(uint32_t addr, T value) {
// SB_GDSTAR, SB_GDLEN, or SB_GDDIR register is overwritten while a DMA
// operation is in progress, the new setting has no effect on the
// current DMA operation.
CHECK_EQ(dc_->SB_GDEN, 1); // dma enabled
CHECK_EQ(dc_->SB_GDDIR, 1); // gd-rom -> system memory
CHECK_EQ(dc_->SB_GDLEN, (uint32_t)dma_size_);
CHECK_EQ(dc_.SB_GDEN, 1); // dma enabled
CHECK_EQ(dc_.SB_GDDIR, 1); // gd-rom -> system memory
CHECK_EQ(dc_.SB_GDLEN, (uint32_t)dma_size_);
int transfer_size = dc_->SB_GDLEN;
uint32_t start = dc_->SB_GDSTAR;
int transfer_size = dc_.SB_GDLEN;
uint32_t start = dc_.SB_GDSTAR;
LOG_INFO("GD DMA START 0x%x -> 0x%x, 0x%x bytes", start,
start + transfer_size, transfer_size);
@ -209,9 +209,9 @@ void GDROM::WriteRegister(uint32_t addr, T value) {
memory_->Memcpy(start, dma_buffer_, transfer_size);
// done
dc_->SB_GDSTARD = start + transfer_size;
dc_->SB_GDLEND = transfer_size;
dc_->SB_GDST = 0;
dc_.SB_GDSTARD = start + transfer_size;
dc_.SB_GDLEND = transfer_size;
dc_.SB_GDST = 0;
holly_->RequestInterrupt(HOLLY_INTC_G1DEINT);
// finish off CD_READ command

View File

@ -207,7 +207,7 @@ class GDROM : public Device {
friend class holly::Holly;
public:
GDROM(Dreamcast *dc);
GDROM(Dreamcast &dc);
~GDROM();
bool Init() final;
@ -231,7 +231,7 @@ class GDROM : public Device {
int ReadSectors(int fad, SectorFormat format, DataMask mask, int num_sectors,
uint8_t *dst);
Dreamcast *dc_;
Dreamcast &dc_;
Memory *memory_;
holly::Holly *holly_;
Register *holly_regs_;

View File

@ -13,8 +13,8 @@ using namespace re::hw::maple;
using namespace re::hw::sh4;
using namespace re::sys;
Holly::Holly(Dreamcast *dc)
: Device(*dc),
Holly::Holly(Dreamcast &dc)
: Device(dc),
MemoryInterface(this),
dc_(dc),
holly_regs_(nullptr),
@ -23,10 +23,10 @@ Holly::Holly(Dreamcast *dc)
sh4_(nullptr) {}
bool Holly::Init() {
holly_regs_ = dc_->holly_regs;
gdrom_ = dc_->gdrom;
maple_ = dc_->maple;
sh4_ = dc_->sh4;
holly_regs_ = dc_.holly_regs;
gdrom_ = dc_.gdrom;
maple_ = dc_.maple;
sh4_ = dc_.sh4;
// initialize registers
#define HOLLY_REG(addr, name, flags, default, type) \
@ -43,20 +43,20 @@ void Holly::RequestInterrupt(HollyInterrupt intr) {
uint32_t irq = static_cast<uint32_t>(intr & ~HOLLY_INTC_MASK);
if (intr == HOLLY_INTC_PCVOINT) {
dc_->maple->VBlank();
dc_.maple->VBlank();
}
switch (type) {
case HOLLY_INTC_NRM:
dc_->SB_ISTNRM |= irq;
dc_.SB_ISTNRM |= irq;
break;
case HOLLY_INTC_EXT:
dc_->SB_ISTEXT |= irq;
dc_.SB_ISTEXT |= irq;
break;
case HOLLY_INTC_ERR:
dc_->SB_ISTERR |= irq;
dc_.SB_ISTERR |= irq;
break;
}
@ -70,15 +70,15 @@ void Holly::UnrequestInterrupt(HollyInterrupt intr) {
switch (type) {
case HOLLY_INTC_NRM:
dc_->SB_ISTNRM &= ~irq;
dc_.SB_ISTNRM &= ~irq;
break;
case HOLLY_INTC_EXT:
dc_->SB_ISTEXT &= ~irq;
dc_.SB_ISTEXT &= ~irq;
break;
case HOLLY_INTC_ERR:
dc_->SB_ISTERR &= ~irq;
dc_.SB_ISTERR &= ~irq;
break;
}
@ -122,10 +122,10 @@ T Holly::ReadRegister(uint32_t addr) {
// bits in SB_ISTEXT and SB_ISTERR, respectively, and writes to these two
// bits are ignored.
uint32_t v = reg.value & 0x3fffffff;
if (dc_->SB_ISTEXT) {
if (dc_.SB_ISTEXT) {
v |= 0x40000000;
}
if (dc_->SB_ISTERR) {
if (dc_.SB_ISTERR) {
v |= 0x80000000;
}
return static_cast<T>(v);
@ -219,15 +219,15 @@ void Holly::WriteRegister(uint32_t addr, T value) {
// FIXME what are SB_LMMODE0 / SB_LMMODE1
void Holly::CH2DMATransfer() {
sh4_->DDT(2, DDT_W, dc_->SB_C2DSTAT);
sh4_->DDT(2, DDT_W, dc_.SB_C2DSTAT);
dc_->SB_C2DLEN = 0;
dc_->SB_C2DST = 0;
dc_.SB_C2DLEN = 0;
dc_.SB_C2DST = 0;
RequestInterrupt(HOLLY_INTC_DTDE2INT);
}
void Holly::SortDMATransfer() {
dc_->SB_SDST = 0;
dc_.SB_SDST = 0;
RequestInterrupt(HOLLY_INTC_DTDESINT);
}
@ -235,9 +235,8 @@ void Holly::ForwardRequestInterrupts() {
// trigger the respective level-encoded interrupt on the sh4 interrupt
// controller
{
if ((dc_->SB_ISTNRM & dc_->SB_IML6NRM) ||
(dc_->SB_ISTERR & dc_->SB_IML6ERR) ||
(dc_->SB_ISTEXT & dc_->SB_IML6EXT)) {
if ((dc_.SB_ISTNRM & dc_.SB_IML6NRM) || (dc_.SB_ISTERR & dc_.SB_IML6ERR) ||
(dc_.SB_ISTEXT & dc_.SB_IML6EXT)) {
sh4_->RequestInterrupt(SH4_INTC_IRL_9);
} else {
sh4_->UnrequestInterrupt(SH4_INTC_IRL_9);
@ -245,9 +244,8 @@ void Holly::ForwardRequestInterrupts() {
}
{
if ((dc_->SB_ISTNRM & dc_->SB_IML4NRM) ||
(dc_->SB_ISTERR & dc_->SB_IML4ERR) ||
(dc_->SB_ISTEXT & dc_->SB_IML4EXT)) {
if ((dc_.SB_ISTNRM & dc_.SB_IML4NRM) || (dc_.SB_ISTERR & dc_.SB_IML4ERR) ||
(dc_.SB_ISTEXT & dc_.SB_IML4EXT)) {
sh4_->RequestInterrupt(SH4_INTC_IRL_11);
} else {
sh4_->UnrequestInterrupt(SH4_INTC_IRL_11);
@ -255,9 +253,8 @@ void Holly::ForwardRequestInterrupts() {
}
{
if ((dc_->SB_ISTNRM & dc_->SB_IML2NRM) ||
(dc_->SB_ISTERR & dc_->SB_IML2ERR) ||
(dc_->SB_ISTEXT & dc_->SB_IML2EXT)) {
if ((dc_.SB_ISTNRM & dc_.SB_IML2NRM) || (dc_.SB_ISTERR & dc_.SB_IML2ERR) ||
(dc_.SB_ISTEXT & dc_.SB_IML2EXT)) {
sh4_->RequestInterrupt(SH4_INTC_IRL_13);
} else {
sh4_->UnrequestInterrupt(SH4_INTC_IRL_13);

View File

@ -158,7 +158,7 @@ enum HollyInterrupt : uint64_t {
class Holly : public Device, public MemoryInterface {
public:
Holly(Dreamcast *dc);
Holly(Dreamcast &dc);
bool Init() final;
@ -178,7 +178,7 @@ class Holly : public Device, public MemoryInterface {
void SortDMATransfer();
void ForwardRequestInterrupts();
Dreamcast *dc_;
Dreamcast &dc_;
Register *holly_regs_;
gdrom::GDROM *gdrom_;
maple::Maple *maple_;

View File

@ -11,8 +11,8 @@ using namespace re::hw::holly;
using namespace re::hw::sh4;
using namespace re::renderer;
PVR2::PVR2(Dreamcast *dc)
: Device(*dc),
PVR2::PVR2(Dreamcast &dc)
: Device(dc),
MemoryInterface(this),
dc_(dc),
scheduler_(nullptr),
@ -26,12 +26,12 @@ PVR2::PVR2(Dreamcast *dc)
current_scanline_(0) {}
bool PVR2::Init() {
scheduler_ = dc_->scheduler;
holly_ = dc_->holly;
ta_ = dc_->ta;
pvr_regs_ = dc_->pvr_regs;
palette_ram_ = dc_->memory->TranslateVirtual(PVR_PALETTE_START);
video_ram_ = dc_->memory->TranslateVirtual(PVR_VRAM32_START);
scheduler_ = dc_.scheduler;
holly_ = dc_.holly;
ta_ = dc_.ta;
pvr_regs_ = dc_.pvr_regs;
palette_ram_ = dc_.memory->TranslateVirtual(PVR_PALETTE_START);
video_ram_ = dc_.memory->TranslateVirtual(PVR_VRAM32_START);
// initialize registers
#define PVR_REG(addr, name, flags, default, type) \
@ -101,7 +101,7 @@ void PVR2::WriteRegister(uint32_t addr, uint32_t value) {
case TA_LIST_INIT_OFFSET: {
if (value & 0x80000000) {
ta_->InitContext(dc_->TA_ISP_BASE.base_address);
ta_->InitContext(dc_.TA_ISP_BASE.base_address);
}
} break;
@ -113,7 +113,7 @@ void PVR2::WriteRegister(uint32_t addr, uint32_t value) {
case STARTRENDER_OFFSET: {
if (value) {
ta_->FinalizeContext(dc_->PARAM_BASE.base_address);
ta_->FinalizeContext(dc_.PARAM_BASE.base_address);
}
} break;
@ -160,22 +160,21 @@ void PVR2::WriteVRamInterleaved(uint32_t addr, T value) {
void PVR2::ReconfigureSPG() {
// get and scale pixel clock frequency
int pixel_clock = 13500000;
if (dc_->FB_R_CTRL.vclk_div) {
if (dc_.FB_R_CTRL.vclk_div) {
pixel_clock *= 2;
}
// hcount is number of pixel clock cycles per line - 1
line_clock_ = pixel_clock / (dc_->SPG_LOAD.hcount + 1);
if (dc_->SPG_CONTROL.interlace) {
line_clock_ = pixel_clock / (dc_.SPG_LOAD.hcount + 1);
if (dc_.SPG_CONTROL.interlace) {
line_clock_ *= 2;
}
LOG_INFO(
"ReconfigureSPG: pixel_clock %d, line_clock %d, vcount %d, hcount %d, "
"interlace %d, vbstart %d, vbend %d",
pixel_clock, line_clock_, dc_->SPG_LOAD.vcount, dc_->SPG_LOAD.hcount,
dc_->SPG_CONTROL.interlace, dc_->SPG_VBLANK.vbstart,
dc_->SPG_VBLANK.vbend);
pixel_clock, line_clock_, dc_.SPG_LOAD.vcount, dc_.SPG_LOAD.hcount,
dc_.SPG_CONTROL.interlace, dc_.SPG_VBLANK.vbstart, dc_.SPG_VBLANK.vbend);
if (line_timer_ != INVALID_TIMER) {
scheduler_->CancelTimer(line_timer_);
@ -187,34 +186,34 @@ void PVR2::ReconfigureSPG() {
}
void PVR2::NextScanline() {
uint32_t num_scanlines = dc_->SPG_LOAD.vcount + 1;
uint32_t num_scanlines = dc_.SPG_LOAD.vcount + 1;
if (current_scanline_ > num_scanlines) {
current_scanline_ = 0;
}
// vblank in
if (current_scanline_ == dc_->SPG_VBLANK_INT.vblank_in_line_number) {
if (current_scanline_ == dc_.SPG_VBLANK_INT.vblank_in_line_number) {
holly_->RequestInterrupt(HOLLY_INTC_PCVIINT);
}
// vblank out
if (current_scanline_ == dc_->SPG_VBLANK_INT.vblank_out_line_number) {
if (current_scanline_ == dc_.SPG_VBLANK_INT.vblank_out_line_number) {
holly_->RequestInterrupt(HOLLY_INTC_PCVOINT);
}
// hblank in
holly_->RequestInterrupt(HOLLY_INTC_PCHIINT);
// bool was_vsync = dc_->SPG_STATUS.vsync;
dc_->SPG_STATUS.vsync = dc_->SPG_VBLANK.vbstart < dc_->SPG_VBLANK.vbend
? (current_scanline_ >= dc_->SPG_VBLANK.vbstart &&
current_scanline_ < dc_->SPG_VBLANK.vbend)
: (current_scanline_ >= dc_->SPG_VBLANK.vbstart ||
current_scanline_ < dc_->SPG_VBLANK.vbend);
dc_->SPG_STATUS.scanline = current_scanline_++;
// bool was_vsync = dc_.SPG_STATUS.vsync;
dc_.SPG_STATUS.vsync = dc_.SPG_VBLANK.vbstart < dc_.SPG_VBLANK.vbend
? (current_scanline_ >= dc_.SPG_VBLANK.vbstart &&
current_scanline_ < dc_.SPG_VBLANK.vbend)
: (current_scanline_ >= dc_.SPG_VBLANK.vbstart ||
current_scanline_ < dc_.SPG_VBLANK.vbend);
dc_.SPG_STATUS.scanline = current_scanline_++;
// FIXME toggle SPG_STATUS.fieldnum on vblank?
// if (!was_vsync && dc_->SPG_STATUS.vsync) {
// if (!was_vsync && dc_.SPG_STATUS.vsync) {
// }
// reschedule

View File

@ -18,7 +18,7 @@ class TileAccelerator;
class PVR2 : public Device, public MemoryInterface {
public:
PVR2(Dreamcast *dc);
PVR2(Dreamcast &dc);
bool Init() final;
@ -37,7 +37,7 @@ class PVR2 : public Device, public MemoryInterface {
void ReconfigureSPG();
void NextScanline();
Dreamcast *dc_;
Dreamcast &dc_;
Scheduler *scheduler_;
holly::Holly *holly_;
holly::TileAccelerator *ta_;

View File

@ -206,13 +206,13 @@ int TileAccelerator::GetVertexType(const PCW &pcw) {
pcw.para_type * TA_NUM_LISTS + pcw.list_type];
}
TileAccelerator::TileAccelerator(Dreamcast *dc, Backend *rb)
: Device(*dc),
TileAccelerator::TileAccelerator(Dreamcast &dc, Backend &rb)
: Device(dc),
MemoryInterface(this),
WindowInterface(this),
dc_(dc),
rb_(rb),
tile_renderer_(*rb, *this),
tile_renderer_(rb, *this),
memory_(nullptr),
holly_(nullptr),
video_ram_(nullptr),
@ -227,9 +227,9 @@ TileAccelerator::TileAccelerator(Dreamcast *dc, Backend *rb)
}
bool TileAccelerator::Init() {
memory_ = dc_->memory;
holly_ = dc_->holly;
video_ram_ = dc_->memory->TranslateVirtual(PVR_VRAM32_START);
memory_ = dc_.memory;
holly_ = dc_.holly;
video_ram_ = dc_.memory->TranslateVirtual(PVR_VRAM32_START);
return true;
}
@ -253,7 +253,7 @@ TextureHandle TileAccelerator::GetTexture(const TSP &tsp, const TCW &tcw,
uint32_t texture_addr = tcw.texture_addr << 3;
// get the texture data
uint8_t *video_ram = dc_->memory->TranslateVirtual(PVR_VRAM32_START);
uint8_t *video_ram = dc_.memory->TranslateVirtual(PVR_VRAM32_START);
uint8_t *texture = &video_ram[texture_addr];
int width = 8 << tsp.texture_u_size;
int height = 8 << tsp.texture_v_size;
@ -263,7 +263,7 @@ TextureHandle TileAccelerator::GetTexture(const TSP &tsp, const TCW &tcw,
int texture_size = (width * height * element_size_bits) >> 3;
// get the palette data
uint8_t *palette_ram = dc_->memory->TranslateVirtual(PVR_PALETTE_START);
uint8_t *palette_ram = dc_.memory->TranslateVirtual(PVR_PALETTE_START);
uint8_t *palette = nullptr;
uint32_t palette_addr = 0;
int palette_size = 0;
@ -459,7 +459,7 @@ void TileAccelerator::OnPaint(bool show_main_menu) {
}
void TileAccelerator::WritePolyFIFO(uint32_t addr, uint32_t value) {
WriteContext(dc_->TA_ISP_BASE.base_address, value);
WriteContext(dc_.TA_ISP_BASE.base_address, value);
}
void TileAccelerator::WriteTextureFIFO(uint32_t addr, uint32_t value) {
@ -517,7 +517,7 @@ void TileAccelerator::InvalidateTexture(TextureCacheMap::iterator it) {
RemoveAccessWatch(entry.palette_watch);
}
rb_->FreeTexture(entry.handle);
rb_.FreeTexture(entry.handle);
textures_.erase(it);
}
@ -552,23 +552,23 @@ void TileAccelerator::HandlePaletteWrite(const Exception &ex, void *data) {
void TileAccelerator::SaveRegisterState(TileContext *tctx) {
// autosort
if (!dc_->FPU_PARAM_CFG.region_header_type) {
tctx->autosort = !dc_->ISP_FEED_CFG.presort;
if (!dc_.FPU_PARAM_CFG.region_header_type) {
tctx->autosort = !dc_.ISP_FEED_CFG.presort;
} else {
uint32_t region_data = memory_->R32(PVR_VRAM64_START + dc_->REGION_BASE);
uint32_t region_data = memory_->R32(PVR_VRAM64_START + dc_.REGION_BASE);
tctx->autosort = !(region_data & 0x20000000);
}
// texture stride
tctx->stride = dc_->TEXT_CONTROL.stride * 32;
tctx->stride = dc_.TEXT_CONTROL.stride * 32;
// texture palette pixel format
tctx->pal_pxl_format = dc_->PAL_RAM_CTRL.pixel_format;
tctx->pal_pxl_format = dc_.PAL_RAM_CTRL.pixel_format;
// write out video width to help with unprojecting the screen space
// coordinates
if (dc_->SPG_CONTROL.interlace ||
(!dc_->SPG_CONTROL.NTSC && !dc_->SPG_CONTROL.PAL)) {
if (dc_.SPG_CONTROL.interlace ||
(!dc_.SPG_CONTROL.NTSC && !dc_.SPG_CONTROL.PAL)) {
// interlaced and VGA mode both render at full resolution
tctx->video_width = 640;
tctx->video_height = 480;
@ -585,7 +585,7 @@ void TileAccelerator::SaveRegisterState(TileContext *tctx) {
// correct solution
uint32_t vram_offset =
PVR_VRAM64_START +
((tctx->addr + dc_->ISP_BACKGND_T.tag_address * 4) & 0x7fffff);
((tctx->addr + dc_.ISP_BACKGND_T.tag_address * 4) & 0x7fffff);
// get surface parameters
tctx->bg_isp.full = memory_->R32(vram_offset);
@ -594,20 +594,20 @@ void TileAccelerator::SaveRegisterState(TileContext *tctx) {
vram_offset += 12;
// get the background depth
tctx->bg_depth = re::load<float>(&dc_->ISP_BACKGND_D);
tctx->bg_depth = re::load<float>(&dc_.ISP_BACKGND_D);
// get the byte size for each vertex. normally, the byte size is
// ISP_BACKGND_T.skip + 3, but if parameter selection volume mode is in
// effect and the shadow bit is 1, then the byte size is
// ISP_BACKGND_T.skip * 2 + 3
int vertex_size = dc_->ISP_BACKGND_T.skip;
if (!dc_->FPU_SHAD_SCALE.intensity_volume_mode && dc_->ISP_BACKGND_T.shadow) {
int vertex_size = dc_.ISP_BACKGND_T.skip;
if (!dc_.FPU_SHAD_SCALE.intensity_volume_mode && dc_.ISP_BACKGND_T.shadow) {
vertex_size *= 2;
}
vertex_size = (vertex_size + 3) * 4;
// skip to the first vertex
vram_offset += dc_->ISP_BACKGND_T.tag_offset * vertex_size;
vram_offset += dc_.ISP_BACKGND_T.tag_offset * vertex_size;
// copy vertex data to context
for (int i = 0, bg_offset = 0; i < 3; i++) {

View File

@ -52,7 +52,7 @@ class TileAccelerator : public Device,
static int GetPolyType(const PCW &pcw);
static int GetVertexType(const PCW &pcw);
TileAccelerator(Dreamcast *dc, renderer::Backend *rb);
TileAccelerator(Dreamcast &dc, renderer::Backend &rb);
bool Init() final;
@ -86,8 +86,8 @@ class TileAccelerator : public Device,
void ToggleTracing();
Dreamcast *dc_;
renderer::Backend *rb_;
Dreamcast &dc_;
renderer::Backend &rb_;
TileRenderer tile_renderer_;
Memory *memory_;
Holly *holly_;

View File

@ -11,8 +11,8 @@ using namespace re::hw::maple;
using namespace re::hw::sh4;
using namespace re::ui;
Maple::Maple(Dreamcast *dc)
: Device(*dc),
Maple::Maple(Dreamcast &dc)
: Device(dc),
WindowInterface(this),
dc_(dc),
memory_(nullptr),
@ -24,9 +24,9 @@ Maple::Maple(Dreamcast *dc)
}
bool Maple::Init() {
memory_ = dc_->memory;
holly_ = dc_->holly;
holly_regs_ = dc_->holly_regs;
memory_ = dc_.memory;
holly_ = dc_.holly;
holly_regs_ = dc_.holly_regs;
return true;
}
@ -35,8 +35,8 @@ bool Maple::Init() {
// in synchronization with the V-BLANK signal. These methods are selected
// through the trigger selection register (SB_MDTSEL).
void Maple::VBlank() {
uint32_t enabled = dc_->SB_MDEN;
uint32_t vblank_initiate = dc_->SB_MDTSEL;
uint32_t enabled = dc_.SB_MDEN;
uint32_t vblank_initiate = dc_.SB_MDTSEL;
if (enabled && vblank_initiate) {
StartDMA();
@ -89,7 +89,7 @@ void Maple::WriteRegister(uint32_t addr, T value) {
switch (offset) {
case SB_MDST_OFFSET: {
uint32_t enabled = dc_->SB_MDEN;
uint32_t enabled = dc_.SB_MDEN;
if (enabled) {
if (value) {
StartDMA();
@ -102,7 +102,7 @@ void Maple::WriteRegister(uint32_t addr, T value) {
}
void Maple::StartDMA() {
uint32_t start_addr = dc_->SB_MDSTAR;
uint32_t start_addr = dc_.SB_MDSTAR;
MapleTransferDesc desc;
MapleFrame frame, res;
@ -135,6 +135,6 @@ void Maple::StartDMA() {
}
} while (!desc.last);
dc_->SB_MDST = 0;
dc_.SB_MDST = 0;
holly_->RequestInterrupt(HOLLY_INTC_MDEINT);
}

View File

@ -104,7 +104,7 @@ class Maple : public Device, public WindowInterface {
friend class holly::Holly;
public:
Maple(Dreamcast *dc);
Maple(Dreamcast &dc);
bool Init() final;
@ -122,7 +122,7 @@ class Maple : public Device, public WindowInterface {
bool HandleFrame(const MapleFrame &frame, MapleFrame &res);
void StartDMA();
Dreamcast *dc_;
Dreamcast &dc_;
Memory *memory_;
holly::Holly *holly_;
Register *holly_regs_;

View File

@ -29,8 +29,8 @@ enum {
SH4_CLOCK_FREQ = 200000000,
};
SH4::SH4(Dreamcast *dc)
: Device(*dc),
SH4::SH4(Dreamcast &dc)
: Device(dc),
DebugInterface(this),
ExecuteInterface(this),
MemoryInterface(this),
@ -54,8 +54,8 @@ SH4::SH4(Dreamcast *dc)
SH4::~SH4() { delete code_cache_; }
bool SH4::Init() {
memory_ = dc_->memory;
scheduler_ = dc_->scheduler;
memory_ = dc_.memory;
scheduler_ = dc_.scheduler;
code_cache_ = new SH4CodeCache(memory_, &ctx_, &SH4::CompilePC);
@ -176,7 +176,7 @@ void SH4::Step() {
block->run();
// let the debugger know we've stopped
dc_->debugger->Trap();
dc_.debugger->Trap();
}
void SH4::AddBreakpoint(int type, uint32_t addr) {
@ -367,7 +367,7 @@ void SH4::InvalidInstruction(SH4Context *ctx, uint64_t data) {
self->ctx_.num_cycles = 0;
// let the debugger know execution has stopped
self->dc_->debugger->Trap();
self->dc_.debugger->Trap();
}
void SH4::Prefetch(SH4Context *ctx, uint64_t data) {

View File

@ -32,7 +32,7 @@ class SH4 : public Device,
friend void RunSH4Test(const SH4Test &);
public:
SH4(Dreamcast *dc);
SH4(Dreamcast &dc);
~SH4();
bool Init() final;
@ -108,7 +108,7 @@ class SH4 : public Device,
template <int N>
void ExpireTimer();
Dreamcast *dc_;
Dreamcast &dc_;
Memory *memory_;
Scheduler *scheduler_;
SH4CodeCache *code_cache_;

View File

@ -39,12 +39,7 @@ bool InterpreterEmitter::Emit(ir::IRBuilder &builder, void *guest_ctx,
}
// assign local offsets
*locals_size = 0;
for (auto local : builder.locals()) {
int type_size = SizeForType(local->type());
local->set_offset(builder.AllocConstant(*locals_size));
*locals_size += type_size;
}
*locals_size = builder.locals_size();
// translate each instruction
*instr = reinterpret_cast<IntInstr *>(codegen_);

View File

@ -115,15 +115,7 @@ BlockPointer X64Emitter::Emit(IRBuilder &builder, Memory &memory,
}
void X64Emitter::EmitProlog(IRBuilder &builder, int *out_stack_size) {
int stack_size = STACK_SIZE;
// align locals
for (auto local : builder.locals()) {
int type_size = SizeForType(local->type());
stack_size = re::align_up(stack_size, type_size);
local->set_offset(builder.AllocConstant(stack_size));
stack_size += type_size;
}
int stack_size = STACK_SIZE + builder.locals_size();
// stack must be 16 byte aligned
stack_size = re::align_up(stack_size, 16);

View File

@ -1,4 +1,5 @@
#include <sstream>
#include "core/math.h"
#include "core/memory.h"
#include "jit/ir/ir_builder.h"
#include "jit/ir/ir_writer.h"
@ -80,7 +81,8 @@ Instr::~Instr() {}
//
// IRBuilder
//
IRBuilder::IRBuilder() : arena_(1024), current_instr_(nullptr) {}
IRBuilder::IRBuilder()
: arena_(1024), current_instr_(nullptr), locals_size_(0) {}
void IRBuilder::Dump() const {
IRWriter writer;
@ -522,16 +524,17 @@ Value *IRBuilder::AllocConstant(double c) {
return v;
}
Value *IRBuilder::AllocDynamic(ValueType type) {
Value *v = arena_.Alloc<Value>();
new (v) Value(type);
return v;
}
Local *IRBuilder::AllocLocal(ValueType type) {
// align local to natural size
int type_size = SizeForType(type);
locals_size_ = re::align_up(locals_size_, type_size);
Local *l = arena_.Alloc<Local>();
new (l) Local(type, AllocConstant(0));
new (l) Local(type, AllocConstant(locals_size_));
locals_.Append(l);
locals_size_ += type_size;
return l;
}

View File

@ -238,14 +238,7 @@ class Local : public IntrusiveListNode<Local> {
Local(ValueType ty, Value *offset);
ValueType type() const { return type_; }
ValueType type() { return type_; }
Value *offset() const { return offset_; }
Value *offset() { return offset_; }
void set_offset(Value *offset) {
offset_->ReplaceRefsWith(offset);
offset_ = offset;
}
private:
ValueType type_;
@ -314,8 +307,7 @@ class IRBuilder {
const IntrusiveList<Instr> &instrs() const { return instrs_; }
IntrusiveList<Instr> &instrs() { return instrs_; }
const IntrusiveList<Local> &locals() const { return locals_; }
IntrusiveList<Local> &locals() { return locals_; }
int locals_size() const { return locals_size_; }
void Dump() const;
@ -398,7 +390,6 @@ class IRBuilder {
Value *AllocConstant(int64_t c);
Value *AllocConstant(float c);
Value *AllocConstant(double c);
Value *AllocDynamic(ValueType type);
Local *AllocLocal(ValueType type);
protected:
@ -408,8 +399,9 @@ class IRBuilder {
Arena arena_;
IntrusiveList<Instr> instrs_;
IntrusiveList<Local> locals_;
Instr *current_instr_;
IntrusiveList<Local> locals_;
int locals_size_;
};
inline const Instr *Value::def() const {

View File

@ -193,11 +193,7 @@ bool IRReader::ParseValue(IRLexer &lex, IRBuilder &builder, Value **value) {
int slot = atoi(&ident[1]);
auto it = slots_.find(slot);
if (it == slots_.end()) {
auto res =
slots_.insert(std::make_pair(slot, builder.AllocDynamic(type)));
it = res.first;
}
CHECK_NE(it, slots_.end());
*value = it->second;
} else if (lex.tok() == TOK_INTEGER) {

View File

@ -17,7 +17,7 @@ ImGuiImpl::~ImGuiImpl() {
bool ImGuiImpl::Init() {
ImGuiIO &io = ImGui::GetIO();
Backend *rb = window_.render_backend();
Backend &rb = window_.render_backend();
// don't really care if this is accurate
io.DeltaTime = 1.0f / 60.0f;
@ -57,8 +57,8 @@ bool ImGuiImpl::Init() {
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
TextureHandle handle =
rb->RegisterTexture(PXL_RGBA, FILTER_BILINEAR, WRAP_REPEAT, WRAP_REPEAT,
false, width, height, pixels);
rb.RegisterTexture(PXL_RGBA, FILTER_BILINEAR, WRAP_REPEAT, WRAP_REPEAT,
false, width, height, pixels);
io.Fonts->TexID = reinterpret_cast<void *>(static_cast<intptr_t>(handle));
@ -81,7 +81,7 @@ void ImGuiImpl::OnPrePaint() {
void ImGuiImpl::OnPostPaint() {
ImGuiIO &io = ImGui::GetIO();
Backend *rb = window_.render_backend();
Backend &rb = window_.render_backend();
// if there are any focused items, enable text input
window_.EnableTextInput(ImGui::IsAnyItemActive());
@ -93,7 +93,7 @@ void ImGuiImpl::OnPostPaint() {
// get the latest draw batches, and pass them off out the render backend
ImDrawData *data = ImGui::GetDrawData();
rb->Begin2D();
rb.Begin2D();
for (int i = 0; i < data->CmdListsCount; ++i) {
const auto cmd_list = data->CmdLists[i];
@ -104,7 +104,7 @@ void ImGuiImpl::OnPostPaint() {
uint16_t *indices = cmd_list->IdxBuffer.Data;
int num_indices = cmd_list->IdxBuffer.size();
rb->BeginSurfaces2D(verts, num_verts, indices, num_indices);
rb.BeginSurfaces2D(verts, num_verts, indices, num_indices);
int index_offset = 0;
@ -125,15 +125,15 @@ void ImGuiImpl::OnPostPaint() {
surf.first_vert = index_offset;
surf.num_verts = cmd.ElemCount;
rb->DrawSurface2D(surf);
rb.DrawSurface2D(surf);
index_offset += cmd.ElemCount;
}
rb->EndSurfaces2D();
rb.EndSurfaces2D();
}
rb->End2D();
rb.End2D();
}
void ImGuiImpl::OnTextInput(const char *text) {

View File

@ -1598,7 +1598,7 @@ MicroProfileImpl::MicroProfileImpl(Window &window)
MicroProfileImpl::~MicroProfileImpl() { window_.RemoveListener(this); }
bool MicroProfileImpl::Init() {
Backend *rb = window_.render_backend();
Backend &rb = window_.render_backend();
// register and enable gpu and runtime group by default
uint16_t gpu_group = MicroProfileGetGroup("gpu", MicroProfileTokenTypeCpu);
@ -1612,7 +1612,7 @@ bool MicroProfileImpl::Init() {
g_MicroProfile.nBars |= MP_DRAW_TIMERS | MP_DRAW_AVERAGE | MP_DRAW_CALL_COUNT;
// register the font texture
font_tex_ = rb->RegisterTexture(
font_tex_ = rb.RegisterTexture(
PXL_RGBA, FILTER_NEAREST, WRAP_CLAMP_TO_EDGE, WRAP_CLAMP_TO_EDGE, false,
FONT_WIDTH, FONT_HEIGHT, reinterpret_cast<const uint8_t *>(s_font_data));
@ -1627,18 +1627,18 @@ void MicroProfileImpl::OnPostPaint() {
MicroProfileDraw(window_.width(), window_.height());
// render the surfaces
Backend *rb = window_.render_backend();
Backend &rb = window_.render_backend();
rb->Begin2D();
rb->BeginSurfaces2D(verts_, num_verts_, nullptr, 0);
rb.Begin2D();
rb.BeginSurfaces2D(verts_, num_verts_, nullptr, 0);
for (int i = 0; i < num_surfs_; i++) {
Surface2D &surf = surfs_[i];
rb->DrawSurface2D(surf);
rb.DrawSurface2D(surf);
}
rb->EndSurfaces2D();
rb->End2D();
rb.EndSurfaces2D();
rb.End2D();
// reset surfaces
num_surfs_ = 0;

View File

@ -20,7 +20,7 @@ enum {
class Window {
public:
SDL_Window *handle() { return window_; }
renderer::Backend *render_backend() { return rb_; }
renderer::Backend &render_backend() { return *rb_; }
int width() { return width_; }
int height() { return height_; }

View File

@ -155,7 +155,7 @@ void RunSH4Test(const SH4Test &test) {
// perhaps initialize the machine once, resetting the SH4 context between
// runs?
std::unique_ptr<Dreamcast> dc(new Dreamcast());
std::unique_ptr<SH4> sh4(new SH4(dc.get()));
std::unique_ptr<SH4> sh4(new SH4(*dc.get()));
CHECK(dc->Init());