Log In  

At the moment, we have 6 native functions to peek and poke the memory :
v=peek(addr, [n] ) you also have v=@addr that is equivalent to peek(addr,1) and peek(addr)
v=peek2(addr, [n] ) and v=%addr
v=peek4(addr, [n] ) and v=$addr
poke ( addr, [value,] [...] )
poke2( addr, [value,] [...] )
poke4( addr, [value,] [...] )

What could be a good extension of this ? The problem is not really the coding part, but rather coming up with conventions that fit well withing the pico8 universe...

poke3 seems like a simple addition, but what three bytes should be copied from the value ?

Pico8 is a little endian universe

XXXX  read from value
..... ignored

       [ pico8 numeric value ]
       [fraction ] [integer  ]
       Byte0 Byte1 Byte2 Byte3
poke   ..... ..... XXXXX ..... 
poke2  ..... ..... XXXXX XXXXX
poke3  ????? XXXXX XXXXX ?????
poke4  XXXXX XXXXX XXXXX XXXXX

Since our standard pico8 numbers are 16.16 bits, we can't go further, poke5 wouldn't make sense.
What we could do is going in the other direction with powers of 2, poke_nibble(), poke_half_nibble() and poke_bit()
That's a whole new can of worm : what is the first bit of a byte ?
To me (It's a convention, feel free to disagree and argue) it makes sense that bits are ordered from least significant to most significant in a byte, in similar little endian spirit than the rest.
Each bit in memory would have an address : bit 0 would have the same address as the byte containing it, bit 1 would have 1/8 more that the previous bit, bit 7 would have 7/8 more.
This fits nicely with how the screen is memory mapped :
pixel_address=0x6000+(128*y+x)/2
second pixel of the 1st screen row would have address 0x6000.8

Here's what I propose :

peekn(byte_size,fractional_address, [n])
poken(byte_size,fractional_address,[value,] [...] )

Example uses :
bs=1/8 -- bit size in bytes, or 0.125 in decimal  0x0.2 in hexa

poken(4*bs,0x6000+(128*y+x)/2,color) -- same effect as pset(x,y,color) minus pal shenanigans 
poken(bs,0x5e00+idx*bs,1) -- treats cartdata spaces as 2048 flags and sets flag idx to 1
peekn(1,addr) -- equivalent to peek(addr) if addr is an integer
peekn(2,addr) -- equivalent to peek2(addr) if addr is an integer
peekn(4,addr) -- equivalent to peek4(addr) if addr is an integer

Only the integer part and the three most significant bits for the fractional part of an address would be taken into account.
For the value, for byte_size between 1/8 and 2, only the least significant bits of the integer part would be taken into account, to stay in line with peek and peek2.
From 17*bs to 4, the most significant bits would count.
That would make poken(3,addr,value) write byte1, byte2 and byte3 from value to addr, addr+1 and addr+2.

Or we could drop compatibility with poke and have a more coherent scheme. I don't like the drawbacks of either solution... What would you wish for ?

P#138674 2023-12-14 13:57 ( Edited 2023-12-14 13:58)

Newbie question here, but what is the difference between using poke and memset?

P#138688 2023-12-14 17:04

@kozm0naut With poke you give all the values you want to write to memory. Memset writes a single value multiple times.

P#138713 2023-12-15 00:43 ( Edited 2023-12-15 00:44)

[Please log in to post a comment]