2 Copyright 2009-2010, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review Open PS2 Loader README & LICENSE files for further details.
17 #include "modload_add.h"
21 #include "cdvdman_add.h"
24 #include <io_common.h>
25 #include "sio2man_imports.h"
30 #define DPRINTF(args...) sio_printf(args)
32 #define DPRINTF(args...) printf(args)
35 #define MODNAME "mcman"
38 // modInfo struct returned by xmcman exports 42
44 struct irx_export_table _exp_mcman
;
46 typedef struct _sceMcStDateTime
{
56 /* MCMAN public structure */
57 typedef struct _sceMcTblGetDir
{ //size = 64
58 sceMcStDateTime _Create
; // 0
59 sceMcStDateTime _Modify
; // 8
60 u32 FileSizeByte
; // 16
65 u8 EntryName
[32]; // 32
68 typedef struct _MCCacheEntry
{
78 typedef struct _MCCacheDir
{
86 #define CF_USE_ECC 0x01
87 #define CF_BAD_BLOCK 0x08
88 #define CF_ERASE_ZEROES 0x10
90 #define MCMAN_MAXSLOT 4
91 #define MCMAN_CLUSTERSIZE 1024
92 #define MCMAN_CLUSTERFATENTRIES 256
94 typedef struct _McFatCluster
{
95 int entry
[MCMAN_CLUSTERFATENTRIES
];
99 #define MAX_CACHEENTRY 0x24
100 u8 mcman_cachebuf
[MAX_CACHEENTRY
* MCMAN_CLUSTERSIZE
];
101 McCacheEntry mcman_entrycache
[MAX_CACHEENTRY
];
102 McCacheEntry
*mcman_mccache
[MAX_CACHEENTRY
];
104 McCacheEntry
*pmcman_entrycache
;
105 McCacheEntry
**pmcman_mccache
;
108 int entry
[1 + (MCMAN_CLUSTERFATENTRIES
* 2)];
111 McFatCache mcman_fatcache
[2][MCMAN_MAXSLOT
];
113 typedef struct { // size = 128
116 s16 linked_block
; // 8
120 sceMcStDateTime created
; // 32
124 sceMcStDateTime modified
; // 48
126 u8 unused2
[65]; // 60
132 typedef struct { // size = 512
136 sceMcStDateTime created
; // 8
139 sceMcStDateTime modified
; // 24
141 u32 unused2
[7]; // 36
143 u8 unused3
[416]; // 96
146 #define MAX_CACHEDIRENTRY 0x3
147 McFsEntry mcman_dircache
[MAX_CACHEDIRENTRY
];
149 int mcman_curdirmaxent
;
150 int mcman_curdirlength
;
151 char mcman_curdirpath
[1024];
152 char *mcman_curdirname
;
154 int mcman_PS1curcluster
;
155 u8 mcman_PS1curdir
[64];
157 typedef struct { // size = 48
169 u32 freeclink
; // 20 link to next free cluster
170 u32 clink
; // 24 link to next cluster
171 u32 clust_offset
;// 28
178 #define MAX_FDHANDLES 3
179 MC_FHANDLE mcman_fdhandles
[MAX_FDHANDLES
];
181 sceMcStDateTime mcman_fsmodtime
;
184 /* 05 */ int McDetectCard(int port
, int slot
);
185 /* 06 */ int McOpen(int port
, int slot
, char *filename
, int flags
);
186 /* 07 */ int McClose(int fd
);
187 /* 08 */ int McRead(int fd
, void *buf
, int length
);
188 /* 09 */ int McWrite(int fd
, void *buf
, int length
);
189 /* 10 */ int McSeek(int fd
, int offset
, int origin
);
190 /* 11 */ int McFormat(int port
, int slot
);
191 /* 12 */ int McGetDir(int port
, int slot
, char *dirname
, int flags
, int maxent
, sceMcTblGetDir
*info
);
192 /* 13 */ int McDelete(int port
, int slot
, char *filename
, int flags
);
193 /* 14 */ int McFlush(int fd
);
194 /* 15 */ int McChDir(int port
, int slot
, char *newdir
, char *currentdir
);
195 /* 16 */ int McSetFileInfo(int port
, int slot
, char *filename
, sceMcTblGetDir
*info
, int flags
);
196 /* 17 */ int McEraseBlock(int port
, int block
, void **pagebuf
, void *eccbuf
);
197 /* 18 */ int McReadPage(int port
, int slot
, int page
, void *buf
);
198 /* 19 */ int McWritePage(int port
, int slot
, int page
, void *pagebuf
, void *eccbuf
);
199 /* 20 */ void McDataChecksum(void *buf
, void *ecc
);
200 /* 29 */ int McReadPS1PDACard(int port
, int slot
, int page
, void *buf
);
201 /* 30 */ int McWritePS1PDACard(int port
, int slot
, int page
, void *buf
);
202 /* 36 */ int McUnformat(int port
, int slot
);
203 /* 37 */ int McRetOnly(int fd
);
204 /* 38 */ int McGetFreeClusters(int port
, int slot
);
205 /* 39 */ int McGetMcType(int port
, int slot
);
206 /* 40 */ void McSetPS1CardFlag(int flag
);
208 /* Available in XMCMAN only */
209 /* 17 */ int McEraseBlock2(int port
, int slot
, int block
, void **pagebuf
, void *eccbuf
);
210 /* 21 */ int McDetectCard2(int port
, int slot
);
211 /* 22 */ int McGetFormat(int port
, int slot
);
212 /* 23 */ int McGetEntSpace(int port
, int slot
, char *dirname
);
213 /* 24 */ int mcman_replacebadblock(void);
214 /* 25 */ int McCloseAll(void);
215 /* 42 */ struct modInfo_t
*McGetModuleInfo(void);
216 /* 43 */ int McGetCardSpec(int port
, int slot
, u16
*pagesize
, u16
*blocksize
, int *cardsize
, u8
*flags
);
217 /* 44 */ int mcman_getFATentry(int port
, int slot
, int fat_index
, int *fat_entry
);
218 /* 45 */ int McCheckBlock(int port
, int slot
, int block
);
219 /* 46 */ int mcman_setFATentry(int port
, int slot
, int fat_index
, int fat_entry
);
220 /* 47 */ int mcman_readdirentry(int port
, int slot
, int cluster
, int fsindex
, McFsEntry
**pfse
);
221 /* 48 */ void mcman_1stcacheEntsetwrflagoff(void);
224 // internal functions prototypes
225 int mcsio2_transfer(int port
, int slot
, sio2_transfer_data_t
*sio2data
);
226 int mcsio2_transfer2(int port
, int slot
, sio2_transfer_data_t
*sio2data
);
227 void long_multiply(u32 v1
, u32 v2
, u32
*HI
, u32
*LO
);
228 int mcman_chrpos(char *str
, int chr
);
229 void mcman_wmemset(void *buf
, int size
, int value
);
230 int mcman_calcEDC(void *buf
, int size
);
231 int mcman_checkpath(char *str
);
232 int mcman_checkdirpath(char *str1
, char *str2
);
233 void mcman_invhandles(int port
, int slot
);
234 int McCloseAll(void);
235 int mcman_detectcard(int port
, int slot
);
236 int mcman_dread(int fd
, fio_dirent_t
*dirent
);
237 int mcman_getstat(int port
, int slot
, char *filename
, fio_stat_t
*stat
);
238 int mcman_getmcrtime(sceMcStDateTime
*time
);
239 void mcman_initPS2com(void);
240 void sio2packet_add(int port
, int slot
, int cmd
, u8
*buf
);
241 int mcman_eraseblock(int port
, int slot
, int block
, void **pagebuf
, void *eccbuf
);
242 int mcman_readpage(int port
, int slot
, int page
, void *buf
, void *eccbuf
);
243 int mcman_cardchanged(int port
, int slot
);
244 int mcman_resetauth(int port
, int slot
);
245 int mcman_probePS2Card2(int port
, int slot
);
246 int mcman_probePS2Card(int port
, int slot
);
247 int secrman_mc_command(int port
, int slot
, sio2_transfer_data_t
*sio2data
);
248 int mcman_getcnum (int port
, int slot
);
249 int mcman_correctdata(void *buf
, void *ecc
);
250 int mcman_sparesize(int port
, int slot
);
251 int mcman_setdevspec(int port
, int slot
);
252 int mcman_reportBadBlocks(int port
, int slot
);
253 int mcman_setdevinfos(int port
, int slot
);
254 int mcman_format2(int port
, int slot
);
255 int mcman_createDirentry(int port
, int slot
, int parent_cluster
, int num_entries
, int cluster
, sceMcStDateTime
*ctime
);
256 int mcman_fatRseek(int fd
);
257 int mcman_fatWseek(int fd
);
258 int mcman_findfree2(int port
, int slot
, int reserve
);
259 int mcman_dread2(int fd
, fio_dirent_t
*dirent
);
260 int mcman_getstat2(int port
, int slot
, char *filename
, fio_stat_t
*stat
);
261 int mcman_setinfo2(int port
, int slot
, char *filename
, sceMcTblGetDir
*info
, int flags
);
262 int mcman_read2(int fd
, void *buffer
, int nbyte
);
263 int mcman_write2(int fd
, void *buffer
, int nbyte
);
264 int mcman_close2(int fd
);
265 int mcman_getentspace(int port
, int slot
, char *dirname
);
266 int mcman_cachedirentry(int port
, int slot
, char *filename
, McCacheDir
*pcacheDir
, McFsEntry
**pfse
, int unknown_flag
);
267 int mcman_getdirinfo(int port
, int slot
, McFsEntry
*pfse
, char *filename
, McCacheDir
*pcd
, int unknown_flag
);
268 int mcman_open2(int port
, int slot
, char *filename
, int flags
);
269 int mcman_chdir(int port
, int slot
, char *newdir
, char *currentdir
);
270 int mcman_writecluster(int port
, int slot
, int cluster
, int flag
);
271 int mcman_setdirentrystate(int port
, int slot
, int cluster
, int fsindex
, int flags
);
272 int mcman_getdir2(int port
, int slot
, char *dirname
, int flags
, int maxent
, sceMcTblGetDir
*info
);
273 int mcman_delete2(int port
, int slot
, char *filename
, int flags
);
274 int mcman_checkBackupBlocks(int port
, int slot
);
275 int mcman_unformat2(int port
, int slot
);
276 void mcman_initPS1PDAcom(void);
277 int mcman_probePS1Card2(int port
, int slot
);
278 int mcman_probePS1Card(int port
, int slot
);
279 int mcman_probePDACard(int port
, int slot
);
280 int mcman_setPS1devinfos(int port
, int slot
);
281 int mcman_format1(int port
, int slot
);
282 int mcman_open1(int port
, int slot
, char *filename
, int flags
);
283 int mcman_read1(int fd
, void *buffer
, int nbyte
);
284 int mcman_write1(int fd
, void *buffer
, int nbyte
);
285 int mcman_getPS1direntry(int port
, int slot
, char *filename
, McFsEntryPS1
**pfse
, int flag
);
286 int mcman_dread1(int fd
, fio_dirent_t
*dirent
);
287 int mcman_getstat1(int port
, int slot
, char *filename
, fio_stat_t
*stat
);
288 int mcman_setinfo1(int port
, int slot
, char *filename
, sceMcTblGetDir
*info
, int flags
);
289 int mcman_getdir1(int port
, int slot
, char *dirname
, int flags
, int maxent
, sceMcTblGetDir
*info
);
290 int mcman_clearPS1direntry(int port
, int slot
, int cluster
, int flags
);
291 int mcman_delete1(int port
, int slot
, char *filename
, int flags
);
292 int mcman_close1(int fd
);
293 int mcman_findfree1(int port
, int slot
, int reserve
);
294 int mcman_fatRseekPS1(int fd
);
295 int mcman_fatWseekPS1(int fd
);
296 int mcman_FNC8ca4(int port
, int slot
, MC_FHANDLE
*fh
);
297 int mcman_PS1pagetest(int port
, int slot
, int page
);
298 int mcman_unformat1(int port
, int slot
);
299 int mcman_cachePS1dirs(int port
, int slot
);
300 int mcman_fillPS1backuparea(int port
, int slot
, int block
);
301 void mcman_initcache(void);
302 int mcman_clearcache(int port
, int slot
);
303 McCacheEntry
*mcman_getcacheentry(int port
, int slot
, int cluster
);
304 void mcman_freecluster(int port
, int slot
, int cluster
);
305 int mcman_getFATindex(int port
, int slot
, int num
);
306 McCacheEntry
*mcman_get1stcacheEntp(void);
307 void mcman_addcacheentry(McCacheEntry
*mce
);
308 int mcman_flushmccache(int port
, int slot
);
309 int mcman_flushcacheentry(McCacheEntry
*mce
);
310 int mcman_readcluster(int port
, int slot
, int cluster
, McCacheEntry
**pmce
);
311 int mcman_readdirentryPS1(int port
, int slot
, int cluster
, McFsEntryPS1
**pfse
);
312 int mcman_readclusterPS1(int port
, int slot
, int cluster
, McCacheEntry
**pmce
);
313 int mcman_replaceBackupBlock(int port
, int slot
, int block
);
314 int mcman_fillbackupblock1(int port
, int slot
, int block
, void **pagedata
, void *eccdata
);
315 int mcman_clearsuperblock(int port
, int slot
);
316 int mcman_ioerrcode(int errcode
);
317 int mcman_modloadcb(char *filename
, int *unit
, u8
*arg3
); // used as callback by modload
318 void mcman_unit2card(u32 unit
);
319 int mcman_initdev(void);
322 // in addition to errno
325 // MCMAN basic error codes
326 #define sceMcResSucceed 0
327 #define sceMcResChangedCard -1
328 #define sceMcResNoFormat -2
329 #define sceMcResFullDevice -3
330 #define sceMcResNoEntry -4
331 #define sceMcResDeniedPermit -5
332 #define sceMcResNotEmpty -6
333 #define sceMcResUpLimitHandle -7
334 #define sceMcResFailReplace -8
335 #define sceMcResFailResetAuth -11
336 #define sceMcResFailDetect -12
337 #define sceMcResFailDetect2 -13
338 #define sceMcResDeniedPS1Permit -51
339 #define sceMcResFailAuth -90
342 // Memory Card device types
343 #define sceMcTypeNoCard 0
344 #define sceMcTypePS1 1
345 #define sceMcTypePS2 2
346 #define sceMcTypePDA 3
349 typedef struct { // size = 384
350 u8 magic
[28]; // Superblock magic, on PS2 MC : "Sony PS2 Memory Card Format "
351 u8 version
[12]; // Version number of the format used, 1.2 indicates full support for bad_block_list
352 s16 pagesize
; // size in bytes of a memory card page
353 u16 pages_per_cluster
; // number of pages in a cluster
354 u16 blocksize
; // number of pages in an erase block
355 u16 unused
; // unused
356 u32 clusters_per_card
; // total size in clusters of the memory card
357 u32 alloc_offset
; // Cluster offset of the first allocatable cluster. Cluster values in the FAT and directory entries are relative to this. This is the cluster immediately after the FAT
358 u32 alloc_end
; // The cluster after the highest allocatable cluster. Relative to alloc_offset. Not used
359 u32 rootdir_cluster
; // First cluster of the root directory. Relative to alloc_offset. Must be zero
360 u32 backup_block1
; // Erase block used as a backup area during programming. Normally the the last block on the card, it may have a different value if that block was found to be bad
361 u32 backup_block2
; // This block should be erased to all ones. Normally the the second last block on the card
363 u32 ifc_list
[32]; // List of indirect FAT clusters. On a standard 8M card there's only one indirect FAT cluster
364 int bad_block_list
[32]; // List of erase blocks that have errors and shouldn't be used
365 u8 cardtype
; // Memory card type. Must be 2, indicating that this is a PS2 memory card
366 u8 cardflags
; // Physical characteristics of the memory card
369 u32 FATentries_per_cluster
;
370 u32 clusters_per_block
;
372 u32 rootdir_cluster2
;
375 u32 max_allocatable_clusters
;
381 MCDevInfo mcman_devinfos
[4][MCMAN_MAXSLOT
];
384 /* High-Level File I/O */
385 #define SCE_CST_MODE 0x01
386 #define SCE_CST_ATTR 0x02
387 #define SCE_CST_SIZE 0x04
388 #define SCE_CST_CT 0x08
389 #define SCE_CST_AT 0x10
390 #define SCE_CST_MT 0x20
391 #define SCE_CST_PRVT 0x40
393 #define SCE_STM_R 0x01
394 #define SCE_STM_W 0x02
395 #define SCE_STM_X 0x04
396 #define SCE_STM_C 0x08
397 #define SCE_STM_F 0x10
398 #define SCE_STM_D 0x20
400 /* file attributes */
401 #define sceMcFileAttrReadable SCE_STM_R
402 #define sceMcFileAttrWriteable SCE_STM_W
403 #define sceMcFileAttrExecutable SCE_STM_X
404 #define sceMcFileAttrDupProhibit SCE_STM_C
405 #define sceMcFileAttrFile SCE_STM_F
406 #define sceMcFileAttrSubdir SCE_STM_D
407 #define sceMcFileCreateDir 0x0040
408 #define sceMcFileAttrClosed 0x0080
409 #define sceMcFileCreateFile 0x0200
410 #define sceMcFile0400 0x0400
411 #define sceMcFileAttrPDAExec 0x0800
412 #define sceMcFileAttrPS1 0x1000
413 #define sceMcFileAttrHidden 0x2000
414 #define sceMcFileAttrExists 0x8000
417 sio2_transfer_data_t mcman_sio2packet
; // buffer for mcman sio2 packet
418 u8 mcman_wdmabufs
[0x0b * 0x90]; // buffer array for SIO2 DMA I/O (write)
419 u8 mcman_rdmabufs
[0x0b * 0x90]; // not sure here for size, buffer array for SIO2 DMA I/O (read)
421 sio2_transfer_data_t mcman_sio2packet_PS1PDA
;
422 u8 mcman_sio2inbufs_PS1PDA
[0x90];
423 u8 mcman_sio2outbufs_PS1PDA
[0x90];
425 u8 mcman_pagebuf
[1056];
426 void *mcman_pagedata
[32];
427 u8 mcman_eccdata
[512]; // size for 32 ecc
429 u8 mcman_backupbuf
[16384];
431 u8 mcman_PS1PDApagebuf
[128];
433 u32 mcman_timercount
;
434 int mcman_timerthick
;
436 int mcman_badblock_port
;
437 int mcman_badblock_slot
;
439 int mcman_replacementcluster
[16];
441 int (*mcman_sio2transfer
)(int port
, int slot
, sio2_transfer_data_t
*sio2data
);
442 int (*mc_detectcard
)(int port
, int slot
);