Ah klar, dass ist das angesprochene Problem, wenn ich $FFFF.FFFF shifte, dann bleibt das Vorzeichen "leider" erhalten.
Somit ist $FFFF.FFFF >> 16 zB nicht $0000.FFFF sondern leider immer noch $FFFF.FFFF
Das PeekL() bei $FF00.0000 im Bin viele 1 davor hat, liegt auch daran, dass versucht wird, das Vorzeichen zu erhalten.
Hier die neue Version, die das Problem behebt:
Code: Alles auswählen
Structure AllTypes
StructureUnion
b.b : w.w : l.l : q.q
EndStructureUnion
EndStructure
Procedure SetBit(*Buffer.AllTypes, Position.i, Value.q, Length.i=1)
Protected Mask.q
If Position > 7
SetBit(*Buffer + Position/8, Position%8, Value, Length)
Else
If Length = 64
Mask = $0000000000000000
Else
Mask = ~(($7FFFFFFFFFFFFFFF>>(63-Length))<<Position)
EndIf
Select Position+Length
Case 1 To 8
*Buffer\b = *Buffer\b & Mask | (Value<<Position)
Case 9 To 16
*Buffer\w = *Buffer\w & Mask | (Value<<Position)
Case 17 To 32
*Buffer\l = *Buffer\l & Mask | (Value<<Position)
Case 33 To 64
*Buffer\q = *Buffer\q & Mask | (Value<<Position)
EndSelect
EndIf
EndProcedure
Procedure.q GetBit(*Buffer.AllTypes, Position.i, Length.i=1)
Protected Mask.q
If Position > 7
ProcedureReturn GetBit(*Buffer + Position/8, Position%8, Length)
EndIf
If Length = 64
Mask = $FFFFFFFFFFFFFFFF
Else
Mask = $7FFFFFFFFFFFFFFF>>(63-Length)
EndIf
Select Position+Length
Case 1 To 8
ProcedureReturn (*Buffer\b>>Position)&Mask
Case 9 To 16
ProcedureReturn (*Buffer\w>>Position)&Mask
Case 17 To 32
ProcedureReturn (*Buffer\l>>Position)&Mask
Case 33 To 64
ProcedureReturn (*Buffer\q>>Position)&Mask
Default
EndSelect
EndProcedure
Procedure.s out(*mem,l)
str$=""
For i = 0 To l-1
str$ + RSet(Bin(PeekB(*mem+i), #PB_Byte),8,"0") + " "
Next
ProcedureReturn str$
EndProcedure
DataSection
test:
Data.b $00,$00$,$00,$FF,$00,$00,$00,$00
EndDataSection
*test = AllocateMemory(8)
CopyMemory(?test,*test,8)
Debug out (*test,4)
SetBit(*test, 28, 0)
Debug out (*test,4)
Debug "---"
CopyMemory(?test,*test,8)
Debug out (*test,8)
Debug RSet(Bin(PeekL(*test) ),64,"0")
SetBit(*test, 28,0,1)
Debug out (*test,8)
Debug RSet(Bin(PeekL(*test) ),64,"0")
FreeMemory(*test)
Du hattest allerdings auch ein Fehler in out(), bei Bin(PeekB()) musst du ,#PB_Byte mit angeben, sonst haut dir Bin auch 64-8 Einsen davor.