mirror of https://github.com/inolen/redream.git
split up Dreamcast object into hw::Dreamcast and emu::Emulator
This commit is contained in:
parent
e83cad251a
commit
0bcc30559b
|
@ -106,7 +106,7 @@ set(DREAVM_SOURCES
|
|||
src/core/assert.cc
|
||||
src/core/filesystem.cc
|
||||
src/core/log.cc
|
||||
src/emu/dreamcast.cc
|
||||
src/emu/emulator.cc
|
||||
src/emu/profiler.cc
|
||||
src/hw/aica/aica.cc
|
||||
src/hw/gdrom/disc.cc
|
||||
|
@ -118,6 +118,7 @@ set(DREAVM_SOURCES
|
|||
src/hw/maple/maple.cc
|
||||
src/hw/maple/maple_controller.cc
|
||||
src/hw/sh4/sh4.cc
|
||||
src/hw/dreamcast.cc
|
||||
src/hw/scheduler.cc
|
||||
src/jit/backend/interpreter/interpreter_backend.cc
|
||||
src/jit/backend/interpreter/interpreter_block.cc
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
#include "core/core.h"
|
||||
#include "emu/emulator.h"
|
||||
#include "emu/profiler.h"
|
||||
#include "renderer/gl_backend.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::gdrom;
|
||||
using namespace dreavm::renderer;
|
||||
using namespace dreavm::system;
|
||||
using namespace dreavm::trace;
|
||||
|
||||
DEFINE_string(bios, "dc_bios.bin", "Path to BIOS");
|
||||
DEFINE_string(flash, "dc_flash.bin", "Path to flash ROM");
|
||||
|
||||
Emulator::Emulator() : trace_writer_(nullptr) {
|
||||
rb_ = new GLBackend(sys_);
|
||||
dc_.set_rb(rb_);
|
||||
}
|
||||
|
||||
Emulator::~Emulator() {
|
||||
delete rb_;
|
||||
delete trace_writer_;
|
||||
}
|
||||
|
||||
void Emulator::Run(const char *path) {
|
||||
Profiler::Init();
|
||||
|
||||
if (!sys_.Init()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rb_->Init()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dc_.Init()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LoadBios(FLAGS_bios.c_str())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LoadFlash(FLAGS_flash.c_str())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (path) {
|
||||
LOG_INFO("Launching %s", path);
|
||||
|
||||
if ((strstr(path, ".bin") && !LaunchBIN(path)) ||
|
||||
(strstr(path, ".gdi") && !LaunchGDI(path))) {
|
||||
LOG_WARNING("Failed to launch %s", path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static const std::chrono::nanoseconds step = HZ_TO_NANO(60);
|
||||
std::chrono::nanoseconds time_remaining = std::chrono::nanoseconds(0);
|
||||
auto current_time = std::chrono::high_resolution_clock::now();
|
||||
auto last_time = current_time;
|
||||
|
||||
while (true) {
|
||||
current_time = std::chrono::high_resolution_clock::now();
|
||||
time_remaining += current_time - last_time;
|
||||
last_time = current_time;
|
||||
|
||||
if (time_remaining < step) {
|
||||
continue;
|
||||
}
|
||||
|
||||
time_remaining -= step;
|
||||
|
||||
PumpEvents();
|
||||
|
||||
dc_.scheduler()->Tick(step);
|
||||
|
||||
RenderFrame();
|
||||
}
|
||||
}
|
||||
|
||||
bool Emulator::LoadBios(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
LOG_WARNING("Failed to open bios at \"%s\"", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (size != BIOS_SIZE) {
|
||||
LOG_WARNING("Bios size mismatch, is %d, expected %d", size, BIOS_SIZE);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = static_cast<int>(fread(dc_.bios(), sizeof(uint8_t), size, fp));
|
||||
fclose(fp);
|
||||
|
||||
if (n != size) {
|
||||
LOG_WARNING("Bios read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Emulator::LoadFlash(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
LOG_WARNING("Failed to open flash at \"%s\"", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (size != FLASH_SIZE) {
|
||||
LOG_WARNING("Flash size mismatch, is %d, expected %d", size, FLASH_SIZE);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = static_cast<int>(fread(dc_.flash(), sizeof(uint8_t), size, fp));
|
||||
fclose(fp);
|
||||
|
||||
if (n != size) {
|
||||
LOG_WARNING("Flash read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Emulator::LaunchBIN(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
uint8_t *data = reinterpret_cast<uint8_t *>(malloc(size));
|
||||
int n = static_cast<int>(fread(data, sizeof(uint8_t), size, fp));
|
||||
fclose(fp);
|
||||
|
||||
if (n != size) {
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
// load to 0x0c010000 (area 3) which is where 1ST_READ.BIN is normally
|
||||
// loaded to
|
||||
dc_.memory()->Memcpy(0x0c010000, data, size);
|
||||
free(data);
|
||||
|
||||
dc_.sh4()->SetPC(0x0c010000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Emulator::LaunchGDI(const char *path) {
|
||||
std::unique_ptr<GDI> gdi(new GDI());
|
||||
|
||||
if (!gdi->Load(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dc_.gdrom()->SetDisc(std::move(gdi));
|
||||
dc_.sh4()->SetPC(0xa0000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Emulator::PumpEvents() {
|
||||
SystemEvent ev;
|
||||
|
||||
sys_.PumpEvents();
|
||||
|
||||
while (sys_.PollEvent(&ev)) {
|
||||
switch (ev.type) {
|
||||
case SE_KEY: {
|
||||
// let the profiler take a stab at the input first
|
||||
if (!Profiler::HandleInput(ev.key.code, ev.key.value)) {
|
||||
// debug tracing
|
||||
if (ev.key.code == K_F2) {
|
||||
if (ev.key.value) {
|
||||
ToggleTracing();
|
||||
}
|
||||
}
|
||||
// else, forward to maple
|
||||
else {
|
||||
dc_.maple()->HandleInput(0, ev.key.code, ev.key.value);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case SE_MOUSEMOVE: {
|
||||
Profiler::HandleMouseMove(ev.mousemove.x, ev.mousemove.y);
|
||||
} break;
|
||||
|
||||
case SE_RESIZE: {
|
||||
rb_->ResizeVideo(ev.resize.width, ev.resize.height);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::ToggleTracing() {
|
||||
if (!trace_writer_) {
|
||||
char filename[PATH_MAX];
|
||||
GetNextTraceFilename(filename, sizeof(filename));
|
||||
|
||||
trace_writer_ = new TraceWriter();
|
||||
|
||||
if (!trace_writer_->Open(filename)) {
|
||||
delete trace_writer_;
|
||||
trace_writer_ = nullptr;
|
||||
|
||||
LOG_INFO("Failed to start tracing");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO("Begin tracing to %s", filename);
|
||||
} else {
|
||||
delete trace_writer_;
|
||||
trace_writer_ = nullptr;
|
||||
|
||||
LOG_INFO("End tracing");
|
||||
}
|
||||
|
||||
dc_.set_trace_writer(trace_writer_);
|
||||
}
|
||||
|
||||
void Emulator::RenderFrame() {
|
||||
rb_->BeginFrame();
|
||||
|
||||
dc_.ta()->RenderLastContext();
|
||||
|
||||
// render stats
|
||||
char stats[512];
|
||||
snprintf(stats, sizeof(stats), "%.2f fps, %.2f vbps", dc_.pvr()->fps(),
|
||||
dc_.pvr()->vbps());
|
||||
rb_->RenderText2D(0, 0, 12.0f, 0xffffffff, stats);
|
||||
|
||||
// render profiler
|
||||
Profiler::Render(rb_);
|
||||
|
||||
rb_->EndFrame();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef EMULATOR_H
|
||||
#define EMULATOR_H
|
||||
|
||||
#include "hw/dreamcast.h"
|
||||
#include "renderer/backend.h"
|
||||
#include "system/system.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
|
||||
class Emulator {
|
||||
public:
|
||||
Emulator();
|
||||
~Emulator();
|
||||
|
||||
void Run(const char *path);
|
||||
|
||||
private:
|
||||
bool LoadBios(const char *path);
|
||||
bool LoadFlash(const char *path);
|
||||
bool LaunchBIN(const char *path);
|
||||
bool LaunchGDI(const char *path);
|
||||
|
||||
void PumpEvents();
|
||||
void ToggleTracing();
|
||||
void RenderFrame();
|
||||
|
||||
system::System sys_;
|
||||
hw::Dreamcast dc_;
|
||||
renderer::Backend *rb_;
|
||||
trace::TraceWriter *trace_writer_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,15 +1,17 @@
|
|||
#include "emu/dreamcast.h"
|
||||
#include "hw/aica/aica.h"
|
||||
#include "hw/dreamcast.h"
|
||||
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::aica;
|
||||
using namespace dreavm::hw::holly;
|
||||
|
||||
AICA::AICA(Dreamcast *dc) : dc_(dc) {}
|
||||
|
||||
void AICA::Init() {
|
||||
bool AICA::Init() {
|
||||
aica_regs_ = dc_->aica_regs();
|
||||
wave_ram_ = dc_->wave_ram();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t AICA::Execute(uint32_t cycles) {
|
||||
|
|
|
@ -5,20 +5,18 @@
|
|||
#include "hw/device.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
class Dreamcast;
|
||||
}
|
||||
|
||||
namespace hw {
|
||||
class Dreamcast;
|
||||
|
||||
namespace aica {
|
||||
|
||||
class AICA : public hw::Device {
|
||||
public:
|
||||
AICA(emu::Dreamcast *dc);
|
||||
AICA(hw::Dreamcast *dc);
|
||||
|
||||
uint32_t GetClockFrequency() { return 22579200; }
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
uint32_t Execute(uint32_t cycles);
|
||||
|
||||
uint32_t ReadRegister32(uint32_t addr);
|
||||
|
@ -28,7 +26,7 @@ class AICA : public hw::Device {
|
|||
void WriteWave32(uint32_t addr, uint32_t value);
|
||||
|
||||
private:
|
||||
emu::Dreamcast *dc_;
|
||||
hw::Dreamcast *dc_;
|
||||
uint8_t *aica_regs_;
|
||||
uint8_t *wave_ram_;
|
||||
};
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#include "core/core.h"
|
||||
#include "hw/dreamcast.h"
|
||||
#include "jit/backend/interpreter/interpreter_backend.h"
|
||||
#include "jit/backend/x64/x64_backend.h"
|
||||
#include "jit/frontend/sh4/sh4_frontend.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "emu/profiler.h"
|
||||
#include "hw/maple/maple_controller.h"
|
||||
#include "renderer/gl_backend.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::aica;
|
||||
using namespace dreavm::hw::gdrom;
|
||||
|
@ -20,118 +16,127 @@ using namespace dreavm::jit::backend::interpreter;
|
|||
using namespace dreavm::jit::backend::x64;
|
||||
using namespace dreavm::jit::frontend::sh4;
|
||||
using namespace dreavm::renderer;
|
||||
using namespace dreavm::system;
|
||||
using namespace dreavm::trace;
|
||||
|
||||
DEFINE_string(bios, "dc_bios.bin", "Path to BIOS");
|
||||
DEFINE_string(flash, "dc_flash.bin", "Path to flash ROM");
|
||||
Dreamcast::Dreamcast()
|
||||
: // allocate registers and initialize references
|
||||
holly_regs_(new Register[HOLLY_REG_SIZE >> 2]),
|
||||
#define HOLLY_REG(offset, name, flags, default, type) \
|
||||
name{reinterpret_cast<type &>(holly_regs_[name##_OFFSET].value)},
|
||||
#include "hw/holly/holly_regs.inc"
|
||||
#undef HOLLY_REG
|
||||
pvr_regs_(new Register[PVR_REG_SIZE >> 2]),
|
||||
#define PVR_REG(offset, name, flags, default, type) \
|
||||
name{reinterpret_cast<type &>(pvr_regs_[name##_OFFSET].value)},
|
||||
#include "hw/holly/pvr2_regs.inc"
|
||||
#undef PVR_REG
|
||||
rb_(nullptr),
|
||||
trace_writer_(nullptr) {
|
||||
// initialize register values
|
||||
#define HOLLY_REG(addr, name, flags, default, type) \
|
||||
holly_regs_[name##_OFFSET] = {flags, default};
|
||||
#include "hw/holly/holly_regs.inc"
|
||||
#undef HOLLY_REG
|
||||
|
||||
Dreamcast::Dreamcast() {
|
||||
scheduler_ = std::unique_ptr<Scheduler>(new Scheduler());
|
||||
memory_ = std::unique_ptr<Memory>(new Memory());
|
||||
rb_ = std::unique_ptr<renderer::Backend>(new GLBackend(sys_));
|
||||
rt_frontend_ =
|
||||
std::unique_ptr<frontend::Frontend>(new SH4Frontend(*memory()));
|
||||
rt_backend_ = std::unique_ptr<backend::Backend>(new X64Backend(*memory()));
|
||||
runtime_ = std::unique_ptr<Runtime>(
|
||||
new Runtime(*memory(), *rt_frontend_.get(), *rt_backend_.get()));
|
||||
sh4_ = std::unique_ptr<SH4>(new SH4(*memory(), *runtime()));
|
||||
aica_ = std::unique_ptr<AICA>(new AICA(this));
|
||||
holly_ = std::unique_ptr<Holly>(new Holly(this));
|
||||
pvr_ = std::unique_ptr<PVR2>(new PVR2(this));
|
||||
ta_ = std::unique_ptr<TileAccelerator>(new TileAccelerator(this));
|
||||
gdrom_ = std::unique_ptr<GDROM>(new GDROM(this));
|
||||
maple_ = std::unique_ptr<Maple>(new Maple(this));
|
||||
#define PVR_REG(addr, name, flags, default, type) \
|
||||
pvr_regs_[name##_OFFSET] = {flags, default};
|
||||
#include "hw/holly/pvr2_regs.inc"
|
||||
#undef PVR_REG
|
||||
|
||||
bios_ = new uint8_t[BIOS_SIZE]();
|
||||
flash_ = new uint8_t[FLASH_SIZE]();
|
||||
ram_ = new uint8_t[MAIN_RAM_SIZE]();
|
||||
unassigned_ = new uint8_t[UNASSIGNED_SIZE]();
|
||||
modem_mem_ = new uint8_t[MODEM_REG_SIZE]();
|
||||
aica_regs_ = new uint8_t[AICA_REG_SIZE]();
|
||||
wave_ram_ = new uint8_t[WAVE_RAM_SIZE]();
|
||||
expdev_mem_ = new uint8_t[EXPDEV_SIZE]();
|
||||
video_ram_ = new uint8_t[PVR_VRAM32_SIZE]();
|
||||
palette_ram_ = new uint8_t[PVR_PALETTE_SIZE]();
|
||||
|
||||
scheduler_ = new Scheduler();
|
||||
memory_ = new Memory();
|
||||
rt_frontend_ = new SH4Frontend(*memory_);
|
||||
rt_backend_ = new X64Backend(*memory_);
|
||||
runtime_ = new Runtime(*memory_, *rt_frontend_, *rt_backend_);
|
||||
aica_ = new AICA(this);
|
||||
gdrom_ = new GDROM(this);
|
||||
holly_ = new Holly(this);
|
||||
maple_ = new Maple(this);
|
||||
pvr_ = new PVR2(this);
|
||||
sh4_ = new SH4(*memory_, *runtime_);
|
||||
ta_ = new TileAccelerator(this);
|
||||
}
|
||||
|
||||
void Dreamcast::Run(const char *path) {
|
||||
if (!Init()) {
|
||||
LOG_WARNING("Failed to initialize emulator");
|
||||
return;
|
||||
}
|
||||
Dreamcast::~Dreamcast() {
|
||||
delete[] holly_regs_;
|
||||
delete[] pvr_regs_;
|
||||
|
||||
if (!LoadBios(FLAGS_bios.c_str())) {
|
||||
return;
|
||||
}
|
||||
delete bios_;
|
||||
delete flash_;
|
||||
delete ram_;
|
||||
delete unassigned_;
|
||||
delete modem_mem_;
|
||||
delete aica_regs_;
|
||||
delete wave_ram_;
|
||||
delete expdev_mem_;
|
||||
delete video_ram_;
|
||||
delete palette_ram_;
|
||||
|
||||
if (!LoadFlash(FLAGS_flash.c_str())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (path) {
|
||||
LOG_INFO("Launching %s", path);
|
||||
|
||||
if ((strstr(path, ".bin") && !LaunchBIN(path)) ||
|
||||
(strstr(path, ".gdi") && !LaunchGDI(path))) {
|
||||
LOG_WARNING("Failed to launch %s", path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static const std::chrono::nanoseconds step = HZ_TO_NANO(60);
|
||||
std::chrono::nanoseconds time_remaining = std::chrono::nanoseconds(0);
|
||||
auto current_time = std::chrono::high_resolution_clock::now();
|
||||
auto last_time = current_time;
|
||||
|
||||
while (true) {
|
||||
current_time = std::chrono::high_resolution_clock::now();
|
||||
time_remaining += current_time - last_time;
|
||||
last_time = current_time;
|
||||
|
||||
if (time_remaining < step) {
|
||||
continue;
|
||||
}
|
||||
|
||||
time_remaining -= step;
|
||||
|
||||
PumpEvents();
|
||||
|
||||
scheduler_->Tick(step);
|
||||
|
||||
RenderFrame();
|
||||
}
|
||||
delete scheduler_;
|
||||
delete memory_;
|
||||
delete rt_frontend_;
|
||||
delete rt_backend_;
|
||||
delete runtime_;
|
||||
delete aica_;
|
||||
delete gdrom_;
|
||||
delete holly_;
|
||||
delete maple_;
|
||||
delete pvr_;
|
||||
delete sh4_;
|
||||
delete ta_;
|
||||
}
|
||||
|
||||
bool Dreamcast::Init() {
|
||||
if (!sys_.Init()) {
|
||||
MapMemory();
|
||||
|
||||
if (!aica_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rb_->Init()) {
|
||||
if (!gdrom_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Profiler::Init();
|
||||
if (!holly_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InitMemory();
|
||||
InitRegisters();
|
||||
if (!maple_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sh4_->Init();
|
||||
aica_->Init();
|
||||
holly_->Init();
|
||||
pvr_->Init();
|
||||
ta_->Init();
|
||||
gdrom_->Init();
|
||||
maple_->Init();
|
||||
if (!pvr_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scheduler_->AddDevice(sh4());
|
||||
scheduler_->AddDevice(aica());
|
||||
if (!sh4_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ta_->Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scheduler_->AddDevice(aica_);
|
||||
scheduler_->AddDevice(sh4_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dreamcast::InitMemory() {
|
||||
void Dreamcast::MapMemory() {
|
||||
using namespace std::placeholders;
|
||||
|
||||
memset(ram_, 0, sizeof(ram_));
|
||||
memset(unassigned_, 0, sizeof(unassigned_));
|
||||
memset(modem_mem_, 0, sizeof(modem_mem_));
|
||||
memset(aica_regs_, 0, sizeof(aica_regs_));
|
||||
memset(wave_ram_, 0, sizeof(wave_ram_));
|
||||
memset(expdev_mem_, 0, sizeof(expdev_mem_));
|
||||
memset(video_ram_, 0, sizeof(video_ram_));
|
||||
memset(palette_ram_, 0, sizeof(palette_ram_));
|
||||
|
||||
// main ram
|
||||
memory_->Mount(BIOS_START, BIOS_END, MIRROR_MASK, bios_);
|
||||
memory_->Mount(FLASH_START, FLASH_END, MIRROR_MASK, flash_);
|
||||
|
@ -265,187 +270,3 @@ void Dreamcast::InitMemory() {
|
|||
std::bind(&SH4::WriteSQ32, sh4(), _1, _2), //
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void Dreamcast::InitRegisters() {
|
||||
#define HOLLY_REG(addr, name, flags, default, type) \
|
||||
holly_regs_[name##_OFFSET] = {flags, default};
|
||||
#include "hw/holly/holly_regs.inc"
|
||||
#undef HOLLY_REG
|
||||
|
||||
#define PVR_REG(addr, name, flags, default, type) \
|
||||
pvr_regs_[name##_OFFSET] = {flags, default};
|
||||
#include "hw/holly/pvr2_regs.inc"
|
||||
#undef PVR_REG
|
||||
}
|
||||
|
||||
bool Dreamcast::LoadBios(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
LOG_WARNING("Failed to open bios at \"%s\"", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (size != BIOS_SIZE) {
|
||||
LOG_WARNING("Bios size mismatch, is %d, expected %d", size, BIOS_SIZE);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = static_cast<int>(fread(bios_, sizeof(uint8_t), size, fp));
|
||||
fclose(fp);
|
||||
|
||||
if (n != size) {
|
||||
LOG_WARNING("Bios read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Dreamcast::LoadFlash(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
LOG_WARNING("Failed to open flash at \"%s\"", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (size != FLASH_SIZE) {
|
||||
LOG_WARNING("Flash size mismatch, is %d, expected %d", size, FLASH_SIZE);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = static_cast<int>(fread(flash_, sizeof(uint8_t), size, fp));
|
||||
fclose(fp);
|
||||
|
||||
if (n != size) {
|
||||
LOG_WARNING("Flash read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Dreamcast::LaunchBIN(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
uint8_t *data = reinterpret_cast<uint8_t *>(malloc(size));
|
||||
int n = static_cast<int>(fread(data, sizeof(uint8_t), size, fp));
|
||||
fclose(fp);
|
||||
|
||||
if (n != size) {
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
// load to 0x0c010000 (area 3) which is where 1ST_READ.BIN is normally
|
||||
// loaded to
|
||||
memory_->Memcpy(0x0c010000, data, size);
|
||||
free(data);
|
||||
|
||||
sh4_->SetPC(0x0c010000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Dreamcast::LaunchGDI(const char *path) {
|
||||
std::unique_ptr<GDI> gdi(new GDI());
|
||||
|
||||
if (!gdi->Load(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gdrom_->SetDisc(std::move(gdi));
|
||||
sh4_->SetPC(0xa0000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dreamcast::PumpEvents() {
|
||||
SystemEvent ev;
|
||||
|
||||
sys_.PumpEvents();
|
||||
|
||||
while (sys_.PollEvent(&ev)) {
|
||||
switch (ev.type) {
|
||||
case SE_KEY: {
|
||||
// let the profiler take a stab at the input first
|
||||
if (!Profiler::HandleInput(ev.key.code, ev.key.value)) {
|
||||
// debug tracing
|
||||
if (ev.key.code == K_F2) {
|
||||
if (ev.key.value) {
|
||||
ToggleTracing();
|
||||
}
|
||||
}
|
||||
// else, forward to maple
|
||||
else {
|
||||
maple_->HandleInput(0, ev.key.code, ev.key.value);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case SE_MOUSEMOVE: {
|
||||
Profiler::HandleMouseMove(ev.mousemove.x, ev.mousemove.y);
|
||||
} break;
|
||||
|
||||
case SE_RESIZE: {
|
||||
rb_->ResizeVideo(ev.resize.width, ev.resize.height);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dreamcast::ToggleTracing() {
|
||||
if (!trace_writer_) {
|
||||
char filename[PATH_MAX];
|
||||
GetNextTraceFilename(filename, sizeof(filename));
|
||||
|
||||
trace_writer_ = std::unique_ptr<TraceWriter>(new TraceWriter());
|
||||
|
||||
if (!trace_writer_->Open(filename)) {
|
||||
trace_writer_ = nullptr;
|
||||
|
||||
LOG_INFO("Failed to start tracing");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO("Begin tracing to %s", filename);
|
||||
} else {
|
||||
trace_writer_ = nullptr;
|
||||
|
||||
LOG_INFO("End tracing");
|
||||
}
|
||||
}
|
||||
|
||||
void Dreamcast::RenderFrame() {
|
||||
rb_->BeginFrame();
|
||||
|
||||
ta_->RenderLastContext();
|
||||
|
||||
// render stats
|
||||
char stats[512];
|
||||
snprintf(stats, sizeof(stats), "%.2f fps, %.2f vbps", pvr_->fps(),
|
||||
pvr_->vbps());
|
||||
rb_->RenderText2D(0, 0, 12.0f, 0xffffffff, stats);
|
||||
|
||||
// render profiler
|
||||
Profiler::Render(rb());
|
||||
|
||||
rb_->EndFrame();
|
||||
}
|
|
@ -1,25 +1,23 @@
|
|||
#ifndef DREAMCAST_H
|
||||
#define DREAMCAST_H
|
||||
|
||||
#include <memory>
|
||||
#include "hw/aica/aica.h"
|
||||
#include "hw/sh4/sh4.h"
|
||||
#include "hw/gdrom/gdrom.h"
|
||||
#include "hw/holly/holly.h"
|
||||
#include "hw/holly/pvr2.h"
|
||||
#include "hw/holly/tile_accelerator.h"
|
||||
#include "hw/maple/maple.h"
|
||||
#include "hw/sh4/sh4.h"
|
||||
#include "hw/memory.h"
|
||||
#include "hw/scheduler.h"
|
||||
#include "jit/backend/backend.h"
|
||||
#include "jit/frontend/frontend.h"
|
||||
#include "jit/runtime.h"
|
||||
#include "renderer/backend.h"
|
||||
#include "system/system.h"
|
||||
#include "trace/trace.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
namespace hw {
|
||||
|
||||
//
|
||||
// memory layout
|
||||
|
@ -80,101 +78,103 @@ struct Register {
|
|||
|
||||
enum {
|
||||
#define AICA_REG(addr, name, flags, default, type) \
|
||||
name##_OFFSET = addr - emu::AICA_REG_START,
|
||||
name##_OFFSET = addr - hw::AICA_REG_START,
|
||||
#include "hw/aica/aica_regs.inc"
|
||||
#undef AICA_REG
|
||||
|
||||
#define HOLLY_REG(addr, name, flags, default, type) \
|
||||
name##_OFFSET = (addr - emu::HOLLY_REG_START) >> 2,
|
||||
name##_OFFSET = (addr - hw::HOLLY_REG_START) >> 2,
|
||||
#include "hw/holly/holly_regs.inc"
|
||||
#undef HOLLY_REG
|
||||
|
||||
#define PVR_REG(addr, name, flags, default_value, type) \
|
||||
name##_OFFSET = (addr - emu::PVR_REG_START) >> 2,
|
||||
name##_OFFSET = (addr - hw::PVR_REG_START) >> 2,
|
||||
#include "hw/holly/pvr2_regs.inc"
|
||||
#undef PVR_REG
|
||||
};
|
||||
|
||||
class Dreamcast {
|
||||
public:
|
||||
hw::Memory *memory() { return memory_.get(); }
|
||||
hw::Scheduler *scheduler() { return scheduler_.get(); }
|
||||
renderer::Backend *rb() { return rb_.get(); }
|
||||
jit::Runtime *runtime() { return runtime_.get(); }
|
||||
hw::aica::AICA *aica() { return aica_.get(); }
|
||||
hw::gdrom::GDROM *gdrom() { return gdrom_.get(); }
|
||||
hw::holly::Holly *holly() { return holly_.get(); }
|
||||
hw::holly::PVR2 *pvr() { return pvr_.get(); }
|
||||
hw::holly::TileAccelerator *ta() { return ta_.get(); }
|
||||
hw::maple::Maple *maple() { return maple_.get(); }
|
||||
hw::sh4::SH4 *sh4() { return sh4_.get(); }
|
||||
trace::TraceWriter *trace_writer() { return trace_writer_.get(); }
|
||||
|
||||
uint8_t *aica_regs() { return aica_regs_; }
|
||||
Register *holly_regs() { return holly_regs_; }
|
||||
Register *pvr_regs() { return pvr_regs_; }
|
||||
|
||||
uint8_t *bios() { return bios_; }
|
||||
uint8_t *flash() { return flash_; }
|
||||
uint8_t *wave_ram() { return wave_ram_; }
|
||||
uint8_t *palette_ram() { return palette_ram_; }
|
||||
uint8_t *video_ram() { return video_ram_; }
|
||||
|
||||
hw::Memory *memory() { return memory_; }
|
||||
hw::Scheduler *scheduler() { return scheduler_; }
|
||||
jit::Runtime *runtime() { return runtime_; }
|
||||
hw::aica::AICA *aica() { return aica_; }
|
||||
hw::gdrom::GDROM *gdrom() { return gdrom_; }
|
||||
hw::holly::Holly *holly() { return holly_; }
|
||||
hw::maple::Maple *maple() { return maple_; }
|
||||
hw::holly::PVR2 *pvr() { return pvr_; }
|
||||
hw::sh4::SH4 *sh4() { return sh4_; }
|
||||
hw::holly::TileAccelerator *ta() { return ta_; }
|
||||
|
||||
renderer::Backend *rb() { return rb_; }
|
||||
void set_rb(renderer::Backend *rb) { rb_ = rb; }
|
||||
|
||||
trace::TraceWriter *trace_writer() { return trace_writer_; }
|
||||
void set_trace_writer(trace::TraceWriter *trace_writer) {
|
||||
trace_writer_ = trace_writer;
|
||||
}
|
||||
|
||||
Dreamcast();
|
||||
~Dreamcast();
|
||||
|
||||
void Run(const char *path);
|
||||
bool Init();
|
||||
|
||||
#define HOLLY_REG(offset, name, flags, default, type) \
|
||||
type &name{reinterpret_cast<type &>(holly_regs_[name##_OFFSET].value)};
|
||||
private:
|
||||
Register *holly_regs_;
|
||||
|
||||
public:
|
||||
#define HOLLY_REG(offset, name, flags, default, type) type &name;
|
||||
#include "hw/holly/holly_regs.inc"
|
||||
#undef HOLLY_REG
|
||||
|
||||
#define PVR_REG(offset, name, flags, default, type) \
|
||||
type &name{reinterpret_cast<type &>(pvr_regs_[name##_OFFSET].value)};
|
||||
private:
|
||||
Register *pvr_regs_;
|
||||
|
||||
public:
|
||||
#define PVR_REG(offset, name, flags, default, type) type &name;
|
||||
#include "hw/holly/pvr2_regs.inc"
|
||||
#undef PVR_REG
|
||||
|
||||
private:
|
||||
bool Init();
|
||||
void InitMemory();
|
||||
void InitRegisters();
|
||||
void MapMemory();
|
||||
|
||||
bool LoadBios(const char *path);
|
||||
bool LoadFlash(const char *path);
|
||||
bool LaunchBIN(const char *path);
|
||||
bool LaunchGDI(const char *path);
|
||||
uint8_t *bios_;
|
||||
uint8_t *flash_;
|
||||
uint8_t *ram_;
|
||||
uint8_t *unassigned_;
|
||||
uint8_t *modem_mem_;
|
||||
uint8_t *aica_regs_;
|
||||
uint8_t *wave_ram_;
|
||||
uint8_t *expdev_mem_;
|
||||
uint8_t *video_ram_;
|
||||
uint8_t *palette_ram_;
|
||||
|
||||
void PumpEvents();
|
||||
void ToggleTracing();
|
||||
void RenderFrame();
|
||||
hw::Memory *memory_;
|
||||
hw::Scheduler *scheduler_;
|
||||
jit::frontend::Frontend *rt_frontend_;
|
||||
jit::backend::Backend *rt_backend_;
|
||||
jit::Runtime *runtime_;
|
||||
hw::aica::AICA *aica_;
|
||||
hw::gdrom::GDROM *gdrom_;
|
||||
hw::holly::Holly *holly_;
|
||||
hw::maple::Maple *maple_;
|
||||
hw::holly::PVR2 *pvr_;
|
||||
hw::sh4::SH4 *sh4_;
|
||||
hw::holly::TileAccelerator *ta_;
|
||||
|
||||
system::System sys_;
|
||||
std::unique_ptr<hw::Memory> memory_;
|
||||
std::unique_ptr<hw::Scheduler> scheduler_;
|
||||
std::unique_ptr<renderer::Backend> rb_;
|
||||
std::unique_ptr<jit::frontend::Frontend> rt_frontend_;
|
||||
std::unique_ptr<jit::backend::Backend> rt_backend_;
|
||||
std::unique_ptr<jit::Runtime> runtime_;
|
||||
std::unique_ptr<hw::aica::AICA> aica_;
|
||||
std::unique_ptr<hw::gdrom::GDROM> gdrom_;
|
||||
std::unique_ptr<hw::holly::Holly> holly_;
|
||||
std::unique_ptr<hw::holly::PVR2> pvr_;
|
||||
std::unique_ptr<hw::holly::TileAccelerator> ta_;
|
||||
std::unique_ptr<hw::maple::Maple> maple_;
|
||||
std::unique_ptr<hw::sh4::SH4> sh4_;
|
||||
std::unique_ptr<trace::TraceWriter> trace_writer_;
|
||||
|
||||
Register holly_regs_[HOLLY_REG_SIZE >> 2];
|
||||
Register pvr_regs_[PVR_REG_SIZE >> 2];
|
||||
|
||||
uint8_t bios_[BIOS_SIZE];
|
||||
uint8_t flash_[FLASH_SIZE];
|
||||
uint8_t ram_[MAIN_RAM_SIZE];
|
||||
uint8_t unassigned_[UNASSIGNED_SIZE];
|
||||
uint8_t modem_mem_[MODEM_REG_SIZE];
|
||||
uint8_t aica_regs_[AICA_REG_SIZE];
|
||||
uint8_t wave_ram_[WAVE_RAM_SIZE];
|
||||
uint8_t expdev_mem_[EXPDEV_SIZE];
|
||||
uint8_t video_ram_[PVR_VRAM32_SIZE];
|
||||
uint8_t palette_ram_[PVR_PALETTE_SIZE];
|
||||
// not owned by us
|
||||
renderer::Backend *rb_;
|
||||
trace::TraceWriter *trace_writer_;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
#include "core/core.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "hw/gdrom/gdrom_replies.inc"
|
||||
#include "hw/dreamcast.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::gdrom;
|
||||
using namespace dreavm::hw::holly;
|
||||
using namespace dreavm::hw::sh4;
|
||||
|
@ -28,12 +28,14 @@ GDROM::GDROM(Dreamcast *dc)
|
|||
|
||||
GDROM::~GDROM() { delete[] dma_buffer_; }
|
||||
|
||||
void GDROM::Init() {
|
||||
bool GDROM::Init() {
|
||||
memory_ = dc_->memory();
|
||||
holly_ = dc_->holly();
|
||||
holly_regs_ = dc_->holly_regs();
|
||||
|
||||
SetDisc(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GDROM::SetDisc(std::unique_ptr<Disc> disc) {
|
||||
|
|
|
@ -5,17 +5,14 @@
|
|||
#include "hw/gdrom/disc.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
class Dreamcast;
|
||||
struct Register;
|
||||
}
|
||||
|
||||
namespace hw {
|
||||
namespace holly {
|
||||
class Holly;
|
||||
}
|
||||
|
||||
class Dreamcast;
|
||||
class Memory;
|
||||
struct Register;
|
||||
|
||||
namespace gdrom {
|
||||
|
||||
|
@ -207,10 +204,10 @@ enum DataMask {
|
|||
|
||||
class GDROM {
|
||||
public:
|
||||
GDROM(emu::Dreamcast *dc);
|
||||
GDROM(hw::Dreamcast *dc);
|
||||
~GDROM();
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
|
||||
void SetDisc(std::unique_ptr<Disc> disc);
|
||||
|
||||
|
@ -234,10 +231,10 @@ class GDROM {
|
|||
int ReadSectors(int fad, SectorFormat format, DataMask mask, int num_sectors,
|
||||
uint8_t *dst);
|
||||
|
||||
emu::Dreamcast *dc_;
|
||||
hw::Dreamcast *dc_;
|
||||
hw::Memory *memory_;
|
||||
hw::holly::Holly *holly_;
|
||||
emu::Register *holly_regs_;
|
||||
hw::Register *holly_regs_;
|
||||
|
||||
GD_FEATURES_T features_;
|
||||
GD_INTREASON_T intreason_;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "core/core.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "hw/dreamcast.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::holly;
|
||||
using namespace dreavm::hw::sh4;
|
||||
using namespace dreavm::renderer;
|
||||
|
@ -10,9 +10,11 @@ using namespace dreavm::system;
|
|||
|
||||
Holly::Holly(Dreamcast *dc) : dc_(dc) {}
|
||||
|
||||
void Holly::Init() {
|
||||
bool Holly::Init() {
|
||||
sh4_ = dc_->sh4();
|
||||
holly_regs_ = dc_->holly_regs();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Holly::RequestInterrupt(HollyInterrupt intr) {
|
||||
|
|
|
@ -4,16 +4,14 @@
|
|||
#include <stdint.h>
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
class Dreamcast;
|
||||
struct Register;
|
||||
}
|
||||
|
||||
namespace hw {
|
||||
namespace sh4 {
|
||||
class SH4;
|
||||
}
|
||||
|
||||
class Dreamcast;
|
||||
struct Register;
|
||||
|
||||
namespace holly {
|
||||
|
||||
// interrupts
|
||||
|
@ -153,9 +151,9 @@ enum HollyInterrupt : uint64_t {
|
|||
|
||||
class Holly {
|
||||
public:
|
||||
Holly(emu::Dreamcast *dc);
|
||||
Holly(hw::Dreamcast *dc);
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
|
||||
void RequestInterrupt(HollyInterrupt intr);
|
||||
void UnrequestInterrupt(HollyInterrupt intr);
|
||||
|
@ -168,8 +166,8 @@ class Holly {
|
|||
void SortDMATransfer();
|
||||
void ForwardRequestInterrupts();
|
||||
|
||||
emu::Dreamcast *dc_;
|
||||
emu::Register *holly_regs_;
|
||||
hw::Dreamcast *dc_;
|
||||
hw::Register *holly_regs_;
|
||||
hw::sh4::SH4 *sh4_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "core/core.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "hw/dreamcast.h"
|
||||
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::holly;
|
||||
using namespace dreavm::hw::sh4;
|
||||
using namespace dreavm::renderer;
|
||||
|
@ -13,7 +13,7 @@ PVR2::PVR2(Dreamcast *dc)
|
|||
fps_(0),
|
||||
vbps_(0) {}
|
||||
|
||||
void PVR2::Init() {
|
||||
bool PVR2::Init() {
|
||||
scheduler_ = dc_->scheduler();
|
||||
holly_ = dc_->holly();
|
||||
ta_ = dc_->ta();
|
||||
|
@ -21,6 +21,8 @@ void PVR2::Init() {
|
|||
video_ram_ = dc_->video_ram();
|
||||
|
||||
ReconfigureSPG();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t PVR2::ReadRegister32(uint32_t addr) {
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
#include "hw/scheduler.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
class Dreamcast;
|
||||
}
|
||||
|
||||
namespace hw {
|
||||
class Dreamcast;
|
||||
|
||||
namespace holly {
|
||||
|
||||
class Holly;
|
||||
|
@ -198,12 +196,12 @@ union TA_ISP_BASE_T {
|
|||
|
||||
class PVR2 {
|
||||
public:
|
||||
PVR2(emu::Dreamcast *dc);
|
||||
PVR2(hw::Dreamcast *dc);
|
||||
|
||||
float fps() { return fps_; }
|
||||
float vbps() { return vbps_; }
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
|
||||
uint32_t ReadRegister32(uint32_t addr);
|
||||
void WriteRegister32(uint32_t addr, uint32_t value);
|
||||
|
@ -218,11 +216,11 @@ class PVR2 {
|
|||
void ReconfigureSPG();
|
||||
void LineClockUpdate();
|
||||
|
||||
emu::Dreamcast *dc_;
|
||||
hw::Dreamcast *dc_;
|
||||
hw::Scheduler *scheduler_;
|
||||
hw::holly::Holly *holly_;
|
||||
hw::holly::TileAccelerator *ta_;
|
||||
emu::Register *pvr_regs_;
|
||||
hw::Register *pvr_regs_;
|
||||
uint8_t *video_ram_;
|
||||
|
||||
hw::TimerHandle line_timer_;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "core/core.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "hw/holly/pixel_convert.h"
|
||||
#include "hw/dreamcast.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::holly;
|
||||
using namespace dreavm::renderer;
|
||||
using namespace dreavm::trace;
|
||||
|
@ -288,10 +288,12 @@ TileAccelerator::~TileAccelerator() {
|
|||
}
|
||||
}
|
||||
|
||||
void TileAccelerator::Init() {
|
||||
bool TileAccelerator::Init() {
|
||||
memory_ = dc_->memory();
|
||||
holly_ = dc_->holly();
|
||||
video_ram_ = dc_->video_ram();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TileAccelerator::SoftReset() {
|
||||
|
|
|
@ -7,15 +7,12 @@
|
|||
#include "renderer/backend.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
class Dreamcast;
|
||||
}
|
||||
|
||||
namespace trace {
|
||||
class TraceWriter;
|
||||
}
|
||||
|
||||
namespace hw {
|
||||
class Dreamcast;
|
||||
class Memory;
|
||||
|
||||
namespace holly {
|
||||
|
@ -479,7 +476,7 @@ struct TileContext {
|
|||
|
||||
class TileTextureCache : public TextureCache {
|
||||
public:
|
||||
TileTextureCache(emu::Dreamcast *dc);
|
||||
TileTextureCache(hw::Dreamcast *dc);
|
||||
|
||||
void Clear();
|
||||
// void RemoveTexture(uint32_t addr);
|
||||
|
@ -487,7 +484,7 @@ class TileTextureCache : public TextureCache {
|
|||
RegisterTextureCallback register_cb);
|
||||
|
||||
private:
|
||||
emu::Dreamcast *dc_;
|
||||
hw::Dreamcast *dc_;
|
||||
|
||||
trace::TraceWriter *trace_writer_;
|
||||
std::unordered_map<TextureKey, renderer::TextureHandle> textures_;
|
||||
|
@ -502,10 +499,10 @@ class TileAccelerator {
|
|||
static int GetPolyType(const PCW &pcw);
|
||||
static int GetVertexType(const PCW &pcw);
|
||||
|
||||
TileAccelerator(emu::Dreamcast *dc);
|
||||
TileAccelerator(hw::Dreamcast *dc);
|
||||
~TileAccelerator();
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
|
||||
void SoftReset();
|
||||
void InitContext(uint32_t addr);
|
||||
|
@ -522,7 +519,7 @@ class TileAccelerator {
|
|||
void WritePVRState(TileContext *tactx);
|
||||
void WriteBackgroundState(TileContext *tactx);
|
||||
|
||||
emu::Dreamcast *dc_;
|
||||
hw::Dreamcast *dc_;
|
||||
hw::Memory *memory_;
|
||||
hw::holly::Holly *holly_;
|
||||
uint8_t *video_ram_;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "core/core.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "hw/maple/maple_controller.h"
|
||||
#include "hw/dreamcast.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
using namespace dreavm::emu;
|
||||
using namespace dreavm::hw;
|
||||
using namespace dreavm::hw::holly;
|
||||
using namespace dreavm::hw::maple;
|
||||
using namespace dreavm::hw::sh4;
|
||||
|
@ -14,10 +14,12 @@ Maple::Maple(Dreamcast *dc) : dc_(dc), devices_() {
|
|||
devices_[0] = std::unique_ptr<MapleController>(new MapleController());
|
||||
}
|
||||
|
||||
void Maple::Init() {
|
||||
bool Maple::Init() {
|
||||
memory_ = dc_->memory();
|
||||
holly_ = dc_->holly();
|
||||
holly_regs_ = dc_->holly_regs();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Maple::HandleInput(int port, Keycode key, int16_t value) {
|
||||
|
|
|
@ -4,17 +4,14 @@
|
|||
#include "system/keys.h"
|
||||
|
||||
namespace dreavm {
|
||||
namespace emu {
|
||||
class Dreamcast;
|
||||
struct Register;
|
||||
}
|
||||
|
||||
namespace hw {
|
||||
namespace holly {
|
||||
class Holly;
|
||||
}
|
||||
|
||||
class Dreamcast;
|
||||
class Memory;
|
||||
struct Register;
|
||||
|
||||
namespace maple {
|
||||
|
||||
|
@ -103,9 +100,9 @@ class MapleDevice {
|
|||
|
||||
class Maple {
|
||||
public:
|
||||
Maple(emu::Dreamcast *dc);
|
||||
Maple(hw::Dreamcast *dc);
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
|
||||
bool HandleInput(int port, system::Keycode key, int16_t value);
|
||||
void VBlank();
|
||||
|
@ -117,10 +114,10 @@ class Maple {
|
|||
bool HandleFrame(const MapleFrame &frame, MapleFrame &res);
|
||||
void StartDMA();
|
||||
|
||||
emu::Dreamcast *dc_;
|
||||
hw::Dreamcast *dc_;
|
||||
hw::Memory *memory_;
|
||||
hw::holly::Holly *holly_;
|
||||
emu::Register *holly_regs_;
|
||||
hw::Register *holly_regs_;
|
||||
|
||||
std::unique_ptr<MapleDevice> devices_[MAX_PORTS];
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ SH4::SH4(Memory &memory, Runtime &runtime)
|
|||
requested_interrupts_(0),
|
||||
pending_interrupts_(0) {}
|
||||
|
||||
void SH4::Init() {
|
||||
bool SH4::Init() {
|
||||
memset(&ctx_, 0, sizeof(ctx_));
|
||||
ctx_.pc = 0xa0000000;
|
||||
ctx_.pr = 0x0;
|
||||
|
@ -43,6 +43,8 @@ void SH4::Init() {
|
|||
memset(cache_, 0, sizeof(cache_));
|
||||
|
||||
ReprioritizeInterrupts();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SH4::SetPC(uint32_t pc) { ctx_.pc = pc; }
|
||||
|
|
|
@ -120,7 +120,7 @@ class SH4 : public hw::Device {
|
|||
|
||||
uint32_t GetClockFrequency() { return 200000000; }
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
void SetPC(uint32_t pc);
|
||||
uint32_t Execute(uint32_t cycles);
|
||||
|
||||
|
|
11
src/main.cc
11
src/main.cc
|
@ -1,7 +1,6 @@
|
|||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include "core/core.h"
|
||||
#include "emu/dreamcast.h"
|
||||
#include "emu/emulator.h"
|
||||
#include "trace/trace_viewer.h"
|
||||
|
||||
using namespace dreavm::core;
|
||||
|
@ -37,11 +36,11 @@ int main(int argc, char **argv) {
|
|||
|
||||
const char *load = argc > 1 ? argv[1] : nullptr;
|
||||
if (load && strstr(load, ".trace")) {
|
||||
std::unique_ptr<TraceViewer> tracer(new TraceViewer());
|
||||
tracer->Run(load);
|
||||
TraceViewer tracer;
|
||||
tracer.Run(load);
|
||||
} else {
|
||||
std::unique_ptr<Dreamcast> emu(new Dreamcast());
|
||||
emu->Run(load);
|
||||
Emulator emu;
|
||||
emu.Run(load);
|
||||
}
|
||||
|
||||
ShutdownFlags();
|
||||
|
|
Loading…
Reference in New Issue