Memory

TODO: Very quickly edited down from the PICO-8 version just to give a starting place. This is FULL of stale misinfo! Please edit and fix!

Picotron has 16 MiB of addressable memory, used for graphics, map, sound, music, and direct access to hardware features. Programs can read from and write to this memory using `peek()` and `poke()`.

While many games can use the built-in functions for graphics and sound, memory access enables advanced techniques such as repurposing memory regions or generating graphics and sound data algorithmically. For some features, `peek()` and `poke()` may be the only way to access them.

The Lua program stack (variables, etc.) is not stored in addressable memory and cannot be accessed directly by the program unless it is userdata that has been mapped to memory with `memmap()`.

See also P64FileFormat, P64PNGFileFormat.

## Memory map

This is the high-level memory map for addressable memory:

The in-memory data formats for each section are described below.

## Sprites and sprite sheets

Unlike PICO-8, sprites and sprite sheets are not in fixed locations. They are created with the `userdata()` function and then optionally mapped to memory with the `memmap()` function, but are typically given to the GPU via their userdata reference.

TODO: determine the actual sprite format vs. the 4-bit PICO-8 format we can paste into Picotron with [gfx] tags.

## Map

TODO: not sure if maps are a native userdata type or if we just have to have 2D arrays of sprite indices which we use to reference tables of sprite userdata.

## Music

TODO: There is currently no audio and no info about music formats

## Sound effects

TODO: There is currently no audio and no info about sfx formats.

## General use

TODO: Most addressable memory is considered general-use, and is backed by userdata assigned to the memory addressed via `memmap()`. It's unclear right now whether there is any pre-assigned general-use memory.

## Persistent cart data

TODO: There is no information about persistent cart data available

## Draw state

This memory region represents the current draw state. The values are as follows:

**0x5f00..0x5f0f / 24320..24335**

Draw palette look-up table (`pal()`, `palt()`). When PICO-8 is asked to draw a certain 4-bit color index, it looks up the color's index in this table to decide which 4-bit color index it should be remapped with to eventually be written to screen memory. The 16 values in this table should have their lower nibble (bits 0-3) set to 0-15, to indicate which index is actually written to screen memory, while their upper nibble (bits 4-7) should be either zero for normal operation, or non-zero (i.e. the byte value is from 16 to 255) if the color index is to be transparent.
**0x5f10..0x5f1f / 24336..24351**

Screen palette look-up table (`pal(...,1)`). PICO-8 reads this table while converting the color indices in screen memory into system ("hardware") colors to be shown on its display. As of this writing, there are *officially* only 16 system colors available, whose values range from 0 to 15. However, an additional, but undocumented, 16 colors appear to be available at values from 128 to 143, and zep appears to be fine with us knowing this. Bits 4-6 (values 16, 32, 64) appear to be ignored.
**0x5f20..0x5f23 / 24352..24355**

Clipping rectangle (`clip()`):
* 0x5f20 / 24352: **x\_begin** (no pixels < **x\_begin** will be drawn)
* 0x5f21 / 24353: **y\_begin** (no pixels < **y\_begin** will be drawn)
* 0x5f22 / 24354: **x\_end** (no pixels >= **x\_end** will be drawn)
* 0x5f23 / 24355: **y\_end** (no pixels >= **y\_end** will be drawn)

If **x\_end** is less than or equal to **x\_begin**, or **y\_end** is less than or equal to **y\_begin**, then no visible clipping area is formed, effectively blocking rendering.
These are somewhat different from the `clip(x,y,w,h)` arguments. Use `clip(xb,yb,xe-xb,ye-yb)` to set a clip rectangle using values like these, or starting with 0.2.2, `poke(0x5f20,xb,yb,xe,ye)` to save tokens.
Note: `clip()` clamps the rectangle to the edges of the display. Expect the `xb,yb,xe,ye` values to be in the range 0..128, inclusive.
**0x5f24 / 24356**

(0.2.3+) After a call to `print()` without coordinate parameters, the print cursor X position (0x5f26) will be set to this value as the newline is appended. This is set by `cursor()` or `print()` with coordinate parameters to ensure intended newline behavior.
**0x5f25 / 24357**

Pen color (`color()`). The bottom 4 bits (0-3) are the current color index, from 0-15. The top 4 bits (4-7) are typically unused, but when using fill patterns, they're the secondary color index.
**0x5f26..0x5f27 / 24358..24359**

Print cursor (`cursor()`). 0x5f26=X, 0x5f27=Y.
**0x5f28..0x5f2b / 24360..24363**

Camera position (`camera()`). The X and Y offsets are stored as 16-bit signed integers with the least significant byte first. 0x5f28..0x5f29=X offset, 0x5f2a..0x5f2b=Y offset.
**0x5f2c / 24364**

This value sets the screen transformation mode to be a variation of stretching, mirroring, flipping, or rotating. This can't be changed in-between draw calls; it affects the entire screen.
* 0 = normal mode
* 1 = horizontal stretch, 64x128 screen, left half of normal screen
* 2 = vertical stretch, 128x64 screen, top half of normal screen
* 3 = both stretch, 64x64 screen, top left quarter of normal screen
* 5 = horizontal mirroring, left half copied and flipped to right half
* 6 = vertical mirroring, top half copied and flipped to bottom half
* 7 = both mirroring, top left quarter copied and flipped to other quarters

The following modes have been added as of 0.2.0:
* 129 = horizontal flip
* 130 = vertical flip
* 131 = both flip
* 133 = clockwise 90 degree rotation
* 134 = 180 degree rotation (effectively equivalent to 131)
* 135 = counterclockwise 90 degree rotation

Bit 6 (value 64) appears to be ignored.
**0x5f2d / 24365**

Controls devkit mode, a feature allowing mouse and keyboard status to be checked via the `stat()` command. From the manual:

```
poke(0x5f2d, flags)  -- where flags are:

		0x1 Enable
		0x2 Mouse buttons trigger btn(4)..btn(6)
		0x4 Pointer lock (use stat 38..39 to read movements)

```

**0x5f2e / 24366**

If bit 0 (value 1) is set, causes the current palette scheme (see `pal()` and/or the 0x5f00..0x5f1f memory range, above) to persist instead of being reset at the end of the program.
If bit 1 (value 2) is set, causes the high-color mode configuration at 0x5f5f..0x5f7f to persist.
If bit 2 (value 4) is set, causes the audio effect switches at 0x5f40..0x5f43 to persist.
If bit 3 (value 8) is set, causes the read/write masks at 0x5f5e to persist.
If bit 4 (value 16) is set, causes the default print attributes at 0x5f58..0x5f5b to persist.
If bit 5 (value 32) is set, causes the fill pattern information at 0x5f31..0x5f33 to persist.
*(Other values are unverified in limited testing.)*
**0x5f2f / 24367**

(undocumented) If set to 1, the PICO-8 audio engine will be paused until it is set to 0 again. If set to 2, the audio will still run when the pause menu is being displayed.
**0x5f30 / 24368**

(undocumented) If set to 1, suppresses the *next* attempt to bring up the pause menu. This can be done as late as discovering the pause button has been pressed this frame:

```
  if(btn(6)) poke(0x5f30,1)

```

**0x5f31..0x5f33 / 24369..24371**

Fill pattern (`fillp()`). 0x5f31..0x5f32 contain the 16-bit fill pattern with the least-significant byte stored first.
0x5f33 contains the attribute flags for the fill pattern. Bit 0 (value 1) enables transparency, bit 1 (value 2) enables fill patterns for sprites, and bit 2 (value 4) enables other drawing functions that accept fill patterns to use the sprite fill pattern mechanism.
**0x5f34 / 24372**

If set to 1, changes the PICO-8 drawing API to accept color values that incorporate not just one or two colors, but optionally include information about the fill pattern right in the color value. From the manual:

```
-- bit  0x1000.0000 means the non-colour bits should be observed
-- bit  0x0700.0000 0x1 transparency, 0x2 apply to sprites, 0x4 apply secondary palette
-- bits 0x00FF.0000 are the usual colour bits
-- bits 0x0000.FFFF are interpreted as the fill pattern

```

**0x5f35 / 24373**

Invalidates the endpoint of the previous line drawn using `line()`, found within 0x5f3c..0x5f3f. When 0, the endpoint is valid. When 1, it's invalid, as if `line()` had been called with no arguments.

**0x5f36 / 24374**

Miscellaneous PICO-8 chipset features:
* If bit 0 (value 1) is set, the undocumented multi-screen feature is enabled.

* If bit 2 (value 4) is set, automatic newlines are no longer added after each call to `print()`. Also, due to a bug with PICO-8 printing escape codes, '\1' through '\6' will become printable if they are at the end of the string, but this should not be relied upon.

* If bit 3 (value 8) is set, causes sprite 0 in `map()` and `tline()` to be rendered as opaque (like other sprites) instead of the usual transparent.

* If bit 4 (value 16) is set, 0x5f59..0x5f5b will be interpreted as default values for sget, mget, and pget.

* If bit 5 (value 32) is set, the dampen filter used for the undocumented PCM audio channel (`serial(0x808,...)`) is disabled.

* If bit 6 (value 64) is set, automatic screen scrolling for `print()` without coordinate parameters is disabled.
* If bit 7 (value 128) is set, automatic character wrap for print() is enabled.

**0x5f37 / 24375**

If set to 1, PICO-8 will not call `reload()` to copy cart ROM to RAM addresses 0x0000..0x42ff whenever exiting any editor mode. Normally this is done to update the expected copy of cart ROM in PICO-8 RAM. However, some carts make dynamic changes to this RAM at runtime, and this can be used to ensure those changes are preserved even if the cart is stopped and an editor is used before resuming. Note that `reload()` may still be used to copy ROM to RAM manually if necessary.
**0x5f38...0x5f39 / 24376..24377**

The width and height of the map area to sample with `tline()`. Coordinates will be calculated modulo these numbers to produce texture wrapping. These normally should be a power of 2 to work as expected, but PICO-8 actually subtracts 1 from these before performing a bitwise AND on the offset into the map.
**0x5f3a..0x5f3b / 24378..24379**

The X and Y offsets of the map area to sample with `tline()`. These are expressed in map tiles. These are applied after the texture wrapping.
**0x5f3c..0x5f3f / 24380..24383**

Endpoint of the previous line drawn using `line()`. The X and Y coordinates are stored as 16-bit signed integers with the least significant byte first. These are only used if the byte at 0x5f35 is 0.
`0x5f3c..0x5f3d` / `24380..24381`: X coordinate
`0x5f3e..0x5f3f` / `24382..24383`: Y coordinate
## Hardware state

These memory addresses represent or control various aspects of the hardware.

**0x5f40..0x5f43** control various audio effects for individual PICO-8 audio channels. These 4 bytes are in control of 2 audio effects each, for a total of 8 effects.

Setting bit 0 (value 1) enables a "low" effect for channel 0, bit 1 (value 2) for channel 1, etc.

Similarly, bit 4 (value 16) enables a "high" effect for channel 0, bit 5 (value 32) for channel 1, etc.

**0x5f40 / 24384**

Low: Halves a channel's clock rate. The main sampling rate in PICO-8 is 22.05 KHz, and enabling the feature for a channel will cause it to be *approximately* 11.025 KHz instead. This affects *all* timings in the channel, such that the note pitch is effectively made an octave lower.
High: Halves a channel's pitch. PICO-8 essentially just subtracts 12 from the note values played on the channel.
**0x5f41 / 24385**

Low: Force-enables REVERB-2 for a channel. This has priority over high.
High: Enables REVERB-1 for a channel, unless REVERB-2 is enabled in its actively-playing SFX/pattern.
**0x5f42 / 24386**

Low: Bitcrushes the output of a channel (limits the set of amplitude levels the channel can output). This has priority over high.
High: Distorts the output of a channel (with bitcrushing applied).
**0x5f43 / 24387**

Low: Force-enables DAMPEN-2 for a channel.
High: Enables DAMPEN-1 for a channel, unless DAMPEN-2 is enabled in its actively-playing SFX/pattern.
Low + High: Force-enables an even stronger dampen level.
With each channel, reverb is processed first, then bitcrush/distortion, and finally dampen.
*Note: Each channel is essentially their own box, isolated from each other, which (alongside the undocumented PCM channel) only have their outputs mixed together by PICO-8. As a result, the effect "modules" are per-channel (e.g. each channel has its own reverb buffer).*
**0x5f44..0x5f4b / 24388..24395**

These 8 bytes mirror the internal state of the pseudo-random number generator that `rnd()` uses to create random values. This memory range can be saved before calling `srand()` and `rnd()` and then restored to continue the original stream of random numbers. This can be useful for games which need separate random number streams so that one may be deterministic over time while another can be used arbitrarily. It is strongly suggested that this state only be saved and restored, but not created. Use `srand()` to create a good, stable randomizer state.
Every time `rnd()` is called, the RNG state is updated as follows:
1. The 16-bit words at 0x5f44 and 0x5f46 are swapped.
2. The 32-bit word at 0x5f48 is added to the 32-bit word at 0x5f44.
3. The 32-bit word at 0x5f44 is added to the 32-bit word at 0x5f48. Both add operations are performed with little-endian values (i.e. the least-significant byte comes first).

**0x5f4c..0x5f53 / 24396..24403**

These 8 bytes contain the current button states for the 8 players. 0x5f4c contains the button state for player 0, 0x5f4d for player 1, and so on up to player 7.
Each byte is a bitmask arranged like the output of `btn()` when called without arguments. Particularly, 0x5f4c is `btn() & 0x3f` and 0x5f4d is `(btn() >> 8) & 0x3f`. Note that PICO-8 doesn't modify bit 6 (value 64) or 7 (value 128) of these bytes, so the state of the pause button can't be read from here. *(It would be more normal for the bits to be cleared, suggesting that they may have correspondence with undocumented functionality. Please update this if you know their significance.)*
**0x5f54 / 24404**

(0.2.4+) Controls the mapping of the sprite sheet, enabling the screen data to be used as the sheet to allow for certain special effects. The legal values are **0x00** for the 0x0000..0x1fff region, and **0x60** for the 0x6000..0x7fff region. Any other value is not officially supported; it will just be treated like 0x00.
**0x5f55 / 24405**

(0.2.4+) Controls the mapping of the screen data, enabling the sprite sheet to be used as a drawing target (similar to render-to-texture). The legal values are **0x60** for the 0x6000..0x7fff region, and **0x00** for the 0x0000..0x1fff region. Any other value is not officially supported; it will just be treated like 0x60.
For more info about these locations, see the release notes on when this was introduced: https://www.lexaloffle.com/bbs/?tid=45538
**0x5f56 / 24406**

(0.2.4+) Controls which map in memory should be used. The legal values are **0x20** for the standard map region, and any value from **0x80** to **0xff** for the extended map, where the value itself is the upper 8 bits of the base address. The lower 8 bits are fixed to 0, so the extended map can only start on a 256-byte boundary. Any other value is not officially supported; it will just be treated like 0x20.
**0x5f57 / 24407**

(0.2.4+) Controls the width of the map, in cells. The default value is 128, and can be set to 0 to make the map 256 cells wide. The height of the map is influenced by how many bytes in memory it occupies.
Note that these locations do not influence the built-in map editor - it always works with the data at 0x2000. They will only affect the map functions `mget()`, `mset()`, `map()`, and `tline()`. For more info, see the release notes: https://www.lexaloffle.com/bbs/?tid=45538
**0x5f58..0x5f5b / 24408..24411**

(0.2.2+) Default attributes for `print()`. From the manual:

```
Although attributes are reset every time print() is called, it is possible to set their default
values by writing to memory addresses 0x5f58..0x5f5b.

0x5f58 // bitfield
	0x1  when set to 0x1, bits 1..7 are observed:
	0x2  padding
	0x4  wide
	0x8  tall
	0x10 solid background
	0x20 invert
	0x40 dotty
	0x80 use custom font

0x5f59 char_w   (low nibble), char_h   (high)
0x5f5a char_w2  (low nibble), tab_w    (high)
0x5f5b offset_x (low nibble), offset_y (high)

// any nibbles equal to 0 are ignored
// tab_w values are mapped to 4..64

```

However, if `poke(0x5f36,0x10)` has been called, 0x5f59..0x5f5b are instead interpreted as default values for out-of-bounds calls for the following functions:
* 0x5f59: sget
* 0x5f5a: mget
* 0x5f5b: pget

**0x5f5c / 24412**

Auto-repeat delay for `btnp()`: When a button is held down, this controls the delay between the initial signal and the first auto-repeat signal. Expressed in 30ths of a second. The default value is 0, which tells PICO-8 to use the system delay setting. A value of 255 (or -1) disables the button repeat feature.
**0x5f5d / 24413**

Auto-repeat interval for `btnp()`: When a button is held down, this controls the intervals between auto-repeat signals. Expressed in 30ths of a second. The default value is 0, which tells PICO-8 to use the system delay setting.
**0x5f5e / 24414**

Allows PICO-8 to mask out certain bits of the input source color of drawing operations, and to write to specific bitplanes in the screen (there's 4 of them since PICO-8 uses a 4BPP display). Bits 0..3 indicate which bitplanes should be set to the new color value, while bits 4..7 indicate which input color bits to keep.
For example, `poke(0x5f5e, 0b00110111)` will cause drawing operations to write to bitplanes 0, 1, and 2 only, with 0 and 1 receiving the color value bits, 2 being cleared, and 3 being unaltered.
This formula is applied for every pixel written:
`dst_color = (dst_color & ~write_mask) | (src_color & write_mask & read_mask)`
**0x5f5f / 24415**

(Undocumented) Specifies a high-color mode (modes that allow for more than 16 colors on-screen on any given frame). Enables per-line palette swapping if set to 0x10, a 5-bitplane resolution-sacrificing screen if set to 0x20 (also requires 0x5f2c to be set to 1), or the usage of line-specific colors if set to 0x3*n* (the *n* digit specifies the primary screen color to replace with horizontal bars of up to 16 colors). Other values are unknown, and PICO-8 appears to just operate in regular 16-color mode. None of these modes allow for any arbitrary 128x128 5BPP image to be displayed.
See Bonevolt's BBS post for more in-depth information and examples.
**0x5f60..0x5f6f / 24416..24431**

(0.2.2+) 16-entry look-up table used for sprite fill patterns (`pal(...,2)`). Once the draw palette remapping is computed as normal, a byte is taken from this LUT. The lower nibble specifies the color for the "0" bits in the fill pattern, and the upper nibble for the "1" bits, just like with the pen colors at 0x5f25. This value is then AND'ed with the read-mask at 0x5f5e as usual.
(Undocumented) This is also a look-up table for the secondary display palette (modes 0x10 and 0x20) and the colors that make up mode 0x3n (the first color is for the top-most 128×8 section, the second for the 128×8 section underneath, etc.). The format of this section is identical to the screen palette in the **Draw State** section (see above).
Since this region is used for two independent features, the programmer must decide whether the sprite fill-pattern rendering or the selection of high-color modes is applicable.
**0x5f70..0x5f7f / 24432..24447**

(Undocumented) A 1x128 bitfield that specifies which screen lines should use the secondary screen palette instead of the primary one in mode 0x10. Mode 0x20 instead swaps palettes on a pixel-by-pixel basis if a pixel in the hidden 64x128 half of the screen is not zero, thus, this section has an unknown or undefined purpose in that mode.
If mode 0x3n is used, these specify a +1 offset for the indexed secondary palette color on the given line (e.g. line 60 uses color 60 \ 8 = 7, setting the bit will cause it to be 8) with color 15 wrapping around to 0.
Each of these 16 bytes are for each 8-line section of the screen. Bit 0 contains the section's top-most line, while bit 7 contains its bottom-most line.
Note that the affected sections aren't limited to horizontal rows. The current screen transformation selected in **0x5f2c** happens after the high-color effect 0x10 or 0x3n takes place. If rotation modes 133 or 135 are used, this can allow those effects to be applied in vertical columns instead. Mode 0x20 requires the screen transformation mode to be 1, other modes such as 2 or 3 don't seem to be supported.
## GPIO pins

TODO: Will Picotron even have GPIO?

This experimental feature provides programs access to the GPIO (general purpose input/output) hardware pins of a Raspberry Pi or CHIP device. These addresses can be used to accept digital input from or write digital output to devices connected to the pins. JavaScript code that runs in a browser can also access them by defining a global array named *pico8\_gpio*. There are up to 128 pins, depending on the platform.

**0x5f80..0x5fff / 24448..24575**

Each byte represents the value of one pin. The possible values vary depending on the platform.
## Video memory

TODO: I only changed the address and the size here. Everything else is obsolete PICO-8 info. Fix it!

This 128 KiB region contains the graphics buffer. This is what is modified by the built-in drawing functions, and is what is copied to the actual display at the end of the game loop or by a call to `flip()`.

**0x10000..0x2ffff / 65536..196607**

All 270 rows of the screen, top to bottom. Each row contains 480 pixels in 480 bytes. Each byte contains one pixel, with the bottom 6 bits being the palette color index and the top two being (TODO: stencil?) bits.
If you have 8-bit sprites elsewhere in memory, you can use `memcpy()` as an alternative way to display them on the screen without using `spr()`.
## Lua Memory

The memory used by Lua (global variables, local variables, tables, etc.) is separate from the PICO-8 memory discussed above and is limited to 16 MiB. Regular Lua data cannot be accessed via the memory map, but Lua userdata can be mapped into Picotron memory with the `memmap()` function.

TODO: I didn't even look at the rest of this, someone needs to check it to see if it's still accurate:

The amount of memory currently used by the program can be checked with `stat(0)` and adds up as follows (all numbers are in bytes):

* **nil / boolean / number** - no extra cost.
* **string** - 17 + 1 \* (# of characters)

Strings of length <= 40 are always interned, meaning creating such a string again (through any means) will simply use the previously created string and cost nothing.

On the other hand, interned strings are also stored in a global hash table, which grows whenever the number of interned strings reaches a new power of 2. Here, each interned string costs an additional ~4-8 bytes, though this cost is only observable - in bulk - whenever the hash table grows.

* **table** - 32 + 8 \* nextpow2(# of 'array' entries) + 20 \* nextpow2(# of 'hash' entries)

Here, nextpow2 gives the next power of 2 (e.g. 2 -> 2, 3 -> 4, 4 -> 4, 5 -> 8, 130 -> 256).

For example, {1,2,a=3,b=4,c=5} takes 128 bytes: 32 + 8 \* 2 + 20 \* 4

* **function** - 16 + 4 \* (# of captured variables) + 32 \* (# of newly captured variables)

A captured variable is any local variable declared outside the function, that's accessed inside the function.

A "newly" captured variable is merely one that wasn't captured before by other functions.

A function that uses any globals automatically captures \_ENV, and this counts as a captured variable. (Unless \_ENV is explicitly re-declared, it never counts as a newly captured variable, though.)

If a function is created multiple times, the previously created instance is reused if possible, thus costing nothing. The previous instance can be reused if it has no captured variables, or if it has captured variables but they're all the same variables as the captured variables of the new function.

* **thread** (created by cocreate) - 352 bytes.