TABLEs and Dynamic Memory?

I was working on a cupboard that opens and closes automatically, with two tables: One that tells if the cupboard door is open (and what it contains) , and the other checking the probability of the door opening. However, it tells me (in Windows Frotz) that the “store is out of dynamic memory”, and in Gargoyle it states that I am attempting to “read to write-only address”.

How do I fix these? And what do the different tables (TABLE, PTABLE, LTABLE, PLTABLE, & ITABLE), when should I use them (ting a value, etc.) and what are their limitations?

I don’t know ZIL, but I know a thing or two about the Z-machine.

Tables can be placed anywhere in the first 64 KB of the story file. However, only the first x bytes of this is dynamic memory, i.e. memory that the program is allowed to change during execution (the value x is held in bytes 14 and 15 of the story file).

If your program tries to store a value in a table outside dynamic memory, you can expect to get an error message from the interpreter like “Store outside dynamic memory.”

I would think there is either a keyword you can use to say a table should be stored in dynamic memory and you need to use it here, or there’s a keyword to say a table should be stored in static memory and you’re currently using it but need to omit it.

The P means pure and L means length.

TABLE is an array in dynamic (writeable) memory without the length in the first slot.

LTABLE is an array in dynamic (writeable) memory with the length of the array in the first slot.

PTABLE is like TABLE but stored in static (readonly) memory.

PLTABLE is like LTABLE but stored in static (readonly) memory.

ITABLE is to init a table of specified length with default values.

All tables defined with P and/or L are word-arrays (each slot is two bytes). If you want a byte-array you define them with TABLE and specify flags for BYTE, LENGTH or PURE.

<TABLE (PURE BYTE) 1 2 3 4 ...>

4 Likes

Writable memory, I assume.

1 Like

You can use with the flags so it can be both (but there’s no shortcut like PLITABLE).

<ITABLE 4 (BYTE LENGTH) 1>

Creates a byte array with a length byte in dynamic memory preloaded with 1.

1 Like

Thanks for the P & L! But I still don’t get it. When would you use ITABLE?

When you need a table of a predefined size that you fill with data later. It’s shorter to type (example from Zork 1 and its definition of the input buffer):

<ITABLE 120 (BYTE LENGTH) 0>

Instead of table followed by 120 0:

<TABLE (BYTE LENGTH) 0 0 0 0 0 0 0 0 ...>

(I had the ITABLE syntax slightly wrong above, I’ve now changed it.)

1 Like

A bit more on ITABLE. There’s some alternate syntaxes and also an additional flag, LEXV with special meaning (used when storing the result of parsing the user input). You usually also assign the TABLE to a GLOBAL so it can be referenced inside the routines. Hopefully the following table illustrates the possibilities.

Syntax                          Resulting byte array                    Comment
------                          --------------------                    -------
<ITABLE 4> or
<ITABLE NONE 4>                 [0 0 0 0 0 0 0 0]                       4 x #WORD

<ITABLE 4 1> or
<ITABLE NONE 4 1>               [0 1 0 1 0 1 0 1]                       4 x #WORD

<ITABLE 4 (LENGTH) 1> or
<ITABLE 4 (LENGTH WORD) 1> or
<ITABLE WORD 4 1>               [0 4 0 1 0 1 0 1 0 1]                   #WORD + 4 x #WORD

<ITABLE 4 (BYTE) 1>             [1 1 1 1]                               4 x #BYTE

<ITABLE 4 (LENGTH BYTE) 1> or
<ITABLE BYTE 4 1>               [4 1 1 1 1]                             #BYTE + 4 x #BYTE

<ITABLE 4 (LEXV) 1 2 3>         [0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]       4 x (#WORD #BYTE #BYTE)

<ITABLE 4 (LENGTH LEXV) 1 2 3>  [0 12 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3]  #WORD + 4 x (#WORD #BYTE #BYTE)

LEXV creates a structure #WORD #BYTE #BYTE.
3 Likes