diff --git a/iop/memorycard/Makefile b/iop/memorycard/Makefile index c64513d835d..8edefcb0dd7 100644 --- a/iop/memorycard/Makefile +++ b/iop/memorycard/Makefile @@ -7,6 +7,7 @@ # Review ps2sdk README & LICENSE files for further details. SUBDIRS = \ + dongleman \ mcman \ mcman-old \ mcserv \ diff --git a/iop/memorycard/dongleman/Makefile b/iop/memorycard/dongleman/Makefile new file mode 100644 index 00000000000..63b2f18e53d --- /dev/null +++ b/iop/memorycard/dongleman/Makefile @@ -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 diff --git a/iop/memorycard/mcman/Makefile b/iop/memorycard/mcman/Makefile index d064e9cb5fa..b0a1f9bb852 100644 --- a/iop/memorycard/mcman/Makefile +++ b/iop/memorycard/mcman/Makefile @@ -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 += \ @@ -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 diff --git a/iop/memorycard/mcman/src/imports.lst b/iop/memorycard/mcman/src/imports.lst index 3e8215304c7..6511427bf2e 100644 --- a/iop/memorycard/mcman/src/imports.lst +++ b/iop/memorycard/mcman/src/imports.lst @@ -107,6 +107,9 @@ secrman_IMPORTS_start I_SecrSetMcCommandHandler I_SecrSetMcDevIDHandler I_SecrAuthCard +#ifdef BUILDING_DONGLEMAN +I_SecrAuthDongle +#endif secrman_IMPORTS_end #endif diff --git a/iop/memorycard/mcman/src/main.c b/iop/memorycard/mcman/src/main.c index e1aeb7defb1..4c6a463bf1b 100644 --- a/iop/memorycard/mcman/src/main.c +++ b/iop/memorycard/mcman/src/main.c @@ -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) { @@ -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; @@ -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; @@ -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 } //-------------------------------------------------------------- diff --git a/iop/memorycard/mcman/src/mcman-internal.h b/iop/memorycard/mcman/src/mcman-internal.h index 52eec493af6..009619ca05c 100644 --- a/iop/memorycard/mcman/src/mcman-internal.h +++ b/iop/memorycard/mcman/src/mcman-internal.h @@ -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 @@ -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__ diff --git a/iop/memorycard/mcman/src/mcsio2.c b/iop/memorycard/mcman/src/mcsio2.c index fe89de59623..10d83dcdd78 100644 --- a/iop/memorycard/mcman/src/mcsio2.c +++ b/iop/memorycard/mcman/src/mcsio2.c @@ -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); @@ -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 @@ -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 + if (p[3] == 0x66) { + //HAKAMA_SIGNALSEMA(); return sceMcResFailReplace; + } #endif - + //HAKAMA_SIGNALSEMA(); return sceMcResNoFormat; } @@ -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; @@ -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; @@ -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); @@ -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]; @@ -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; } @@ -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); @@ -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; } } @@ -862,6 +891,7 @@ int mcman_probePS2Card2(int port, int slot) return sceMcResNoFormat; #endif + HAKAMA_SIGNALSEMA(); return sceMcResFailDetect2; } @@ -874,21 +904,29 @@ 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; } } @@ -896,15 +934,31 @@ int mcman_probePS2Card(int port, int slot) //2 #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 {