|
Prev: (Advanced) CopyBits routine.
Next: (Advanced) CopyBits routine (Skybuck Entry 1, fixed, it was little endian display issue, now display in Big Endian)
From: Skybuck Flying on 3 Jan 2008 08:35 Skybuck's Entry 1 Most code copied and pasted from other projects. CopyBits implementation pretty lazy and straight forward, bit by bit copy. However there seems to be a bug somewhere ? That's unexpected. ( See undesired output below ) Here is the code: // *** Begin of Code *** program Project1; {$APPTYPE CONSOLE} { Skybuck's (Advanced) CopyBits Entry 1 Version 0.01 created on 3 january 2008 by Skybuck Flying. Code copy & pasted from other projects, main code is new as well as CopyBits routine Something strange is going on according to the main code/demonstration code. Bits are copied weird. Don't know yet what is going on. Could be a pretty serious (dumb ?) bug somewhere ;) Amazing and strange... } uses SysUtils; procedure SetBit( BaseAddress : pointer; BitIndex : longword ); asm bts [eax], edx end; procedure ClearBit( BaseAddress : pointer; BitIndex : longword ); asm btr [eax], edx end; function GetBit( BaseAddress : pointer; BitIndex : longword ) : boolean; asm mov result, false bt [eax], edx jnc @exit mov result, true @exit: end; // make overloaded versions for easy coding procedure WriteBitPattern( const ParaByte : byte ); overload; type TbitRange = 0..7; TbitSet = set of TbitRange; var vBit : TbitRange; begin for vBit:= 7 downto 0 do begin if vBit in TbitSet(ParaByte) then begin write('1'); end else begin write('0'); end; end; end; procedure WriteBitPattern( const ParaWord : word ); overload; type TbitRange = 0..15; TbitSet = set of TbitRange; var vBit : TbitRange; begin for vBit:= 15 downto 0 do begin if vBit in TbitSet(ParaWord) then begin write('1'); end else begin write('0'); end; end; end; procedure WriteBitPattern( const ParaLongWord : longword ); overload; type TbitRange = 0..31; TbitSet = set of TbitRange; var vBit : TbitRange; begin for vBit:= 31 downto 0 do begin if vBit in TbitSet(ParaLongWord) then begin write('1'); end else begin write('0'); end; end; end; procedure CopyBits( SourceBase : pointer; SourcePosition : integer; DestBase : pointer; DestPosition : integer; BitsToCopy : integer ); var vLoop : integer; begin for vLoop := 0 to BitsToCopy-1 do begin if GetBit( SourceBase, SourcePosition ) then begin SetBit(DestBase, DestPosition); end else begin ClearBit(DestBase, DestPosition); end; SourcePosition := SourcePosition + 1; DestPosition := DestPosition + 1; end; end; procedure Main; var InputArray : array of byte; OutputArray : array of byte; vIndex : integer; begin writeln('program started'); SetLength( InputArray, 10 ); SetLength( OutputArray, 10 ); InputArray[0] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[1] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[2] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[3] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[4] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[5] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[6] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[7] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[8] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; InputArray[9] := 0 + 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; FillChar( OutputArray[0], 10, 0 + 1 + 4 + 16 + 64 ); // FillChar( pointer(@OutputArray[0])^, 10, 0 ); writeln('InputArray before copybits: '); for vIndex := 0 to 9 do begin WriteBitPattern( InputArray[vIndex] ); end; writeln; writeln('OutputArray before copybits: '); for vIndex := 0 to 9 do begin WriteBitPattern( OutputArray[vIndex] ); end; writeln; CopyBits( @InputArray[0], 55, @OutputArray[0], 66, 10 ); writeln('InputArray after copybits: '); for vIndex := 0 to 9 do begin WriteBitPattern( InputArray[vIndex] ); end; writeln; writeln('OutputArray after copybits: '); for vIndex := 0 to 9 do begin WriteBitPattern( OutputArray[vIndex] ); end; writeln; OutputArray := nil; InputArray := nil; writeln('program finished'); end; begin try Main; { TODO -oUser -cConsole Main : Insert code here } except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; writeln('press enter to exit'); readln; end. { Undesired output: program started InputArray before copybits: 11111111111111111111111111111111111111111111111111111111111111111111111111111111 OutputArray before copybits: 01010101010101010101010101010101010101010101010101010101010101010101010101010101 InputArray after copybits: 11111111111111111111111111111111111111111111111111111111111111111111111111111111 OutputArray after copybits: 01010101010101010101010101010101010101010101010101010101010101011111110101011111 ^ ? ^ ? program finished press enter to exit } // *** End of Code *** Bye, Skybuck.
From: Skybuck Flying on 3 Jan 2008 08:36
Oh I see it's probably because of little endian/big endien thingy. Gotta investigate how to display it properly (?) ;) Bye, Skybuck. |