WAIT

From C64-Wiki
Jump to navigationJump to search
BASIC keyword
Keyword: WAIT
Abbreviation: W Shift+A
Type: Command
Token code: 146/$92
Handling routine
in BASIC ROM:
47149–47176
$B82D–B848
List of all BASIC keywords


Remark: This article describes the BASIC command WAIT in BASIC V2 at the Commodore 64.

Type: Command
General Programming-Syntax: WAIT <Memoryaddress>,<and-mask>[,<flip-mask>]

WAIT is a keyword in the built-in BASIC interpreter, which waits for a given memory location to match specific bit constellations. The parameter values are specified as a bit mask, so WAITing on a value of 32 will cause the program to continue when bit 5 changes to 1. WAITing on 3 will cause it to continue when either bit 1 or 2 is set. The optional 3rd parameter enables a check for unset bits by inverting the locations bits.

Syntax[edit | edit source]

WAIT <address>,<and-mask>[,flip-mask]

  • address is a 16-bit unsigned integer value in range from 0 to 65535 which designats the address of the location the wait condition is acting on.
  • and-mask and flip-mask are unsigned byte values in range from 0 to 255, together comprising the wait condition the command is waiting for.

Values outside the given ranges result in the BASIC error ?ILLEGAL QUANTITY ERROR.

Operation[edit | edit source]

WAIT is performed by a loop in ROM address 47166–47175/$B83E–$B847, which first reads the contents of the given address, then does a bit-wise exclusive-or with the flip-mask parameter (if given, otherwise it defaults to 0 which leaves the value unchanged), and finally a bit-wise and with the and-mask parameter. The loop will run as long as the result of these operation sequence yields a zero byte.

Examples[edit | edit source]

Keyboard checks[edit | edit source]

WAIT 653,2
This will wait for the Commodore key to be pressed — until that happens, the "least drastic" way out of this, is to press RUN/STOP  + RESTORE . The three least significant bits in address 653 turn "on" (1) if Shift keys, the Commodore key or the Ctrl keys are pressed down at the moment; you may change the "2" at the end of the WAIT instruction to a "1" to wait for Shift keys, or a "4" to wait for the Ctrl key to be pressed.

WAIT 203,64
Try this one in direct mode: When pressing RETURN  after typing the command, hold the Return key down for a while, and notice how the "Ready." prompt and cursor doesn't reappear before you release. Address 203 holds the keyboard code for the key currently being pressed, or the value 64/$40 if none are pressed.

WAIT 203,64,64
Since the keyboard codes for all keys are less than 64, bit 6 basically indicate that no key is currently pressed. To wait for a key to be pressed, this example uses the extra mask2 parameter to "invert" that bit, and wait for this "inverted" bit to indicate that a key was pressed.
If this example is given in direct mode, be sure to press and release the Return key very rapidly after typing in the command — otherwise the WAIT command will find the Return key still pressed down as it does it's loop the first time.

POKE 198,0: WAIT 198,1 The C64 wait until a key is pressed on the keyboard.

Miscellaneous checks[edit | edit source]

WAIT 1, 32, 32 
(The C64 wait until a button is pressed on the datassette.)
  WAIT 53273, 6, 6
(The C64 wait until a sprite has got a collision with a char.)
 
WAIT 36868, 144, 16
(The C64 wait until at the memory address 36868 the 4th bit is deleted or
the 7th bit is set.)
 

Time delays[edit | edit source]

A simple approach:

POKE 162,0:WAIT 162,64

The system's internal clock is stored in location 162 (the low significant byte, and 161, the middle significant and 160, the high significant byte of the 24-bit counter) and is incremented every jiffy, 1/60th of a second. Because WAIT is looking at bits, not the decimal value, this instruction means "wait until bit 6 changes". That will happen after 64 jiffies, or 64/60ths of a second, slightly more than one second.

You cannot wait one second by using 60 as the value, as this will occur if any of the bits change in 60 = 32 + 16 + 8 + 4. This means it will continue after 4 jiffies, not what might be expected. To wait for a specific number of jiffies you have to use several WAIT instructions in a row:

POKE 162,0:WAIT 162,32:WAIT 162,16:WAIT 162,8:WAIT 162,4

will wait exactly one second because it will first wait 32/60ths, then 16, 8 and 4 = 60/60ths.


An easier way to achieve random values with just one WAIT:

T=90
POKE 162,128-T:WAIT 162,128

This works for values in variable T from 1 to 128 (up to 2.13 seconds).
This scheme can be extended to 16 bit, covering a time range up to 9 minutes, 6 seconds and 8 1/60th seconds:

T=32768-600 :REM 600 JIFFIES, 10 SECONDS
POKE 161,T/256: POKE 162,255ANDT: WAIT 161,128

A more general approach:

To wait for a flexible time (in opposite to the above hard-coded wait sequence):

100 T=90: REM WAIT 1,5 SECONDS
110 TI$="000000": REM TO ENSURE A USABLE TI$
120 GOSUB 900
130 PRINT TI
140 END
900 WT=162: REM LOW BYTE 24-BIT TIMER
910 POKE WT,0: REM RESET TIMER
920 WAIT WT, 128, NOT(T) AND 128
921 WAIT WT, 64, NOT(T) AND 64
922 WAIT WT, 32, NOT(T) AND 32
923 WAIT WT, 16, NOT(T) AND 16
924 WAIT WT, 8, NOT(T) AND 8
925 WAIT WT, 4, NOT(T) AND 4
926 WAIT WT, 2, NOT(T) AND 2
927 WAIT WT, 1, NOT(T) AND 1
930 RETURN

The subroutine starting at line 900 waits for multiples of 1/60th of a second as given by variable T. The run-time behavior leads to some blurring effect.
Even it would be sufficient to wait just for set bits this subroutine waits for 0 bit flipping it my means of the 3rd parameter before the logic-AND masking is enforced.
Operator NOT() needs the parenthesis to prevent to tokenizer from recognizing the token TAN in NOT TAND 1 (possibly also a turn around of the expression to 1 AND T helps).

Note: This implementation suffers from the relatively slow processing of BASIC code. It takes a significant time to reach the bit with value 1, so it might happen that this bit's change has been missed and the WAIT catches the bit 1, 2, 4 or 8 jiffies later. This could be mitigated by using variable instead of constants for numbers and compact the code into long lines.

The following table shows a comparison of the waiting time to the real elapsed time for a value range from 1 to 100:

Delay     Elapsed   Difference
1         9         8
2         6         4
3         11        8
4         6         2
8         10        2
12        14        2
16        18        2
17        18        1
20        22        2
24        26        2
28        30        2
32        36        4
33        37        4
36        38        2
40        42        2
44        46        2
48        50        2
49        50        1
52        54        2
56        58        2
60        62        2
64        68        4
65        69        4
66        68        2
68        70        2
72        74        2
76        78        2
80        82        2
84        85        1
88        90        2
92        93        1
96        100       4
97        101       4
100       101       1


BASIC V2.0 (second release) Commands

ABS | AND | ASC | ATN | CHR$ | CLOSE | CLR | CMD | CONT | COS | DATA | DEF | DIM | END | EXP | FN | FOR | FRE | GET | GET# | GOSUB | GOTO | IF | INPUT | INPUT# | INT | LEFT$ | LEN | LET | LIST | LOAD | LOG | MID$ | NEW | NEXT | NOT | ON | OPEN | OR | PEEK | π | POKE | POS | PRINT | PRINT# | READ | REM | RESTORE | RETURN | RIGHT$ | RND | RUN | SAVE | SGN | SIN | SPC | SQR | STATUS/ST | STEP | STOP | STR$ | SYS | TAB | TAN | THEN | TIME/TI | TIME$/TI$ | TO | USR | VAL | VERIFY | WAIT