?
The question mark, ?, is a BASIC operator to read or change bytes in memory. In this context it is pronounced 'query'. It is equivalent to PEEK and POKE statements in other dialects of BASIC.
Availability | Present in all original versions of BBC BASIC. | |
Syntax | BASIC I-V | <num-var> = [<num-var>]? <numeric>[<num-var>] ? <numeric> = <numeric>
|
Token (hex) | BASIC I-V | 3F (operator, lvalue)
|
Description | BASIC I-V | If there are two operands, ? adds them to obtain an effective address. Otherwise, the single operand is the effective address.In the first form, ? returns the byte value at the effective address.In the second form, the value assigned to ? is written to the byte at the effective address.
|
Associated keywords | ! , $ , CALL , USR
|
Contents
Description
?
is an operator providing access to the memory of the
machine running BASIC. It allows the contents of memory to be inspected
or changed one byte at a time. A byte is a unit of storage that can
hold a value between 0 and 255. By contrast the !
operator acts on a doubleword, or four consecutive bytes.
Like -
and !
, ?
can be either a
unary or binary operator. This doesn't depend on whether it is
used to PEEK or POKE, but is a syntactic convenience to help with
handling data structures.
If used as a unary operator, for example ?&3000
or
?o7f_block%
, then the single operand is used as the effective
address.
If used as a binary operator, for example I%?&3000
or
o7f_block%?6
, then the two operands are added together to
form the effective address. The first operand, conventionally the
base address, must not be a constant. The second operand is the
offset, typically a constant offset into a MOS control block.
Whether unary or binary, the operator will either read or write to memory,
depending on whether it is evaluated as an expression, or assigned a
value. In the latter case the whole [<num-var>]?
<numeric>
expression serves as an lvalue, or <num-var>.
For example, ?o7f_block% = drive%
sets the byte at the
address given by o7f_block%
, to the value of
drive%
. Other BASICs would use POKE
o7f_block%,drive%
.
result% = o7f_block%?10
fetches the byte ten addresses up
from o7f_block%
's value, and returns it to
result%
. This translates as result% = PEEK
o7f_block%+10
. (A more common idiom on the BBC Micro is
result% = o7f_block%?(7+o7f_block%?5)
, which fetches another
byte from the control block to calculate the offset of the result byte.)
The binary operation is the highest priority operation in any expression.
For example, A%?PAGE+4
reads the byte at
(A%+PAGE)
and then adds 4 to it. A%?(PAGE+4)
reads the byte at (A%+PAGE+4)
.
Bytes in BBC BASIC are unsigned, that is to say, between 0 and 255. If a
number outside this range is assigned to the ?
operator, it
is rounded toward zero and the least significant byte is written to memory
(in two's-complement form if necessary). For instance 1000.1 is written
as 232, -254 becomes 2, and -253.5 is stored as 3.
Warnings
The BBC Microcomputer User Guide is peppered with warnings about the use
of ?
, !
and $
. They are not to be
used to access memory-mapped devices or the system's internal variables –
at least, not in published programs. The relevant addresses may change or
disappear on different machines and MOS versions, or the program may find
itself running on the other side of the Tube! The MOS offers a
comprehensive API to access system functions in a portable way.
Address space
The address space in which ?
operates is the one BASIC
chooses to provide for ?
. Normally this is the address space
of the processor running BASIC. The BASIC program appears in this space,
between PAGE
and TOP
, but as mentioned
above, well-behaved programs must not alter it.
BAS128 for the B+ and Master puts the 6502
address space from 0 to &FFFF, and adds an extended space between &10000
and &1FFFF. This is made of the four slots of sideways RAM and
contains the user's program , variables and memory blocks. The MOS cannot
access this space (unless its own extended addressing system is enabled)
and machine code definitely cannot run in it although it can be assembled
there with OPT
ions 4 to 7.
Bugs
?
operators cannot be made LOCAL
to, or be
the formal parameters of, procedures or functions. For example,
neither of the following lines are safe:
DEF FNfred(?block%) LOCAL ?temp
In 6502 BASIC I to III, the BASIC stack can only hold integers and strings, not bytes. On entry to the procedure or function, the global value of the byte is saved on the stack as an integer. On exit, this integer is 'restored', overwriting four bytes instead of one. Furthermore it is restored to the wrong address with potentially harmful results.
The bug was fixed in 6502 BASIC III. !
operators are safe to
use in this way from BASIC II onwards.
-- beardo 04:56, 11 October 2007 (BST)