void PrintPmove(pmove_t *pm){ unsigned c1, c2; c1 = CheckBlock(&pm->s, sizeof(pm->s)); c2 = CheckBlock(&pm->cmd, sizeof(pm->cmd)); Com_Printf("sv %3i:%i %i\n", pm->cmd.impulse, c1, c2); }
void PrintPmove(pmove_t *pm) { unsigned c1, c2; if (!pm) { return; } c1 = CheckBlock(&pm->s, sizeof(pm->s)); c2 = CheckBlock(&pm->cmd, sizeof(pm->cmd)); gi.dprintf("sv %3i:%i %i\n", pm->cmd.impulse, c1, c2); }
int EBuffer::BlockUnTab() { EPoint B, E; ELine *L; int O, C; AutoExtend = 0; if (CheckBlock() == 0) return 0; if (RCount <= 0) return 0; B = BB; E = BE; Draw(B.Row, E.Row); for (int i = B.Row; i < E.Row; i++) { L = RLine(i); O = 0; C = 0; while (O < L->Count) { if (L->Chars[O] == '\t') { C = NextTab(C, BFI(this, BFI_TabSize)); if (DelChars(i, O, 1) != 1) return 0; if (InsChars(i, O, C - O, 0) != 1) return 0; O = C; } else { O++; C++; } } } return 1; }
int EBuffer::BlockExtendBegin() { CheckBlock(); ExtendGrab = 0; AutoExtend = 0; int Y = VToR(CP.Row); switch (BlockMode) { case bmStream: if ((Y == BB.Row) && (CP.Col == BB.Col)) ExtendGrab |= 1; if ((Y == BE.Row) && (CP.Col == BE.Col)) ExtendGrab |= 2; break; case bmLine: if (Y == BB.Row) ExtendGrab |= 1; if (Y == BE.Row) ExtendGrab |= 2; break; case bmColumn: if (Y == BB.Row) ExtendGrab |= 1; if (Y == BE.Row) ExtendGrab |= 2; if (CP.Col == BB.Col) ExtendGrab |= 4; if (CP.Col == BE.Col) ExtendGrab |= 8; break; } if (ExtendGrab == 0) { BlockBegin(); BlockEnd(); if (BlockMode == bmColumn) ExtendGrab = 1 | 2 | 4 | 8; else ExtendGrab = 1 | 2; } return 1; }
int EBuffer::BlockUnindent() { EPoint B, E; int L; AutoExtend = 0; if (CheckBlock() == 0) return 0; if (RCount <= 0) return 0; B = BB; E = BE; Draw(B.Row, E.Row); if (SetPosR(B.Col, B.Row) == 0) return 0; for (L = B.Row; L <= E.Row; L++) { switch (BlockMode) { case bmStream: case bmLine: if (L < E.Row || E.Col != 0) { int I = LineIndented(L) - 1; if (I >= 0) IndentLine(L, I); } break; case bmColumn: if (L < E.Row) { if (InsText(L, E.Col, 1, 0) == 0) return 0; if (DelText(L, B.Col, 1) == 0) return 0; } break; } } if (SetPosR(B.Col, B.Row) == 0) return 0; return 1; }
int EBuffer::BlockTrim() { EPoint B, E; int L; AutoExtend = 0; if (CheckBlock() == 0) return 0; if (RCount <= 0) return 0; B = BB; E = BE; Draw(B.Row, E.Row); for (L = B.Row; L <= E.Row; L++) { switch (BlockMode) { case bmStream: if (L < E.Row || E.Col != 0) if (TrimLine(L) == 0) return 0; break; case bmLine: case bmColumn: if (L < E.Row) if (TrimLine(L) == 0) return 0; break; } } return 1; }
void* mir_realloc( void* ptr, size_t size ) { char* p; if ( ptr != NULL ) { if ( !CheckBlock( ptr )) return NULL; p = ( char* )ptr - sizeof(DWORD)*2; } else p = NULL; p = ( char* )realloc( p, size + sizeof(DWORD)*3 ); if ( p == NULL ) { OutputDebugStringA( "memory overflow\n" ); #if defined( _DEBUG ) DebugBreak(); #endif return NULL; } *( DWORD* )p = ( DWORD )size; *( DWORD* )&p[ sizeof(DWORD) ] = BLOCK_ALLOCED; *( DWORD* )&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED; return p + sizeof( DWORD )*2; }
// Test that a Sprout tx with negative version is still rejected // by CheckBlock under Sprout consensus rules. TEST(CheckBlock, BlockSproutRejectsBadVersion) { SelectParams(CBaseChainParams::MAIN); CMutableTransaction mtx; mtx.vin.resize(1); mtx.vin[0].prevout.SetNull(); mtx.vin[0].scriptSig = CScript() << 1 << OP_0; mtx.vout.resize(1); mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; mtx.vout[0].nValue = 0; mtx.vout.push_back(CTxOut( GetBlockSubsidy(1, Params().GetConsensus())/5, Params().GetFoundersRewardScriptAtHeight(1))); mtx.fOverwintered = false; mtx.nVersion = -1; mtx.nVersionGroupId = 0; CTransaction tx {mtx}; CBlock block; block.vtx.push_back(tx); MockCValidationState state; CBlockIndex indexPrev {Params().GenesisBlock()}; auto verifier = libzcash::ProofVerifier::Strict(); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1); EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); }
int main() { SetupAll(); SetupBalls(); DoTimers(); LoadBitmaps(); DoBlock(); while (!key[KEY_ESC] && GoGame == 1) { CheckDead(); CheckBlock(); MoveBall(); if (BallsToDrop > 0) DropBalls(); if (Lives <= 0) GoGame = 0; DrawBack(); CheckExplode(); DrawBalls(); MoveMouse(); MoveStoneBlock(); WaitTimer(); flip(); } EndOfGame(); allegro_exit(); //Clean up allegro return 0; }
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransaction>& vtx_missing) const { assert(!header.IsNull()); block = header; block.vtx.resize(txn_available.size()); size_t tx_missing_offset = 0; for (size_t i = 0; i < txn_available.size(); i++) { if (!txn_available[i]) { if (vtx_missing.size() <= tx_missing_offset) return READ_STATUS_INVALID; block.vtx[i] = vtx_missing[tx_missing_offset++]; } else block.vtx[i] = *txn_available[i]; } if (vtx_missing.size() != tx_missing_offset) return READ_STATUS_INVALID; CValidationState state; if (!CheckBlock(block, state, Params().GetConsensus())) { if (state.CorruptionPossible()) return READ_STATUS_FAILED; // Possible Short ID collision return READ_STATUS_INVALID; } LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size()); if (vtx_missing.size() < 5) { for (const CTransaction& tx : vtx_missing) LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", header.GetHash().ToString(), tx.GetHash().ToString()); } return READ_STATUS_OK; }
// 旋转方块 void OnRotate() { // 获取可以旋转的 x 偏移量 int dx; BLOCKINFO tmp = g_CurBlock; tmp.dir++; if (CheckBlock(tmp)) { dx = 0; goto rotate; } tmp.x = g_CurBlock.x - 1; if (CheckBlock(tmp)) { dx = -1; goto rotate; } tmp.x = g_CurBlock.x + 1; if (CheckBlock(tmp)) { dx = 1; goto rotate; } tmp.x = g_CurBlock.x - 2; if (CheckBlock(tmp)) { dx = -2; goto rotate; } tmp.x = g_CurBlock.x + 2; if (CheckBlock(tmp)) { dx = 2; goto rotate; } return;rotate: // 旋转 DrawBlock(g_CurBlock, HIDE); g_CurBlock.dir++; g_CurBlock.x += dx; DrawBlock(g_CurBlock); }
int EBuffer::BlockSort(int Reverse) { int rq; ELine *oldL; if (CheckBlock() == 0) return 0; if (RCount == 0) return 0; SortMinRow = BB.Row; SortMaxRow = BE.Row; if (BlockMode != bmStream || BE.Col == 0) SortMaxRow--; if (SortMinRow >= SortMaxRow) return 1; SortBuffer = this; SortReverse = Reverse; switch (BlockMode) { case bmLine: case bmStream: SortMinCol = -1; SortMaxCol = -1; break; case bmColumn: SortMinCol = BB.Col; SortMaxCol = BE.Col; break; } SortRows = (int *)malloc((SortMaxRow - SortMinRow + 1) * sizeof(int)); if (SortRows == 0) { free(SortRows); return 0; } for (rq = 0; rq <= SortMaxRow - SortMinRow; rq++) SortRows[rq] = rq + SortMinRow; qsort(SortRows, SortMaxRow - SortMinRow + 1, sizeof(int), SortProc); // now change the order of lines according to new order in Rows array. for (rq = 0; rq <= SortMaxRow - SortMinRow; rq++) { oldL = RLine(SortRows[rq]); if (InsLine(1 + rq + SortMaxRow, 0) == 0) return 0; if (InsChars(1 + rq + SortMaxRow, 0, oldL->Count, oldL->Chars) == 0) return 0; } for (rq = 0; rq <= SortMaxRow - SortMinRow; rq++) if (DelLine(SortMinRow) == 0) return 0; free(SortRows); return 1; }
int EBuffer::BlockEnd() { EPoint X; X.Row = VToR(CP.Row); X.Col = CP.Col; CheckBlock(); SetBE(X); return 1; }
TEST(CheckBlock, VersionTooLow) { auto verifier = libzcash::ProofVerifier::Strict(); CBlock block; block.nVersion = 1; MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "version-too-low", false)).Times(1); EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); }
int EBuffer::InsertString(const char *aStr, int aCount) { int P; int C, L; int Y = VToR(CP.Row); if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (CP.Col < LineLen()) if (KillChar() == 0) return 0; if (InsText(Y, CP.Col, aCount, aStr) == 0) return 0; C = CP.Col; L = VToR(CP.Row); P = CharOffset(RLine(L), C); P += aCount; C = ScreenPos(RLine(L), P); if (SetPos(C, CP.Row) == 0) return 0; if (BFI(this, BFI_Trim) && *aStr != '\t') if (TrimLine(L) == 0) return 0; if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; } else if (BFI(this, BFI_WordWrap) == 1) { int P, C = CP.Col; PELine LP; int L; if (C > BFI(this, BFI_RightMargin)) { L = CP.Row; C = BFI(this, BFI_RightMargin); P = CharOffset(LP = RLine(L), C); while ((C > BFI(this, BFI_LeftMargin)) && ((LP->Chars[P] != ' ') && (LP->Chars[P] != 9))) C = ScreenPos(LP, --P); if (P <= BFI(this, BFI_LeftMargin)) { C = BFI(this, BFI_RightMargin); } else C = ScreenPos(LP, P); if (SplitLine(L, C) == 0) return 0; IndentLine(L + 1, BFI(this, BFI_LeftMargin)); if (SetPos(CP.Col - C - 1 + BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0; } } return 1; }
int EBuffer::TypeChar(char aCh) { // does abbrev expansion if appropriate if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (ChClass(aCh) == 0 && BFI(this, BFI_Abbreviations) == 1) { PELine L = VLine(CP.Row); int C, P, P1, C1, Len, R; char Str[256]; EAbbrev *ab; R = VToR(CP.Row); C = CP.Col; P = CharOffset(L, C); if (P >= 0 && P <= L->Count) { //fprintf(stderr, "TypeChar 1\n"); P1 = P; C1 = ScreenPos(L, P); while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_'))) P--; Len = P1 - P; C = ScreenPos(L, P); assert(C1 - C == Len); if (Len > 0 && Len < int (sizeof(Str))) { //fprintf(stderr, "TypeChar 2\n"); memcpy(Str, L->Chars + P, Len); Str[Len] = 0; ab = Mode->FindAbbrev(Str); if (ab) { //fprintf(stderr, "TypeChar 3\n"); if (ab->Replace != 0) { //fprintf(stderr, "TypeChar 4\n"); if (DelText(R, C, C1 - C) == 0) return 0; if (ab->Replace) { //fprintf(stderr, "TypeChar 5 %s <- %s\n", ab->Replace, ab->Match); Len = strlen(ab->Replace); if (InsText(R, C, Len, ab->Replace) == 0) return 0; if (SetPos(C + Len, CP.Row) == 0) return 0; } else { if (SetPos(C, CP.Row) == 0) return 0; } } else { if (((EGUI *)gui)->ExecMacro(View->MView->Win, ab->Cmd) == 0) return 0; } } } } } return InsertString(&aCh, 1); }
int EBuffer::BlockExtendEnd() { EPoint T, B, E; CheckBlock(); B = BB; E = BE; switch (BlockMode) { case bmLine: if (ExtendGrab & 1) { B.Row = VToR(CP.Row); B.Col = 0; } else if (ExtendGrab & 2) { E.Row = VToR(CP.Row); E.Col = 0; } if (B.Row > E.Row) { T = B; B = E; E = T; } break; case bmStream: if (ExtendGrab & 1) { B.Col = CP.Col; B.Row = VToR(CP.Row); } else if (ExtendGrab & 2) { E.Col = CP.Col; E.Row = VToR(CP.Row); } if ((B.Row > E.Row) || ((B.Row == E.Row) && (B.Col > E.Col))) { T = B; B = E; E = T; } break; case bmColumn: if (ExtendGrab & 1) B.Row = VToR(CP.Row); else if (ExtendGrab & 2) E.Row = VToR(CP.Row); if (ExtendGrab & 4) B.Col = CP.Col; else if (ExtendGrab & 8) E.Col = CP.Col; if (B.Row > E.Row) { int T; T = B.Row; B.Row = E.Row; E.Row = T; } if (B.Col > E.Col) { int T; T = B.Col; B.Col = E.Col; E.Col = T; } break; } SetBB(B); SetBE(E); ExtendGrab = 0; AutoExtend = 0; return 1; }
int EBuffer::BlockReIndent() { EPoint P = CP; EPoint B, E; AutoExtend = 0; if (CheckBlock() == 0) return 0; if (RCount <= 0) return 0; B = BB; E = BE; Draw(B.Row, E.Row); for (int i = B.Row; i < E.Row; i++) { if (SetPosR(0, i) == 0) return 0; if (LineIndent() == 0) return 0; } return SetPos(P.Col, P.Row); }
void mir_free( void* ptr ) { char* p; DWORD size; if ( ptr == NULL ) return; if ( !CheckBlock( ptr )) return; p = ( char* )ptr - sizeof(DWORD)*2; size = *( DWORD* )p; *( DWORD* )&p[ sizeof(DWORD) ] = BLOCK_FREED; *( DWORD* )&p[ size + sizeof(DWORD)*2 ] = BLOCK_FREED; free( p ); }
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) { assert(!header.IsNull()); uint256 hash; if (header.nVersionPoW2Witness == 0) hash = header.GetHashLegacy(); else hash = header.GetHashPoW2(); block = header; block.vtx.resize(txn_available.size()); size_t tx_missing_offset = 0; for (size_t i = 0; i < txn_available.size(); i++) { if (!txn_available[i]) { if (vtx_missing.size() <= tx_missing_offset) return READ_STATUS_INVALID; block.vtx[i] = vtx_missing[tx_missing_offset++]; } else block.vtx[i] = std::move(txn_available[i]); } // Make sure we can't call FillBlock again. header.SetNull(); txn_available.clear(); if (vtx_missing.size() != tx_missing_offset) return READ_STATUS_INVALID; CValidationState state; if (!CheckBlock(block, state, Params().GetConsensus())) { // TODO: We really want to just check merkle tree manually here, // but that is expensive, and CheckBlock caches a block's // "checked-status" (in the CBlock?). CBlock should be able to // check its own merkle root and cache that check. if (state.CorruptionPossible()) return READ_STATUS_FAILED; // Possible Short ID collision return READ_STATUS_CHECKBLOCK_FAILED; } LogPrint(BCLog::CMPCTBLOCK, "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool (incl at least %lu from extra pool) and %lu txn requested\n", hash.ToString(), prefilled_count, mempool_count, extra_count, vtx_missing.size()); if (vtx_missing.size() < 5) { for (const auto& tx : vtx_missing) { LogPrint(BCLog::CMPCTBLOCK, "Reconstructed block %s required tx %s\n", hash.ToString(), tx->GetHash().ToString()); } } return READ_STATUS_OK; }
static void DuplicateInputs(benchmark::State& state) { const CScript SCRIPT_PUB{CScript(OP_TRUE)}; const CChainParams& chainparams = Params(); CBlock block{}; CMutableTransaction coinbaseTx{}; CMutableTransaction naughtyTx{}; CBlockIndex* pindexPrev = ::ChainActive().Tip(); assert(pindexPrev != nullptr); block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); block.nNonce = 0; auto nHeight = pindexPrev->nHeight + 1; // Make a coinbase TX coinbaseTx.vin.resize(1); coinbaseTx.vin[0].prevout.SetNull(); coinbaseTx.vout.resize(1); coinbaseTx.vout[0].scriptPubKey = SCRIPT_PUB; coinbaseTx.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus()); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; naughtyTx.vout.resize(1); naughtyTx.vout[0].nValue = 0; naughtyTx.vout[0].scriptPubKey = SCRIPT_PUB; uint64_t n_inputs = (((MAX_BLOCK_SERIALIZED_SIZE / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).GetTotalSize() + CTransaction(naughtyTx).GetTotalSize())) / 41) - 100; for (uint64_t x = 0; x < (n_inputs - 1); ++x) { naughtyTx.vin.emplace_back(GetRandHash(), 0, CScript(), 0); } naughtyTx.vin.emplace_back(naughtyTx.vin.back()); block.vtx.push_back(MakeTransactionRef(std::move(coinbaseTx))); block.vtx.push_back(MakeTransactionRef(std::move(naughtyTx))); block.hashMerkleRoot = BlockMerkleRoot(block); while (state.KeepRunning()) { CValidationState cvstate{}; assert(!CheckBlock(block, cvstate, chainparams.GetConsensus(), false, false)); assert(cvstate.GetRejectReason() == "bad-txns-inputs-duplicate"); } }
static void DeserializeAndCheckBlockTest(benchmark::State& state) { CDataStream stream((const char*)block_bench::block413567, (const char*)&block_bench::block413567[sizeof(block_bench::block413567)], SER_NETWORK, PROTOCOL_VERSION); char a = '\0'; stream.write(&a, 1); // Prevent compaction const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); while (state.KeepRunning()) { CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here stream >> block; assert(stream.Rewind(sizeof(block_bench::block413567))); CValidationState validationState; assert(CheckBlock(block, validationState, chainParams->GetConsensus())); } }
// remove selected text and paste information from clipboard to replace it int EBuffer::BlockPasteOver(int clipboard) { // if there is existing selection, remove it's contents if (CheckBlock()) { BlockKill(); } // paste text from clipboard if (BlockPaste(clipboard)) { // go to end of selection SetPos(BE.Col, BE.Row); // remove selection return BlockUnmark(); } return 0; }
int EBuffer::InsertSpacesToTab(int TSize) { int P = CP.Col, P1; if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (TSize <= 0) TSize = BFI(this, BFI_TabSize); P1 = NextTab(P, TSize); if (BFI(this, BFI_Insert) == 0) { if (CP.Col < LineLen()) if (DelText(VToR(CP.Row), CP.Col, P1 - P) == 0) return 0; } if (InsText(VToR(CP.Row), CP.Col, P1 - P, 0) == 0) return 0; if (SetPos(P1, CP.Row) == 0) return 0; return 1; }
int EBuffer::Delete() { int Y = VToR(CP.Row); if (CheckBlock() == 1 && BFI(this, BFI_DeleteKillBlock)) { if (BlockKill() == 0) return 0; } else if (CP.Col < LineLen()) { if (BFI(this, BFI_DeleteKillTab)) { int P; int C = CP.Col, C1; P = CharOffset(RLine(Y), C); C1 = ScreenPos(RLine(Y), P + 1); if (DelText(Y, C, C1 - C) == 0) return 0; } else { ELine *L = RLine(Y); int C = CharOffset(L, CP.Col); if (L->Count > 0 && L->Chars[C] == '\t') { /* We're on top of tab character. Skip over all spaces and tabs so that only the last space/tab gets deleted. */ while (C < L->Count && (L->Chars[C+1] == '\t' || L->Chars[C+1] == ' ')) C++; } if (DelText(Y, ScreenPos(L, C), 1) == 0) return 0; } } else if (LineJoin() == 0) return 0; if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; if (CP.Col >= LineLen(Y)) if (CP.Row < VCount - 1) { if (SetPos(BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0; } } if (BFI(this, BFI_Trim)) if (TrimLine(VToR(CP.Row)) == 0) return 0; return 1; }
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransaction>& vtx_missing) const { assert(!header.IsNull()); block = header; block.vtx.resize(txn_available.size()); size_t tx_missing_offset = 0; for (size_t i = 0; i < txn_available.size(); i++) { if (!txn_available[i]) { if (vtx_missing.size() <= tx_missing_offset) return READ_STATUS_INVALID; block.vtx[i] = vtx_missing[tx_missing_offset++]; } else block.vtx[i] = *txn_available[i]; } if (vtx_missing.size() != tx_missing_offset) return READ_STATUS_INVALID; CValidationState state; if (!CheckBlock(block, state, Params().GetConsensus())) { // TODO: We really want to just check merkle tree manually here, // but that is expensive, and CheckBlock caches a block's // "checked-status" (in the CBlock?). CBlock should be able to // check its own merkle root and cache that check. if (state.CorruptionPossible()) return READ_STATUS_FAILED; // Possible Short ID collision return READ_STATUS_INVALID; } LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size()); if (vtx_missing.size() < 5) { for(const CTransaction& tx : vtx_missing) LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", header.GetHash().ToString(), tx.GetHash().ToString()); } return READ_STATUS_OK; }
//------------------------------------------------------------------------------ /// Initializes a ManagedNandFlash instance. Scans the device to retrieve or /// create block status information. /// \param managed Pointer to a ManagedNandFlash instance. /// \param model Pointer to the underlying nand chip model. Can be 0. /// \param commandAddress Address at which commands are sent. /// \param addressAddress Address at which addresses are sent. /// \param dataAddress Address at which data is sent. /// \param pinChipEnable Pin controlling the CE signal of the NandFlash. /// \param pinReadyBusy Pin used to monitor the ready/busy signal of the Nand. /// \param baseBlock Base physical block address of managed area, managed 0. /// \param sizeInBlocks Number of blocks that is managed. //------------------------------------------------------------------------------ unsigned char ManagedNandFlash_Initialize( struct ManagedNandFlash *managed, const struct NandFlashModel *model, unsigned int commandAddress, unsigned int addressAddress, unsigned int dataAddress, const Pin pinChipEnable, const Pin pinReadyBusy, unsigned short baseBlock, unsigned short sizeInBlocks) { unsigned char error; unsigned char spare[NandCommon_MAXPAGESPARESIZE]; unsigned int numBlocks; const struct NandSpareScheme *scheme; unsigned int block, phyBlock; struct NandBlockStatus blockStatus; unsigned char badBlockMarker; unsigned int eraseCount, minEraseCount, maxEraseCount; TRACE_DEBUG("ManagedNandFlash_Initialize()\n\r"); // Initialize EccNandFlash error = EccNandFlash_Initialize(ECC(managed), model, commandAddress, addressAddress, dataAddress, pinChipEnable, pinReadyBusy); if (error) { return error; } // Retrieve model information numBlocks = NandFlashModel_GetDeviceSizeInBlocks(MODEL(managed)); scheme = NandFlashModel_GetScheme(MODEL(managed)); // Initialize base & size if (sizeInBlocks == 0) sizeInBlocks = numBlocks; if (baseBlock > numBlocks) { baseBlock = 0; } else if (baseBlock + sizeInBlocks > numBlocks) { sizeInBlocks = numBlocks - baseBlock; } TRACE_INFO("Managed NF area: %d + %d\n\r", baseBlock, sizeInBlocks); if (sizeInBlocks > NandCommon_MAXNUMBLOCKS) { TRACE_ERROR("Out of Maxmized Managed Size: %d > %d\n\r", sizeInBlocks, NandCommon_MAXNUMBLOCKS); TRACE_INFO("Change NandCommon_MAXNUMBLOCKS or sizeInBlocks\n\r"); return NandCommon_ERROR_OUTOFBOUNDS; } managed->baseBlock = baseBlock; managed->sizeInBlocks = sizeInBlocks; // Initialize block statuses // First, check if device is virgin if (IsDeviceVirgin(managed, spare)) { TRACE_WARNING("Device is virgin, doing initial block scanning ...\n\r"); // Perform initial scan of the device area for (block=0; block < sizeInBlocks; block++) { phyBlock = baseBlock + block; // Check if physical block is bad error = CheckBlock(managed, phyBlock, spare); if (error == BADBLOCK) { // Mark block as bad TRACE_DEBUG("Block #%d is bad\n\r", block); managed->blockStatuses[block].status = NandBlockStatus_BAD; } else if (error == GOODBLOCK) { // Mark block as free with erase count 0 TRACE_DEBUG("Block #%d is free\n\r", block); managed->blockStatuses[block].status = NandBlockStatus_FREE; managed->blockStatuses[block].eraseCount = 0; // Write status in spare of block first page error = WriteBlockStatus(managed, phyBlock, &(managed->blockStatuses[block]), spare); if (error) { TRACE_ERROR("ManagedNandFlash_Initialize: WR spare\n\r"); return error; } } else { TRACE_ERROR("ManagedNandFlash_Initialize: Scan device\n\r"); return error; } } } else { TRACE_INFO("Managed, retrieving information ...\n\r"); // Retrieve block statuses from their first page spare area // (find maximum and minimum wear at the same time) minEraseCount = 0xFFFFFFFF; maxEraseCount = 0; for (block=0; block < sizeInBlocks; block++) { phyBlock = baseBlock + block; // Read spare of first page error = RawNandFlash_ReadPage(RAW(managed), phyBlock, 0, 0, spare); if (error) { TRACE_ERROR("ManagedNandFlash_Initialize: Read block #%d(%d)\n\r", block, phyBlock); } // Retrieve bad block marker and block status NandSpareScheme_ReadBadBlockMarker(scheme, spare, &badBlockMarker); NandSpareScheme_ReadExtra(scheme, spare, &blockStatus, 4, 0); // If they do not match, block must be bad if ( (badBlockMarker != 0xFF) && (blockStatus.status != NandBlockStatus_BAD)) { TRACE_DEBUG("Block #%d(%d) is bad\n\r", block, phyBlock); managed->blockStatuses[block].status = NandBlockStatus_BAD; } // Check that block status is not default // (meaning block is not managed) else if (blockStatus.status == NandBlockStatus_DEFAULT) { TRACE_ERROR("Block #%d(%d) is not managed\n\r", block, phyBlock); return NandCommon_ERROR_NOMAPPING; } // Otherwise block status is accurate else { TRACE_DEBUG("Block #%03d(%d) : status = %2d | eraseCount = %d\n\r", block, phyBlock, blockStatus.status, blockStatus.eraseCount); managed->blockStatuses[block] = blockStatus; // Check for min/max erase counts if (blockStatus.eraseCount < minEraseCount) { minEraseCount = blockStatus.eraseCount; } if (blockStatus.eraseCount > maxEraseCount) { maxEraseCount = blockStatus.eraseCount; } //// Clean block //// Release LIVE blocks //if (managed->blockStatuses[block].status == NandBlockStatus_LIVE) { // // ManagedNandFlash_ReleaseBlock(managed, block); //} //// Erase DIRTY blocks //if (managed->blockStatuses[block].status == NandBlockStatus_DIRTY) { // // ManagedNandFlash_EraseBlock(managed, block); //} } } // Display erase count information TRACE_ERROR_WP("|--------|------------|--------|--------|--------|\n\r"); TRACE_ERROR_WP("| Wear | Count | Free | Live | Dirty |\n\r"); TRACE_ERROR_WP("|--------|------------|--------|--------|--------|\n\r"); for (eraseCount=minEraseCount; eraseCount <= maxEraseCount; eraseCount++) { unsigned int count = 0, live = 0, dirty = 0, free = 0; for (block=0; block < sizeInBlocks; block++) { if ((managed->blockStatuses[block].eraseCount == eraseCount) && (managed->blockStatuses[block].status != NandBlockStatus_BAD)) { count++; switch (managed->blockStatuses[block].status) { case NandBlockStatus_LIVE: live++; break; case NandBlockStatus_DIRTY: dirty++; break; case NandBlockStatus_FREE: free++; break; } } } if (count > 0) { TRACE_ERROR_WP("| %4d | %8d | %4d | %4d | %4d |\n\r", eraseCount, count, free, live, dirty); } } TRACE_ERROR_WP("|--------|------------|--------|--------|--------|\n\r"); } return 0; }
int EBuffer::BlockEnTab() { EPoint B, E; ELine *L; int O, C, O1, C1; char tab = '\t'; AutoExtend = 0; if (CheckBlock() == 0) return 0; if (RCount <= 0) return 0; B = BB; E = BE; Draw(B.Row, E.Row); for (int i = B.Row; i < E.Row; i++) { L = RLine(i); O = C = 0; O1 = C1 = 0; while (O < L->Count) { if (L->Chars[O] == '\t') { // see if there are spaces to remove int C2 = NextTab(C, BFI(this, BFI_TabSize)); int N = BFI(this, BFI_TabSize) - (C2 - C); if (O - O1 < N) N = O - O1; if (N > 0) { if (DelChars(i, O - N, N) != 1) return 0; O -= N; C = C2; O++; C1 = C; O1 = O; } else { O++; C = C2; O1 = O; C1 = C; } } else if (L->Chars[O] != ' ') { // nope, cannot put tab here O++; C++; C1 = C; O1 = O; } else if (((C % BFI(this, BFI_TabSize)) == (BFI(this, BFI_TabSize) - 1)) && (C - C1 > 0)) { // reached a tab and can put one int N = BFI(this, BFI_TabSize); if (O - O1 + 1 < N) { N = O - O1 + 1; } else if (O - O1 + 1 > N) { O1 = O - N + 1; } if (DelChars(i, O1, N) != 1) return 0; if (InsChars(i, O1, 1, &tab) != 1) return 0; O1++; O = O1; C++; C1 = C; } else { O++; C++; } } } return 1; }
int EBuffer::BackSpace() { int Y = VToR(CP.Row); if (CheckBlock() == 1 && BFI(this, BFI_BackSpKillBlock)) { if (BlockKill() == 0) return 0; } else if (BFI(this, BFI_WordWrap) == 2 && CP.Row > 0 && !IsLineBlank(Y - 1) && CP.Col <= BFI(this, BFI_LeftMargin) && CP.Col <= LineIndented(Y)) { if (SetPos(LineLen(Y - 1), CP.Row - 1) == 0) return 0; } else if (CP.Col == 0) { if (CP.Row > 0) if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0; if (MoveUp() == 0) return 0; if (MoveLineEnd() == 0) return 0; if (LineJoin() == 0) return 0; } else { if (BFI(this, BFI_BackSpUnindents) && (LineIndented(Y) == CP.Col)) { int C = CP.Col, C1 = 0; int L = VToR(CP.Row); C1 = C; while (L > 0 && (IsLineBlank(L - 1) || (C1 = LineIndented(L - 1)) >= C)) L--; if (L == 0) C1 = 0; if (C1 == C) C1--; if (C1 < 0) C1 = 0; if (C1 > C) C1 = C; if (SetPos(C1, CP.Row) == 0) return 0; if (C > LineIndented(Y)) return 0; if (DelText(Y, C1, C - C1) == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (InsText(Y, C1, 1, " ") == 0) return 0; } else if (BFI(this, BFI_BackSpKillTab)) { int P; int C = CP.Col, C1; P = CharOffset(RLine(Y), C - 1); C1 = ScreenPos(RLine(Y), P); if (SetPos(C1, CP.Row) == 0) return 0; if (DelText(Y, C1, C - C1) == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (InsText(Y, C1, 1, " ") == 0) return 0; } else { if (MovePrev() == 0) return 0; ELine *L = RLine(Y); int C = CharOffset(L, CP.Col); if (L->Count > 0 && L->Chars[C] == 9) { /* We're on top of tab character. Skip over all spaces and tabs so that only the last space/tab gets deleted. */ while (C < L->Count && (L->Chars[C+1] == 9 || L->Chars[C+1] == ' ')) C++; } if (DelText(Y, ScreenPos(L, C), 1) == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (InsText(Y, ScreenPos(L, C), 1, " ") == 0) return 0; } } if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; } if (BFI(this, BFI_Trim)) { Y = VToR(CP.Row); if (TrimLine(Y) == 0) return 0; } return 1; }
int EBuffer::KillBlockOrCharPrev() { if (CheckBlock() == 0) return KillCharPrev(); else return BlockKill(); }