Danke fürs Testen alter Mann.
Bei der Abfrage des Types muss ich natürlich die Position und Länge berücksichtigen, um den Typ zu bestimmen.
Hier die neue abgeänderte Version:
Code: Alles auswählen
Structure AllTypes
StructureUnion
b.b : w.w : l.l : q.q
EndStructureUnion
EndStructure
Procedure SetBit(*Buffer.AllTypes, Position.i, Value.i, Length.i=1)
If Position > 7
SetBit(*Buffer + Position/8, Position%8, Value, Length)
EndIf
Select Position+Length
Case 1 To 8
*Buffer\b = *Buffer\b & ~(($FF>>(8-Length))<<Position) | (Value<<Position)
Case 9 To 16
*Buffer\w = *Buffer\w & ~(($FFFF>>(16-Length))<<Position) | (Value<<Position)
Case 17 To 32
*Buffer\l = *Buffer\l & ~(($FFFFFFFF>>(32-Length))<<Position) | (Value<<Position)
Case 33 To 64
*Buffer\q = *Buffer\q & ~(($FFFFFFFFFFFFFFFF>>(64-Length))<<Position) | (Value<<Position)
EndSelect
EndProcedure
Procedure GetBit(*Buffer.AllTypes, Position.i, Length.i=1)
If Position > 7
ProcedureReturn GetBit(*Buffer + Position/8, Position%8, Length)
EndIf
Select Position+Length
Case 1 To 8
ProcedureReturn (*Buffer\b>>Position)&($FF>>(8-Length))
Case 9 To 16
ProcedureReturn (*Buffer\w>>Position)&($FFFF>>(16-Length))
Case 17 To 32
ProcedureReturn (*Buffer\l>>Position)&($FFFFFFFF>>(32-Length))
Case 33 To 64
ProcedureReturn (*Buffer\q>>Position)&($FFFFFFFFFFFFFFFF>>(64-Length))
Default
EndSelect
EndProcedure
Define Long.l = 0
SetBit(@Long, 7, %111111111, 9)
Debug RSet(Bin(Long), 32, "0")
Debug Bin(GetBit(@Long, 7, 9))
@Nic: Immer eine Quad zu schreiben ist schlecht, da ein Feld/Buffer ja u.U. auch kleiner sein kann, und dann kommt ein IMA.
Mit der neuen Version sollte es jetzt funktionieren, mit der Einschränkung, das ich auf einem 8-Teilerfremden Bit keine komplette Quad schreiben kann. Könnte man aber durchaus noch hinzufügen, als Case 65 To 72, und dort eine Quad und ein Byte manipulieren ...
Leider fällt mir gerade auf, dass das BitShift von PB probleme mit Sign-Quads hat:
Das Vorzeichen bleibt bestehen.
Ich werde heute Abend zuhause mal n ASM-Code dafür schreiben.