Here are 2 procedures to Peek/Poke single bits inside large memoryblocks.
Further there are 2 procedures to Peek/Poke the value of 1-31 Bits inside large memoryblocks.
This is useful for example to store a lot of LONG-values which do not exactly use all 32 Bits with only the needed bits per value.
Code: Select all
;- Froggerprogger 16.09.03
;-
;- This program gives you the Procedures PokeBit(), PeekBit(), PokeBits() and PeekBits()
;- Because of PB using signed variables, all bitfields are interpretated as signed values, too
;-
;- Announcements:
;- 1. Byteoffset + (Bitoffset/8) < 2147483647
;- (because sum is of type signed Long)
;-
;- 2. The resulting Bitposition is the sum of the Byteoffset (0-2147483647) and Bitoffset (0-2147483647)
;- Is the Byteoffset 0, the maximum direct adressable Bitposition is 2147483647 (Bitoffset of type signed Long),
;- and so these Bits lay in range of 0 to 2147483647 / 8 = 268435456 Bytes - 1 Bit
;-
;- Examples:
;- (Byteoffset ; Bitoffset) = (Byteoffset + 1*n ; Bitoffset - 8*n)
;-
;- (0 ; 32769) = (1 ; 32761) = (4096 ; 1) = (4097 ; -7) = ...
;- (0 ; 2147483640) = (268435455 ; 0) = ...
;- (0 ; 2147483647) = (268435455 ; 7) = ... + 1 Bit => (268435456 ; 0) = (1 ; 2147483640)
;-
;- PokeBit-parameter:
; *memory - pointer to preallocated memory
; Byteoffset - Byteoffset (0 - 2147483647)
; Bitoffset - Bitoffset (0 - 2147483647)
; value - the value to set (0 or 1)
Procedure PokeBit(*memory, Byteoffset.l, Bitoffset.l, value.l)
Protected PositionMod.l : PositionMod = Bitoffset - Bitoffset / 8 * 8 ; Modulo - don't use 64 instead of 8*8
Protected ByteAlignedPosition.l : ByteAlignedPosition = (Bitoffset - PositionMod)>>3 + Byteoffset
If value = 0
PokeB(*memory + ByteAlignedPosition, PeekB(*memory + ByteAlignedPosition) & ~(1 << PositionMod))
Else
PokeB(*memory + ByteAlignedPosition, PeekB(*memory + ByteAlignedPosition) | (1 << PositionMod))
EndIf
EndProcedure
;- PeekBit-parameter:
; *memory - pointer to preallocated memory
; Byteoffset - Byteoffset (0 - 2147483647)
; Bitoffset - Bitoffset (0 - 2147483647)
; Procedurereturn - LONG-value of the specified Bit (0 or 1)
Procedure.l PeekBit(*memory, Byteoffset.l, Bitoffset.l)
Protected result.l : result = 0
Protected PositionMod.l : PositionMod = Bitoffset - Bitoffset / 8 * 8 ; Modulo - don't use 64 instead of 8*8
Protected ByteAlignedPosition.l : ByteAlignedPosition = (Bitoffset - PositionMod)>>3 + Byteoffset
If PeekB(*memory + ByteAlignedPosition) >> PositionMod & 1
result = 1
EndIf
ProcedureReturn result
EndProcedure
;- PokeBits-parameter
; *memory - pointer to preallocated memory
; Byteoffset - Byteoffset (0 - 2147483647)
; Bitoffset - Bitoffset (0 - 2147483647)
; Length - number of Bits to write (1 to 32)
; value - value to write (-1*Pow(2,Length) < value < Pow(2, Length)-1) for correct results)
Procedure PokeBits(*memory, Byteoffset.l, Bitoffset.l, Length.l, value.l)
Protected i.l
If Bitoffset > 2147483615 : Byteoffset + 4 : Bitoffset - 32 : EndIf ; avoid Bitoffset-Overrun
For i=0 To Length - 1
PokeBit(*memory, Byteoffset, Bitoffset + i, 1 & value >> (Length - 1 - i))
Next
EndProcedure
;- PeekBits-parameter
; *memory - pointer to preallocated memory
; Byteoffset - Byteoffset (0 - 2147483647)
; Bitoffset - Bitoffset (0 - 2147483647)
; Length - number of Bits to write (1 to 32)
; Procedurereturn - LONG-value of the specified Bitfield
;- annotation
; PeekBits() for a one-bit-value returns 0 or 1, though 0 or -1 would be
; mathematically correct for a signed one-bit-value - but not as practical.
; [See the term If Length > 1 for this]
Procedure.l PeekBits(*memory, Byteoffset.l, Bitoffset.l, Length.l)
Protected i.l
Protected result.l
If Bitoffset > 2147483615 : Byteoffset + 4 : Bitoffset - 32 : EndIf ; avoid Bitoffset-Overrun
For i=0 To Length - 1
result + PeekBit(*memory, Byteoffset, Bitoffset + (Length - 1 - i)) << i
Next
If Length > 1 And result>>(Length-1) ; "if Length > 1 and it is a negative result in a 'Length'Bit-Bitfield"
result | $FFFFFFFF<<(Length-1) ; "fill all the Bits > Length with 1, so it is a negative result in the 32Bit-Bitfield, too."
EndIf
ProcedureReturn result
EndProcedure
;- an example
*mem = AllocateMemory(4096)
bits = 7
p=0
For i=2 To 62 Step 2
PokeBits(*mem, 3, p, bits, i)
p+bits
Next
p=0
For i=2 To 62 Step 2
Debug PeekBits(*mem, 3, p, bits)
p+bits
Next