void subElectronFromBelow(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawElectronFromBelow(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0xF; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si + FieldWidth]) != fiExplosion) { PlayField16[si + FieldWidth] = 0; // electron left that field } if (bl < 8) // electron still goes up { bl = bl + 0x10; MovHighByte(&PlayField16[si], bl); return; } // loc_g_7C84 PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field ax = PlayField16[si - 1]; // check left field if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy { MovHighByte(&PlayField16[si], 1); // start to turn left return; } // loc_g_7CA4: ax = PlayField16[si - FieldWidth]; // cannot turn left -> check above if (ax == 0) // check if empty { PlayField16[si] = 0x1BB; // mark as "electron leaving" si = si - FieldWidth; // go up! PlayField16[si] = 0x1018; return; } if (LowByte(ax) == fiMurphy) // check for murphy above { ExplodeFieldSP(si); // Explode return; } // loc_g_7CC6: ax = PlayField16[si + 1]; // check right field if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy { MovHighByte(&PlayField16[si], 9); // start to turn right return; } // loc_g_7CE0: // else: no way to go, start turning around MovHighByte(&PlayField16[si], 1); }
void subElectronFromLeft(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawElectronFromLeft(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0x27; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si - 1]) != fiExplosion) { PlayField16[si - 1] = 0; // electron left that field } if (bl < 8) // electron still goes right { bl = bl + 0x28; MovHighByte(&PlayField16[si], bl); return; } // loc_g_7E7E: PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field ax = PlayField16[si - FieldWidth]; // check above if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 7); return; } // loc_g_7E9E: ax = PlayField16[si + 1]; // check right(straight on) if (ax == 0) { PlayField16[si] = 0x4BB; si = si + 1; // 1 field right PlayField16[si] = 0x2818; return; } // loc_g_7EB5: if (LowByte(ax) == fiMurphy) { ExplodeFieldSP(si); // Explode return; } // loc_g_7EC0: ax = PlayField16[si + FieldWidth]; // check below if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 0xB); return; } // loc_g_7A69: MovHighByte(&PlayField16[si], 7); }
void subElectronFromAbove(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawElectronFromAbove(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0x1F; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si - FieldWidth]) != fiExplosion) { PlayField16[si - FieldWidth] = 0; // electron left that field } if (bl < 8) // electron still goes down { bl = bl + 0x20; MovHighByte(&PlayField16[si], bl); return; } // loc_g_7DD7 PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field ax = PlayField16[si + 1]; // check right if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 5); return; } // loc_g_7DF7: ax = PlayField16[si + FieldWidth]; // check below if (ax == 0) { PlayField16[si] = 0x3BB; si = si + FieldWidth; // 1 field down PlayField16[si] = 0x2018; return; } // loc_g_7E0E: if (LowByte(ax) == fiMurphy) { ExplodeFieldSP(si); // Explode return; } // loc_g_7E19: ax = PlayField16[si - 1]; // check left if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 0xD); return; } // loc_g_7E33: MovHighByte(&PlayField16[si], 5); }
void subElectronFromRight(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawElectronFromRight(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0x17; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si + 1]) != fiExplosion) { PlayField16[si + 1] = 0; // electron left that field } // loc_g_7D1D: if (bl < 8) // sniksnak still goes left { bl = bl + 0x18; MovHighByte(&PlayField16[si], bl); return; } // loc_g_7D2A: PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field ax = PlayField16[si + FieldWidth]; // check below if (ax == 0 || LowByte(ax) == fiMurphy) // empty or murphy? { MovHighByte(&PlayField16[si], 3); // yes -> turn left down return; } // loc_g_7D4A: ax = PlayField16[si - 1]; // check left, etc ... see the comments on subElectronFromBelow() if (ax == 0) { PlayField16[si] = 0x2BB; si = si - 1; // 1 field left PlayField16[si] = 0x1818; return; } // loc_g_7D61: if (LowByte(ax) == fiMurphy) { ExplodeFieldSP(si); // Explode return; } // loc_g_7D6C: ax = PlayField16[si - FieldWidth]; // check above if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 0xF); return; } // loc_g_7D86: MovHighByte(&PlayField16[si], 3); }
__checkReturn std::string UnpackedIP( __in PackedIP const f_ip ) { std::stringstream ss; ss << static_cast<int>(LowByte( LowWord( f_ip ) )) << "." << static_cast<int>(HighByte( LowWord( f_ip ) )) << "." << static_cast<int>(LowByte( HighWord( f_ip ) )) << "." << static_cast<int>(HighByte( HighWord( f_ip ) )); return ss.str(); }
void subCleanUpForInfotronsAbove(int si) { int ax; if (LowByte(PlayField16[si]) != fiExplosion) PlayField16[si] = 0; if (PlayField16[si - FieldWidth] != 0) { if (PlayField16[si - FieldWidth] != 0x9999) return; if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiZonk) return; } if (PlayField16[si - FieldWidth - 1] == fiInfotron) goto loc_g_16FE; loc_g_16F6: if (PlayField16[si - FieldWidth + 1] == fiInfotron) goto loc_g_1722; return; loc_g_16FE: ax = PlayField16[si - 1]; if (ax == fiZonk || ax == fiInfotron || ax == fiRAM) { PlayField16[si - FieldWidth - 1] = 0x6004; PlayField16[si - FieldWidth] = 0x8888; return; } goto loc_g_16F6; loc_g_1722: ax = PlayField16[si + 1]; if (ax == fiZonk || ax == fiInfotron || ax == fiRAM) { PlayField16[si - FieldWidth + 1] = 0x5004; PlayField16[si - FieldWidth] = 0x8888; } }
void subAnimateElectrons(int si) { int bx, Tmp; if (SnikSnaksElectronsFrozen == 1) return; if (LowByte(PlayField16[si]) != fiElectron) return; bx = HighByte(PlayField16[si]); Tmp = bx / 8; switch (Tmp) { case 0: subElectronTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc. break; case 1: subElectronTurnRight(si, bx); // turn right break; case 2: subElectronFromBelow(si, bx); // access si from below break; case 3: subElectronFromRight(si, bx); // access si from right break; case 4: subElectronFromAbove(si, bx); // access si from above break; case 5: subElectronFromLeft(si, bx); // access si from left break; } }
void UpdatePlayfield(boolean force_redraw) { int x, y; #if 1 int num_redrawn = 0; #endif for (y = DisplayMinY; y <= DisplayMaxY; y++) { for (x = DisplayMinX; x <= DisplayMaxX; x++) { int element = LowByte(PlayField16[GetSI(x, y)]); int graphic = GfxGraphic[x][y]; int sync_frame = GfxFrame[x][y]; boolean redraw = force_redraw; #if 0 redraw = TRUE; // !!! TEST ONLY -- ALWAYS REDRAW !!! #endif if (graphic < 0) { GfxGraphicLast[x][y] = GfxGraphic[x][y]; continue; } if (element != GfxElementLast[x][y] && graphic == GfxGraphicLast[x][y]) { /* element changed, but not graphic => disable updating graphic */ GfxElementLast[x][y] = element; GfxGraphicLast[x][y] = GfxGraphic[x][y] = -1; continue; } if (graphic != GfxGraphicLast[x][y]) // new graphic { redraw = TRUE; GfxElementLast[x][y] = element; GfxGraphicLast[x][y] = GfxGraphic[x][y]; sync_frame = GfxFrame[x][y] = 0; } else if (isNextAnimationFrame_SP(graphic, sync_frame)) // new frame { redraw = TRUE; } if (redraw) { int sx = x * StretchWidth; int sy = y * StretchWidth; #if 0 printf("::: REDRAW (%d, %d): %d, %d\n", x, y, graphic, sync_frame); #endif DDSpriteBuffer_BltImg(sx, sy, graphic, sync_frame); #if 1 num_redrawn++; #endif } } } #if 0 printf("::: FRAME %d: %d redrawn\n", FrameCounter, num_redrawn); #endif }
bool GoPiGo::IBoard::WriteAnalog(char APin, char AValue) { return this->WriteBlock(analog_write_cmd, APin, LowByte(AValue), 0); }
void subElectronTurnLeft(int si, int bx) { int ax, bl; ax = (TimerVar & 3); if (ax != 0) { if (ax == 3) goto loc_g_7ACD; return; } // loc_g_7A9F: // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawElectronTurnLeft(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = (bx + 1) & 0x7; MovHighByte(&PlayField16[si], bx); return; loc_g_7ACD: bl = HighByte(PlayField16[si]); if (bl == 0) goto loc_g_7AE6; if (bl == 2) goto loc_g_7B05; if (bl == 4) goto loc_g_7B24; if (bl == 6) goto loc_g_7B43; return; loc_g_7AE6: // pointing up ax = PlayField16[si - FieldWidth]; if (ax == 0) // above is empty -> go up goto loc_g_7AF5; if (LowByte(ax) == fiMurphy) // above is murphy -> explode ExplodeFieldSP(si); return; loc_g_7AF5: // above is empty -> go up PlayField16[si] = 0x1BB; si = si - FieldWidth; // 1 field up PlayField16[si] = 0x1018; return; loc_g_7B05: // pointing left ax = PlayField16[si - 1]; if (ax == 0) // left is empty -> go there goto loc_g_7B14; if (LowByte(ax) == fiMurphy) // left is murphy -> explode ExplodeFieldSP(si); return; loc_g_7B14: // left is empty -> go there PlayField16[si] = 0x2BB; si = si - 1; // 1 field left PlayField16[si] = 0x1818; return; loc_g_7B24: // pointing down ax = PlayField16[si + FieldWidth]; if (ax == 0) // below is empty -> go down goto loc_g_7B33; if (LowByte(ax) == fiMurphy) // below is murphy -> explode ExplodeFieldSP(si); return; loc_g_7B33: // below is empty -> go down PlayField16[si] = 0x3BB; si = si + FieldWidth; // 1 field down PlayField16[si] = 0x2018; return; loc_g_7B43: // pointing Right ax = PlayField16[si + 1]; if (ax == 0) // right is empty -> go there goto loc_g_7B55; if (LowByte(ax) == fiMurphy) // right is murphy -> explode ExplodeFieldSP(si); return; loc_g_7B55: // right is empty -> go there PlayField16[si] = 0x4BB; si = si + 1; // 1 field right PlayField16[si] = 0x2818; }
void subElectronTurnRight(int si, int bx) { int ax, bl; ax = (TimerVar & 3); if (ax != 0) { if (ax == 3) goto loc_g_7BA3; return; } // loc_g_7B73: // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawElectronTurnRight(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = ((bx + 1) & 0x7) | 8; MovHighByte(&PlayField16[si], bx); return; loc_g_7BA3: bl = HighByte(PlayField16[si]); if (bl == 0x8) goto loc_g_7BBC; if (bl == 0xA) goto loc_g_7C19; if (bl == 0xC) goto loc_g_7BFA; if (bl == 0xE) goto loc_g_7BDB; return; loc_g_7BBC: // pointing up ax = PlayField16[si - FieldWidth]; if (ax == 0) // above is empty -> go up goto loc_g_7BCB; if (LowByte(ax) == fiMurphy) // above is murphy -> explode ExplodeFieldSP(si); return; loc_g_7BCB: // above is empty -> go up PlayField16[si] = 0x1BB; si = si - FieldWidth; // 1 field up PlayField16[si] = 0x1018; return; loc_g_7BDB: // pointing left ax = PlayField16[si - 1]; if (ax == 0) // left is empty -> go there goto loc_g_7BEA; if (LowByte(ax) == fiMurphy) // left is murphy -> explode ExplodeFieldSP(si); return; loc_g_7BEA: // left is empty -> go there PlayField16[si] = 0x2BB; si = si - 1; // 1 field left PlayField16[si] = 0x1818; return; loc_g_7BFA: // pointing down ax = PlayField16[si + FieldWidth]; if (ax == 0) // below is empty -> go down goto loc_g_7C09; if (LowByte(ax) == fiMurphy) // below is murphy -> explode ExplodeFieldSP(si); return; loc_g_7C09: // below is empty -> go down PlayField16[si] = 0x3BB; si = si + FieldWidth; // 1 field down PlayField16[si] = 0x2018; return; loc_g_7C19: // pointing Right ax = PlayField16[si + 1]; if (ax == 0) // right is empty -> go there goto loc_g_7C2B; if (LowByte(ax) == fiMurphy) // right is murphy -> explode ExplodeFieldSP(si); return; loc_g_7C2B: // right is empty -> go there PlayField16[si] = 0x4BB; si = si + 1; // 1 field right PlayField16[si] = 0x2818; }
// TODO(bwd): Some asserts can move to lower level functions internal MIN_UNIT_TEST_FUNC(TestPaddingOracleDecrypt) { u32 InputStringIndex = rand() % ARRAY_LENGTH(InputStringArray); u32 InputStringLength = InputStringLengths[InputStringIndex]; u8 InputString[MAX_INPUT_PADDED_SIZE]; memcpy(InputString, InputStringArray[InputStringIndex], InputStringLength); u32 Key[AES_128_BLOCK_LENGTH_WORDS]; GenRandUnchecked(Key, ARRAY_LENGTH(Key)); u32 Iv[AES_128_BLOCK_LENGTH_WORDS]; GenRandUnchecked(Iv, ARRAY_LENGTH(Iv)); u8 Ciphertext[MAX_INPUT_PADDED_SIZE]; Stopif(sizeof(Ciphertext) < InputStringLength, "String too long for Ciphertext TestPaddingOracleDecrypt"); u32 PaddedLength = AesCbcEncrypt(Ciphertext, InputString, InputStringLength, (u8 *)Key, (u8 *)Iv); u32 InputStringLengthMod16 = (InputStringLength % AES_128_BLOCK_LENGTH_BYTES); Stopif((PaddedLength < InputStringLength) || ((InputStringLengthMod16 == 0) && (PaddedLength != (InputStringLength + AES_128_BLOCK_LENGTH_BYTES))) || ((InputStringLengthMod16 != 0) && (PaddedLength <= InputStringLength)) || ((PaddedLength % AES_128_BLOCK_LENGTH_BYTES) != 0), "Invalid PaddedLength from AesCbcEncrypt in TestPaddingOracleDecrypt"); u8 Plaintext[MAX_INPUT_PADDED_SIZE]; u8 DecryptScratchBuffer[AES_128_BLOCK_LENGTH_BYTES]; u8 GuessPrevCipherBlock[AES_128_BLOCK_LENGTH_BYTES]; for (u32 PaddedBlocksIndex = 0; PaddedBlocksIndex < (PaddedLength/AES_128_BLOCK_LENGTH_BYTES); ++PaddedBlocksIndex) { u32 BlockOffsetInBytes = AES_128_BLOCK_LENGTH_BYTES*PaddedBlocksIndex; for (i32 CurrentGuessIndex = (AES_128_BLOCK_LENGTH_BYTES - 1); CurrentGuessIndex >= 0; --CurrentGuessIndex) { if (PaddedBlocksIndex == 0) { memcpy(GuessPrevCipherBlock, Iv, AES_128_BLOCK_LENGTH_BYTES); } else { memcpy(GuessPrevCipherBlock, Ciphertext + AES_128_BLOCK_LENGTH_BYTES*(PaddedBlocksIndex - 1), AES_128_BLOCK_LENGTH_BYTES); } u32 CurrentPaddingByteCount = AES_128_BLOCK_LENGTH_BYTES - CurrentGuessIndex; for (u32 GuessPaddingByteIndex = CurrentGuessIndex + 1; GuessPaddingByteIndex < AES_128_BLOCK_LENGTH_BYTES; ++GuessPaddingByteIndex) { GuessPrevCipherBlock[GuessPaddingByteIndex] ^= ((Plaintext[BlockOffsetInBytes + GuessPaddingByteIndex]) ^ CurrentPaddingByteCount); } b32 ByteGuessed = false; u32 GuessByte; for (GuessByte = 0; GuessByte <= 0xFF; ++GuessByte) { u8 CurrentPaddingByte = LowByte(AES_128_BLOCK_LENGTH_BYTES - CurrentGuessIndex); u8 CurrentXorValue = LowByte(GuessByte) ^ CurrentPaddingByte; u8 *CurrentXorByte = ((u8 *)GuessPrevCipherBlock + CurrentGuessIndex); *CurrentXorByte ^= CurrentXorValue; // NOTE(bwd): server padding check AesCbcDecrypt(DecryptScratchBuffer, Ciphertext + BlockOffsetInBytes, sizeof(DecryptScratchBuffer), (u8 *)Key, (u8 *)GuessPrevCipherBlock); *CurrentXorByte ^= CurrentXorValue; u32 StrippedStringLength; u8 *StrippedString = StripPkcs7GetStrippedLength(DecryptScratchBuffer, &StrippedStringLength, AES_128_BLOCK_LENGTH_BYTES); if (StrippedString && (StrippedStringLength == (u32)CurrentGuessIndex)) { ByteGuessed = true; Plaintext[BlockOffsetInBytes + CurrentGuessIndex] = LowByte(GuessByte); break; } } Stopif(!ByteGuessed, "No guess byte found in TestPaddingOracleDecrypt"); } Stopif(memcmp(Plaintext + BlockOffsetInBytes, InputString + BlockOffsetInBytes, AES_128_BLOCK_LENGTH_BYTES) != 0, "Block %d not decrypted correctly", PaddedBlocksIndex); } MinUnitAssert(memcmp(Plaintext, InputString, InputStringLength) == 0, "Plaintext not recovered in TestPaddingOracleDecrypt"); }