Difference between revisions of "!"

From BeebWiki
Jump to: navigation, search
m (Description: typo)
m (Slight formatting change.)
Line 1: Line 1:
 
[[Category:BASIC keywords]]
 
[[Category:BASIC keywords]]
 
The exclamation mark, '''!''', is a BASIC operator to read or change
 
The exclamation mark, '''!''', is a BASIC operator to read or change
''doublewords'' in memory. In this context it is pronounced 'pling',
+
''doublewords'' in memory. In this context it is pronounced 'pling', 'bang'
'bang' or, rarely, 'shriek'. It is somewhat equivalent to '''PEEK''' and
+
or, rarely, 'shriek'. It is somewhat equivalent to '''PEEK''' and '''POKE'''
'''POKE''' statements in other dialects of BASIC.
+
statements in other dialects of BASIC.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 20: Line 20:
 
| Description
 
| Description
 
| BASIC I-V
 
| BASIC I-V
| If there are two operands, <code>!</code> adds them to obtain an effective address. Otherwise, the single operand is the effective address.<br>In the first form, <code>!</code> returns the doubleword value at the effective address.<br>In the second form, the value assigned to <code>!</code> is written to the doubleword at the effective address.
+
| If there are two operands, <code>!</code> adds them to obtain an effective address. Otherwise, the single operand is the effective address.<br>In the first form, <code>!</code> returns the doubleword value at the effective address.<br>In the second form, the value assigned to <code>!</code> is written to the doubleword at the effective address.
 
|- style="vertical-align:top"
 
|- style="vertical-align:top"
 
| Associated keywords
 
| Associated keywords
Line 27: Line 27:
  
 
== Description ==
 
== Description ==
 
+
<code>!</code> is an operator providing access to the memory of the machine
<code>!</code> is an operator providing access to the memory of the
+
running BASIC. It allows the contents of memory to be inspected or changed
machine running BASIC. It allows the contents of memory to be inspected
+
one ''doubleword'' at a time. A doubleword is a unit of four bytes, and can
or changed one ''doubleword'' at a time. A doubleword is a unit of
+
hold a value between-2,147,483,648 and 2,147,483,647 or between &00000000
four bytes, and can hold a value between −2,147,483 648 and 2,147,483,647
+
and &FFFFFFFF. By contrast the <code>[[?]]</code> operator acts on
or between &00000000 and &FFFFFFFF. By contrast the <code>[[?]]</code>
+
individual bytes.
operator acts on individual bytes.
 
  
 
Like <code>[[-]]</code> and <code>?</code>, <code>!</code> can be either a
 
Like <code>[[-]]</code> and <code>?</code>, <code>!</code> can be either a
''unary'' or ''binary'' operator. This doesn't depend on whether it is
+
''unary'' or ''binary'' operator. This doesn't depend on whether it is used
used to ''PEEK'' or ''POKE'', but is a syntactic convenience to help with
+
to ''PEEK'' or ''POKE'', but is a syntactic convenience to help with
 
handling data structures.
 
handling data structures.
  
Line 46: Line 45:
 
If used as a binary operator, for example <code>I%!&3000</code> or
 
If used as a binary operator, for example <code>I%!&3000</code> or
 
<code>osword_block%!1</code>, then the two operands are added together to
 
<code>osword_block%!1</code>, then the two operands are added together to
form the effective address. The first operand, conventionally the
+
form the effective address. The first operand, conventionally the ''base
''base address'', must not be a constant. The second operand is the
+
address'', must not be a constant. The second operand is the ''offset'',
''offset'', typically a constant offset into a MOS control block.
+
typically a constant offset into a MOS control block.
  
 
Whether unary or binary, the operator will either read or write to memory,
 
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
+
depending on whether it is evaluated as an expression, or assigned a value.
value. In the latter case the whole [<num-var>]<code>!</code><numeric>
+
In the latter case the whole [<num-var>]<code>!</code><numeric> expression
expression serves as an ''lvalue'', or <num-var>.
+
serves as an ''lvalue'', or <num-var>.
  
 
For example, <code>!osword_block% = target%</code> sets the doubleword at
 
For example, <code>!osword_block% = target%</code> sets the doubleword at
Line 64: Line 63:
  
 
The binary operation is the highest priority operation in any expression.
 
The binary operation is the highest priority operation in any expression.
For example, <code>A%!PAGE+4</code> reads the word at
+
For example, <code>A%!PAGE+4</code> reads the word at <code>(A%+PAGE)</code>
<code>(A%+PAGE)</code> and then adds 4 to it. <code>A%!(PAGE+4)</code>
+
and then adds 4 to it. <code>A%!(PAGE+4)</code> reads the word at
reads the word at <code>(A%+PAGE+4)</code>.
+
<code>(A%+PAGE+4)</code>.
  
 
Doublewords in BBC BASIC are signed and little-endian: the byte ''at'' the
 
Doublewords in BBC BASIC are signed and little-endian: the byte ''at'' the
effective address holds the units place, the next one up holds the 256s
+
effective address holds the units place, the next one up holds the 256s
place, and so on. The whole doubleword is stored in two's-complement form
+
place, and so on. The whole doubleword is stored in two's-complement form
when the value is negative.   If a fractional number is assigned to the
+
when the value is negative. If a fractional number is assigned to the
 
<code>!</code> operator, it is rounded toward zero.
 
<code>!</code> operator, it is rounded toward zero.
  
== Warnings ==
+
==Warnings==
 
+
The BBC Microcomputer User Guide is peppered with warnings about the use of
The BBC Microcomputer User Guide is peppered with warnings about the use
+
<code>?</code>, <code>!</code> and <code>$</code>. They are not to be used
of <code>?</code>, <code>!</code> and <code>$</code>. They are not to be
+
to access memory-mapped devices or the system's internal variables - at
used to access memory-mapped devices or the system's internal variables
+
least, not in published programs. The relevant addresses may change or
at least, not in published programs. The relevant addresses may change or
 
 
disappear on different machines and MOS versions, or the program may find
 
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
+
itself running on the other side of the [[Tube]]! The MOS offers a
 
comprehensive API to access system functions in a portable way.
 
comprehensive API to access system functions in a portable way.
  
== Address space ==
+
==Address space==
 
+
The address space in which <code>!</code> operates is the one BASIC chooses
The address space in which <code>!</code> operates is the one BASIC
+
to provide for <code>!</code>. Normally this is the address space of the
chooses to provide for <code>!</code>. Normally this is the address space
+
processor running BASIC. The BASIC program appears in this space, between
of the processor running BASIC. The BASIC program appears in this space,
+
<code>[[PAGE]]</code> and <code>[[TOP]]</code>, but as mentioned above,
between <code>[[PAGE]]</code> and <code>[[TOP]]</code>, but as mentioned
+
well-behaved programs must not alter it.
above, well-behaved programs must not alter it.
 
  
 
''BAS128'' for the [[Model B plus|B+]] and [[Master]] puts the [[6502]]
 
''BAS128'' for the [[Model B plus|B+]] and [[Master]] puts the [[6502]]
address space from 0 to &FFFF, and adds an extended space between &10000
+
address space from 0 to &FFFF, and adds an extended space between &10000 and
and &1FFFF. This is made of the four slots of [[sideways RAM]] and
+
&1FFFF. This is made of the four slots of [[sideways RAM]] and contains the
contains the user's program, variables and memory blocks. The MOS cannot
+
user's program, variables and memory blocks. The MOS cannot access this
access this space (unless its own extended addressing system is enabled)
+
space (unless its own extended addressing system is enabled) and machine
and machine code definitely cannot run in it although it can be assembled
+
code definitely cannot run in it although it can be assembled there with
there with <code>[[OPT]]</code>ions 4 to 7.
+
<code>[[OPT]]</code>ions 4 to 7.
  
 
-- [[User:Beardo|beardo]] 04:43, 11 October 2007 (BST)
 
-- [[User:Beardo|beardo]] 04:43, 11 October 2007 (BST)

Revision as of 17:46, 12 November 2017

The exclamation mark, !, is a BASIC operator to read or change doublewords in memory. In this context it is pronounced 'pling', 'bang' or, rarely, 'shriek'. It is somewhat 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 21 (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 doubleword value at the effective address.
In the second form, the value assigned to ! is written to the doubleword at the effective address.
Associated keywords ?, $, CALL, USR

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 doubleword at a time. A doubleword is a unit of four bytes, and can hold a value between-2,147,483,648 and 2,147,483,647 or between &00000000 and &FFFFFFFF. By contrast the ? operator acts on individual 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 !osword_block%, then the single operand is used as the effective address.

If used as a binary operator, for example I%!&3000 or osword_block%!1, 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, !osword_block% = target% sets the doubleword at the address given by osword_block%, to the value of target%.

result% = osgbpb_block%!5 fetches the doubleword five to eight bytes up from osgbpb_block%'s value, and returns it to result%.

The binary operation is the highest priority operation in any expression. For example, A%!PAGE+4 reads the word at (A%+PAGE) and then adds 4 to it. A%!(PAGE+4) reads the word at (A%+PAGE+4).

Doublewords in BBC BASIC are signed and little-endian: the byte at the effective address holds the units place, the next one up holds the 256s place, and so on. The whole doubleword is stored in two's-complement form when the value is negative. If a fractional number is assigned to the ! operator, it is rounded toward zero.

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 OPTions 4 to 7.

-- beardo 04:43, 11 October 2007 (BST)