fill fill::pattern(pattern_fill::type pattern_type) { fill f; f.type_ = type::pattern; f.pattern_ = pattern_fill(pattern_type); return f; }
void game_init(){ int8u no; int8u count; display_off(); pattern_fill(0x3800, 0, (BG_HIGH + BG_PAL1 + BG_TOP), 32 * 28 * 2); actors_clear(); scene_wait = 0; player_create(0); alive_players = 1; smoke_wait = 0; scene_type = SCENE_GAME_PLAYING; vram_store(0x3000, fopen("bmp/font.ptn"), 0x0800); /* load pattern */ switch(stage){ case 0: vram_store(0x2000, fopen("bmp/castle.ptn"), 0x1000); vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000); break; case 1: vram_store(0x2000, fopen("bmp/summer.ptn"), 0x1000); vram_store(0x0000, fopen("bmp/sp_summer.ptn"), 0x2000); break; case 2: vram_store(0x2000, fopen("bmp/jungle.ptn"), 0x1000); vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000); break; default: vram_store(0x2000, fopen("bmp/winter.ptn"), 0x1000); vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000); break; } /* load palette */ load_palette(stage, 0); /* set enemy */ enemies_rotation_count = level << 3; for(count = stage; count != 0; count--){ /* 8 charactors * 3 levels * stage 2 */ enemies_rotation_count += 8 * 3; } enemies_rotation_limit = enemies_rotation_count + 8; enemies_count = ACTORS_INITINAL_COUNT; enemies_alive = 0; enemies_left = 6 + stage; for(count = 0; count < enemies_count; count++){ no = actors_get_null(); actor_create_random(no); } display_on(); }
/* ----------------------------------------------------------------------------------- */ void gameover_main(char *message){ int8u c; display_off(); palette_store( 0, fopen("bmp/title.pal"), 16); palette_store(16, fopen("bmp/sp_castle.pal"), 16); vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000); vram_store(0x2000, fopen("bmp/title.ptn"), 0x1000); vram_store(0x3000, fopen("bmp/font.ptn"), 0x800); pattern_fill(0x3800, 0, BG_HIGH, 32 * 24 * 2); print_init(); store_pattern_name_buffer(10); print(message, 10); store_pattern_name_buffer(9); print("1P SCORE XXXX0 ", 8); pattern_name_buffer[17 << 1] = VRAM_NUMBER + score_ints[3]; pattern_name_buffer[18 << 1] = VRAM_NUMBER + score_ints[2]; pattern_name_buffer[19 << 1] = VRAM_NUMBER + score_ints[1]; pattern_name_buffer[20 << 1] = VRAM_NUMBER + score_ints[0]; store_pattern_name_buffer(11); if(players_count == 2){ print("2P SCORE XXXX0 ", 8); pattern_name_buffer[17 << 1] = VRAM_NUMBER + score_ints[7]; pattern_name_buffer[18 << 1] = VRAM_NUMBER + score_ints[6]; pattern_name_buffer[19 << 1] = VRAM_NUMBER + score_ints[5]; pattern_name_buffer[20 << 1] = VRAM_NUMBER + score_ints[4]; store_pattern_name_buffer(13); } actors_clear(); scroll_y = 0; print_init(); display_on(); psg_set_bgm(fopen("sound/over.sn7"), FALSE); for(c = 6; c != 0; c--){ for(frame_count = 0; frame_count < 60; frame_count++){ sprites_clear(); vsync_wait(); sprites_store(); scroll_store(); psg_play(); } } psg_stop(); }
static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, blk_t first_block, size_t blocks_at_once, int nb_passes) { unsigned char *buffer = NULL, *read_buffer; const unsigned int pattern[] = {0xaa, 0x55, 0xff, 0x00}; int i, pat_idx; unsigned int bb_count = 0; blk_t got, tryout, recover_block = ~0, *blk_id; size_t id_offset; if ((nb_passes < 1) || (nb_passes > 4)) { uprintf("%sInvalid number of passes\n", bb_prefix); cancel_ops = -1; return 0; } buffer = allocate_buffer(2 * blocks_at_once * block_size); read_buffer = buffer + blocks_at_once * block_size; if (!buffer) { uprintf("%sError while allocating buffers\n", bb_prefix); cancel_ops = -1; return 0; } uprintf("%sChecking from block %lu to %lu\n", bb_prefix, (unsigned long) first_block, (unsigned long) last_block - 1); nr_pattern = nb_passes; cur_pattern = 0; for (pat_idx = 0; pat_idx < nb_passes; pat_idx++) { if (cancel_ops) goto out; srand((unsigned int)GetTickCount()); id_offset = rand()* (block_size-sizeof(blk_t)) / RAND_MAX; pattern_fill(buffer, pattern[pat_idx], blocks_at_once * block_size); uprintf("%sBlock ID at offset: %d\n", bb_prefix, id_offset); num_blocks = last_block - 1; currently_testing = first_block; if (s_flag | v_flag) uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pat_idx]); cur_op = OP_WRITE; tryout = blocks_at_once; while (currently_testing < last_block) { if (cancel_ops) goto out; if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { uprintf(abort_msg); fprintf(log_fd, abort_msg); fflush(log_fd); } cancel_ops = -1; goto out; } if (currently_testing + tryout > last_block) tryout = last_block - currently_testing; if (detect_fakes) { /* Add the block number at a fixed (random) offset during each pass to allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */ for (i=0; i<(int)blocks_at_once; i++) { blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size); *blk_id = (blk_t)(currently_testing + i); } } got = do_write(hDrive, buffer, tryout, block_size, currently_testing); if (v_flag > 1) print_status(); if (got == 0 && tryout == 1) bb_count += bb_output(currently_testing++, WRITE_ERROR); currently_testing += got; if (got != tryout) { tryout = 1; if (recover_block == ~0) recover_block = currently_testing - got + blocks_at_once; continue; } else if (currently_testing == recover_block) { tryout = blocks_at_once; recover_block = ~0; } } num_blocks = 0; if (s_flag | v_flag) uprintf("%sReading and comparing\n", bb_prefix); cur_op = OP_READ; num_blocks = last_block; currently_testing = first_block; tryout = blocks_at_once; while (currently_testing < last_block) { if (cancel_ops) goto out; if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { uprintf(abort_msg); fprintf(log_fd, abort_msg); fflush(log_fd); } cancel_ops = -1; goto out; } if (currently_testing + tryout > last_block) tryout = last_block - currently_testing; if (detect_fakes) { for (i=0; i<(int)blocks_at_once; i++) { blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size); *blk_id = (blk_t)(currently_testing + i); } } got = do_read(hDrive, read_buffer, tryout, block_size, currently_testing); if (got == 0 && tryout == 1) bb_count += bb_output(currently_testing++, READ_ERROR); currently_testing += got; if (got != tryout) { tryout = 1; if (recover_block == ~0) recover_block = currently_testing - got + blocks_at_once; continue; } else if (currently_testing == recover_block) { tryout = blocks_at_once; recover_block = ~0; } for (i=0; i < got; i++) { if (memcmp(read_buffer + i * block_size, buffer + i * block_size, block_size)) bb_count += bb_output(currently_testing+i-got, CORRUPTION_ERROR); } if (v_flag > 1) print_status(); } num_blocks = 0; } out: free_buffer(buffer); return bb_count; }
static void general_test (NANDDriver *nandp, size_t first, size_t last, size_t read_rounds){ size_t block, page, round; bool status; uint8_t op_status; uint32_t recc, wecc; red_led_on(); /* initialize time measurement units */ chTMObjectInit(&tmu_erase); chTMObjectInit(&tmu_write_data); chTMObjectInit(&tmu_write_spare); chTMObjectInit(&tmu_read_data); chTMObjectInit(&tmu_read_spare); /* perform basic checks */ for (block=first; block<last; block++){ if (!nandIsBad(nandp, block)){ if (!is_erased(nandp, block)){ op_status = nandErase(nandp, block); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ } } } /* write block with pattern, read it back and compare */ for (block=first; block<last; block++){ if (!nandIsBad(nandp, block)){ for (page=0; page<nandp->config->pages_per_block; page++){ pattern_fill(); chTMStartMeasurementX(&tmu_write_data); op_status = nandWritePageData(nandp, block, page, nand_buf, nandp->config->page_data_size, &wecc); chTMStopMeasurementX(&tmu_write_data); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ chTMStartMeasurementX(&tmu_write_spare); op_status = nandWritePageSpare(nandp, block, page, nand_buf + nandp->config->page_data_size, nandp->config->page_spare_size); chTMStopMeasurementX(&tmu_write_spare); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ /* read back and compare */ for (round=0; round<read_rounds; round++){ memset(nand_buf, 0, NAND_PAGE_SIZE); chTMStartMeasurementX(&tmu_read_data); nandReadPageData(nandp, block, page, nand_buf, nandp->config->page_data_size, &recc); chTMStopMeasurementX(&tmu_read_data); osalDbgCheck(0 == (recc ^ wecc)); /* ECC error detected */ chTMStartMeasurementX(&tmu_read_spare); nandReadPageSpare(nandp, block, page, nand_buf + nandp->config->page_data_size, nandp->config->page_spare_size); chTMStopMeasurementX(&tmu_read_spare); osalDbgCheck(0 == memcmp(ref_buf, nand_buf, NAND_PAGE_SIZE)); /* Read back failed */ } } /* make clean */ chTMStartMeasurementX(&tmu_erase); op_status = nandErase(nandp, block); chTMStopMeasurementX(&tmu_erase); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ status = is_erased(nandp, block); osalDbgCheck(true == status); /* blocks was not erased successfully */ }/* if (!nandIsBad(nandp, block)){ */ } red_led_off(); }
static void ecc_test(NANDDriver *nandp, uint32_t block){ uint32_t corrupted; uint32_t byte, bit; const uint32_t ecclen = 28; uint32_t ecc_ref, ecc_broken; uint8_t op_status; ecc_result_t ecc_result = ECC_NO_ERROR; /* This test requires good block.*/ osalDbgCheck(!nandIsBad(nandp, block)); if (!is_erased(nandp, block)) nandErase(&NAND, block); pattern_fill(); /*** Correctable errors ***/ op_status = nandWritePageData(nandp, block, 0, nand_buf, nandp->config->page_data_size, &ecc_ref); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ nandReadPageData(nandp, block, 0, nand_buf, nandp->config->page_data_size, &ecc_broken); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_NO_ERROR == ecc_result); /* unexpected error */ /**/ byte = 0; bit = 7; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 1, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /**/ byte = 2047; bit = 0; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 2, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /**/ byte = 1027; bit = 3; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 3, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /*** Uncorrectable error ***/ byte = 1027; invert_bit(nand_buf, byte, 3); invert_bit(nand_buf, byte, 4); op_status = nandWritePageData(nandp, block, 4, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, 3); invert_bit(nand_buf, byte, 4); ecc_result = parse_ecc(28, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_UNCORRECTABLE_ERROR == ecc_result); /* This error must be NOT correctable */ /*** make clean ***/ nandErase(&NAND, block); }
msg_t EepromTestThread(void *sdp){ chRegSetThreadName("EepromTst"); cli_println("basic tests"); cli_println("--------------------------------------------------------------"); cli_print("mount aligned file sized to whole test area"); ocfg.barrier_low = TEST_AREA_START; ocfg.barrier_hi = TEST_AREA_END; EepromFileOpen(&ofile, &ocfg); OK(); printfileinfo(sdp, &ofile); cli_print("test fill with 0xFF"); pattern_fill(&ofile, 0xFF); if (chThdShouldTerminate()){goto END;} OK(); cli_print("test fill with 0xAA"); pattern_fill(&ofile, 0xAA); if (chThdShouldTerminate()){goto END;} OK(); cli_print("test fill with 0x55"); pattern_fill(&ofile, 0x55); if (chThdShouldTerminate()){goto END;} OK(); cli_print("test fill with 0x00"); pattern_fill(&ofile, 0x00); if (chThdShouldTerminate()){goto END;} OK(); cli_print("Closing file"); chFileStreamClose(&ofile); OK(); uint32_t b1, b2, b3, b4, istart, ilen; uint8_t pattern = 0x55; b1 = TEST_AREA_START; b2 = TEST_AREA_START + EEPROM_PAGE_SIZE; b3 = TEST_AREA_END - EEPROM_PAGE_SIZE; b4 = TEST_AREA_END; istart = 0; ilen = b3-b2; cli_println(" Linear barriers testing."); chThdSleepMilliseconds(20); overflow_check( b1, b2, b3, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2, b3, b4, istart + 1, ilen - 1, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2, b3, b4, istart + 1, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2, b3, b4, istart + 1, ilen + 23, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b3 + 1, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 2, b3 + 2, b4, istart + 2, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b3 + 1, b4, istart + 1, ilen + 23, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 2, b3 + 2, b4, istart + 1, ilen + 23, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 + 2, b3 - 3, b4, istart + 2, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2, b2 + 1, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2, b2 + 2, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2, b2 + 3, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 + 1, b2 + 2, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 + 1, b2 + 3, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 + 1, b2 + 4, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b2, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b2 + 1, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b2 + 2, b4, istart, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b2 + 1, b4, istart + 1, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b2 + 2, b4, istart + 1, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; overflow_check( b1, b2 - 1, b2 + 3, b4, istart + 1, ilen, pattern, FALSE, sdp); if (chThdShouldTerminate()){goto END;} pattern++; cli_println(" Basic API testing."); chThdSleepMilliseconds(20); ocfg.barrier_low = TEST_AREA_START; ocfg.barrier_hi = TEST_AREA_END; EepromFileOpen(&ofile, &ocfg); chFileStreamSeek(&ofile, 0); EepromWriteByte(&ofile, 0x11); EepromWriteHalfword(&ofile, 0x2222); EepromWriteWord(&ofile, 0x33333333); chFileStreamSeek(&ofile, 0); if(EepromReadByte(&ofile) != 0x11) chDbgPanic(""); if(EepromReadHalfword(&ofile) != 0x2222) chDbgPanic(""); if(EepromReadWord(&ofile) != 0x33333333) chDbgPanic(""); chFileStreamClose(&ofile); OK(); cli_println("All tests passed successfully."); END: chThdExit(0); return 0; }
/** * Create overlapped files like this: * * |<--------- outer file ------------>| * | | * ======b1==b2========================b3===b4====== * | | | | * | |<------ inner file ------>| | * |<----------------- EEPROM -------------------->| */ static void overflow_check(uint32_t b1, uint32_t b2, uint32_t b3, uint32_t b4, uint32_t istart, uint32_t ilen, uint8_t pattern, bool_t pat_autoinc, BaseSequentialStream *sdp){ uint32_t status, i, n; chDbgCheck(ilen < (b4-b1),"sequences more than length of outer file can not be verified"); chprintf(sdp, "b1=%u, b2=%u, b3=%u, b4=%u, istart=%u, ilen=%u, ", b1, b2, b3, b4, istart, ilen); cli_print("autoinc="); if (pat_autoinc) cli_print("TRUE"); else cli_print("FALSE"); chThdSleepMilliseconds(50); /* open outer file and clear it */ ocfg.barrier_low = b1; ocfg.barrier_hi = b4; EepromFileOpen(&ofile, &ocfg); pattern_fill(&ofile, 0x00); /* open inner file */ icfg.barrier_low = b2; icfg.barrier_hi = b3; EepromFileOpen(&ifile, &icfg); /* reference buffer */ memset(referencebuf, 0x00, b4-b1); n = b2 - b1 + istart; if ((ilen + istart) > (b3-b2)) i = b3 - b2 - istart; else i = ilen; while (i > 0){ referencebuf[n] = pattern; n++; i--; if (pat_autoinc) pattern++; } /* check buffer */ n = 0; while (n < ilen){ checkbuf[n] = pattern; n++; if (pat_autoinc) pattern++; } /* now write check buffer content into inner file */ chThdSleepMilliseconds(20); chFileStreamSeek(&ifile, istart); status = chFileStreamWrite(&ifile, checkbuf, ilen); if ((istart + ilen) > (b3 - b2)){ /* data must be clamped */ if (status != (b3 - b2 - istart)) chDbgPanic("not all data written or overflow ocrred"); } else{/* data fitted in file */ if (status != ilen) chDbgPanic("not all data written or overflow ocrred"); } /* read outer file and compare content with reference buffer */ memset(checkbuf, 0x00, b4-b1); chFileStreamSeek(&ofile, 0); status = chFileStreamRead(&ofile, checkbuf, b4-b1); if (status != (b4-b1)) chDbgPanic("reading back failed"); if (memcmp(referencebuf, checkbuf, b4-b1) != 0) chDbgPanic("veryfication failed"); chFileStreamClose(&ofile); chFileStreamClose(&ifile); OK(); }
static unsigned int test_rw(HANDLE hDrive, blk64_t last_block, size_t block_size, blk64_t first_block, size_t blocks_at_once, int pattern_type, int nb_passes) { const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] = { BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC }; unsigned char *buffer = NULL, *read_buffer; int i, pat_idx; unsigned int bb_count = 0; blk64_t got, tryout, recover_block = ~0, *blk_id; size_t id_offset = 0; if ((pattern_type < 0) || (pattern_type >= BADLOCKS_PATTERN_TYPES)) { uprintf("%sInvalid pattern type\n", bb_prefix); cancel_ops = -1; return 0; } if ((nb_passes < 1) || (nb_passes > BADBLOCK_PATTERN_COUNT)) { uprintf("%sInvalid number of passes\n", bb_prefix); cancel_ops = -1; return 0; } buffer = allocate_buffer(2 * blocks_at_once * block_size); read_buffer = buffer + blocks_at_once * block_size; if (!buffer) { uprintf("%sError while allocating buffers\n", bb_prefix); cancel_ops = -1; return 0; } uprintf("%sChecking from block %lu to %lu (1 block = %s)\n", bb_prefix, (unsigned long) first_block, (unsigned long) last_block - 1, SizeToHumanReadable(BADBLOCK_BLOCK_SIZE, FALSE, FALSE)); nr_pattern = nb_passes; cur_pattern = 0; for (pat_idx = 0; pat_idx < nb_passes; pat_idx++) { if (cancel_ops) goto out; if (detect_fakes && (pat_idx == 0)) { srand((unsigned int)GetTickCount64()); id_offset = rand() * (block_size - sizeof(blk64_t)) / RAND_MAX; uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset); } // coverity[dont_call] pattern_fill(buffer, pattern[pattern_type][pat_idx], blocks_at_once * block_size); num_blocks = last_block - 1; currently_testing = first_block; if (s_flag | v_flag) uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pattern_type][pat_idx]); cur_op = OP_WRITE; tryout = blocks_at_once; while (currently_testing < last_block) { if (cancel_ops) goto out; if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { uprintf(abort_msg); fprintf(log_fd, abort_msg); fflush(log_fd); } cancel_ops = -1; goto out; } if (currently_testing + tryout > last_block) tryout = last_block - currently_testing; if (detect_fakes && (pat_idx == 0)) { /* Add the block number at a fixed (random) offset during each pass to allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */ for (i=0; i<(int)blocks_at_once; i++) { blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size); *blk_id = (blk64_t)(currently_testing + i); } } got = do_write(hDrive, buffer, tryout, block_size, currently_testing); if (v_flag > 1) print_status(); if (got == 0 && tryout == 1) bb_count += bb_output(currently_testing++, WRITE_ERROR); currently_testing += got; if (got != tryout) { tryout = 1; if (recover_block == ~0) recover_block = currently_testing - got + blocks_at_once; continue; } else if (currently_testing == recover_block) { tryout = blocks_at_once; recover_block = ~0; } } num_blocks = 0; if (s_flag | v_flag) uprintf("%sReading and comparing\n", bb_prefix); cur_op = OP_READ; num_blocks = last_block; currently_testing = first_block; tryout = blocks_at_once; while (currently_testing < last_block) { if (cancel_ops) goto out; if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { uprintf(abort_msg); fprintf(log_fd, abort_msg); fflush(log_fd); } cancel_ops = -1; goto out; } if (currently_testing + tryout > last_block) tryout = last_block - currently_testing; if (detect_fakes && (pat_idx == 0)) { for (i=0; i<(int)blocks_at_once; i++) { blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size); *blk_id = (blk64_t)(currently_testing + i); } } got = do_read(hDrive, read_buffer, tryout, block_size, currently_testing); if (got == 0 && tryout == 1) bb_count += bb_output(currently_testing++, READ_ERROR); currently_testing += got; if (got != tryout) { tryout = 1; if (recover_block == ~0) recover_block = currently_testing - got + blocks_at_once; continue; } else if (currently_testing == recover_block) { tryout = blocks_at_once; recover_block = ~0; } for (i=0; i < got; i++) { if (memcmp(read_buffer + i * block_size, buffer + i * block_size, block_size)) bb_count += bb_output(currently_testing+i-got, CORRUPTION_ERROR); } if (v_flag > 1) print_status(); } num_blocks = 0; } out: free_buffer(buffer); return bb_count; }