How do I search for bytes with @scan_table?

From the spec:

scan_table

VAR:247 17
4 scan_table x table len form → (result)

Is x one of the words in table, which is len words long? If so, return the address where it first occurs and branch. If not, return 0 and don’t.

The form is optional (and only used in Version 5?): bit 7 is set for words, clear for bytes: the rest contains the length of each field in the table. (The first word or byte in each field being the one looked at.) Thus $82 is the default.

If I have a table mapping bytes to bytes (that is, each entry is two bytes long, the first byte is the key, the second byte is the value), what form is that? I know bit 7 needs to be clear, since the keys are bytes; but is the length 2 (two bytes long) or 1 (one word long)?

(I’m trying to upgrade Dialog’s uppercase handling by consulting a lowercase-ZSCII-to-uppercase-ZSCII table for any characters above 127.)

Form = 2.

The bottom 7 bits is the length of each entry, in bytes.

1 Like

BTW, PunyInform Adventure (source in games/source/inform on if-archive) uses this when checking if a dwarf can go directly to the player’s location.

1 Like

And it’s working!

[ R_EXT_UPPER l0 l1;
    @scantable l0 CASING_TABLE CASING_SIZE $02 ->l1 ?found;
    @ret l0;
.found
    @loadb l1 1 ->l0;
    @ret l0;
];

Though I’m seeing now I could save one instruction by inverting the sense of the branch. Maybe I’ll optimize that later.

1 Like