GBA Hardware: I know this e-Reader code is wrong

This commit is contained in:
Vicki Pfau 2017-10-16 22:43:02 -07:00
parent 40a22eba77
commit 4b5efa2365
7 changed files with 69 additions and 1 deletions

View File

@ -88,6 +88,12 @@ struct GBASIOBattlechipGate {
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*);
#define EREADER_BLOCK_SIZE 40
struct GBAEReaderDataSource {
bool (*readBlock)(struct GBAEReaderDataSource*, void*);
};
CXX_GUARD_END
#endif

View File

@ -172,6 +172,7 @@ struct GBACartridgeHardware {
uint8_t eReaderActiveRegister;
uint8_t eReaderByte;
uint8_t eReaderDelay;
struct GBAEReaderDataSource* eReaderSource;
};
void GBAHardwareInit(struct GBACartridgeHardware* gpio, uint16_t* gpioBase);
@ -196,6 +197,7 @@ void GBAHardwareEReaderWrite(struct GBACartridgeHardware* hw, uint32_t address,
void GBAHardwareEReaderWriteFlash(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value);
uint16_t GBAHardwareEReaderRead(struct GBACartridgeHardware* hw, uint32_t address);
uint8_t GBAHardwareEReaderReadFlash(struct GBACartridgeHardware* hw, uint32_t address);
void GBAHardwareEReaderScan(struct GBACartridgeHardware* hw, struct GBAEReaderDataSource* source);
void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba);

View File

@ -39,6 +39,7 @@ static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cy
static void _eReaderReset(struct GBACartridgeHardware* hw);
static void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value);
static void _eReaderWriteControl1(struct GBACartridgeHardware* hw, uint8_t value);
static void _eReaderReadData(struct GBACartridgeHardware* hw);
static const int RTC_BYTES[8] = {
0, // Force reset
@ -666,6 +667,14 @@ uint8_t GBAHardwareEReaderReadFlash(struct GBACartridgeHardware* hw, uint32_t ad
}
}
void GBAHardwareEReaderScan(struct GBACartridgeHardware* hw, struct GBAEReaderDataSource* source) {
if (!EReaderControl0IsScan(hw->eReaderRegisterControl0)) {
return;
}
hw->eReaderSource = source;
_eReaderReadData(hw);
}
void _eReaderReset(struct GBACartridgeHardware* hw) {
memset(hw->eReaderData, 0, sizeof(hw->eReaderData));
hw->eReaderRegisterUnk = 0;
@ -738,7 +747,7 @@ void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value) {
++hw->eReaderActiveRegister;
break;
default:
mLOG(GBA_HW, ERROR, "???");
mLOG(GBA_HW, ERROR, "Hit undefined state in e-Reader state machine");
break;
}
hw->eReaderState = EREADER_SERIAL_BIT_0;
@ -759,15 +768,33 @@ void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value) {
control = EReaderControl0ClearData(control);
}
hw->eReaderRegisterControl0 = control;
if (!EReaderControl0IsScan(oldControl) && EReaderControl0IsScan(control)) {
_eReaderReadData(hw);
}
mLOG(GBA_HW, STUB, "Unimplemented e-Reader Control0 write: %02X", value);
}
void _eReaderWriteControl1(struct GBACartridgeHardware* hw, uint8_t value) {
EReaderControl1 control = (value & 0x32) | 0x80;
hw->eReaderRegisterControl1 = control;
if (EReaderControl0IsScan(hw->eReaderRegisterControl0) && !EReaderControl1IsScanline(control)) {
_eReaderReadData(hw);
}
mLOG(GBA_HW, STUB, "Unimplemented e-Reader Control1 write: %02X", value);
}
void _eReaderReadData(struct GBACartridgeHardware* hw) {
if (!hw->eReaderSource) {
return;
}
memset(hw->eReaderData, 0, EREADER_BLOCK_SIZE);
hw->eReaderSource->readBlock(hw->eReaderSource, hw->eReaderData);
hw->eReaderRegisterControl1 = EReaderControl1FillScanline(hw->eReaderRegisterControl1);
if (EReaderControl0IsLedEnable(hw->eReaderRegisterControl0)) {
GBARaiseIRQ(hw->p, IRQ_GAMEPAK, 0);
}
}
// == Serialization
void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASerializedState* state) {

View File

@ -680,6 +680,24 @@ void CoreController::setFakeEpoch(const QDateTime& time) {
m_threadContext.core->rtc.value = time.toMSecsSinceEpoch();
}
void CoreController::scanCard(const QString& path) {
#ifdef M_CORE_GBA
if (m_eReader.file.isOpen()) {
m_eReader.file.close();
}
m_eReader.file.setFileName(path);
if (!m_eReader.file.open(QIODevice::ReadOnly)) {
return;
}
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* thread) {
CoreController* controller = static_cast<CoreController*>(thread->userData);
GBAHardwareEReaderScan(&static_cast<GBA*>(thread->core->board)->memory.hw, &controller->m_eReader);
});
#endif
}
void CoreController::importSharkport(const QString& path) {
#ifdef M_CORE_GBA
if (platform() != PLATFORM_GBA) {

View File

@ -6,6 +6,7 @@
#pragma once
#include <QByteArray>
#include <QFile>
#include <QList>
#include <QMutex>
#include <QObject>
@ -127,6 +128,7 @@ public slots:
void loadSave(const QString&, bool temporary);
void loadPatch(const QString&);
void scanCard(const QString&);
void replaceGame(const QString&);
void yankPak();
@ -256,6 +258,10 @@ private:
#ifdef M_CORE_GBA
GBASIOBattlechipGate m_battlechip;
struct GameControllerEReader : GBAEReaderDataSource {
CoreController* p;
QFile file;
} m_eReader;
#endif
};

View File

@ -423,6 +423,13 @@ void Window::selectPatch() {
}
}
void Window::scanCard() {
QString filename = GBAApp::app()->getOpenFileName(this, tr("Select e-Reader dotcode"));
if (!filename.isEmpty()) {
m_controller->scanCard(filename);
}
}
void Window::openView(QWidget* widget) {
connect(this, &Window::shutdown, widget, &QWidget::close);
widget->setAttribute(Qt::WA_DeleteOnClose);
@ -1118,6 +1125,7 @@ void Window::setupMenu(QMenuBar* menubar) {
#endif
m_actions.addAction(tr("Replace ROM..."), "replaceROM", this, &Window::replaceROM, "file");
m_actions.addAction(tr("Scan e-Reader dotcode..."), "scanCard", this, &Window::scanCard, "file");
Action* romInfo = addGameAction(tr("ROM &info..."), "romInfo", openControllerTView<ROMInfo>(), "file");

View File

@ -75,6 +75,7 @@ public slots:
void selectSave(bool temporary);
void selectState(bool load);
void selectPatch();
void scanCard();
void enterFullScreen();
void exitFullScreen();
void toggleFullScreen();