static int rip_sec(int tn,int first,int count,int type,char *dst_file, int disc_type){ double percent,percent_last=0.0; maple_device_t *cont; cont_state_t *state; file_t hnd; int secbyte = (type == 4 ? 2048 : 2352) , i , count_old=count, bad=0, cdstat, readi; uint8 *buffer = (uint8 *)memalign(32, SEC_BUF_SIZE * secbyte); GUI_WidgetMarkChanged(self.app->body); // ds_printf("Track %d First %d Count %d Type %d\n",tn,first,count,type); /* if (secbyte == 2048) cdrom_set_sector_size (secbyte); else _cdrom_reinit (1); */ cdrom_set_sector_size (secbyte); if ((hnd = fs_open(dst_file,O_WRONLY | O_TRUNC | O_CREAT)) == FILEHND_INVALID) { ds_printf("Error open file %s\n" ,dst_file); cdrom_spin_down(); free(buffer); return CMD_ERROR; } LockVideo(); while(count) { int nsects = count > SEC_BUF_SIZE ? SEC_BUF_SIZE : count; count -= nsects; while((cdstat=cdrom_read_sectors(buffer, first, nsects)) != ERR_OK ) { if (atoi(GUI_TextEntryGetText(self.num_read)) == 0) break; readi++ ; if (readi > 5) break ; thd_sleep(200); } readi = 0; if (cdstat != ERR_OK) { if (!GUI_WidgetGetState(self.bad)) { UnlockVideo(); GUI_ProgressBarSetPosition(self.read_error, 1.0); for(;;) { cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if(!cont) continue; state = (cont_state_t *)maple_dev_status(cont); if(!state) continue; if(state->buttons & CONT_A) { GUI_ProgressBarSetPosition(self.read_error, 0.0); GUI_WidgetMarkChanged(self.app->body); ds_printf("DS_ERROR: Can't read sector %ld\n", first); free(buffer); fs_close(hnd); return CMD_ERROR; } else if(state->buttons & CONT_B) { GUI_ProgressBarSetPosition(self.read_error, 0.0); GUI_WidgetMarkChanged(self.app->body); break; } else if(state->buttons & CONT_Y) { GUI_ProgressBarSetPosition(self.read_error, 0.0); GUI_WidgetSetState(self.bad, 1); GUI_WidgetMarkChanged(self.app->body); break; } } } // Ошибка, попробуем по одному uint8 *pbuffer = buffer; LockVideo(); for(i = 0; i < nsects; i++) { while((cdstat=cdrom_read_sectors(pbuffer, first, 1)) != ERR_OK ) { readi++ ; if (readi > atoi(GUI_TextEntryGetText(self.num_read))) break ; if (readi == 1 || readi == 6 || readi == 11 || readi == 16 || readi == 21 || readi == 26 || readi == 31 || readi == 36 || readi == 41 || readi == 46) cdrom_reinit(); thd_sleep(200); } readi = 0; if (cdstat != ERR_OK) { // Ошибка, заполним нулями и игнорируем UnlockVideo(); cdrom_reinit(); memset(pbuffer, 0, secbyte); bad++; ds_printf("DS_ERROR: Can't read sector %ld\n", first); LockVideo(); } pbuffer += secbyte; first++; } } else { // Все ок, идем дальше first += nsects; } if(fs_write(hnd, buffer, nsects * secbyte) < 0) { // Ошибка записи, печально, прерываем процесс UnlockVideo(); free(buffer); fs_close(hnd); return CMD_ERROR; } UnlockVideo(); percent = 1-(float)(count) / count_old; if ((percent = ((int)(percent*100 + 0.5))/100.0) > percent_last) { percent_last = percent; GUI_ProgressBarSetPosition(self.pbar, percent); LockVideo(); } } UnlockVideo(); free(buffer); fs_close(hnd); ds_printf("%d Bad sectors on track\n", bad); return CMD_OK; }
int BiosFlasher_WriteBiosFileToFlash(const char* filename, BiosFlasher_OperationCallback guiClbk) { size_t i = 0; uint8* data = 0; file_t pFile = 0; UPDATE_GUI(eReading, 0.0f, guiClbk); // Detect writible flash bflash_dev_t *dev = NULL; bflash_manufacturer_t *mrf = NULL; if( bflash_detect(&mrf, &dev) < 0 || !(dev->flags & F_FLASH_PROGRAM) ) { ds_printf("DS_ERROR: flash chip detection error.\n"); return eDetectionFail; } // Read bios file from file to memory pFile = fs_open(filename, O_RDONLY); if (pFile == FILEHND_INVALID) { ds_printf("DS_ERROR: Can't open bios file: %s.\n", filename); return eFileFail; } size_t fileSize = fs_total(pFile); if(fileSize > dev->size * 1024) { ds_printf("DS_ERROR: The firmware larger than a flash chip (%d KB vs %d KB).\n", (fileSize / 1024), dev->size); fs_close(pFile); return eFileFail; } data = (uint8 *) memalign(32, fileSize); if(data == NULL) { ds_printf("DS_ERROR: Not enough memory\n"); fs_close(pFile); return eUnknownFail; } size_t readLen = fs_read(pFile, data, fileSize); if (fileSize != readLen) { ds_printf("DS_ERROR: File wasn't loaded fully to memory\n"); fs_close(pFile); return eFileFail; } fs_close(pFile); EXPT_GUARD_BEGIN; // Erasing if (dev->flags & F_FLASH_ERASE_SECTOR || dev->flags & F_FLASH_ERASE_ALL) { for (i = 0; i < dev->sec_count; ++i) { UPDATE_GUI(eErasing, (float)i / dev->sec_count, guiClbk); if (bflash_erase_sector(dev, dev->sectors[i]) < 0) { ds_printf("DS_ERROR: Can't erase flash\n"); free(data); EXPT_GUARD_RETURN eErasingFail; } } } // Writing size_t offset = 0; if (fileSize >= settings.m_DataStart + settings.m_DataLength) { offset = settings.m_DataStart; fileSize = (settings.m_DataLength > 0) ? offset + settings.m_DataLength : fileSize - offset; } size_t chunkCount = fileSize / CHUNK_SIZE; for (i = 0; i <= chunkCount; ++i) { UPDATE_GUI(eWriting, (float)i / chunkCount, guiClbk); size_t dataPos = i * CHUNK_SIZE + offset; size_t dataLen = (dataPos + CHUNK_SIZE > fileSize) ? fileSize - dataPos : CHUNK_SIZE; // ScreenWaitUpdate(); LockVideo(); int result = bflash_write_data(dev, dataPos, data + dataPos, dataLen); UnlockVideo(); if (result < 0) { ds_printf("DS_ERROR: Can't write flash\n"); free(data); EXPT_GUARD_RETURN eWritingFail; } } EXPT_GUARD_CATCH; ds_printf("DS_ERROR: Fatal error\n"); free(data); fs_close(pFile); EXPT_GUARD_RETURN eFileFail; EXPT_GUARD_END; free(data); fs_close(pFile); return 0; }