Well, all SUBs and FUNCTIONs discussed so far are supposed for any special
case memory operations.  Now we still need a set of routines for the low
level access to the memory.  That is, accessing single bytes, words etc..
Here the various PokeXX and PeekXX routines come into place.  The "XX" in
the SUB/FUNCTION names are replaced by letters logically representing the
size/type of an access.  The routines defined so far are:

  Integers:
    PokeB   / PeekB%%  - byte access (8 bits)
    PokeW   / PeekW%   - word (in QB64 INTEGER) access (16 bits)
    PokeL   / PeekL&   - long access (32 bits)
    PokeLL  / PeekLL&& - long long (in QB64 _INTEGER64) access (64 bits)

  Floating points:
    PokeS   / PeekS!   - write/read single floating point (32 bits)
    PokeD   / PeekD#   - write/read double floating point (64 bits)

  Strings:
    PokeSTR / PeekSTR$ - write/read zero terminated strings

  The general syntax for all PokeXX SUBs and PeekXX FUNCTIONs is:

        PokeXX addr&, offs&, value
        value = PeekXX(addr&, offs&)

The addr& and offs& arguments are generally interchangeable, they are
simply added together internally to build the actual address to access.
I chose this way, so you can put the base address (eg. any structure)
into the addr& argument and the offset to access within that structure
to the offs& argument.  However, you can also add the addresses and
offsets yourself and put it in either addr& or offs& and set the unused
argument to zero.  Simply find the most convenient way for you.

Note that the integer PokeXX routines can take either signed or unsigned
values, but the respective PeekXX functions will always return signed
values.  However, if the result is assigned to a unsigned integer variable,
then the value is automatically converted to unsigned again.  If needed
within a temporary operation, then you may use a logic AND operation of
the appropriate size to convert the value.  See example:

    'CHR$ accepts positive values only, so if in doubt what is returned
    'by PeekB%%, then make the result unsigned for CHR$ to avoid errors
    PRINT CHR$(PeekB%%(addr&, offs&) AND &HFF~%%)

Something special you need to keep in mind using PokeSTR is, that this SUB does automatically add the zero termination byte after the actual string. That is, you don't need to add CHR$(0) to any of your strings, but on the other hand it will be required to allocate buffers with LEN(string) + 1, or the adding of the zero byte would violate innocent memory following the buffer. If you define embedded strings within a structure using the SUB DefSTRING from the types.bm include file, then this SUB already takes care of adding 1 for the termination byte, also the FUNCTION CreateGPMString& discussed earlier will take care of allocating a big enough buffer. You just need to remember the +1 rule, if you for any reason allocate a buffer by yourself. On the other hand PeekSTR$ will always return the string without the zero termination byte, hence you get it back as you did poke it in. So in fact you can also poke and peek back empty ("") strings. Back to GPM Functions