PS2SDK
PS2 Homebrew Libraries
ps2mc_fio.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright (c) 2009 jimmikaelkael
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include <mcman.h>
12 #include "mcman-internal.h"
13 
14 static int mcman_curdirmaxent;
15 static int mcman_curdirlength;
16 static char mcman_curdirpath[1024];
17 static const char *mcman_curdirname;
18 static sceMcStDateTime mcman_fsmodtime;
19 
20 //--------------------------------------------------------------
21 int mcman_format2(int port, int slot)
22 {
23  register int r, i, size, ifc_index, indirect_offset, allocatable_clusters_per_card;
24  register int ifc_length, fat_length, fat_entry, alloc_offset;
25  register int j = 0, z = 0;
26  MCDevInfo *mcdi = &mcman_devinfos[port][slot];
27  McCacheEntry *mce;
28 
29  DPRINTF("mcman_format2 port%d, slot%d cardform %d\n", port, slot, mcdi->cardform);
30 
31  if (mcdi->cardform < 0) {
32  for (i = 0; i < 32; i++)
33  mcdi->bad_block_list[i] = -1;
34  mcdi->rootdir_cluster = 0;
35  mcdi->rootdir_cluster2 = 0;
36  goto lbl1;
37  }
38 
39  if (mcdi->cardform > 0) {
40  if (((mcdi->version[0] - 48) >= 2) || ((mcdi->version[2] - 48) >= 2))
41  goto lbl1;
42  }
43 
44  r = mcman_reportBadBlocks(port, slot);
45  if ((r != sceMcResSucceed) && (r != sceMcResNoFormat))
46  return sceMcResChangedCard;
47 
48 lbl1:
49  // set superblock magic & version
50  memset((void *)&mcdi->magic, 0, sizeof (mcdi->magic) + sizeof (mcdi->version));
51  strcpy(mcdi->magic, SUPERBLOCK_MAGIC);
52  strcat(mcdi->magic, SUPERBLOCK_VERSION);
53 
54  //size = 8192 / mcdi->cluster_size; // get blocksize in cluster a better way must be found
55  size = mcdi->blocksize;
56  mcdi->cardform = -1;
57 
58  mcman_wr_port = -1;
59  mcman_wr_slot = -1;
60  mcman_wr_block = -1;
61  mcman_wr_flag3 = -10;
62 
63  //if (size <= 0)
64  // size = 1;
65  if (mcdi->blocksize <= 0)
66  size = 8;
67 
68  // clear first 8 clusters
69  for (i = 0; i < size; i++) {
70  r = mcman_writecluster(port, slot, i, 1);
71  if (r == 0)
72  return sceMcResNoFormat;
73 
74  if (r != 1)
75  return -40;
76  }
77 
78  fat_length = (((mcdi->clusters_per_card << 2) - 1) / mcdi->cluster_size) + 1; // get length of fat in clusters
79  ifc_length = (((fat_length << 2) - 1) / mcdi->cluster_size) + 1; // get number of needed ifc clusters
80 
81  if (!(ifc_length <= 32)) {
82  ifc_length = 32;
83  fat_length = mcdi->FATentries_per_cluster << 5;
84  }
85 
86  // clear ifc clusters
87  if (ifc_length > 0) {
88  j = 0;
89  do {
90  if ((u32)i >= mcdi->clusters_per_card)
91  return sceMcResNoFormat;
92 
93  do {
94  if (mcman_writecluster(port, slot, i, 1) != 0)
95  break;
96 
97  i++;
98  } while ((u32)i < mcdi->clusters_per_card);
99 
100  if ((u32)i >= mcdi->clusters_per_card)
101  return sceMcResNoFormat;
102 
103  mcdi->ifc_list[j] = i;
104  j++;
105  i++;
106  } while (j < ifc_length);
107  }
108 
109  // read ifc clusters to mc cache and clear fat clusters
110  if (fat_length > 0) {
111  j = 0;
112 
113  do {
114  ifc_index = j / mcdi->FATentries_per_cluster;
115  indirect_offset = j % mcdi->FATentries_per_cluster;
116 
117  if (indirect_offset == 0) {
118  if (McReadCluster(port, slot, mcdi->ifc_list[ifc_index], &mce) != sceMcResSucceed)
119  return -42;
120  mce->wr_flag = 1;
121  }
122 
123  if ((u32)i >= mcdi->clusters_per_card)
124  return sceMcResNoFormat;
125 
126  do {
127  r = mcman_writecluster(port, slot, i, 1);
128  if (r == 1)
129  break;
130 
131  if (r < 0)
132  return -43;
133 
134  i++;
135  } while ((u32)i < mcdi->clusters_per_card);
136 
137  if ((u32)i >= mcdi->clusters_per_card)
138  return sceMcResNoFormat;
139 
140  j++;
141  McFatCluster *fc = (McFatCluster *)mce->cl_data;
142  fc->entry[indirect_offset] = i;
143  i++;
144 
145  } while (j < fat_length);
146  }
147  alloc_offset = i;
148 
149  mcdi->backup_block1 = 0;
150  mcdi->backup_block2 = 0;
151 
152  // clear backup blocks
153  for (i = (mcdi->clusters_per_card / mcdi->clusters_per_block) - 1; i > 0; i--) {
154 
155  r = mcman_writecluster(port, slot, mcdi->clusters_per_block * i, 1);
156  if (r < 0)
157  return -44;
158 
159  if ((r != 0) && (mcdi->backup_block1 == 0))
160  mcdi->backup_block1 = i;
161  else if ((r != 0) && (mcdi->backup_block2 == 0)) {
162  mcdi->backup_block2 = i;
163  break;
164  }
165  }
166 
167  // set backup block2 to erased state
168  if (mcman_eraseblock(port, slot, mcdi->backup_block2, NULL, NULL) != sceMcResSucceed)
169  return -45;
170 
171  u32 hi, lo, temp;
172 
173  long_multiply(mcdi->clusters_per_card, 0x10624dd3, &hi, &lo);
174  temp = (hi >> 6) - (mcdi->clusters_per_card >> 31);
175  allocatable_clusters_per_card = (((((temp << 5) - temp) << 2) + temp) << 3) + 1;
176  j = alloc_offset;
177 
178  // checking for bad allocated clusters and building FAT
179  if ((u32)j < i * mcdi->clusters_per_block) {
180  z = 0;
181  do { // quick check for bad clusters
182  r = mcman_writecluster(port, slot, j, 0);
183  if (r == 1) {
184  if (z == 0) {
185  mcdi->alloc_offset = j;
186  mcdi->rootdir_cluster = 0;
187  fat_entry = 0xffffffff; // marking rootdir end
188  }
189  else
190  fat_entry = ~0x80000000; // marking free cluster
191  z++;
192  if (z == allocatable_clusters_per_card)
193  mcdi->max_allocatable_clusters = (j - mcdi->alloc_offset) + 1;
194  }
195  else {
196  if (r != 0)
197  return -45;
198  fat_entry = 0xfffffffd; // marking bad cluster
199  }
200 
201  if (McSetFATentry(port, slot, j - mcdi->alloc_offset, fat_entry) != sceMcResSucceed)
202  return -46;
203 
204  j++;
205  } while ((u32)j < (i * mcdi->clusters_per_block));
206  }
207 
208  mcdi->alloc_end = (i * mcdi->clusters_per_block) - mcdi->alloc_offset;
209 
210  if (mcdi->max_allocatable_clusters == 0)
211  mcdi->max_allocatable_clusters = i * mcdi->clusters_per_block;
212 
213  if ((u32)z < mcdi->clusters_per_block)
214  return sceMcResNoFormat;
215 
216  // read superblock to mc cache
217  for (i = 0; (unsigned int)i < sizeof (MCDevInfo); i += MCMAN_CLUSTERSIZE) {
218  if (i < 0)
219  size = i + (MCMAN_CLUSTERSIZE - 1);
220  else
221  size = i;
222 
223  if (McReadCluster(port, slot, size >> 10, &mce) != sceMcResSucceed)
224  return -48;
225 
226  size = MCMAN_CLUSTERSIZE;
227  mce->wr_flag = 1;
228 
229  if ((sizeof (MCDevInfo) - i) <= 1024)
230  size = sizeof (MCDevInfo) - i;
231 
232  memcpy((void *)mce->cl_data, (void *)(mcdi + i), size);
233  }
234 
235  mcdi->unknown1 = 0;
236  mcdi->unknown2 = 0;
237  mcdi->unknown5 = -1;
238  mcdi->rootdir_cluster2 = mcdi->rootdir_cluster;
239 
240  // Create root dir
241  if (McCreateDirentry(port, slot, 0, 0, 0, NULL) != sceMcResSucceed)
242  return -49;
243 
244  // finally flush cache to memcard
245  r = McFlushCache(port, slot);
246  if (r != sceMcResSucceed)
247  return r;
248 
249  mcdi->cardform = 1;
250 
251  return sceMcResSucceed;
252 }
253 
254 //--------------------------------------------------------------
255 int mcman_dread2(int fd, MC_IO_DRE_T *dirent)
256 {
257  register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
258  McFsEntry *fse;
259 
260  DPRINTF("mcman_dread2 fd %d\n", fd);
261 
262  if (fh->position >= fh->filesize)
263  return sceMcResSucceed;
264 
265  do {
266  register int r;
267 
268  r = McReadDirEntry(fh->port, fh->slot, fh->freeclink, fh->position, &fse);
269  if (r != sceMcResSucceed)
270  return r;
271 
272  if (fse->mode & sceMcFileAttrExists)
273  break;
274 
275  fh->position++;
276  } while (fh->position < fh->filesize);
277 
278  if (fh->position >= fh->filesize)
279  return sceMcResSucceed;
280 
281  fh->position++;
282  mcman_wmemset((void *)dirent, sizeof (MC_IO_DRE_T), 0);
283  strcpy(dirent->name, fse->name);
284  *(u8 *)&dirent->name[32] = 0;
285 
286  if (fse->mode & sceMcFileAttrReadable)
287  dirent->stat.mode |= MC_IO_S_RD;
288  if (fse->mode & sceMcFileAttrWriteable)
289  dirent->stat.mode |= MC_IO_S_WR;
290  if (fse->mode & sceMcFileAttrExecutable)
291  dirent->stat.mode |= MC_IO_S_EX;
292 #if !MCMAN_ENABLE_EXTENDED_DEV_OPS
293  if (fse->mode & sceMcFileAttrPS1)
294  dirent->stat.mode |= sceMcFileAttrPS1;
295  if (fse->mode & sceMcFileAttrPDAExec)
296  dirent->stat.mode |= sceMcFileAttrPDAExec;
297  if (fse->mode & sceMcFileAttrDupProhibit)
298  dirent->stat.mode |= sceMcFileAttrDupProhibit;
299 #endif
300  if (fse->mode & sceMcFileAttrSubdir)
301  dirent->stat.mode |= MC_IO_S_DR;
302  else
303  dirent->stat.mode |= MC_IO_S_FL;
304 
305  dirent->stat.attr = fse->attr;
306  dirent->stat.size = fse->length;
307  memcpy(dirent->stat.ctime, &fse->created, sizeof(sceMcStDateTime));
308  memcpy(dirent->stat.mtime, &fse->modified, sizeof(sceMcStDateTime));
309 
310  return 1;
311 }
312 
313 //--------------------------------------------------------------
314 int mcman_getstat2(int port, int slot, const char *filename, MC_IO_STA_T *stat)
315 {
316  register int r;
317  McFsEntry *fse;
318 
319  DPRINTF("mcman_getstat2 port%d slot%d filename %s\n", port, slot, filename);
320 
321  r = mcman_cachedirentry(port, slot, filename, NULL, &fse, 1);
322  if (r != sceMcResSucceed)
323  return r;
324 
325  mcman_wmemset((void *)stat, sizeof (MC_IO_STA_T), 0);
326 
327  if (fse->mode & sceMcFileAttrReadable)
328  stat->mode |= MC_IO_S_RD;
329  if (fse->mode & sceMcFileAttrWriteable)
330  stat->mode |= MC_IO_S_WR;
331  if (fse->mode & sceMcFileAttrExecutable)
332  stat->mode |= MC_IO_S_EX;
333 #if !MCMAN_ENABLE_EXTENDED_DEV_OPS
334  if (fse->mode & sceMcFileAttrPS1)
335  stat->mode |= sceMcFileAttrPS1;
336  if (fse->mode & sceMcFileAttrPDAExec)
337  stat->mode |= sceMcFileAttrPDAExec;
338  if (fse->mode & sceMcFileAttrDupProhibit)
339  stat->mode |= sceMcFileAttrDupProhibit;
340 #endif
341  if (fse->mode & sceMcFileAttrSubdir)
342  stat->mode |= MC_IO_S_DR;
343  else
344  stat->mode |= MC_IO_S_FL;
345 
346  stat->attr = fse->attr;
347 
348  if (!(fse->mode & sceMcFileAttrSubdir))
349  stat->size = fse->length;
350 
351  memcpy(stat->ctime, &fse->created, sizeof(sceMcStDateTime));
352  memcpy(stat->mtime, &fse->modified, sizeof(sceMcStDateTime));
353 
354  return sceMcResSucceed;
355 }
356 
357 //--------------------------------------------------------------
358 int mcman_setinfo2(int port, int slot, const char *filename, sceMcTblGetDir *info, int flags)
359 {
360  register int r, fmode;
361  McFsEntry *fse;
362  McCacheDir dirInfo;
363  McFsEntry mfe;
364 
365  DPRINTF("mcman_setinfo2 port%d slot%d filename %s flags %x\n", port, slot, filename, flags);
366 
367  r = mcman_cachedirentry(port, slot, filename, &dirInfo, &fse, 1); //dirInfo=sp218 fse=sp228
368  if (r != sceMcResSucceed)
369  return r;
370 
371  if ((flags & sceMcFileAttrFile) != 0) {
372  u8 *pfsentry, *pfseend, *mfee;
373 
374  if ((!strcmp(".", info->EntryName)) || (!strcmp("..", info->EntryName)))
375  return sceMcResNoEntry;
376 
377  if (info->EntryName[0] == 0)
378  return sceMcResNoEntry;
379 
380  r = mcman_chrpos(info->EntryName, '/');
381  if (r >= 0)
382  return sceMcResNoEntry;
383 
384  if (dirInfo.fsindex < 2)
385  return sceMcResNoEntry;
386 
387  r = McReadDirEntry(port, slot, dirInfo.cluster, 0, &fse);
388  if (r != sceMcResSucceed)
389  return r;
390 
391  r = McReadDirEntry(port, slot, fse->cluster, fse->dir_entry, &fse);
392  if (r != sceMcResSucceed)
393  return r;
394 
395  pfsentry = (u8 *)fse;
396  mfee = (u8 *)&mfe;
397  pfseend = (u8 *)(pfsentry + sizeof (McFsEntry));
398 
399  do {
400  *((u32 *)mfee ) = *((u32 *)pfsentry );
401  *((u32 *)mfee+1) = *((u32 *)pfsentry+1);
402  *((u32 *)mfee+2) = *((u32 *)pfsentry+2);
403  *((u32 *)mfee+3) = *((u32 *)pfsentry+3);
404  pfsentry += 16;
405  mfee += 16;
406  } while (pfsentry < pfseend);
407 
408  r = mcman_getdirinfo(port, slot, &mfe, info->EntryName, NULL, 1);
409  if (r != 1) {
410  if (r < 2) {
411  if (r == 0)
412  return sceMcResNoEntry;
413  return r;
414  }
415  else {
416  if (r != 2)
417  return r;
418  return sceMcResDeniedPermit;
419  }
420  }
421  }
422 
423  r = McReadDirEntry(port, slot, dirInfo.cluster, dirInfo.fsindex, &fse);
424  if (r != sceMcResSucceed)
425  return r;
426 
427  Mc1stCacheEntSetWrFlagOff();
428 
429  //Special fix clause for file managers (like uLaunchELF)
430  //This allows writing most entries that can be read by mcGetDir
431  //and without usual restrictions. This flags value should cause no conflict
432  //as Sony code never uses it, and the value is changed after its use here.
433  if(flags == 0xFEED){
434  fse->mode = info->AttrFile;
435  //fse->unused = info->Reserve1;
436  //fse->length = info->FileSizeByte;
437  flags = sceMcFileAttrReadable|sceMcFileAttrWriteable;
438  //The changed flags value allows more entries to be copied below
439  }
440 
441  if ((flags & sceMcFileAttrDupProhibit) != 0)
442  fse->attr = info->Reserve2;
443 
444  if ((flags & sceMcFileAttrExecutable) != 0) {
445  fmode = 0xffff7fcf;
446  if (!PS1CardFlag)
447  fmode = 0x180f;
448  fse->mode = (fse->mode & ~fmode) | (info->AttrFile & fmode);
449  }
450 
451  if ((flags & sceMcFileCreateFile) != 0) {
452  fmode = 0x380f;
453  if (!PS1CardFlag)
454  fmode = 0x180f;
455  fse->mode = (fse->mode & ~fmode) | (info->AttrFile & fmode);
456  }
457 
458  if ((flags & sceMcFileAttrReadable) != 0)
459  fse->created = info->_Create;
460 
461  if ((flags & sceMcFileAttrWriteable) != 0)
462  fse->modified = info->_Modify;
463 
464  if ((flags & sceMcFileAttrFile) != 0) {
465  strncpy(fse->name, info->EntryName, 32);
466  fse->name[31] = 0;
467  }
468 
469  return sceMcResSucceed;
470 }
471 
472 //--------------------------------------------------------------
473 int mcman_read2(int fd, void *buffer, int nbyte)
474 {
475  register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
476  register MCDevInfo *mcdi = &mcman_devinfos[fh->port][fh->slot];
477  McCacheEntry *mce;
478 
479  DPRINTF("mcman_read2 fd %d buf %x size %d\n", fd, (int)buffer, nbyte);
480 
481  if (fh->position < fh->filesize) {
482  register int temp, rpos;
483 
484  temp = fh->filesize - fh->position;
485  if (nbyte > temp)
486  nbyte = temp;
487 
488  rpos = 0;
489  if (nbyte > 0) {
490 
491  do {
492  register int r, size, offset;
493 
494  offset = fh->position % mcdi->cluster_size; // file pointer offset % cluster size
495  temp = mcdi->cluster_size - offset;
496  if (temp < nbyte)
497  size = temp;
498  else
499  size = nbyte;
500 
501  r = mcman_fatRseek(fd);
502 
503  if (r <= 0)
504  return r;
505 
506  r = McReadCluster(fh->port, fh->slot, r, &mce);
507  if (r != sceMcResSucceed)
508  return r;
509 
510  memcpy((void *)((u8 *)buffer + rpos), (void *)((u8 *)(mce->cl_data) + offset), size);
511 
512  rpos += size;
513  mce->rd_flag = 1;
514  nbyte -= size;
515  fh->position += size;
516 
517  } while (nbyte);
518  }
519  return rpos;
520  }
521 
522  return 0;
523 }
524 
525 //--------------------------------------------------------------
526 int mcman_write2(int fd, void *buffer, int nbyte)
527 {
528  register int r, wpos;
529  register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
530  register MCDevInfo *mcdi = &mcman_devinfos[fh->port][fh->slot];
531  McCacheEntry *mce;
532 
533  if (nbyte) {
534  if (fh->unknown2 == 0) {
535  fh->unknown2 = 1;
536  r = mcman_close2(fd);
537  if (r != sceMcResSucceed)
538  return r;
539  r = McFlushCache(fh->port, fh->slot);
540  if (r != sceMcResSucceed)
541  return r;
542  }
543  }
544 
545  wpos = 0;
546  if (nbyte) {
547  do {
548  register int r2, size, offset;
549 
550  r = mcman_fatRseek(fd);
551  if (r == sceMcResFullDevice) {
552 
553  r2 = mcman_fatWseek(fd);
554  if (r2 == r)
555  return sceMcResFullDevice;
556 
557  if (r2 != sceMcResSucceed)
558  return r2;
559 
560  r = mcman_fatRseek(fd);
561  }
562  else {
563  if (r < 0)
564  return r;
565  }
566 
567  r = McReadCluster(fh->port, fh->slot, r, &mce);
568  if (r != sceMcResSucceed)
569  return r;
570 
571  mce->rd_flag = 1;
572 
573  offset = fh->position % mcdi->cluster_size; // file pointer offset % cluster size
574  r2 = mcdi->cluster_size - offset;
575  if (r2 < nbyte)
576  size = r2;
577  else
578  size = nbyte;
579 
580  memcpy((void *)((u8 *)(mce->cl_data) + offset), (void *)((u8 *)buffer + wpos), size);
581 
582  mce->wr_flag = 1;
583 
584  r = fh->position + size;
585  fh->position += size;
586 
587  if ((u32)r < fh->filesize)
588  r = fh->filesize ;
589 
590  fh->filesize = r;
591 
592  nbyte -= size;
593  wpos += size;
594 
595  } while (nbyte);
596  }
597 
598  r = mcman_close2(fd);
599  if (r != sceMcResSucceed)
600  return r;
601 
602  return wpos;
603 }
604 
605 //--------------------------------------------------------------
606 int mcman_close2(int fd)
607 {
608  register int r, fmode;
609  register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
610  McFsEntry *fse1, *fse2;
611 
612  DPRINTF("mcman_close2 fd %d\n", fd);
613 
614  r = McReadDirEntry(fh->port, fh->slot, fh->cluster, fh->fsindex, &fse1);
615  if (r != sceMcResSucceed)
616  return -31;
617 
618  if (fh->unknown2 == 0) {
619  fmode = fse1->mode | sceMcFileAttrClosed;
620  }
621  else {
622  fmode = fse1->mode & 0xff7f;
623  }
624  fse1->mode = fmode;
625 
626  mcman_getmcrtime(&fse1->modified);
627 
628  fse1->cluster = fh->freeclink;
629  fse1->length = fh->filesize;
630 
631  Mc1stCacheEntSetWrFlagOff();
632 
633  mcman_fsmodtime = fse1->modified;
634 
635  r = McReadDirEntry(fh->port, fh->slot, fh->parent_cluster, fh->parent_fsindex, &fse2);
636  if (r != sceMcResSucceed)
637  return r;
638 
639  fse2->modified = mcman_fsmodtime;
640 
641  Mc1stCacheEntSetWrFlagOff();
642 
643  return sceMcResSucceed;
644 }
645 
646 //--------------------------------------------------------------
647 int mcman_open2(int port, int slot, const char *filename, int flags)
648 {
649  register int fd, i, r, rdflag, wrflag, pos, mcfree;
650  register MC_FHANDLE *fh;
651  register MCDevInfo *mcdi;
652  McCacheDir cacheDir;
653  McFsEntry *fse1, *fse2;
654  McCacheEntry *mce;
655  u8 *pfsentry, *pcache, *pfseend;
656  const char *p;
657  int fat_entry;
658 
659  DPRINTF("mcman_open2 port%d slot%d name %s flags %x\n", port, slot, filename, flags);
660 
661  if ((flags & sceMcFileCreateFile) != 0)
662  flags |= sceMcFileAttrWriteable; // s5
663 
664  //if (!mcman_checkpath(filename))
665  // return sceMcResNoEntry;
666  if (filename[0] == 0)
667  return sceMcResNoEntry;
668 
669  fd = 0;
670  do {
671  fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
672  if (fh->status == 0)
673  break;
674  } while (++fd < MAX_FDHANDLES);
675 
676  if (fd == MAX_FDHANDLES)
677  return sceMcResUpLimitHandle;
678 
679  fh = (MC_FHANDLE *)&mcman_fdhandles[fd]; // s2
680 
681  mcman_wmemset((void *)fh, sizeof (MC_FHANDLE), 0);
682 
683  mcdi = (MCDevInfo *)&mcman_devinfos[port][slot]; // s3
684 
685  if ((flags & (sceMcFileCreateFile | sceMcFileCreateDir)) == 0)
686  cacheDir.maxent = -1; //sp20
687  else
688  cacheDir.maxent = 0; //sp20
689 
690  //fse1 = sp28
691  //sp18 = cacheDir
692 
693  fse1 = NULL;
694  r = mcman_cachedirentry(port, slot, filename, &cacheDir, &fse1, 1);
695  if (r < 0)
696  return r;
697 
698  if (fse1) {
699  pfsentry = (u8 *)fse1;
700  pcache = (u8 *)&mcman_dircache[1];
701  pfseend = (u8 *)(pfsentry + sizeof(McFsEntry));
702 
703  do {
704  *((u32 *)pcache ) = *((u32 *)pfsentry );
705  *((u32 *)pcache+1) = *((u32 *)pfsentry+1);
706  *((u32 *)pcache+2) = *((u32 *)pfsentry+2);
707  *((u32 *)pcache+3) = *((u32 *)pfsentry+3);
708  pfsentry += 16;
709  pcache += 16;
710  } while (pfsentry < pfseend);
711 
712  if ((flags == 0) && ((fse1->mode & sceMcFileAttrExists) == 0))
713  r = 1;
714  }
715 
716  if (r == 2)
717  return sceMcResNoEntry;
718 
719  if (r == 3)
720  return sceMcResDeniedPermit;
721 
722  if ((r == 0) && ((flags & sceMcFileCreateDir) != 0))
723  return sceMcResNoEntry;
724 
725  if ((r == 1) && ((flags & (sceMcFileCreateFile | sceMcFileCreateDir)) == 0))
726  return sceMcResNoEntry;
727 
728  rdflag = flags & sceMcFileAttrReadable;
729  wrflag = flags & sceMcFileAttrWriteable;
730  fh->freeclink = -1;
731  fh->clink = -1;
732  fh->clust_offset = 0;
733  fh->filesize = 0;
734  fh->position = 0;
735  fh->port = port;
736  fh->slot = slot;
737  fh->unknown2 = 0;
738  fh->rdflag = rdflag;
739  fh->wrflag = wrflag;
740  fh->unknown1 = 0;
741  fh->cluster = cacheDir.cluster;
742  fh->fsindex = cacheDir.fsindex;
743 
744  // fse2 = sp2c
745 
746  if (r == 0) {
747 
748  if ((wrflag != 0) && ((mcman_dircache[1].mode & sceMcFileAttrWriteable) == 0))
749  return sceMcResDeniedPermit;
750 
751  if (!PS1CardFlag) {
752  if ((flags & sceMcFileAttrReadable) != 0) {
753  if ((mcman_dircache[1].mode & sceMcFileAttrReadable) == 0)
754  return sceMcResDeniedPermit;
755  }
756  }
757  r = McReadDirEntry(port, slot, cacheDir.cluster, 0, &fse2);
758  if (r != sceMcResSucceed)
759  return r;
760 
761  fh->parent_cluster = fse2->cluster;
762  fh->parent_fsindex = fse2->dir_entry;
763 
764  if ((mcman_dircache[1].mode & sceMcFileAttrSubdir) != 0) {
765  if ((mcman_dircache[1].mode & sceMcFileAttrReadable) == 0)
766  return sceMcResDeniedPermit;
767 
768  fh->freeclink = mcman_dircache[1].cluster;
769  fh->rdflag = 0;
770  fh->wrflag = 0;
771  fh->unknown1 = 0;
772  fh->drdflag = 1;
773  fh->status = 1;
774  fh->filesize = mcman_dircache[1].length;
775  fh->clink = fh->freeclink;
776 
777  return fd;
778  }
779 
780  if ((flags & sceMcFileAttrWriteable) != 0) {
781  i = 0;
782  do {
783  register MC_FHANDLE *fh2;
784 
785  fh2 = (MC_FHANDLE *)&mcman_fdhandles[i];
786 
787  if ((fh2->status == 0) || (fh2->port != port) || (fh2->slot != slot) \
788  || (fh2->cluster != (u32)(cacheDir.cluster)) || (fh2->fsindex != (u32)(cacheDir.fsindex)))
789  continue;
790 
791  if (fh2->wrflag != 0)
792  return sceMcResDeniedPermit;
793 
794  } while (++i < MAX_FDHANDLES);
795  }
796 
797  if ((flags & sceMcFileCreateFile) != 0) {
798  r = McSetDirEntryState(port, slot, cacheDir.cluster, cacheDir.fsindex, 0);
799  McFlushCache(port, slot);
800 
801  if (r != sceMcResSucceed)
802  return -43;
803 
804  if (cacheDir.fsindex < cacheDir.maxent)
805  cacheDir.maxent = cacheDir.fsindex;
806  }
807  else {
808  fh->freeclink = mcman_dircache[1].cluster;
809  fh->filesize = mcman_dircache[1].length;
810  fh->clink = fh->freeclink;
811 
812  if (fh->rdflag != 0)
813  fh->rdflag = (*((u8 *)&mcman_dircache[1].mode)) & sceMcFileAttrReadable;
814  else
815  fh->rdflag = 0;
816 
817  if (fh->wrflag != 0)
818  fh->wrflag = (mcman_dircache[1].mode >> 1) & sceMcFileAttrReadable;
819  else
820  fh->wrflag = 0;
821 
822  fh->status = 1;
823 
824  return fd;
825  }
826  }
827  else {
828  fh->parent_cluster = cacheDir.cluster;
829  fh->parent_fsindex = cacheDir.fsindex;
830  }
831 
832  r = McReadDirEntry(port, slot, fh->parent_cluster, fh->parent_fsindex, &fse1);
833  if (r != sceMcResSucceed)
834  return r;
835 
836  pfsentry = (u8 *)fse1;
837  pcache = (u8 *)&mcman_dircache[2];
838  pfseend = (u8 *)(pfsentry + sizeof(McFsEntry));
839 
840  do {
841  *((u32 *)pcache ) = *((u32 *)pfsentry );
842  *((u32 *)pcache+1) = *((u32 *)pfsentry+1);
843  *((u32 *)pcache+2) = *((u32 *)pfsentry+2);
844  *((u32 *)pcache+3) = *((u32 *)pfsentry+3);
845  pfsentry += 16;
846  pcache += 16;
847  } while (pfsentry < pfseend);
848 
849  i = -1;
850  if (mcman_dircache[2].length == (u32)(cacheDir.maxent)) {
851  register int fsindex, fsoffset;
852 
853  fsindex = mcman_dircache[2].length / (mcdi->cluster_size >> 9); //v1
854  fsoffset = mcman_dircache[2].length % (mcdi->cluster_size >> 9); //v0
855 
856  if (fsoffset == 0) {
857  register int fat_index;
858 
859  fat_index = mcman_dircache[2].cluster;
860  i = fsindex;
861 
862  if ((mcman_dircache[2].cluster == 0) && (i >= 2)) {
863  if (mcman_getFATindex(port, slot, i - 1) >= 0) {
864  fat_index = mcman_getFATindex(port, slot, i - 1); // s3
865  i = 1;
866  }
867  }
868  i--;
869 
870  if (i != -1) {
871 
872  do {
873  r = McGetFATentry(port, slot, fat_index, &fat_entry);
874  if (r != sceMcResSucceed)
875  return r;
876 
877  if (fat_entry >= -1) {
878  r = mcman_findfree2(port, slot, 1);
879  if (r < 0)
880  return r;
881 
882  fat_entry = r;
883  mce = mcman_get1stcacheEntp(); // s4
884 
885  fat_entry |= 0x80000000;
886 
887  r = McSetFATentry(port, slot, fat_index, fat_entry);
888  if (r != sceMcResSucceed)
889  return r;
890 
891  mcman_addcacheentry(mce);
892  }
893  i--;
894  fat_index = fat_entry & ~0x80000000;
895 
896  } while (i != -1);
897  }
898  }
899 
900  r = McFlushCache(port, slot);
901  if (r != sceMcResSucceed)
902  return r;
903 
904  i = -1;
905 
906  mcman_dircache[2].length++;
907  }
908 
909  do {
910  p = filename + i + 1;
911  pos = i + 1;
912  r = mcman_chrpos(p, '/');
913  if (r < 0)
914  break;
915  i = pos + r;
916  } while (1);
917 
918  p = filename + pos;
919 
920  mcfree = 0;
921 
922  if ((flags & sceMcFileCreateDir) != 0) {
923  r = mcman_findfree2(port, slot, 1); // r = s3
924  if (r < 0)
925  return r;
926  mcfree = r;
927  }
928 
929  mce = mcman_get1stcacheEntp(); // mce = s4
930 
931  mcman_getmcrtime(&mcman_dircache[2].modified);
932 
933  r = McReadDirEntry(port, slot, mcman_dircache[2].cluster, cacheDir.maxent, &fse2);
934  if (r != sceMcResSucceed)
935  return r;
936 
937  mcman_wmemset((void *)fse2, sizeof (McFsEntry), 0);
938 
939  strncpy(fse2->name, p, 32);
940 
941  fse2->created = mcman_dircache[2].modified;
942  fse2->modified = mcman_dircache[2].modified;
943 
944  Mc1stCacheEntSetWrFlagOff();
945 
946  mcman_addcacheentry(mce);
947 
948  if (!PS1CardFlag)
949  flags &= 0xffffdfff;
950 
951  if ((flags & sceMcFileCreateDir) != 0) {
952 
953  fse2->mode = ((flags & sceMcFileAttrHidden) | sceMcFileAttrReadable | sceMcFileAttrWriteable \
954  | sceMcFileAttrExecutable | sceMcFileAttrSubdir | sceMcFile0400 | sceMcFileAttrExists) // 0x8427
955  | (flags & (sceMcFileAttrPS1 | sceMcFileAttrPDAExec));
956  fse2->length = 2;
957  fse2->cluster = mcfree;
958 
959  r = McCreateDirentry(port, slot, mcman_dircache[2].cluster, cacheDir.maxent, mcfree, (sceMcStDateTime *)&fse2->created);
960  if (r != sceMcResSucceed)
961  return -46;
962 
963  r = McReadDirEntry(port, slot, fh->parent_cluster, fh->parent_fsindex, &fse1);
964  if (r != sceMcResSucceed)
965  return r;
966 
967  pfsentry = (u8 *)fse1;
968  pcache = (u8 *)&mcman_dircache[2];
969  pfseend = (u8 *)(pfsentry + sizeof(McFsEntry));
970 
971  do {
972  *((u32 *)pfsentry ) = *((u32 *)pcache );
973  *((u32 *)pfsentry+1) = *((u32 *)pcache+1);
974  *((u32 *)pfsentry+2) = *((u32 *)pcache+2);
975  *((u32 *)pfsentry+3) = *((u32 *)pcache+3);
976  pfsentry += 16;
977  pcache += 16;
978  } while (pfsentry < pfseend);
979 
980  Mc1stCacheEntSetWrFlagOff();
981 
982  r = McFlushCache(port, slot);
983  if (r != sceMcResSucceed)
984  return r;
985 
986  return sceMcResSucceed;
987  }
988  else {
989  fse2->mode = ((flags & sceMcFileAttrHidden) | sceMcFileAttrReadable | sceMcFileAttrWriteable \
990  | sceMcFileAttrExecutable | sceMcFileAttrFile | sceMcFile0400 | sceMcFileAttrExists) // 0x8417
991  | (flags & (sceMcFileAttrPS1 | sceMcFileAttrPDAExec));
992 
993  fse2->cluster = -1;
994  fh->cluster = mcman_dircache[2].cluster;
995  fh->status = 1;
996  fh->fsindex = cacheDir.maxent;
997 
998  r = McReadDirEntry(port, slot, fh->parent_cluster, fh->parent_fsindex, &fse1);
999  if (r != sceMcResSucceed)
1000  return r;
1001 
1002  pfsentry = (u8 *)fse1;
1003  pcache = (u8 *)&mcman_dircache[2];
1004  pfseend = (u8 *)(pfsentry + sizeof(McFsEntry));
1005 
1006  do {
1007  *((u32 *)pfsentry ) = *((u32 *)pcache );
1008  *((u32 *)pfsentry+1) = *((u32 *)pcache+1);
1009  *((u32 *)pfsentry+2) = *((u32 *)pcache+2);
1010  *((u32 *)pfsentry+3) = *((u32 *)pcache+3);
1011  pfsentry += 16;
1012  pcache += 16;
1013  } while (pfsentry < pfseend);
1014 
1015  Mc1stCacheEntSetWrFlagOff();
1016 
1017  r = McFlushCache(port, slot);
1018  if (r != sceMcResSucceed)
1019  return r;
1020  }
1021 
1022  return fd;
1023 }
1024 
1025 //--------------------------------------------------------------
1026 int mcman_chdir(int port, int slot, const char *newdir, char *currentdir)
1027 {
1028  register int r, len, len2, cluster;
1029  register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
1030  McCacheDir cacheDir;
1031  McFsEntry *fse;
1032 
1033  DPRINTF("mcman_chdir port%d slot%d newdir %s\n", port, slot, newdir);
1034 
1035  //if (!mcman_checkpath(newdir))
1036  // return sceMcResNoEntry;
1037 
1038  cacheDir.maxent = -1;
1039 
1040  r = mcman_cachedirentry(port, slot, newdir, &cacheDir, &fse, 1);
1041  if (r < 0)
1042  return r;
1043 
1044  if (((u32)(r - 1)) < 2)
1045  return sceMcResNoEntry;
1046 
1047  mcdi->rootdir_cluster2 = cacheDir.cluster;
1048  mcdi->unknown1 = cacheDir.fsindex;
1049 
1050  cluster = cacheDir.cluster;
1051  if (!strcmp(fse->name, "..")) {
1052  r = McReadDirEntry(port, slot, cluster, 0, &fse);
1053  if (r != sceMcResSucceed)
1054  return r;
1055  }
1056 
1057  if (!strcmp(fse->name, ".")) {
1058  mcdi->rootdir_cluster2 = fse->cluster;
1059  mcdi->unknown1 = fse->dir_entry;
1060 
1061  cluster = fse->cluster;
1062  r = McReadDirEntry(port, slot, cluster, fse->dir_entry, &fse);
1063  if (r != sceMcResSucceed)
1064  return r;
1065  }
1066 
1067  currentdir[0] = 0;
1068 
1069 lbl1:
1070  if (strcmp(fse->name, ".")) {
1071 
1072  if (strlen(fse->name) < 32)
1073  len = strlen(fse->name);
1074  else
1075  len = 32;
1076 
1077  if (strlen(currentdir)) {
1078  len2 = strlen(currentdir);
1079  if (len2 >= 0) {
1080  do {
1081  currentdir[1 + len2 + len] = currentdir[len2];
1082  } while (--len2 >= 0);
1083  }
1084  currentdir[len] = '/';
1085  strncpy(currentdir, fse->name, len);
1086  }
1087  else {
1088  strncpy(currentdir, fse->name, 32);
1089  currentdir[32] = 0;
1090  }
1091 
1092  r = McReadDirEntry(port, slot, cluster, 0, &fse);
1093  if (r != sceMcResSucceed)
1094  return r;
1095 
1096  r = McReadDirEntry(port, slot, fse->cluster, fse->dir_entry, &fse);
1097 
1098  if (r == sceMcResSucceed)
1099  goto lbl1;
1100  }
1101  else {
1102  len = strlen(currentdir);
1103 
1104  if (len >= 0) {
1105  do {
1106  currentdir[1 + len] = currentdir[len];
1107  } while (--len >= 0);
1108  }
1109  currentdir[0] = '/';
1110 
1111  r = sceMcResSucceed;
1112  }
1113 
1114  return r;
1115 }
1116 
1117 //--------------------------------------------------------------
1118 int mcman_getdir2(int port, int slot, const char *dirname, int flags, int maxent, sceMcTblGetDir *info)
1119 {
1120  register int r, nument;
1121  register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
1122  McFsEntry *fse;
1123  char *p;
1124 
1125  DPRINTF("mcman_getdir2 port%d slot%d dir=%s flags=%d maxent=%d\n", port, slot, dirname, flags, maxent);
1126 
1127  nument = 0;
1128  flags &= 0xffff;
1129 
1130  if (!flags) {
1131  register int pos;
1132 
1133  p = mcman_curdirpath;
1134  strncpy(p, dirname, 1023);
1135  mcman_curdirpath[1023] = 0;
1136 
1137  pos = -1; // s1
1138  p++; //s0
1139  do {
1140  r = mcman_chrpos((void *)&p[pos], '/');
1141  if (r < 0)
1142  break;
1143  pos += 1 + r;
1144  } while (1);
1145 
1146  if (pos <= 0) {
1147  if (pos == 0)
1148  *p = 0;
1149  else
1150  p[-1] = 0;
1151  }
1152  else {
1153  mcman_curdirpath[pos] = 0;
1154  }
1155 
1156  mcman_curdirname = &dirname[pos] + 1;
1157 
1158  r = mcman_cachedirentry(port, slot, mcman_curdirpath, NULL, &fse, 1);
1159  if (r > 0)
1160  return sceMcResNoEntry;
1161  if (r < 0)
1162  return r;
1163 
1164  if (!(fse->mode & sceMcFileAttrSubdir)) {
1165  mcman_curdircluster = -1;
1166  return sceMcResNoEntry;
1167  }
1168 
1169  mcman_curdircluster = fse->cluster;
1170  mcman_curdirlength = fse->length;
1171 
1172  if ((fse->cluster == mcdi->rootdir_cluster) && (fse->dir_entry == 0))
1173  mcman_curdirmaxent = 2;
1174  else
1175  mcman_curdirmaxent = 0;
1176  }
1177  else {
1178  if (mcman_curdircluster < 0)
1179  return sceMcResNoEntry;
1180  }
1181 
1182  if (maxent != 0) {
1183  do {
1184  if (mcman_curdirmaxent >= mcman_curdirlength)
1185  break;
1186 
1187  r = McReadDirEntry(port, slot, mcman_curdircluster, mcman_curdirmaxent, &fse);
1188  if (r != sceMcResSucceed)
1189  return r;
1190 
1191  mcman_curdirmaxent++;
1192 
1193  if (!(fse->mode & sceMcFileAttrExists))
1194  continue;
1195  if ((fse->mode & sceMcFileAttrHidden) && (!PS1CardFlag))
1196  continue;
1197  if (!mcman_checkdirpath(fse->name, mcman_curdirname))
1198  continue;
1199 
1200  mcman_wmemset((void *)info, sizeof (sceMcTblGetDir), 0);
1201 
1202  if (mcman_curdirmaxent == 2) {
1203 
1204  r = McReadDirEntry(port, slot, mcman_curdircluster, 0, &fse);
1205  if (r != sceMcResSucceed)
1206  return r;
1207 
1208  r = McReadDirEntry(port, slot, fse->cluster, 0, &fse);
1209  if (r != sceMcResSucceed)
1210  return r;
1211 
1212  r = McReadDirEntry(port, slot, fse->cluster, fse->dir_entry, &fse);
1213  if (r != sceMcResSucceed)
1214  return r;
1215 
1216  info->EntryName[0] = '.';
1217  info->EntryName[1] = '.';
1218  info->EntryName[2] = '\0';
1219  }
1220  else if (mcman_curdirmaxent == 1) {
1221 
1222  r = McReadDirEntry(port, slot, mcman_curdircluster, 0, &fse);
1223  if (r != sceMcResSucceed)
1224  return r;
1225 
1226  r = McReadDirEntry(port, slot, fse->cluster, fse->dir_entry, &fse);
1227  if (r != sceMcResSucceed)
1228  return r;
1229 
1230  info->EntryName[0] = '.';
1231  info->EntryName[1] = '\0';
1232  }
1233  else {
1234  strncpy(info->EntryName, fse->name, 32);
1235  }
1236 
1237  info->AttrFile = fse->mode;
1238  info->Reserve1 = fse->unused;
1239 
1240  info->_Create = fse->created;
1241  info->_Modify = fse->modified;
1242 
1243  if (!(fse->mode & sceMcFileAttrSubdir))
1244  info->FileSizeByte = fse->length;
1245 
1246  nument++;
1247  maxent--;
1248  info++;
1249 
1250  } while (maxent);
1251  }
1252 
1253  return nument;
1254 }
1255 
1256 //--------------------------------------------------------------
1257 int mcman_delete2(int port, int slot, const char *filename, int flags)
1258 {
1259  register int r, i;
1260  McCacheDir cacheDir;
1261  McFsEntry *fse1, *fse2;
1262 
1263  DPRINTF("mcman_delete2 port%d slot%d filename %s flags %x\n", port, slot, filename, flags);
1264 
1265  //if (!mcman_checkpath(filename))
1266  // return sceMcResNoEntry;
1267 
1268  r = mcman_cachedirentry(port, slot, filename, &cacheDir, &fse1, ((u32)(flags < 1)) ? 1 : 0);
1269  if (r > 0)
1270  return sceMcResNoEntry;
1271  if (r < 0)
1272  return r;
1273 
1274  if (!flags) {
1275  if (!(fse1->mode & sceMcFileAttrExists))
1276  return sceMcResNoEntry;
1277  }
1278  else {
1279  if (fse1->mode & sceMcFileAttrExists)
1280  return sceMcResNoEntry;
1281  }
1282 
1283  if ((!PS1CardFlag) && (!flags)) {
1284  if (!(fse1->mode & sceMcFileAttrWriteable))
1285  return sceMcResDeniedPermit;
1286  }
1287 
1288  if ((!fse1->cluster) && (!fse1->dir_entry))
1289  return sceMcResNoEntry;
1290 
1291  i = 2;
1292  if ((!flags) && (fse1->mode & sceMcFileAttrSubdir) && ((u32)i < fse1->length)) {
1293 
1294  do {
1295  r = McReadDirEntry(port, slot, fse1->cluster, i, &fse2);
1296  if (r != sceMcResSucceed)
1297  return r;
1298 
1299  if (fse2->mode & sceMcFileAttrExists)
1300  return sceMcResNotEmpty;
1301 
1302  } while ((u32)(++i) < fse1->length);
1303  }
1304 
1305  r = McSetDirEntryState(port, slot, cacheDir.cluster, cacheDir.fsindex, flags);
1306  if (r != sceMcResSucceed)
1307  return r;
1308 
1309  r = McFlushCache(port, slot);
1310  if (r != sceMcResSucceed)
1311  return r;
1312 
1313  return sceMcResSucceed;
1314 }
1315 
1316 //--------------------------------------------------------------
1317 int mcman_unformat2(int port, int slot)
1318 {
1319  register int r, i, j, z, l, pageword_cnt, page, blocks_on_card, erase_byte, err_cnt;
1320  register u32 erase_value;
1321  register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
1322 
1323  DPRINTF("mcman_unformat2 port%d slot%d\n", port, slot);
1324 
1325  pageword_cnt = mcdi->pagesize >> 2;
1326  blocks_on_card = mcdi->clusters_per_card / mcdi->clusters_per_block; //sp18
1327 
1328  erase_value = 0xffffffff; //s6
1329  if (!(mcdi->cardflags & CF_ERASE_ZEROES))
1330  erase_value = 0x00000000;
1331 
1332  for (i = 0; i < pageword_cnt; i++)
1333  mcman_pagebuf.word[i] = erase_value;
1334 
1335  for (i = 0; i < 128; i++)
1336  *((u32 *)&mcman_eccdata + i) = erase_value;
1337 
1338  i = 1;
1339  if (i < blocks_on_card) {
1340  erase_byte = erase_value & 0xff; // sp20
1341  do {
1342  page = i * mcdi->blocksize;
1343  if (mcdi->cardform > 0) {
1344  j = 0;
1345  for (j = 0; j < 16; j++) {
1346  if (mcdi->bad_block_list[j] <= 0) {
1347  j = 16;
1348  goto lbl1;
1349  }
1350  if (mcdi->bad_block_list[j] == i)
1351  goto lbl1;
1352  }
1353  }
1354  else {
1355  err_cnt = 0;
1356  j = -1;
1357  z = 0;
1358  if (mcdi->blocksize > 0) {
1359  do {
1360  r = McReadPage(port, slot, page + z, &mcman_pagebuf);
1361  if (r == sceMcResNoFormat) {
1362  j = -2;
1363  break;
1364  }
1365  if (r != sceMcResSucceed)
1366  return -42;
1367 
1368  if ((mcdi->cardflags & CF_USE_ECC) == 0) {
1369  for (l = 0; l < mcdi->pagesize; l++) {
1370  if (mcman_pagebuf.byte[l] != erase_byte)
1371  err_cnt++;
1372  if ((u32)err_cnt >= (mcdi->clusters_per_block << 6)) {
1373  j = 16;
1374  break;
1375  }
1376  }
1377  if (j != -1)
1378  break;
1379  }
1380  } while (++z < mcdi->blocksize);
1381  }
1382  }
1383 
1384  if (((mcdi->cardflags & CF_USE_ECC) != 0) && (j == -1))
1385  j = 16;
1386 lbl1:
1387  if (j == 16) {
1388  r = mcman_eraseblock(port, slot, i, NULL, NULL);
1389  if (r != sceMcResSucceed)
1390  return -43;
1391  }
1392  else {
1393  for (l = 0; l < pageword_cnt; l++)
1394  mcman_pagebuf.word[l] = erase_value;
1395 
1396  if (mcdi->blocksize > 0) {
1397  z = 0;
1398  do {
1399  r = McWritePage(port, slot, page + z, &mcman_pagebuf, mcman_eccdata);
1400  if (r != sceMcResSucceed)
1401  return -44;
1402  } while (++z < mcdi->blocksize);
1403  }
1404  }
1405  } while (++i < blocks_on_card);
1406  }
1407 
1408  r = mcman_eraseblock(port, slot, 0, NULL, NULL);
1409  if (r != sceMcResSucceed)
1410  return -45;
1411 
1412  return sceMcResSucceed;
1413 }
1414 
1415 //--------------------------------------------------------------
_MCCacheDir
Definition: mcman-internal.h:93
s_info
Definition: xprintf.c:78
mcman_pagebuf
Definition: mcman-internal.h:327
_sceMcTblGetDir
Definition: libmc.h:139
_MCCacheEntry
Definition: libmc-common.h:69
_McFatCluster
Definition: mcman-internal.h:113
MC_FHANDLE
Definition: mcman-internal.h:125
_sceMcStDateTime
Definition: libmc-common.h:22
MCDevInfo
Definition: mcman-internal.h:295
mcman.h
McFsEntry
Definition: libmc-common.h:54