Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions iop/memorycard/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# Review ps2sdk README & LICENSE files for further details.

SUBDIRS = \
dongleman \
mcman \
mcman-old \
mcserv \
Expand Down
18 changes: 18 additions & 0 deletions iop/memorycard/dongleman/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright 2001-2025, ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.

PARENT_DIR=$(PS2SDKSRC)/iop/memorycard/mcman

IOP_SRC_DIR = $(PARENT_DIR)/src/
IOP_INC_DIR = $(PARENT_DIR)/include/

IOP_BIN = dongleman.irx

MCMAN_BUILDING_DONGLEMAN ?= 1

include $(PARENT_DIR)/Makefile
7 changes: 7 additions & 0 deletions iop/memorycard/mcman/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ MCMAN_BUILDING_XFROMMAN ?= 0
# Read from a file on the filesystem insead of the memory card?
MCMAN_BUILDING_VMCMAN ?= 0

# Support for arcade PS2
MCMAN_BUILDING_DONGLEMAN ?= 0

# IOP_CFLAGS += -DSIO_DEBUG -DDEBUG

IOP_INCS += \
Expand Down Expand Up @@ -57,6 +60,10 @@ IOP_CFLAGS += -DIOMANX_OLD_NAME_COMPATIBILITY=0
IOP_CFLAGS += -DIOMANX_OLD_NAME_ADDDELDRV=0
endif

ifneq (x$(MCMAN_BUILDING_DONGLEMAN),x0)
IOP_CFLAGS += -DBUILDING_DONGLEMAN
endif

include $(PS2SDKSRC)/Defs.make
include $(PS2SDKSRC)/iop/Rules.bin.make
include $(PS2SDKSRC)/iop/Rules.make
Expand Down
3 changes: 3 additions & 0 deletions iop/memorycard/mcman/src/imports.lst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ secrman_IMPORTS_start
I_SecrSetMcCommandHandler
I_SecrSetMcDevIDHandler
I_SecrAuthCard
#ifdef BUILDING_DONGLEMAN
I_SecrAuthDongle
#endif
secrman_IMPORTS_end
#endif

Expand Down
20 changes: 19 additions & 1 deletion iop/memorycard/mcman/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ static const u8 mcman_xortable[256] = {
};
// clang-format on

#ifdef BUILDING_DONGLEMAN
int sema_hakama_id = 0;
#endif

//--------------------------------------------------------------
void long_multiply(u32 v1, u32 v2, u32 *HI, u32 *LO)
{
Expand Down Expand Up @@ -1162,6 +1166,8 @@ int McReadPage(int port, int slot, int page, void *buf) // Export #18
u8 eccbuf[32];
u8 *pdata, *peccb;

HAKAMA_WAITSEMA();

count = (mcdi->pagesize + 127) >> 7;
erase_byte = (mcdi->cardflags & CF_ERASE_ZEROES) ? 0x0 : 0xFF;

Expand Down Expand Up @@ -1203,6 +1209,8 @@ int McReadPage(int port, int slot, int page, void *buf) // Export #18
}
} while (++retries < 5);

HAKAMA_SIGNALSEMA();

if (retries < 5)
return sceMcResSucceed;

Expand Down Expand Up @@ -1241,7 +1249,17 @@ void McDataChecksum(void *buf, void *ecc) // Export #20
//--------------------------------------------------------------
int mcman_getcnum(int port, int slot)
{
return ((port & 1) << 3) + slot;
return
#if !defined(BUILDING_DONGLEMAN)
((port & 1) << 3) + slot;
#else
/**
* this cnum is impossible to get with any combination in 4 slots, 2 ports
* most likely this is intened to be used by MCMAN modules that read dongles. as Arcade rom0:MCMANO does not have this.
* secrAuthDongle will xor this number with 0x40 for `mechacon_auth_81()`
*/
0xF;
#endif
}

//--------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions iop/memorycard/mcman/src/mcman-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
#define MODNAME "vmcman"
#elif defined(BUILDING_XFROMMAN)
#define MODNAME "xfromman"
#elif defined(BUILDING_DONGLEMAN)
#define MODNAME "dongleman"
#endif
#define MODVER 0x20b

Expand Down Expand Up @@ -363,4 +365,14 @@ extern u8 mcman_eccdata[512]; // size for 32 ecc
// Defined in mcsio2.c
extern u8 mcman_sio2outbufs_PS1PDA[0x90];

#ifdef BUILDING_DONGLEMAN
extern int sema_hakama_id;
/// El_isra: Not sure why it hangs... I still need to determine their actual purpose. disabled for now...
#define HAKAMA_SIGNALSEMA() //SignalSema(sema_hakama_id)
#define HAKAMA_WAITSEMA() //WaitSema(sema_hakama_id)
#else
#define HAKAMA_SIGNALSEMA() //while(0) {} /* SignalSema wrapper for an additional semaphore used by arcade MCMAN */
#define HAKAMA_WAITSEMA() //while(0) {} /* WaitSema wrapper for an additional semaphore used by arcade MCMAN */
#endif

#endif // __MCMAN_INTERNAL_H__
88 changes: 71 additions & 17 deletions iop/memorycard/mcman/src/mcsio2.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,16 @@ void mcman_initPS2com(void)
DPRINTF("mcman_initPS2com registering mcman_getcnum callback\n");

SecrSetMcDevIDHandler((void *)mcman_getcnum);

#ifdef BUILDING_DONGLEMAN
iop_sema_t sema_hakama;
sema_hakama.attr = 1;
sema_hakama.initial = 1;
sema_hakama.max = 1;
sema_hakama.option = 0;
sema_hakama_id = CreateSema(&sema_hakama);
#endif

#elif defined(BUILDING_XFROMMAN)
flash_detect();
flash_get_info(&dev9_flash_info);
Expand Down Expand Up @@ -448,6 +458,7 @@ int mcman_eraseblock(int port, int slot, int block, void **pagebuf, void *eccbuf
{
register int retries, size, ecc_offset;
int page;
HAKAMA_WAITSEMA();
#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
u8 *p = mcman_sio2packet.out_dma.addr;
#endif
Expand Down Expand Up @@ -519,14 +530,19 @@ int mcman_eraseblock(int port, int slot, int block, void **pagebuf, void *eccbuf
if (((mcman_sio2packet.stat6c & 0xF000) != 0x1000))
continue;

if (p[3] == 0x5a)
if (p[3] == 0x5a) {
HAKAMA_SIGNALSEMA();
return sceMcResSucceed;
}
} while (++retries < 100);

if (p[3] == 0x66)
HAKAMA_SIGNALSEMA(); //El_isra: Original impl has two semas (still commented there) replaced with one for simplicity
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can't signal before as it could potentially change the value of p before you read in the following "ifs"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right

if (p[3] == 0x66) {
//HAKAMA_SIGNALSEMA();
return sceMcResFailReplace;
}
#endif

//HAKAMA_SIGNALSEMA();
return sceMcResNoFormat;
}

Expand All @@ -540,6 +556,8 @@ int McWritePage(int port, int slot, int page, void *pagebuf, void *eccbuf) // Ex
u8 *p = mcman_sio2packet.out_dma.addr;
#endif

HAKAMA_WAITSEMA();

#ifdef BUILDING_XFROMMAN
(void)port;
(void)slot;
Expand Down Expand Up @@ -611,14 +629,19 @@ int McWritePage(int port, int slot, int page, void *pagebuf, void *eccbuf) // Ex
if (flash_page_write(&dev9_flash_info, page, page_buf))
continue;
#endif
HAKAMA_SIGNALSEMA();
return sceMcResSucceed;

} while (++retries < 5);

#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
if (p[3] == 0x66)
HAKAMA_SIGNALSEMA(); // El_isra: simplify original impl
if (p[3] == 0x66) {
//HAKAMA_SIGNALSEMA();
return sceMcResFailReplace;
}

//HAKAMA_SIGNALSEMA();
return sceMcResNoFormat;
#else
return sceMcResFailReplace;
Expand Down Expand Up @@ -729,6 +752,8 @@ int McGetCardSpec(int port, int slot, s16 *pagesize, u16 *blocksize, int *cardsi

DPRINTF("McGetCardSpec sio2cmd port%d slot%d\n", port, slot);

HAKAMA_WAITSEMA();

sio2packet_add(port, slot, 0xffffffff, NULL);
sio2packet_add(port, slot, 0x07, NULL);
sio2packet_add(port, slot, 0xfffffffe, NULL);
Expand All @@ -746,8 +771,10 @@ int McGetCardSpec(int port, int slot, s16 *pagesize, u16 *blocksize, int *cardsi
}
} while (++retries < 5);

if (retries >= 5)
if (retries >= 5) {
HAKAMA_SIGNALSEMA();
return sceMcResChangedCard;
}

*pagesize = (p[4] << 8) + p[3];
*blocksize = (p[6] << 8) + p[5];
Expand All @@ -767,8 +794,8 @@ int McGetCardSpec(int port, int slot, s16 *pagesize, u16 *blocksize, int *cardsi
if (dev9_flash_info.page_bytes != 512)
*flags |= CF_USE_ECC;
#endif

DPRINTF("McGetCardSpec sio2cmd pagesize=%d blocksize=%u cardsize=%d flags%x\n", *pagesize, *blocksize, *cardsize, *flags);
HAKAMA_SIGNALSEMA();

return sceMcResSucceed;
}
Expand Down Expand Up @@ -818,7 +845,7 @@ int mcman_probePS2Card2(int port, int slot)
u8 *p = mcman_sio2packet.out_dma.addr;

DPRINTF("mcman_probePS2Card2 sio2cmd port%d slot%d\n", port, slot);

HAKAMA_WAITSEMA();
retries = 0;
do {
sio2packet_add(port, slot, 0xffffffff, NULL);
Expand All @@ -831,21 +858,23 @@ int mcman_probePS2Card2(int port, int slot)
break;
} while (++retries < 5);

if (retries >= 5)
if (retries >= 5) {
HAKAMA_SIGNALSEMA();
return sceMcResFailDetect;
}

if (p[3] == 0x5a) {
r = McGetFormat(port, slot);
if (r > 0)
{
DPRINTF("mcman_probePS2Card2 succeeded\n");

HAKAMA_SIGNALSEMA();
return sceMcResSucceed;
}
else if (r < 0)
{
DPRINTF("mcman_probePS2Card2 sio2cmd failed (no format)\n");

HAKAMA_SIGNALSEMA();
return sceMcResNoFormat;
}
}
Expand All @@ -862,6 +891,7 @@ int mcman_probePS2Card2(int port, int slot)
return sceMcResNoFormat;
#endif

HAKAMA_SIGNALSEMA();
return sceMcResFailDetect2;
}

Expand All @@ -874,37 +904,61 @@ int mcman_probePS2Card(int port, int slot) //2
u8 *p = mcman_sio2packet.out_dma.addr;
#endif

HAKAMA_WAITSEMA();

DPRINTF("mcman_probePS2Card sio2cmd port%d slot%d\n", port, slot);

r = mcman_cardchanged(port, slot);
if (r == sceMcResSucceed) {
r = McGetFormat(port, slot);
#ifdef BUILDING_DONGLEMAN
if (r != 0 && port == 0) {
DPRINTF("mcman_probePS2Card:[McGetFormat() != 0]: calling authdongle(2, %d, %d)\n", slot, mcman_getcnum(port, slot));
SecrAuthDongle(2, slot, mcman_getcnum(port, slot));
}
#endif
if (r > 0)
{
DPRINTF("mcman_probePS2Card sio2cmd succeeded\n");

HAKAMA_SIGNALSEMA();
return sceMcResSucceed;
}
else if (r < 0)
{
DPRINTF("mcman_probePS2Card sio2cmd failed (no format)\n");

HAKAMA_SIGNALSEMA();
return sceMcResNoFormat;
}
}

#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
if (mcman_resetauth(port, slot) != sceMcResSucceed) {
DPRINTF("mcman_probePS2Card sio2cmd failed (auth reset failed)\n");

HAKAMA_SIGNALSEMA();
return sceMcResFailResetAuth;
}

if (SecrAuthCard(port + 2, slot, mcman_getcnum(port, slot)) == 0) {
DPRINTF("mcman_probePS2Card sio2cmd failed (auth failed)\n");
#ifdef BUILDING_DONGLEMAN
if (port == 0) {
DPRINTF("mcman_probePS2Card: SecrAuthDongle(2, %d, %d)\n", slot, mcman_getcnum(port, slot));
if (SecrAuthDongle(2, slot, mcman_getcnum(port, slot)) == 0) {
DPRINTF("mcman_probePS2Card SecrAuthDongle Failed\n");

return sceMcResFailAuth;
}
return sceMcResFailAuth;
}
}
else if (SecrAuthCard(port + 2, slot, mcman_getcnum(port, slot)) == 0) {
DPRINTF("mcman_probePS2Card sio2cmd failed (auth failed)\n");

return sceMcResFailAuth;
}
#else
if (SecrAuthCard(port + 2, slot, mcman_getcnum(port, slot)) == 0) {
DPRINTF("mcman_probePS2Card sio2cmd failed (auth failed)\n");

return sceMcResFailAuth;
}
#endif

retries = 0;
do {
Expand Down