Skip to content

Commit 7cef06d

Browse files
committed
feat: add Multikeys doc
1 parent f6d05b8 commit 7cef06d

File tree

8 files changed

+355
-120
lines changed

8 files changed

+355
-120
lines changed

docs/identifier.md

Lines changed: 94 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,112 @@
11
#Identifier
22

33

4-
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!)
4+
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!)
55

6-
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.
6+
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.
77

88
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.
99

10-
## Reserved Identifiers
10+
## Reserved Identifiers
1111

12-
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.
12+
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.
1313

14-
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_:
14+
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_:
1515

1616
* **[ABS](abs.md)** **(function)**
17-
* **[ACS](acs.md)** **(function)**
18-
* **[AND](operators.md#AND)** **(operator)**
19-
* [ALIGN](align.md) **(special)**
20-
* [ASM](asm.md) **(special)**
21-
* **[ASN](asn.md)** **(function)**
22-
* **[AT](at.md)**
23-
* **[ATN](atn.md)** **(function)**
17+
* **[ACS](acs.md)** **(function)**
18+
* **[AND](operators.md#AND)** **(operator)**
19+
* [ALIGN](align.md) **(special)**
20+
* [ASM](asm.md) **(special)**
21+
* **[ASN](asn.md)** **(function)**
22+
* **[AT](at.md)**
23+
* **[ATN](atn.md)** **(function)**
2424
* **[bAND](bitwiselogic.md)** **(operator)**
2525
* **[bNOT](bitwiselogic.md)** **(operator)**
2626
* **[bOR](bitwiselogic.md)** **(operator)**
2727
* **[bXOR](bitwiselogic.md)** **(operator)**
28-
* **[BEEP](beep.md)** **(statement)**
29-
* [BOLD](bold.md)
30-
* **[BORDER](border.md)** **(statement)**
31-
* **[BRIGHT](bright.md)** **(statement)**
32-
* [ByRef](byref.md)
33-
* [ByVal](byval.md)
34-
* [CAST](cast.md) **(function)**
35-
* **[CHR](chr.md)** **(function)** (can also be written as **CHR$**)
36-
* **[CIRCLE](circle.md)** **(statement)**
37-
* **[CLS](cls.md)** **(statement)**
38-
* **[CODE](code.md)** **(function)**
39-
* [CONST](const.md)
40-
* **[CONTINUE](continue.md)** **(statement)**
41-
* **[COS](cos.md)** **(function)**
28+
* **[BEEP](beep.md)** **(statement)**
29+
* [BOLD](bold.md)
30+
* **[BORDER](border.md)** **(statement)**
31+
* **[BRIGHT](bright.md)** **(statement)**
32+
* [ByRef](byref.md)
33+
* [ByVal](byval.md)
34+
* [CAST](cast.md) **(function)**
35+
* **[CHR](chr.md)** **(function)** (can also be written as **CHR$**)
36+
* **[CIRCLE](circle.md)** **(statement)**
37+
* **[CLS](cls.md)** **(statement)**
38+
* **[CODE](code.md)** **(function)**
39+
* [CONST](const.md)
40+
* **[CONTINUE](continue.md)** **(statement)**
41+
* **[COS](cos.md)** **(function)**
4242
* **[DECLARE](declare.md)** **<modifier>**
43-
* **[DIM](dim.md)** **(statement)**
44-
* [DO](do.md) **(statement)**
45-
* **[DATA](data.md)** **(statement)**
46-
* **[DRAW](draw.md)** **(statement)**
47-
* [ELSE](if.md)
48-
* [ELSEIF](if.md)
49-
* [END](end.md)
50-
* [EXIT](exit.md) **(statement)**
51-
* **[EXP](exp.md)** **(function)**
52-
* [FastCall](fastcall.md)
53-
* **[FLASH](flash.md)** **(statement)**
54-
* **[FOR](for.md)** **(statement)**
55-
* [FUNCTION](function.md)
56-
* **[GO TO](goto.md)** or [GOTO](goto.md) **(statement)**
43+
* **[DIM](dim.md)** **(statement)**
44+
* [DO](do.md) **(statement)**
45+
* **[DATA](data.md)** **(statement)**
46+
* **[DRAW](draw.md)** **(statement)**
47+
* [ELSE](if.md)
48+
* [ELSEIF](if.md)
49+
* [END](end.md)
50+
* [EXIT](exit.md) **(statement)**
51+
* **[EXP](exp.md)** **(function)**
52+
* [FastCall](fastcall.md)
53+
* **[FLASH](flash.md)** **(statement)**
54+
* **[FOR](for.md)** **(statement)**
55+
* [FUNCTION](function.md)
56+
* **[GO TO](goto.md)** or [GOTO](goto.md) **(statement)**
5757
* **[GO SUB](gosub.md)** or [GOSUB](gosub.md) **(statement)**
58-
* **[IF](if.md)** **(statement)**
59-
* **[IN](in.md)** **(function)**
60-
* **[INK](ink.md)** **(statement)**
61-
* **[INKEY](inkey.md)** **(function)** (can also be written as **INKEY$**)
58+
* **[IF](if.md)** **(statement)**
59+
* **[IN](in.md)** **(function)**
60+
* **[INK](ink.md)** **(statement)**
61+
* **[INKEY](inkey.md)** **(function)** (can also be written as **INKEY$**)
6262
* **[INPUT](input.md)** **(function)** (not compatible with ZX BASIC)
63-
* **[INT](int.md)** **(function)**
64-
* **[INVERSE](inverse.md)** **(statement)**
63+
* **[INT](int.md)** **(function)**
64+
* **[INVERSE](inverse.md)** **(statement)**
6565
* [ITALIC](italic.md)
66-
* [LBOUND](lbound.md) **<function;>**
67-
* **[LET](let.md)** **(statement)**
68-
* **[LEN](len.md)** **(function)**
69-
* **[LN](ln.md)** **(function)**
70-
* **[LOAD](load.md)** **(statement)**
71-
* [LOOP](do.md) **(statement)**
66+
* [LBOUND](lbound.md) **<function;>**
67+
* **[LET](let.md)** **(statement)**
68+
* **[LEN](len.md)** **(function)**
69+
* **[LN](ln.md)** **(function)**
70+
* **[LOAD](load.md)** **(statement)**
71+
* [LOOP](do.md) **(statement)**
7272
* [MOD](operators.md#Arithmetic Operators) **(operator)**
73-
* **[NEXT](for.md)** **(statement)**
74-
* **[NOT](operators.md#NOT)** **(operator)**
75-
* **[OR](operators.md#OR)** **(operator)**
76-
* **[OVER](over.md)** **(statement)**
77-
* **[OUT](out.md)** **(statement)**
78-
* **[PAPER](paper.md)** **(statement)**
79-
* **[PAUSE](pause.md)** **(statement)**
80-
* **[PEEK](peek.md)** **(function)**
81-
* **[PI](pi.md)** **<constant>**
82-
* **[PLOT](plot.md)** **(statement)**
83-
* **[POKE](poke.md)** **(statement)**
84-
* **[PRINT](print.md)** **(statement)**
85-
* **[RANDOMIZE](randomize.md)** **(statement)**
86-
* **[READ](read.md)** **(statement)**
87-
* **[REM](comments.md)** **(commentary)** (can also be written as ')
88-
* **[RESTORE](restore.md)** **(statement)**
89-
* **[RETURN](return.md)** **(statement)**
90-
* **[RND](rnd.md)** **(function)**
91-
* **[SAVE](load.md)** **(statement)**
92-
* **[SGN](sgn.md)** **(function)**
93-
* [SHL or <<](shl.md) (operator)
94-
* [SHR or >>](shl.md) (operator)
95-
* **[SIN](sin.md)** **(function)**
96-
* **[SQR](sqr.md)** **(function)**
97-
* [StdCall](stdcall.md)
73+
* **[NEXT](for.md)** **(statement)**
74+
* **[NOT](operators.md#NOT)** **(operator)**
75+
* **[OR](operators.md#OR)** **(operator)**
76+
* **[OVER](over.md)** **(statement)**
77+
* **[OUT](out.md)** **(statement)**
78+
* **[PAPER](paper.md)** **(statement)**
79+
* **[PAUSE](pause.md)** **(statement)**
80+
* **[PEEK](peek.md)** **(function)**
81+
* **[PI](pi.md)** **<constant>**
82+
* **[PLOT](plot.md)** **(statement)**
83+
* **[POKE](poke.md)** **(statement)**
84+
* **[PRINT](print.md)** **(statement)**
85+
* **[RANDOMIZE](randomize.md)** **(statement)**
86+
* **[READ](read.md)** **(statement)**
87+
* **[REM](comments.md)** **(commentary)** (can also be written as ')
88+
* **[RESTORE](restore.md)** **(statement)**
89+
* **[RETURN](return.md)** **(statement)**
90+
* **[RND](rnd.md)** **(function)**
91+
* **[SAVE](load.md)** **(statement)**
92+
* **[SGN](sgn.md)** **(function)**
93+
* [SHL or <<](shl.md) (operator)
94+
* [SHR or >>](shl.md) (operator)
95+
* **[SIN](sin.md)** **(function)**
96+
* **[SQR](sqr.md)** **(function)**
97+
* [StdCall](stdcall.md)
9898
* **[STEP](for.md)**
9999
* **[STOP](stop.md)**
100-
* **[STR](str.md)** **(function)** (Can also be written as **STR$**)
101-
* **[SUB](sub.md)**
102-
* **[TAN](tan.md)** **(function)**
103-
* **[THEN](if.md)**
104-
* **[TO](to.md)**
105-
* [UBOUND](ubound.md) **(function)**
106-
* [UNTIL](do.md) **(statement)**
107-
* **[VAL](val.md)** **(function)**
108-
* **[VERIFY](load.md)** **(statement)**
109-
* [WEND](while.md) **(statement)**
100+
* **[STR](str.md)** **(function)** (Can also be written as **STR$**)
101+
* **[SUB](sub.md)**
102+
* **[TAN](tan.md)** **(function)**
103+
* **[THEN](if.md)**
104+
* **[TO](to.md)**
105+
* [UBOUND](ubound.md) **(function)**
106+
* [UNTIL](do.md) **(statement)**
107+
* **[VAL](val.md)** **(function)**
108+
* **[VERIFY](load.md)** **(statement)**
109+
* [WEND](while.md) **(statement)**
110110
* [WHILE](while.md) **(statement)**
111111
* **[XOR](operators#logical_operators.md)** **(operator)**
112112

@@ -117,14 +117,14 @@ You should also avoid defining (with a SUB or FUNCTION command) routines with th
117117
* **[ATTR (Library Function)](library/attr.md)** **(function)**
118118
* **[CSRLIN (Library Function)](library/csrlin.md)** **(function)**
119119
* [HEX (Library Function)](library/hex.md) **(function)**
120-
* [HEX16 (Library Function)](library/hex.md) **(function)**
120+
* [HEX16 (Library Function)](library/hex.md) **(function)**
121121
* **[INPUT (Library Function)](library/input.md)** **(function)**
122-
* **[GetKey (Library Function)](library/keys.bas.md)** **(function)**
123-
* **[MultiKeys (Library Function)](library/keys.bas.md)** **(function)**
124-
* **[GetKeyScanCode (Library Function)](library/keys.bas.md)** **(function)**
125-
* **[LCase (Library Function)](library/lcase.md)** **(function)**
126-
* **[UCase (Library Function)](library/ucase.md)** **(function)**
127-
* **[POINT (Library Function)](library/point.md)** **(function)**
122+
* **[GetKey (Library Function)](library/keys/getkey.md)** **(function)**
123+
* **[MultiKeys (Library Function)](library/keys/multikeys.md)** **(function)**
124+
* **[GetKeyScanCode (Library Function)](library/keys/getkeyscancode.md)** **(function)**
125+
* **[LCase (Library Function)](library/string/lcase.md)** **(function)**
126+
* **[UCase (Library Function)](library/string/ucase.md)** **(function)**
127+
* **[POINT (Library Function)](library/string/point.md)** **(function)**
128128
* **[POS (Library Function)](library/pos.md)** **(function)**
129129
* **[print42 (Library Subroutine)](library/print42.bas.md)** **(sub)**
130130
* **[printat42 (Library Subroutine)](library/print42.bas.md)** **(sub)**

docs/library/keys.bas.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# KEYS.BAS
2+
3+
Library to check for keys being pressed. It provide functions which are
4+
much faster than [INKEY$](../inkey.md), take less memory and does not require
5+
the Sinclair ROM to be present.
6+
7+
## Functions
8+
Functions provided in this library:
9+
10+
* [GetKey](./keys/getkey.md)
11+
* [GetKeyScanCode](./keys/getkeyscancode.md)
12+
* [MultiKeys](./keys/multikeys.md)
13+
14+
15+
### Scan codes
16+
17+
This library define some global constants named _Scan codes_ which are just
18+
UInteger constant.
19+
20+
Each key has assigned a unique Scan code. The ZX Spectrum Keyboard is divided
21+
in 8 Rows half. Each Row half comprises 5 keys (from the left or right side of the speccy
22+
QWERTY keyboard).
23+
24+
For example letters H, J, K L and ENTER belong to row half #2 (see below).
25+
26+
It is possible, for some routines, to use more than one scan code simultaneously, with `bOR`
27+
operator.
28+
For example `KEYH bOR KEYL` means Key H and/or Key L.
29+
The only restriction is that both keys must be in the same Row Half.
30+
31+
These are all the scan codes available and their values.
32+
```
33+
Scan Codes
34+
35+
1st Keyboard ROW half
36+
const KEYB AS UInteger = 07F10h
37+
const KEYN AS UInteger = 07F08h
38+
const KEYM AS UInteger = 07F04h
39+
const KEYSYMBOL AS UInteger = 07F02h
40+
const KEYSPACE AS UInteger = 07F01h
41+
42+
2nd Keyboard ROW half
43+
const KEYH AS UInteger = 0BF10h
44+
const KEYJ AS UInteger = 0BF08h
45+
const KEYK AS UInteger = 0BF04h
46+
const KEYL AS UInteger = 0BF02h
47+
const KEYENTER AS UInteger = 0BF01h
48+
49+
REM 3rd Keyboard ROW half
50+
const KEYY AS UInteger = 0DF10h
51+
const KEYU AS UInteger = 0DF08h
52+
const KEYI AS UInteger = 0DF04h
53+
const KEYO AS UInteger = 0DF02h
54+
const KEYP AS UInteger = 0DF01h
55+
56+
REM 4th Keyboard ROW half
57+
const KEY6 AS UInteger = 0EF10h
58+
const KEY7 AS UInteger = 0EF08h
59+
const KEY8 AS UInteger = 0EF04h
60+
const KEY9 AS UInteger = 0EF02h
61+
const KEY0 AS UInteger = 0EF01h
62+
63+
REM 5th Keyboard ROW half
64+
const KEY5 AS UInteger = 0F710h
65+
const KEY4 AS UInteger = 0F708h
66+
const KEY3 AS UInteger = 0F704h
67+
const KEY2 AS UInteger = 0F702h
68+
const KEY1 AS UInteger = 0F701h
69+
70+
REM 6th Keyboard ROW half
71+
const KEYT AS UInteger = 0FB10h
72+
const KEYR AS UInteger = 0FB08h
73+
const KEYE AS UInteger = 0FB04h
74+
const KEYW AS UInteger = 0FB02h
75+
const KEYQ AS UInteger = 0FB01h
76+
77+
REM 7th Keyboard ROW half
78+
const KEYG AS UInteger = 0FD10h
79+
const KEYF AS UInteger = 0FD08h
80+
const KEYD AS UInteger = 0FD04h
81+
const KEYS AS UInteger = 0FD02h
82+
const KEYA AS UInteger = 0FD01h
83+
84+
REM 8th Keyboard ROW half
85+
const KEYV AS UInteger = 0FE10h
86+
const KEYC AS UInteger = 0FE08h
87+
const KEYX AS UInteger = 0FE04h
88+
const KEYZ AS UInteger = 0FE02h
89+
const KEYCAPS AS UInteger = 0FE01h
90+
```
91+
92+
## See Also
93+
94+
* [INKEY$](../inkey.md)

docs/library/keys/getkey.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# GetKey
2+
3+
Library: `#include <keys.bas>`
4+
5+
Wait for a key to be pressed (using [INKEY$](../../inkey.md)), and return its ASCII Code.
6+
7+
8+
### Syntax
9+
`GetKey()`
10+
11+
Waits for a key pressed and returns its ASCII code. It cannot detect multiple keys pressed.
12+
This is useful, for example, to program options menus in games were only a single option
13+
can be selected.
14+
15+
## Examples
16+
17+
```
18+
#include <keys.bas>
19+
20+
PRINT "PRESS A KEY"
21+
x = GetKey
22+
PRINT "You pressed the "; CHR x; " key"
23+
```
24+
Will print the key pressed. Unlike [INKEY$](../../inkey.md) it returns an Ubyte (ASCII code)
25+
which is more efficent that working with strings.
26+
27+
### See also
28+
29+
* [GetKeyScanCode](getkeyscancode.md)
30+
* [MultiKeys](multikeys.md)
31+
32+
33+
Back to parent page: [Keys ibrary](../keys.bas.md)

docs/library/keys/getkeyscancode.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# GetKey
2+
3+
Library: `#include <keys.bas>`
4+
5+
Returns the Key Scan code of the key pressed or 0 if no keypress is detected.
6+
7+
8+
### Syntax
9+
`GetKeyScanCode()`
10+
11+
Examines the keyboard and returns 0 if no key is pressed (Unlike [GetKey](getkey.md), it
12+
does not way for a key press).
13+
14+
If there is at least a key pressed, returns all of them ORed (bitwise).
15+
16+
## Examples
17+
18+
```
19+
#include <keys.bas>
20+
21+
PRINT "PRESS H, L or both"
22+
DO
23+
LOOP UNTIL GetKeyScanCode()
24+
PAUSE 10
25+
x = GetKeyScanCode()
26+
27+
IF x = KEYH THEN PRINT "You pressed the H key"
28+
IF x = KEYL THEN PRINT "You pressed the L key"
29+
IF x = KEYL bOR KEYH THEN PRINT "You pressed both"
30+
```
31+
To detect more than one key, they must be in the same "row half" (see [keys.bas library](../keys.bas.md))
32+
for further explanation.
33+
34+
### See also
35+
36+
* [GetKey](getkey.md)
37+
* [MultiKeys](multikeys.md)
38+
39+
40+
Back to parent page: [Keys library](../keys.bas.md)

0 commit comments

Comments
 (0)