Add support for Slot 2 flashcarts using Compact Flash (#84)

- Supercard CF (SUPERCARDCF)
- GBA Media Player CF (MPCF)
- M3 Adapter CF (M3CF)
- Max Media Dock CF (MMCF)
This commit is contained in:
Edoardo Lolletti
2026-01-10 23:00:39 +01:00
committed by GitHub
parent eac8f7e734
commit 6a97b677a7
22 changed files with 945 additions and 3 deletions

View File

@@ -0,0 +1,21 @@
#include "common.h"
#include "SuperCardCFLoaderPlatform.h"
#define SC_MODE_REG (*(vu16*)0x09FFFFFE)
#define SC_MODE_MAGIC 0xA55A
#define SC_MODE_MEDIA 0x3
#define SC_MODE_RAM_RO 0x1
static void changeSupercardMode(u8 mode)
{
SC_MODE_REG = SC_MODE_MAGIC;
SC_MODE_REG = SC_MODE_MAGIC;
SC_MODE_REG = mode;
SC_MODE_REG = mode;
}
void SuperCardCFLoaderPlatform::SetCardLocked(bool locked) const
{
changeSupercardMode(locked ? SC_MODE_RAM_RO : SC_MODE_MEDIA);
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include "common.h"
#include "SuperCardCFLockUnlockCardPatchCode.h"
#include "../compactflash-common/CompactFlashCommonLoaderPlatform.h"
/// @brief Implementation of LoaderPlatform for the DATEL line of flashcarts
class SuperCardCFLoaderPlatform : public CompactFlashCommonLoaderPlatform
{
protected:
const ICompactFlashLockUnlockPatchCode* CreateLockingPatchCode(
PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override
{
return patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCFLockUnlockCardPatchCode(patchHeap);
});
}
void SetCardLocked(bool locked) const override;
const cf_registers_t& GetCfRegisters() const override
{
static const cf_registers_t registers
{
.data = (vu16*)0x09000000,
.altStatus = (vu16*)0x098C0000,
.command = (vu16*)0x090E0000,
.error = (vu16*)0x09020000,
.sectorCount = (vu16*)0x09040000,
.lba1 = (vu16*)0x09060000,
.lba2 = (vu16*)0x09080000,
.lba3 = (vu16*)0x090A0000,
.lba4 = (vu16*)0x090C0000,
};
return registers;
}
};

View File

@@ -0,0 +1,20 @@
#pragma once
#include "sections.h"
#include "patches/PatchCode.h"
#include "../compactflash-common/ICompactFlashLockUnlockPatchCode.h"
DEFINE_SECTION_SYMBOLS(sccf_lock_unlock);
extern "C" void sccf_lockUnlockCard(bool lock);
class SuperCardCFLockUnlockCardPatchCode : public PatchCode, public ICompactFlashLockUnlockPatchCode
{
public:
explicit SuperCardCFLockUnlockCardPatchCode(PatchHeap& patchHeap)
: PatchCode(SECTION_START(sccf_lock_unlock), SECTION_SIZE(sccf_lock_unlock), patchHeap) { }
const void* GetLockUnlockFunction() const override
{
return GetAddressAtTarget((void*)sccf_lockUnlockCard);
}
};

View File

@@ -0,0 +1,26 @@
.cpu arm7tdmi
.syntax unified
.thumb
.section "sccf_lock_unlock", "ax"
.global sccf_lockUnlockCard
.type sccf_lockUnlockCard, %function
sccf_lockUnlockCard:
cmp r0, #1
bne unlock
@ void sc_change_mode(uint16_t mode);
sccf_changeMode:
push {r1-r3, lr}
ldr r2,= 0x09FFFFFE
ldr r3,= 0xA55A
strh r3, [r2]
strh r3, [r2]
strh r0, [r2]
strh r0, [r2]
pop {r1-r3, pc}
unlock:
movs r0, #3
b sccf_changeMode
.pool