Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
feat: add Multikeys doc
Browse files Browse the repository at this point in the history
  • Loading branch information
boriel committed Sep 24, 2022
1 parent f6d05b8 commit c88a391
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 107 deletions.
188 changes: 94 additions & 94 deletions docs/identifier.md
Original file line number Diff line number Diff line change
@@ -1,112 +1,112 @@
#Identifier


Identifiers are used in your ZX BASIC program to define _variable names_, _function names_, _subroutine names_ and _[labels](labels.md)_. ZX Basic identifiers **must** start with a letter (a..z / A..Z) followed by an arbitrary number of letters and or digits. Original Sinclair BASIC allows spaces within variable names, but ZX BASIC <u>does not</u> (in fact, I found it a bit confusing!)
Identifiers are used in your ZX BASIC program to define _variable names_, _function names_, _subroutine names_ and _[labels](labels.md)_. ZX Basic identifiers **must** start with a letter (a..z / A..Z) followed by an arbitrary number of letters and or digits. Original Sinclair BASIC allows spaces within variable names, but ZX BASIC <u>does not</u> (in fact, I found it a bit confusing!)

Some identifiers are **reserved words**. Most of them are either BASIC _statements_ or _functions_. Functions return a value to be used in an _expression_ whilst statements do not.
Some identifiers are **reserved words**. Most of them are either BASIC _statements_ or _functions_. Functions return a value to be used in an _expression_ whilst statements do not.

Note that there are a number of common statements that you may find in ZX BASIC programs that are not technically reserved words, but library functions. Some of the internal libraries form functions that may overlap with your subroutine and function names (such as POS). So while they may not be technically reserved, you should consider the library function names as ones you should avoid. Also, some Sinclair Basic statements are implemented as library functions, so you should be especially aware of identifiers of this type, such as INPUT, POINT and ATTR.

## Reserved Identifiers
## Reserved Identifiers

The following identifiers are _reserved words_, and can't be used as variables, functions or labels. Reserved identifiers are _case insensitive_ (it doesn't matter whether you write them in upper or lower case letters, or a mix of them). So **PRINT**, **print** and **PrInT** means all the same in ZX BASIC. On the other hand, non-reserved words can be either case sensitive or not (depending on the [options](options.md)) in effect.
The following identifiers are _reserved words_, and can't be used as variables, functions or labels. Reserved identifiers are _case insensitive_ (it doesn't matter whether you write them in upper or lower case letters, or a mix of them). So **PRINT**, **print** and **PrInT** means all the same in ZX BASIC. On the other hand, non-reserved words can be either case sensitive or not (depending on the [options](options.md)) in effect.

Identifiers shown in bold are taken from the Sinclair BASIC (beware their meaning here might be different, however). Some of them has been marked as _statements_, _functions_ or _operators_:
Identifiers shown in bold are taken from the Sinclair BASIC (beware their meaning here might be different, however). Some of them has been marked as _statements_, _functions_ or _operators_:

* **[ABS](abs.md)** **(function)**
* **[ACS](acs.md)** **(function)**
* **[AND](operators.md#AND)** **(operator)**
* [ALIGN](align.md) **(special)**
* [ASM](asm.md) **(special)**
* **[ASN](asn.md)** **(function)**
* **[AT](at.md)**
* **[ATN](atn.md)** **(function)**
* **[ACS](acs.md)** **(function)**
* **[AND](operators.md#AND)** **(operator)**
* [ALIGN](align.md) **(special)**
* [ASM](asm.md) **(special)**
* **[ASN](asn.md)** **(function)**
* **[AT](at.md)**
* **[ATN](atn.md)** **(function)**
* **[bAND](bitwiselogic.md)** **(operator)**
* **[bNOT](bitwiselogic.md)** **(operator)**
* **[bOR](bitwiselogic.md)** **(operator)**
* **[bXOR](bitwiselogic.md)** **(operator)**
* **[BEEP](beep.md)** **(statement)**
* [BOLD](bold.md)
* **[BORDER](border.md)** **(statement)**
* **[BRIGHT](bright.md)** **(statement)**
* [ByRef](byref.md)
* [ByVal](byval.md)
* [CAST](cast.md) **(function)**
* **[CHR](chr.md)** **(function)** (can also be written as **CHR$**)
* **[CIRCLE](circle.md)** **(statement)**
* **[CLS](cls.md)** **(statement)**
* **[CODE](code.md)** **(function)**
* [CONST](const.md)
* **[CONTINUE](continue.md)** **(statement)**
* **[COS](cos.md)** **(function)**
* **[BEEP](beep.md)** **(statement)**
* [BOLD](bold.md)
* **[BORDER](border.md)** **(statement)**
* **[BRIGHT](bright.md)** **(statement)**
* [ByRef](byref.md)
* [ByVal](byval.md)
* [CAST](cast.md) **(function)**
* **[CHR](chr.md)** **(function)** (can also be written as **CHR$**)
* **[CIRCLE](circle.md)** **(statement)**
* **[CLS](cls.md)** **(statement)**
* **[CODE](code.md)** **(function)**
* [CONST](const.md)
* **[CONTINUE](continue.md)** **(statement)**
* **[COS](cos.md)** **(function)**
* **[DECLARE](declare.md)** **<modifier>**
* **[DIM](dim.md)** **(statement)**
* [DO](do.md) **(statement)**
* **[DATA](data.md)** **(statement)**
* **[DRAW](draw.md)** **(statement)**
* [ELSE](if.md)
* [ELSEIF](if.md)
* [END](end.md)
* [EXIT](exit.md) **(statement)**
* **[EXP](exp.md)** **(function)**
* [FastCall](fastcall.md)
* **[FLASH](flash.md)** **(statement)**
* **[FOR](for.md)** **(statement)**
* [FUNCTION](function.md)
* **[GO TO](goto.md)** or [GOTO](goto.md) **(statement)**
* **[DIM](dim.md)** **(statement)**
* [DO](do.md) **(statement)**
* **[DATA](data.md)** **(statement)**
* **[DRAW](draw.md)** **(statement)**
* [ELSE](if.md)
* [ELSEIF](if.md)
* [END](end.md)
* [EXIT](exit.md) **(statement)**
* **[EXP](exp.md)** **(function)**
* [FastCall](fastcall.md)
* **[FLASH](flash.md)** **(statement)**
* **[FOR](for.md)** **(statement)**
* [FUNCTION](function.md)
* **[GO TO](goto.md)** or [GOTO](goto.md) **(statement)**
* **[GO SUB](gosub.md)** or [GOSUB](gosub.md) **(statement)**
* **[IF](if.md)** **(statement)**
* **[IN](in.md)** **(function)**
* **[INK](ink.md)** **(statement)**
* **[INKEY](inkey.md)** **(function)** (can also be written as **INKEY$**)
* **[IF](if.md)** **(statement)**
* **[IN](in.md)** **(function)**
* **[INK](ink.md)** **(statement)**
* **[INKEY](inkey.md)** **(function)** (can also be written as **INKEY$**)
* **[INPUT](input.md)** **(function)** (not compatible with ZX BASIC)
* **[INT](int.md)** **(function)**
* **[INVERSE](inverse.md)** **(statement)**
* **[INT](int.md)** **(function)**
* **[INVERSE](inverse.md)** **(statement)**
* [ITALIC](italic.md)
* [LBOUND](lbound.md) **<function;>**
* **[LET](let.md)** **(statement)**
* **[LEN](len.md)** **(function)**
* **[LN](ln.md)** **(function)**
* **[LOAD](load.md)** **(statement)**
* [LOOP](do.md) **(statement)**
* [LBOUND](lbound.md) **<function;>**
* **[LET](let.md)** **(statement)**
* **[LEN](len.md)** **(function)**
* **[LN](ln.md)** **(function)**
* **[LOAD](load.md)** **(statement)**
* [LOOP](do.md) **(statement)**
* [MOD](operators.md#Arithmetic Operators) **(operator)**
* **[NEXT](for.md)** **(statement)**
* **[NOT](operators.md#NOT)** **(operator)**
* **[OR](operators.md#OR)** **(operator)**
* **[OVER](over.md)** **(statement)**
* **[OUT](out.md)** **(statement)**
* **[PAPER](paper.md)** **(statement)**
* **[PAUSE](pause.md)** **(statement)**
* **[PEEK](peek.md)** **(function)**
* **[PI](pi.md)** **<constant>**
* **[PLOT](plot.md)** **(statement)**
* **[POKE](poke.md)** **(statement)**
* **[PRINT](print.md)** **(statement)**
* **[RANDOMIZE](randomize.md)** **(statement)**
* **[READ](read.md)** **(statement)**
* **[REM](comments.md)** **(commentary)** (can also be written as ')
* **[RESTORE](restore.md)** **(statement)**
* **[RETURN](return.md)** **(statement)**
* **[RND](rnd.md)** **(function)**
* **[SAVE](load.md)** **(statement)**
* **[SGN](sgn.md)** **(function)**
* [SHL or <<](shl.md) (operator)
* [SHR or >>](shl.md) (operator)
* **[SIN](sin.md)** **(function)**
* **[SQR](sqr.md)** **(function)**
* [StdCall](stdcall.md)
* **[NEXT](for.md)** **(statement)**
* **[NOT](operators.md#NOT)** **(operator)**
* **[OR](operators.md#OR)** **(operator)**
* **[OVER](over.md)** **(statement)**
* **[OUT](out.md)** **(statement)**
* **[PAPER](paper.md)** **(statement)**
* **[PAUSE](pause.md)** **(statement)**
* **[PEEK](peek.md)** **(function)**
* **[PI](pi.md)** **<constant>**
* **[PLOT](plot.md)** **(statement)**
* **[POKE](poke.md)** **(statement)**
* **[PRINT](print.md)** **(statement)**
* **[RANDOMIZE](randomize.md)** **(statement)**
* **[READ](read.md)** **(statement)**
* **[REM](comments.md)** **(commentary)** (can also be written as ')
* **[RESTORE](restore.md)** **(statement)**
* **[RETURN](return.md)** **(statement)**
* **[RND](rnd.md)** **(function)**
* **[SAVE](load.md)** **(statement)**
* **[SGN](sgn.md)** **(function)**
* [SHL or <<](shl.md) (operator)
* [SHR or >>](shl.md) (operator)
* **[SIN](sin.md)** **(function)**
* **[SQR](sqr.md)** **(function)**
* [StdCall](stdcall.md)
* **[STEP](for.md)**
* **[STOP](stop.md)**
* **[STR](str.md)** **(function)** (Can also be written as **STR$**)
* **[SUB](sub.md)**
* **[TAN](tan.md)** **(function)**
* **[THEN](if.md)**
* **[TO](to.md)**
* [UBOUND](ubound.md) **(function)**
* [UNTIL](do.md) **(statement)**
* **[VAL](val.md)** **(function)**
* **[VERIFY](load.md)** **(statement)**
* [WEND](while.md) **(statement)**
* **[STR](str.md)** **(function)** (Can also be written as **STR$**)
* **[SUB](sub.md)**
* **[TAN](tan.md)** **(function)**
* **[THEN](if.md)**
* **[TO](to.md)**
* [UBOUND](ubound.md) **(function)**
* [UNTIL](do.md) **(statement)**
* **[VAL](val.md)** **(function)**
* **[VERIFY](load.md)** **(statement)**
* [WEND](while.md) **(statement)**
* [WHILE](while.md) **(statement)**
* **[XOR](operators#logical_operators.md)** **(operator)**

Expand All @@ -117,14 +117,14 @@ You should also avoid defining (with a SUB or FUNCTION command) routines with th
* **[ATTR (Library Function)](library/attr.md)** **(function)**
* **[CSRLIN (Library Function)](library/csrlin.md)** **(function)**
* [HEX (Library Function)](library/hex.md) **(function)**
* [HEX16 (Library Function)](library/hex.md) **(function)**
* [HEX16 (Library Function)](library/hex.md) **(function)**
* **[INPUT (Library Function)](library/input.md)** **(function)**
* **[GetKey (Library Function)](library/keys.bas.md)** **(function)**
* **[MultiKeys (Library Function)](library/keys.bas.md)** **(function)**
* **[GetKeyScanCode (Library Function)](library/keys.bas.md)** **(function)**
* **[LCase (Library Function)](library/lcase.md)** **(function)**
* **[UCase (Library Function)](library/ucase.md)** **(function)**
* **[POINT (Library Function)](library/point.md)** **(function)**
* **[GetKey (Library Function)](../library/keys/getkey.md)** **(function)**
* **[MultiKeys (Library Function)](../library/keys/multikeys.md)** **(function)**
* **[GetKeyScanCode (Library Function)](../library/keys/getkeyscancode.md)** **(function)**
* **[LCase (Library Function)](library/string/lcase.md)** **(function)**
* **[UCase (Library Function)](library/string/ucase.md)** **(function)**
* **[POINT (Library Function)](library/string/point.md)** **(function)**
* **[POS (Library Function)](library/pos.md)** **(function)**
* **[print42 (Library Subroutine)](library/print42.bas.md)** **(sub)**
* **[printat42 (Library Subroutine)](library/print42.bas.md)** **(sub)**
Expand Down
94 changes: 94 additions & 0 deletions docs/library/keys.bas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# KEYS.BAS

Library to check for keys being pressed. It provide functions which are
much faster than [INKEY$](../inkey.md), take less memory and does not require
the Sinclair ROM to be present.

## Functions
Functions provided in this library:

* [GetKey](./keys/getkey.md)
* [GetKeyScanCode](./keys/getkeyscancode.md)
* [MultiKeys](./keys/multikeys.md)


### Scan codes

This library define some global constants named _Scan codes_ which are just
UInteger constant.

Each key has assigned a unique Scan code. The ZX Spectrum Keyboard is divided
in 8 Rows half. Each Row half comprises 5 keys (from the left or right side of the speccy
QWERTY keyboard).

For example letters H, J, K L and ENTER belong to row half #2 (see below).

It is possible, for some routines, to use more than one scan code simultaneously, with `bOR`
operator.
For example `KEYH bOR KEYL` means Key H and/or Key L.
The only restriction is that both keys must be in the same Row Half.

These are all the scan codes available and their values.
```
Scan Codes
1st Keyboard ROW half
const KEYB AS UInteger = 07F10h
const KEYN AS UInteger = 07F08h
const KEYM AS UInteger = 07F04h
const KEYSYMBOL AS UInteger = 07F02h
const KEYSPACE AS UInteger = 07F01h
2nd Keyboard ROW half
const KEYH AS UInteger = 0BF10h
const KEYJ AS UInteger = 0BF08h
const KEYK AS UInteger = 0BF04h
const KEYL AS UInteger = 0BF02h
const KEYENTER AS UInteger = 0BF01h
REM 3rd Keyboard ROW half
const KEYY AS UInteger = 0DF10h
const KEYU AS UInteger = 0DF08h
const KEYI AS UInteger = 0DF04h
const KEYO AS UInteger = 0DF02h
const KEYP AS UInteger = 0DF01h
REM 4th Keyboard ROW half
const KEY6 AS UInteger = 0EF10h
const KEY7 AS UInteger = 0EF08h
const KEY8 AS UInteger = 0EF04h
const KEY9 AS UInteger = 0EF02h
const KEY0 AS UInteger = 0EF01h
REM 5th Keyboard ROW half
const KEY5 AS UInteger = 0F710h
const KEY4 AS UInteger = 0F708h
const KEY3 AS UInteger = 0F704h
const KEY2 AS UInteger = 0F702h
const KEY1 AS UInteger = 0F701h
REM 6th Keyboard ROW half
const KEYT AS UInteger = 0FB10h
const KEYR AS UInteger = 0FB08h
const KEYE AS UInteger = 0FB04h
const KEYW AS UInteger = 0FB02h
const KEYQ AS UInteger = 0FB01h
REM 7th Keyboard ROW half
const KEYG AS UInteger = 0FD10h
const KEYF AS UInteger = 0FD08h
const KEYD AS UInteger = 0FD04h
const KEYS AS UInteger = 0FD02h
const KEYA AS UInteger = 0FD01h
REM 8th Keyboard ROW half
const KEYV AS UInteger = 0FE10h
const KEYC AS UInteger = 0FE08h
const KEYX AS UInteger = 0FE04h
const KEYZ AS UInteger = 0FE02h
const KEYCAPS AS UInteger = 0FE01h
```

## See Also

* [INKEY$](../inkey.md)
33 changes: 33 additions & 0 deletions docs/library/keys/getkey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# GetKey

Library: `#include <keys.bas>`

Wait for a key to be pressed (using [INKEY$](../../inkey.md)), and return its ASCII Code.


### Syntax
`GetKey()`

Waits for a key pressed and returns its ASCII code. It cannot detect multiple keys pressed.
This is useful, for example, to program options menus in games were only a single option
can be selected.

## Examples

```
#include <keys.bas>
PRINT "PRESS A KEY"
x = GetKey
PRINT "You pressed the "; CHR x; " key"
```
Will print the key pressed. Unlike [INKEY$](../../inkey.md) it returns an Ubyte (ASCII code)
which is more efficent that working with strings.

### See also

* [GetKeyScanCode](getkeyscancode.md)
* [MultiKeys](multikeys.md)


Back to parent page: [Keys ibrary](../keys.bas.md)
38 changes: 38 additions & 0 deletions docs/library/keys/getkeyscancode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# GetKey

Library: `#include <keys.bas>`

Returns the Key Scan code of the key pressed or 0 if no keypress is detected.


### Syntax
`GetKeyScanCode()`

Examines the keyboard and returns 0 if no key is pressed (Unlike [GetKey](getkey.md), it
does not way for a key press).

If there is at least a key pressed, returns the Scan Codes of it. It

Waits for a key pressed and returns its ASCII code. It cannot detect multiple keys pressed.
This is useful, for example, to program options menus in games were only a single option
can be selected.

## Examples

```
#include <keys.bas>
PRINT "PRESS A KEY"
x = GetKey
PRINT "You pressed the "; CHR x; " key"
```
Will print the key pressed. Unlike [INKEY$](../../inkey.md) it returns an Ubyte (ASCII code)
which is more efficent that working with strings.

### See also

* [GetKeyScanCode](getkeyscancode.md)
* [MultiKeys](multikeys.md)


Back to parent page: [String library](../keys.bas.md)

0 comments on commit c88a391

Please sign in to comment.