s32 cellFsRead(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread) { cellFs.trace("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); // call the syscall return sys_fs_read(fd, buf, nbytes, nread ? nread : vm::var<u64>{}); }
s32 cellFsRead(PPUThread& ppu, u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread) { cellFs.Log("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); // call the syscall return sys_fs_read(fd, buf, nbytes, nread ? nread : vm::var<u64>(ppu)); }
// FDFS Device int devcall_FDFS(CALLFS_PARAM* param){ CALLFS_OPEN* open = (CALLFS_OPEN*)param; CALLFS_IOCTL* ioctl = (CALLFS_IOCTL*)param; CALLFS_DTX* dtx = (CALLFS_DTX*)param; switch(param->fscmd){ // open or close case devcall_open: switch(open->index){ case 0: return sys_fs_open(bind_devid,0); default: return 0; } case devcall_close: switch(open->index){ case 0: return sys_fs_close(bind_devid,0); default: return 0; } // IOCTL case devcall_ioctl: { switch(ioctl->ioctl_cmd){ case ioctl_get_information: *(volume_info*)ioctl->data=volume; case ioctl_check_read_status: case ioctl_check_write_status: case ioctl_nop: return 0; case ioctl_fs_bind: bind_devid=(uint32_t)(intptr_t)ioctl->data; // sys_fs_ioctl(bind_devid,ioctl_get_information,sizeof(volume_info),&volume); // sys_fs_ioctl(bind_devid,ioctl_reset_device,0,0); case ioctl_reset_device: sector_buffer_index=-1; return sys_fs_ioctl(bind_devid,ioctl_reset_device,0,0); case ioctl_read_toc: { bool mount_ok=false; bool sf16=false; memset(rootdir,0,rootdir_size*sizeof(FAT_DIRENT)); memset(fatbuffer,0,2*4096); sector_buffer_index=-1; DEBUG_PRINT("FDFS: Mounting...\n"); int r; for(int i=0;;i++){ sys_fs_ioctl(bind_devid,ioctl_reset_device,0,0); r=sys_fs_read(bind_devid,0,0,sector_buffer,18); if(r<0){ if(i>=3){ return r; } }else{ break; } } // ファイルシステム認識 FAT_BPB *bpb=(FAT_BPB*)sector_buffer; volume.BytesParSector=bpb->bytes_per_sector; volume.records.BytesParRecord=bpb->bytes_per_sector*bpb->sectors_per_cluster; int max_sectors,max_records; if(!memcmp(bpb->fs_signature,"FAT12 ",8)){ mount_ok=true; if(bpb->total_sectors==0xFFFF&&bpb->total_sectors32>0xFFFF){ max_sectors = bpb->total_sectors32; }else{ max_sectors = bpb->total_sectors; } volume.FirstRecord=(bpb->reserved_sectors+(bpb->n_fats*bpb->sectors_per_fat)+(bpb->root_entries*sizeof(FAT_DIRENT)/bpb->bytes_per_sector)-2*bpb->sectors_per_cluster); max_records = (max_sectors-(volume.FirstRecord+2*bpb->sectors_per_cluster))/bpb->sectors_per_cluster; for(int i=0;i<2048;i++){ fatbuffer[i*2] = (sector_buffer[512+i*3]+(sector_buffer[513+i*3]<<8))&0xFFF; fatbuffer[i*2+1] = (sector_buffer[513+i*3]+(sector_buffer[514+i*3]<<8))>>4; } }else if(bpb->SF16_signature[0]==0x53 && bpb->SF16_signature[1]==0x46 && bpb->SF16_signature[2]==0x31 && bpb->SF16_signature[3]==0x36){ mount_ok=true; sf16=true; max_sectors=bpb->SF16_max_sectors; max_records=(max_sectors-0x280)/bpb->sectors_per_cluster; volume.FirstRecord=(0x50000/0x200)-2; r=sys_fs_read(bind_devid,0,0x8000/0x200,fatbuffer,(2847*2+0x1FF)/0x200); } volume.nTotalSector=max_sectors; volume.records.nTotalRecords=max_records; if(!mount_ok) return -ENODEV; // 空き容量 int free_records=0; for(int i=0;i<volume.records.nTotalRecords;i++){ if(fatbuffer[i+2]==0) free_records++; } volume.records.nFreeRecords=free_records; // ルートディレクトリ FAT_DIRENT dot={{'.',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},0x10}; rootdir[0]=dot; rootdir[1]=dot; rootdir[1].filename[1]='.'; if(sf16){ r=sys_fs_read(bind_devid,0,(0x48000/0x200),rootdir+2,14); }else{ r=sys_fs_read(bind_devid,0,19,rootdir+2,14); } if(r<0) return r; return 0; } case ioctl_fast_find: { fastfind_t* ff=(fastfind_t*)ioctl->data; if(1){ DEBUG_PRINT("FDFS: FAST_FIND ["); DEBUG_PRINT(ff->name); DEBUG_PRINT("]\n"); } if(!strcmp(ff->name,"/")){ memset(ff->result,0,sizeof(readdir_t)); ff->result->raw[0]='/'; ff->result->filename[0]='/'; ff->result->devid=ioctl->device; ff->result->index=1; return 0; } const char* p = ff->name; int index=ff->dir_index; if(p[0]=='/'){ p++; index=1; } for(int i=0;;i++){ int r=sys_fs_read_dir(ioctl->device,index,i,ff->result); if(r<0) return r; if(!ff->result->raw[0]) break; if(!strcasecmp(ff->result->filename,p)) return 0; } DEBUG_PRINT("FDFS_FAST_FIND: NOT FOUND\n"); return -ENOENT; } default: return -EINVAL; } }