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.
11 struct modInfo_t mcman_modInfo
= { "mcman_cex", 0x20b };
13 char sio2man_modname
[8] = "sio2man\0";
14 int sio2man_type
= SIO2MAN
;
16 char SUPERBLOCK_MAGIC
[] = "Sony PS2 Memory Card Format ";
17 char SUPERBLOCK_VERSION
[] = "1.2.0.0";
19 int mcman_wr_port
= -1;
20 int mcman_wr_slot
= -1;
21 int mcman_wr_block
= -1;
22 int mcman_wr_flag3
= -10;
23 int mcman_curdircluster
= -1;
26 u32 DOTDOT
= 0x00002e2e;
33 u8 mcman_xortable
[256] = {
34 0x00, 0x87, 0x96, 0x11, 0xA5, 0x22, 0x33, 0xB4,
35 0xB4, 0x33, 0x22, 0xA5, 0x11, 0x96, 0x87, 0x00,
36 0xC3, 0x44, 0x55, 0xD2, 0x66, 0xE1, 0xF0, 0x77,
37 0x77, 0xF0, 0xE1, 0x66, 0xD2, 0x55, 0x44, 0xC3,
38 0xD2, 0x55, 0x44, 0xC3, 0x77, 0xF0, 0xE1, 0x66,
39 0x66, 0xE1, 0xF0, 0x77, 0xC3, 0x44, 0x55, 0xD2,
40 0x11, 0x96, 0x87, 0x00, 0xB4, 0x33, 0x22, 0xA5,
41 0xA5, 0x22, 0x33, 0xB4, 0x00, 0x87, 0x96, 0x11,
42 0xE1, 0x66, 0x77, 0xF0, 0x44, 0xC3, 0xD2, 0x55,
43 0x55, 0xD2, 0xC3, 0x44, 0xF0, 0x77, 0x66, 0xE1,
44 0x22, 0xA5, 0xB4, 0x33, 0x87, 0x00, 0x11, 0x96,
45 0x96, 0x11, 0x00, 0x87, 0x33, 0xB4, 0xA5, 0x22,
46 0x33, 0xB4, 0xA5, 0x22, 0x96, 0x11, 0x00, 0x87,
47 0x87, 0x00, 0x11, 0x96, 0x22, 0xA5, 0xB4, 0x33,
48 0xF0, 0x77, 0x66, 0xE1, 0x55, 0xD2, 0xC3, 0x44,
49 0x44, 0xC3, 0xD2, 0x55, 0xE1, 0x66, 0x77, 0xF0,
50 0xF0, 0x77, 0x66, 0xE1, 0x55, 0xD2, 0xC3, 0x44,
51 0x44, 0xC3, 0xD2, 0x55, 0xE1, 0x66, 0x77, 0xF0,
52 0x33, 0xB4, 0xA5, 0x22, 0x96, 0x11, 0x00, 0x87,
53 0x87, 0x00, 0x11, 0x96, 0x22, 0xA5, 0xB4, 0x33,
54 0x22, 0xA5, 0xB4, 0x33, 0x87, 0x00, 0x11, 0x96,
55 0x96, 0x11, 0x00, 0x87, 0x33, 0xB4, 0xA5, 0x22,
56 0xE1, 0x66, 0x77, 0xF0, 0x44, 0xC3, 0xD2, 0x55,
57 0x55, 0xD2, 0xC3, 0x44, 0xF0, 0x77, 0x66, 0xE1,
58 0x11, 0x96, 0x87, 0x00, 0xB4, 0x33, 0x22, 0xA5,
59 0xA5, 0x22, 0x33, 0xB4, 0x00, 0x87, 0x96, 0x11,
60 0xD2, 0x55, 0x44, 0xC3, 0x77, 0xF0, 0xE1, 0x66,
61 0x66, 0xE1, 0xF0, 0x77, 0xC3, 0x44, 0x55, 0xD2,
62 0xC3, 0x44, 0x55, 0xD2, 0x66, 0xE1, 0xF0, 0x77,
63 0x77, 0xF0, 0xE1, 0x66, 0xD2, 0x55, 0x44, 0xC3,
64 0x00, 0x87, 0x96, 0x11, 0xA5, 0x22, 0x33, 0xB4,
65 0xB4, 0x33, 0x22, 0xA5, 0x11, 0x96, 0x87, 0x00
68 //--------------------------------------------------------------
69 void long_multiply(u32 v1
, u32 v2
, u32
*HI
, u32
*LO
)
71 register long a
, b
, c
, d
;
74 a
= (v1
>> 16) & 0xffff;
76 c
= (v2
>> 16) & 0xffff;
81 y
= ((*LO
>> 16) & 0xffff) + x
;
83 *LO
= (*LO
& 0xffff) | ((y
& 0xffff) << 16);
84 *HI
= (y
>> 16) & 0xffff;
89 //--------------------------------------------------------------
90 int mcman_chrpos(char *str
, int chr
)
97 if (*p
== (chr
& 0xff))
102 if (*p
!= (chr
& 0xff))
107 //--------------------------------------------------------------
108 int _start(int argc
, const char **argv
)
110 iop_library_table_t
*libtable
;
111 iop_library_t
*libptr
;
112 register int i
, sio2man_loaded
;
116 sio_init(38400, 0, 0, 0, 0);
119 DPRINTF("mcman: _start...\n");
122 // Get sio2man lib ptr
124 libtable
= GetLibraryEntryTable();
125 libptr
= libtable
->tail
;
126 while (libptr
!= 0) {
127 for (i
=0; i
<8; i
++) {
128 if (libptr
->name
[i
] != sio2man_modname
[i
])
135 libptr
= libptr
->prev
;
138 if (!sio2man_loaded
) {
140 DPRINTF("mcman: sio2man module is not loaded...\n");
142 return MODULE_NO_RESIDENT_END
;
146 DPRINTF("mcman: sio2man version=0x%03x\n", libptr
->version
);
148 if (libptr
->version
> 0x101)
149 sio2man_type
= XSIO2MAN
;
151 // Get sio2man export table
152 export_tab
= (void **)(((struct irx_export_table
*)libptr
)->fptrs
);
154 // Set functions pointers to match SIO2MAN exports
155 sio2_mc_transfer_init
= export_tab
[24];
156 sio2_transfer
= export_tab
[25];
157 // set internals function pointers for MCMAN
158 mcman_sio2transfer
= (void *)mcsio2_transfer
;
159 mc_detectcard
= (void *)McDetectCard2
;
161 if (sio2man_type
== XSIO2MAN
) {
162 // Set functions pointers to match XSIO2MAN exports
163 sio2_transfer_reset
= export_tab
[26];
164 sio2_func1
= export_tab
[55];
166 // set internals function pointers for XMCMAN
167 mcman_sio2transfer
= (void *)mcsio2_transfer2
;
168 mc_detectcard
= (void *)mcman_detectcard
;
170 // Modify mcman export ver
171 _exp_mcman
.version
= 0x203;
172 // Get mcman export table
173 export_tab
= (void **)(struct irx_export_table
*)&_exp_mcman
.fptrs
;
174 export_tab
[17] = (void *)McEraseBlock2
;
175 export_tab
[21] = (void *)McDetectCard2
;
176 export_tab
[22] = (void *)McGetFormat
;
177 export_tab
[23] = (void *)McGetEntSpace
;
178 export_tab
[24] = (void *)mcman_replacebadblock
;
179 export_tab
[25] = (void *)McCloseAll
;
180 export_tab
[42] = (void *)McGetModuleInfo
;
181 export_tab
[43] = (void *)McGetCardSpec
;
182 export_tab
[44] = (void *)mcman_getFATentry
;
183 export_tab
[45] = (void *)McCheckBlock
;
184 export_tab
[46] = (void *)mcman_setFATentry
;
185 export_tab
[47] = (void *)mcman_readdirentry
;
186 export_tab
[48] = (void *)mcman_1stcacheEntsetwrflagoff
;
187 export_tab
[49] = (void *)mcman_createDirentry
;
188 export_tab
[50] = (void *)mcman_readcluster
;
189 export_tab
[51] = (void *)mcman_flushmccache
;
190 export_tab
[52] = (void *)mcman_setdirentrystate
;
194 DPRINTF("mcman: registering exports...\n");
196 if (RegisterLibraryEntries(&_exp_mcman
) != 0)
197 return MODULE_NO_RESIDENT_END
;
202 DPRINTF("mcman: initPS2com...\n");
207 DPRINTF("mcman: initPS1PDAcom...\n");
209 mcman_initPS1PDAcom();
212 DPRINTF("mcman: initcache...\n");
217 DPRINTF("mcman: initdev...\n");
221 timer_ID
= ReferHardTimer(1, 32, 0, 0x6309);
223 if (timer_ID
!= -150)
224 return MODULE_RESIDENT_END
;
226 timer_ID
= AllocHardTimer(1, 32, 1);
229 SetTimerMode(timer_ID
, 0);
232 DPRINTF("mcman: _start returns MODULE_RESIDENT_END...\n");
235 return MODULE_RESIDENT_END
;
238 //--------------------------------------------------------------
239 int McGetFormat(int port
, int slot
) // Export #22 XMCMAN only
242 DPRINTF("mcman: McGetFormat port%d slot%d\n", port
, slot
);
244 return mcman_devinfos
[port
][slot
].cardform
;
247 //--------------------------------------------------------------
248 int McGetMcType(int port
, int slot
) // Export #39
251 DPRINTF("mcman: McGetMcType port%d slot%d\n", port
, slot
);
253 return mcman_devinfos
[port
][slot
].cardtype
;
256 //--------------------------------------------------------------
257 struct modInfo_t
*McGetModuleInfo(void) // Export #42 XMCMAN only
260 DPRINTF("mcman: McGetModuleInfo\n");
262 return (struct modInfo_t
*)&mcman_modInfo
;
265 //--------------------------------------------------------------
266 void McSetPS1CardFlag(int flag
) // Export #40
269 DPRINTF("mcman: McSetPS1CardFlag flag %x\n", flag
);
274 //--------------------------------------------------------------
275 int McGetFreeClusters(int port
, int slot
) // Export #38
277 register int r
, mcfree
;
278 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
281 DPRINTF("mcman: McGetFreeClusters port%d slot%d\n", port
, slot
);
285 if (mcdi
->cardform
) {
286 switch (mcdi
->cardtype
) {
288 mcfree
= mcman_findfree2(port
, slot
, 0);
292 mcfree
= mcman_findfree1(port
, slot
, 0);
294 case sceMcTypeNoCard
:
298 if (mcfree
== sceMcResFullDevice
)
309 //--------------------------------------------------------------
310 void mcman_wmemset(void *buf
, int size
, int value
)
313 size
= (size
>> 2) - 1;
318 } while (--size
> -1);
322 //--------------------------------------------------------------
323 int mcman_calcEDC(void *buf
, int size
)
325 register u32 checksum
;
334 while (size
-- != -1) {
339 return checksum
& 0xff;
342 //--------------------------------------------------------------
343 int mcman_checkpath(char *str
) // check that a string do not contain special chars ( chr<32, ?, *)
350 if (((p
[i
] & 0xff) == '?') || ((p
[i
] & 0xff) == '*'))
352 if ((p
[i
] & 0xff) < 32)
359 //--------------------------------------------------------------
360 int mcman_checkdirpath(char *str1
, char *str2
)
362 register int r
, pos1
, pos2
, pos
;
367 pos1
= mcman_chrpos(p2
, '?');
368 pos2
= mcman_chrpos(p2
, '*');
370 if ((pos1
< 0) && (pos2
< 0)) {
385 if (strncmp(p2
, p1
, pos
) != 0)
391 while (p2
[0] == '?') {
397 } while (p2
[0] != '*');
399 while((p2
[0] == '*') || (p2
[0] == '?'))
404 pos
= mcman_chrpos(p1
, (u8
)p2
[0]);
408 r
= mcman_checkdirpath(p1
, p2
);
415 //--------------------------------------------------------------
416 void mcman_invhandles(int port
, int slot
)
419 register MC_FHANDLE
*fh
= (MC_FHANDLE
*)&mcman_fdhandles
;
422 if ((fh
->port
== port
) && (fh
->slot
== slot
))
425 } while (++i
< MAX_FDHANDLES
);
428 //--------------------------------------------------------------
429 int McCloseAll(void) // Export #25 XMCMAN only
431 register int fd
= 0, rv
= 0;
434 if (mcman_fdhandles
[fd
].status
) {
443 } while (fd
< MAX_FDHANDLES
);
448 //--------------------------------------------------------------
449 int McDetectCard(int port
, int slot
) // Export #5
451 return mc_detectcard(port
, slot
);
454 //--------------------------------------------------------------
455 int mcman_detectcard(int port
, int slot
)
458 register MCDevInfo
*mcdi
;
461 DPRINTF("mcman: mcman_detectcard port%d slot%d\n", port
, slot
);
463 mcdi
= (MCDevInfo
*)&mcman_devinfos
[port
][slot
];
465 if ((mcdi
->cardtype
== sceMcTypeNoCard
) || (mcdi
->cardtype
== sceMcTypePS2
)) {
466 r
= mcman_probePS2Card2(port
, slot
);
468 r
= mcman_probePS1Card2(port
, slot
);
470 if (mcman_probePDACard(port
, slot
)) {
471 mcdi
->cardtype
= sceMcTypePS1
;
472 return (!PS1CardFlag
) ? sceMcResDeniedPS1Permit
: r
;
475 mcdi
->cardtype
= sceMcTypePDA
;
481 mcdi
->cardtype
= sceMcTypePS2
;
486 r
= mcman_probePS1Card2(port
, slot
);
488 if ((r
< -9) || (r
>= 0)) {
489 r
= mcman_probePS2Card2(port
, slot
);
491 mcdi
->cardtype
= sceMcTypePS2
;
496 if (mcman_probePDACard(port
, slot
)) {
497 mcdi
->cardtype
= sceMcTypePS1
;
498 return (!PS1CardFlag
) ? sceMcResDeniedPS1Permit
: r
;
501 mcdi
->cardtype
= sceMcTypePDA
;
508 return sceMcResSucceed
;
509 if (mcdi
->cardtype
== sceMcTypePS1
)
510 return sceMcResDeniedPS1Permit
;
511 return sceMcResSucceed
;
517 mcman_invhandles(port
, slot
);
518 mcman_clearcache(port
, slot
);
523 //--------------------------------------------------------------
524 int McDetectCard2(int port
, int slot
) // Export #21 XMCMAN only
527 register MCDevInfo
*mcdi
;
530 DPRINTF("mcman: McDetectCard2 port%d slot%d\n", port
, slot
);
533 mcdi
= (MCDevInfo
*)&mcman_devinfos
[port
][slot
];
535 if ((mcdi
->cardtype
== sceMcTypeNoCard
) || (mcdi
->cardtype
== sceMcTypePS2
)) {
536 r
= mcman_probePS2Card(port
, slot
);
538 r
= mcman_probePS1Card(port
, slot
);
540 if (mcman_probePDACard(port
, slot
)) {
541 mcdi
->cardtype
= sceMcTypePS1
;
542 return (!PS1CardFlag
) ? sceMcResDeniedPS1Permit
: r
;
545 mcdi
->cardtype
= sceMcTypePDA
;
551 mcdi
->cardtype
= sceMcTypePS2
;
556 r
= mcman_probePS1Card(port
, slot
);
558 if ((r
< -9) || (r
>= 0)) {
559 r
= mcman_probePS2Card(port
, slot
);
561 mcdi
->cardtype
= sceMcTypePS2
;
566 if (mcman_probePDACard(port
, slot
)) {
567 mcdi
->cardtype
= sceMcTypePS1
;
568 return (!PS1CardFlag
) ? sceMcResDeniedPS1Permit
: r
;
571 mcdi
->cardtype
= sceMcTypePDA
;
578 return sceMcResSucceed
;
579 if (mcdi
->cardtype
== sceMcTypePS1
)
580 return sceMcResDeniedPS1Permit
;
581 return sceMcResSucceed
;
587 mcman_invhandles(port
, slot
);
588 mcman_clearcache(port
, slot
);
593 //--------------------------------------------------------------
594 int McOpen(int port
, int slot
, char *filename
, int flag
) // Export #6
598 r
= McDetectCard(port
, slot
);
599 if (r
!= sceMcResSucceed
)
603 flag
&= 0xFFFFDFFF; // disables FRCOM flag OR what is it
605 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
606 r
= mcman_open2(port
, slot
, filename
, flag
);
608 r
= mcman_open1(port
, slot
, filename
, flag
);
611 mcman_invhandles(port
, slot
);
612 mcman_clearcache(port
, slot
);
618 //--------------------------------------------------------------
619 int McClose(int fd
) // Export #7
621 register MC_FHANDLE
*fh
;
622 register MCDevInfo
*mcdi
;
625 if (!((u32
)fd
< MAX_FDHANDLES
))
626 return sceMcResDeniedPermit
;
628 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
630 return sceMcResDeniedPermit
;
633 r
= McDetectCard(fh
->port
, fh
->slot
);
634 if (r
!= sceMcResSucceed
)
637 r
= mcman_flushmccache(fh
->port
, fh
->slot
);
639 mcman_invhandles(fh
->port
, fh
->slot
);
640 mcman_clearcache(fh
->port
, fh
->slot
);
643 if (r
!= sceMcResSucceed
)
646 if (fh
->unknown2
!= 0) {
648 mcdi
= (MCDevInfo
*)&mcman_devinfos
[fh
->port
][fh
->slot
];
649 if (mcdi
->cardtype
== sceMcTypePS2
)
650 r
= mcman_close2(fd
);
652 r
= mcman_close1(fd
);
655 mcman_invhandles(fh
->port
, fh
->slot
);
656 mcman_clearcache(fh
->port
, fh
->slot
);
659 if (r
!= sceMcResSucceed
)
663 r
= mcman_flushmccache(fh
->port
, fh
->slot
);
665 mcman_invhandles(fh
->port
, fh
->slot
);
666 mcman_clearcache(fh
->port
, fh
->slot
);
672 //--------------------------------------------------------------
673 int McFlush(int fd
) // Export #14
676 register MC_FHANDLE
*fh
;
677 register MCDevInfo
*mcdi
;
679 if (!((u32
)fd
< MAX_FDHANDLES
))
680 return sceMcResDeniedPermit
;
682 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
684 return sceMcResDeniedPermit
;
686 r
= McDetectCard(fh
->port
, fh
->slot
);
687 if (r
!= sceMcResSucceed
)
690 r
= mcman_flushmccache(fh
->port
, fh
->slot
);
692 mcman_invhandles(fh
->port
, fh
->slot
);
693 mcman_clearcache(fh
->port
, fh
->slot
);
696 if (r
!= sceMcResSucceed
) {
701 if (fh
->unknown2
!= 0) {
703 mcdi
= (MCDevInfo
*)&mcman_devinfos
[fh
->port
][fh
->slot
];
704 if (mcdi
->cardtype
== sceMcTypePS2
)
705 r
= mcman_close2(fd
);
707 r
= mcman_close1(fd
);
710 mcman_invhandles(fh
->port
, fh
->slot
);
711 mcman_clearcache(fh
->port
, fh
->slot
);
714 if (r
!= sceMcResSucceed
) {
720 r
= mcman_flushmccache(fh
->port
, fh
->slot
);
725 mcman_invhandles(fh
->port
, fh
->slot
);
726 mcman_clearcache(fh
->port
, fh
->slot
);
732 //--------------------------------------------------------------
733 int McSeek(int fd
, int offset
, int origin
) // Export #10
736 register MC_FHANDLE
*fh
;
739 DPRINTF("mcman: McSeek fd %d offset %d origin %d\n", fd
, offset
, origin
);
742 if (!((u32
)fd
< MAX_FDHANDLES
))
743 return sceMcResDeniedPermit
;
745 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
747 return sceMcResDeniedPermit
;
749 r
= McDetectCard(fh
->port
, fh
->slot
);
750 if (r
!= sceMcResSucceed
)
756 r
= fh
->position
+ offset
;
762 r
= fh
->filesize
+ offset
;
766 return fh
->position
= (r
< 0) ? 0 : r
;
769 //--------------------------------------------------------------
770 int McRead(int fd
, void *buf
, int length
) // Export #8
773 register MC_FHANDLE
*fh
;
775 if (!((u32
)fd
< MAX_FDHANDLES
))
776 return sceMcResDeniedPermit
;
778 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
780 return sceMcResDeniedPermit
;
783 return sceMcResDeniedPermit
;
785 r
= McDetectCard(fh
->port
, fh
->slot
);
786 if (r
!= sceMcResSucceed
)
789 if (mcman_devinfos
[fh
->port
][fh
->slot
].cardtype
== sceMcTypePS2
)
790 r
= mcman_read2(fd
, buf
, length
);
792 r
= mcman_read1(fd
, buf
, length
);
798 mcman_invhandles(fh
->port
, fh
->slot
);
799 mcman_clearcache(fh
->port
, fh
->slot
);
805 //--------------------------------------------------------------
806 int McWrite(int fd
, void *buf
, int length
) // Export #9
809 register MC_FHANDLE
*fh
;
811 if (!((u32
)fd
< MAX_FDHANDLES
))
812 return sceMcResDeniedPermit
;
814 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
816 return sceMcResDeniedPermit
;
819 return sceMcResDeniedPermit
;
821 r
= McDetectCard(fh
->port
, fh
->slot
);
822 if (r
!= sceMcResSucceed
)
825 if (mcman_devinfos
[fh
->port
][fh
->slot
].cardtype
== sceMcTypePS2
)
826 r
= mcman_write2(fd
, buf
, length
);
828 r
= mcman_write1(fd
, buf
, length
);
834 mcman_invhandles(fh
->port
, fh
->slot
);
835 mcman_clearcache(fh
->port
, fh
->slot
);
841 //--------------------------------------------------------------
842 int McGetEntSpace(int port
, int slot
, char *dirname
) // Export #23 XMCMAN only
846 r
= McDetectCard(port
, slot
);
847 if (r
!= sceMcResSucceed
)
850 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
) {
851 r
= mcman_getentspace(port
, slot
, dirname
);
855 mcman_invhandles(port
, slot
);
856 mcman_clearcache(port
, slot
);
862 //--------------------------------------------------------------
863 int McGetDir(int port
, int slot
, char *dirname
, int flags
, int maxent
, sceMcTblGetDir
*info
) // Export #12
867 r
= McDetectCard(port
, slot
);
868 if (r
!= sceMcResSucceed
)
871 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
872 r
= mcman_getdir2(port
, slot
, dirname
, flags
& 0xFFFF, maxent
, info
);
874 r
= mcman_getdir1(port
, slot
, dirname
, flags
& 0xFFFF, maxent
, info
);
877 mcman_invhandles(port
, slot
);
878 mcman_clearcache(port
, slot
);
884 //--------------------------------------------------------------
885 int mcman_dread(int fd
, fio_dirent_t
*dirent
)
888 register MC_FHANDLE
*fh
;
890 if (!((u32
)fd
< MAX_FDHANDLES
))
891 return sceMcResDeniedPermit
;
893 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
895 return sceMcResDeniedPermit
;
898 return sceMcResDeniedPermit
;
900 r
= McDetectCard(fh
->port
, fh
->slot
);
901 if (r
!= sceMcResSucceed
)
904 if (mcman_devinfos
[fh
->port
][fh
->slot
].cardtype
== sceMcTypePS2
)
905 r
= mcman_dread2(fd
, dirent
);
907 r
= mcman_dread1(fd
, dirent
);
913 mcman_invhandles(fh
->port
, fh
->slot
);
914 mcman_clearcache(fh
->port
, fh
->slot
);
920 //--------------------------------------------------------------
921 int mcman_getstat(int port
, int slot
, char *filename
, fio_stat_t
*stat
)
925 r
= McDetectCard(port
, slot
);
926 if (r
!= sceMcResSucceed
)
929 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
930 r
= mcman_getstat2(port
, slot
, filename
, stat
);
932 r
= mcman_getstat1(port
, slot
, filename
, stat
);
935 mcman_invhandles(port
, slot
);
936 mcman_clearcache(port
, slot
);
942 //--------------------------------------------------------------
943 int McSetFileInfo(int port
, int slot
, char *filename
, sceMcTblGetDir
*info
, int flags
) // Export #16
947 r
= McDetectCard(port
, slot
);
948 if (r
!= sceMcResSucceed
)
951 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
952 r
= mcman_setinfo2(port
, slot
, filename
, info
, flags
);
954 r
= mcman_setinfo1(port
, slot
, filename
, info
, flags
);
957 mcman_invhandles(port
, slot
);
958 mcman_clearcache(port
, slot
);
961 if (r
== sceMcResSucceed
) {
962 r
= mcman_flushmccache(port
, slot
);
964 mcman_invhandles(port
, slot
);
965 mcman_clearcache(port
, slot
);
972 //--------------------------------------------------------------
973 int McChDir(int port
, int slot
, char *newdir
, char *currentdir
) // Export #15
977 r
= McDetectCard(port
, slot
);
978 if (r
!= sceMcResSucceed
)
981 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
982 r
= mcman_chdir(port
, slot
, newdir
, currentdir
);
989 mcman_invhandles(port
, slot
);
990 mcman_clearcache(port
, slot
);
996 //--------------------------------------------------------------
997 int McDelete(int port
, int slot
, char *filename
, int flags
) // Export #13
1001 r
= McDetectCard(port
, slot
);
1002 if (r
!= sceMcResSucceed
)
1005 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
1006 r
= mcman_delete2(port
, slot
, filename
, flags
);
1008 r
= mcman_delete1(port
, slot
, filename
, flags
);
1011 mcman_invhandles(port
, slot
);
1012 mcman_clearcache(port
, slot
);
1018 //--------------------------------------------------------------
1019 int McFormat(int port
, int slot
) // Export #11
1023 mcman_invhandles(port
, slot
);
1025 r
= McDetectCard(port
, slot
);
1029 mcman_clearcache(port
, slot
);
1031 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
1032 r
= mcman_format2(port
, slot
);
1034 r
= mcman_format1(port
, slot
);
1037 mcman_invhandles(port
, slot
);
1038 mcman_clearcache(port
, slot
);
1044 //--------------------------------------------------------------
1045 int McUnformat(int port
, int slot
) // Export #36
1049 mcman_invhandles(port
, slot
);
1051 r
= McDetectCard(port
, slot
);
1055 mcman_clearcache(port
, slot
);
1057 if (mcman_devinfos
[port
][slot
].cardtype
== sceMcTypePS2
)
1058 r
= mcman_unformat2(port
, slot
);
1060 r
= mcman_unformat1(port
, slot
);
1062 mcman_devinfos
[port
][slot
].cardform
= 0;
1065 mcman_invhandles(port
, slot
);
1066 mcman_clearcache(port
, slot
);
1072 //--------------------------------------------------------------
1073 int mcman_getmcrtime(sceMcStDateTime
*time
)
1075 register int retries
;
1081 if (sceCdRC(&cdtime
))
1083 } while (--retries
> 0);
1085 if (cdtime
.stat
& 128) {
1086 *((u16
*)&cdtime
.month
) = 0x7d0;
1096 time
->Sec
= ((((cdtime
.second
>> 4) << 2) + (cdtime
.second
>> 4)) << 1) + (cdtime
.second
& 0xf);
1097 time
->Min
= ((((cdtime
.minute
>> 4) << 2) + (cdtime
.minute
>> 4)) << 1) + (cdtime
.minute
& 0xf);
1098 time
->Hour
= ((((cdtime
.hour
>> 4) << 2) + (cdtime
.hour
>> 4)) << 1) + (cdtime
.hour
& 0xf);
1099 time
->Day
= ((((cdtime
.day
>> 4) << 2) + (cdtime
.day
>> 4)) << 1) + (cdtime
.day
& 0xf);
1101 if ((cdtime
.month
& 0x10) != 0)
1102 time
->Month
= (cdtime
.month
& 0xf) + 0xa;
1104 time
->Month
= cdtime
.month
& 0xf;
1106 time
->Year
= ((((cdtime
.year
>> 4) << 2) + (cdtime
.year
>> 4)) << 1) + ((cdtime
.year
& 0xf) | 0x7d0);
1111 //--------------------------------------------------------------
1112 int McEraseBlock(int port
, int block
, void **pagebuf
, void *eccbuf
) // Export #17 in MCMAN
1114 return mcman_eraseblock(port
, 0, block
, (void **)pagebuf
, eccbuf
);
1117 //--------------------------------------------------------------
1118 int McEraseBlock2(int port
, int slot
, int block
, void **pagebuf
, void *eccbuf
) // Export #17 in XMCMAN
1120 return mcman_eraseblock(port
, slot
, block
, (void **)pagebuf
, eccbuf
);
1123 //--------------------------------------------------------------
1124 int McReadPage(int port
, int slot
, int page
, void *buf
) // Export #18
1126 register int r
, index
, ecres
, retries
, count
, erase_byte
;
1127 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1131 count
= (mcdi
->pagesize
+ 127) >> 7;
1132 erase_byte
= (mcdi
->cardflags
& CF_ERASE_ZEROES
) ? 0x0 : 0xFF;
1135 ecres
= sceMcResSucceed
;
1137 if (!mcman_readpage(port
, slot
, page
, buf
, eccbuf
)) {
1138 if (mcdi
->cardflags
& CF_USE_ECC
) { // checking ECC from spare data block
1139 // check for erased page (last byte of spare data set to 0xFF or 0x0)/
1140 if (eccbuf
[mcman_sparesize(port
, slot
) - 1] == erase_byte
)
1146 peccb
= (u8
*)eccbuf
;
1150 r
= mcman_correctdata(pdata
, peccb
);
1156 } while (++index
< count
);
1159 if (ecres
== sceMcResSucceed
)
1162 if ((retries
== 4) && (!(ecres
< sceMcResNoFormat
)))
1166 } while (++retries
< 5);
1169 return sceMcResSucceed
;
1171 return (ecres
!= sceMcResSucceed
) ? sceMcResNoFormat
: sceMcResChangedCard
;
1174 //--------------------------------------------------------------
1175 void McDataChecksum(void *buf
, void *ecc
) // Export #20
1177 register u8
*p
, *p_ecc
;
1178 register int i
, a2
, a3
, v
, t0
;
1187 v
= mcman_xortable
[*p
++];
1193 } while (++i
< 0x80);
1196 p_ecc
[0] = ~a2
& 0x77;
1197 p_ecc
[1] = ~a3
& 0x7F;
1198 p_ecc
[2] = ~t0
& 0x7F;
1201 //--------------------------------------------------------------
1202 int mcman_getcnum(int port
, int slot
)
1204 return ((port
& 1) << 3) + slot
;
1207 //--------------------------------------------------------------
1208 int mcman_correctdata(void *buf
, void *ecc
)
1210 register int xor0
, xor1
, xor2
, xor3
, xor4
;
1214 McDataChecksum(buf
, eccbuf
);
1216 xor0
= p
[0] ^ eccbuf
[0];
1217 xor1
= p
[1] ^ eccbuf
[1];
1218 xor2
= p
[2] ^ eccbuf
[2];
1221 xor4
= (xor0
& 0xf) ^ (xor0
>> 4);
1223 if (!xor0
&& !xor1
&& !xor2
)
1226 if ((xor3
== 0x7f) && (xor4
== 0x7)) {
1227 p
[xor2
] ^= 1 << (xor0
>> 4);
1238 } while (xor2
>= 0);
1246 } while (xor2
>= 0);
1254 //--------------------------------------------------------------
1255 int mcman_sparesize(int port
, int slot
)
1256 { // Get ps2 mc spare size by dividing pagesize / 32
1257 return (mcman_devinfos
[port
][slot
].pagesize
+ 0x1F) >> 5;
1260 //--------------------------------------------------------------
1261 int mcman_setdevspec(int port
, int slot
)
1264 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1267 DPRINTF("mcman: mcman_setdevspec port%d, slot%d\n", port
, slot
);
1270 if (McGetCardSpec(port
, slot
, &mcdi
->pagesize
, &mcdi
->blocksize
, &cardsize
, &mcdi
->cardflags
) != sceMcResSucceed
)
1271 return sceMcResFullDevice
;
1273 mcdi
->pages_per_cluster
= MCMAN_CLUSTERSIZE
/ mcdi
->pagesize
;
1274 mcdi
->cluster_size
= MCMAN_CLUSTERSIZE
;
1277 mcdi
->unused
= 0xff00;
1278 mcdi
->FATentries_per_cluster
= MCMAN_CLUSTERFATENTRIES
;
1279 mcdi
->unknown5
= -1;
1280 mcdi
->rootdir_cluster2
= mcdi
->rootdir_cluster
;
1281 mcdi
->clusters_per_block
= mcdi
->blocksize
/ mcdi
->pages_per_cluster
;
1282 mcdi
->clusters_per_card
= (cardsize
/ mcdi
->blocksize
) * (mcdi
->blocksize
/ mcdi
->pages_per_cluster
);
1284 return sceMcResSucceed
;
1287 //--------------------------------------------------------------
1288 int mcman_setdevinfos(int port
, int slot
)
1290 register int r
, allocatable_clusters_per_card
, iscluster_valid
, current_allocatable_cluster
, cluster_cnt
;
1291 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1295 DPRINTF("mcman: mcman_setdevinfos port%d slot%d\n", port
, slot
);
1298 mcman_wmemset((void *)mcdi
, sizeof(MCDevInfo
), 0);
1300 r
= mcman_setdevspec(port
, slot
);
1301 if (r
!= sceMcResSucceed
)
1304 r
= McReadPage(port
, slot
, 0, mcman_pagebuf
);
1305 if (r
== sceMcResNoFormat
)
1306 return sceMcResNoFormat
; // should rebuild a valid superblock here
1307 if (r
!= sceMcResSucceed
)
1310 if (strncmp(SUPERBLOCK_MAGIC
, mcman_pagebuf
, 28) != 0) {
1312 DPRINTF("mcman: mcman_setdevinfos No card format !!!\n");
1314 return sceMcResNoFormat
;
1317 if (((mcman_pagebuf
[28] - 48) == 1) && ((mcman_pagebuf
[30] - 48) == 0)) // check ver major & minor
1318 return sceMcResNoFormat
;
1321 for (r
=0; r
<0x150; r
++)
1322 p
[r
] = mcman_pagebuf
[r
];
1324 mcdi
->cardtype
= sceMcTypePS2
; // <--
1326 r
= mcman_checkBackupBlocks(port
, slot
);
1327 if (r
!= sceMcResSucceed
)
1330 r
= mcman_readdirentry(port
, slot
, 0, 0, &pfse
);
1331 if (r
!= sceMcResSucceed
)
1332 return sceMcResNoFormat
; // -46
1334 if (strcmp(pfse
->name
, ".") != 0)
1335 return sceMcResNoFormat
;
1337 if (mcman_readdirentry(port
, slot
, 0, 1, &pfse
) != sceMcResSucceed
)
1340 if (strcmp(pfse
->name
, "..") != 0)
1341 return sceMcResNoFormat
;
1344 // mcdi->cardtype = sceMcTypePS2;
1346 if (((mcman_pagebuf
[28] - 48) == 1) && ((mcman_pagebuf
[30] - 48) == 1)) { // check ver major & minor
1347 if ((mcdi
->clusters_per_block
* mcdi
->backup_block2
) == mcdi
->alloc_end
)
1348 mcdi
->alloc_end
= (mcdi
->clusters_per_block
* mcdi
->backup_block2
) - mcdi
->alloc_offset
;
1353 long_multiply(mcdi
->clusters_per_card
, 0x10624dd3, &hi
, &lo
);
1354 temp
= (hi
>> 6) - (mcdi
->clusters_per_card
>> 31);
1355 allocatable_clusters_per_card
= (((((temp
<< 5) - temp
) << 2) + temp
) << 3) + 1;
1356 iscluster_valid
= 0;
1358 current_allocatable_cluster
= mcdi
->alloc_offset
;
1360 while (cluster_cnt
< allocatable_clusters_per_card
) {
1361 if (current_allocatable_cluster
>= mcdi
->clusters_per_card
)
1364 if (((current_allocatable_cluster
% mcdi
->clusters_per_block
) == 0) \
1365 || (mcdi
->alloc_offset
== current_allocatable_cluster
)) {
1366 iscluster_valid
= 1;
1367 for (r
=0; r
<16; r
++) {
1368 if ((current_allocatable_cluster
/ mcdi
->clusters_per_block
) == mcdi
->bad_block_list
[r
])
1369 iscluster_valid
= 0;
1372 if (iscluster_valid
== 1)
1374 current_allocatable_cluster
++;
1377 mcdi
->max_allocatable_clusters
= current_allocatable_cluster
- mcdi
->alloc_offset
;
1379 return sceMcResSucceed
;
1382 //--------------------------------------------------------------
1383 int mcman_reportBadBlocks(int port
, int slot
)
1385 register int r
, i
, block
, bad_blocks
, page
, erase_byte
, err_cnt
, err_limit
;
1386 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1390 DPRINTF("mcman: mcman_reportBadBlocks port%d, slot%d\n", port
, slot
);
1393 mcman_wmemset((void *)mcdi
->bad_block_list
, 128, -1);
1395 if ((mcdi
->cardflags
& CF_BAD_BLOCK
) == 0)
1396 return sceMcResSucceed
;
1398 err_limit
= (((mcdi
->pagesize
<< 16) >> 16) + ((mcdi
->pagesize
<< 16) >> 31)) >> 1; //s7
1401 if ((mcdi
->cardflags
& CF_ERASE_ZEROES
) != 0)
1404 bad_blocks
= 0; // s2
1406 if ((mcdi
->clusters_per_card
/ mcdi
->clusters_per_block
) > 0) {
1411 if (bad_blocks
>= 16)
1418 r
= McReadPage(port
, slot
, (block
* mcdi
->blocksize
) + page
, mcman_pagebuf
);
1419 if (r
== sceMcResNoFormat
) {
1420 mcdi
->bad_block_list
[bad_blocks
] = block
;
1424 if (r
!= sceMcResSucceed
)
1427 if ((mcdi
->cardflags
& CF_USE_ECC
) == 0) {
1428 p
= (u8
*)&mcman_pagebuf
;
1429 for (i
= 0; i
< mcdi
->pagesize
; i
++) {
1430 // check if the content of page is clean
1431 if (*p
++ != erase_byte
)
1434 if (err_cnt
>= err_limit
) {
1435 mcdi
->bad_block_list
[bad_blocks
] = block
;
1441 } while (++page
< 2);
1443 } while (++block
< (mcdi
->clusters_per_card
/ mcdi
->clusters_per_block
));
1446 return sceMcResSucceed
;
1449 //--------------------------------------------------------------
1450 int mcman_createDirentry(int port
, int slot
, int parent_cluster
, int num_entries
, int cluster
, sceMcStDateTime
*ctime
)
1454 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1455 McFsEntry
*mfe
, *mfe_next
, *pfse
;
1458 DPRINTF("mcman: mcman_createDirentry port%d slot%d parent_cluster %x num_entries %d cluster %x\n", port
, slot
, parent_cluster
, num_entries
, cluster
);
1461 r
= mcman_readcluster(port
, slot
, mcdi
->alloc_offset
+ cluster
, &mce
);
1462 if (r
!= sceMcResSucceed
)
1465 mcman_wmemset(mce
->cl_data
, MCMAN_CLUSTERSIZE
, 0);
1467 mfe
= (McFsEntry
*)mce
->cl_data
;
1468 mfe_next
= (McFsEntry
*)(mce
->cl_data
+ sizeof (McFsEntry
));
1470 mfe
->mode
= sceMcFileAttrReadable
| sceMcFileAttrWriteable
| sceMcFileAttrExecutable \
1471 | sceMcFileAttrSubdir
| sceMcFile0400
| sceMcFileAttrExists
; // 0x8427
1474 mcman_getmcrtime(&mfe
->created
);
1476 mfe
->created
= *ctime
;
1478 mfe
->modified
= mfe
->created
;
1481 mfe
->dir_entry
= num_entries
;
1482 mfe
->cluster
= parent_cluster
;
1483 *(u16
*)&mfe
->name
= *((u16
*)&DOT
);
1485 if ((parent_cluster
== 0) && (num_entries
== 0)) {
1486 // entry is root directory
1487 mfe_next
->created
= mfe
->created
;
1491 mfe
->mode
= sceMcFileAttrWriteable
| sceMcFileAttrExecutable
| sceMcFileAttrSubdir \
1492 | sceMcFile0400
| sceMcFileAttrExists
| sceMcFileAttrHidden
; // 0xa426
1497 // entry is normal "." / ".."
1498 mcman_readdirentry(port
, slot
, parent_cluster
, 0, &pfse
);
1500 mfe_next
->created
= pfse
->created
;
1503 mfe
->mode
= sceMcFileAttrReadable
| sceMcFileAttrWriteable
| sceMcFileAttrExecutable \
1504 | sceMcFileAttrSubdir
| sceMcFile0400
| sceMcFileAttrExists
; // 0x8427
1505 mfe
->dir_entry
= pfse
->dir_entry
;
1507 mfe
->cluster
= pfse
->cluster
;
1510 mfe
->modified
= mfe
->created
;
1513 *(u16
*)&mfe
->name
= *(u16
*)&DOTDOT
;
1514 *(u8
*)&mfe
->name
[2] = *((u8
*)&DOTDOT
+2);
1518 return sceMcResSucceed
;
1521 //--------------------------------------------------------------
1522 int mcman_fatRseek(int fd
)
1524 register int r
, entries_to_read
, fat_index
;
1525 register MC_FHANDLE
*fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
]; //s1
1526 register MCDevInfo
*mcdi
= &mcman_devinfos
[fh
->port
][fh
->slot
]; //s2
1529 entries_to_read
= fh
->position
/ mcdi
->cluster_size
; //s0
1533 if (entries_to_read
< fh
->clust_offset
) //v1 = fh->fh->clust_offset
1534 fat_index
= fh
->freeclink
;
1536 fat_index
= fh
->clink
; // a2
1537 entries_to_read
-= fh
->clust_offset
;
1540 if (entries_to_read
== 0) {
1542 return fat_index
+ mcdi
->alloc_offset
;
1544 return sceMcResFullDevice
;
1548 r
= mcman_getFATentry(fh
->port
, fh
->slot
, fat_index
, &fat_entry
);
1549 if (r
!= sceMcResSucceed
)
1552 fat_index
= fat_entry
;
1554 if (fat_index
>= -1)
1555 return sceMcResFullDevice
;
1559 fat_index
&= 0x7fffffff;
1560 fh
->clink
= fat_index
;
1561 fh
->clust_offset
= (fh
->position
/ mcdi
->cluster_size
) - entries_to_read
;
1563 } while (entries_to_read
> 0);
1565 return fat_index
+ mcdi
->alloc_offset
;
1568 //--------------------------------------------------------------
1569 int mcman_fatWseek(int fd
) // modify FAT to hold new content for a file
1571 register int r
, entries_to_write
, fat_index
;
1572 register MC_FHANDLE
*fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
1573 register MCDevInfo
*mcdi
= &mcman_devinfos
[fh
->port
][fh
->slot
];
1574 register McCacheEntry
*mce
;
1577 entries_to_write
= fh
->position
/ mcdi
->cluster_size
;
1579 if ((fh
->clust_offset
== 0) || (entries_to_write
< fh
->clust_offset
)) {
1580 fat_index
= fh
->freeclink
;
1582 if (fat_index
< 0) {
1583 fat_index
= mcman_findfree2(fh
->port
, fh
->slot
, 1);
1586 return sceMcResFullDevice
;
1588 mce
= (McCacheEntry
*)mcman_get1stcacheEntp();
1589 fh
->freeclink
= fat_index
;
1591 r
= mcman_close2(fd
);
1592 if (r
!= sceMcResSucceed
)
1595 mcman_addcacheentry(mce
);
1596 mcman_flushmccache(fh
->port
, fh
->slot
);
1600 fat_index
= fh
->clink
;
1601 entries_to_write
-= fh
->clust_offset
;
1604 if (entries_to_write
!= 0) {
1606 r
= mcman_getFATentry(fh
->port
, fh
->slot
, fat_index
, &fat_entry
);
1607 if (r
!= sceMcResSucceed
)
1610 if (fat_entry
>= 0xffffffff) {
1611 r
= mcman_findfree2(fh
->port
, fh
->slot
, 1);
1615 fat_entry
|= 0x80000000;
1617 mce
= (McCacheEntry
*)mcman_get1stcacheEntp();
1619 r
= mcman_setFATentry(fh
->port
, fh
->slot
, fat_index
, fat_entry
);
1620 if (r
!= sceMcResSucceed
)
1623 mcman_addcacheentry(mce
);
1627 fat_index
= fat_entry
& 0x7fffffff;
1628 } while (entries_to_write
> 0);
1631 fh
->clink
= fat_index
;
1632 fh
->clust_offset
= fh
->position
/ mcdi
->cluster_size
;
1634 return sceMcResSucceed
;
1637 //--------------------------------------------------------------
1638 int mcman_findfree2(int port
, int slot
, int reserve
)
1640 register int r
, rfree
, indirect_index
, ifc_index
, fat_offset
, indirect_offset
, fat_index
, block
;
1641 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1642 McCacheEntry
*mce1
, *mce2
;
1645 DPRINTF("mcman: mcman_findfree2 port%d slot%d reserve%d\n", port
, slot
, reserve
);
1648 fat_index
= mcdi
->unknown2
;
1651 for (fat_index
= mcdi
->unknown2
; fat_index
< mcdi
->max_allocatable_clusters
; fat_index
++) {
1653 indirect_index
= fat_index
/ mcdi
->FATentries_per_cluster
;
1654 fat_offset
= fat_index
% mcdi
->FATentries_per_cluster
;
1656 if ((fat_offset
== 0) || (fat_index
== mcdi
->unknown2
)) {
1658 ifc_index
= indirect_index
/ mcdi
->FATentries_per_cluster
;
1659 r
= mcman_readcluster(port
, slot
, mcdi
->ifc_list
[ifc_index
], &mce1
);
1660 if (r
!= sceMcResSucceed
)
1663 //if ((fat_offset == 0) || (fat_index == mcdi->unknown2)) {
1664 indirect_offset
= indirect_index
% mcdi
->FATentries_per_cluster
;
1665 McFatCluster
*fc
= (McFatCluster
*)mce1
->cl_data
;
1666 r
= mcman_readcluster(port
, slot
, fc
->entry
[indirect_offset
], &mce2
);
1667 if (r
!= sceMcResSucceed
)
1671 McFatCluster
*fc
= (McFatCluster
*)mce2
->cl_data
;
1673 if (fc
->entry
[fat_offset
] >= 0) {
1674 block
= (mcdi
->alloc_offset
+ fat_offset
) / mcdi
->clusters_per_block
;
1675 if (block
!= mcman_badblock
) {
1677 fc
->entry
[fat_offset
] = 0xffffffff;
1679 mcdi
->unknown2
= fat_index
;
1688 return sceMcResFullDevice
;
1690 return (rfree
) ? rfree
: sceMcResFullDevice
;
1693 //--------------------------------------------------------------
1694 int mcman_getentspace(int port
, int slot
, char *dirname
)
1696 register int r
, i
, entspace
;
1697 McCacheDir cacheDir
;
1700 u8
*pfsentry
, *pmfe
, *pfseend
;
1703 DPRINTF("mcman: mcman_getentspace port%d slot%d dirname %s\n", port
, slot
, dirname
);
1706 r
= mcman_cachedirentry(port
, slot
, dirname
, &cacheDir
, &fse
, 1);
1708 return sceMcResNoEntry
;
1712 pfsentry
= (u8
*)fse
;
1714 pfseend
= (u8
*)(pfsentry
+ sizeof (McFsEntry
));
1717 *((u32
*)pmfe
) = *((u32
*)pfsentry
);
1718 *((u32
*)pmfe
+1) = *((u32
*)pfsentry
+1);
1719 *((u32
*)pmfe
+2) = *((u32
*)pfsentry
+2);
1720 *((u32
*)pmfe
+3) = *((u32
*)pfsentry
+3);
1723 } while (pfsentry
< pfseend
);
1725 entspace
= mfe
.length
& 1;
1727 for (i
= 0; i
< mfe
.length
; i
++) {
1729 r
= mcman_readdirentry(port
, slot
, mfe
.cluster
, i
, &fse
);
1730 if (r
!= sceMcResSucceed
)
1732 if ((fse
->mode
& sceMcFileAttrExists
) == 0)
1739 //--------------------------------------------------------------
1740 int mcman_cachedirentry(int port
, int slot
, char *filename
, McCacheDir
*pcacheDir
, McFsEntry
**pfse
, int unknown_flag
)
1742 register int r
, fsindex
, cluster
, fmode
;
1743 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
1745 McCacheDir cacheDir
;
1746 u8
*p
, *pfsentry
, *pcache
, *pfseend
;
1749 DPRINTF("mcman: mcman_cachedirentry port%d slot%d name %s\n", port
, slot
, filename
);
1752 if (pcacheDir
== NULL
) {
1753 pcacheDir
= &cacheDir
;
1754 pcacheDir
->maxent
= -1;
1764 cluster
= mcdi
->rootdir_cluster2
;
1765 fsindex
= mcdi
->unknown1
;
1768 r
= mcman_readdirentry(port
, slot
, cluster
, fsindex
, &fse
);
1769 if (r
!= sceMcResSucceed
)
1773 if (!(fse
->mode
& sceMcFileAttrExists
))
1776 if (pcacheDir
== NULL
) {
1777 *pfse
= (McFsEntry
*)fse
;
1778 return sceMcResSucceed
;
1781 pfsentry
= (u8
*)fse
;
1782 pcache
= (u8
*)&mcman_dircache
[0];
1783 pfseend
= (u8
*)(pfsentry
+ sizeof (McFsEntry
));
1786 *((u32
*)pcache
) = *((u32
*)pfsentry
);
1787 *((u32
*)pcache
+1) = *((u32
*)pfsentry
+1);
1788 *((u32
*)pcache
+2) = *((u32
*)pfsentry
+2);
1789 *((u32
*)pcache
+3) = *((u32
*)pfsentry
+3);
1792 } while (pfsentry
< pfseend
);
1794 r
= mcman_getdirinfo(port
, slot
, (McFsEntry
*)&mcman_dircache
[0], ".", pcacheDir
, unknown_flag
);
1796 mcman_readdirentry(port
, slot
, pcacheDir
->cluster
, pcacheDir
->fsindex
, pfse
);
1806 fmode
= sceMcFileAttrReadable
| sceMcFileAttrExecutable
;
1807 if ((fse
->mode
& fmode
) != fmode
)
1808 return sceMcResDeniedPermit
;
1810 if (mcman_chrpos(p
, '/') < 0)
1813 pfsentry
= (u8
*)fse
;
1814 pcache
= (u8
*)&mcman_dircache
[0];
1815 pfseend
= (u8
*)(pfsentry
+ sizeof(McFsEntry
));
1818 *((u32
*)pcache
) = *((u32
*)pfsentry
);
1819 *((u32
*)pcache
+1) = *((u32
*)pfsentry
+1);
1820 *((u32
*)pcache
+2) = *((u32
*)pfsentry
+2);
1821 *((u32
*)pcache
+3) = *((u32
*)pfsentry
+3);
1824 } while (pfsentry
< pfseend
);
1826 r
= mcman_getdirinfo(port
, slot
, (McFsEntry
*)&mcman_dircache
[0], p
, pcacheDir
, unknown_flag
);
1829 if (mcman_chrpos(p
, '/') >= 0)
1832 pcacheDir
->cluster
= cluster
;
1833 pcacheDir
->fsindex
= fsindex
;
1838 r
= mcman_chrpos(p
, '/');
1839 if ((r
>= 0) && (p
[r
+ 1] != 0)) {
1840 p
+= mcman_chrpos(p
, '/') + 1;
1841 cluster
= pcacheDir
->cluster
;
1842 fsindex
= pcacheDir
->fsindex
;
1844 mcman_readdirentry(port
, slot
, cluster
, fsindex
, &fse
);
1847 mcman_readdirentry(port
, slot
, pcacheDir
->cluster
, pcacheDir
->fsindex
, pfse
);
1849 return sceMcResSucceed
;
1853 return sceMcResSucceed
;
1856 //--------------------------------------------------------------
1857 int mcman_getdirinfo(int port
, int slot
, McFsEntry
*pfse
, char *filename
, McCacheDir
*pcd
, int unknown_flag
)
1859 register int i
, r
, ret
, len
, pos
;
1861 u8
*pfsentry
, *pfsee
, *pfseend
;
1864 DPRINTF("mcman: mcman_getdirinfo port%d slot%d name %s\n", port
, slot
, filename
);
1867 pos
= mcman_chrpos(filename
, '/');
1869 pos
= strlen(filename
);
1872 if ((pos
== 2) && (!strncmp(filename
, "..", 2))) {
1874 r
= mcman_readdirentry(port
, slot
, pfse
->cluster
, 0, &fse
);
1875 if (r
!= sceMcResSucceed
)
1878 r
= mcman_readdirentry(port
, slot
, fse
->cluster
, 0, &fse
);
1879 if (r
!= sceMcResSucceed
)
1883 pcd
->cluster
= fse
->cluster
;
1884 pcd
->fsindex
= fse
->dir_entry
;
1887 r
= mcman_readdirentry(port
, slot
, fse
->cluster
, fse
->dir_entry
, &fse
);
1888 if (r
!= sceMcResSucceed
)
1891 pfsentry
= (u8
*)fse
;
1893 pfseend
= (u8
*)(pfsentry
+ sizeof(McFsEntry
));
1896 *((u32
*)pfsee
) = *((u32
*)pfsentry
);
1897 *((u32
*)pfsee
+1) = *((u32
*)pfsentry
+1);
1898 *((u32
*)pfsee
+2) = *((u32
*)pfsentry
+2);
1899 *((u32
*)pfsee
+3) = *((u32
*)pfsentry
+3);
1902 } while (pfsentry
< pfseend
);
1904 if ((fse
->mode
& sceMcFileAttrHidden
) != 0) {
1908 if ((pcd
== NULL
) || (pcd
->maxent
< 0))
1913 if ((pcd
== NULL
) || (pcd
->maxent
< 0))
1914 return sceMcResSucceed
;
1917 if ((pos
== 1) && (!strncmp(filename
, ".", 1))) {
1919 r
= mcman_readdirentry(port
, slot
, pfse
->cluster
, 0, &fse
);
1920 if (r
!= sceMcResSucceed
)
1924 pcd
->cluster
= fse
->cluster
;
1925 pcd
->fsindex
= fse
->dir_entry
;
1928 if ((fse
->mode
& sceMcFileAttrHidden
) != 0) {
1932 if ((pcd
== NULL
) || (pcd
->maxent
< 0))
1936 if ((pcd
== NULL
) || (pcd
->maxent
< 0))
1937 return sceMcResSucceed
;
1942 if ((pcd
== NULL
) || (pcd
->maxent
< 0))
1943 return sceMcResSucceed
;
1948 if ((pcd
) && (pcd
->maxent
>= 0))
1949 pcd
->maxent
= pfse
->length
;
1951 if (pfse
->length
> 0) {
1955 r
= mcman_readdirentry(port
, slot
, pfse
->cluster
, i
, &fse
);
1956 if (r
!= sceMcResSucceed
)
1959 if (((fse
->mode
& sceMcFileAttrExists
) == 0) && (pcd
) && (i
< pcd
->maxent
))
1963 if ((fse
->mode
& sceMcFileAttrExists
) == 0)
1967 if ((fse
->mode
& sceMcFileAttrExists
) != 0)
1974 if ((pos
>= 11) && (!strncmp(&filename
[10], &fse
->name
[10], pos
-10))) {
1976 if (strlen(fse
->name
) >= pos
)
1977 len
= strlen(fse
->name
);
1979 if (!strncmp(filename
, fse
->name
, len
))
1980 goto continue_check
;
1983 if (strlen(fse
->name
) >= pos
)
1984 len
= strlen(fse
->name
);
1988 if (strncmp(filename
, fse
->name
, len
))
1994 if ((fse
->mode
& sceMcFileAttrHidden
) != 0) {
2003 pcd
->cluster
= pfse
->cluster
;
2005 if (pcd
->maxent
< 0)
2008 } while (++i
< pfse
->length
);
2014 return ((ret
< 1) ? 1 : 0);
2017 //--------------------------------------------------------------
2018 int mcman_writecluster(int port
, int slot
, int cluster
, int flag
)
2020 register int r
, i
, j
, page
, block
, pageword_cnt
;
2021 register u32 erase_value
;
2022 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
2024 block
= cluster
/ mcdi
->clusters_per_block
;
2026 if ((mcman_wr_port
== port
) && (mcman_wr_slot
== slot
) && (mcman_wr_block
== block
))
2027 return mcman_wr_flag3
;
2029 mcman_wr_port
= port
;
2030 mcman_wr_slot
= slot
;
2031 mcman_wr_block
= block
;
2032 mcman_wr_flag3
= -9;
2034 for (i
= 0; i
< 16; i
++) { // check only 16 bad blocks ?
2035 if (mcdi
->bad_block_list
[i
] < 0)
2037 if (mcdi
->bad_block_list
[i
] == block
) {
2039 return sceMcResSucceed
;
2044 for (i
= 1; i
< mcdi
->blocksize
; i
++)
2045 mcman_pagedata
[i
] = 0;
2047 mcman_pagedata
[0] = &mcman_pagebuf
;
2049 pageword_cnt
= mcdi
->pagesize
>> 2;
2050 page
= block
* mcdi
->blocksize
;
2052 if (mcdi
->cardflags
& CF_ERASE_ZEROES
)
2053 erase_value
= 0xffffffff;
2055 erase_value
= 0x00000000;
2057 for (i
= 0; i
< pageword_cnt
; i
++)
2058 *((u32
*)&mcman_pagebuf
+ i
) = erase_value
;
2060 r
= mcman_eraseblock(port
, slot
, block
, (void **)mcman_pagedata
, (void *)mcman_eccdata
);
2061 if (r
== sceMcResFailReplace
)
2062 return sceMcResSucceed
;
2063 if (r
!= sceMcResSucceed
)
2064 return sceMcResChangedCard
;
2066 for (i
= 1; i
< mcdi
->blocksize
; i
++) {
2067 r
= McWritePage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2068 if (r
== sceMcResFailReplace
)
2069 return sceMcResSucceed
;
2070 if (r
!= sceMcResSucceed
)
2071 return sceMcResNoFormat
;
2074 for (i
= 1; i
< mcdi
->blocksize
; i
++) {
2075 r
= McReadPage(port
, slot
, page
+ i
, mcman_pagebuf
);
2076 if (r
== sceMcResNoFormat
)
2077 return sceMcResSucceed
;
2078 if (r
!= sceMcResSucceed
)
2079 return sceMcResFullDevice
;
2081 for (j
= 0; j
< pageword_cnt
; j
++) {
2082 if (*((u32
*)&mcman_pagebuf
+ j
) != erase_value
) {
2084 return sceMcResSucceed
;
2089 r
= mcman_eraseblock(port
, slot
, block
, NULL
, NULL
);
2090 if (r
!= sceMcResSucceed
)
2091 return sceMcResChangedCard
;
2093 r
= McWritePage(port
, slot
, page
, mcman_pagebuf
, mcman_eccdata
);
2094 if (r
== sceMcResFailReplace
)
2095 return sceMcResSucceed
;
2096 if (r
!= sceMcResSucceed
)
2097 return sceMcResNoFormat
;
2099 r
= McReadPage(port
, slot
, page
, mcman_pagebuf
);
2100 if (r
== sceMcResNoFormat
)
2101 return sceMcResSucceed
;
2102 if (r
!= sceMcResSucceed
)
2103 return sceMcResFullDevice
;
2105 for (j
= 0; j
< pageword_cnt
; j
++) {
2106 if (*((u32
*)&mcman_pagebuf
+ j
) != erase_value
) {
2108 return sceMcResSucceed
;
2112 r
= mcman_eraseblock(port
, slot
, block
, NULL
, NULL
);
2113 if (r
== sceMcResFailReplace
)
2114 return sceMcResSucceed
;
2115 if (r
!= sceMcResSucceed
)
2116 return sceMcResFullDevice
;
2118 erase_value
= ~erase_value
;
2120 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2121 r
= McReadPage(port
, slot
, page
+ i
, mcman_pagebuf
);
2122 if (r
!= sceMcResSucceed
)
2123 return sceMcResDeniedPermit
;
2125 for (j
= 0; j
< pageword_cnt
; j
++) {
2126 if (*((u32
*)&mcman_pagebuf
+ j
) != erase_value
) {
2128 return sceMcResSucceed
;
2135 return mcman_wr_flag3
;
2138 //--------------------------------------------------------------
2139 int mcman_setdirentrystate(int port
, int slot
, int cluster
, int fsindex
, int flags
)
2141 register int r
, i
, fat_index
;
2142 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
2146 r
= mcman_readdirentry(port
, slot
, cluster
, fsindex
, &fse
);
2147 if (r
!= sceMcResSucceed
)
2150 if (fse
->name
[0] == '.') {
2151 if ((fse
->name
[1] == 0) || (fse
->name
[1] == '.'))
2152 return sceMcResNoEntry
;
2157 if (mcman_fdhandles
[i
].status
== 0)
2160 if ((mcman_fdhandles
[i
].port
!= port
) || (mcman_fdhandles
[i
].slot
!= slot
))
2163 if (mcman_fdhandles
[i
].field_20
!= cluster
)
2166 if (mcman_fdhandles
[i
].field_24
== fsindex
)
2167 return sceMcResDeniedPermit
;
2169 } while (++i
< MAX_FDHANDLES
);
2172 fse
->mode
= fse
->mode
& (sceMcFileAttrExists
- 1);
2174 fse
->mode
= fse
->mode
| sceMcFileAttrExists
;
2176 mcman_1stcacheEntsetwrflagoff();
2178 fat_index
= fse
->cluster
;
2180 if (fat_index
>= 0) {
2181 if (fat_index
< mcdi
->unknown2
)
2182 mcdi
->unknown2
= fat_index
;
2183 mcdi
->unknown5
= -1;
2186 r
= mcman_getFATentry(port
, slot
, fat_index
, &fat_entry
);
2187 if (r
!= sceMcResSucceed
)
2191 fat_entry
&= 0x7fffffff;
2192 if (fat_index
< mcdi
->unknown2
)
2193 mcdi
->unknown2
= fat_entry
;
2196 fat_entry
|= 0x80000000;
2198 r
= mcman_setFATentry(port
, slot
, fat_index
, fat_entry
);
2199 if (r
!= sceMcResSucceed
)
2202 fat_index
= fat_entry
& 0x7fffffff;
2204 } while (fat_index
!= 0x7fffffff);
2207 return sceMcResSucceed
;
2210 //--------------------------------------------------------------
2211 int mcman_checkBackupBlocks(int port
, int slot
)
2213 register int r1
, r2
, r
, value1
, value2
, eccsize
;
2214 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
2216 int *pagebuf
= (int *)&mcman_pagebuf
;
2218 // First check backup block2 to see if it's in erased state
2219 r1
= McReadPage(port
, slot
, mcdi
->backup_block2
* mcdi
->blocksize
, mcman_pagebuf
); //s1
2221 value1
= *pagebuf
; //s3
2222 if (((mcdi
->cardflags
& CF_ERASE_ZEROES
) != 0) && (value1
== 0))
2225 value1
= value1
& 0x7fffffff;
2227 r2
= McReadPage(port
, slot
, (mcdi
->backup_block2
* mcdi
->blocksize
) + 1, mcman_pagebuf
); //a0
2229 value2
= *pagebuf
; //s0
2230 if (((mcdi
->cardflags
& CF_ERASE_ZEROES
) != 0) && (value2
== 0))
2233 value2
= value2
& 0x7fffffff;
2235 if ((value1
!= -1) && (value2
== -1))
2237 if ((r1
< 0) || (r2
< 0))
2240 if ((value1
== -1) && (value1
== value2
))
2241 return sceMcResSucceed
;
2243 // bachup block2 is not erased, so programming is assumed to have not been completed
2244 // reads content of backup block1
2245 for (r1
= 0; r1
< mcdi
->clusters_per_block
; r1
++) {
2247 mcman_readcluster(port
, slot
, (mcdi
->backup_block1
* mcdi
->clusters_per_block
) + r1
, &mce
);
2250 for (r2
= 0; r2
< mcdi
->pages_per_cluster
; r2
++) {
2251 mcman_pagedata
[(r1
* ((mcdi
->pages_per_cluster
<< 16) >> 16)) + r2
] = \
2252 (void *)(mce
->cl_data
+ (r2
* mcdi
->pagesize
));
2256 // Erase the block where data must be written
2257 r
= mcman_eraseblock(port
, slot
, value1
, (void **)mcman_pagedata
, (void *)mcman_eccdata
);
2258 if (r
!= sceMcResSucceed
)
2262 for (r1
= 0; r1
< mcdi
->blocksize
; r1
++) {
2264 eccsize
= mcdi
->pagesize
;
2267 eccsize
= eccsize
>> 5;
2269 r
= McWritePage(port
, slot
, (value1
* ((mcdi
->blocksize
<< 16) >> 16)) + r1
, \
2270 mcman_pagedata
[r1
], (void *)(mcman_eccdata
+ (eccsize
* r1
)));
2272 if (r
!= sceMcResSucceed
)
2276 for (r1
= 0; r1
< mcdi
->clusters_per_block
; r1
++)
2277 mcman_freecluster(port
, slot
, (mcdi
->backup_block1
* mcdi
->clusters_per_block
) + r1
);
2280 // Finally erase backup block2
2281 return mcman_eraseblock(port
, slot
, mcdi
->backup_block2
, NULL
, NULL
);
2284 //--------------------------------------------------------------
2285 int McCheckBlock(int port
, int slot
, int block
)
2287 register int r
, i
, j
, page
, ecc_count
, pageword_cnt
, flag
, erase_value
;
2288 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
2292 DPRINTF("mcman: McCheckBlock port%d slot%d block 0x%x\n", port
, slot
, block
);
2296 page
= block
* mcdi
->blocksize
; //sp18
2297 pageword_cnt
= mcdi
->pagesize
>> 2; //s6
2299 ecc_count
= mcdi
->pagesize
;
2300 if (mcdi
->pagesize
< 0)
2302 ecc_count
= ecc_count
>> 7; // s7
2306 if (mcdi
->cardform
> 0) {
2307 for (i
= 0; i
< 16; i
++) {
2308 if (mcdi
->bad_block_list
[i
] <= 0)
2310 if (mcdi
->bad_block_list
[i
] == block
)
2317 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2318 r
= mcman_readpage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2319 if (r
!= sceMcResSucceed
)
2322 if ((mcdi
->cardflags
& CF_USE_ECC
) != 0) {
2323 if (mcman_eccdata
[mcman_sparesize(port
, slot
) - 1] != 0xff) {
2324 p_page
= (void *)mcman_pagebuf
; //s1
2325 p_ecc
= (void *)mcman_eccdata
; //s2
2327 for (j
= 0; j
< ecc_count
; j
++) {
2328 r
= mcman_correctdata(p_page
, p_ecc
);
2329 if (r
!= sceMcResSucceed
) {
2340 for (j
= 0; j
< pageword_cnt
; j
++)
2341 *((u32
*)&mcman_pagebuf
+ j
) = 0x5a5aa5a5;
2343 for (j
= 0; j
< 128; j
++)
2344 *((u32
*)&mcman_eccdata
+ j
) = 0x5a5aa5a5;
2346 r
= mcman_eraseblock(port
, slot
, block
, NULL
, NULL
);
2347 if (r
!= sceMcResSucceed
) {
2348 r
= mcman_probePS2Card2(port
, slot
);
2349 if (r
!= sceMcResSucceed
)
2355 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2356 r
= McWritePage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2357 if (r
!= sceMcResSucceed
) {
2358 r
= mcman_probePS2Card2(port
, slot
);
2359 if (r
!= sceMcResSucceed
)
2366 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2367 r
= mcman_readpage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2368 if (r
!= sceMcResSucceed
)
2371 for (j
= 0; j
< pageword_cnt
; j
++) {
2372 if (*((u32
*)&mcman_pagebuf
+ j
) != 0x5a5aa5a5) {
2378 for (j
= 0; j
< 128; j
++) {
2379 if (*((u32
*)&mcman_eccdata
+ j
) != 0x5a5aa5a5) {
2386 for (j
= 0; j
< pageword_cnt
; j
++)
2387 *((u32
*)&mcman_pagebuf
+ j
) = 0x05a55a5a;
2389 for (j
= 0; j
< 128; j
++)
2390 *((u32
*)&mcman_eccdata
+ j
) = 0x05a55a5a;
2392 r
= mcman_eraseblock(port
, slot
, block
, NULL
, NULL
);
2393 if (r
!= sceMcResSucceed
) {
2394 r
= mcman_probePS2Card2(port
, slot
);
2395 if (r
!= sceMcResSucceed
)
2401 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2402 r
= McWritePage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2403 if (r
!= sceMcResSucceed
) {
2404 r
= mcman_probePS2Card2(port
, slot
);
2405 if (r
!= sceMcResSucceed
)
2412 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2413 r
= mcman_readpage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2414 if (r
!= sceMcResSucceed
)
2417 for (j
= 0; j
< pageword_cnt
; j
++) {
2418 if (*((u32
*)&mcman_pagebuf
+ j
) != 0x05a55a5a) {
2424 for (j
= 0; j
< 128; j
++) {
2425 if (*((u32
*)&mcman_eccdata
+ j
) != 0x05a55a5a) {
2434 mcman_eraseblock(port
, slot
, block
, NULL
, NULL
);
2435 return sceMcResSucceed
;
2438 erase_value
= 0x00000000;
2439 if ((mcdi
->cardflags
& CF_ERASE_ZEROES
) != 0)
2440 erase_value
= 0xffffffff;
2442 for (j
= 0; j
< pageword_cnt
; j
++)
2443 *((u32
*)&mcman_pagebuf
+ j
) = erase_value
;
2445 for (j
= 0; j
< 128; j
++)
2446 *((u32
*)&mcman_eccdata
+ j
) = erase_value
;
2448 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
2449 r
= McWritePage(port
, slot
, page
+ i
, mcman_pagebuf
, mcman_eccdata
);
2450 if (r
!= sceMcResSucceed
) {
2451 r
= mcman_probePS2Card2(port
, slot
);
2452 if (r
!= sceMcResSucceed
)
2460 //--------------------------------------------------------------
2461 int mcman_setPS1devinfos(int port
, int slot
)
2464 MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
2467 DPRINTF("mcman: mcman_setPS1devinfos port%d slot%d\n", port
, slot
);
2470 memset((void *)mcdi
, 0, sizeof (MCDevInfo
));
2471 memset((void *)&mcdi
->bad_block_list
[0], -1, 128);
2473 mcdi
->pagesize
= 128;
2474 mcdi
->blocksize
= 128;
2475 mcdi
->pages_per_cluster
= 64;
2476 mcdi
->unused
= 0xff00;
2477 mcdi
->cluster_size
= 8192;
2478 mcdi
->FATentries_per_cluster
= 2048;
2479 mcdi
->clusters_per_card
= 16;
2480 mcdi
->clusters_per_block
= 0;
2484 r
= McReadPS1PDACard(port
, slot
, 0, mcman_PS1PDApagebuf
);
2488 if (mcman_sio2outbufs_PS1PDA
[1] != 0)
2491 if (mcman_PS1PDApagebuf
[0] != 0x4d)
2492 return sceMcResNoFormat
;
2494 if (mcman_PS1PDApagebuf
[1] != 0x43)
2495 return sceMcResNoFormat
;
2497 for (i
= 0; i
< 20; i
++) {
2498 r
= McReadPS1PDACard(port
, slot
, i
+ 16, mcman_PS1PDApagebuf
);
2499 if (r
!= sceMcResSucceed
)
2502 if (mcman_PS1PDApagebuf
[127] == (mcman_calcEDC(mcman_PS1PDApagebuf
, 127) & 0xff)) {
2503 mcdi
->bad_block_list
[i
] = *((u32
*)mcman_PS1PDApagebuf
);
2507 r
= mcman_cachePS1dirs(port
, slot
);
2509 if (r
!= sceMcResSucceed
)
2514 return sceMcResSucceed
;
2517 //--------------------------------------------------------------
2518 int mcman_getPS1direntry(int port
, int slot
, char *filename
, McFsEntryPS1
**pfse
, int flag
)
2524 DPRINTF("mcman: mcman_getPS1direntry port%d slot%d file %s flag %x\n", port
, slot
, filename
, flag
);
2532 r
= mcman_readdirentryPS1(port
, slot
, i
, pfse
);
2533 if (r
!= sceMcResSucceed
)
2537 if (pfse
[0]->mode
!= 0x51)
2541 if (pfse
[0]->mode
!= 0xa1)
2545 if (!strcmp(p
, pfse
[0]->name
))
2550 return sceMcResNoEntry
;
2553 //--------------------------------------------------------------
2554 int mcman_clearPS1direntry(int port
, int slot
, int cluster
, int flags
)
2556 register int r
, i
, temp
;
2562 DPRINTF("mcman: mcman_clearPS1direntry port%d slot%d cluster %x flags %x\n", port
, slot
, cluster
, flags
);
2565 r
= mcman_readdirentryPS1(port
, slot
, cluster
, &fse
);
2566 if (r
!= sceMcResSucceed
)
2569 fh
= (MC_FHANDLE
*)&mcman_fdhandles
[0];
2571 for (i
= 0; i
< MAX_FDHANDLES
; i
++) {
2572 if ((fh
->status
!= 0) && (fh
->port
== port
) && (fh
->slot
== slot
)) {
2573 if (fh
->freeclink
== cluster
)
2574 return sceMcResDeniedPermit
;
2581 if (fse
->mode
!= 0x51)
2582 return sceMcResNoEntry
;
2585 if (fse
->mode
!= 0xa1)
2586 return sceMcResNoEntry
;
2591 mce
= mcman_get1stcacheEntp();
2593 if (cluster
+ 1 < 0)
2598 mce
->wr_flag
|= 1 << ((cluster
+ 1) - ((temp
>> 3) << 3));
2601 temp
= (fse
->mode
& 0xf) | 0xa0;
2603 temp
= (fse
->mode
& 0xf) | 0x50;
2606 fse
->edc
= mcman_calcEDC((void *)fse
, 127);
2608 if (fse
->linked_block
< 0) {
2613 cluster
= fse
->linked_block
;
2615 r
= mcman_readdirentryPS1(port
, slot
, cluster
, &fse
);
2616 if (r
!= sceMcResSucceed
)
2620 if ((fse
->mode
& 0xf0) != 0x50)
2625 } while ((fse
->mode
& 0xf0) == 0xa0);
2627 r
= mcman_flushmccache(port
, slot
);
2628 if (r
!= sceMcResSucceed
)
2631 return sceMcResNoEntry
;
2634 r
= mcman_flushmccache(port
, slot
);
2635 if (r
!= sceMcResSucceed
)
2638 return sceMcResSucceed
;
2641 //--------------------------------------------------------------
2642 int mcman_findfree1(int port
, int slot
, int reserve
)
2644 register int r
, i
, free
;
2648 DPRINTF("mcman: mcman_findfree1 port%d slot%d reserve %d\n", port
, slot
, reserve
);
2655 r
= mcman_readdirentryPS1(port
, slot
, i
, &fse
);
2656 if (r
!= sceMcResSucceed
)
2659 if ((fse
->mode
& 0xf0) == 0xa0) {
2667 return sceMcResFullDevice
;
2672 return sceMcResFullDevice
;
2675 //--------------------------------------------------------------
2676 int mcman_fatRseekPS1(int fd
)
2678 register int r
, rpos
, numclust
, clust
;
2679 MC_FHANDLE
*fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
2680 MCDevInfo
*mcdi
= &mcman_devinfos
[fh
->port
][fh
->slot
];
2683 numclust
= fh
->position
/ mcdi
->cluster_size
;
2685 clust
= fh
->freeclink
;
2687 if (numclust
> -1) {
2690 return sceMcResFullDevice
;
2692 r
= mcman_readdirentryPS1(fh
->port
, fh
->slot
, clust
, &fse
);
2693 if (r
!= sceMcResSucceed
)
2695 clust
= fse
->linked_block
;
2697 } while (--numclust
> -1);
2701 return sceMcResFullDevice
;
2703 rpos
= fh
->position
% mcdi
->cluster_size
;
2708 return ((clust
+ 1) << 6) + ((rpos
>> 10) * (1024 / mcdi
->pagesize
));
2711 //--------------------------------------------------------------
2712 int mcman_fatWseekPS1(int fd
)
2714 register int r
, numclust
, clust
;
2715 MC_FHANDLE
*fh
= (MC_FHANDLE
*)&mcman_fdhandles
[fd
];
2716 MCDevInfo
*mcdi
= &mcman_devinfos
[fh
->port
][fh
->slot
];
2719 numclust
= fh
->position
/ mcdi
->cluster_size
;
2722 clust
= fh
->freeclink
;
2724 r
= mcman_readdirentryPS1(fh
->port
, fh
->slot
, clust
, &fse
);
2725 if (r
!= sceMcResSucceed
)
2728 clust
= fse
->linked_block
;
2731 r
= mcman_FNC8ca4(fh
->port
, fh
->slot
, (MC_FHANDLE
*)fh
);
2736 } while (--numclust
);
2738 r
= mcman_flushmccache(fh
->port
, fh
->slot
);
2743 //--------------------------------------------------------------
2744 int mcman_FNC8ca4(int port
, int slot
, MC_FHANDLE
*fh
)
2746 register int r
, i
, j
, mcfree
, cluster_size
, pages_per_FATclust
;
2748 MCDevInfo
*mcdi
= &mcman_devinfos
[fh
->port
][fh
->slot
];
2749 McFsEntryPS1
*fse1
, *fse2
, *fse3
;
2751 u8
*pfsentry
, *pfsee
, *pfseend
;
2754 DPRINTF("mcman: mcman_FNC8ca4 port%d slot%d\n", port
, slot
);
2757 if (mcdi
->cluster_size
< 0)
2758 cluster_size
= mcdi
->cluster_size
+ 1023;
2760 cluster_size
= mcdi
->cluster_size
;
2762 cluster_size
= cluster_size
>> 10;
2764 pages_per_FATclust
= 1024 / mcdi
->pagesize
;
2766 r
= mcman_findfree1(port
, slot
, 1);
2777 if (cluster_size
> 0) {
2781 mcman_freecluster(port
, slot
, ((mcfree
* cluster_size
) + i
) * pages_per_FATclust
);
2783 r
= mcman_readclusterPS1(port
, slot
, ((i
* cluster_size
) + i
) * pages_per_FATclust
, &mce
);
2784 if (r
!= sceMcResSucceed
)
2788 mce
->cluster
-= (i
- mcfree
) * cluster_size
;
2790 } while (++i
< cluster_size
);
2793 r
= mcman_readdirentryPS1(port
, slot
, i
, &fse1
);
2794 if (r
!= sceMcResSucceed
)
2797 r
= mcman_readdirentryPS1(port
, slot
, mcfree
, &fse2
);
2798 if (r
!= sceMcResSucceed
)
2801 mce
= mcman_get1stcacheEntp();
2808 mce
->wr_flag
|= 1 << ((mcfree
+ 1) - ((temp
>> 3) << 3));
2810 pfsentry
= (u8
*)fse1
;
2812 pfseend
= (u8
*)(pfsentry
+ sizeof(McFsEntryPS1
));
2815 *((u32
*)pfsee
) = *((u32
*)pfsentry
);
2816 *((u32
*)pfsee
+1) = *((u32
*)pfsentry
+1);
2817 *((u32
*)pfsee
+2) = *((u32
*)pfsentry
+2);
2818 *((u32
*)pfsee
+3) = *((u32
*)pfsentry
+3);
2821 } while (pfsentry
< pfseend
);
2824 r
= mcman_readdirentryPS1(port
, slot
, j
, &fse3
);
2825 if (r
!= sceMcResSucceed
)
2828 mce
= mcman_get1stcacheEntp();
2835 mce
->wr_flag
|= 1 << ((j
+ 1) - ((temp
>> 3) << 3));
2836 fse3
->linked_block
= mcfree
;
2837 fse3
->edc
= mcman_calcEDC((void *)fse3
, 127);
2840 fh
->freeclink
= mcfree
;
2848 r
= mcman_readdirentryPS1(port
, slot
, j
, &fse1
);
2849 if (r
!= sceMcResSucceed
)
2852 i
= fse1
->linked_block
;
2856 r
= mcman_readdirentryPS1(port
, slot
, mcfree
, &fse2
);
2857 if (r
!= sceMcResSucceed
)
2860 mce
= mcman_get1stcacheEntp();
2867 mce
->wr_flag
|= 1 << ((mcfree
+ 1) - ((temp
>> 3) << 3));
2869 mcman_wmemset((void *)fse2
, sizeof(McFsEntryPS1
), 0);
2872 fse2
->linked_block
= -1;
2873 fse2
->edc
= mcman_calcEDC((void *)fse2
, 127);
2875 r
= mcman_readdirentryPS1(port
, slot
, j
, &fse3
);
2876 if (r
!= sceMcResSucceed
)
2879 mce
= mcman_get1stcacheEntp();
2886 mce
->wr_flag
|= 1 << ((j
+ 1) - ((temp
>> 3) << 3));
2888 if (fse3
->mode
== 0x53)
2891 fse3
->linked_block
= mcfree
;
2892 fse3
->edc
= mcman_calcEDC((void *)fse3
, 127);
2897 //--------------------------------------------------------------
2898 int mcman_PS1pagetest(int port
, int slot
, int page
)
2902 for (i
= 0; i
< 32; i
++)
2903 *((u32
*)&mcman_PS1PDApagebuf
+i
) = 0xffffffff;
2905 r
= McWritePS1PDACard(port
, slot
, page
, mcman_PS1PDApagebuf
);
2906 if (r
!= sceMcResSucceed
)
2907 return sceMcResDeniedPermit
;
2909 r
= McReadPS1PDACard(port
, slot
, page
, mcman_PS1PDApagebuf
);
2910 if (r
!= sceMcResSucceed
)
2911 return sceMcResNotEmpty
;
2913 for (i
= 0; i
< 32; i
++) {
2914 if (*((u32
*)&mcman_PS1PDApagebuf
+ i
) != 0xffffffff) {
2919 for (i
= 0; i
< 32; i
++)
2920 *((u32
*)&mcman_PS1PDApagebuf
+ i
) = 0;
2922 r
= McWritePS1PDACard(port
, slot
, page
, mcman_PS1PDApagebuf
);
2923 if (r
!= sceMcResSucceed
)
2924 return sceMcResDeniedPermit
;
2926 r
= McReadPS1PDACard(port
, slot
, page
, mcman_PS1PDApagebuf
);
2927 if (r
!= sceMcResSucceed
)
2928 return sceMcResNotEmpty
;
2930 for (i
= 0; i
< 32; i
++) {
2931 if (*((u32
*)&mcman_PS1PDApagebuf
+ i
) != 0) {
2939 //--------------------------------------------------------------
2940 int mcman_cachePS1dirs(int port
, int slot
)
2942 register int r
, i
, j
, temp1
, temp2
, index
, linked_block
;
2943 McFsEntryPS1
*fs_t
[15];
2944 McCacheEntry
*mce
[2];
2948 DPRINTF("mcman: mcman_cachePS1dirs port%d slot%d\n", port
, slot
);
2953 r
= mcman_readdirentryPS1(port
, slot
, i
, &fs_t
[i
]);
2954 if (r
!= sceMcResSucceed
)
2957 fs_t
[i
]->field_38
= fs_t
[i
]->length
; /// <-- Special fix for saves from a real PS1
2960 mce
[0] = mcman_get1stcacheEntp();
2964 mce
[1] = mcman_get1stcacheEntp();
2968 memset((void *)cluster_t
, -1, sizeof(cluster_t
));
2972 temp1
= fs_t
[i
]->mode
& 0xf0;
2974 if ((fs_t
[i
]->mode
& 0xf) != 1)
2979 linked_block
= fs_t
[i
]->linked_block
;
2980 if (linked_block
>= 0) {
2982 if ((fs_t
[linked_block
]->mode
& 0xf0) != temp1
)
2985 if (fs_t
[linked_block
]->mode
== 0xa0)
2988 if (cluster_t
[linked_block
] != -1)
2991 cluster_t
[linked_block
] = i
;
2992 linked_block
= fs_t
[linked_block
]->linked_block
;
2994 } while (linked_block
>= 0);
2996 if ((linked_block
< 0) && (temp1
!= 0))
3006 if (cluster_t
[j
] != i
)
3009 memset((void *)fs_t
[j
], 0, sizeof (McFsEntryPS1
));
3011 fs_t
[j
]->mode
= 0xa0;
3012 fs_t
[j
]->linked_block
= -1;
3013 fs_t
[j
]->edc
= mcman_calcEDC((void *)fs_t
[j
], 127);
3027 mce
[index
]->wr_flag
|= (1 << (temp2
- ((temp1
>> 3) << 3)));
3035 if ((cluster_t
[i
] != -1) || (fs_t
[i
]->mode
== 0xa0))
3038 memset((void *)fs_t
[i
], 0, sizeof (McFsEntryPS1
));
3040 fs_t
[i
]->mode
= 0xa0;
3041 fs_t
[i
]->linked_block
= cluster_t
[i
];
3042 fs_t
[i
]->edc
= mcman_calcEDC((void *)fs_t
[i
], 127);
3056 mce
[index
]->wr_flag
|= (1 << (temp2
- ((temp1
>> 3) << 3)));
3060 return sceMcResSucceed
;
3063 //--------------------------------------------------------------
3064 int mcman_fillPS1backuparea(int port
, int slot
, int block
)
3066 register int r
, i
, curpage
;
3067 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3069 memset(mcman_PS1PDApagebuf
, 0, 128);
3074 if (mcdi
->bad_block_list
[i
] == block
) {
3075 mcdi
->bad_block_list
[i
] = block
| 0x01000000;
3076 *((u32
*)&mcman_PS1PDApagebuf
) = block
| 0x01000000;
3077 mcman_PS1PDApagebuf
[127] = mcman_calcEDC(mcman_PS1PDApagebuf
, 127);
3078 r
= McWritePS1PDACard(port
, slot
, curpage
, mcman_PS1PDApagebuf
);
3079 if (r
!= sceMcResSucceed
)
3083 if (mcdi
->bad_block_list
[i
] < 0) {
3084 *((u32
*)&mcman_PS1PDApagebuf
) = block
;
3085 mcman_PS1PDApagebuf
[127] = mcman_calcEDC(mcman_PS1PDApagebuf
, 127);
3086 r
= McWritePS1PDACard(port
, slot
, curpage
, mcman_PS1PDApagebuf
);
3087 if (r
!= sceMcResSucceed
)
3089 mcdi
->bad_block_list
[i
] = block
;
3096 return sceMcResSucceed
;
3099 //--------------------------------------------------------------
3100 void mcman_initcache(void)
3106 DPRINTF("mcman: mcman_initcache\n");
3109 j
= MAX_CACHEENTRY
- 1;
3110 p
= (u8
*)mcman_cachebuf
;
3112 for (i
= 0; i
< MAX_CACHEENTRY
; i
++) {
3113 mcman_entrycache
[i
].cl_data
= (u8
*)p
;
3114 mcman_mccache
[i
] = (McCacheEntry
*)&mcman_entrycache
[j
- i
];
3115 mcman_entrycache
[i
].cluster
= -1;
3116 p
+= MCMAN_CLUSTERSIZE
;
3119 pmcman_entrycache
= (McCacheEntry
*)mcman_entrycache
;
3120 pmcman_mccache
= (McCacheEntry
**)mcman_mccache
;
3122 for (i
= 0; i
< MCMAN_MAXSLOT
; i
++) {
3123 mcman_devinfos
[0][i
].unknown3
= -1;
3124 mcman_devinfos
[0][i
].unknown4
= -1;
3125 mcman_devinfos
[0][i
].unknown5
= -1;
3126 mcman_devinfos
[1][i
].unknown3
= -1;
3127 mcman_devinfos
[1][i
].unknown4
= -1;
3128 mcman_devinfos
[1][i
].unknown5
= -1;
3131 memset((void *)mcman_fatcache
, -1, sizeof (mcman_fatcache
));
3133 for (i
= 0; i
< MCMAN_MAXSLOT
; i
++) {
3134 mcman_fatcache
[0][i
].entry
[0] = 0;
3135 mcman_fatcache
[1][i
].entry
[0] = 0;
3139 //--------------------------------------------------------------
3140 int McRetOnly(int fd
) // Export #37
3143 DPRINTF("mcman: McRetOnly param %x\n", fd
);
3145 return sceMcResSucceed
;
3148 //--------------------------------------------------------------
3149 int mcman_clearcache(int port
, int slot
)
3152 McCacheEntry
**pmce
= (McCacheEntry
**)pmcman_mccache
;
3153 McCacheEntry
*mce
, *mce_save
;
3156 DPRINTF("mcman: mcman_clearcache port%d, slot%d\n", port
, slot
);
3159 for (i
= MAX_CACHEENTRY
- 1; i
>= 0; i
--) {
3160 mce
= (McCacheEntry
*)pmce
[i
];
3161 if ((mce
->mc_port
== port
) && (mce
->mc_slot
== slot
) && (mce
->cluster
>= 0)) {
3169 for (i
= 0; i
< (MAX_CACHEENTRY
- 1); i
++) {
3170 mce
= (McCacheEntry
*)pmce
[i
];
3171 mce_save
= (McCacheEntry
*)pmce
[i
];
3172 if (mce
->cluster
< 0) {
3173 for (j
= i
+1; j
< MAX_CACHEENTRY
; j
++) {
3174 mce
= (McCacheEntry
*)pmce
[j
];
3175 if (mce
->cluster
>= 0)
3178 if (j
== MAX_CACHEENTRY
)
3181 pmce
[i
] = (McCacheEntry
*)pmce
[j
];
3182 pmce
[j
] = (McCacheEntry
*)mce_save
;
3186 memset((void *)&mcman_fatcache
[port
][slot
], -1, sizeof (McFatCache
));
3188 mcman_fatcache
[port
][slot
].entry
[0] = 0;
3190 return sceMcResSucceed
;
3193 //--------------------------------------------------------------
3194 McCacheEntry
*mcman_getcacheentry(int port
, int slot
, int cluster
)
3197 McCacheEntry
*mce
= (McCacheEntry
*)pmcman_entrycache
;
3199 //DPRINTF("mcman: mcman_getcacheentry port%d slot%d cluster %x\n", port, slot, cluster);
3201 for (i
= 0; i
< MAX_CACHEENTRY
; i
++) {
3202 if ((mce
->mc_port
== port
) && (mce
->mc_slot
== slot
) && (mce
->cluster
== cluster
))
3210 //--------------------------------------------------------------
3211 void mcman_freecluster(int port
, int slot
, int cluster
) // release cluster from entrycache
3214 McCacheEntry
*mce
= (McCacheEntry
*)pmcman_entrycache
;
3216 for (i
= 0; i
< MAX_CACHEENTRY
; i
++) {
3217 if ((mce
->mc_port
== port
) && (mce
->mc_slot
== slot
) && (mce
->cluster
== cluster
)) {
3225 //--------------------------------------------------------------
3226 int mcman_getFATindex(int port
, int slot
, int num
)
3228 return mcman_fatcache
[port
][slot
].entry
[num
];
3231 //--------------------------------------------------------------
3232 void mcman_1stcacheEntsetwrflagoff(void)
3234 McCacheEntry
*mce
= (McCacheEntry
*)*pmcman_mccache
;
3239 //--------------------------------------------------------------
3240 McCacheEntry
*mcman_get1stcacheEntp(void)
3242 return *pmcman_mccache
;
3245 //--------------------------------------------------------------
3246 void mcman_addcacheentry(McCacheEntry
*mce
)
3249 McCacheEntry
**pmce
= (McCacheEntry
**)pmcman_mccache
;
3251 i
= MAX_CACHEENTRY
- 1;
3264 pmce
[i
] = pmce
[i
-1];
3268 pmce
[0] = (McCacheEntry
*)mce
;
3271 //--------------------------------------------------------------
3272 int mcman_flushmccache(int port
, int slot
)
3275 McCacheEntry
**pmce
= (McCacheEntry
**)pmcman_mccache
;
3279 DPRINTF("mcman: mcman_flushmccache port%d slot%d\n", port
, slot
);
3282 i
= MAX_CACHEENTRY
- 1;
3286 mce
= (McCacheEntry
*)pmce
[i
];
3287 if ((mce
->mc_port
== port
) && (mce
->mc_slot
== slot
) && (mce
->wr_flag
!= 0)) {
3288 r
= mcman_flushcacheentry((McCacheEntry
*)mce
);
3289 if (r
!= sceMcResSucceed
)
3296 return sceMcResSucceed
;
3299 //--------------------------------------------------------------
3300 int mcman_flushcacheentry(McCacheEntry
*mce
)
3302 register int r
, i
, j
, ecc_count
;
3303 register int temp1
, temp2
, offset
, pageindex
;
3304 static int clusters_per_block
, blocksize
, cardtype
, pagesize
, sparesize
, flag
, cluster
, block
, pages_per_fatclust
;
3305 McCacheEntry
*pmce
[16]; // sp18
3306 register MCDevInfo
*mcdi
;
3308 static u8 eccbuf
[32];
3309 void *p_page
, *p_ecc
;
3312 DPRINTF("mcman: mcman_flushcacheentry mce %x cluster %x\n", (int)mce
, (int)mce
->cluster
);
3315 if (mce
->wr_flag
== 0)
3316 return sceMcResSucceed
;
3318 mcdi
= (MCDevInfo
*)&mcman_devinfos
[mce
->mc_port
][mce
->mc_slot
];
3320 //mcdi->pagesize = sp84
3321 pagesize
= mcdi
->pagesize
; //sp84
3322 cardtype
= mcdi
->cardtype
;
3324 if (cardtype
== 0) {
3326 return sceMcResSucceed
;
3329 if ((cardtype
== sceMcTypePS1
) || (cardtype
== sceMcTypePDA
)) {
3330 pages_per_fatclust
= MCMAN_CLUSTERSIZE
/ pagesize
;
3331 i
= mce
->cluster
; //s0
3335 if (pages_per_fatclust
> 0) {
3339 if (((mce
->wr_flag
>> j
) & 1) != 0) {
3340 //DPRINTF("flushing ent %x cl_data %x to page %d offset %d\n", mce, mce->cl_data, i, (pagesize * j));
3341 r
= McWritePS1PDACard(mce
->mc_port
, mce
->mc_slot
, i
, (void *)(mce
->cl_data
+ (pagesize
* j
)));
3342 if (r
== sceMcResFailReplace
)
3344 if (r
!= sceMcResSucceed
)
3349 } while (++j
< pages_per_fatclust
);
3352 if (j
== pages_per_fatclust
) {
3353 r
= mcman_probePS1Card2(mce
->mc_port
, mce
->mc_slot
);
3355 r
= sceMcResFailReplace
;
3357 if (cardtype
!= sceMcTypePS1
) {
3358 if (r
== sceMcResFailReplace
)
3362 return sceMcResSucceed
;
3366 return sceMcResSucceed
;
3369 if ((mce
->wr_flag
& ~(-1 << j
)) == 0) {
3371 return sceMcResSucceed
;
3376 return sceMcResSucceed
;
3382 if (((mce
->wr_flag
>> j
) & 1) != 0) {
3383 r
= mcman_fillPS1backuparea(mce
->mc_port
, mce
->mc_slot
, i
);
3384 if (r
!= sceMcResSucceed
)
3385 return sceMcResFailReplace
;
3392 return sceMcResSucceed
;
3395 clusters_per_block
= mcdi
->clusters_per_block
; //sp7c
3396 block
= mce
->cluster
/ mcdi
->clusters_per_block
; //sp78
3397 blocksize
= mcdi
->blocksize
; //sp80
3398 sparesize
= mcman_sparesize(mce
->mc_port
, mce
->mc_slot
); //sp84
3401 memset((void *)pmce
, 0, 64);
3404 if (MAX_CACHEENTRY
> 0) {
3405 mcee
= (McCacheEntry
*)pmcman_entrycache
;
3407 if ((*((u32
*)&mcee
->mc_slot
) & 0xff00ffff) == (*((u32
*)&mce
->mc_slot
) & 0xff00ffff)) {
3408 temp1
= mcee
->cluster
/ clusters_per_block
;
3409 temp2
= mcee
->cluster
% clusters_per_block
;
3411 if (temp1
== block
) {
3412 pmce
[temp2
] = (McCacheEntry
*)mcee
;
3413 if (mcee
->rd_flag
== 0)
3418 } while (++i
< MAX_CACHEENTRY
);
3421 if (clusters_per_block
> 0) {
3424 cluster
= block
* clusters_per_block
; // sp8c
3430 for (j
= 0; j
< mcdi
->pages_per_cluster
; j
++) {
3431 mcman_pagedata
[pageindex
+ j
] = (void *)(pmce
[i
]->cl_data
+ offset
);
3437 // s2 = (cluster + i) * mcdi->pages_per_cluster
3440 offset
= (pageindex
+ j
) * pagesize
; // t0
3441 mcman_pagedata
[pageindex
+ j
] = (void *)(mcman_backupbuf
+ offset
);
3443 r
= McReadPage(mce
->mc_port
, mce
->mc_slot
, \
3444 ((cluster
+ i
) * mcdi
->pages_per_cluster
) + j
, \
3445 mcman_backupbuf
+ offset
);
3446 if (r
!= sceMcResSucceed
)
3449 } while (++j
< mcdi
->pages_per_cluster
);
3452 pageindex
+= mcdi
->pages_per_cluster
;
3453 } while (++i
< clusters_per_block
);
3457 if ((flag
!= 0) && (mcman_badblock
<= 0)) {
3458 r
= mcman_eraseblock(mce
->mc_port
, mce
->mc_slot
, mcdi
->backup_block1
, (void**)mcman_pagedata
, mcman_eccdata
);
3459 if (r
== sceMcResFailReplace
) {
3461 r
= mcman_replaceBackupBlock(mce
->mc_port
, mce
->mc_slot
, mcdi
->backup_block1
);
3462 mcdi
->backup_block1
= r
;
3465 if (r
!= sceMcResSucceed
)
3468 *((u32
*)&mcman_pagebuf
) = block
| 0x80000000;
3469 p_page
= (void *)mcman_pagebuf
; //s0
3470 p_ecc
= (void *)eccbuf
; //s2 = sp58
3475 ecc_count
= (pagesize
+ 0x7f) >> 7;
3477 ecc_count
= pagesize
>> 7;
3482 McDataChecksum(p_page
, p_ecc
);
3490 r
= McWritePage(mce
->mc_port
, mce
->mc_slot
, mcdi
->backup_block2
* blocksize
, mcman_pagebuf
, eccbuf
);
3491 if (r
== sceMcResFailReplace
)
3493 if (r
!= sceMcResSucceed
)
3496 if (r
< mcdi
->blocksize
) {
3498 p_ecc
= (void *)mcman_eccdata
;
3501 r
= McWritePage(mce
->mc_port
, mce
->mc_slot
, (mcdi
->backup_block1
* blocksize
) + i
, mcman_pagedata
[i
], p_ecc
);
3502 if (r
== sceMcResFailReplace
)
3504 if (r
!= sceMcResSucceed
)
3507 } while (++i
< mcdi
->blocksize
);
3510 r
= McWritePage(mce
->mc_port
, mce
->mc_slot
, (mcdi
->backup_block2
* blocksize
) + 1, mcman_pagebuf
, eccbuf
);
3511 if (r
== sceMcResFailReplace
)
3513 if (r
!= sceMcResSucceed
)
3517 r
= mcman_eraseblock(mce
->mc_port
, mce
->mc_slot
, block
, (void**)mcman_pagedata
, mcman_eccdata
);
3518 //if (block == 1) /////
3519 // r = sceMcResFailReplace; /////
3520 if (r
== sceMcResFailReplace
) {
3521 r
= mcman_fillbackupblock1(mce
->mc_port
, mce
->mc_slot
, block
, (void**)mcman_pagedata
, mcman_eccdata
);
3522 for (i
= 0; i
< clusters_per_block
; i
++) {
3524 pmce
[i
]->wr_flag
= 0;
3526 if (r
== sceMcResFailReplace
)
3530 if (r
!= sceMcResSucceed
)
3533 if (mcdi
->blocksize
> 0) {
3535 p_ecc
= (void *)mcman_eccdata
;
3538 if (pmce
[i
/ mcdi
->pages_per_cluster
] == 0) {
3539 r
= McWritePage(mce
->mc_port
, mce
->mc_slot
, (block
* blocksize
) + i
, mcman_pagedata
[i
], p_ecc
);
3540 if (r
== sceMcResFailReplace
) {
3541 r
= mcman_fillbackupblock1(mce
->mc_port
, mce
->mc_slot
, block
, (void**)mcman_pagedata
, mcman_eccdata
);
3542 for (i
= 0; i
< clusters_per_block
; i
++) {
3544 pmce
[i
]->wr_flag
= 0;
3546 if (r
== sceMcResFailReplace
)
3550 if (r
!= sceMcResSucceed
)
3554 } while (++i
< mcdi
->blocksize
);
3557 if (mcdi
->blocksize
> 0) {
3559 p_ecc
= (void *)mcman_eccdata
;
3562 if (pmce
[i
/ mcdi
->pages_per_cluster
] != 0) {
3563 r
= McWritePage(mce
->mc_port
, mce
->mc_slot
, (block
* blocksize
) + i
, mcman_pagedata
[i
], p_ecc
);
3564 if (r
== sceMcResFailReplace
) {
3565 r
= mcman_fillbackupblock1(mce
->mc_port
, mce
->mc_slot
, block
, (void**)mcman_pagedata
, mcman_eccdata
);
3566 for (i
= 0; i
< clusters_per_block
; i
++) {
3568 pmce
[i
]->wr_flag
= 0;
3570 if (r
== sceMcResFailReplace
)
3574 if (r
!= sceMcResSucceed
)
3578 } while (++i
< mcdi
->blocksize
);
3581 if (clusters_per_block
> 0) {
3585 pmce
[i
]->wr_flag
= 0;
3586 } while (++i
< clusters_per_block
);
3589 if ((flag
!= 0) && (mcman_badblock
<= 0)) {
3590 r
= mcman_eraseblock(mce
->mc_port
, mce
->mc_slot
, mcdi
->backup_block2
, NULL
, NULL
);
3591 if (r
== sceMcResFailReplace
) {
3594 if (r
!= sceMcResSucceed
)
3600 r
= mcman_replaceBackupBlock(mce
->mc_port
, mce
->mc_slot
, mcdi
->backup_block2
);
3601 mcdi
->backup_block2
= r
;
3605 return sceMcResSucceed
;
3608 //--------------------------------------------------------------
3609 int mcman_readcluster(int port
, int slot
, int cluster
, McCacheEntry
**pmce
)
3611 register int r
, i
, block
, block_offset
;
3612 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3615 if (mcman_badblock
> 0) {
3616 block
= cluster
/ mcdi
->clusters_per_block
;
3617 block_offset
= cluster
% mcdi
->clusters_per_block
;
3619 if ((block
== mcman_badblock
) && (mcman_badblock_port
== port
) && (mcman_badblock_slot
== slot
)) {
3620 cluster
= (mcdi
->backup_block1
* mcdi
->clusters_per_block
) + block_offset
;
3623 if (mcman_badblock
> 0) {
3624 for (i
= 0; i
< mcdi
->clusters_per_block
; i
++) {
3625 if ((mcman_replacementcluster
[i
] != 0) && (mcman_replacementcluster
[i
] == cluster
)) {
3626 block_offset
= i
% mcdi
->clusters_per_block
;
3627 cluster
= (mcdi
->backup_block1
* mcdi
->clusters_per_block
) + block_offset
;
3634 mce
= mcman_getcacheentry(port
, slot
, cluster
);
3636 mce
= pmcman_mccache
[MAX_CACHEENTRY
- 1];
3638 if (mce
->wr_flag
!= 0) {
3639 r
= mcman_flushcacheentry((McCacheEntry
*)mce
);
3640 if (r
!= sceMcResSucceed
)
3644 mce
->mc_port
= port
;
3645 mce
->mc_slot
= slot
;
3646 mce
->cluster
= cluster
;
3648 //s3 = (cluster * mcdi->pages_per_cluster);
3650 for (i
= 0; i
< mcdi
->pages_per_cluster
; i
++) {
3651 r
= McReadPage(port
, slot
, (cluster
* mcdi
->pages_per_cluster
) + i
, \
3652 (void *)(mce
->cl_data
+ (i
* mcdi
->pagesize
)));
3653 if (r
!= sceMcResSucceed
)
3658 mcman_addcacheentry(mce
);
3659 *pmce
= (McCacheEntry
*)mce
;
3661 return sceMcResSucceed
;
3664 //--------------------------------------------------------------
3665 int mcman_readdirentry(int port
, int slot
, int cluster
, int fsindex
, McFsEntry
**pfse
) // Export #47 XMCMAN only
3668 static int maxent
, index
, clust
;
3669 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3670 register McFatCache
*fci
= &mcman_fatcache
[port
][slot
];
3674 DPRINTF("mcman: mcman_readdirentry port%d slot%d cluster %d fsindex %d\n", port
, slot
, cluster
, fsindex
);
3677 maxent
= 0x402 / (mcdi
->cluster_size
>> 9); //a1
3678 index
= fsindex
/ (mcdi
->cluster_size
>> 9);//s2
3682 if ((cluster
== 0) && (index
!= 0)) {
3683 if (index
< maxent
) {
3685 if ((fci
->entry
[index
]) >= 0 )
3686 clust
= fci
->entry
[index
];
3693 if (fci
->entry
[i
] < 0)
3695 clust
= fci
->entry
[i
];
3696 } while (++i
< index
);
3703 r
= mcman_getFATentry(port
, slot
, clust
, &clust
);
3704 if (r
!= sceMcResSucceed
)
3707 if (clust
== 0xffffffff)
3708 return sceMcResNoEntry
;
3709 clust
&= 0x7fffffff;
3714 fci
->entry
[i
] = clust
;
3716 } while (i
< index
);
3719 r
= mcman_readcluster(port
,slot
, mcdi
->alloc_offset
+ clust
, &mce
);
3720 if (r
!= sceMcResSucceed
)
3723 *pfse
= (McFsEntry
*)(mce
->cl_data
+ ((fsindex
% (mcdi
->cluster_size
>> 9)) << 9));
3725 return sceMcResSucceed
;
3728 //--------------------------------------------------------------
3729 int mcman_readdirentryPS1(int port
, int slot
, int cluster
, McFsEntryPS1
**pfse
)
3731 register int r
, offset
, index
, pages_per_fatclust
;
3733 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3738 pages_per_fatclust
= MCMAN_CLUSTERSIZE
/ mcdi
->pagesize
;
3741 index
= cluster
/ pages_per_fatclust
;
3742 offset
= cluster
% pages_per_fatclust
;
3744 r
= mcman_readclusterPS1(port
, slot
, index
* pages_per_fatclust
, &mce
);
3745 if (r
!= sceMcResSucceed
)
3748 *pfse
= (void *)&mce
->cl_data
[offset
<< 7];
3750 if (sio2man_type
== XSIO2MAN
) {
3751 McFsEntryPS1
*fse
= (McFsEntryPS1
*)*pfse
; // <--- XMCMAN seems to work with this
3752 fse
->field_7d
= 0; //
3755 return sceMcResSucceed
;
3758 //--------------------------------------------------------------
3759 int mcman_setFATentry(int port
, int slot
, int fat_index
, int fat_entry
) // Export #46 XMCMAN only
3761 register int r
, ifc_index
, indirect_index
, indirect_offset
, fat_offset
;
3763 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3765 //DPRINTF("mcman: mcman_setFATentry port%d slot%d fat_index %x fat_entry %x\n", port, slot, fat_index, fat_entry);
3767 indirect_index
= fat_index
/ mcdi
->FATentries_per_cluster
;
3768 fat_offset
= fat_index
% mcdi
->FATentries_per_cluster
;
3770 ifc_index
= indirect_index
/ mcdi
->FATentries_per_cluster
;
3771 indirect_offset
= indirect_index
% mcdi
->FATentries_per_cluster
;
3773 r
= mcman_readcluster(port
, slot
, mcdi
->ifc_list
[ifc_index
], &mce
);
3774 if (r
!= sceMcResSucceed
)
3777 McFatCluster
*fc
= (McFatCluster
*)mce
->cl_data
;
3779 r
= mcman_readcluster(port
, slot
, fc
->entry
[indirect_offset
], &mce
);
3780 if (r
!= sceMcResSucceed
)
3783 fc
= (McFatCluster
*)mce
->cl_data
;
3785 fc
->entry
[fat_offset
] = fat_entry
;
3788 return sceMcResSucceed
;
3791 //--------------------------------------------------------------
3792 int mcman_getFATentry(int port
, int slot
, int fat_index
, int *fat_entry
) // Export #44 XMCMAN only
3794 register int r
, ifc_index
, indirect_index
, indirect_offset
, fat_offset
;
3796 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3798 indirect_index
= fat_index
/ mcdi
->FATentries_per_cluster
;
3799 fat_offset
= fat_index
% mcdi
->FATentries_per_cluster
;
3801 ifc_index
= indirect_index
/ mcdi
->FATentries_per_cluster
;
3802 indirect_offset
= indirect_index
% mcdi
->FATentries_per_cluster
;
3804 r
= mcman_readcluster(port
, slot
, mcdi
->ifc_list
[ifc_index
], &mce
);
3805 if (r
!= sceMcResSucceed
)
3808 McFatCluster
*fc
= (McFatCluster
*)mce
->cl_data
;
3810 r
= mcman_readcluster(port
, slot
, fc
->entry
[indirect_offset
], &mce
);
3811 if (r
!= sceMcResSucceed
)
3814 fc
= (McFatCluster
*)mce
->cl_data
;
3816 *fat_entry
= fc
->entry
[fat_offset
];
3818 return sceMcResSucceed
;
3821 //--------------------------------------------------------------
3822 int mcman_readclusterPS1(int port
, int slot
, int cluster
, McCacheEntry
**pmce
)
3824 register int r
, i
, pages_per_fatclust
;
3825 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3828 mce
= mcman_getcacheentry(port
, slot
, cluster
);
3830 mce
= pmcman_mccache
[MAX_CACHEENTRY
- 1];
3832 if (mce
->wr_flag
!= 0) {
3833 r
= mcman_flushcacheentry((McCacheEntry
*)mce
);
3834 if (r
!= sceMcResSucceed
)
3838 mce
->mc_port
= port
;
3839 mce
->mc_slot
= slot
;
3840 mce
->cluster
= cluster
;
3842 pages_per_fatclust
= MCMAN_CLUSTERSIZE
/ mcdi
->pagesize
;
3844 for (i
= 0; i
< pages_per_fatclust
; i
++) {
3845 r
= McReadPS1PDACard(port
, slot
, cluster
+ i
, (void *)(mce
->cl_data
+ (i
* mcdi
->pagesize
)));
3846 if (r
!= sceMcResSucceed
)
3851 mcman_addcacheentry(mce
);
3852 *pmce
= (McCacheEntry
*)mce
;
3854 return sceMcResSucceed
;
3857 //--------------------------------------------------------------
3858 int mcman_replaceBackupBlock(int port
, int slot
, int block
)
3861 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3863 if (mcman_badblock
> 0)
3864 return sceMcResFailReplace
;
3866 for (i
= 0; i
< 16; i
++) {
3867 if (mcdi
->bad_block_list
[i
] == -1)
3872 if ((mcdi
->alloc_end
- mcdi
->max_allocatable_clusters
) < 8)
3873 return sceMcResFullDevice
;
3875 mcdi
->alloc_end
-= 8;
3876 mcdi
->bad_block_list
[i
] = block
;
3877 mcman_badblock_port
= port
;
3878 mcman_badblock_slot
= slot
;
3879 mcman_badblock
= -1;
3881 return (mcdi
->alloc_offset
+ mcdi
->alloc_end
) / mcdi
->clusters_per_block
;
3884 return sceMcResFullDevice
;
3887 //--------------------------------------------------------------
3888 int mcman_fillbackupblock1(int port
, int slot
, int block
, void **pagedata
, void *eccdata
)
3890 register int r
, i
, sparesize
, page_offset
;
3891 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
3895 DPRINTF("mcman: mcman_fillbackupblock1 port%d slot%d block %x mcman_badblock %x\n", port
, slot
, block
, mcman_badblock
);
3898 sparesize
= mcman_sparesize(port
, slot
);
3900 if (mcman_badblock
!= 0) {
3901 if ((mcman_badblock
!= block
) || (mcman_badblock_port
!= port
) || (mcman_badblock_slot
!= slot
))
3902 return sceMcResFailReplace
;
3905 if ((mcdi
->alloc_offset
/ mcdi
->clusters_per_block
) == block
) // Appparently this refuse to take care of a bad rootdir cluster
3906 return sceMcResFailReplace
;
3908 r
= mcman_eraseblock(port
, slot
, mcdi
->backup_block2
, NULL
, NULL
);
3909 if (r
!= sceMcResSucceed
)
3912 r
= mcman_eraseblock(port
, slot
, mcdi
->backup_block1
, NULL
, NULL
);
3913 if (r
!= sceMcResSucceed
)
3916 for (i
= 0; i
< 16; i
++) {
3917 if (mcdi
->bad_block_list
[i
] == -1)
3922 return sceMcResFailReplace
;
3924 page_offset
= mcdi
->backup_block1
* mcdi
->blocksize
;
3925 p_ecc
= (u8
*)eccdata
;
3927 for (i
= 0; i
< mcdi
->blocksize
; i
++) {
3928 r
= McWritePage(port
, slot
, page_offset
+ i
, pagedata
[i
], p_ecc
);
3929 if (r
!= sceMcResSucceed
)
3934 mcman_badblock_port
= port
;
3935 mcman_badblock_slot
= slot
;
3936 mcman_badblock
= block
;
3940 mcman_replacementcluster
[i
] = 0;
3943 return sceMcResSucceed
;
3946 //--------------------------------------------------------------
3947 int mcman_replacebadblock(void)
3949 register int r
, i
, curentry
, clust
, index
, offset
, numifc
, fat_length
, temp
, length
;
3950 register int value
, value2
, cluster
, index2
, offset2
, s3
;
3951 register MCDevInfo
*mcdi
= &mcman_devinfos
[mcman_badblock_port
][mcman_badblock_slot
];
3958 DPRINTF("mcman: mcman_replacebadblock mcman_badblock_port%d mcman_badblock_slot%d mcman_badblock %x\n", mcman_badblock_port
, mcman_badblock_slot
, mcman_badblock
);
3961 if (mcman_badblock
== 0)
3962 return sceMcResSucceed
;
3964 if (mcman_badblock
>= 0) {
3965 mcman_flushmccache(mcman_badblock_port
, mcman_badblock_slot
);
3966 mcman_clearcache(mcman_badblock_port
, mcman_badblock_slot
);
3968 for (i
= 0; i
<16; i
++) {
3969 if (mcdi
->bad_block_list
[i
] == -1)
3975 if (mcdi
->alloc_end
>= (mcdi
->max_allocatable_clusters
+ 8)) {
3976 mcdi
->max_allocatable_clusters
+= 8;
3977 mcdi
->bad_block_list
[i
] = mcman_badblock
;
3980 fat_length
= (((mcdi
->clusters_per_card
<< 2) - 1) / mcdi
->cluster_size
) + 1;
3981 numifc
= (((fat_length
<< 2) - 1) / mcdi
->cluster_size
) + 1;
3985 fat_length
= mcdi
->FATentries_per_cluster
<< 5;
3989 value
= ~(-1 << mcdi
->clusters_per_block
);
3991 clust
= (mcman_badblock
* mcdi
->clusters_per_block
) + i
;
3992 if (clust
< mcdi
->alloc_offset
) {
3996 r
= mcman_getFATentry(mcman_badblock_port
, mcman_badblock_slot
, clust
- mcdi
->alloc_offset
, &fat_entry
[i
]);
3997 if (r
!= sceMcResSucceed
)
4000 if (((fat_entry
[i
] & 0x80000000) == 0) || ((fat_entry
[i
] < -1) && (fat_entry
[i
] >= -9)))
4003 } while (++i
< mcdi
->clusters_per_block
);
4005 if (mcdi
->clusters_per_block
> 0) {
4008 if ((value
& (1 << i
)) != 0) {
4009 r
= mcman_findfree2(mcman_badblock_port
, mcman_badblock_slot
, 1);
4011 mcman_replacementcluster
[i
] = r
;
4014 r
+= mcdi
->alloc_offset
;
4015 mcman_replacementcluster
[i
] = r
;
4017 } while (++i
< mcdi
->clusters_per_block
);
4020 if (mcdi
->clusters_per_block
> 0) {
4023 if ((value
& (1 << i
)) != 0) {
4024 if (fat_entry
[i
] != 0) {
4025 index
= ((fat_entry
[i
] & 0x7fffffff) + mcdi
->alloc_offset
) / mcdi
->clusters_per_block
;
4026 offset
= ((fat_entry
[i
] & 0x7fffffff) + mcdi
->alloc_offset
) % mcdi
->clusters_per_block
;
4027 if (index
== mcman_badblock
) {
4028 fat_entry
[i
] = (mcman_replacementcluster
[offset
] - mcdi
->alloc_offset
) | 0x80000000;
4032 } while (++i
< mcdi
->clusters_per_block
);
4035 if (mcdi
->clusters_per_block
> 0) {
4038 if ((mcman_replacementcluster
[i
] != 0) && (fat_entry
[i
] != 0)) {
4039 r
= mcman_setFATentry(mcman_badblock_port
, mcman_badblock_slot
, mcman_replacementcluster
[i
] + mcdi
->alloc_offset
, fat_entry
[i
]);
4040 if (r
!= sceMcResSucceed
)
4043 } while (++i
< mcdi
->clusters_per_block
);
4046 for (i
= 0; i
< numifc
; i
++) {
4047 index
= mcdi
->ifc_list
[i
] / mcdi
->clusters_per_block
;
4048 offset
= mcdi
->ifc_list
[i
] % mcdi
->clusters_per_block
;
4050 if (index
== mcman_badblock
) {
4051 value
&= ~(1 << offset
);
4052 mcdi
->ifc_list
[i
] = mcman_replacementcluster
[i
];
4059 for (i
= 0; i
< fat_length
; i
++) {
4060 index
= i
/ mcdi
->FATentries_per_cluster
;
4061 offset
= i
% mcdi
->FATentries_per_cluster
;
4064 r
= mcman_readcluster(mcman_badblock_port
, mcman_badblock_slot
, mcdi
->ifc_list
[index
], &mce
);
4065 if (r
!= sceMcResSucceed
)
4068 offset
= i
% mcdi
->FATentries_per_cluster
;
4069 index2
= *((u32
*)&mce
->cl_data
[offset
]) / mcdi
->clusters_per_block
;
4070 offset2
= *((u32
*)&mce
->cl_data
[offset
]) % mcdi
->clusters_per_block
;
4072 if (index2
== mcman_badblock
) {
4073 value
&= ~(1 << offset2
);
4074 *((u32
*)&mce
->cl_data
[offset
]) = mcman_replacementcluster
[offset2
];
4079 mcman_flushmccache(mcman_badblock_port
, mcman_badblock_slot
);
4080 mcman_clearcache(mcman_badblock_port
, mcman_badblock_slot
);
4087 for (i
= 0; i
< mcdi
->alloc_end
; i
++) {
4088 r
= mcman_getFATentry(mcman_badblock_port
, mcman_badblock_slot
, i
, &fat_entry2
);
4089 if (r
!= sceMcResSucceed
)
4092 index
= (u32
)(((fat_entry2
& 0x7fffffff) + mcdi
->alloc_offset
) / mcdi
->clusters_per_block
);
4093 offset
= (u32
)(((fat_entry2
& 0x7fffffff) + mcdi
->alloc_offset
) % mcdi
->clusters_per_block
);
4095 if (index
== mcman_badblock
) {
4096 value
&= ~(1 << offset
);
4097 r
= mcman_setFATentry(mcman_badblock_port
, mcman_badblock_slot
, i
, (mcman_replacementcluster
[offset
] - mcdi
->alloc_offset
) | 0x80000000);
4098 if (r
!= sceMcResSucceed
)
4103 if (value2
!= value
)
4104 mcman_flushmccache(mcman_badblock_port
, mcman_badblock_slot
);
4106 r
= mcman_readdirentry(mcman_badblock_port
, mcman_badblock_slot
, 0, 0, &fse
);
4107 if (r
!= sceMcResSucceed
)
4112 length
= fse
->length
;
4115 if (curentry
>= length
)
4118 r
= mcman_readdirentry(mcman_badblock_port
, mcman_badblock_slot
, s3
, curentry
, &fse
);
4119 if (r
!= sceMcResSucceed
)
4122 cluster
= fse
->cluster
;
4123 index
= (fse
->cluster
+ mcdi
->alloc_offset
) / mcdi
->clusters_per_block
;
4124 offset
= (fse
->cluster
+ mcdi
->alloc_offset
) % mcdi
->clusters_per_block
;
4128 if (index
== mcman_badblock
) {
4129 fse
->cluster
= mcman_replacementcluster
[offset
] - mcdi
->alloc_offset
;
4130 mcman_1stcacheEntsetwrflagoff();
4133 if ((fse
->mode
& sceMcFileAttrSubdir
) == 0) {
4138 r
= mcman_readdirentry(mcman_badblock_port
, mcman_badblock_slot
, cluster
, 0, &fse
);
4139 if (r
!= sceMcResSucceed
)
4142 if ((fse
->mode
& sceMcFileAttrSubdir
) == 0) {
4147 if (fse
->cluster
!= 0) {
4152 if (fse
->dir_entry
!= curentry
) {
4159 if (strcmp(fse
->name
, "."))
4168 r
= mcman_readdirentry(mcman_badblock_port
, mcman_badblock_slot
, s3
, 1, &fse
);
4169 if (r
!= sceMcResSucceed
)
4172 index
= (fse
->cluster
+ mcdi
->alloc_offset
) / mcdi
->clusters_per_block
;
4173 offset
= (fse
->cluster
+ mcdi
->alloc_offset
) % mcdi
->clusters_per_block
;
4175 if (index
== mcman_badblock
) {
4176 fse
->cluster
= mcman_replacementcluster
[offset
] - mcdi
->alloc_offset
;
4177 mcman_1stcacheEntsetwrflagoff();
4180 r
= mcman_readdirentry(mcman_badblock_port
, mcman_badblock_slot
, fse
->cluster
, fse
->dir_entry
, &fse
);
4181 if (r
!= sceMcResSucceed
)
4184 length
= fse
->length
;
4186 r
= mcman_readdirentry(mcman_badblock_port
, mcman_badblock_slot
, s3
, 0, &fse
);
4187 if (r
!= sceMcResSucceed
)
4191 index
= (fse
->cluster
+ mcdi
->alloc_offset
) / mcdi
->clusters_per_block
;
4192 offset
= (fse
->cluster
+ mcdi
->alloc_offset
) % mcdi
->clusters_per_block
;
4193 curentry
= fse
->dir_entry
+ 1;
4195 if (index
== mcman_badblock
) {
4196 fse
->cluster
= mcman_replacementcluster
[offset
] - mcdi
->alloc_offset
;
4197 mcman_1stcacheEntsetwrflagoff();
4207 if (mcdi
->clusters_per_block
> 0) {
4210 clust
= (mcman_badblock
* mcdi
->clusters_per_block
) + i
;
4211 if (clust
>= mcdi
->alloc_offset
) {
4212 r
= mcman_setFATentry(mcman_badblock_port
, mcman_badblock_slot
, clust
- mcdi
->alloc_offset
, 0xfffffffd);
4213 if (r
!= sceMcResSucceed
)
4216 } while (++i
< mcdi
->clusters_per_block
);
4219 mcman_flushmccache(mcman_badblock_port
, mcman_badblock_slot
);
4220 mcman_clearcache(mcman_badblock_port
, mcman_badblock_slot
);
4224 if (mcdi
->clusters_per_block
> 0) {
4227 if (mcman_replacementcluster
[i
] != 0) {
4228 r
= mcman_readcluster(mcman_badblock_port
, mcman_badblock_slot
, (mcdi
->backup_block1
* mcdi
->clusters_per_block
) + i
, &mce
);
4229 if (r
!= sceMcResSucceed
)
4232 mce
->cluster
= mcman_replacementcluster
[i
];
4235 } while (++i
< mcdi
->clusters_per_block
);
4238 mcman_flushmccache(mcman_badblock_port
, mcman_badblock_slot
);
4244 r
= mcman_clearsuperblock(mcman_badblock_port
, mcman_badblock_slot
);
4249 return sceMcResFailReplace
;
4252 //--------------------------------------------------------------
4253 int mcman_clearsuperblock(int port
, int slot
)
4255 register int r
, i
, size
, temp
;
4256 register MCDevInfo
*mcdi
= &mcman_devinfos
[port
][slot
];
4259 // set superblock magic & version
4260 memset((void *)&mcdi
->magic
, 0, sizeof (mcdi
->magic
) + sizeof (mcdi
->version
));
4261 *((u32
*)&mcdi
->magic
) = *((u32
*)&SUPERBLOCK_MAGIC
);
4262 *((u32
*)&mcdi
->magic
+ 1) = *((u32
*)&SUPERBLOCK_MAGIC
+ 1);
4263 *((u32
*)&mcdi
->magic
+ 2) = *((u32
*)&SUPERBLOCK_MAGIC
+ 2);
4264 *((u32
*)&mcdi
->magic
+ 3) = *((u32
*)&SUPERBLOCK_MAGIC
+ 3);
4265 *((u32
*)&mcdi
->magic
+ 4) = *((u32
*)&SUPERBLOCK_MAGIC
+ 4);
4266 *((u32
*)&mcdi
->magic
+ 5) = *((u32
*)&SUPERBLOCK_MAGIC
+ 5);
4267 *((u32
*)&mcdi
->magic
+ 6) = *((u32
*)&SUPERBLOCK_MAGIC
+ 6);
4268 *((u8
*)&mcdi
->magic
+ 28) = *((u8
*)&SUPERBLOCK_MAGIC
+ 28);
4270 strcat((char *)&mcdi
->magic
, SUPERBLOCK_VERSION
);
4272 for (i
= 0; (u32
)(i
< sizeof(MCDevInfo
)); i
+= 1024) {
4276 r
= mcman_readcluster(port
, slot
, temp
>> 10, &mce
);
4277 if (r
!= sceMcResSucceed
)
4281 temp
= sizeof(MCDevInfo
) - i
;
4286 memcpy((void *)mce
->cl_data
, (void *)mcdi
, size
);
4289 r
= mcman_flushmccache(port
, slot
);
4294 //--------------------------------------------------------------