mirror of
https://github.com/libretro/Mu.git
synced 2026-05-06 20:34:20 +00:00
Fix code formatting again, add debuging tools
This commit is contained in:
@@ -18,7 +18,7 @@ TEMPLATE = app
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
CONFIG(debug, debug|release){
|
||||
DEFINES += EMU_DEBUG
|
||||
DEFINES += EMU_DEBUG EMU_OPCODE_LEVEL_DEBUG
|
||||
}
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
|
||||
a.setOrganizationDomain("meepingsnesroms.github.com");
|
||||
a.setApplicationName("Mu");
|
||||
w.show();
|
||||
a.setOrganizationDomain("meepingsnesroms.github.com");
|
||||
a.setApplicationName("Mu");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
@@ -31,244 +31,252 @@ static uint8_t romBuffer[ROM_SIZE];
|
||||
|
||||
|
||||
void popupErrorDialog(std::string error){
|
||||
//add error dialog code
|
||||
//add error dialog code
|
||||
}
|
||||
|
||||
uint8_t* getFileBuffer(std::string filePath, size_t& size, uint32_t& error){
|
||||
uint8_t* rawData = NULL;
|
||||
if(filePath != ""){
|
||||
struct stat st;
|
||||
int doesntExist = stat(filePath.c_str(), &st);
|
||||
if(doesntExist == 0 && st.st_size){
|
||||
FILE* dataFile = fopen(filePath.c_str(), "rb");
|
||||
if(dataFile != NULL){
|
||||
rawData = new (std::nothrow) uint8_t[st.st_size];
|
||||
if(rawData){
|
||||
size_t bytesRead = fread(rawData, 1, st.st_size, dataFile);
|
||||
if(bytesRead == (size_t)st.st_size){
|
||||
size = bytesRead;
|
||||
error = FRONTEND_ERR_NONE;
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_UNFINISHED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_OUT_OF_MEMORY;
|
||||
}
|
||||
fclose(dataFile);
|
||||
uint8_t* rawData = NULL;
|
||||
if(filePath != ""){
|
||||
struct stat st;
|
||||
int doesntExist = stat(filePath.c_str(), &st);
|
||||
if(doesntExist == 0 && st.st_size){
|
||||
FILE* dataFile = fopen(filePath.c_str(), "rb");
|
||||
if(dataFile != NULL){
|
||||
rawData = new (std::nothrow) uint8_t[st.st_size];
|
||||
if(rawData){
|
||||
size_t bytesRead = fread(rawData, 1, st.st_size, dataFile);
|
||||
if(bytesRead == (size_t)st.st_size){
|
||||
size = bytesRead;
|
||||
error = FRONTEND_ERR_NONE;
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_UNFINISHED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_PROTECTED;
|
||||
error = FRONTEND_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_DOESNT_EXIST;
|
||||
}
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_EMPTY_PATH;
|
||||
}
|
||||
fclose(dataFile);
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_PROTECTED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_DOESNT_EXIST;
|
||||
}
|
||||
}
|
||||
else{
|
||||
error = FRONTEND_FILE_EMPTY_PATH;
|
||||
}
|
||||
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
if(rawData)
|
||||
delete[] rawData;
|
||||
rawData = NULL;
|
||||
size = 0;
|
||||
}
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
if(rawData)
|
||||
delete[] rawData;
|
||||
rawData = NULL;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
return rawData;
|
||||
return rawData;
|
||||
}
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow){
|
||||
ui->setupUi(this);
|
||||
emuOn = false;
|
||||
emuInited = false;
|
||||
screenWidth = 160;
|
||||
screenHeight = 160 + 60;
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow){
|
||||
ui->setupUi(this);
|
||||
emuOn = false;
|
||||
emuInited = false;
|
||||
screenWidth = 160;
|
||||
screenHeight = 160 + 60;
|
||||
|
||||
loadRom();
|
||||
loadRom();
|
||||
|
||||
ui->ctrlBtn->setText("Start");
|
||||
ui->ctrlBtn->setText("Start");
|
||||
|
||||
refreshDisplay = new QTimer(this);
|
||||
connect(refreshDisplay, SIGNAL(timeout()), this, SLOT(updateDisplay()));
|
||||
//update display every 16.67 miliseconds = 60*second
|
||||
refreshDisplay->start(16);
|
||||
refreshDisplay = new QTimer(this);
|
||||
connect(refreshDisplay, SIGNAL(timeout()), this, SLOT(updateDisplay()));
|
||||
//update display every 16.67 miliseconds = 60*second
|
||||
refreshDisplay->start(16);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow(){
|
||||
emuMutex.lock();
|
||||
emulatorExit();
|
||||
emuMutex.unlock();
|
||||
delete ui;
|
||||
emuMutex.lock();
|
||||
emulatorExit();
|
||||
emuMutex.unlock();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::loadRom(){
|
||||
std::string rom = settings.value("romPath", "").toString().toStdString();
|
||||
if(rom == ""){
|
||||
//keep the selector open until a valid file is picked
|
||||
while(settings.value("romPath", "").toString().toStdString() == "")
|
||||
selectRom();
|
||||
}
|
||||
std::string rom = settings.value("romPath", "").toString().toStdString();
|
||||
if(rom == ""){
|
||||
//keep the selector open until a valid file is picked
|
||||
while(settings.value("romPath", "").toString().toStdString() == "")
|
||||
selectRom();
|
||||
}
|
||||
|
||||
uint32_t error;
|
||||
size_t size;
|
||||
uint8_t* romData = getFileBuffer(rom, size, error);
|
||||
if(romData){
|
||||
size_t romSize = size < ROM_SIZE ? size : ROM_SIZE;
|
||||
memcpy(romBuffer, romData, romSize);
|
||||
if(romSize < ROM_SIZE)
|
||||
memset(romBuffer + romSize, 0x00, ROM_SIZE - romSize);
|
||||
delete[] romData;
|
||||
}
|
||||
uint32_t error;
|
||||
size_t size;
|
||||
uint8_t* romData = getFileBuffer(rom, size, error);
|
||||
if(romData){
|
||||
size_t romSize = size < ROM_SIZE ? size : ROM_SIZE;
|
||||
memcpy(romBuffer, romData, romSize);
|
||||
if(romSize < ROM_SIZE)
|
||||
memset(romBuffer + romSize, 0x00, ROM_SIZE - romSize);
|
||||
delete[] romData;
|
||||
}
|
||||
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
popupErrorDialog("Could not open ROM file");
|
||||
}
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
popupErrorDialog("Could not open ROM file");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::selectRom(){
|
||||
std::string rom = QFileDialog::getOpenFileName(this, "Palm OS ROM (palmos41-en-m515.rom)", QDir::root().path(), 0).toStdString();
|
||||
uint32_t error;
|
||||
size_t size;
|
||||
uint8_t* romData = getFileBuffer(rom, size, error);
|
||||
if(romData){
|
||||
//valid file
|
||||
settings.setValue("romPath", QString::fromStdString(rom));
|
||||
delete[] romData;
|
||||
}
|
||||
std::string rom = QFileDialog::getOpenFileName(this, "Palm OS ROM (palmos41-en-m515.rom)", QDir::root().path(), 0).toStdString();
|
||||
uint32_t error;
|
||||
size_t size;
|
||||
uint8_t* romData = getFileBuffer(rom, size, error);
|
||||
if(romData){
|
||||
//valid file
|
||||
settings.setValue("romPath", QString::fromStdString(rom));
|
||||
delete[] romData;
|
||||
}
|
||||
|
||||
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
popupErrorDialog("Could not open ROM file");
|
||||
}
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
popupErrorDialog("Could not open ROM file");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_install_pressed(){
|
||||
std::string app = QFileDialog::getOpenFileName(this, "Open Prc/Pdb/Pqa", QDir::root().path(), 0).toStdString();
|
||||
uint32_t error;
|
||||
size_t size;
|
||||
uint8_t* appData = getFileBuffer(app, size, error);
|
||||
if(appData){
|
||||
error = emulatorInstallPrcPdb(appData, size);
|
||||
delete[] appData;
|
||||
}
|
||||
std::string app = QFileDialog::getOpenFileName(this, "Open Prc/Pdb/Pqa", QDir::root().path(), 0).toStdString();
|
||||
uint32_t error;
|
||||
size_t size;
|
||||
uint8_t* appData = getFileBuffer(app, size, error);
|
||||
if(appData){
|
||||
error = emulatorInstallPrcPdb(appData, size);
|
||||
delete[] appData;
|
||||
}
|
||||
|
||||
if(error != FRONTEND_ERR_NONE){
|
||||
popupErrorDialog("Could not install app");
|
||||
}
|
||||
if(error != FRONTEND_ERR_NONE)
|
||||
popupErrorDialog("Could not install app");
|
||||
}
|
||||
|
||||
//display
|
||||
void MainWindow::updateDisplay(){
|
||||
if(emuOn){
|
||||
if(emuMutex.try_lock()){
|
||||
emulateFrame();
|
||||
video = QImage((unsigned char*)palmFramebuffer, screenWidth, screenHeight, QImage::Format_RGB16);//16 bit
|
||||
ui->display->setPixmap(QPixmap::fromImage(video).scaled(ui->display->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
ui->display->update();
|
||||
emuMutex.unlock();
|
||||
}
|
||||
}
|
||||
if(emuOn){
|
||||
if(emuMutex.try_lock()){
|
||||
#ifdef EMU_DEBUG
|
||||
if(emulateUntilDebugEventOrFrameEnd()){
|
||||
//debug event occured
|
||||
emuOn = false;
|
||||
ui->ctrlBtn->setText("Resume");
|
||||
}
|
||||
#else
|
||||
emulateFrame();
|
||||
#endif
|
||||
|
||||
video = QImage((unsigned char*)palmFramebuffer, screenWidth, screenHeight, QImage::Format_RGB16);//16 bit
|
||||
ui->display->setPixmap(QPixmap::fromImage(video).scaled(ui->display->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
ui->display->update();
|
||||
emuMutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_display_destroyed(){
|
||||
//do nothing
|
||||
//do nothing
|
||||
}
|
||||
|
||||
//palm buttons
|
||||
void MainWindow::on_power_pressed(){
|
||||
palmInput.buttonPower = true;
|
||||
palmInput.buttonPower = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_power_released(){
|
||||
palmInput.buttonPower = false;
|
||||
palmInput.buttonPower = false;
|
||||
}
|
||||
|
||||
void MainWindow::on_calender_pressed(){
|
||||
palmInput.buttonCalender = true;
|
||||
palmInput.buttonCalender = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_calender_released(){
|
||||
palmInput.buttonCalender = false;
|
||||
palmInput.buttonCalender = false;
|
||||
}
|
||||
|
||||
void MainWindow::on_addressBook_pressed(){
|
||||
palmInput.buttonAddress = true;
|
||||
palmInput.buttonAddress = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_addressBook_released(){
|
||||
palmInput.buttonAddress = false;
|
||||
palmInput.buttonAddress = false;
|
||||
}
|
||||
|
||||
void MainWindow::on_todo_pressed(){
|
||||
palmInput.buttonTodo = true;
|
||||
palmInput.buttonTodo = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_todo_released(){
|
||||
palmInput.buttonTodo = false;
|
||||
palmInput.buttonTodo = false;
|
||||
}
|
||||
|
||||
void MainWindow::on_notes_pressed(){
|
||||
palmInput.buttonNotes = true;
|
||||
palmInput.buttonNotes = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_notes_released(){
|
||||
palmInput.buttonNotes = false;
|
||||
palmInput.buttonNotes = false;
|
||||
}
|
||||
|
||||
//ui buttons
|
||||
void MainWindow::on_mainLeft_clicked(){
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(2));
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(2));
|
||||
}
|
||||
|
||||
void MainWindow::on_mainRight_clicked(){
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(1));
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(1));
|
||||
}
|
||||
|
||||
void MainWindow::on_settingsLeft_clicked(){
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(0));
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(0));
|
||||
}
|
||||
|
||||
void MainWindow::on_settingsRight_clicked(){
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(2));
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(2));
|
||||
}
|
||||
|
||||
void MainWindow::on_joyLeft_clicked(){
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(1));
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(1));
|
||||
}
|
||||
|
||||
void MainWindow::on_joyRight_clicked(){
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(0));
|
||||
ui->controlPanel->setCurrentWidget(ui->controlPanel->widget(0));
|
||||
}
|
||||
|
||||
void MainWindow::on_settings_clicked(){
|
||||
//setprocess(SETUP);
|
||||
//setprocess(SETUP);
|
||||
}
|
||||
|
||||
//emu control
|
||||
void MainWindow::on_ctrlBtn_clicked()
|
||||
{
|
||||
emuMutex.lock();
|
||||
if(!emuOn && !emuInited){
|
||||
//start emu
|
||||
emulatorInit(romBuffer, NULL/*bootloader*/, ACCURATE);
|
||||
emuInited = true;
|
||||
emuOn = true;
|
||||
ui->ctrlBtn->setText("Pause");
|
||||
}
|
||||
else if(emuOn){
|
||||
emuOn = false;
|
||||
ui->ctrlBtn->setText("Resume");
|
||||
}
|
||||
else if(!emuOn){
|
||||
emuOn = true;
|
||||
ui->ctrlBtn->setText("Pause");
|
||||
}
|
||||
emuMutex.unlock();
|
||||
emuMutex.lock();
|
||||
if(!emuOn && !emuInited){
|
||||
//start emu
|
||||
emulatorInit(romBuffer, NULL/*bootloader*/, ACCURATE);
|
||||
emuInited = true;
|
||||
emuOn = true;
|
||||
ui->ctrlBtn->setText("Pause");
|
||||
}
|
||||
else if(emuOn){
|
||||
emuOn = false;
|
||||
ui->ctrlBtn->setText("Resume");
|
||||
}
|
||||
else if(!emuOn){
|
||||
emuOn = true;
|
||||
ui->ctrlBtn->setText("Pause");
|
||||
}
|
||||
emuMutex.unlock();
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@ extern uint32_t screenWidth;
|
||||
extern uint32_t screenHeight;
|
||||
|
||||
enum{
|
||||
FRONTEND_ERR_NONE,
|
||||
FRONTEND_FILE_DOESNT_EXIST,
|
||||
FRONTEND_FILE_EMPTY_PATH,
|
||||
FRONTEND_FILE_UNFINISHED,
|
||||
FRONTEND_FILE_MODIFYED,
|
||||
FRONTEND_FILE_INVALID_TYPE,
|
||||
FRONTEND_FILE_PROTECTED,
|
||||
FRONTEND_OUT_OF_MEMORY
|
||||
FRONTEND_ERR_NONE,
|
||||
FRONTEND_FILE_DOESNT_EXIST,
|
||||
FRONTEND_FILE_EMPTY_PATH,
|
||||
FRONTEND_FILE_UNFINISHED,
|
||||
FRONTEND_FILE_MODIFYED,
|
||||
FRONTEND_FILE_INVALID_TYPE,
|
||||
FRONTEND_FILE_PROTECTED,
|
||||
FRONTEND_OUT_OF_MEMORY
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
@@ -24,44 +24,44 @@ class MainWindow;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void loadRom();
|
||||
void selectRom();
|
||||
void on_install_pressed();
|
||||
void loadRom();
|
||||
void selectRom();
|
||||
void on_install_pressed();
|
||||
|
||||
//display
|
||||
void updateDisplay();
|
||||
void on_display_destroyed();
|
||||
//display
|
||||
void updateDisplay();
|
||||
void on_display_destroyed();
|
||||
|
||||
//palm buttons
|
||||
void on_power_pressed();
|
||||
void on_power_released();
|
||||
void on_calender_pressed();
|
||||
void on_calender_released();
|
||||
void on_addressBook_pressed();
|
||||
void on_addressBook_released();
|
||||
void on_todo_pressed();
|
||||
void on_todo_released();
|
||||
void on_notes_pressed();
|
||||
void on_notes_released();
|
||||
//palm buttons
|
||||
void on_power_pressed();
|
||||
void on_power_released();
|
||||
void on_calender_pressed();
|
||||
void on_calender_released();
|
||||
void on_addressBook_pressed();
|
||||
void on_addressBook_released();
|
||||
void on_todo_pressed();
|
||||
void on_todo_released();
|
||||
void on_notes_pressed();
|
||||
void on_notes_released();
|
||||
|
||||
//ui buttons
|
||||
void on_mainLeft_clicked();
|
||||
void on_mainRight_clicked();
|
||||
void on_settingsLeft_clicked();
|
||||
void on_settingsRight_clicked();
|
||||
void on_joyLeft_clicked();
|
||||
void on_joyRight_clicked();
|
||||
void on_settings_clicked();
|
||||
//ui buttons
|
||||
void on_mainLeft_clicked();
|
||||
void on_mainRight_clicked();
|
||||
void on_settingsLeft_clicked();
|
||||
void on_settingsRight_clicked();
|
||||
void on_joyLeft_clicked();
|
||||
void on_joyRight_clicked();
|
||||
void on_settings_clicked();
|
||||
|
||||
void on_ctrlBtn_clicked();
|
||||
void on_ctrlBtn_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "src/emulator.h"
|
||||
|
||||
float rangeSwap(float newRange, float oldRange, float value){
|
||||
return value / oldRange * newRange;
|
||||
return value / oldRange * newRange;
|
||||
}
|
||||
|
||||
TouchScreen::TouchScreen(QWidget* parent)
|
||||
@@ -16,17 +16,17 @@ TouchScreen::~TouchScreen(){
|
||||
}
|
||||
|
||||
void TouchScreen::mousePressEvent(QMouseEvent* ev){
|
||||
palmInput.touchscreenX = (uint16_t)rangeSwap(screenWidth, this->width(), ev->x());
|
||||
palmInput.touchscreenY = (uint16_t)rangeSwap(screenHeight, this->height(), ev->y());
|
||||
palmInput.touchscreenX = (uint16_t)rangeSwap(screenWidth, this->width(), ev->x());
|
||||
palmInput.touchscreenY = (uint16_t)rangeSwap(screenHeight, this->height(), ev->y());
|
||||
palmInput.touchscreenTouched = true;
|
||||
}
|
||||
void TouchScreen::mouseMoveEvent(QMouseEvent* ev){
|
||||
palmInput.touchscreenX = (uint16_t)rangeSwap(screenWidth, this->width(), ev->x());
|
||||
palmInput.touchscreenY = (uint16_t)rangeSwap(screenHeight, this->height(), ev->y());
|
||||
palmInput.touchscreenX = (uint16_t)rangeSwap(screenWidth, this->width(), ev->x());
|
||||
palmInput.touchscreenY = (uint16_t)rangeSwap(screenHeight, this->height(), ev->y());
|
||||
}
|
||||
|
||||
void TouchScreen::mouseReleaseEvent(QMouseEvent* ev){
|
||||
palmInput.touchscreenTouched = false;
|
||||
palmInput.touchscreenTouched = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,13 +8,13 @@ class TouchScreen : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TouchScreen(QWidget* parent=0 );
|
||||
~TouchScreen();
|
||||
explicit TouchScreen(QWidget* parent=0 );
|
||||
~TouchScreen();
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* ev);
|
||||
void mouseMoveEvent(QMouseEvent* ev);
|
||||
void mouseReleaseEvent(QMouseEvent* ev);
|
||||
void mousePressEvent(QMouseEvent* ev);
|
||||
void mouseMoveEvent(QMouseEvent* ev);
|
||||
void mouseReleaseEvent(QMouseEvent* ev);
|
||||
|
||||
//void touchReleaseEvent(QTouchEvent* ev);
|
||||
//void touchReleaseEvent(QTouchEvent* ev);
|
||||
};
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ double palmCrystalCycles;//how many cycles before toggling the 32.768 kHz cry
|
||||
double palmCycleCounter;//can be greater then 0 if too many cycles where run
|
||||
double palmClockMultiplier;//used by the emulator to overclock the emulated Palm
|
||||
|
||||
|
||||
uint64_t (*emulatorGetSysTime)();
|
||||
uint64_t* (*emulatorGetSdCardStateChunkList)(uint64_t sessionId, uint64_t stateId);//returns the bps chunkIds for a stateId in the order they need to be applied
|
||||
void (*emulatorSetSdCardStateChunkList)(uint64_t sessionId, uint64_t stateId, uint64_t* data);//sets the bps chunkIds for a stateId in the order they need to be applied
|
||||
@@ -52,12 +53,48 @@ static inline bool allSdCardCallbacksPresent(){
|
||||
}
|
||||
|
||||
|
||||
//debug
|
||||
#ifdef EMU_OPCODE_LEVEL_DEBUG
|
||||
#define LOGGED_OPCODES 10
|
||||
static bool invalidBehaviorAbort;
|
||||
static char disassemblyBuffer[LOGGED_OPCODES][100];//store the opcode and program counter for the last 10 opcodes
|
||||
|
||||
static void invalidBehaviorCheck(){
|
||||
for(uint32_t i = 0; i < LOGGED_OPCODES - 1; i++)
|
||||
strcpy(disassemblyBuffer[i], disassemblyBuffer[i + 1]);
|
||||
|
||||
uint32_t programCounter = m68k_get_reg(NULL, M68K_REG_PC);
|
||||
uint16_t instruction = m68k_get_reg(NULL, M68K_REG_IR);
|
||||
|
||||
m68k_disassemble(disassemblyBuffer[LOGGED_OPCODES - 1], programCounter, M68K_CPU_TYPE_68020);
|
||||
strcat(disassemblyBuffer[LOGGED_OPCODES - 1], "\n");
|
||||
|
||||
if(bankType[programCounter >> 16] == EMPTY_BANK)
|
||||
invalidBehaviorAbort = true;
|
||||
|
||||
if(!m68k_is_valid_instruction(instruction, M68K_CPU_TYPE_68020) || instruction == 0x0000){
|
||||
//0x0000 is "ori.b #$0, D0", effectivly NOP but still a valid opcode
|
||||
//usualy never encountered unless executing empty address space, so it still triggers debug abort
|
||||
invalidBehaviorAbort = true;
|
||||
}
|
||||
|
||||
if(invalidBehaviorAbort)
|
||||
m68k_end_timeslice();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void emulatorInit(uint8_t* palmRomDump, uint8_t* palmBootDump, uint32_t specialFeatures){
|
||||
//cpu
|
||||
//CPU
|
||||
m68k_init();
|
||||
m68k_set_cpu_type(M68K_CPU_TYPE_68020);
|
||||
m68k_set_reset_instr_callback(emulatorReset);
|
||||
m68k_set_int_ack_callback(interruptAcknowledge);
|
||||
#ifdef EMU_OPCODE_LEVEL_DEBUG
|
||||
for(uint32_t i = 0; i < LOGGED_OPCODES; i++)
|
||||
strcpy(disassemblyBuffer[i], "Not an opcode.\n");
|
||||
m68k_set_instr_hook_callback(invalidBehaviorCheck);
|
||||
#endif
|
||||
patchMusashiOpcodeHandlerCpu32();
|
||||
resetHwRegisters();
|
||||
lowPowerStopActive = false;
|
||||
@@ -342,3 +379,30 @@ void emulateFrame(){
|
||||
|
||||
//debugLog("Ran frame, executed %f cycles.\n", palmCycleCounter + CPU_FREQUENCY / EMU_FPS);
|
||||
}
|
||||
|
||||
bool emulateUntilDebugEventOrFrameEnd(){
|
||||
#ifdef EMU_OPCODE_LEVEL_DEBUG
|
||||
invalidBehaviorAbort = false;
|
||||
|
||||
refreshButtonState();
|
||||
while(palmCycleCounter < CPU_FREQUENCY / EMU_FPS){
|
||||
if(cpuIsOn())
|
||||
palmCycleCounter += m68k_execute(palmCrystalCycles * palmClockMultiplier) / palmClockMultiplier;//normaly 33mhz / 60fps
|
||||
else
|
||||
palmCycleCounter += palmCrystalCycles;
|
||||
clk32();
|
||||
if(invalidBehaviorAbort)
|
||||
break;
|
||||
}
|
||||
palmCycleCounter -= CPU_FREQUENCY / EMU_FPS;
|
||||
|
||||
if(invalidBehaviorAbort)
|
||||
for(uint32_t i = 0; i < LOGGED_OPCODES; i++)
|
||||
debugLog(disassemblyBuffer[i]);
|
||||
|
||||
return invalidBehaviorAbort;
|
||||
#else
|
||||
emulateFrame();
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
//to enable opcode level debugging define EMU_OPCODE_LEVEL_DEBUG
|
||||
|
||||
#ifdef EMU_DEBUG
|
||||
#define debugLog(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
@@ -151,6 +153,7 @@ void emulatorSaveState(uint8_t* data);
|
||||
void emulatorLoadState(uint8_t* data);
|
||||
uint32_t emulatorInstallPrcPdb(uint8_t* data, uint32_t size);
|
||||
void emulateFrame();
|
||||
bool emulateUntilDebugEventOrFrameEnd();//false for frame end, true for debug event
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void setHwRegister32(unsigned int address, unsigned int value);
|
||||
//timing
|
||||
void clk32();//also checks all interrupts
|
||||
|
||||
//cpu
|
||||
//CPU
|
||||
bool cpuIsOn();
|
||||
int interruptAcknowledge(int intLevel);
|
||||
bool registersAreXXFFMapped();
|
||||
|
||||
@@ -130,7 +130,11 @@
|
||||
/* If ON, CPU will call the instruction hook callback before every
|
||||
* instruction.
|
||||
*/
|
||||
#ifdef EMU_OPCODE_LEVEL_DEBUG
|
||||
#define M68K_INSTRUCTION_HOOK OPT_ON
|
||||
#else
|
||||
#define M68K_INSTRUCTION_HOOK OPT_OFF
|
||||
#endif
|
||||
#define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user