ZX Spectrum

BASIC programozási kézikönyv


Tartalom

1. Fejezet Bevezetés
A ZX Spectrum billentyűzete; a televíziós kép leírása
2. Fejezet Programozási alapfogalmak
Programok; sorszámozás; programszerkesztés; RUN; LIST; GO TO; CONTINUE; INPUT; NEW; REM; PRINT; STOP az adatbevitel (INPUT) közben; BREAK
3. Fejezet Programelágazások
IF, STOP
=, <, >, <=, >=, <>
4. Fejezet Utasításciklusok
FOR, NEXT
TO, STEP
5. Fejezet Szubrutinok
GO SUB, RETURN
6. Fejezet A READ, DATA és RESTORE utasítások
7. Fejezet

Kifejezések
Aritmetikai kifejezések a négy alapművelet használatával; számok exponenciális alakja; a változók nevei

8. Fejezet Stringek (karaktersorozatok)
A stringek kezelése; részstring-képzés
9. Fejezet Függvények
A felhasználó által definiált és standard ZX Spectrum függvények:
DEF, LEN, STR$, VAL, SGN, ABS, INT, SQR, FN
10. Fejezet

Matematikai függvények
(Egyszerű trigonometrikus függvények)
^, PI, EXP, LN, SIN, COS, TAN, ASN, ACS, ATN

11. Fejezet Véletlenszámok
RANDOMIZE, RND
12. Fejezet Tömbök
String- és numerikus tömbök; DIM
13. Fejezet Feltételek
és logikai kifejezések
AND, OR, NOT
14. Fejezet A karakterkészlet
A ZX Spectrum karakterkészlete; grafikus és felhasználói grafikus karakterek
CODE, CHR$, POKE, PEEK, USR, BIN
15. Fejezet További tudnivalók a PRINT és INPUT utasításról
A két utasítás összetettebb alkalmazása az elhatároló jelek (, ; '), a TAB, AT LINE és CLS használata
16. Fejezet Színek
INK, PAPER, FLASH, BRIGHT, INVERSE, OVER, BORDER
17. Fejezet Grafikus Lehetőségek
PLOT, DRAW, CIRCLE, POINT
18. Fejezet Mozgás
Mozgó ábrák; PAUSE, INKEY$, és PEEK
19. Fejezet Hangok
A BEEP utasítás használata
20. Fejezet Adattárolás kazettán
Programok tárolása kazettás magnetofonnal
LOAD, SAVE, VERIFY, MERGE
21. Fejezet A ZX nyomtató
LLIST, LPRINT, COPY
22. Fejezet Kiegészítő berendezések használata
23. Fejezet Az IN függvény és az OUT utasítás
Bemeneti / kimeneti portok és használatuk
24. Fejezet A memória
A ZX Spectrum belső működése
CLEAR
25. Fejezet A rendszerváltozók
26. Fejezet A gépi kód használata
USR numerikus argumentummal
Függelékek
A. A karakterkészlet
B. A számítógép üzenetei
C. A ZX Spectrum leírása
A ZX Spectrum BASIC
D. Mintaprogramok
E. A bináris és a hexadecimális számrendszer

Bevezetés

Akár elolvastuk a Bevezető füzetet, akár nem, a követ kezőkkel tisztában kell lennünk: a közvetlen parancsokat a számítógép azonnal végrehajtja; a programsorok egy sorszámmal kezdődnek, és ezeket a számítógép későbbi használatra eltárolja. Ismernünk kell a PRINT, a LET és az INPUT utasításokat (ezek valamennyi BASIC nyelven programozható számítógépen megtalálhatók), ill. a BORDER, a PAPER és a BEEP utasításokat (ezeket csak a Spectrum használja).
Ez a BASIC kézikönyv néhány, a Bevezető füzetben már ismertetett téma ismétlésével kezdődik, ezekét azonban részletesebben tárgyalja, pontosan megtudhatjuk, hogy mit szabad és mit nem Szabad tennünk. A fejezetek végén gyakorlatokat is találunk, ezeket se hagyjuk ki. Nagyon sok gyakorlatban olyan kérdések is előfordulnak, amelyeket a könyvben csak érintünk. Nézzük át ezeket, és amelyekhez kedvet érzünk, vagy olyan területet érint, amely nem teljesen világos, végezzük el.
A kézikönyv tanulmányozása során mindig használjuk a számítógépet is! Így az olyan kérdésekre, hogy mit csinál a számítógép, ha ezt vagy azt a gombot megnyomjuk, a válasz egyszerű lesz: megnyomjuk a kérdéses gombot, és megnézzük az eredményt. Ha a kézikönyv valaminek a beírását kéri tőlünk, mindig gondoljuk meg, hogyan tudnánk ugyanazt másképp végrehajtani, és próbáljuk ki saját megoldásunkat is. Minél több saját programot írunk, annál jobban megértjük a számítógép működését.
A programozási kézikönyv végére néhány mellékletet is illesztettünk. Ezekben többek között megadjuk a teljes karakterkészletet, a számítógép üzeneteit, majd néhány, a számítógép teljesítőképességét bemutató mintaprogram következik.

A billentyűzet
A ZX Spectrum karakterei nem csak egyszerű jeleket (betűk, számjegyek stb.), hanem összetett szimbólumokat (kulcsszók, függvény-nevek stb.) is magukba foglalnak, és ezeket egy gombnyomással, a bennük szereplő egyes betűk egyenkénti lenyomása nélkül beírhatjuk. Valamennyi függvény és utasítás megvalósítása érdekében néhány billentyűnek öt vagy még több különböző jelentése lehet, ezek megkülönböztetése a SHIFT billentyűkkel (a CAPS SHIFT vagy a SYMBOL SHIFT és a kérdéses gomb egyidejű megnyomása) vagy a számítógép különböző üzemmódjaival történik.
Az üzemmódot a kurzor jelzi: ez egy villogó betű, amely egyúttal a következő beírásra kerülő karakter helyét is jelzi.

Ha bármelyik gombot egy másodpercnél tovább lenyomva tartjuk, funkcióját folyamatosan ismétli.
A billentyűzetről bevitt karakterek a képernyő alsó részén jelennek meg, közvetlenül a kurzor előtt. A kurzor mozgatása a CAPS SHIFT és 5 (balra) ill. a CAPS SHIFT és 8 (jobbra) gombokkal történhet. A kurzor előtti karaktert vagy kulcsszót a DELETE (CAPS SHIFT és 0) törli. Az egész sor törlése az EDIT (CAPS SHIFT, és 1) majd ezt követben az ENTER megnyomásával lehetséges.
Az ENTER megnyomására a szintaktikailag helyes sor vagy végrehajtódik, vagy programsorként tárolódik, vagy adatbevitelként lesz értelmezve. A szintaktikai hibát előfordulása helyén egy villogó ? jelzi.
Programsorok bevitelénél ezek listája a képernyő felső részén jelenik meg. Az utolsóként bevitt sort aktuális sornak (current line) nevezzük, ezt egy > jelzi, amit a ( CAPS SHIFT és 6 ) é s a (CAPS SHIFT és 7) gombokkal mozgathatunk. Az EDIT (CAPS SHIFT és 1) hatására ez a sor a képernyő aljára kerül, és szerkeszthető.
Egy parancs végrehajtásánál illetve egy program futtatásánál az eredmények a képernyő felső részén jelennek meg, és mindaddig ott maradnak, míg vagy egy programsort be nem léptetünk, vagy üres sornál az ENTER gombot meg nem nyomjuk, vagy a illetve jeleket nem használjuk. A képernyő alsó részén egy üzenet jelenik meg, ennek kódjait (egy számjegy vagy egy betű) a B. melléklet tartalmazza. Az üzenet a következő gomb megnyomásáig marad a képernyőn (és K üzemmódot jelent).
Bizonyos feltételek mellett a CAPS SHIFT és SPACE gombok egyidejű lenyomása BREAK jelentés ű , ami D vagy L üzenet kiadásával leállítja a számítógép működését. A gép ezt a jelet

  1. egy utasítás végrehajtásának befejezése után, vagy
  2. magnetofon ill. nyomtató működtetése közben fogadja el.

A televíziós képernyő
A képernyő 24, egyenként 32 karakter hosszúságú sorból áll, és két részre oszlik: a felső rész legfeljebb 22 sort tartalmazhat, és programlisták vagy eredmények kijelzésére szolgál. Ha a képernyő felső 22 sora betelik, az egész rész egy sorral feljebb lép. Ha így olyan sor tűnne el, amelyet még nem láthattunk, a számítógép a scroll? üzenet kiadásával leáll. Az N, a SPACE vagy a STOP gombok megnyomása a program futását a D BRBAK - CONT repeats üzenettel leállítja; az összes többi gomb a felfelé léptetés (scrolling) művelet folytatását tovább engedi. A képernyő alsó része parancsok, programsorok és adatok (INPUT) bevitelére szolgál, illetve a számítógép üzenetei is itt jelennek meg. Az alsó rész kezdetben két sorból áll (ebből a felső üres), de a beírt szöveg méretének megfelelően bővül. Ha eléri a felső részben kijelzett szöveget, azt fölfelé lépteti.

Programozási alapfogalmak

Két szám összegét kinyomtató számítógépes program részeként írjuk be a következő két sort:

20 PRINT a
10 LET a=10

A képernyőn ekkor ezt látjuk:

Azt már tudjuk, hogy ezeket a sorokat, mivel számmal kezdődnek, a számítógép nem hajtja azonnal végre, hanem programsorokként tárolja. Azt is észrevehetjük, hogy ezek a számok a programon belül meghatározzák a sorok sorrendjét: ennek elsősorban a program futtatásánál van jelentősége, de a képernyőn a program listáján is már ez a sorrend.
Mivel eddig csak egy számot adtunk meg, írjuk be:

15 LET b=15

Ezt a sort nem tudtuk volna az előző kettő közé iktatni, ha sorszámként a 10 és 20 helyett 1-et és 2-t használtunk volna (a sorszámok 1 és 9999 közötti egész számok lehetnek). Éppen ezért ajánlott gyakorlat, hogy az első beírásnál a sorszámok között helyett hagyjunk. Ezek után a 20-as sort meg kell változtatnunk, hogy így nézzen ki:

PRINT a+b

A teljes sort újra beírhatjuk, de egyszerűbb a Bevezető füzetben leírt EDIT használata. A 15-ös sorra mutató jelet programkurzornak nevezzük, és ez mindig az aktuális sorra mutat. Ez általában az utoljára bevitt sor, de a és gombok segítségével a programkurzor fel-le mozgatható. (Próbáljuk ki a mozgatást, majd végül a kurzort állítsuk a 20-as sorra!)
Ha megnyomjuk az EDIT gombot, az aktuális sor a képernyő alján kerül kijelzésre - esetünkben ez a 20-as sor lesz. A gombbal mozgassuk az L kurzort addig, míg a sor végére nem ér, majd írjuk be:

+b (ENTER nélkül)

A sor még mindig a képernyő alján, most így néz ki:

20 PRINT a+b

Nyomjuk meg az ENTER gombot, és a régi 20-as sor kicserélődik, tehát a képernyőn ezt látjuk:

Futtassuk a programot a RUN és az ENTER megnyomásával, és az összeg meg fog jelenni a képernyőn.
Futtassuk újra a programot, majd írjuk be:

PRINT a+b

A változók továbbra is a képernyőn láthatók, jóllehet a program már befejeződött.

Az EDIT használatával könnyen megszabadulhatunk a képernyő alsó részén lévő szükségtelen szövegtől. Írjunk be tetszés szerinti szöveget (ENTER nem kell), majd tegyük fel, hogy az egészre nincs szükségünk. A törlés egyik módja, hogy a DELETE gombot addig tartjuk lenyomva, míg a sor el nem tűnik. A másik módszer az EDIT megnyomása, amelynek hatására a képernyő alsó részén a felesleges szöveget az aktuális sor fogja felváltani. Ha most megnyomjuk az ENTER gombot, az aktuális sor változtatás nélkül visszakerül a programba, és a képernyő alsó része üres marad.
Ha egy sort tévedésből irtunk be, például

12 LET b=8

és az a programba került már, amikor felfedezzük a hibát, törlését egyszerűen a következő módon végezzük:

12 (és természetesen ENTER)

Ekkor azt látjuk, hogy a programkurzor eltűnik. Arra kell gondolnunk, hogy a 10 és 15-ös sorok között van valahol, így a megnyomása a 10 -es, míg a megnyomása a 15-ös sorra mozgatja a programkurzort.
Újra írjuk be:

12 (és ENTER)

A programkurzor újra a 10 és 15-ös sorok között tűnt el. Most nyomjuk meg az EDIT gombot, erre a 15-ös sor kerül a képernyő alsó részére: ha a programkurzor két sor között eltűnik, az EDIT az új sorszám utáni első sort viszi le. Az ENTER megnyomásával töröljük a képernyő alsó részét, majd írjuk be:

30 (és ENTER)

Ekkor a programkurzor a program vége után fog eltűnni; az EDIT megnyomása a 20-as sort fogja lehívni.
Végül írjuk be ezt:

LIST 15

A képernyőn ekkor a következőt látjuk:

15>LET b=15
20 PRINT a+b

A 10 -es sor eltűnik a képernyőről, de még mindig a programban van (ennek igazolására nyomjuk meg az ENTER gombot ). A LIST 15 hatása csak annyi, hogy kilistázza a programot a 15-ös sortól kezdődően, valamint a programkurzort a 15-ös sorba helyezi. Ha nagyon hosszú programon dolgozunk, a programkurzor mozgatása a LIST használatával sokkal egyszerűbb, mintha a és gombokat használnánk.
A fentiek a sorszámok még egy fontos tulajdonságát megmutatták: ezek ugyanis a programsorok neveiként viselkedtek, ezekre hivatkozni lehetett (hasonlóan ahhoz, ahogy a változóknak is nevük van).
A LIST önmagában (sorszám nélkül) a listázást a program elejéről kezdi.
Még egy paranccsal találkoztunk a Bevezető füzetben. Ez a NEW, amely programok és változók törlésére szolgál. Írjuk be a következő programot, amely a hőmérsékletet számítja át Fahrenheit-fokról Celsius-fokra:

10 REM Homerseklet atszamitas
20 PRINT "F-fok","C-fok"
30 PRINT
40 INPUT "Ird be az F-fokot'",F
50 PRINT F,(F-32)*5/9
60 GO TO 40

A 10-es sorban lévő szöveget is nekünk kell beírni. A GO TO (G gomb) egyetlen kulcsszónak számit, jóllehet betűköz is szerepel benne.
A program futtatásánál a képernyőn látni fogjuk a 20-as sorban lévő fejlécet; de mi történt a 10-es sorral? Látszólag a számítógép teljesen figyelmen kívül hagyta. Ez valóban így van. A 10-es sorban a REM a remark vagy reminder rövidítése (megjegyzés, emlékeztető), és egyetlen feladata, hogy a program funkciójára emlékeztessen. A REM utasítás alakja: REM majd utána bármilyen szöveg; a számítógép a sor végéig az egészet figyelmen kívül hagyja.
A számítógép eljutott a 40-es sorban lévő INPUT, parancsig, és arra vár, hogy az F változó számára egy értéket beírjunk. Ezt megtehetjük, mivel L kurzor van jelen. Írjunk be egy számot, utána ne feledjük megnyomni az ENTER gombot. A számítógép erre kijelzi az eredményt, és várja a következő számot, mivel a 60-as sor (GO TO 40) jelentése: menj a 40-es sorra, vagyis a számítógép a programból való kilépés és leállás helyett visszaugrat a 40-es sorra. Írjunk be egy újabb hőmérséklet-értéket!

Néhány további beírás után felmerülhet a kérdés, hogy a számítógépnek mikor lesz már elege az egészből, és mikor hagyja abba. Ám az mindaddig végrehajtja a programot, míg például a következőt nem csináljuk: egy adatkérésnél írjuk be a STOP parancsot. A számítógép a H STOP in INPUT in line 40:1 üzenetet írja ki, amely közli, hogy miért és hol (a 40-es sor első utasításánál) állt le.
Ha folytatni akarjuk a program végrehajtását, írjuk be:

CONTINUE

és a számítógép újra egy számot vár tőlünk.
A CONTINUE használatánál a számítógép emlékezik az utolsóként kiadott üzenetben szereplő sorszámra (hacsak az üzenet nem OK volt), és visszaugrik erre a sorra: esetünkben ez a 40-es sorra, az INPUT utasításra ugrást jelenti.
Cseréljük ki a 60-as sort GO TO 31 -re! A program futásában ez nem okoz semmi változást, ugyanis ha a GO TO utasításban lévő sorszám nem létező sorra hivatkozik, az ugrás mindig az utána következő első létező sorra fog vonatkozni. Ugyanez igaz a RUN parancsnál is; a sorszám nélküli RUN jelentése RUN 0.
A program futtatása során most írjunk be annyi számot, hogy a képernyő megteljen. Ekkor a számítógép a képernyő teljes felső részét egy sorral felfelé lépteti, és a fejléc fölül eltűnik. Ezt scrollingnak (felfelé léptetés) nevezzük.
Állítsuk le a programot a STOP beírásával, és listázzuk ki a programot az ENTER gomb lenyomásával!
Nézzük meg az 50-es sorban lévő PRINT utasítást! Az írásjelek használata itt nagyon lényeges (jelen esetben vesszőt használtunk), és mindig figyelnünk kell erre, mert sokkal szigorúbb szabályok vonatkoznak használatukra, mint mondjuk az angol vagy a magyar nyelvben.
A vesszők alkalmazásánál a kiíratás vagy a baloldali margónál, vagy a képernyő közepén kezdődik, attól függően, hogy melyik következik. Így az 50-es sornál a vessző hatására a Celsius-fokban kifejezett hőmérsékletek a sor közepénél kezdődnek. Ha pontosvesszőt használunk, a következő szám vagy string közvetlenül az előző után jelenik meg. Ezt az 50-es sornál is megfigyelhetjük, ha a vesszőt pontosvesszőre cseréljük.
Még egy írásjelet használhatunk a PRINT utasításban, ez az aposztróf ('). Ennek hatására a következő kiírandó a következő sor elején fog megjelenni a képernyőn. Az egyes PRINT utasítások ezt a funkciót automatikusan teljesítik, így nem kell az aposztrófot állandóan kitennünk. Ezért van az, hogy az 50-es sor PRINT utasítása hatására a számítógép a kiírást mindig új sorban kezdi, illetve a 30-as sorban lévő PRINT hatására egy üres sor lesz a képernyőn.
Ha a fenti funkciót tiltani akarjuk, hogy így egy PRINT utasítást követő újabb PRINT hatására ugyanaz a sor folytatódjék, vesszőt vagy pontosvesszőt tehetünk az első PRINT végén. A funkciók megismerésére az 50-es sorba egymás után írjuk be a következőket, és minden egyes változatnál futtassuk a programot:

50 PRINT f,
50 PRINT f;
50 PRINT f
50 PRITN f'

A vesszőt tartalmazó változatnál az eredmény két elkülönülő oszlop lesz; a pontosvesszőnél minden összezsúfolódik; ha egyik sincs, minden szám új sorban fog megjelenni, és ugyanez a helyzet az aposztróf esetében is, csak itt nem automatikusan, hanem az aposztróf hatására történik a sorváltás.
A PRINT parancsnál ne feledkezzünk meg a vessző és a pontosvessző közötti különbségről, és ne keverjük össze ezeket az írásjeleket a kettősponttal (:), amely egy adott sorban az utasítások elválasztására szolgál Írjuk be a következő sorokat:

100 REM Ez az udvarias program megjegyzi a nevedet
110 INPUT n$
120 PRINT "Hello ";n$;"!"
130 GO TO 110

Ez az előbbitől különálló program, de mindkettőt egyidejűleg a számítógépben tarthatjuk. Az újabb program futtatására írjuk be:

RUN 100

Mivel ez a program nem számot, hanem stringet (karaktersorozatot) olvas be, két idézőjelet ír ki - ez egyrészt emlékeztető a felhasználó számára, másrészt némi beírási munkát is megtakarít. Próbáljuk ki a programot más nevekkel is! A legközelebbi menetben, amikor ismét két idézőjelet ír ki a gép, megtehetjük azt is, hogy az idézőjeleket nem használjuk. Például töröljük az idézőjeleket ( a és a DELETE segítségével, de akár az EDIT használatával, amely egyszerűbb) és írjuk be:

n$

Mivel most nincsenek idézőjelek, a számítógép felismeri, hogy bizonyos műveleteket kell végeznie: ebben az esetben meg kell határoznia az n$ nevű stringváltozó értékét, amely nem más, mint amit a legutóbbi esetben éppen beírtunk. Mivel az INPUT utasítás most úgy működik, mint a LET n$=n$, az n$ értéke változatlan marad.
Az összehasonlítás kedvéért a következő alkalommal írjuk be ismét:

n$

de ezúttal ne töröljük az idézőjeleket. Ekkor az n$ változó értéke "n$" lesz.
Ha stringek beolvasását akarjuk leállítani a STOP segítségével, akkor először a kurzort a segítségével a sor elejére kell vinnünk, és csak ezután írhatjuk be: STOP.

Menjünk egy kicsit vissza a RUN 100 parancsra: ez a 100-as sorra ugrást jelent. Nem írhattuk-e volna helyette a GO TO 100 parancsot? Ebben az esetben a válasz igen, de a kettő között különbség is van. A RUN 100 mindenek előtt törli az összes változót és a képernyőt, és csak ezek után végzi ugyanazt, mint a GO TO 100. A GO TO 100 semmit sem töröl. Bizonyos esetekben úgy akarunk egy programot futtatni, hogy az indítás ne törölje a változókat: ekkor a GO TO a helyes választás, a RUN nem megfelelő. Éppen ezért ne szokjunk rá, hogy a programot automatikusan a RUN paranccsal indítjuk. Még egy különbség van a RUN és a GO TO között: az előbbit sorszám megadása nélkül is használhatjuk, és ez a program első soráról való indítást jelent. A GO TO esetében mindig egy sorszámot is meg kell adnunk.
Mindkét fenti program leállt, mivel az adatbevitel közben beírtuk a STOP parancsot. Néha, esetleg tévedésből, olyan programot is írhatunk, amelyet nem tudunk leállítani, és önmagát sem állítja le. Például írjuk ezt be:

200 GO TO 200
RUN 200

Ez látszólag mindaddig fut, míg a tápegység csatlakozóját ki nem húzzuk; ám ennél kevésbé drasztikus megoldás is van. Nyomjuk meg a CAPS SHIFT és a SPACE, gombot egyszerre (utóbbi fölé BREAK van írva). A programfutás az L BREAK into program üzenettel leáll.
A program minden utasítás után megvizsgálja, hogy a fenti gombok nincsenek-e lenyomva, és ha igen, a programfutás leáll. A BREAK máskor is használható: a kazettás magnetofon vagy a nyomtató illetve a számítógéphez kapcsolható egyéb berendezések használatánál olyan esetekben, amikor a számítógép valamilyen műveletet vár ezektől, de azt nem hajtják végre. Ezekben az esetekben a kijelzett üzenet a következő lesz: D BREAK - CONT repeats. A CONTINUE ebben az esetben (é s az esetek nagy többségében ) azt az utasítást ismétli meg, ahol a program leállt. Az L BREAK into program üzenet után a CONTINUE a következő utasításnál folytatja a futást, beleértve az esetleges ugrásokat is.
Futtassuk újra a név-programot, és amikor az a bevitelre vár, írjuk be:

n$ (az idézőjelek törlése után)

Az n$ definiálatlan változó, így a 2 Variable not found hibaüzenetet kapjuk (az üzenetek jelentését lásd a B. függelékben). Ha most a következőt írjuk be:

LEN n$="valami hatarozott"

( ennek saját üzenete 0 OK,0:1 ) majd

CONTINUE

azt tapasztaljuk, hogy az n$ mint bemeneti adat minden probléma nélkül használható. Ebben az esetben a CONTINUE hatására a 110-es sorban lévő INPUT utasításra ugrik a program: ugyanis a számítógép figyelmen kívül hagyja a LET utasítás üzenetét, mivel az 'OK', és az előző üzenetben megadott utasításra, azaz a 110-es sor első utasítására ugrik. A fenti módszer gyakran hasznosnak bizonyul. Ha egy program valamilyen hiba miatt leáll, kijavítására számos lehetőség van, és ezután a CUNTINUE segítségével még folytatható a végrehajtás.
Amint említettük, az L BREAK into program speciális üzenet, mivel ezután a CONTINUE nem a program megszakításánál lévő utasítást ismétli.

Bizonyára meglepődtünk az automatikus listázáson (ez nem a LIST parancs hatására történik, hanem egy új sor bevitelénél). Kipróbálásához írjunk be egy 50 sorból és csupa REM utasításból álló programot:

1 REM
2 REM
3 REM
...
...
49 REM
50 REM

Az első megjegyzendő dolog, hogy az aktuális sor (ezt a > programkurzor jelzi) mindig megjelenik a képernyőn, és általában középtájon.
Írjuk be:

LIST (és természetesen ENTER)

Amikor a scroll? megjelenik (mivel a képernyő betelt) , nyomjuk meg az n gombot (jelentése itt "No" = "Nem") . A számítógép a D BREAK - CONT repeats üzenetet írja ki, hasonlóan ahhoz, mintha a BREAK gombot nyomtuk volna meg.
Bizonyára rájöttünk, hogy mi történt volna, ha az n helyett az y gombot nyomtuk volna meg ("Yes" = "Igen" a jelentése): általában a scroll?, kérdésre adott válaszban az n, a SPACE és a STOP "Nem" jelentésű, míg az összes többi gomb jelentése "Igen".
Ezek után nyomjuk meg újra az ENTER gombot, hogy automatikus listázást kapjunk: ekkor az 1-től 22-ig terjedő sorokat kell látnunk a képernyőn. Írjuk be:

23 REM

Erre a 2-t ől 23-ig terjedő sorok jelennek meg. Írjuk be:

28 REM

A 7-től 28-ig terjedő sorok jelennek meg. (Mindkét esetben az új sor beírásával a programkurzort úgy mozgattuk, hogy egy új lista keletkezett.)

A fenti eljárás talán egy kicsit önkényesnek látszik. Valójában az történik, hogy a számítógép azt akarja végrehajtani, amit a felhasználó kíván, bár nem mindig tudja azt meghatározni, lévén az emberek következetlen lények.
A számítógép nem csak az aktuális sort (amelynek a képernyőn mindig meg kell jelennie), hanem a képernyő legfelső sorát is számon tartja. Ha listázásra kerül sor, az első dolog e két sor összehasonlítása. Ha a legfelső sor később következik, semmi oka sincs itt kezdeni a listázást, így az aktuális sor lesz az új legfelső sor. Az ellenkező esetben az eljárás az, hogy a listázást a legfelső sorral kezdi a számítógép, és addig folytatja, míg az aktuális sort is ki nem írja, közben szükség szerint felfelé léptetés is történik. Először azonban egy durva számítást végez el, hogy milyen hosszú lesz a lista, és ha az eredmény túl hosszúnak bizonyul, a legfelső sort lefelé mozgatja, hogy az közelebb kerüljön az aktuális sorhoz. Miután így kiszámította a legfelső sort, ettől kezdi a listázást. Ha eléri a program végét vagy a képernyő alját, és az aktuális sor is megjelent, a listázás leáll. Ellenkező esetben addig léptet felfelé, míg az aktuális sor a képernyőre nem kerül, és minden ilymódon a képernyőre kerülő sornál a legfelső sort addig mozgatja lefelé, hogy az aktuális sor a legfelső sor szomszédja legyen.
Az aktuális sor mozgatásának vizsgálatára írjuk be a következőt:

[sorszám] REM

A LIST az aktuális sort mozgatja, a legfelső sort nem, így egy következő listázás az előzőtől eltérő lehet. Például írjuk be:

LIST

Így a LIST parancsnak megfelelő listát kapunk, majd nyomjuk meg az ENTER gombot újra, hogy így a 0-s sor legyen a legfelső sor. Ekkor az 1-től 22-ig terjedő sorokat kell kapnunk a képernyőn. Írjuk be:

LIST 22

Ekkor a 22-től 43-ig terjedő sorokat kapjuk; ha újra megnyomjuk az ENTER gombot, visszakapjuk az 1-től 22-ig terjedő sorokat. Ez rövid programoknál hasznos eljárás.
A fenti, csupa REM utasításból álló programnál írjuk be:

LIST

A scroll? kérdésre a válasz legyen n. Ezután írjuk be:

CONTINUE

A CONTINUE itt egy kissé furcsa eredményt ad, ugyanis a képernyő alsó része üressé válik; de a BREAK újra a normális állapotot állítja helyre. A fentiek magyarázata: a sorban a LIST volt az első parancs, így a CONTINUE ezt ismételte meg. Az utóbbi esetben viszont a sor első parancsa maga a CONTINUE, így a számítógép a megállításig ezt ismétli. Segíthetünk ezen, ha a LIST helyett ezt írjuk:

:LIST

amelyre a CONTINUE a 0 OK üzenetet eredményezi, mivel a CONTINUE hatásara a sor második parancsára történik ugrás, amely egyben a sor utolsó parancsa. Beírhatjuk ezt is:

::LIST

amelyre a CONTINUE az N Statement lost üzenetet eredményezi (mivel itt a CONTINUE a sor harmadik parancsára ugrást jelent, amely azonban nem létezik).

A fentiekben a PRINT, LET, INPUT, RUN, LIST, GO TO, CONTINUE, NEW és REM utasításokat ismertük meg, amelyek közvetlen parancsként vagy programsorokban is használhatók. Ez a Zx Spectrum szinte valamennyi utasítására igaz. A RUN, LIST, CONTINUE és NEW utasításokat a programokban általában nem használjuk, de alkalmazásuk lehetséges.

Gyakorlatok

  1. Használjuk a LIST utasítást egy olyan programban, amely a futtatásnál önmagát listázza.
  2. Írjunk egy olyan programot, amely a beadott árak adóját adja meg (az adó legyen 15%)! A PRINT utasítást úgy helyezzük el, hogy a számítógép jelezze a teendőket, és udvariasan kérje az ár bevitelét. Módosítsuk a programot úgy, hogy mi adhassuk meg az adó %-át is (amely lehet 0 is, vagy ilymódon változhat is).
  3. Írjunk olyan programot, amely a beadott számok mindenkori összegét írja ki! (Legyen két változónk: az "összeg" - amely kezdetben zérus -, és a "tétel", amelyet mindig adjunk hozzá az "összeg" változóhoz; mindkettőt írassuk ki, majd ez ismétlődjék újra).
  4. Milyen szerepe lehet a CONTINUE és a NEW utasításoknak egy programban?

Programelágazások

Az eddig vizsgált valamennyi program közös vonása volt, hogy egymás után sorba vette az utasításokat, majd újra a program eleje következett. A gyakorlatban ez nem túl célszerű eljárás, hiszen a számítógéptől döntések végrehajtását, és az eredménynek megfelelő lépéseket is elvárhatunk. Az erre szolgáló utasítás alakja a következő:

... IF ("ha") valami igaz vagy nem igaz, THEN ("akkor") csinálj valami mást.

Példaképpen a NEW paranccsal töröljük a számítógépben lévő előző programot, majd írjuk be és futtassuk az alábbi programot, amelyet két játékos játszhat:

10 REM Talald ki a szamot!
20 INPUT a: CLS
30 INPUT "Talald ki a szamot!",b
40 IF b=a THEN PRINT "A szam helyes": STOP
50 IF b<a THEN PRINT "Ez a szam kissebb, probald ujra!"
60 IF b>a THEN PRINT "Ez a szam nagyobb, probald ujra!"
70 GO TO 30

Látható, hogy az IF utasítás alakja a következő: IF feltétel THEN ...
ahol a p ontok helyére általában egymástól kettőspontokkal elválasztott utasítások sorozata kerül. A feltételt ki kell értékelni, az eredmény igaz vagy hamis: ha igaz, akkor a sor hátralévő részében a THEN után következő utasítások végrehajtásra kerülnek; ellenkező esetben viszont ezeket a számítógép kihagyja, és a végrehajtás a következő programsorban folytatódik.
A legegyszerűbb feltételek két számot vagy két karaktersorozatot hasonlítanak össze: vizsgálható, hogy két szám egyenlő-e, az egyik nagyobb-e a másiknál; a két karaktersorozat egyenlősége is vizsgálható, illetve az is, hogy az egyik a betűrendben előbb következik-e, mint a másik. A feltételekben a következő relációkat használhatjuk:

>, <=, >=,<>.

Az = jel egyenlőséget jelent. Bár a jelölés megegyezik a LET parancsban használt = jellel, itt teljesen más értelemben használjuk. A < jel (SYMBOL SHIFT és K ) jelentése "kisebb, mint" , így az alábbi feltételek mind igaz eredményt

1<2
-2<-1
-3<1

Hamis eredményt ad például a következő két feltétel:

1<0
0<-2

Az előbbi program 40-es sora a és b összehasonlítását végzi el. Ha ezek egyenlőek, a program a STOP utasítás hatására leáll. A képernyő alján megjelenő 9 STOP statement, 40:3 üzenet jelentése: a program leállását a 40-es sor harmadik utasítása okozta, azaz a STOP.
Az 50-es sor azt vizsgálja, hogy b kisebb-e a-nál, míg a 60-as sor azt, hogy b nagyobb-e a-nál. Ha e két feltétel közül valamelyik teljesül, a megfelelő szöveg kiíródik a képernyőre, majd a 70-es sor következik, amely ugrás a 30-as sorra.
A 20-as sorban lévő CLS (töröld a képernyőt) utasítás azért kell, hogy a másik játékos ne lássa a beírt számot.

A > jel (SYMBOL SHIFT és T) jelentése "nagyobb, mint". Ne keverjük össze a < jellel: a nyíl hegye mindig a kisebbnek feltételezett szám felé mutat.
A <= jel (SYMBOL SHIFT, és Q; ezt a jelet nem szabad egy < jel és egy = jel egymás utáni beírásával megadni) jelentése "kisebb vagy egyenlő"; hasonló a < feltételhez azzal a különbséggel, hogy ez a feltétel akkor is igaz, ha a két szám egyenlő. így a 2<=2 igaz, de a 2<2 hamis.
A >= jel (SYMBOL SHIFT és E) jelentése "nagyobb vagy egyenlő".
A <> jel (SYMBOL SHIFT és W/ jelentése "nem egyenlő", vagyis az = feltétel ellentettje.

A matematikusok a "a<3 és 3<4" helyett azt is írják, hogy 2<3<4, de ez a BASIC-ben így nem írható.
Néhány BASIC verzióban (a ZX Spectrum BASIC-ben nem) az IF utasítás alakja a következő:

IF feltétel THEN sorszám

Ez itt így írható:

IF feltétel THEN GO TO sorszám

Gyakorlatok
Próbáljuk ki az alábbi rövid programot:

10 PRINT "x": STOP: PRINT "y"

A futtatásnál a program kiír egy x betűt, majd a 9 STOP statement, 10:2 üzenet jelenik meg. Ezután írjuk be:

CONTINUE

Azt várnánk, hogy ennek hatására a program visszaugrik a STOP utasításra, hiszen a CONTINUE általában az üzenetben megadott utasítást ismétli meg. Ez azonban itt nem lenne célszerű, hiszen a számítógép állandóan leállna, és nem jelezné ki az y betűt. Éppen ezért a 9-es üzenet után a CONTINUE, a STOP utáni utasításra ugrik - példánkban a CONTINUE hatására a számítógép kiírja az y betűt is, és ezzel befejeződik a program.

Utasításciklusok

Tegyük fel, hogy öt számot akarunk bevinni, majd ezeket összeadni. Ennek egyik módja a következő (ezt a programot nem érdemes beírni):

10 LET osszeg=0
20 INPUT a
30 LET osszeg=osszeg+a
40 INPUT a
50 LET osszeg=osszeg+a
60 INPUT a
70 LET osszeg=osszeg+a
80 INPUT a
90 LET osszeg=osszeg+a
100 INPUT a
110 LET osszeg=osszeg+a
120 PRINT osszeg

A fenti eljárás nem a megfelelő megoldás: öt szám esetében még elfogadható, de képzeljük el, milyen hosszú lenne a program tíz szám összeadásánál, száz számról már nem is beszélve. Sokkal, jobb, ha egy változó segítségével 5-ig számolunk, majd leállítjuk a programot. Az egyik megoldás a következő (ezt a programot már érdemes beírni):

10 LET osszeg=0
20 LET szamlalo=1
30 INPUT a
40 REM szamlalo=az "a" beviteleinek szama
50 LET osszeg=osszeg+a
60 LET szamlalo=szamlalo+1
70 IF szamlalo<=5 THEN GO TO 30
80 PRINT osszeg

Figyeljük meg, hogy a 70-es sor megváltoztatásával milyen egyszerűen átalakítható a program tíz vagy akár száz szám összeadásának elvégzésére. Az ilyen módon való számlálás gyakran hasznos, ezért alkalmazását két speciális utasítás teszi könnyebbé: ez a FOR és a NEXT. Ezeket mindig együtt használjuk. Alkalmazásukkal az alábbi program ugyanazt hajtja végre mint az előző:

10 LET osszeg=0
20 FOR c=1 TO 5
30 INPUT a
40 REM c=az "a" beviteleink a szama
50 LET osszeg=osszeg+a
60 NEXT c
80 PRINT osszeg

(Ezt a programot az előző átalakításával is megkaphatjuk: a 20, 40, 60 és 70-es sorokban kell módosítást végrehajtani. A TO a SYMBOL SHIFT és az F egyidejű lenyomásával kapható.)
Figryeljük meg, hogy a számláló, változót c-re változtattuk. Ennek oka az, hogy egy FOR - NEXT ciklus ciklusváltozójának neve csak egyetlen betűből állhat.
A program úgy működik, hogy c az 1-es értékről (kezdőérték) indulva felveszi a 2, 3, 4 és 5 (végérték) értékeket, és minden egyes értéknél a 30, 40 és 50-es sorok végrehajtásra kerülnek. Ha c elérte a végértéket, a 80-as sor kerül végrehajtásra. További finomság, hogy a ciklusváltozó nem csak egyesével növekedhet, hanem bármennyivel, ha a FOR utasítás STEP részét is használjuk. A FOR utasítás általános alakja tehát a következő:

FOR ciklusváltozó = kezdőérték TO végérték STEP lépésköz

ahol a ciklusváltozó egyetlen betű, a kezdőérték, a végérték és a lépésköz pedig bármi, amit a számítógép számként kiszámíthat: lehet maga a szám, vagy egy összeg, vagy egy aritmetikai változó neve. Így ha a 20-as sorba ezt írjuk

20 FOR c=1 TO 5 STEP 3/2

akkor a c értékei a következők lesznek: 1, 2.5 és 4. Figyeljük meg, hogy nem csak egész számokat használhatunk, és a ciklusváltozónak nem kell pontosan elérnie a végértéket, hanem a ciklus addig folytatódik, míg a ciklusváltozó kisebb vagy egyenlő a végértékkel.
Próbáljuk ki a következő programot, amely az 1 és 10 közé eső számokat írja ki csökkenő sorrendben:

10 FOR n=10 TO 1 STEP -1
20 PRINT n
30 NEXT n

Az előbb azt mondtuk, hogy a program addig marad a ciklusban, míg a ciklusváltozó kisebb vagy egyenlő a végértékkel. Látható, hogy ez ebben az esetben képtelenség. A szabályt pontosítani kell: ha a lépésközre negatív értéket adunk meg, a program addig marad a ciklusban, míg a ciklusváltozó nagyobb vagy egyenlő a végértékkel.
Óvatosnak kell lennünk, ha két egymásba ágyazott FOR - NEXT ciklust tartalmaz a program. Próbáljuk ki a következő programot, amely a hatpettyes dominókészlet elemeit írja ki:

10 FOR m=0 TO 6
20 FOR n=0 TO m
30 PRINT m;":";n;" ";
40 NEXT n
50 PRINT
60 NEXT m

Láthatjuk, hogy az n-ciklus teljesen beleágyazódik az m-ciklusba. Helytelen és kerülendő az olyan FOR - NEXT ciklus, amelynél ezek úgy fedik át egymást, hogy egyik sincs teljesen beleágyazva a másikba. Hibás például a következő program:

5 REM Ez a program rossz
10 FOR m=0 TO 6
20 FOR n=0 TO m
30 PRINT m;":";n;" ";
40 NEXT m
50 PRINT
60 NEXT n

Két FOR - NEXT ciklusnál az egyiknek a másikon belül kell elhelyezkedni, vagy teljesen különállóknak kell lenniük.
Egy másik kerülendő eljárás egy FOR - NEXT ciklus közepébe való ugratás kívülről. A ciklusváltozó helyes beállítása a FOR utasítás végrehajtásával történik meg, így ha ez elmarad, a NEXT utasítást sem tudja kezelni a számítógép. A hibaüzenet ekkor NEXT without FOR ("NEXT FOR nélkül") vagy Variable not found ("definiálatlan változó").
A FOR és a NEXT közvetlen parancsként is használható, például:

FOR m=0 TO 10: PRINT m: NEXT m

Ez a GO TO helyett is használható, hiszen az egy parancsban nem helyezhető el, mivel sorszám a közvetlen parancsoknál nem szerepel. Például:

FOR m=0 TO 1 STEP 0: INPUT a: PRINT a: NEXT m

A lépésközre megadott 0 hatására a parancs állandóan ismétlődik. A módszer azonban nem ajánlott, mivel hiba esetén a parancs elveszik, és azt újra be kell írni - a CONTINUE itt hatástalan.

Gyakorlatok

1. A ciklusváltozónak nem csak neve és értéke van mint az egyszerű változóknak, hanem egy végértéket kell és egy lépésközt is lehet megadni, valamint a megfelelő FOR utasítás után egy hivatkozás is szükséges az utasításra. S FOR végrehajtásakor valamennyi információnak rendelkezésre kell állnia (a kezdőérték a változó által felvett első érték).Ez az információ elegendő a NEXT utasítás számára, hogy hányszor növelje (vagy csökkentse) az értéket, hogy hányszor ugorjon vissza, és ez az ugrás hová történjék.

2. Futtassuk a fejezet harmadik programját, majd írjuk be:

PRINT c

Miért kapunk eredményül 6-ot, és nem 5-öt?
(Válasz: a 60-as sor NEXT utasítását ötször hajtja végre a számítógép, és minden alkalommal 1 adódik hozzá a c értékéhez. Az utolsó alkalommal a c 6 lesz, erre a NEXT utasítás nem visszaugrást hajt végre, mivel a végértéket a c már meghaladta.)
Mi történik, ha a 20-as sorba ezt írjuk még: STEP 2?

3. Alakítsuk át a harmadik programot úgy, hogy öt szám automatikus összeadása helyett megkérdezze, hogy hány számot akarunk összeadni!
E program futtatásakor mi történik, ha erre a kérdésre 0-t írunk be, azaz egyetlen számot sem akarunk összeadni. Miért okoz problémát ez a számítógépnek, hiszen világos, hogy mit akarunk? (A számítógépnek egy vagy több utasításon is végig kell haladnia, mire a NEXT utasításhoz elér, bár ez nem mindig szükséges.)

4. A fejezet negyedik programjában a 10 -es sorban a 10 helyett írjunk be 100 -at, és futtassuk a programot! Ekkor a képernyőn 100-tól 79-ig jelennek meg a számok, és az alsó részen a scroll? kérdés látható, azaz a számítógép lehetővé teszi a felfelé léptetésnél eltűnő számok megtekintését. Ha megnyomjuk az N, a STOP vagy a BREAK gombok közül valamelyiket, a program a D BREAK - CONT repeats üzenet kiadásával leáll. Bármelyik másik gomb megnyomására újabb 22 sor és a scrollY jelenik meg a képernyőn.

5. A negyedik programban töröljük a 30-as sort. Ez a program most kiírja az első számot, majd OK üzenettel leáll. Ha beírjuk

NEXT n

a program még egyszer végigmegy a cikluson, és kiírja a következő számot.

Szubrutinok

Sokszor előfordul, hogy a program különböző részei nagyon hasonló feladatot végeznek. Ezt a program beírásánál abból vesszük észre, hogy kétezer vagy még többször ugyanazokat a sorokat kell beírnunk. Ez azonban nem szükségszerű: ezeket az ismétlődő sorokat elegendő csak egyszer, szubrutinként beírni, és később ez a rész a programban bárhol használható (hívható) anélkül, hogy újra leírnánk. Ehhez a GO SUB (GO to SUBroutine - ugorj szubrutinra) és a RETURN (visszatérés) utasításokat kell használni.
A z utasítás alakja a következő:

GO SUB n

ahol n a szubrutin első sorának sorszáma. Ez hasonló a GO TO n utasításhoz, a különbség annyi, hogy a számítógép megjegyzi a GO SUB utasítás helyét, és a szubrutin befejezése után erre a helyre tér vissza. Ez úgy történik, hogy a sorszámot és az utasítás számát a soron belül (ezek együttesen az ún. visszatérési címet alkotják) a belőlük alkotott "halom" (az ún. GO SUB stack) tetejére helyezi. A

RETURN

veszi a GO SUB stack legfelső visszatérési címét, majd az ez után következő utasításra ugrat. Példaként vegyük újra a számkitalálási programot, és írjuk át a következő módon:

10 REM Talald ki a szamot! 2. valtozat
20 INPUT a: CLS
30 INPUT "Talald ki a szamot!",b
40 IF b=a THEN PRINT "A szam helyes": STOP
50 IF b<a THEN GO SUB 100
60 IF b>a THEN GO SUB 100
70 GO TO 30
100 PRINT "Probald ujra!"
110 RETURN

A 70-es sor GO TO utasítása nagyon fontos, mivel enélkül a program ráléphetne a szubrutinra, és a RETURN utasítás elérésekor hibát jelezne (7 RETURN without GO SUB).
Az alábbi "butácska" program is a GO SUB használatát mutatja:

100 LET x=10
110 GO SUB 500
120 PRINT s
130 LET x=x+4
140 GO SUB 500
150 PRINT s
160 LET x=x+2
170 GO SUB 500
180 PRINT s
190 STOP
500 LET s=0
510 FOR y=1 TO x
520 LET s=s+y
530 NEXT y
540 RETURN

Futtassuk a programot, és közben gondoljuk meg, hogyan működik. A szubrutin az 500-as sorban kezdődik.
Egy szubrutin egy másikat vagy akár önmagát is hívhatja (az önmagát hívó szubrutint rekurzívnak nevezzük), így a szubrutinok is egymásba ágyazhatók.

A READ, DATA és RESTORE utasítások

Néhány eddig vizsgált programban már láttuk, hogy az INPUT utasítás segítségével információ vagy adat vihető be közvetlenül a számítógépbe. Néha ez fárasztó lehet, különösen akkor, ha a program ismételt futtatásánál sok adat ismétlődik. Sok időt megtakaríthatunk a READ, DATA és RESTORE utasításokkal. Például:

10 READ a,b,c
20 PRINT a,b,c
30 DATA 10,20,30
40 STOP

A READ utasítás a READ kulcsszóból és az ezután következő, egymástól vesszővel elválasztott változónevekből áll. Az INPUT utasításhoz hasonlóan működik azzal a különbséggel, hogy nem nekünk kell a változóknak adandó értékeket beírni, hanem a számítógép ezeket az értékeket a DATA utasításban keresi meg.
Valamennyi DATA utasítás egy aritmetikai vagy string kifejezésből álló lista; a kifejezéseket vesszők választják el egymástól. A DATA utasításokat a programban bárhol elhelyezhetjük, mivel a számítógép ezeket figyelmen kívül hagyja, kivéve ha egy READ utasítást hajt végre. Úgy kell elképzelnünk, hogy a program összes DATA utasításában szereplő kifejezéseket a gép egyetlen hosszú listába gyűjti össze, ez az ún. DATA lista. Amikor a számítógép az első READ utasítást végrehajtja, a DATA lista első elemét olvassa be; a következő READ utasításnál a második elemre kerül sor stb.: az egymást követő READ utasítások mindig a soron következő DATA lista elemet olvassák be, egészen a DATA lista végéig. (Ha a számítógép a DATA lista végére ért, a legközelebbi READ kísérlet esetén hibát jelez.)
A DATA utasítások használata közvetlen parancsban időpocsékolás, ugyanis a READ ezeket nem fogja megtalálni. A DATA utasítást csak programban használjuk!
N ézzük meg, hogyan működik mindez az előbb beírt programban! A 10 -es sor arra utasítja a számítógépet, hogy olvasson be három adatot, és ezeket rendelje az a, b és c változókhoz. A 20-as sor ezeket a változókat íratja ki. A 30-as sor DATA utasítása a, b és c értékeit adja meg. A 40-es sor leállítja a programot. Nézzük meg mi történik, ha a 20-as sort átírjuk! Legyen

20 PRINT b,c,a

A DATA utasításban elhelyezett információ egy FOR - NEXT ciklus része is lehet. Írjuk be:

10 FOR n=1 TO 6
20 READ d
30 DATA 2,4,6,8,10,12
40 PRINT d
50 NEXT n
60 STOP

E program futtatásakor láthatjuk, hogy a READ utasítás végigmegy a DATA listán. A DATA utasítás string-változókat is tartalmazhat, például:

10 READ d$
20 PRINT "A mai datum: ",d$
30 DATA "1983. szeptember 23."
40 STOP

A DATA listáról történő kifejezések lehívásának ez az egyszerű módja: elkezdjük az elején, és addig folytatjuk, míg a végére nem érünk. A számítógép a DATA listában ugrást is végezhet (de ez eltér a más számítógépeknél szokásostól); ennek végrehajtására a RESTORE utasítás szolgál. Ebben az utasításban a RESTORE kulcsszó után egy sorszám áll. Az utasítás hatására a következő READ utasítások annál a DATA utasításnál kezdik a beolvasást, amely a megadott sorszámú programsorban vagy azt követően helyezkedik el. (Ha a RESTORE utasításban nem adunk meg sorszámot, a számítógép ezt úgy tekinti, mintha a program első sorának számát írtuk volna be.)
Próbáljuk ki a következő programot:

10 READ a,b
20 PRINT a,b
30 RESTORE 10
40 READ x,y,z
50 PRINT x,y,z
60 DATA 1,2,3
70 STOP

ebben a programban a 10-es sor által kért adatoknak megfelelően a=1 és b=2 lesz. A RESTORE 10 után lehetővé válik, hogy az x, y és z változók értéke a DATA utasítás elejéről kezdve beolvasható legyen. Futtassuk a programot a 50-as sor kihagyásával is, és nézzük meg, hogy mi történik.

Kifejezések

Már eddig is láttunk néhány példát arra, hogyan végez műveleteket számokkal a ZX Spectrum. Végre tudja hajtani a négy számtani alapműveletet (ne feledjük, hogy a szorzás jele a csillag, (*; míg az osztásé a ferde vonal (/), és egy változónak meg tudja határozni az értékét, ha megadjuk a változó nevét.
A következő példa azt a fontos tényt is érinti, hogy ezek a műveletek kombináltan is használhatók

LET ado=osszeg*15/100

Az ilyen kombinációt, mint az osszeg*15/100 kifejezésnek nevezzük: így a kifejezés olyan tömör megadási mód, amely a számítógépet több számítás egymás utáni elvégzésére utasítja. Példánkban az összeg*15/l00 kifejezés jelentése a következő: keresd meg az "osszeg" nevű változó értékét, szorozd meg 15-tel, az eredményt oszd el 100-zal.
Aki nem olvasta el a ZX Spectrum Bevezető füzetet, annak azt ajánljuk, hogy nézze át abban, hogyan kezeli a ZX Spectrum a számokat, valamint hogyan értékeli ki a matematikai kifejezéseket.

Emlékeztető:
Először a szorzások és az osztások kerülnek sorra; ezek nagyobb prioritású műveletek, mint az összeadás és a kivonás. A szorzás és az osztás egymáshoz viszonyítva azonos prioritású, ami azt jelenti, hogy ezeket a számítógép sorban, balról jobbra haladva hajtja végre. Ha ez kész, maradnak az összeadások és a kivonások, amelyek újra azonos prioritásúak, így ugyancsak balról jobbra haladva kerülnek sorra.
Most már csak azt kell tudni, hogy két művelet közül melyik a nagyobb prioritású. A számítógép ezt a műveletekhez rendelt, a prioritást jelző 1 és 16 közé eső szám alapján dönti el: a szorzás és az osztás prioritása 8, az összeadás és a kivonás prioritása 6. (A teljes listát a C. függelék tartalmazza).
Ezt a kötött számítási rendet csak zárójelek használatival változtathatjuk meg: először mindig a zárójelben lévő műveleteket hajtja végre a számítógép, majd az eredményt számként kezeli.

A kifejezések nagyon hasznosak lehetnek, ugyanis valahányszor a számítógép számot vár, ehelyett egy kifejezés is megadható, és a gép majd elvégzi a kijelölt műveleteket. E szabály alól csak nagyon kevés kivétel van, ezeket az adott helyen meg fogjuk említeni.
Egy kifejezésben tetszőleges számú stringet összeadhattunk, és zárójeleket is használhatunk.
Nos, nézzük me g , hogy a változóknak milyen neveket adhatunk. Már láttuk, hogy egy stringváltozó neve egyetlen betű és az azt követő $ jel lehet; egy FOR - NEXT ciklus cikl usváltozójának nevét pedig csak egyetlen betűvel jelelhetjük; az egyszerű aritmetikai változók neveinél viszont sokkal szabadabban járhatunk el. Bármilyen betűt vagy számot tartalmazhatnak, az egyetlen megkötés az, hogy az első helyen egy betű szerepeljen. Betűközt is használhatunk a könnyebb megértés érdekében, de ez nem lesz a név része. Ugyanígy semmi különbség sincs, ha kis vagy nagybetűt használunk.
Íme néhány példa változónevekre:

x
t42
ez a nev nagyon hosszu de azert a szamitogep elfogadja valtozonevnek
hatan vagyunk
hATANvaGYUnK

(A két utolsó név azonosnak számit, így ugyanarra a változóra vonatkozik.)
A következők nem lehetnek változónevek:

2001 (számmal kezdődik)
3 medve (számmal kezdődik)
M*A*S*H (a csillag nem betű vagy szám)
Fotherington-Thomas (a kötőjel nem betű vagy szám)

A numerikus kifejezéseket megadhatjuk exponenciális alakban is (lásd Bevezető füzet). Próbáljuk ki a következőket:

PRINT 2.34e0
PRINT 2.34e1
PRINT 2.34e2
...
PRINT 2.34e15

Látni fogjuk, hogy egy idő után a számítógép is áttér erre az ábrázolásra, mivel egy szám megjelenítésére 14 hely áll rendelkezésre. A fentiekhez hasonlóan próbáljuk ki a következőket is:

PRINT 2.34e-1
PRINT 2.34e-2
...

A PRINT a számok nyolc magasabb helyértékű jegyét adja csak meg. Írjuk be:

PRINT 4294967295, 4294967295-429e7

Ebből láthatjuk, hogy a számítógép a 4294967295 valamennyi számjegyét megőrzi, jóllehet az egyszerre való megjelenítése nem lehetséges.
A ZX Spectrum ún. lebegőpontos aritmetikát használ, azaz külön tárolja a számok jegyeit (mantissza) és a tizedespont pozícióját (exponens). Ez nem mindíg pontos, még egész számoknál sem. például:

PRINT 1e10+1-1e10,1e10-1e10+1

A számok kb. 9 és fél számjegy pontossággal tárolódnak, így az 1e10 túl nagy ahhoz, hogy pontosan tároljuk. A pontatlanság nagyobb mint 1 (jelen esetben kb. 2), így az 1e10 és az 1e10+1 a számítógép számára egyenlő.
Egy még jellemzőbb példa:

PRINT 5e9+1-5e9

Itt az 5e9 pontossága 1 körüli, és a hozzáadandó 1 valójában 2-re kerekítődik. Az 5e9+1 és az 5e9+2 számok a számítógép számára azonosak.
A legnagyobb egész szám, amely teljes pontossággal kezelhető 32 db 2-es egymással vett szorzata mínusz 1 (azaz 4 294 967 295)

A karakter nélküli "" szimbólumot üres vagy null-string-nek nevezzük. Vigyázzunk a betűközre: egy üres string nem azonos a semmi mást, csak betűközöket tartalmazóval. Próbáljuk ki a következőt:

PRINT "Olvastad-e az "Egri Csillagokat"?"

Ha megnyomjuk az ENTER gombot, villogó kérdőjel jelzi, hogy a sorban valahol hiba van. Amikor a számítógép eljut az "Egri csillagok" elején lévő idézőjelig, úgy veszi, hogy ez az "Olvastad-e az" karaktersorozat végét jelzi, és az "Egri csillagokat" részt már nem tudja értelmezni. Ha egy karaktersorozat közepén idézőjelet szeretnénk kitenni, azt kétszer kell beírnunk:

PRINT "Olvastad-e az ""Egri Csillagokat""?"

Amint látjuk, a képernyőn a megkettőzött idézőjelek csak egyszeresen jelennek meg, a párjuk csak a felismerésükhöz kellett.

Stringek (karaktersorozatok)

Részstringek képzése a TO segítségiével. (Ez a kulcsszó nem szabványos a BASIC-ben.) Egy adott string részstringjének nevezzük azt a karaktersorozatot, amely az eredeti síring egy vagy több, egymást az eredeti sorrendben követő karakteréből áll. Így a "lánc" az "Eszterlánc" részstringje, de az "E lánc" vagy az "Ez lánc" már nem.
A részstringek előállításának műveletét részstring-képzésnek nevezzük. Ez a művelet tetszőleges string-kifejezésen elvégezhető. A művelet alakja a következő:

string-kifejezés (kezdet TO vég)

Például:

"abcdef"(2 TO 5)="bcde"

Ha a "kezdet" megadását elhagyjuk, a számítógép ennek értékét 1-nek veszi; ha a "vég" értékét nem adjuk meg, akkor ez az érték a string teljes hossza lesz. Tehát:

"abcdef" ( TO 5) = "abcdef" (1 TO 5) = "abcde"
"abcdef" (2 TO ) = "abcdef" (2 To 6) = "bcdef"
"abcdef" ( TO ) = "abcdef" (1 TO 6) = "abcdef"

Az utols ó t így is írhattuk volna:

"abcdef" ()

Más a helyzet, ha a TO marad el, és csak egy számot írunk:

"abcdef" (3) = "c"

Szabály, hogy a "kezdet" és a "vég" megadásában a karaktersorozat létező részére kell hivatkozni, kivétel: ha a "kezdet" nagyobb, mint a "vég", ekkor az eredmény egy: üres string. Tehát az

"abcdef" (5 TO 7)

hatására a 3 subscript wrong (helytelen index) hibaüzenet jelenik meg, mivel a string csak 6 karakterből áll; de

"abcdef" (8 TO 7)=""

illetve

"abcdef" (1 To 0)=""

A "kezdet" és a "vég" nem lehet negatív, ha az, a B integer out of range hibaüzenetet kapjuk.
A következő program a fenti szabályokat illusztrálja:

10 LET a$"abcdef"
20 FOR n=1 TO 6
30 PRINT a$(n TO 6)
40 NEXT n
50 STOP

A NEW parancs után írjuk be a következő programot is:

10 LET a$="MEGTETTEM!"
20 FOR n=1 TO 10
30 PRINT a$(n TO 10),a$((10-n) TO 10)
40 NEXT n
50 STOP

A stringváltozókbál nem csak kihasíthatunk részstringeket, hanem be is toldhatunk. Például:

LET a$="Ez a ZX Spectrum"
LET a$(5 TO 8)="******"
PRINT a$

Ha a fenti három sort egymás után beírjuk, láthatjuk, hogy csak az első négy csillag került fölhasználásra, mivel az a$(5 TO 8) részstring csak négy karakter hosszúságú. Ez a részstringek betoldásánál mindig igaz: a részstring a betoldás után megadott hosszát megtartja. Ennek biztosítására, ha a betoldandó részstring túl hosszú, jobbról megfelelő számú karaktert levág a számítógép, míg ha túl rövid, betűközökkel tölti ki. Ezt az eljárást Prokrusztész illesztésnek nevezzük. (Prokrusztész ókori görög vendégfogadás volt, aki minden vendégét ugyanabba az ágyba fektette, s aki hosszabb volt, mint az ágy, annak tagjaiból levágott annyit, hogy éppen elférjen az ágyban; aki kisebb termetű volt, azt pedig kínpadon nyújtotta)
Írjuk be:

LET a$()="Hello"

majd

PRINT a$;"!"

Látjuk, hogy ugyanaz történt újra (ezúttal betűközök kerültek be), mivel az a$() részstringnek számít. A helyes megoldás a következő:

LET a$="Hello!"

Összetett string-kifejezéseknél a kihasítás előtt zárójeleket is használnunk kell. Például:

"abc"+"def"(1 TO 2)="abcde"
("abc"+"def")(1 TO 2)="ab"

Gyakorlat
Írjunk olyan programot, amely a hét napjait írja ki egy string kihasításával! (A string legyen a következő: HeKeddSzerCsutPeSzomVas)

Függvények

Képzeljünk el egy kolbásztöltő gépet: az egyik végén beadunk egy darab húst, megforgatjuk a kereket, és a másik végén kijön a kolbász. Sertéshúsból sertéskolbász, marhahúsból marhakolbász lesz stb.
A függvények hasonlóak a kolbásztöltő géphez. A különbség annyi, hogy nem hússal, hanem számokkal és stringekkel dolgoznak.Bbeadunk egy értéket (elnevezése független változó vagy argumentum), néhány művelet következik ezen, és végül egy másik értéket kapunk, a függvényértéket.

hús be kolbásztöltő kolbász ki
független változó be függvény függvényérték ki

Különböző független változókhoz különböző függvényértékek tartoznak; és ha a független változó nem megfelelő, a függvény leáll és hibaüzenetet ad. Ahogy különböző termékek előállításához különböző gépeket használunk, különböző függvények különböző műveleteket hajtanak végre. Adott független változóhoz különböző függvényeknél különböző érték tartozik.
Kifejezésekben a függvényt úgy használjuk, hogy beírjuk a nevét, majd ezt követően a független változót, és amikor a kifejezést kiértékeli a számítógép, a függvényértéket is kiszámítja.
Példaként vegyük a LEN nevű függvényt, amely egy sring hosszát számítja ki. Független változója az a karaktersorozat, amelynek hosszát meg akarjuk tudni, a függvényérték pedig a hossz. Tehát a

PRINT LEN "Sinclair"

hatására a számítógép kiírja a választ, ami 8,vagyis a "Sinclair" szóban lévő betűk száma. (A LEN a legtöbb függvénynévhez hasonlóan a kiterjesztett üzemmódban található: a CAPS SHIFT és a SYMBOL SHIFT egyidejű lenyomására a kurzor L-ről E-re vált, és ekkor a LEN a K gomb megnyomásával írható be.)
Ha ugyanabban a kifejezésben függvények és műveletek is szerepelnek, a függvények végrehajtása történik előbb, de természetesen zárójelek használatával ez a sorrend megváltoztatható. A következő két kifejezés például csak a zárójelekben különbözik egymástól, de a kiértékelés teljesen különböző sorrendben történik (a két esetben a végeredmény ezúttal azonos):

LEN "Kovacs" + LEN "Peti"
LEN ("Kovacs" + "Peti")
6 + LEN "Peti"
LEN ("KovacsPeti")
6 + 4
LEN "KovacsPeti"
10
10

Az alábbiakban néhány további függvényt ismertetünk.

Az STR$ számokat alakít stringekké, független változója egy szám, a függvényérték pedig az a karaktersorozat, amely akkor jelenne meg a képernyőn, ha a számot a PRINT utasítással kiíratnánk. A függvény neve a $ jellel végződik annak jelzésére, hogy a függvényérték egy string. Például a

LET a$=STR$ 1e2

ugyanazt az eredményt adja, mintha ezt

LET a$="100"

Egy másik példa:

PRINT LEN STR$ 100.0000

Az eredmény 3, mivel STR$ 100.0000 = "100".

A VAL az előbbi függvény "fordítottját" végzi: stringeket alakít számértékké. Például:

VAL "3.5" = 3.5

Csak az egyik irányban igaz az inverz funkció: egy számra alkalmazva az STR$ függvényt, majd a függvényértékre a VAL függvényt, visszakapjuk az eredeti számot. Ha viszont egy karaktersorozatra a VAL függvényt, alkalmazzuk, majd a függvényértékre az STR$ függvényt, a végeredmény nem mindig az eredeti karaktersorozat.
A VAL nagyon hatékony függvény, mivel a független vál tozóként megadott stringnek nem feltétlenül kell egyszerű számnak lenni, hanem tetszőleges aritmetikai kifejezés is lehet. Például

VAL "2*3" = 6

vagy akár

VAL ("2"+"*3") = 6

Itt két eljárás történik: először a VAL argumentumát mint karaktersorozatot értékeli ki a számítógép: a "2"+"*3" stringkifejezés kiértékelésének eredménye a "2*3" karaktersorozat. Ezután a karaktersorozatról leválasztja az idézőjeleket, és ami marad, azt számként értékeli ki: így a 2*3 kiértékelésének eredménye 6.
A fentiekre alaposan oda kell figyelni, mert könnyen tévedhetünk. Például:

PRINT VAL "VAL""VAL""""2"""""""

(Ne feledjük, hogy egy stringen belül az idézőjelet kétszer kell kitenni. Ha egyre beljebb jutunk a stringben, négyszeres vagy akár nyolcszoros idézőjelre is szükség lehet.)

A VAL függvényhez hasonló, talán nem annyira elterjedten alkalmazható a VAL$ függvény. Argumentuma szintén string, és a függvényértéke is az. Emlékezzünk, hogyan is működik a VAL: először az argumentumot mint karaktersorozatot kiértékeli a gép, majd a második lépésben elhagyja az idézőjeleket, és ami így marad, azt számként értékeli ki. A VAL$ esetében az első lépés megegyezik az előzővel, de a második lépésben az idézőjelek elhagyása után maradó rész ugyancsak stringként lesz kiértékelve. Tehát

VAL$"""Citrancs""" = "Citrancs"

(Figyeljük meg itt is az idézőjelek számát!) írjuk be:

LET a$="99"

majd í rassuk ki a következőket: VAL a$ , VAL "a$", VAL """a$""", VAL$ a$, VAL$ "a$" és VAL$ """a$"""
Ezek közül nem mindegyik fog működni: próbáljuk meg értelmezni az eredményeket.

Az SGN az előjel függvény. Az eddig megismert függvények közül az első, amely a stringeket nem tudja kezelni, ugyanis mind a független változója, mind a függvényértéke szám. Az eredmény +1, ha a független változó pozitív; 0 a függvény értéke, ha az argumentum zérus; és -1, ha az argumentum negatív.

Az ABS függvény argumentuma és függvényértéke szintén szám. Ez a függvény a független változót pozitív számmá alakítja (ez a függvényérték), azaz elhagyja az előjelet. Például:

ABS -3.2 = ABS 3.2 = 3.2

Az INT az egészrész függvény, amely törtszámot alakít (pozitív vagy negatív) egész számmá a törtrész elhagyásával. Például:

INT 3.9 = 3

Negatív független változó esetében figyelni kell arra, hogy az INT függvény mindig lefelé kerekít, azaz

INT -3.9 = -4

Az SQR függvény egy azám négyzetgyökét számítja ki: a függvényérték önmagával vett szorzata a független változót adja vissza. Például:

SQR 4 = 2   - mivel 2*2=4
SQR 0.25 = 0.5   - mivel 0.5*0.5=0.25
SQR 2 = 1.4142136   - (nem pontosan), mivel 1.4142136*1.4142136=2.0000001

Bármely szám önmagával vett szorzata pozitív, így negatív számnak nincs négyzetgyöke. Ha az SQR függvény után negatív független változót írunk, az A Invalid Argumentum (érvénytelen argumentum) hibaüzenetet írja ki a számítógép.

A felhasználó is definiálhat függvényeket. Az ilyen függvények neveinek megadása a következőképpen történik: az FN kulcsszót egy betű követi (ha a függvényérték szám) illetve az FN után egy betű és a $ jel áll (ha a függvényérték string). A zárójelek használata itt szigorúbb: az argumentumot mindig zárójelek közé kell tenni.
A programban egy függvény definiálása a DEF utasítással történik. Például a következő sor az FN s függvény definícióját adja (ez a függvény a független változó négyzetét adja eredményül):

10 DEF FN s(x)=x*x: REM x negyzete

A DEF a kiterjesztett üzemmódban SYMBOL SHIFT és 1. Ennek beírására a számítógép automatikusan kiírja az FN-t is, mivel egy DEF utasításban a DEF-et mindig azonnal követi az FN. Ezután az s teszi teljessé a függvény FN s nevét.
A zárójelben lévő x olyan név, amellyel a függvény argumentumára fogunk hivatkozni. Itt bármelyik betű használható (mindig csak egy, ill. ha a függvény argumentuma string, a betű után a $ jel következik).
Az = jel után a függvény tényleges definíciója következik. Ez tetszőleges kifejezés lehet, és a megadott névvel (ebben az esetben x) az argumentulmra is hivatkozhat, mintha az egy egyszerű változó lenne.
A fenti sor beírása után erre a függvényre ügy hivatkozhatunk mint a számítógép saját függvényeire, beírva a nevét (FN s) és ezt követően az argumentumot. Ne feledjük, hogy az ilymódon definiált függvényeknél az argumentumot zárójelek közé kell tenni. Próbáljunk ki néhány példát:

PRINT FN s(2)
PRINT FN s(3+4)
PRINT 1+INT FN s(LEN "csirke"/2+3)

ha a programban elhelyezünk egy megfelelő DEF utasítást, a saját függvényeket kifejezésekben ugyanolyan szabadon Használhatjuk, mint a számítógép függvényeit.
Megjegyzés: néhány BASIC változatban a számítógép függvényeinél is zárójelbe kell tenni az argumentumot. Mint láttuk, a ZX Spectrum BASIC nem ilyen.

Az INT függvény mindig lefelé kerekít. A legközelebbi egész számra való kerekítés 0.5 előzetes hozzáadásával érhető el. Erre egy saját függvényt definiálhatunk:

20 DEF FN r(x)=INT (x+0.5): REM x erteket a legkozelebbi egesz szamra kerekiti

ezután próbáljuk ki a függvényt néhány értéknél, például:

FN r(2.9) = 3
FN r(-2.9) = -3
FN r(2.4) = 2
FN r(-2.4) = -2

Hasonlítsuk ezt össze azokkal az eredményekkel, amelyeket az FN r helyett az INT függvényre kapnánk!
Írjuk be és futtassuk a következő programot:

10 LET x=0: LET y=0: LET a=10
20 DEF FN p(x,y)=a+x*y
30 DEF FN q()=a+x*y
40 PRINT FN p(2,3),FN q()

Több lényeges dologra kell rámutatnunk ebben a programban:

  1. Egy függvénynek nem csak egy független változója lehet. Lehet több is; de a zárójeleket akkor is ki kell tenni, ha egy sincs.
  2. Teljesen mindegy, hogy a programban hol szerepelnek a DEF utasítások. A számítógép a 10 -es sor végrehajtása után egyszerűen kihagyja a 20-as és 30-as sorokat, és a 40-es sorra lép. A DFF utasításoknak azonban mindig valahol a programban kell lenniük, nem szerepelhetnek parancsban.
  3. Az x és az y egyrészt a teljes programban lévő változók nevei, másrészt az FN p függvény független változóinak nevei is. Az FN p ideiglenesen nem törődik az x és y nevű változókkal, viszont mivel a nevű független változónév nincs a függvényben, az a változót megtartja. Így amikor az FN p(2,3) függvényt kiértékeli, az a értéke 10 , mivel ez változó, az x értéke 2, mivel ez az első független változó, az y értéke pedig 3, mivel ez a második független változó. A függvény értéke tehát 10+2*3=16.
    Amikor viszont az FN q() függvényt értékeli ki a számítógép, mivel független változó nincs, az a, x és y mind változónévként szerepel, és értékeik sorban 10, 0 és 0. Az eredmény ebben az esetben 10+0*0=10

Cseréljük ki a 20-as sort:

20 DEF FN p(x,y) = FN q()

Ekkor az FN p(2,3) függvény értéke 10 lesz, mivel az FN q még mindig az x és y változókra utal, és nem az FN p független változóit kell használni.

Néhány BASIC változat (a ZX Spectrum nem ilyen) a következő függvényeket is tartalmazza: LEFT$, RIGHT$, MID$ és TL$.
A LEFT$ (a$,n) az a$ azon részstringjét adja meg, amely az első n karakterből áll.
A RIGHT$ (a$,n) az a$ azon részstringjét adja meg, amely az n-edik karaktertől kezdődő karakterekből áll.
A MID$ (a$,n1,n2) az a$ azon részstringjét adja meg, amely n2 karakterből áll és az n1-ediktől kezdődik.
A TL$ (a$) az a$ azon részstringjét adja meg, amely az első kivételével az összes karaktert tartalmazza.
Ezeket a függvényeket a felhasználó által definiált függvényekkel megvalósíthatjuk, például:

10 DEF FN t$(a$)=a$(2 TO ): REM TL$
20 DEF FN I$(a$,n)=a$( TO n): REM LEFT$

Vizsgáljuk meg, hogyan működnek ezek a függvények 0 és 1 hosszúságú stringekkel!
Figyeljük meg, hogy az FN I$ két független változót tartalmaz: az egyik szám, a másik viszont string. Egy függvénynek maximálisan 26 numerikus független változója és egyidejűleg maximálisan 26 string független változója lehet. (Gondoljuk meg, hogy miért pont 26!)

Gyakorlat
Az SQR függvény ellenőrzésére használjuk az FN s (x) = x*x függvényt! Azt találjuk, hogy

FN s(SQR x) = x

ha az x helyére tetszőleges pozitív számot írunk, és

SQR FN s(x) = ABS x

ha az x pozitív és negatív is lehet. (Miért ABS x ?)

Matematikai függvények

Ez a fejezet a ZX Spectrumban használható matematikai függvényeket ismerteti. Lehet, hogy ezek használatára sohasem lesz szükségünk, így ha ezt a részt túl nehéznek találjuk, ki is hagyhatjuk. Szó lesz a hatványozásról (^ jel), az EXP és LN függvényről, a SIN, COS, TAN trigonometrikus függvényekről és ezek inverzeiről (ASN, ACS és ATN).

^ és EXP
Egy számot egy másik számmal jelzett hatványra emelhetünk: ez azt jelenti, hogy az első számot önmagával annyiszor kell megszorozni, ahányszor a második szám mutatja. Ezt általában úgy jelöljük, hogy a második számot az első fölé kissé jobbra írjuk. Ez a jelölés a számítógépeknél nehézkes lenne, így helyette a ^ jelet használjuk. Például 2 néhány hatványát jelentik a következő kifejezések:

2^1 = 2  
2^2 = 2*2 = 4 (2 négyzete)
2^3 = 2*2*2 = 8 (2 köbe)
2^4 = 2*2*2*2 = 16 (2 negyedik hatványa)

Első közelítésben azt mondhatjuk, hogy az "a^b" jelentése a következő: az "a" szám önmagával vett szorzata "b"-szer. Ennek nyilván csak akkor van értelme, ha "b" pozitív egész szám. A "b" szám más értékeinél is érvényes definícióhoz fontoljuk meg a következő szabályt:

a^(b+c) = a^b * a^c

(Figyeljük meg, hogy a hatványozás nagyobb prioritású, mint a szorzás vagy az osztás, így ha egy kifejezésben több művelet szerepel, a hatványozások a szorzás és az osztás előtt kerülnek sorra.) Könnyen belátható, hogy a fenti egyenlet igaz, ha "b" és "c" pozitív egész számok. Ha más értékekre is ki akarjuk terjeszteni érvényességét, el kell fogadnunk az alábbi definíciókat:

a^0 = 1
a^(-b) = 1/a^b
a^(1/b) = az "a" szám "b"-edik gyöke, tehát az a szám, amelyet önmagával b-szer megszorozva az "a" számot adja eredményül
a^(b*c) = (a^b)^c

Ha eddig ezekkel a szabályokkal még nem találkoztunk, elegendő megjegyezni a következőket:

a^(-1) = 1/a
a^(1/2) = SQR a

Ha ezeket megértjük, a többi is könnyebben érthetővé válik. A fentiek gyakorlására próbáljuk ki a következő programot:

10 INPUT a,b,c
20 PRINT a^(b+c), a^b*a^c
30 GO TO 10

Ha a korábban ismertetett szabály igaz, a számítógép által kiírt két számnak mindig egyenlőnek kell lenni. (Megjegyzés: a hatványozás műveletének elvégzési módja miatt a ^ jel bal oldalán álló szám - jelen esetben az "a" szám - nem lehet negatív.)
A hatványfüggvény alkalmazására jellemző példa a kamatos kamat számítás. Tegyük fel, hogy valaki a pénzét olyan vállalkozásba fekteti, amelyik évi 15%-os kamatot fizet. Egy év múlva nem csak a pénz 100%-ával rendelkezik, hanem további 15%-kal is, amit kamatként kap, azaz összesen az eredeti összeg 115%-a az övé. Másképp kifejezve összegét 1.15-tel megszorozta. Egy további év múlva ugyanez lesz a helyzet, vagyis 1.15*1.15 = 1.15^2 = 1.3225-szeresére növekedett az eredeti összeg. Általánosan: y év múlva 1.15^y-szeresére növekszik az induló összeg. Írjuk be a következő parancsot:

FOR y=0 to 100: PRINT y,1000*1.15^y: NEXT y

Látjuk, hogy bár kicsi, 1000 forint az indulási összeg, az évenkénti összeg elég gyorsan növekszik, sőt a növekedés az idő múlásával egyre gyorsabb. Ezt a jellemzőt, amikor egy adott időtartam után egy mennyiséget egy adott hányaddal meg kell szorozni, exponenciális növekedésnek nevezzük, és kiszámítása úgy történik, hogy az adott számot az idő hatványára emeljük.
Írjuk be a következőt:

10 DEF FN a(x) = a^x

Itt az a mennyiség többé-kevésbé fix érték (a LET utasítással állítjuk be): ennek értéke a kamat.
Van az a-nak egy olyan értéke, amely az FN a függvényt a matematikusok számára kitüntetetté teszi: ezt az értéket "e"-nek nevezzük. A ZX Spectrum egyik függvényét (EXP) a következő definíció adja meg:

EXP x = e^x

Az "e" irracionális szám, pontosan nem írható le az értéke (csak végtelen, ismétlődő szakaszokat nem tartalmazó tizedestörtként). Első néhány tizedesjegyét a következőképpen nézhetjük meg:

PRINT EXP 1

hiszen EXP 1 = e^1 = e. Természetesen a kiírt szám csak közelítő érték.

LN
Az exponenciális függvény inverze a logaritmus függvény: az " x" szám "a" alapú logaritmusa egy olyan kitevő, amelyre az "a" -t kell emelni, hogy az " x " számot kapjuk. Jelölése:

loga x

A fenti definíció szerint a loga x = x; valamint az is igaz, hogy loga(a^x)= x.
Bizonyára találkoztunk már a tízes alapú (közönséges) logaritmussal, amely szorzások elvégzésére használható. A ZX Spectrum az LN függvényt tartalmazza, amely az "e"-alapú logaritmusokat számolja ki, és ezeket természetes logaritmusoknak nevezzük. Más alapú logaritmusok az LN segítségével úgy kaphatók meg, hogy a természetes logaritmust osztjuk az alap természetes logaritmusával:

loga x = LN x/LN a

PI
Bármely kör kerületét úgy kapjuk, hogy átmérőjét szorozzuk PI-nek nevezett számmal. A PI a görög p betű, és a periméter (kerület) szó rövidítéseként használjuk. A PI az "e"-hez hasonlóan irracionális szám, bizonyos pontossággal értéke a következő: 3.141592653589... A ZX Spectrumban ezt az értéket a PI képviseli (a kiterjesztett üzemmódban M). Próbáljuk ki; írjuk be: PRINT PI.

SIN, COS és TAN; ASN, ACS és ATN
A trigonometrikus függvények azt jelzik, hogy mi történik, ha egy pont egy kör mentén mozog. Vegyünk egy egységnyi sugarú kört (a mértékegység bármi lehet, a lényeg az, hogy azt a vizsgálat során végig megtartsuk), és egy pontot, amely a kör kerületén mozog! A pont induljon a 3 óra pozícióból, és az óramutató járásával ellentétes irányba haladjon! Két vonalat is berajzolhatunk, amelyek a kör középpontján haladnak át és ezeket tengelyeknek nevezzük. A 3 és 9 órán áthaladó az x-tengely, a 6 és 12 órán áthaladó az y-tengely (lásd az ábrán).

A pont helyzetét meghatározhatjuk azzal a távolsággal, amelyet a kör mentén a 3 óra kiinduló helyzettől megtett: legyen ez "a". Tudjuk, hogy a kör kerülete 2*PI (mivel sugara 1, így átmérője 2 egység); így ha a pont egy negyed kört megtesz, akkor a=PI/2, félkörnyi út esetén a=PI, míg egy teljes kör megtételénél a = 2PI.
A köríven megtett "a" út ismeretében két további távolság is meghatározható: a pont távolsága az y-tengelytől ill. az x-tengelytől. Ezeknek a távolságoknak az értékét az "a" koszinuszának ill. szinuszának nevezzük. A COS és a SIN függvények éppen ezt számítják ki.
Figyeljük meg, hogy ha a pont az y-tengely bal oldalára kerül, a koszinusz negatív lesz; míg ha a pont az x-tengely alá kerül, a szinusz válik negatívvá.

Egy további jellemző, hogy ha az "a" eléri a 2PI-t, vagyis amikor visszajut kiinduló helyzetébe, a szinusz és a koszinusz újra kiindulási értékeiket veszik fel:

SIN (a+2*PI) = SIN a
COS (a+2*PI) = COS a

Az "a" tangense definíció szerint a szinusz és a koszinusz hányadosa; az ennek megfelelő függvény neve TAN.
Szükségünk lehet e függvények inverzére is, azaz annak az "a" értéknek a megkeresésére, amelynek szinusza, koszinusza vagy tangense adott. E függvények nevei: arkusz-szinusz (a számítógépen ASN), arkusz-koszinusz (ACS) és arkusz-tangens (ATN).

A körív mentén mozgó pontot bemutató ábrán tekintsük most a pontot a kör középpontjával összekötő sugarat! Láthatjuk, hogy "a"-nak nevezett távolság (a körív mentén a pont által megtett távolság) tulajdonképpen a sugár által az x -tengelytől megtett szöget is méri. Ha a=2PI , a szög 360°; ha a= PI /2, a szög 90°; ha a=PI, a szög 180°. Felejtsük el most a fokokat, és a szöget mérjük az "a" távolsággal! Ekkor azt mondjuk, hogy a szöget radiánban mérjük. Így PI/2 radian = 90° stb.
Mindig figyeljünk arra, hogy a ZX Spectrum SIN, COS stb. függvényei a fokok helyett radiánt használnak! A fokokban megadott szögeket radiánra a következőképpen Számítjuk át: osztunk 180-nal, majd szorzunk PI-vel. Radiánból fokokba számítás: osztás PI-vel, majd szorzás 180-nal.

Véletlenszámok

Ez a fejezet az RND függvénnyel és a RANDOMIZE kulcsszóval foglalkozik. Mindkettő a véletlenszámokkal kapcsolatos, így megkülönböztetésükre vigyázzunk. Mindkettő ugyanazon a gombon található (T); a RANDOMIZEE, rövidítése RAND.
Az RND bizonyos értelemben függvény: számításokat végez, és eredményt ad. Abban különbözik a függvényektől, hogy független változója nincs (ill. van, de azt a gép adja). Valahányszor használjuk, mindig egy új, 0 és 1 közé eső véletlenszámot ad (a 0 értéket felveheti, az 1-et nem). Az RND működését a következő programmal nézhetjük meg:

10 PRINT RND
20 GO TO 10

Az egymás utáni megjelenő számokban semmi szabályosságot sem fedezhetünk fel: a "véletlen" elnevezés éppen erre utál.
Valójában az RND nem igazi véletlenszámot ad, mivel 65536 számból válogat alkalmas rendszer szerint. Azonban ezek a számok annyira össze vannak keverve, hogy végül is szabályosságot nehezen fedezhetünk fel bennük, így azt mondhatjuk, hogy az RND álvéletlen számokat ad.
Az RND 0 és 1 közötti véletlenszámot ad, de könnyen kaphatunk más tartományba esőt is. Például az 5*RND 0 és 5 közötti, míg az 1.3+0.7*RND 1.3 és 2 közötti számot ad. Ha egész számra van szükség, az INT függvényt használhatjuk (ne feledjük, hogy az INT mindig lefelé kerekít); például az itt következő kockadobó programban az 1+INT(RND*6) kifejezést használjuk. Az RND*6 0 és 6 közötti számot ad, de mivel 6 nem lehet, az INT(RND*6) 0, 1, 2, 3, 4 vagy 5 lehet. A program a következő:

10 REM kockadobo program
20 CLS
30 FOR n=1 to 2
40 PRINT 1+INT (RND*6);" ";
50 NEXT n
60 INPUT a$: GO TO 20

Ha dobni akarunk, nyomjuk meg az ENTER gombot.
A RANDOMIZE utasítás segítségével megvalósítható, hogy az RND definiált helyről induljon. Ez a következő programból látható:

10 RANDOMIZE 1
20 FOR n=1 TO 5: PRINT RND,: NEXT n
30 PRINT GO TO 10

A RANDOMIZE 1 minden egyes végrehajtása után az RND sorozat induló értéke mindig 0.0022735596. A RANDOMIZE utasításban más, 1 és 65 535 közé eső számot is megadhatunk, így az RND sorozat ennek megfelelően más helyről indul.
Ha programban szerepel az RND, és a programban valami hiba van, amit nem tudunk megtalálni, segíthet a RANDOMIZE fenti módon való használata, mivel így a program minden egyes futtatásánál azonos módon fog viselkedni.
A RANDOMIZE szám nélkül (és ugyanígy a RANDOMIZE 0) másképp működik: ezután az RND valóban véletlenszerű lesz. Ezt a következő programban láthatjuk:

10 RANDOMIZE
20 PRINT RND: GO TO 10

Az ezzel kapott számsorozat nem igazán véletlenszerű, mivel a RANDOMIZE a számítógép bekapcsolásától eltelt időt használja. Mivel ez a RANDOMIZE egyes végrehajtásai között azonos mennyiséggel növekszik, a következő RND többé-kevésbé azonos értéket ad. Valóban véletlenszerű számokat kapunk, ha a GO TO 10 helyett a GO TO 20 utasítást írjuk.
Megjegyzés: a legtöbb BASIC változat az RND és a RANDOMIZE utasításokat használja a véletlenszámok előállítására, de nem mindig a fent leírt módon.
A következő program a pénzfeldobást valósítja meg, és számolja a fej ill. az írás gyakoriságát:

10 LET fej=0: LET iras=0
20 LET erem=INT (RND*2)
30 IF erem=0 THEN LET fej=fej+1
40 IF erem= 1 THEN LET iras=iras+1
50 PRINT fej;","iras,
60 IF iras<>0 THEN PRINT fej/iras
70 PRINT: GO TO 20

Elegendően sok dobás, után a fej/írás hányados közel lesz az 1 értékhez, mivel hosszabb idő után a fej és az írás esetek várható száma közelítőleg azonos lesz.

Gyakorlatok
1.
Ellenőrizzük a következő szabályt:
Vegyünk egy 1 és 872 közé eső számot, majd írjuk be:

RANDOMIZE "választott szám"

Az RND következő értéke ekkor ez lesz:

(75*(választott szám +1)-1)/65536

2. (csak matematikusok számára)
Legyen "p" egy (elég nagy) prímszám, míg "a" egy primitív-gyök modulo p. Ha ekkor b1 az a1 maradéka modulo p (1 <= bi <= p-1), akkor a

(bi-1) / (p-1)

sorozat a p-1 diszkrét számok sorozata a 0-1 intervallumban (az 1 kizárva). Az "a" értékét megfelelően választva ez a sorozat véletlenszerűnek látszik.
A 65 537 Fermat-féle prímszám (2^16+1). Mivel a nullától különböző maradékok modulo 65537 multiplikatív csoportjának rendje 2-nek valamilyen hatványa, a maradék akkor és csak akkor lesz primitív gyök, ha az egy kvadratikus maradék. A négyzetes reciprocitás Gauss-féle törvényével mutassuk ki, hogy 75 egy primitív gyök modulo 65 537.
A ZX Spectrumban p=65537, a=75, és a memóriában néhány bi-1 érték tárolódik. Az RND hatására a memóriában a bi-1 helyére bi+1-1 kerül, és az eredmény (bi+1-1)/(p-1) lesz.
A RANDOMIZE n (ahol 1<= n <= 65535) a bi értékét (n+1)-gyel teszi egyenlővé.
Az RND a 0-1 tartományban megközelítőleg egyenletes eloszlású.

Tömbök

(A ZX Spectrum a szokásostól eltérő módon kezeli a stringtömböket!)

DIM...
Tegyük fel, hogy számokból álló listánk van, amely például egy osztály tíz tanúlójának osztályzatait tartalmazza. Az adatok számítógépben való tárolására minden egyes tanuló számára külön változót definiálhatnánk, de ez a módszer elég kényelmetlen. Legyenek ezek a változók sorra Adatok 1, Adatok 2 stb., az utolsó Adatok 10. A változókat definiáló program azonban elég hosszú lenne, és fölöslegesen sok beírási munkát igényelne.
Sokkal egyszerűbb lenne, ha a következőket írhatnánk:

5 REM ez a program nem mukodik
10 FOR n=1 TO 10
20 READ adatok n
30 NEXT n
40 DATA 10,2,5,19,16,3,11,1,0,6

Ez azonban így nem megy.
Létezik azonban egy olyan eljárás, amelyben a fenti ötlet jól alkalmazható, és ez a tömbök használata (a vektorokat és a mátrixokat közös néven tömbnek nevezzük). Egy tömb azonos nevű változókból (elemekből) áll; a tömb elemeit a név után zárójelbe tett számmal (index) különböztetjük meg. Példánkban a név legyen "b" (hasonlóan a FOR - NEXT ciklusváltozójához egy mátrix neve is csak egyetlen betű lehet), így a tíz változó rendre a következő:
b(1), b(2), ..., b(10).

Egy tömb elemeit indexes változóknak nevezzük, szemben a már megismert egyszerű változókkal.
Mielőtt egy tömböt használhatnánk, a számítógépben helyet kell foglalni számára: ezt a DIM (a dimenzió rövidítése) utasítással hajtjuk végre. Például a

DIM b(10)

egy "b" nevű tömböt definiál, amelynek mérete 10 (azaz 10 indexes változó szerepel benne: b(1) , ... , b (10), és mind a tíz indexes változó értékét 0-ra állítja be. Ez az utasítás egyúttal törli az előzőleg már meglévő "b" nevű tömböt. (Az ilyen nevű egyszerű változót viszont nem törli, vagyis azonos néven egyidejűleg egy tömb és egy egyszerű numerikus változó is létezhet: a számítógép nem fogja összekeverni ezeket, mivel a tömbváltozó mindig indexet is tartalmaz.)
Az index tetszőleges numerikus kifejezés lehet, így a fenti probléma helyes megoldása a következő:

5 DIM b(10)
10 FOR n=1 TO 10
20 READ b(n)
30 NEXT n
40 DATA 10,2,5,19,16,3,11,1,0,6

Egynél több dimenziós tömböket (mátrixokat) is definiálhatunk. Egy kétdimenziós mátrixban bármelyik elem kijelöléséhez két számra van szükségünk - hasonlóan ahhoz, ahogy egy sor- és egy oszlopszám kell egy karakter helyzetének meghatározásához a TV képernyőn. Így a kétdimenziós mátrix olyan, mint egy táblázat. Ha a sor- és oszlopszámokat (két dimenzió) egy nyomtatott oldalra vonatkoztatva képzeljük el, akkor az oldalszámok számára egy újabb dimenziót kaphatunk. Természetesen numerikus tömbökről beszélünk, vagyis az elemek nem lehetnek nyomtatott karakterek mint egy könyvben, hanem csak számok. Gondoljunk a "v" háromdimenziós tömb elemeire, amelyet a "v" (oldalszám, sorszám, oszlopszám) határoz meg.
Például adjuk meg a "c" kétdimenziós tömböt 3 és 6 dimenzióméretekkel a DIM utasítás segítségével:

DIM c,(3,6)

Ez 3*6 = 18 indexes változót jelent:

C(1,1)
C(1,2)
C(1,3)
C(1,4)
C(1,5)
C(1,6)
C(2,1)
C(2,2)
C(2,3)
C(2,4)
C(2,5)
C(2,6)
C(3,1)
C(3,2)
C(3,3)
C(3,4)
C(3,5)
C(3,6)

Ugyanez az elv érvényes tetszőleges méret esetében is.

Bár egy egyszerű változó és egy tömb szerepelhet azonos néven, de két tömbnek már nem lehet azonos a neve, még akkor sem, ha méretük különbözik is egymástól.
Léteznek stringtömbök is. Egy tömböt alkotó stringek az egyszerű stringtől abban különböznek, hogy rögzített hosszúságúak, és megadásuk a stringeknél említett Prokrusztész eljárással történik (levágás illetve betűközzel feltöltés). A stringtömböt felfoghatjuk karakterekből álló tömbként is (amelynek egy további dimenziója van). A stringtömb neve egyetlen betűből és az ezt követő $ jelből állhat. Egy egyszerű stringváltozó és egy stringtömb, ellentétben a számokkal, nem lehet azonos nevű.
Tegyük fel, hogy egy 5 stringből álló a$ nevű tömböt akarunk definiálni. El kell azt is döntenünk, hogy a stringek milyen hosszúak legyenek: tegyük fel, hogy 10 karakter mindegyiknél elegendő. Ekkor a következőt kell beírnunk:

DIM a$(5,10)

Ez egy 5*10-es méretű stringtömböt határoz meg, de az egyes sorokat is felfoghatjuk stringként

a$(1)=a$(1,1), a$(1,2), ..., a$(1,10)
a$(2)=a$(2,1), a$(2,2), ..., a$(2,10)
...
a$(5)=a$(5,1), a$(5,2), ..., a$(5,10)

Ha ugyanannyi indexszámot (jelen esetben kettőt) adunk meg, mint amennyi a DIM utasításban lévő dimenziók száma, akkor egyetlen karaktert kapunk; de ha az utolsó indexszámot elhagyjuk, akkor egy fix hosszúságú stringet kapunk. Például: A$(2,7) az A$(2) string hetedik karaktere, amelyet a részstringképzésnél használt jelöléssel A$ (2) (7) alakban is felírhatunk.
Írjuk be a következőket:

LET a$(2)="1234567890"

majd

PRINT a$(2),a$(2,7)

Ekkor ezt kapjuk:

1234567890      7

Az utolsó indexre (amit elhagyhatunk) is alkalmazhatjuk a részstringképzés műveletét, például:

a$(2,4 TO 8)=a$(2)(4 TO 8)="45678"

Összefoglalva:
Egy stringtömbben minden string azonos, fix hosszúságú. A DIM utasításban egy további (az utolsó) szám adja meg ezt a hosszúságot. Ha egy stringtömbre vonatkozó indexes változót adunk meg, egy további számot is beírhatunk (a stringcsonkítás mértékét), amely a DIM utasításban lévő megfelelő kiegészítő számnak felel meg.
Léteznek dimenzió nélküli stringtömbök is. Például írjuk be:

DIM a$(10)

Az a$ stringváltozóként fog viselkedni azzal a különbséggel, hogy hossza mindig 10 lesz, és az értékadásnál mindig a prokrusztészi elv érvényesül.

Gyakorlat
Használjuk a READ és a DATA utasít á sokat a 12 stringből álló m$ , tömb létrehozásában, amelyben az m$ n az n-edik hónap neve. Legyen a DIM utasítás a következő: DIM m$ (12,10)). Ellenőrzésképpen írassuk ki az összes m$ n stringet (ehhez használjunk ciklust)!
Ezután írjuk be a következőt:

PRINT "Eljott a ";m$;"hava","A boldog legenyek dala"

Mit tehetünk a betűközökkel?

Feltételek

A 3. fejezetben láttuk, hogy az IF utasítás alakja a következő:

IF feltétel THEN ...

A "feltétel" itt valamelyik reláció (=, <, >, <= és >=), amely két számot vagy két stringet hasonlít össze. Ezek közül többet kombinálhatunk is, ha az AND (ÉS), OR (VAGY) vagy a NOT (NEM) logikai műveleteket is használjuk.

"Egy reláció AND egy másik reláció" akkor igaz, ha mindkét reláció igaz. Példaul:

IF a$="igen" AND x>0 THEN PRINT x

Ekkor az x csak akkor kerül kiíratásra, ha a$="igen" és x>0. (A BASIC itt szinte teljesen követi a mindennapi (angol) nyelv szabályait. Csakúgy, mint a beszélt nyelvben, a BASIC-ben is számos relációt összeköthetünk az AND segítségével, és ekkor az egész kijelentés akkor lesz igaz, ha az összes egyedi reláció igaz).

"Egy reláció OR egy másik reláció" akkor igaz, ha legalább az egyik reláció igaz. (Vegyük észre, hogy akkor is igaz, ha mindkét reláció igaz: ez a beszélt nyelvben nem mindig van így.)

A NOT megfordítja a dolgokat. A "NOT reláció" akkor igaz, ha a reláció hamis, és akkor hamis, ha a reláció igaz.

A relációk és az AND, OR és NOT felhasználásával logikai kifejezéseket hozhatunk létre hasonlóan ahhoz, ahogy a számokból és a +, - stb. műveletekből; valamint a zárójelek használata is megegyezik e két esetben. A végrehajtási sorrendet szabályozó prioritás a következő: a legkisebb prioritású az OR, ezután következik az AND majd a NOT, a relációk ezeknél nagyobb prioritásúak, majd ezután következnek a már megismert algebrai műveletek.
A NOT valójában függvény; hiszen argumentuma és függvényértéke van, de prioritása sokkal kisebb, mint a többi függvényé. Éppen ezért argumentumát nem kell zárójelbe tenni, hacsak nem tartalmaz AND vagy OR műveletet (vagy mindkettőt). A NOT (a=b) ugyanazt jelenti, mint a NOT a=b (természetesen az a<>b, is azonos jelentésű ezekkel).
A <> az = negáltja abban az értelemben, hogy akkor és csak akkor igaz, ha az = hamis. Más szavakkal

a<>b ugyanaz, mint a NOT a=b

illetve

NOT a<>b ugyanaz, minz az a=b

Győződjünk meg arról, hogy a <= illetve a >= rendre a > illetve a < negáltjával egyenlő: ezt felhasználva, a reláció kicserélésével megszabadulhatunk a relációk elején lévő NOT logikai művelettől. Tehát De Morgan tétele alapján

NOT (első logikai kifejezés AND egy második)

ugyanazt jelenti, mint a

NOT (első kifejezés) OR NOT (a második)

Ugyanígy igaz a következő is:

NOT (első logikai kifejezés OR egy második)

ugyanazt jelenti, mint a

NOT (első kifejezés) AND NOT (a második)

A fenti átalakítások felhasználásával elérhetjük, hogy végül a NOT ténylegesen relációkra vonatkozzék, majd ezután a korábban említett módon (más relációval kicserélve) a NOT elhagyható. Logikai értelemben tehát a NOT szükségtelen, bár a programot érthetőbbé teheti.
A következő rész már kissé bonyolultabb, így ha megértése nehezebben megy, kihagyhatjuk.
Írjuk be:

PRINT 1=2,1<>2

Erre szintaktikai hibát várnánk! Valójában azonban a számítógép számára logikai értékek nem léteznek, helyettük a következő szabályok szerint közönséges számokat használ.

  1. Az =, < , > , <=, >= és <> művelet eredménye mindig egy szám: 1 az eredmény, ha a reláció igaz, és 0, ha hamis. Így a fenti PRINT parancs hatására 0 íródik ki az "1=2" eredményeként (mivel ez a reláció nem igaz), és 1 íródik ki az "1<2" eredményeként (mivel ez igaz).
  2. Az
    IF feltétel THEN ...
    utasításban a "feltétel" tetszőleges numerikus kifejezés lehet. Ha ennek értéke 0, akkor ez hamisnak számít, míg minden más esetben (beleértve az igaz reláció eredményét, az 1-et is) igaznak számit. Ezek szerint az IF utasítás pontosan a következőt jelenti:
    IF feltétel<>0 THEN ...
  3. z AND, OR és NOT logikai műveletek szintén egy számot adnak eredményül:
x AND y értéke

x, ha y igaz (zérustól különböző)
0 (hamis), ha y hamis (zérus)

x OR y értéke

1 (igaz), ha y igaz (zérustól különböző)
x, ha y hamis (zérus)

NOT x értéke

0 (hamis), ha x igaz (zérustól különböző)
1 (igaz), ha x hamis (zérus)

(Vegyük észre, hogy az "igaz" jelentése "nem zérus" akkor, ha egy adott értéket vizsgálunk, míg jelentése "1", ha egy eredményt jelölünk.
Olvassuk el újra a fejezetet a fentiek figyelembe vételével, és győződjünk meg a megállapítások helyességéről!
Az x AND y, x OR y és NOT x kifejezésekben az x és y értéke az igaz és a hamis állításnak megfelelően 1 ill. 0. Képezzük a tíz lehetséges kombinációt (négy az AND, négy az OR és kettő a NOT esetében), és ellenőrizzük, hogy az eredmények megfelelnek a fejezetben leírtaknak!
Próbáljuk ki a következő programot:

10 INPUT a
20 INPUT b
30 PRINT (a AND a>=b)+(b AND a<b)
40 GO TO 10

A program az a és a b számok közül a nagyobbat fogja kiírni.
A logikai kifejezések működésének megjegyzését segítik az alábbi szabályok (érvényességükről győződjünk meg):

x AND y

értéle

x, ha y igaz (egyébként az eredmény 0)

illetve

x OR y

értéke

x, ha y nem igaz (egyébként az eredmény 1)

Az AND vagy OR logikai műveletet tartalmazó kifejezéseket feltételes kifejezéseknek nevezzük. A következd sor az OR használatára mutat példát:

LET fogy ar=ar min ado*(1.15 OR v$"adomentes")

String-értéket adó feltételes kifejezéseket is használhatunk, azzal a megkötéssel, hogy csak az AND művelet alkalmazható.

x$ AND y értéke

x$, ha y nem zérus
"" (üres string), ha y zérus

azaz az eredmény x$, ha y igaz (egyébként az eredmény üres string).
Próbáljuk ki a következő programot, amely két stringet olvas be, és ezeket ábécé sorrendben kiírja:

10 INPUT "Irj be ket stringet!" 'a$,b$
20 IF a$>b$ THEN LET c$=a$: LET a$=b$: LET b$=c$
30 PRINT a$;" ";("<" AND a$<b$)+("=" AND a$=b$);" ";b$
40 GO TO 10

Gyakorlat
A fejezetben utaltunk a BASIC és a beszélt nyelv "hasonlóságára". Ez nem mindig van így. Ennek illusztrálására vegyük a következő feltételt: "Ha "a" nem egyenlő "b"-vel vagy "c"-vel". Hogyan írnánk ezt BASIC nyelven? Vigyázzunk, a következő két megoldás például nem helyes:

IF a<>b OR c   illetve   IF a<>b OR a<>c

A karakterkészlet

Azokat a betűket, számjegyeket, írásjeleket stb., amelyek a stringekben szerepelhetnek, közös néven karaktereknek nevezzük, és ezek együttesen azt a karakterkészletet alkotják, amelyet a ZX Spectrum használ. E karakterek többsége egyetlen szimbólum, de van néhány összetett szimbólumnak nevezett jel is, amelyek akár teljes szavakat is megadhatnak (például PRINT, STOP, <> stb). Összesen 256 karakter létezik, és mindegyikhez egy 0 és 255 közé eső számkód tartozik. A karakterek felsorolását az A. függelékben találjuk. A kódok és karakterek közötti átalakítást két függvény, a CODE és a CHR$ végzi.
A CODE egy stringre alkalmazható, és a string első karakterének kódját adja meg (üres string esetében a függvény értéke 0).
A CHR$ argumentuma egy szám, és eredményül azt az egy karakteres stringet adja meg, amelynek kódja a kérdéses szám.
A következő program a teljes karakterkészletet kiírja:

10 FOR a=32 TO 255: PRINT CHR$ a;:NEXT a

A karakterkészletben, az elején lévő betűköz után, sorra a következő karaktereket láthatjuk: 15 szimbólum ill. írásjel, a 10 számjegy, hét újabb szimbólum, nagybetűk, hat további szimbólum, kisbetűk, végül öt szimbólum. Eze k együttesen £ a és a © jel kivételével) a széles körben alkalmazott ASCII karakterkészlet elemei (az ASCII az American Standard Codes for Information Interchange rövidítése). A ZX Spectrum is a karakterekhez rendelt ASCII számkódokat használja.
A fennmaradó karakterek nem tartoznak az ASCII karakterkészletbe, ezek kifejezetten a ZX Spectrumra jellemzőek. Ezek között található K grafikus szimbólumoknak nevezett 16 fekete-fehér minta, amelyek képek kirajzolására használhatók. Ezeket a billentyűzetről vihetjük be a grafikus üzemmódban. Ha egyidejűleg megnyomjuk a CAPS SHIFT és a 9-es gombot (jelentése GRAPHICS), a kurzor G lesz. Ebben az üzemmódban a grafikus szimbólumokat az 1...8 számjegyek gombjai adják: ha csak ezeket nyomjuk meg, akkor a minta a gombra rajzolt szimbólum lesz, míg ha emellett valamelyik SHIFT gombot is megnyomjuk, a szimbólum invertáltját kapjuk (azaz a fekete rész lesz a fehér és viszont). A SHIFT gomboktól függetlenül a 9-es gomb megnyomása a normál (L) üzemmódba visszatérést jelenti, míg a 0-s gomb a DELETE (törlés) funkciót látja el.
A grafikus szimbólumok után következő részben újra az abécé betűi láthatóak (a)-tól (u)-ig. Ezek szabadon definiálható karaktereket jelentenek és "felhasználó által definiált grafikus karaktereknek" nevezzük. A számítógép bekapcsolása után az A...U betűket tartalmazzák. Ezek beírása a billentyűzetről történik a grafikus üzemmódban az A-tól U-ig terjedő betűgombok megnyomásával.
Egy új karakter definiálása a következő eljárással történik (esetünkben a karakter jelenítse meg a PI jelet).

1.
Tervezzük meg, hogyan nézzen ki a karakter! Minden karakterhez egy kis négyzetekből álló 8*8-as nagyobb négyzet tartozik, és a 64 kis négyzet közül mindegyik vagy paper vagy ink színű lehet (lásd erről a bevezető füzetet). Ha az ink szín fekete, a következő ábra megfelelő lehet a megjelenítésére:

Egy kis négyzetből álló keretet üresen hagytunk, hiszen ez a többi betűnél is van (kivéve néhány kisbetű alsó szárát).

2.
Döntsük el, hogy melyik felhasználói grafikus karakter jelenítse meg a PI-t! Legyen ez a P-hez tartozó, azaz a grafikus üzemmódban a P megnyomására jelenjen meg a PI.

3.
Tároljuk ezt az új alakzatot! Minden felhasználói grafikus karakter alakzatát soronként nyolc szám formájában tároljuk. Ezeket a számokat a következőképpen írhatjuk: a BIN kulcsszó, majd ezután nyolc számjegy, amely 0 a paper és 1 az ink esetében. Ezek szerint a PI karakter nyolc száma így néz ki:

BIN 00000000
BIN 00000000
BIN 00000010
BIN 00111100
BIN 01010100
BIN 00010100
BIN 00010100
BIN 00000000

(ha ismerjük a bináris számokat, akkor nyilvánvaló, hogy a BIN a számok szokásos decimális jelölése helyett a bináris alakban történő jelölésre szolgál).
Ez a nyolc szám a memória nyolc rekeszében tárolódik, ezek mindegyikéhez egy cím tartozik. Az első byte (nyolcjegyű csoport) címe USR "P" (azért P, mert a 2. pontban ezt választottuk), a második byte címe USR "P"+1 stb., végül a nyolcadik byte címe USR "P"+7.
Az itt használt USR olyan függvény, amely egy string argumentumot alakít át a felhasználói grafikus karakter tárolására szolgáló memória első byte-jának címévé. A string argumentum egyetlen karakter lehet, amely vagy maga a felhasználói grafikus karakter, vagy az ennek megfelelő betű (lehet nagy- vagy kisbetű). Az USR függvény másik felhasználásánál az argumentum egy szám, ezzel később foglalkozunk.
A következő program a tárolást hajtja végre:

10 FOR n=0 TO 7
20 INPUT sor: POKE USR "P"+n,sor
30 NEXT n

A program a nyolc leállásánál arra vár, hogy beírjuk a fenti nyolc BIN számot. Tegyük ezt meg a legfelső sornál kezdve és lefelé haladva!

A POKE utasítás egy számot közvetlenül egy memóriarekeszben helyez el, kikerülve a BASIC-nél szokásos mechanizmust. A POKE ellentettje a PEEK, amely lehetővé teszi számunkra, hogy egy memóriarekesz tartalmát megnézzük. Az utasítás hatására a rekesz tartalma nem változik meg. E két utasítással a 24. fejezetben részletesebben foglalkozunk.

A felhasználói grafikus karakterek után a karakterkészletben az összetett szimbólumok következnek.
A karakterkészletben megfigyelhettük, hogy az első 32 karaktert nem írattuk ki. A 0 és 31 közötti kódszámokhoz tartozó karakterek vezérlő karakterek, és ezekhez nem valamiféle nyomtatható karakter tartozik, hanem bizonyos meghatározott funkciót látnak el, illetve nem a televíziót, hanem más eszközöket vezérelnek. A képernyőn a ? jelenik meg, ha egy vezérlő karaktert a számítógép nem tud értelmezni. Részletes leírásukat lásd az A. függelékben.
A 6, 8 és 13-as kódszámú vezérlő karaktert a televízió használja; ezek közül a CHR$ 8 tűnik különösen hasznosnak.
A CHR$ 6 a kiírt részek között hagy ki megfelelő részt pontosan úgy, ahogy a PRINT utasításban lévő vessző. Így például a

PRINT 1; CHR$ 6;2

és a

PRINT 1,2

eredménye a képernyőn azonos. Alkalmazására jellemzőbb (és hasznosabb) példa a következő:

LET a$="1"+CHR$ 6+"2"
PRINT a$

A CHR$ 8 az írási pozíciót egy hellyel visszaállítja, például a következő sor hatására 1235 fog megjelenni a képernyőn:

PRINT "1234"; CHR$ 8;"5"

A CHR$ 13 jelentése új sor, vagyis az írási pozíciót a következő sor elejére állítja.

A televízió használja a 16 és 23 közé eső kódszámú vezérlő karaktereket is (ezekről a 15. és 16. fejezetben lesz szó).

A karakterek kódjai segítségével az abécé sorrend fogalma a betűkön túl a tetszőleges karaktereket tartalmazó stringekre is kiterjeszthető. Ebben az esetben a 26 betűből álló szokásos ábécé helyett a 256 karaktert tartalmazó kiterjesztett ábécé-t vesszük alapul, amelyben a karakterek kódjaik szerint következnek egymás után. E szabály szerint a következő stringek a ZX Spectrum szerinti ábécé rendben következnek egymás után. (Figyeljük meg a következő érdekes tulajdonságot: a kisbetűk a nagybetűk után következnek, így tehát az "a" a "Z" után következik; továbbá a betűközt is figyelembe kell venni.)

CHR$ 3+"ZOOLOGICAL GARDENS"
CHR$ 8+"AARDVARK HUNTING"
" AAAARGH!"
"(Parenthetical remark)"
"100"
"129.95 inc VAT"
"AASVOFEL"
"Aardvark"
"Print"
"Zoo"
"/interpolation/"
"aardvark"
"aasvogel"
"zoo"
"zoology"

Két stringről az alábbi szabály szerint dönthetjük el, hogy melyik következik előbb: először hasonlítsuk össze az első karaktereket. Ha ezek különbözőek, akkor az a string következik előbb (az a kisebb), amelyik a kisebb kódszámú karaktert tartalmazza. Ha az első karakterek egyformák, akkor a következő karaktereket kell összehasonlítani, és így tovább. Ha az összehasonlítások során az egyik string elfogy, akkor ez a string következik előbb.
Az =, <, >, <=, >= és <> relációk a számokhoz hasonlóan stringekre is alkalmazhatók: a < jelentése "előbb következik", a > jelentése "később következik". Ezek szerint a következő két reláció igaz:

"AA man" < "AARDVARK"
"AARDVARK" > "AA man"

A <= és a >= jelentése megegyezik a számoknál megismerttel, így a következő sor igaz:

"Ugyanaz a string"<="Ugyanaz a string"

míg az alábbi sor hamis

"Ugyanaz a string"<"Ugyanaz a string"

A most megismertek gyakorlására futtassuk az alábbi programot, amely két stringet olvas be, és helyes sorrendbe állít:

10 INPUT "Irj be ket stringet:",a$,b$
20 IF a$>b$ THEN LET c$=a$: LET a$=b$: LET b$=c$
30 PRINT a$;" ";
40 IF a$<b$ THEN PRINT "<";: GO TO 60
50 PRINT "="
60 PRINT " ";b$
70 GO TO 10

a programban figyeljük meg a 20-as sorban a c$ változó bevezetését, amellyel az a$, és a b$ felcserélését hajtjuk végre. Ezt a felcserélést a

LET a$=b$: LET b$=a$

nem végezte volna el.
A következő program a felhasználói grafikus karakterek segítségével a sakkfigurákat jeleníti meg. A betűk kiosztása a következő:

P - gyalog (pawn)
R - bástya (rook)
N - huszár (knight)
B - futó (bishop)
K - király (king)
Q - vezér (queen)

Figyeljük meg, hogy a BIN 00000000 helyett 0 írható!
A program futtatása után az egyes figurákat a grafikus üzemmódban nézhetjük meg.

5 LET b=BIN 01111100: LET c=BIN 00111000: LET d=BIN 00010000
10 FOR n=1 TO 6: READ p$: REM 6 figura
20 FOR f=0 TO 7: REM 8 byte beolvasása figuránként
30 READ a: POKE USR p$+f,a
40 NEXT f
50 NEXT n
100 REM futo
110 DATA "b",0,d, BIN 00101000, BIN 01000100
120 DATA BIN 01101100,c,b,0
130 REM kiraly
140 DATA "k",0,d,c,d
150 DATA c, BIN 01000100,c,0
160 REM bastya
170 DATA "r",0, BIN 01010100,b,c
180 DATA c,b,b,0
190 REM vezer
200 DATA "q",0, BIN 01010100, BIN 00101000,d
210 DATA BIN 01101100,b,b,0
220 REM gyalog
230 DATA "p",0,0,d,c
240 DATA c,d,b,0
250 REM huszar
260 DATA "n",0,d,c, BIN 01111000
270 DATA BIN 00011000,c,b,0

Gyakorlatok
1. Képzeljünk el egy egy karakternyi helyet elfoglaló szimbólumot, amelyet négy egyforma négyzetre osztunk. Mindegyik negyed lehet fekete vagy fehér, tehát összesen 2x2x2x2=16 kombináció lehetséges. Keressük meg a megfelelő szimbólumokat a karakterkészletben!

2. Futtassuk a következő programot:

10 INPUT a
20 PRINT CHR$ a;
30 GO TO 10

Néhány végrehajtás után észrevehetjük, hogy a CHR$ a a legközelebbi egész számra kerekít. Ha a nincs a 0...255 tartományban, a program leáll, és a hibaüzenet B integer out of range.

3. A következő két string közül melyik a kisebb:

"EVIL"
"evil"

4. A felhasználói grafikus karaktereket meghatározó programot hogyan kell átalakítanunk, hogy az INPUT helyett a READ és a DATA utasításokat használja?

További tudnivalók a PRINT és INPUT utasításról

A PRINT utasítással már többször találkoztunk, így használatáról és működéséről van némi fogalmunk. Azokat a kifejezéseket, amelyeknek értékét kiíratjuk, kiíratási tételeknek (PRINT listaelemeknek) nevezzük, és ezeket vesszőkkel vagy pontosvesszőkkel választjuk elegymástól. Ezek a jelek az elhatároló jelek. A PRINT listaelemek hiányozhatnak is (a PRINT után nem áll semmi), ennek hatása megegyezik azzal, mintha két vesszőt használnánk egy sorban.
Két további PRINT listaelem is van, amellyel nem azt közöljük a számítógéppel, hogy mit, hanem hogy hol írjon ki. Például a PRINT AT 11,16;"*" hatására a képernyő közepén egy csillag jelenik meg. Az

AT sorszám,oszlopszám

a kiírási pozíciót (PRINT pozíció: a következő karakter kiírási helyét) a megadott sorra ill. oszlopra helyezi. A sorokat 0-tól (a képernyő teteje) 21-ig, az oszlopokat 0-tól (a képernyő bal oldala) 31-ig számozzuk.
A SCREEN$ a PRINT AT-tel ellentétes funkciójú, és (bizonyos határok között) azt mutatja meg, hogy a képernyő egy adott pozíciójában milyen karakter van. A sor és oszlopszámokat a PRINT AT utasításnál megismert módon használja azzal a különbséggel, hogy itt ezeket zárójelbe kell tenni. Például a

PRINT SCREEN$ (11,16)

hatására visszanyerjük a fent beírt csillagot.
Az összetett szimbólumok karaktereit a gép ugyanúgy, egyenként írja ki, mint az egyéb karaktereket; a betűközöket is betűközként kapjuk vissza. A PLOT, DRAW és CIRCLE utasítások segítségével rajzolt vonalak illetve a felhasználói grafikus karakterek és a grafikus karakterek viszont üres (null) stringként jelennek meg. Ugyanez érvényes akkor is, ha az OVER utasítást használjuk összetett karakter létrehozására.
A

TAB oszlopszám

annyi betűközt helyez el, hogy a kiírási pozíció a megadott oszlopba kerüljön, vagy ha visszalépés is szerepelne, az a következő sorba kerül. A számítógép az oszlopszámot mindig elosztja 32-vel, és a maradékot veszi (modulo 32), így a TAB 33 és a TAB 1 jelentése azonos.
A következő példa azt mutatja be, hogyan tudjuk elhelyezni egy könyv első oldalára a tartalomjegyzéket:

PRINT TAB 30;1;TAB 12;"Tartalom"; AT 3,1;"Fejezet"; TAB 24;"oldal"

Az alábbi program a " TAB-szám modulo 32 " jelentését világítja meg:

10 FOR n=0 TO 20
20 PRINT TAB 8*n;n;
30 NEXT n

(Még szemléletesebb a példa, ha a 20-as sorban a 8-as számot 6-ra cseréljük.)
Néhány további megjegyzés a fentiekhez:

  1. Megfigyelhetjük, hogy az újonnan megismert PRINT listaelemeket pontosvesszővel zártuk le. Vesszőt is írhattunk volna (ill. az utasítás végén egyiket sem), de ez a beállított kiírási pozíciót azonnal tovább helyezi, és ez általában nem cél.
  2. A képernyő alsó két sorába (22-es és 23-as sor) nem írathatunk ki, ezek a parancsok, az adatbevitelek (INPUT) stb. számára fenntartott sorok (lásd a 2. gyakorlatot!). Ennek megfelelően, ha a legalsó sorra hivatkozunk, ez általában a 21-es sort jelenti.
  3. Az AT segítségével a PRINT pozíciót olyan helyre is vihetjük, ahol már van valami kijelezve: ekkor a gép a régi karakter helyére az újat írja ki.

A PRINT utasítással kapcsolatos még a CLS is. Ez az utasítás törli az egész képernyőt (ugyanilyen hatású a CLEAR és a RUN is).
Ha a kiírás során elérjük a képernyő alját, felfelé léptetés (scrolling) következik. Figyeljük ezt meg a következő parancsok hatására:

CLS: FOR n=1 TO 22: PRINT n: NEXT n

majd néhányszor írjuk be:

PRINT 99

A számítógép azonban gondoskodik arról, hogy a felfelé léptetésnél semmi olyan sem tűnjön el, amit kellő ideig ne figyelhetnénk meg. Írjuk be a következő sort, és figyeljük, hogy mi történik:

CLS: FOR n=1 TO 100: PRINT n: NEXT n

Amikor a képernyő megtelik, a kiíratás leáll és a képernyő alján a scroll? kérdés jelenik meg, így az első 22 számot nyugodtan végignézhetjük. Ha már nincs szükségünk ezekre, nyomjuk meg az y gombot (jelentése itt yes - igen), erre a számítógép egy újabb számokkal teli "oldalt" ír ki. Valójában három gomb kivételével bármelyik megnyomása a kiíratás folytatását jelenti, ha viszont az n (jelentése itt no - nem), a SPACE (BREAK gomb) vagy a STOP (SYMBOL SHIFT és A) gombok valamelyikét nyomjuk meg, a számítógép leállítja a program futását és a D BREAK - CONT repeats üzenet jelenik meg.

Az INPUT utasítás sokkal sokoldalúbban használható, mint ahogy eddig láttuk. Találkoztunk már az utasítás egyszerűbb alakjaival, például:

INPUT "Hany eves vagy?", eletkor

Ekkor a számítógép a képernyő aljára kiírja a "Hany eves vagy?" kérdést, és erre be kell írnunk az életkorunkat (az "eletkor" nevű változó értékét kell megadnunk).
Valójában az INPUT utasítás is listaelemeket (beolvasási tételek) és elhatároló jeleket tartalmaz ugyanúgy, mint a PRINT utasítás; vagyis a "Hany eves vagy?" és az "eletkor" is INPUT listaelem. Az INPUT listaelemek általában ugyanazok lehetnek, mint a PRINT listaelemek, de van néhány nagyon lényeges különbség:

  1. A változó nyilvánvalóan különleges beolvasási tétel, amelynek értékét nekünk (a felhasználónak) kell beírni; a fenti példában ilyen az "eletkor". A szabály a kelvetkező: ha egy beolvasási tétel betűvel kezdődik, akkor ez változó, amelynek értékét be kell írni.
  2. A fenti szabályból az következne, hogy változók értékeit egy felirat részeként nem tudnánk kiíratni. Ez azonban a változó zárójelbe tételével megoldható, azaz tetszőleges, betűvel kezdődő kifejezést zárójelbe kell tenni, ha azt egy felirat részeként akarjuk kiíratni.

Tetszőleges más PRINT listaelem, amelyre ezek a szabályok nem vonatkoznak, egyúttal INPUT listaelem is. A következő példa a fentieket illusztrálja:

LET eletkorom= INT (RND*100): INPUT ("En ";eletkorom;" eves vagyok.");"Hany eves vagy?",eletkorod

Mivel az "eletkorom" a zárójelen belül van, így értéke megjelenik a képernyőn; az "eletkorod" viszont nincs zárójelben, így ennek értékét nekünk kell beírni.
Minden, ami az INPUT utasítás hatására kiíródik, a képernyő alsó részére kerül, amely a felső résztől függetlenül működik. E rész sorait az alsó rész legfelső sorához viszonyítva számozzuk, még akkor is, ha a tényleges televíziós kép feljebb tolódik; ez akkor fordul elő, ha sok adatot írunk be.
Az AT működését az INPUT utasításban a következő programsor mutatja:

10 INPUT "Ez az 1-es sor",a$; AT 0,0;"Ez a 0-as sor",a$; AT 2,0;"Ez a 2-es sor",a$; AT 1,0;"Meg mindig ez az 1-es sor",a$

(minden egyes leállásnál nyomjuk meg az ENTER gombot). Amikor az "Ez a 2-es sor' kerül kiírásra, a képernyő alsó része felfelé bővül, így a számítógép helyet biztosít ennek a szövegnek is. Ezzel együtt a sorok számozása is változik, így a szöveg sorai megtartják számaikat.
Próbáljuk ki a következő programot is:

10 FOR n=0 TO 19: PRINT AT n,0;n;: NEXT n
20 INPUT AT 0,0;a$; AT 1,0;a$; AT 2,0;a$; AT 3,0;a$; AT 4,0;a$; AT 5,0;a$;

A képernyő alsó része egyre feljebb kerül: ez mindaddig nem zavarja a felső részt, míg a kiírási pozícióval azonos sorba nem kerül. Ekkor a felső rész felfelé léptetése (scrolling) következik.

Az INPUT utasításnál nem találkoztunk még az ún. sorbeolvasással (LINE), amely egy stringváltozó beolvasásának egy másik módja. Ha a beolvasandó stringváltozó elé a LINE kulcsszót írjuk, a számítógép nem írja ki az idézőjeleket, ahogy ezt általában a stringváltozóknál eddig tette (de úgy viselkedik, mintha ezek ott lennének). Például:

INPUT LINE a$

Ha ezután beolvasandó adatként mondjuk beírjuk a következő stringet

macska

az a$ felveszi a macska értéket. Mivel idézőjelek itt nem jelennek meg, ezek nem is törölhetők, és így beolvasási adatként nem írható be másfajta stringkifejezés. Ne feledjük: a LINE numerikus változóknál nem használható.
Az INPUT LINE művelet alkalmazásánál a STOP-mechanizmus nem működik, ezért ha ilyenkor meg akarjuk állítani a program futását, a billentyűt (CAPS SHIFT és 6) kell használnunk. Az üzenet ebben az esetben is "H" lesz.

A CHR$ 22 és a CHR$ 23 vezérlő karakterek ugyanolyan hatásúak, mint az AT és a TAB. Ezek azonban ritkán fordulnak elő vezérlő karakterként, mivel ha ezeket kiíratásra küldjük a televízióba, két további karakternek kell következni, amelyek nem a szokásos hatásukat fejtik ki: ezeket olyan számként (ez megegyezik a karakter kódjával) kezeli a számítógép, amely az AT esetében a sort és az oszlopot, míg a TAB esetében a tabulátor pozíciót adja meg. Általában egyszerűbb az AT és a TAB szokásos módon való használata, de bizonyos körülmények között a vezérlő karakterek is hasznosak lehetnek. Az AT vezérlő karakter a CHR$ 22. Az ezután következő első karakter a sorszámot, a második az oszlopszámot határozza meg, tehát a

PRINT CHR$ 22+CHR$ 1+CHR$ c;

pontosan ugyanolyan hatású, mint a

PRINT AT 1,c;

Ez még akkor is így van, ha a CHR$ 1 vagy a CHR$ c egyébként ettől eltérő jelentésű lenne (például ha c=13): az előttük álló CHR$ 22 hatálytalanítja az eredeti jelentést.

A TAB vezérlő karakter a CHR$ 23, és az ezután következő két karakter egy olyan 0 és 65 535 közé eső számot határoz meg, amely a tabulátor-pozíciót adja meg. Így a

PRINT CHR$ 23+CHR$ a+CHR$ b;

pontosan ugyanolyan hatású, mint a

PRINT TAB a+256*b;

A POKE utasítás felhasználható a scroll? kiküszöbölésére. Például a

POKE 23692,255

hatására 255-ször felfelé léptetés következik, és csak ezután áll le a program, és jelenik meg a scroll? kérdés.
Hasonló példát mutat a következő program, azonban itt mindvégig elmarad a scroll? Kérdés:

10 FOR n=0 TO 100000
20 PRINT n: POKE 23692,255
30 NEXT n

Gyakorlatok

1. A következő program alkalmas annak eldöntésére, hogy a gyerekek tudják-e a szorzótáblát:

10 LET m$=""
20 LET a=INT (RND*12)+1: LET b=INT (RND*12)+1
30 INPUT (m$)' ' "Mennyi ";(a);" * ";(b);"?";c
100 IF c=a*b THEN LET m$="Helyes": GO TO 20
110 LET m$="Nem ko. Probald ujra!": GO TO 30

Az élelmes (és tegyük hozzá értelmes) gyerekek gyorsan rájönnek, hogy a számítást nem kell nekik elvégezni. Ha például a számítógép azt kérdezi, hogy mennyi 2*3, elegendő azt válaszolni, hogy: 2*3.
A fenti "csalás" kiküszöbölésének egyik módja az, hogy számok helyett stringek bevitelét kérjük tőluk. Írjuk a 30-as sorban lévő c helyére a c$-t, míg a 100-as sorban a c helyére a VAL c$-t, és illesszük a programba még a következi sort is:

40 IF c$<>STR$ VAL c$ THEN LET m$="Ird be az eredmenyt szamkent": GO TO 30

E z már kifog rajtuk! De a legélelmesebbek még erre is találnak megoldást: kitörlik az idézőjeleket, és beírják:

STR$ (2*3)

Ezt a lehetőséget is megszüntethetjük, ha a 30-as sorban a c$ helyett ezt írjuk: LINE c$.

2. Különlegességként próbáljuk ki az alábbi programot és nézzük meg mit ír ki, ha futtatjuk:

10 PRINT #1;TAB 6;"22. sor" ' TAB 6;"23. sor"
20 FOR n=0 TO 20: PRINT AT n,6;n;". sor": NEXT n
30 GO TO 30

Színek

Írjuk be és futtassuk a következő programot:

10 FOR m=0 TO 1: BRIGHT m
20 FOR n=1 TO 10
30 FOR c=0 TO 7
40 PAPER c: PRINT "    ";:REM 4 szines betukoz
50 NEXT c: NEXT n: NEXT m
60 FOR m=0 TO 1: BRIGHT m: PAPER 7
70 FOR c=0 TO 3
80 INK c: PRINT c;"   ";
90 NEXT c: PAPER 0
100 FOR c= 4 TO 7
110 INK c: PRINT c;"   ";
120 NEXT c: NEXT m
130 PAPER 7: INK 0: BRIGHT 0

Ez a program azt a nyolc színt (beleértve a fehéret és a feketét is) és két fényességszintet jeleníti meg, amelyeket a ZX Spectrum egy színes televízión előállíthat. (Ha fekete-fehér televíziónk van, a szürke különböző árnyalatait láthatjuk.) Íme a nyolc szín kódszáma (a színek a megfelelő számú gomb fölött is fel vannak tüntetve):

0 - BALCK fekete
1 - BLUE kék
2 - RED piros
3 - MAGENTA bíbor
4 - GREEN zöld
5 - CYAN világoskék
6 - YELLOW sárga
7 - WHITE fehér

A fekete-fehér televízión ezek a színek a kódszámok csökkenő sorrendjében csökkenő fényességet (a szürke csökkenő árnyalatait) jelentik.
A színek helyes használatához egy kicsit meg kell ismerkednünk a televíziós kép felépítésével. A kép 768 ( 24 sor, mindegyikben 32 ) olyan pozícióból áll, amelyek mindegyikébe karakterek írhatók. Minden karakter egy négyzetben helyezkedik el, amely 8*8, kisebb négyzetből (képelem) áll. (ld. 14. fejezet).
A karakter-pozíció két színnel is kapcsolatban van, ezek az ink (vagy előtér szín), amely esetünkben a fekete képpontoknak felel meg, és a paper (vagy háttér szín), amely itt a fehér képelemeknek felel meg. Kezdetben minden pozícióban az ink szín fekete, míg a paper fehér, vagyis a kiírás fehér háttérben fekete karakternek felel meg.
A karakter-pozíció két fényességi szintű lehet, illetve a kijelzett karakter villoghat is. (A villogásnál az ink és a paper színe váltja egymást.) A karakterpozíciók valamennyi jellemzője számkódokkal adható meg, így összefoglalva egy karakter-pozíció a következő kódolható jellemzőkkel rendelkezik:

  1. Egy 8*8-as, 0-kból és 1-ekből álló négyzet, amely a karakter alakját adja; 0 a paper, az 1 az ink megfelelője.
  2. Ink és paper színek, kódolásuk 0 és 7 közötti számmal történik.
  3. Fényesség-szint: 0 a normál fényesség, 1 az extra fényesség jele.
  4. Villogás: 0 az álló, 1 a villogó karakter kódja.

Az ink és a paper színek az egész karakter-pozícióra vonatkoznak, így egy 64 képelemből álló blokkra kettőnél több szín nem adható meg. Ugyanez igaz a fényességi és a villogási kódszámra is: ezek sem egyedi képelemekre, hanem a teljes karakter-pozícióra vonatkoznak. A színeket, a fényességi és villogási kódszámokat az adott pozíció jellemzőinek (attributum) nevezzük.
Ha kiíratunk egy karaktert a képernyőre, ezzel megváltoztatjuk abban a pozícióban a képpont-mintát; kevésbé nyilvánvaló, hogy egyúttal a pozíció jellemzőit is megváltoztatjuk. Kezdetben ezt nem vesszük észre, mivel minden fekete ink és fehér paper színnel történik (és a fényesség is normális értékű és villogás sincs). Ez azonban megváltoztatható, ha az INK, PAPER, BRIGHT vagy FLASH utasításokat használjuk. Írjuk be:

PAPER 5

Majd írassunk ki néhány karaktert: ezek világoskék háttérben fognak megjelenni, mivel a kiíratásnál azoknál a pozícióknál, amelyet ezek a karakterek elfoglalnak, a paper szín az 5-ös kódszámú világoskék lesz.
A többi jellemző is hasonlóan érvényesül, vagyis a

PAPER 0 és 7 közötti szám
INK 0 és 7 közötti szám
BRIGHT 0 vagy 1 (az 1 a bekapcsolt állapot jelzése)
FLASH 0 vagy 1 (az 1 a bekapcsolt állapot jelzése)

utasítások után bármilyen kijelzett karakter a megyelelő jellemzőkkel fog rendelkezni valamennyi olyan pozícióban, amelyet a kijelzésre fölhasználunk. Néhány beállítást próbáljunk ki! Ezek után a fejezet elején megadott program működését is jobban megértjük (ne feledjük: a betűköz is karakter, amelynek ink és paper színe azonos). Fenti utasításokban még további számokat is használhatunk, ezek azonban kevésbé közvetlen hatásúak.
A 8-as kódszám mind a négy utasításban használható, jelentése "átlátszó", vagyis az előző jellemző érvényesül. Például a

PAPER 8

hatására ilyen kódszámú paper színt egyetlen karakter-pozició sem fog felvenni, mivel ilyen szín nincs; mindössze annyi történik, hogy a kiírásnál felhasználásra kerülő pozíciókban a paper szín ugyanaz marad, mint korábban volt. Az INK 8, BRIGHT 8 és FLASH 8 ugyanúgy működik a többi jellemzőnél, mint a PAPER 8 a háttér színnél.
A 9-es kódszám csak a PAPER és az INK utasítással használható, jelentése "kontraszt". Amelyik színre ezt alkalmazzuk, az a másik szín kontrasztja lesz, azaz fehér lesz, ha a másik szín sötét (fekete, kék, piros vagy bíbor) ill. fekete lesz, ha a másik világos szín (zöld, világoskék, sárga vagy fehér). A 9-es kódszám hatását szemlélteti a következő sor:

INK 9: FOR c=0 TO 7: PAPER c: PRINT c: NEXT c

A kontraszt funkciót még hatásosabban megfigyelhetjük, ha a fejezet elején megadott program futtatása után beírjuk a következőket:

INK 9: PAPER 8: PRINT AT 0,0;: FOR n=1 TO 1000: PRINT n;: NEXT n

Ekkor az ink szín minden pozícióban az előző paper szín kontrasztja lesz.
A színes televízió arra a különös tényre épül, hogy az emberi szem valójában. csak három színt lát - ezek az elsődleges színek, a kék, a piros ás a zöld. A többi szín ezek keverékéből áll. Például a bíbor a piros és a kék keverékéből áll elő - éppen ezért kódja a két alapszín, a kék és a piros kódjainak összege.
A nyolc szín egymással való kapcsolatát szemlélteti a következő kísérlet: képzeljünk el három négyzet alakú fényszórót, amelyek kék, piros és zöld színnel világítanak meg egy sötétben lévő fehér papírlapot. (A fényforrások tengelye nem esik egybe.) Ahol a színek fedik egymást, ott különböző színkeverékeket figyelhetünk meg. Ezt szemlélteti a következő program is(az ink színű betűközök beírása a G üzemmódban valamelyik SHIFT és a 8-as gomb megnyomásával történik):

10 BORDER 0: PAPER 0: INK 7: CLS
20 FOR a=1 TO 6
30 PRINT TAB 6; INK 1;"                  ": REM 18 ink szinu negyzet
40 NEXT a
50 LET adatsor=200
60 GO SUB 1000
70 LET adatsor=210
80 GO SUB 1000
90 STOP
200 DATA 2,3,7,5,4
210 DATA 2,2,6,4,4
1000 FOR a=1 TO 6
1010 RESTORE adatsor
1020 FOR b=1 TO 5
1030 READ c: PRINT INK c;"      ";:REM 6 ink szinu negyzet
1040 NEXT b: PRINT: NEXT a
1050 RETURN

Létezik egy olyan függvény is, amely a képernyő egy adott pozíciójának jellemzőit (attributumait) adja meg. Ez az ATTR függvény (ezzel az eléggé bonyolult függvénnyel majd a fejezet végén foglalkozunk).
Két további utasítás, az INVERSE és az OVER, nem a karakter-pozíció jellemzőit, hanem a képernyőn megjelenő képpont-mintát vezérli. A FLASH és a BRIGHT utasításokhoz hasonlóan itt is a 0 és az 1 kódszámokat használhatjuk, de itt csak ezeket. Az INVERSE 1 hatására a kijelzett képpont-minta a szokásos forma inverze lesz: a paper pontok helyére ink pontok kerülnek és megfordítva. Így például az a betű képe ez lesz:

Ha az INVERSE 1 alkalmazása előtt az ink szín fekete és a paper fehér volt, az a betű fekete háttérben fehérként fog megjelenni, de a fekete ink és a fehér paper szín továbbra is fennmarad ebben a karakter-pozícióban, hiszen nem ezt, hanem a képpontokat változtattuk meg.
Az

OVER 1

utasítás egy sajátos felülírást valósít meg. Normális esetben, ha egy karakter-pozícióba valamit beírunk, az a korábban ott lévőt teljesen törli, az OVER 1 után viszont egyszerűen az új karakter "hozzáadódik" az ott lévőhöz (ezzel kapcsolatban lásd még az 1. gyakorlatot is). Ez különösen összetett karakterek (pl. ékezetes betűk) kiíratásánál hasznos. A NEW parancs után írjuk, be a következő programot, amely az umlautos o betűt írja ki (a CHR$ 8 vezérlő karakter egy pozícióval visszaállítja a kiírási pozíciót):

10 OVER 1
20 FOR n=1 TO 32
30 PRINT "o"; CHR$ 8;"""";
40 NEXT n

Az INK, PAPER stb. használatának van egy másik módja is, amely az utasításként való használatánál talán még hasznosabb is. Ezek ugyanis lehetnek egy PRINT utasítás listaelemei is (utánuk ilyenkor pontosvesszőt kell tenni). Ekkor hatásuk pontosan ugyanaz, mintha utasításként használtuk volna ezeket, azzal a különbséggel, hogy ez a hatás csak ideiglenes: csak annak a PRINT utasításnak a végéig érvényesek, amelyben szerepelnek. Írjuk be a következőket:

PRINT PAPER 6;"x";: PRINT "y"

Láthatjuk, hogy csak az x jelenik meg sárga háttérben.
Az INK stb. utasításként történő használatánál ezek nem befolyásolják a képernyő alsó részének színeit (itt a parancsok és az INPUT nyomán bevitt adatok jelennek meg). A képernyő alsó részének paper színét a keret (border) színe határozza meg, az ink színre a 9-es kód érvényesül, a villogás itt mindig kikapcsolt állapotban van, és minden normális fényességgel jelenik meg. A keret színét a következő utasítás segítségével bármelyik normál színre megváltoztathatjuk (a 8-as és a 9-es kódszám nem használható):

BORDER színkód

Amikor az INPUT utasításban adatokat írunk be, a beírásnál érvényesül a fenti szabály (a border színű paper mellett kontraszt ink); de a számítbgép által kiírt szövegek színét megváltoztathatjuk, ha az INPUT utasításban az INK, PAPER stb. listaelemként szerepel (hasonlóan, ahogy a PRINT utasításban). Ezek hatása vagy az utasítás végéig, vagy néhány adat beviteléig érvényes (attól függően, hogy melyik van előbb). Próbáljuk ki a következőt:

INPUT FLASH 1; INK 1;"Mondj egy szamot!";n

A színek változtatása történhet a vezérlő karakterekkel is (hasonlóan, mint az AT és a TAB esetében, lásd 15. fejezet).

CHR$ 16
megfelelője
INK
CHR$ 17
megfelelője
PASPER
CHR$ 18
megfelelője
FLASH
CHR$ 19
megfelelője
BRIGHT
CHR$ 20
megfelelője
INVERSE
CHR$ 21
megfelelője
OVER

Ezeket a vezérlő karaktereket mindig egy olyan karakter követi, amely a szín kódját adja meg. Így például a következő két sor azonos hatású:

PRINT CHR$ 16+CHR$ 9; ...
PRINT INK 9; ...

A színek megadására általában nem érdemes a vezérlő karaktereket használni, de van egy hasznos felhasználási terület, amikor programban alkalmazzuk: ekkor a kiíratások egyes részeit különböző színűre választhatjuk, ami segíthet az egyes részek elkülönítésében. Az ilyen vezérlő karaktereket a sorszám után kell kitennünk, különben hatásukat nem fejtik ki.
A színváltások programba írását a billentyűzetről kell végrehajtani általában a kiterjesztett (E) üzemmódban a számjegy gombok segítségével. A 0-tól 7-ig terjedő számok a megfelelő színt állítják be - ha a CAPS SHIFT gombot is egyidejűleg megnyomjuk, akkor az ink, ha nem, akkor a paper színt. Pontosabban: ha E üzemmódban megnyomunk egy számjegy gombot, mondjuk a sárgát jelentő 6-os gombot (a szám minden esetben 0 és 7 között lehet csak, 8-as és 9-es nem lehet ) , akkor két karakter íródik be: először a PAPER megfelelője, a CHR$ 17, majd a CHR$ 6, amelynek jelentése: állítsd be sárgára. Ha a számjegy megnyomásakor a CAPS SHIFT gombot is megnyomtuk, akkor a CHR$ 17 helyett a CHR$ 16 karaktert kapjuk, amelynek jelentése: állítsd be az ink színt. Mivel ezek a beírások két karaktert jelentenek, törlésük is a szokásostól eltérően történik: a DELETE gombot kétszer kell megnyomni. Az első DELETE után egy kérdőjelet vagy valami mást ír ki a gép: ettől nem kell megijedni, nyugodtan nyomjuk meg újra a DELETE gombot.
A vezérlő karaktereknél a és kurzort mozgató gombok is másképp viselkednek: a vezérlő karaktereket átlépik.
A kiterjesztett üzemmódban a maradék két számjegy gomb jelentése a következő:

8 CHR$ 19 és CHR$ 0 (normál fényesség)
9 CHR$ 19 és CHR$ 1 (extra fényesség)
CAPS SHIFT és 8 CHR$ 18 és CHR$ 0 (nincs villogás)
CAPS SHIFT és 9 CHR$ 18 és CHR$ 1 (villogás)

Két további funkció az L üzemmódban hatásos:

CAPS SHIFT és 3 CHR$ 20 és CHR$ 0 (normál karakter)
CAPS SHIFT és 4 CHR$ 20 és CHR$ 1 (inverz karakter)

A korábban már említett ATTR függvény alakja a következő:

ATTR sor, oszlop

A függvény két független változója a sor- és az oszlopszám (ezt használtuk az AT listaelemnél is), míg függvényértéke egy szám , amely a televíziós képernyő megfelelő karakter-pozíciójának színét és más jellemzőit adja meg. Az ATTR a többi függvényhez hasonlóan használható kifejezésekben is. Az eredményül kapott szám a következő négy szám összege

Például: az adott karakter-pozíció villog, normál fényességű, a paper színe sárga, az ink színe kék. Ekkor a négy összeadandó szám a következő: 128, 0, 8*6=48 és 1, ami összesen 177. Ellenőrizzük ezt a következő sor beírásával:

PRINT AT 0,0; FLASH 1; PAPER 6; INK 1;" ";ATTR(0,0)

Gyakorlatok

1. Írjuk be a következő sort:

PRINT "B"; CHR$ 8; OVER 1;"/";

Ahol a "/" jel a B betűt keresztezi, fehér képelemeket fogunk látni. Ez a ZX Spectrum felülírási módszeréből következik: két paper vagy két ink eredménye paper, míg egy paper és egy ink eredménye ink. Ebből az is következik, hogy ha ugyanazzal a karakterrel kétszer felülírunk valamit, a kiinduló karaktert kapjuk. Írjuk most be ezt a sort:

PRINT CHR$ 8; OVER 1;"/"

Miért kaptuk vissza az eredeti B betűt?

2. Írjuk be:

PAPER 0: INK 0

Ez a képernyő alsó részét nem befolyásolja. Ezután írjuk be a kivetkező sort, és nézzük meg a képernyőt:

BORDER 0

3. írjuk be és futtassuk az alábbi programot:

10 POKE 22527+RND*704, RND*127
20 GO TO 10

Ne foglalkozzunk a program működésével, csak az eredményt nézzük: a képernyőn négyzetek fogják változtatni a színeiket, és az RND függvények hatására ez a változás véletlenszerű lesz. AZ átlós csíkok az RND álvéletlen jellegét mutatják.

4. Írjuk be (vagy ha kazettára vettük töltsük be) a 14. fejezetben megadott sakkfigurákat megjelenítő programot! Az alábbi program ezután a sakktáblát rajzolja fel a figurákkal:

5 REM ures tabla
10 LET bb=1: LET bw=2: REM piros es kek
15 PAPER bw: INK bb: CLS
20 PLOT 79,128: REM keret
30 DRAW 65,0: DRAW 0,-65
40 DRAW -65,0: DRAW 0,65
50 BORDER bb
60 REM tabla
70 FOR n=0 TO 3: FOR m=0 TO 3
80 PRINT AT 6+2*n,11+2*m;" "
90 PRINT AT 7+2*n,10+2*m;" "
100 NEXT m: NEXT n
110 PAPER 8
120 LET pw=6: LET pb=5: REM a babuk szinei
200 DIM b$(8,8): REM a babuk pozicioi
205 REM kezdoallas
210 LET b$(1)="rnbqkbnr"
220 LET b$(2)="pppppppp"
230 LET b$(7)="PPPPPPPP"
240 LET b$(8)="RNBQKBNR"
300 REM a tabla kijelzese
310 FOR n=1 TO 8: FOR m= 1 TO 8
320 LET bc=CODE b$(n,m): INK pw
325 IF bc=CODE " " THEN GO TO 350: REM ures
330 IF bc>CODE"Z" THEN INK pb: LET bc=bc-32: REM kisbetu a feketehez
340 LET bc=bc+79: REM atteres grafikus karakterekre
350 PRINT AT 5+n,9+m; CHR$ bc
360 NEXT m: NEXT n
400 PAPER 7: INK 0

Grafikus Lehetőségek

Eddig csak a grafikus karakterek segítségével tudtunk rajzolni, azonban a ZX Spectrummal tetszőleges grafikát, rajzokat elkészíthetünk. A képernyő tetszőleges pozíciójába pontot rajzolhatunk a PLOT utasítással a beállított ink színnel. Az utasítás alakja: PLOT sor, oszlop A következő program a képernyő véletlenszerű pontjára rajzol pontokat:

10 PLOT INT (RND*256), INT (RND*176): INPUT a$: GO TO 10

Az alábbi hasznosabb program a szinusz függvényt rajzolja fel a 0 ... 2PI tartományban:

10 FOR n=0 TO 255
20 PLOT n,88+80*SIN (n/128*PI)
30 NEXT n

Egy parabola részletet rajzolhatunk fel az SQR függvény segítségévei:

10 FOR n=0 TO 255
20 PLOT n,80*SQR (n/64)
30 NEXT n

Figyeljük meg, hogy a képelem koordináták különböznek az AT listaelemnél használatos sor- és oszlopszámtól. (A képernyőre több pont fér el, mint ahány karakter: 255*175 képpont) Az ábrák elkészítését könnyíti meg a DRAW és a CIRCLE utasítás, amelyek segítségével vonalak, körök és körívek rajzolhatók. Az egyenes vonalat rajzoló DRAW utasítás alakja a következő:

DRAW x,y

A vonal kezdőpontja az a képelem, ahol a legutóbbi PLOT, DRAW vagy CIRCLE utasítás abbahagyta a rajzolást (ezt a pontot PLOT pozíciónak nevezzük; a RUN, CLEAR, CLS és NEW a PLOT pozíciót a (0,0) pontba, vagyis a bal alsó sarokba állítja). A vonal végpontja az a képelem, amely vízszintesen a megadott x, függőlegesen a megadott y távolságra van a kezdőponttól. A DRAW utasítás tehát csak a vonal hosszát és irányát határozza meg, a kezdőpontját nem.
Írjuk be például a következő parancsokat:

PLOT 0,100: DRAW 80,-35
PLOT 90,150: DRAW 80,-35

Figyeljük meg, hogy a DRAW utasításban negatív számokat is használhatunk, míg a PLOT utasításban csak pozitív számok szerepelhetnek.
Az ábrák készítéséhez a színeket is felhasználhatjuk, de mindig szem előtt kell tartanunk, hogy a színek a teljes karakter-pozícióra vonatkoznak, vagyis egyedi képelemek színei nem írhatók elő. Egy-egy képpont kirajzolásakor az az állandó ink színnel jelenik meg, míg az azt tartalmazó karakter-pozíció színe az aktuális ink szín lesz. Ezt a következő program illusztrálja:

10 BORDER 0: PAPER 0: INK 7: CLS: REM fekete kepernyo
20 LET x1=0: LET y1=0: REM a vonal kezdopontja
30 LET c=1: REM ink szin, indulaskor kek
40 LET x2=INT (RND*256): LET y2=INT (RND*176): REM a vonal vegpontja veletlen helyen
50 DRAW INK c;x2-x1,y2-y1
60 LET x1=x2:LET y1=y2: REM a kovetkezo vonal az elozo vegpontjabol indul
70 LET c=c+1: IF c=8 THEN LET c=1: REM uj szin
80 GO TO 40

A program működése során a vonalak szélesedni látszanak, mivel a vonalak mindazoknak a képelemeknek a színeit megváltoztatják, amelyek azokban a karakter-pozíciókban vannak, amelyeken a vonal áthalad. Vegyük észre, hogy a PLOT és a DRAW utasításokban ugyanúgy előfordulhatnak a PAPER, INK, FLASH, BRIGHT, INVERSE és OVER listaelemek, mint a PRINT vagy az INPUT utasításokban. Ezeket a kulcsszó és a koordináták között kell megadni, és utánuk pontosvessző vagy vessző áll.
A DRAW utasítás nem csak egyenes vonalak, hanem körívek rajzolására is felhasználható, ha még egy számot megadunk, amely a körív nyílásszögét definiálja. Az utasítás alakja ekkor a következő:

DRAW x,y,a

ahol x és y szolgál a végpont megadására, míg a az elfordulás szöge radiánban. Ha az a pozitív, az elmozdulás balra, ha negatív, akkor jobbra történik. Az a érték tulajdonképpen azt mutatja, hogy egy teljes kör mekkora részét rajzoljuk fel: mivel a 2PI radián egy teljes kört ad meg, ha a=PI egy félkört kapunk, az a=0.5*PI egy negyedkört definiál stb. Legyen például az a=PI. Ekkor x és y tetszőleges értékénél egy félkört fogunk kapni. írjuk be a következőt:

10 PLOT 100,100: DRAW 50,50,PI

E programsor futtatása után a képernyőn ezt látjuk:

A rajzolás dél-keleti irányba indul, de a körív befejezésekor az irány észak-nyugat lesz, eközben 180 fok, azaz PI radián elfordulás történik (ez az a érték). Futtassuk a programot más a értékekkel is (például: -PI, PI/2, 3*PI/2. PI/4, 1, 0).
E fejezet utolsó utasítása a CIRCLE, amely egy teljes kört rajzol fel. Ebben a középpont koordinátáit és a kör sugarát kell megadnunk a következő alakban:

CIRCLE x koordináta, y koordináta, sugár

Hasonlóan a PLOT és a DRAW utasításhoz, az utasítás elején itt is megadhatunk különböző, színre vonatkozó listaelemeket.

A POINT függvény azt mutatja meg, hogy egy adott képelem ink vagy paper színű-e. A függvénynek két független változója van, ezek a képelem koordinátái, amelyeket zárójelbe kell tenni. A függvény értéke 0, ha a képelem paper színű, illetve 1, ha ink színű. Próbáljuk ki a következő parancssort::

CLS: PRINT POINT (0,0): PLOT 0,0: PRINT POINT (0,0)

írjuk be

PAPER 7: INK 0

És figyeljük meg, hogyan működik az INVERSE és az OVER utasításon belül. E két utasítás csak a kérdéses képelemeket befolyásolja, a karakter-pozíció többi részét nem. Egy PLOT utasításban ezek alapértéke 0 (kikapcsolt állapot), tehát csak akkor kell figyelnünk, ha be akarjuk "kapcsolni" ezeket (1 érték).
Az alábbiakban összefoglaljuk az egyes lehetőségeket:

PLOT ez az általános alak, amely egy képelemet az ink színre állít
PLOT INVERSE 1

a képelemet a paper színre állítja

PLOT OVER 1

ez megváltoztatja a képelem színét, azaz ha ink színű volt, paper színű lesz, és megfordítva

PLOT INVERSE 1; OVER 1 ez a képpont színét előző állapotában hagyja, de a PLOT poz í ciót megváltoztatja

Az OVER utasítás használatára vegyünk egy másik példát: írjuk tele a képernyőt fehér alapon fekete karakterekkel, majd írjuk be:

PLOT 0,0: DRAW OVER 1;255,175

Ekkor egy közel egyenes vonalat kapunk, bár bizonyos helyeken, ahol előzőleg beírt karaktereket érint, üres részek lesznek. Ezután hajtsuk végre újra az előző parancsokat. A vonal teljesen eltűnik: ez az OVER 1 egyik nagy előnye. Ha a vonalat a

PLOT 0,0, DRAW 255,175

paranccsal rajzoltuk volna fel, majd a törlést a

PLOT 0,0: DRAW INVERSE 1;255,175

paranccsal végeztük volna, akkor az előzőleg bevitt karakterek bizonyos részeit is kitöröltük volna.
Írjuk most be a következőt:

PLOT 0,0: DRAW OVER 1;250,175

Próbáljuk ezt kitörölni a következő módon:

DRAW OVER 1;-250,-175

Ez nem mindig sikerül, ugyanis a visszafelé haladó vonal nem pontosan ugyanazokat a képelemeket használja, mint az eredeti. Egy vonalat pontosan abban az irányban kell törölnünk, mint ahogy felrajzoltuk azt.
A nyolc normál színen kívül más színeket is kaphatunk, ha ugyanabban a négyzetben a felhasználói grafikus karakterek segítségével "összekeverünk" két normál színt. Futtassuk a következő programot, amely sakktábla mintát ad:

1000 FOR n=0 TO 6 STEP 2
1010 POKE USR "a"+n, BIN 01010101: POKE USR "a"+n+1, BIN 10101010
1020 NEXT n

ha ezt a karaktert sárga paper és piros ink szín mellett kiíratjuk (grafikus üzemmódban a betű), akkor narancssárga színt kapunk.

Gyakorlatok

1. használjuk a PAPER, INK, FLASH és BRIGHT utasításokat egy PLOT utasítás listaelemeként. Ezek olyan tételek, amelyek az adott képelemet tartalmazó teljes karakter-pozícióra vonatkoznak. Normális esetben a PLOT utasítást úgy is felfoghatjuk, mintha így kezdődne:

PLOT PAPER 8; FLASH 8; BRIGHT 8; ...

és csak a karakter-pozíció ink színe változna, ha valamit kirajzolunk. Ez azonban megváltoztatható.
Legyünk óvatosak, ha a színeket az INVERSE 1 feltétel mellett használjuk! Ez ugyanis a képelemet paper színűre állítja, de megváltoztatja az ink szint is, és lehet, hogy ez számunkra nem megfelelő.

2. Próbáljunk meg kört rajzolni a SIN és a COS függvény felhasználásával (a 10. fejezet segítségünkre lehet). Futtassuk a következő programot:

10 FOR n=0 TO 2*PI STEP PI/180
20 PLOT 100+80*COS n,87+80*SIN n
30 NEXT n
40 CIRCLE 150,87,80

Láthatjuk, hogy a CIRCLE utasítás sokkal gyorsabban rajzol (bár nem ad olyan pontos eredményt).

3. Írjuk be:

CIRCLE 100,87,80: DRAW 50,50

Ebből láthatjuk, hogy a CIRCLE utasítás a PLOT pozíciót pontosan meg nem határozható helyre állítja (ez valahol a kör jobb oldali ívén középen van). Így a CIRCLE utasítás után, ha még valamit rajzolni akarunk, előbb egy PLOT utasítást is be kell írnunk.

4. A következő program szinte tetszőleges függvényt felrajzol. A program először egy "n" szám beírását kéri tőlünk; a függvényt a -n-től +n-ig terjedő értékekre fogja felrajzolni. Ezután magát a függvényt kell beírnunk string alakban. A stringnek olyan kifejezésnek kell lenni, amelyben az x mint a függvény argumentuma szerepel. Futtassuk a programot! Legyen az n értéke 10, míg a függvény 10*TAN x. A program a tangens x függvényt rajzolja fel a -10...+10 tartományban.

10 PLOT 0,87: DRAW 255,0
20 PLOT 127,0: DRAW 0,175
30 INPUT s,e$
35 LET t=0
40 FOR f=0 TO 255
50 LET x=(f-128)*s/128: LET y=VAL e$
60 IF ABS y>87 THEN LET t=0: GO TO 100
70 IF NOT t THEN PLOT f,y+88: LET t=1: GO TO 100
80 DRAW 1,y-y2
100 LET y2=INT (y+.5)
110 NEXT f

Mozgás

Gyakran előfordul, hogy a program futását bizonyos ideig le akarjuk állítani. Ilyenkor használható a PAUSE utasítás. A

PAUSE n

leállítja a számításokat, és az adott képet "n" számú televíziós képváltás idejére kimerevíti (Európában 50, Amerikában 60 kép jelenik meg másodpercenként). Az "n" értéke maximálisan 65535 lehet, amely kb. 22 perces szünetet jelent; az n=0 állandó PAUSE. A szünet egy tetszőleges gomb lenyomásával megszakítható (a CAPS SHIFT és a SPACE együttes lenyomása egyúttal a program megszakítását is jelenti). A gombot a szünet megkezdése után kell megnyomni.
A következő program a másodpercmutató mozgását jeleníti meg a képernyőn:

10 REM eloszor a szamlapot rajzoljuk
20 FOR n=1 TO 12
30 PRINT AT 10-10*COS (n/6*PI),16+10*SIN (n/6*PI);n
40 NEXT n
50 REM most az ora kovetkezik
60 FOR t=0 TO 200000: REM "t" az ido masodpercben
70 LET a=t/30*PI: REM a masodpercmutato szoge radianban
80 LET sx=80*SIN a: LET sy=80*COS a
200 PLOT 128,88: DRAW OVER 1;sx,sy: REM a masodpercmutatot rajzolja
210 PAUSE 42
220 PLOT 128,88: DRAW OVER 1;sx,sy: REM a masodpercmutatot torli
400 NEXT t

Ez az óra mintegy 55 és fél órán keresztül jár (ezt a 60-as sor határozza meg, így ez az idő megváltoztatható). Az időzítést a 210-es sor szabályozza. Itt PAUSE 50 utasítást várnánk, ami 1 másodpercet jelentene, de gondolni kell a számításokra is, amelyek szintén időbe telnek. Ennek beállítása kísérletileg történhet: hasonlítsuk össze a számítógépes óra járását egy pontos óráéval, és addig változtassuk a 210-es sort, míg a kettő egyező nem lesz (teljes pontosságot ne varjunk: egy kép egy másodpercig történő kijelzése 2%-os pontossággal állítható be, ami naponta fél óra eltérést jelent).
Az idő érésére van pontosabb módszer is, amelyben bizonyos memóriarekeszek tartalmát használjuk. A tárolt adatok visszanyerésére a PEEK utasítás szolgál. (A 25. fejezetben részletesen megismerkedhetünk a memória felépítésével.) A következő kifejezést fogjuk használni:

(65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50

Ez a kifejezés a számítógép bekapcsolása óta eltelt időt adja meg másodpercben (maximális értéke kb. 3 nap és 21 óra, ezután értéke újra 0 lesz). Lényeges tudni, hogy ez a "belső óra" ármenetelig megáll a SAVE, a LOAD, a BEEP és más periféria-kommunikációs utasítások végrehajtásának időtartamára.
A fenti kifejezést is tartalmazó új óraprogram a következő:

10 REM eloszor a szamlapot rajzoljuk
20 FOR n=1 TO 12
30 PRINT AT 10-10*COS (n/6*PI),16+10*SIN (n/6*PI);n
40 NEXT n
50 DEF FN t()=INT ((65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50): REM a bekapcsolas ota eltelt ido masodperceben
100 REM most az ora kovetkezik
110 LET t1=FN t()
120 LET a=t1/30*PI: REM " a" a masodpercmutato szoge radianban
130 LET sx=72*SIN a: LET sy=72*COS a
140 PLOT 131,91: DRAW OVER 1;sx,sy: REM mutato
200 LET t=FN ()
210 IF t<=t1 THE GO TO 200: REM varakozas
220 PLOT 131,91: DRAW OVER 1;sx,sy: REM az elozo masodpercmutato torlese
230 LET t1=t: GO TO 120

Ennél a megoldásnál tulajdonképpen a számítógép belső óráját használjuk, amelynek pontossága a programfutások idején 0,01 % (10 másodperc naponta). Ha viszont BEEP utasítást, kazettás magnetofont, nyomtatót vagy más, a számítógéphez kapcsolható berendezést használunk, a belső óra átmenetileg leáll, így késni fog.
A PEEK 23674, PEEK 23673 és a PEEK 23672 számokat a számítógép tárolja, és a másodperc 50-ed részével való számolásra szolgálnak. Mindegyik szám értéke 0 és 255 között lehet: 0-tól 255-ig egyesével növekednek, majd 255 után értékük újra 0 lesz. A leggyakrabban a PEEK 23672 növekszik, értéke minden 1/50-ed másodpercben eggyel nő. A 255-ös érték után a következő növelésnél értéke 0 lesz, de ekkor a PEEK 23673 értéke is eggyel növekszik. Minden 256/50 másodpercnél a PEEK 23673 értéke 255-ről 0-ra változik, ami a PEEK 23674 értékét eggyel növeli. Ennek ismeretében a második programban használt kifejezés működése már világosabb.
Képzeljük most el a következő állapotot: a PEEK 23674 értéke legyen 0, míg a PEEK 23673 és a PEEK 23672, értéke egyaránt 255. Ez azt jelenti, hogy mintegy 21 perc telt el a számítógép bekapcsolása óta. A korábban használt kifejezésünk ekkor a következő értéket veszi fel:

(65536*0+256*255+255)/50=1310.7

Ez az állapot veszélyeket rejt magába! A következő 1/50 másodperc számlálásakor a három szám rendre a következő értékű lesz: 1, 0 és 0. Gyakran előfordul, hogy ez a váltás akkor következik be, amikor a számítógép a kifejezés kiértékelésének közepén tart: a PEEK 23674 0-nak adódik, míg a másik két szám még a kiolvasás előtt 0-ra vált. A kifejezés értéke ekkor a következő:

(65536*0+256*0+0)/50=0

Ez a hibás érték megzavarja a program működését. Ezt a problémát a következő egyszeres szabály alkalmazásával küszöbölhetjük ki: a kifejezést értékeljük ki kétszer egymás után, és a helyes eredménynek a nagyobb értéket fogadjuk el. Ha gondosan végignézzük a második programot, felfedezhetjük ezt a kétszeres kiértékelést.
A fenti szabályt a következő ügyes fogással alkalmazhatjuk: definiáljunk függvényeket a következő módon:

10 DEF FN m(x,y)=(x+y+ABS (x-y))/2: REM x es y kozul a magasabb
20 DEF FN u()=(65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50: REM ido, esetleg helytelen
30 DEF FN t()= FN m(FN u(), FN u(): REM helyes ido

A három időszámláló számot úgy is beállíthatjuk, hogy a számítógép bekapcsolásától eltelt idő helyett a tényleges időt jelezzék. Állítsunk be például 10 órát! Ez 10*60*60*50 = 1800000 1/50-ed másodpercnek felel meg. .Erre az értékre igaz a következő egyenlőség:

1800000 = 65536*27+256*119+64

A három időszámláló számot a következőképpen állíthatjuk be a kívánt értékekre (27, 119 és 64):

POKE 23674,27: POKE 23673,119: POKE 23672,64

Azokban az országokban, ahol a hálózati frekvencia 60 Hz, a fenti programban a megfelelő helyen 50 helyett 60-at kell írni.

Az INKEY$ (argumentum nélküli) függvény végrehajtásának pillanatában a billentyűzetet olvassa le. Ha egy gombot (ill. egy SHIFT gombot és még egy gombot) lenyomva talál, a függvény értéke az a karakter, amelyet ez a gomb az L üzemmódban jelent; a függvény értéke minden más esetben az üres, karakter nélküli string. Próbáljuk ki a következő programot, amely úgy működik, mint egy írógép:

10 IF INKEY$<>"" THE GO TO 10
20 IF INKEY$="" THEN GO TO 20
30 PRINT INKEY$
40 GO TO 10

A programban a 10-es sor arra vár, hogy ujjunkat levegyük a gombról, míg a 20-as sor egy gomb megnyomására vár. Figyeljük meg, hogy az INPUT utasítással ellentétben az INKEY$ "nem vár" a felhasználóra. Az ENTER gombot itt nem kell megnyomni, viszont ha egyetlen gombot sem nyomunk meg, a függvény a kívánt eredmény helyett az üres stringet adja.

Gyakorlatok

1. Mi történik, ha az utolsó programban a 10-es sort kihagyjuk?

2. Az INKEY$ függvényt a PAUSE utasítással kombinálva is használhatjuk. Például az írógép programot így is írhatjuk:

10 PAUSE 0
20 PRINT INKEY$
30 GO TO 10

Miért nélkülözhetetlen a program működéséhez, hogy a PAUSE ne érjen véget, ha a program olyankor indul, amikor lenyomva tartunk egy gombot?

3. Alakítsuk át a másodpercmutató mozgását leíró programot úgy, hogy a kis- és a nagymutatót is percenként kijelezze! Legyen a program olyan, hogy minden negyedórában valamilyen külön kijelzést is adjon - például játssza el a Big Ben harangjátékot a BEEP utasítás segítségével (ennek leírását a következő fejezetben találjuk. Ha így az elvártnál többet késne az óra, gondoljunk arra, hogy a belső óra a BEEP-nél leáll; próbáljuk meg ezt korrigálni!)

4. Próbáljuk ki a következő programot:

10 IF INKEY$="" THEN GO TO 10
20 PRINT AT 11,14;"JAJJ!!!"
30 IF INKEY$<>"" THEN GO TO 30
40 PRINT AT 11,14;"      ":REM hat betukoz
50 GO TO 10

Hangok

Aki eddig még nem tudott arról, hogy a ZX Spectrum beépített hangszóróval is rendelkezik, e fejezet tanulmányozása előtt olvassa el a Bevezető füzet megfelelő részét. A ZX Spectrum hangszóróját a BEEP utasítás segítségével működtetjük. Az utasítás alakja a következő:

BEEP tartam, magasság

ahol szokás szerint a hang "tartama" és a "hangmagasság" tetszőleges aritmetikai kifejezés lehet. A tartamot másodpercben mérjük, míg a második szám a közép C feletti hangmagasságot adja meg félhangokban (a negatív számok itt a közép C-nél mélyebb hangokat jelentenek). A következő ábrán a zongora egy oktávjának hangmagasságait adjuk meg:

Ha magasabb vagy mélyebb hangokat akarunk meghatározni, annyiszor 12-t kell hozzáadni ill. kivonni az itt megadott számokból, ahány oktávval magasabb illetve mélyebb a hang. Ha egy zongora is kéznél van, amikor a hangokat programozzuk, a hangmagasságok kiszámításához a fenti ábrán kívül másra nincs is szükségünk. Ha viszont kottából programozunk, érdemes minden vonalhoz és vonalközhöz odaírni a hangmagasság megfelelő értékét (természetesen a hangnem figyelembe vételével).
Példaképpen írjuk be a következő programot:

10 PRINT "Frere Gustav"
20 BEEP 1,0: BEEP 1,2: BEEP .5,3: BEEP.5,2: BEEP 1,0
30 BEEP 1,0: BEEP 1,2: BEEP .5,3: BEEP.5,2: BEEP 1,0
40 BEEP 1,3: BEEP 1,5: BEEP 2,7
50 BEEP 1,3: BEEP 1,5: BEEP 2,7
60 BEEP .75,7: BEEP .25,8: BEEP .5,7: BEEP .5,5: BEEP .5,3: BEEP .5,2: BEEP1,0
70 BEEP .75,7: BEEP .25,8: BEEP .5,7: BEEP .5,5: BEEP .5,3: BEEP .5,2: BEEP1,0
80 BEEP 1,0: BEEP 1,-5: BEEP 2,0
90 BEEP 1,0: BEEP 1,-5: BEEP 2,0

A fenti program futtatásakor Mahler 1. szimfóniájából a gyászinduló részletét halljuk.
Tegyük fel, hogy a fenti Mahler darabhoz hasonlóan, a lejátszani kívánt dallam hangneme C-moll. A lejátszott dallam eleje az ábrán látható (Erre a hangok hangmagasságát jelző számokat is beírhatjuk):

A jobb érthetőség kedvéért a kotta öt vonala fölé és alá még egy-egy pótvonalat is behúztunk. Figyeljük meg, hogy a hangnem megadásban a félhanggal leszállítás (esz) nem csak a legfelső sorközben lévő E hangra vonatkozik (értéke 16-ról 15-re változik), hanem a legalsó sor E hangjára is (ennek értéke 4-ről 3-ra változik). Ezután már könnyen meghatározhatjuk a kotta tetszőleges hangjának hangmagasság-értékét.
Ha a zenedarab hangnemét változtatni akarjuk, érdemes felvennünk egy hangnem nevű változót, és minden egyes hangmagasság-érték elé beírni: hangnem+ . Ezzel a második sor így alakul:

20 BEEP 1,hangnem+0: BEEP 1,hangnem+2: BEEP.5,hangnem+3: BEEP .5,hangnem+2: BEEP 1,hangnem+0

Ilyenkor a programok futtatása előtt meg kell adnunk a hangnem változó értékét: ez 0 a C-moll, 2 a D-moll, 12 az egy oktávval magasabb C-moll esetében, stb. A hangnem megfelelő beállításával (tört érték) a számítógépet egy hangszerhez hangolhatjuk.
A hangmagasságon kívül a hangok tartamát is meg kell határoznunk. Mivel ez a zenedarab elég lassú, egy negyedhangjegyhez egy másodpercet adtunk meg, majd ennek alapján fél másodperc tartozik a nyolcad-hangjegyhez, stb.
Rugalmasabbá tehetjük a programozást, ha definiálunk egy tartam nevű változót is, amely a negyedhangok tartamát határozza meg. Ezzel a 20-as sor a következő lesz:

20 BEEP tartam,hangnem+0: BEEP tartam,hangnem+2: BEEP tartam/2,hangnem+3: BEEP tartam/2,hangnem+2: BEEP tartam,hangnem+0

(Természetesen a két új változónak rövidebb nevet is adhatunk.) A tartam megfelelő értékadásával a zenedarab tempóját egyszerűen változtathatjuk.
Mivel a számítógépben csak egy hangszóró van, egyidejűleg csak egy hangot szólaltathatunk meg, ezért csak felharmonikusok nélküli dallamot játszhatunk le. (Akinek ez kevés, nem marad más hátra, mint megtanulni a hangok gépi kódú programozását vagy elénekelni a dallamot.) Megpróbálhatunk saját, kezdetben nyílván egyszerű, dallam programozásával is. Ha se zongoránk, se leírt kottánk nincs, a dallam kidolgozásában segítségünkre lehet egy egyszerű hangszer (pl. bádogsíp) vagy egy magnetofon. Az ilyen egyszerű hangszeren lejátszható hangokról a hangmagasság-értékeket tartalmazó táblázatot is készíthetünk.
Írjuk be a következő sort:

FOR n=0 TO 1000: BEEP .5,n: NEXT n

Egyre magasabb hangokat fogunk hallani, míg végül a B integer out of range hibaüzenetet kapjuk. Az n értékének kiíratásával megtudhatjuk, milyen magas hangig jutottunk. Ugyanezt megpróbálhatjuk a mély hangok irányába is. Az egészen mély hangok már rövid kattogásnak hangzanak; tulajdonképpen a magasabb hangok is ilyen kattogásból állnak, de olyan sűrűn követik egymást, hogy az emberi fül már nem is képes megkülönböztetni ezeket. Az élvezhető zenéhez a középső tartományba eső hangok a legmegfelelőbbek; a mély hangok túlságosan kattogás-szerűek, míg a magas hangok gyengék és kissé ciripelés-szerűek.
Írjuk be a következő programsort:

10 BEEP .5,0: BEEP .5,2: BEEP .5,4: BEEP .5,5: BEEP .5,7: BEEP .5,9: BEEP .5,11: BEEP .5,12: STOP

Ez a C-dúr skálát szólaltatja meg, azaz a zongorán a fehér billentyűkhöz tartozó hangokat halljuk a közép C-től a következő C hangig. E skála hangzása pontosan megegyezik a zongoráéval, és kiegyenlített hangzásnak nevezzük, mivel a félhangok hangmagasság-közel a skálán végig azonosak. Egy hegedűs egy kissé másképp játszaná el ezt a skálát, valamennyi hang magassága eltérő lenne, és a fül számára kellemesebb hangzást adna. Ezt a hangzást úgy éri el, hogy ujjait a húrokon fel-le mozgatja. A zongorán ez megvalósíthatatlan.
A természetes skála, ami a hegedűn is megszólal, körülbelül a következő:

20 BEEP .5,0: BEEP .5,2.039: BEEP .5,3.86: BEEP .5,4.98: BEEP .5,7.02: BEEP .5,8.48: BEEP .5,10.88: BEEP .5,12: STOP

A két skála hangjai között csak a jó hallással rendelkezők fedeznek fel különbséget. Az első szembeötlő különbség az, hogy a természetes skálán a harmadik hang kissé mélyebb. Ha tökéletes megoldásra törekszünk, dallamainkat a természetes skála hangjainak felhasználásával is programozhatjuk. Ennek azonban hátránya is van: a moll hangnemben tökéletesen megfelelő, míg más hangnemekben már kevésbé ill. egyáltalán nem, vagyis mindegyik hangnemnek saját természetes skálája van. A kiegyenlített skála alig különbözik a természetestől, de minden hangnemben egyaránt jól alkalmazható. A fenti probléma a számítógépen kisebb gondot okoz, hiszen a hangnem változó hozzáadásával áthidalható.
Vannak olyan zenék is (például a hindu zene), ahol a hangmagasságközök kisebbek egy félhangnál. Ezek a BEEP utasításban minden nehézség nélkül leírhatók, például a közép C fölötti negyedhang hangmagasság-értéke 0.5.
Említettük, hogy ha egy gombot lenyomunk, és azt a gép elfogadja, halk kopogó hangot hallunk. Ennek a hangnak a tartamát beállíthatjuk, például:

POKE 23609,255

A második szám e hang tartamát határozza meg (próbáljuk ki különböző, 0 és 255 közé eső értékekkel is,) Ha értéke 0, a hang egészen rövid lesz.

A EEEP utasításban leírt hangok nem csak a számítógép saját hangszóróján hallgathatók. A hangoknak megfelelő jelek a "MIC" és az "EAR" csatlakozókon is megjelennek, így ezek külső hangszóróra (például fülhallgató vagy fejhallgató) vezethetők. (Az "EAR" csatlakozón a jelszint magasabb.) A külső hangszóró rákapcsolásával a számítógép saját hangszórója továbbra is működik. Ha még hangosabb zenét akarunk, erősítőt is beiktathatunk (erre a célra a "MIC" csatlakozó jelszintje az alkalmasabb); illetve a hang magnetofonra is fölvehető. Próbálkozzunk nyugodtan: a számítógépben még akkor sem tehetünk kárt, ha az "EAR" és a "MIC" csatlakozókat véletlenül rövidre zárjuk.

Gyakorlat
Írjuk át a Mahler zenét megszólaltató programot úgy, hogy az azonos taktusok ismétlését FOR ciklusok hajtsák végre!
Készítsünk olyan programot, amely nem csak a gyászindulót, hanem a Mahler szimfónia többi részét is megszólaltatja.

Adattárolás kazettán

A programok kazettára történő vételének (SAVE), visszatöltésének (LOAD) és ellenőrzésének (VERIFY) módszerét a Bevezető füzetben ismertettük. Mielőtt ezt a fejezetet áttanulmányoznánk, olvassuk el a Bevezető füzet idevágó részét, és az ott leírt eljárást magnetofonnal is próbáljuk ki.
Láttuk, hogy a LOAD mielőtt a kazettáról új programot és változókat töltene a számítógép memóriájába, a régi programot és változókat törli onnan. Létezik egy másik utasítás, amely ezt a törlést nem így végzi. A MERGE csak akkor töröl (és helyettesít újjal) egy régi programsort ill. változót, ha a betöltendő új programban is van ilyen számú sor ill. ilyen nevű változó. Írjuk be a 11. fejezetben megadott kockadobó programot, majd "kocka" néven vegyük kazettára. Ezután írjuk be és futtassuk a következő programot:

1 PRINT 1
2 PRINT 2
10 PRINT 10
20 LET x=20

Ezután hajtsunk végre egy ellenőrzést, de a VERIFY "kocka" helyett ezt írjuk be:

MERGE "kocka"

Ha kilistázzuk a programot látjuk, hogy az 1-es és a 2-es sor megmaradt, míg a 10-es és a 20-as helyett a kockadobó program megfelelő sora került a programba. Az x változó szintén nem törlődött (ezt a PRINT x beírásával ellenőrizhetjük).
A kazettás magnetofon használatánál előforduló utasítások hatása tehát a következő:

SAVE kazettára veszi a programot és a változókat
VERIFY a kazettán lévő programot és változókat összehasonlítja a számítógépben lévő programmal ill. változókkal
LOAD törli a számítógépben lévő valamennyi programot és változót, és a kazettáról új programot és változókat tölt be
MERGE

hasonló a LOAD működéséhez azzal a különbséggel, hogy csak akkor töröl egy régi sort ill. változót, ha a kazettáról betöltendő új programban is van ilyen számú sor ill. ilyen nevű változó.

A kulcsszók után minden esetben egy string következik; a SAVE esetében ez lesz a program neve a szalagon, míg a másik három esetben ez közli a számítógéppel, hogy melyik programot keresse. Amíg a számítógép a szalagon a megadott programot keresi, a közben talált programok neveit kiírja a képernyőre. A fenti szabályhoz néhány kiegészítés tartozik. Lássuk most ezeket!
A VERIFY, LOAD és MERGE esetében a keresett névként üres stringet is megadhatunk: ekkor a számítógép a szalagon elsőként megtalált programot veszi.
A SAVE alakja a következő is lehet:

SAVE string LINE szám

Az ilymádon felvett program a LOAD paranccsal (a MERGE esetében nem) történő visszatöltés után automatikusan a LINE után megadott számú sorra ugrik, így önmagát "futtatja".
Eddig csak programok és ezek változóinak kazettára vételét láttuk. Más típusú információ is kazettára vehető, ilyenek a tömbök és a byte-ok. A tömbök kazettára vételénél a SAVE utasításban a DATA kulcsszót is használjuk. Alakja a következő:

SAVE string DATA tombnev()

A "string" az információ neve lesz a szalagon (ugyanúgy, mint egy program vagy byte-ok felvételénél). A "tombnev" azt a tömböt adja meg, amelyet szalagra akarunk venni, tehát egy betűből vagy egy betűből és a $ jelből állhat. Ne feledkezzünk meg az ez után álló zárójelekről sem! (A zárójelek használata logikailag szükségtelennek tűnik, de ki kell tenni, mert a számítógép munkáját megkönnyíti.) A "string" és a "tombnev" különböző funkciójú, erre mindig figyeljünk. Például ha ezt írjuk:

SAVE "Adatok" DATA b()

akkor a SAVE a számítógépben lévő "b" tömböt eltárolja a kazettán a "Adatok" néven. Ha ezt írjuk:

VERIFY "Adatok" DATA b()

a számítógép a kazettán "Adatok" néven tárolt numerikus tömböt fog keresni, amikor megtalálja, a képernyőre a "Number array: Adatok" üzenetet írja, majd összehasonlítja a számítógépben lévő "b" tömbbel. A

LOAD "Adatok" DATA b()

megkeresi ezt a tömböt a kazettán, majd (ha elegendő hely van a számítógépben) törli a "b" néven esetleg meglévő tömböt, és az új "b" tömböt a kazettáról betölti. A kazettán tárolt tömbök visszatöltésére a MERGE nem használható.
A fenti módszerrel stringtömböket is tárolhatunk ill. visszatölthetünk. Amikor a számítógép egy stringtömböt megtalál, a képernyőre a "Character array:" és a tömb nevét írja ki. Egy stringtömb betöltésénél a számítógépben nem csak az azonos nevű stringtömb, hanem valamennyi ilyen nevű string is törlődik.
A byte-ok tárolását olyan információk esetében használjuk, amikor az információ felhasználására semmiféle hivatkozás sincs. Ez az információ lehet például egy televíziós kép, felhasználói grafikus karakter stb. Byte-ok tárolásánál és visszatöltésénél a CODE kulcsszót is használjuk. Például:

SAVE "Tv kep" CODE 16384,6912

A memóriában történő tárolás egysége a byte (amely egy és 255 közé eső szám), és minden byte-hoz egy cím tartozik (a cím egy 0 és 65535 közé eső szám). A CODE utáni első szám a kazettán tárolandó első byte címe, míg a második szám a tárolandó byte-ok száma. Esetünkben a 16384 az ún. display file első byte-jának címe (a display file tárolja a televíziós képet), míg a 6912 az ebben a file-ban lévő byte-ok száma, vagyis így a televíziós képernyő tartalmát tároljuk. (Ezt ki is próbálhatjuk!) A "tv kep" név szerepe ugyanaz, mint a programoknál.
A byte-ok visszatöltésénél ezt kell írni:

LOAD "Tv kep" CODE

A CODE utáni számokat a következő alakban is írhatjuk:

LOAD név CODE kezdőcím, hossz

Ebben a " hossz" csak biztonságból kell, amikor ugyanis a számítógép az adott néven megtalálja a byte-okat a kazettán, csak akkor fogja betölteni a számítógép memóriájába, ha a byte-ok száma nem nagyobb, mint a megadott " hossz ". Ezzel elkerülhető, hogy olyan adatokat is felülírjunk, amelyeket nem akarunk. Ellenkező esetben a gép az R Tape loading error hibaüzenetet írja ki. A "hossz" számát elhagyhatjuk: ekkor a számítógép a megadott néven talált byte-okat (számuktól függetlenül) beolvassa a kazettáról.
A "kezdőcím" a visszatöltendő első byte címét adja meg, és ez különbözhet attól a címtől, ahonnan a tárolás történt; ha viszont ez a két cím megegyezik, a LOAD utasításban a "kezdőcím" is elhagyható.
A CODE 16384,6912 a TV-képek tárolásánál és visszatöltésénél gyakran használt, így ehelyett egyetlen kulcsszó is használható, ez a SCREEN$. Például:

SAVE "Tv kep" SCREEN$
LOAD "Tv kep" SCREEN$

Ez az a ritka esetek közé tartozik, amikor a VERIFY nem használható. A VERIFY, kiírja a képernyőre a kazettán talált különböző típusú információk neveit, így mire az ellenőrzés végére ér, a display file már megváltozik, így az ellenőrzés hibás eredményt adna. Minden más esetben, amikor a SAVE utasítást használjuk, a VERIFY is használható.
A következőkben összefoglaljuk az ebben a fejezetben vizsgált négy utasítás működését.

SAVE
A megadott néven információt tárol a kazettán. Ha a név üres string vagy 10-nél több karakterből' áll, "F" hiba keletkezik. A SAVE után mindig megjelenik a következő üzenet: Start tape, then press any key) Indítsd el a magnetofont, és nyomd meg bármelyik gombot). A tárolás egy gomb megnyomására kezdődik.

1. Program és változók:

SAVE név LINE sorszám

a programot és a változókat úgy tárolja, hogy a visszatöltésnél a LOAD után automatikusan a

GO TO sorszám

2. Byte-ok: a

SAVE név CODE kezdőcím, hossz

"hossz" számú byte-ot tárol, az első byte címe a "kezdőcím". A

SAVE név SCREEN$

hatása megegyezik a

SAVE név CODE 16384,6912

hatásával, és egy televíziós képet tárol.

3. Tömbök: a

SAVE név DATA betű()

vagy a

SAVE név DATA betű$()

azt a tömböt tárolja, amelynek neve a "betű" vagy a "betű$" (ennek semmi köze a "névhez").

VERIFY
A kazettára vett és a számítógép memóriájában lévő információt hasonlítja össze és ellenőrzi. Ha e kettő nem egyezik, a számítógép az R Tape loading error (betöltési hiba) üzenetet írja ki a képernyőre.

1. Program és változók:

VERIFY név

2. Byte-ok:

VERIFY név CODE kezdőcím, hossz

Ha a megadott néven kazettára vett byte-ok száma nagyobb a megadott "hossz" számnál, ez "R" hibát jelent; egyébként a egadott "kezdőcímtől" kezdve összehasonlítja a kazettára vett és a számítógép memóriájában lévő információt. A

VERIFY név CODE kezdőcím

a megadott néven kazettán tárolt byte-okat a megadott "kezdőcímtől" kezdve a számítógép memóriájában lévőkkel hasonlítja össze. A

VERIFY név CODE

a megadott néven kazettán tárolt byte-okat a számítógép memóriájában lévőkkel hasonlítja össze, a kezdőcím az a memóriacím, amelyről a tárolásnál az első byte-ot vettük. A

VERIFY név SCREEN$

utasítás megegyező hatású a

VERIFY név CODE 16384,6912

utasítással. Ez az ellenőrzés azonban általában hibát jelez.

3. Tömbök: a

VERIFY név DATA betű()

vagy a

VERIFY név DATA betű$()

a megadott néven kazettán tárolt tömböt hasonlítja össze a számítógép memóriájában lévő "betű" vagy "betű$" nevű tömbbel.

LOAD
A kazettáról új információt tölt be, egyúttal a számítógép memóriájából a régit törli.

1. Program és változók:

LOAD név

a számítógép memóriájából törli a régi programokat és változókat, és a megadott néven kazettán tárolt programot és változókat betölti. Ha a programot a SAVE név LINE típusú utasítással tároltuk, a gép a visszatöltés után automatikus ugrást is végrehajt. ha a memóriában nincs elegendő hely az új program és a változók számára, a számítógép a 4 Out of memory hibaüzenetet írja ki, és ebben az esetben a régi programot és változókat nem törli.

2. Byte-ok:

LOAD név CODE kezdőcím, hossz

Ha a megadott néven kazettára vett byte-ok száma nagyobb a megadott "hossz" értéknél, ez "R" hibát okoz; egyébként a számítógép a megadott "kezdőcímtől" kezdve a memóriába tölti a byte-okat, és a korábban ott lévő információt felülírja. A

LOAD név CODE kezdőcím

a megadott néven kazettán lévő byte-okat a megadott "kezőcímtől" kezdve a memóriába tölti, és a korábban ott lévő információt felülírja. A

LOAD név CODE

a megadott néven kazettán lévő byte-okat a memóriába tölti, a kezdőcím az a memóriacím, amelyről a tárolásnál az első byte-ot vettük; az érintett memóriarész tartalma átíródik.

3. Tömbök: a

LOAD név DATA betű()

illetve

LOAD név DATA betű$()

a memóriában lévő "betű" illetve "betű$" nevű tömböt törli, és a kazettáról beolvassa az újat. Ha az új tömb számára nincs elegendő hely a memóriában, a számítógép a 4 Out of memory hibaüzenetet írja ki, és ebben az esetben a régi tömböt nem törli.

MERGE
Ú j információt tölt be a kazettáról, a törlés szelektív.

1. Program és változók: a

MERGE név

a megadott néven kazettán lévő programot a memóriában lévő programmal "egyesíti", azaz csak akkor töröl (és helyettesít újjal) egy régi programsort ill. változót, ha a betöltendő programban is van ilyen számú sor ill. ilyen nevű változó.
Ha a memóriában nincs elég hely a régi program és változók valamint az új program és változói számára, a számítógép a 4 Out of memory hibaüzenetet írja ki.

2. Byte-ok: nem használható

3. Tömbök: nem használható

Gyakorlatok

1. Készítsünk olyan kazetta-felvételt, amelyen az első program a visszatöltés után a kazettán lévő programok listáját (menü) írja ki, a felhasználótól megkérdezi, hogy melyik programot akarja használni, és ezt betölti a számítógép memóriájába.

2. Írjuk be és futtassuk a 14. fejezetben leírt, sakkfigurákat megadó programot, majd írjuk be: NEW. A figurákat megjelenítő gombok lenyomása igazolja, hogy funkciójuk nem törlődött. A számítógép kikapcsolása után viszont ez az információ elveszik, és megőrzésének egyetlen módja, hogy kazettára vesszük a SAVE és a CODE utasítással. A huszonegy felhasználói grafikus karakter felvételének legegyszerűbb módja a következő:

SAVE "babuk" CODE USR "a",21*8

majd az ellenőrzésre írjuk be:

VERIFY "babuk" CODE

Ez a byte-ok tárolásának módszere, amelyet a televíziós kép tárolásánál is használtunk. Az első tárolandó byte címe USR "a", amely az első felhasználói grafikus karakter bitmintáját meghatározó nyolc byte közül az első byte címe, míg a tárolandó byte-ok száma 21*8 mivel a 21 grafikus karakter mindegyike nyolc byte-ot tartalmaz.
A visszatöltés a szokásos módon történhet:

LOAD "babuk" CODE

Ha a visszatöltés eltérő memóriakapacitású Spectrumba történik, vagy ha a felhasználói grafikus karakterek címeit megváltoztattuk (ez megfelelő módszerekkel megtehető), a visszatöltésnél óvatosan kell eljárnunk. Ilyenkor ezt írjuk:

LOAD "babuk" CODE USR "a"

Az USR lehetővé teszi a grafikus karakterek esetleges eltérő címre történő visszatöltését is.

A ZX nyomtató

Megjegyzés: az LPRINT, LLIST, COPY utasítások nem standard BASIC utasítások, bár az LPRINT néhány más típusú számítógépen is használható. Ha ZX nyomtatóval is rendelkezünk, ennek működését a mellékelt használati utasításbál ismerhetjük meg. Ebben a fejezetben a működtetéshez szükséges BASIC utasításokat tárgyaljuk.
Az első kettő, az LPRINT és az LLIST ugyanúgy működik, mint a már megismert PRINT és LIST, csak a televízió helyett a nyomtatóra íratják ki az információt. (Az L betűnek történelmi okai vannak: a BASIC bevezetésekor a televíziós képernyő helyett elektromos írógépet használtak, így a PRINT valójában kinyomtatást jelentett. Nagyobb mennyiségű információ megjelenítése esetén a számítógéphez kapcsolt gyors sornyomtatót (Line printer) használtak, így az LPRINT eredeti jelentése "Line printer PRINT").
Próbáljuk ki a következő programot:

10 LPRINT "Ez a program"
20 LLIST
30 LPRINT ' "a karakterkeszletet nyomtatja ki." '
40 FOR n=32 TO 255
50 LPRINT CHR$ n;
60 NEXT n

A harmadik itt szereplő utasítás a COPY, amely a televíziós képernyő tartalmát másolja át a nyomtatóra. Példaként a fenti program listáját írassuk a képernyőre a LIST paranccsal, majd írjuk be:

COPY

Vigyázzunk: a COPY a számítógép által automatikusan a képernyőre írt információra nem alkalmazható, mivel ez egy parancs végrehajtásakor törlődik a képernyőről. Így a COPY előtt vagy a LIST parancsot is használni kell, vagy a nyomtatóra íratást az LLIST alkalmazásával kell végrehajtani.
A nyomtató működése a BREAK gombbal (CAPS SHIFT és SPACE) állítható le.
Ha ezeket az utasításokat akkor használjuk, amikor a számítógéphez nincs nyomtató kapcsolva, a kimeneti információt elveszítjük, és a számítógép a kivetkező utasításnál folytatja a végrehajtást.
Írjuk be és futtassuk a következő programot:

10 FOR n=31 TO 0 STEP -1
20 PRINT AT 31-n,n; CHR$ (CODE "0"+n);
30 NEXT n

A képernyőn a felső jobb sarokból átlós irányban lefelé haladó karaktereket fogunk látni, majd a képernyő aljának elérése után a scroll? kérdés jelenik meg.
A 20-as sorban az AT 31-n,n helyett írjuk be: TAB n! A futtatás eredménye ezúttal is ugyanaz lesz, mint előbb.
A 20-as sorban most a PRINT kulcsszót cseréljük ki, és írjuk be helyette: LPRINT. Ekkor a scroll? nem fog megjelenni (ez a nyomtató használatánál sohasem jelenik meg), és a karakterek kiíratása tovább folytatódik: az F-től 0-ig. terjedő betűk is láthatók lesznek.
A 20-as sorban a TAB n helyére írjuk vissza: AT 31-n,n; az LPRINT maradjon továbbra is a sorban. Ekkor csak egyetlen sor szimbólumot kapunk. Az eltérés magyarázata az, hogy az LPRINT hatására nem azonnal kezdődik meg a nyomtatás, hanem egy sornak megfelelő képinformáció előbb egy átmeneti tárba kerül, majd a számítógép ezt egyszerre küldi ki a nyomtatónak. A nyomtatás a következő esetekben kezdődi-kel:

  1. ha az átmeneti tár megtelik,
  2. olyan LPRINT utasítás után, amelyik végén nincs vessző vagy pontosvessző
  3. ha egy vessz ő , aposztróf vagy TAB hatására új sor következik
  4. egy program végén, ha még maradt kinyomtatandó szöveg.

A 3. pont a tabulátor-mozgatást (TAB tartalmazó programváltozat működésére ad magyarázatot. Amikor a programban AT szerepel, a sorszámot nem veszi figyelembe a számítógép, és az LPRINT pozíció (hasonlóan a PRINT pozícióhoz, csak ezúttal nem a képernyőn, hanem a nyomtatón) a megadott oszlopszámra változik. Az AT hatására a számítógép sohasem küld ki egy sort a nyomtatónak.

Gyakorlat
Nyomtassuk ki a 17. fejezetben megadott program futtatásával és a COPY segítségével a szinusz függvényt!

Kiegészítő berendezések használata

A ZX Spectrumhoz a nyomtatón kívül más berendezéseket is csatlakoztathatunk.
A ZX Microdrive nagysebességű, nagykapacitású tároló-berendezés, amely a kazettás magnetofonnál sokkal rugalmasabban használható háttértároló. Működtetésénél nem csak a SAVE, VERIFY, LOAD és MERGE utasítások használhatók, hanem a PRINT, LIST, INPUT és INKEY$ is.
A több Spectrum összekapcsolását és kölcsönös kommunikációját biztosító hálózat olyan, hogy egyetlen Microdrive egység több számítógépet is kiszolgálhat.
Az RS232 szabványos interface segítségével a Spectrumhoz billentyűzet, nyomtató, számítógép és más különféle berendezés csatlakoztatható még akkor is, ha ezeket nem kifejezetten a Spectrummal való használatra tervezték.
A külső berendezések működtetéséhez a billentyűzeten néhány külön kulcsszót is találunk (ezeket azonban csak külső berendezések csatlakoztatása esetén használhatjuk), amelyek a következők: OPEN#, CLOSE#, MOVE, ERASE, CAT és FORMAT.

Az IN függvény és az OUT utasítás

A processzor a PEEK függvény illetve a POKE utasítás segítségével információt olvashat ki a memóriából, illetve (a RAM esetében) információt írhat be a memóriába. A processzor nem törődik azzal a ténnyel, hogy a memória ROM, RAM vagy valamilyen más típusú: csak azt tudja, hogy 65536 memóriacím létezik, és mindegyik címről egy byte információ olvasható ki (a gyakorlatban ez nem mindegyik címnél igaz), és mindegyik címre egy byte információ írható be (ez az információ bizonyos címeknél elveszik). Ezzel teljesen analóg módon 65536 bemeneti-kimeneti egység is létezik. Ezeket I/O portoknak nevezzük, amely az Input/Output port rövidítése. Ezeket az egységeket a processzor például a billentyűzet vagy a nyomtató működésénél használja. Az I/O portok vezérlésére a BASIC programozási nyelvben az IN függvény és az OUT utasítás szolgál.
AZ IN a PEEK-hez hasonló függvény. Alakja:

IN cím

A függvény argumentuma a kérdéses I/O port címe, míg függvényértéke az erről a portról leolvasott byte.
Az OUT a POKE-hoz hasonló utasítás. Alakja:

OUT cím, érték

Az utasítás a megadott című portba a megadott értéket írja. A címek értelmezése nagymértékben függ a számítógép többi részének szervezésétől. Gyakran előfordul, hogy több különböző cím ugyanazt az egységet jelöli ki. A Spectrum esetében érdemes a címet bináris alakban elképzelni, mivel az egyes bitek működése általában egymástól független. A 16 címbitet a következőképpen jelöljük (az "A" az address szóra utal, jelentése cím):

A15, A14, A13, A12, ..., A2, A1, A0

e bben a jelölésrendszerben
az A0 az 1-es helyértékű bit (tehát jelentése 0 vagy 1),
az A1 a 2-es helyértékű bit (tehát jelentése 0 vagy 2) ,
az A2 a 4-es helyértékű bit (tehát jelentése 0 vagy 4) stb.
Az A0 , A1 , A2, A3 és A4 biteknek nagyon lényeges szerepük van.

normális esetben ezek 1 értékűek. ha valamelyik közülük 0, ez azt jelzi a számítógépnek, hogy valamilyen speciális dolgot kell végrehajtani. A számítógép egyszerre csak egy dologgal foglalkozhat, így a fenti öt bitből egyidejűleg csak egy lehet 0 értékű. Az A6 és A7 biteket a számítógép figyelmen kívül hagyja (az elektronikában járatosak tetszőleges módon felhasználhatják). A legkedvezőbben használható címek 32 ill. ennek többszörösénél eggyel kevesebb értékűek, azaz amelyekben az A0...A4 bitek mind 1 értékűek. Az A8, A9 stb. bitek különleges információk közlésére használhatók.
A kiolvasott ill. beírt byte-ok 8 bitből állnak, ezek jelölése: D7, D6, ..., D1, D0 (a D itt a data szóra utal, jelentése adat).

A következőkben a felhasznált I/O portok címeit ismertetjük. A bemeneti címek egy csoportja a billentyűzettel és az EAR csatlakozóval kapcsolatos. A billentyűzet nyolc félsorból áll, amelyek egyenként 5 gombot tartalmaznak.

IN 65278

a CAPS SHIFT gombtól a V gombig terjedő félsort olvassa le

IN 65022 az A gombtól a G gombig terjedő félsort olvassa le
IN 64510

a Q gombtól a T gombig terjedő félsort olvassa le

IN 63486

az 1-es gombtól az 5-ös gombig terjedő félsort olvassa le

IN 61438

a 0-ás gombtól a 6-os gombig terjedő félsort olvassa le

IN 57342

a P gombtól a 7-es gombig terjedő félsort olvassa le

IN 49150

az ENTER gombtól a H gombig terjedő félsort olvassa le

IN 32766

a SPACE gombtól a B gombig terjedő félsort olvassa le

(E címek általános alakja 254+256*(255-2^n), ahol az "n" 0-tól 7-ig terjed.)
A leolvasott byte-okban a D0...D4 bitek az adott félsorban az öt billentyűnek felelnek meg: D0 a szélső billentyűt, míg D4 a középre eső billentyűt jelenti. A gomb megnyomásakor a kérdéses bit értéke 0, ha nincs megnyomva 1. A D6 bit az EAR csatlakozó értékét adja.
A 254-es című kimeneti port a hangszórót (D4) és a MIC csatlakozót (D3) hajtja meg, és egyúttal a border színt is beállítja (D2, D1 és D0).
A 251-es című port a nyomtatót működteti mind olvasási, mind írási üzemmódban: az olvasásnál azt deríti ki, hogy a nyomtató kész-e újabb információ fogadására, míg írásnál a kinyomtatandó információt küldi ki.
A 254, 247 és 239-es című portok a 22. fejezetben emlitett külső berendezések üzemeltetésére szolgálnak.
Futtassuk a következő programot:

10 FOR n=0 TO 7: REM felsorok
20 LET a=254+256*(255-2^n)
30 PRINT AT 0,0; IN a: GO TO 30

Nyomjunk meg tetszőleges billentyűket az adott félsorban! Ha ezt a félsort meguntuk, a BREAK lenyomása után a következő "n" érték kipróbálásához írjuk be:

NEXT n

A vezérlő-, adat- és címsínt a készülék hátoldalán lévő csatlakozóra is kivezették, így a Spectrummal szinte minden olyan művelet elvégezhető, ami a Z80 mikroprocesszorral megtehető (néhányat a Spectrum többi hardware része megakadályozhat ).

A memória

A számítógép belsejében minden bitek (1-esek és 0-ák) formájában tárolódik, de a gép általában ezek nyolcas csoportjait, a byte-okat (azaz 0 és 255 közé eső számokat) kezel. Legyen bármi a tárolt információ (például valaminek az ára, egy vállalat címe), ezt előbb byte-okká alakítja a gép, és ezeket már kezelni tudja.
Minden olyan helyhez, ahol egy byte tárolható, egy cím tartozik, amely egy 0 és FFFFh közötti szám (a "h" betű hexadecimális számot jelöl, lásd B függelék). Így egy cím tárolásához két byte szükséges. A memóriát tehát számozott rekeszek hosszú sorozataként képzelhetjük el, amelyben minden rekesz egy byte-ot tartalmazhat. Ezek a rekeszek azonban nem mind egyformák. A 16K RAM memóriával rendelkező alapgépben a 8000h címtől az FFFFh címig terjedő rekeszek egyszerűen nem is léteznek. A 4000h és a 7FFFh cím közötti terület RAM rekeszeket tartalmaz, amely azt jelenti, hogy ezek tartalma megváltoztatható. A 0 és 3FFFh cím közötti területen ROM rekeszek helyezkednek el, amelyekből csak a számítógép készítésekor elhelyezett tartalom olvasható ki, ezekbe beírni nem lehet.

Egy rekesz tartalmának vizsgálata a PEEK függvénnyel lehetséges, amelynek argumentuma a rekesz címe, míg függvényértéke a rekesz tartalma. Például a következő program a ROM első 21 byte-ját írja ki a képernyőre )a hozzátartozó címmel együtt):

10 PRINT "Cim"; TAB 8; "Byte"
20 FOR a=0 TO 20
30 PRINT a; TAB 8; PEEK a
40 NEXT a

Ezek a byte-ok számunkra nem sokat mondanak, ám a processzor számára utasításokat jelentenek. Egy rekesz (ha az RAM) tartalmának megváltoztatására a POKE utasítást használjuk, amelynek alakja a következő:

POKE cím, új tartalom

ahol a "cím" és az "új tartalom" aritmetikai kifejezés lehet. Például ha ezt írjuk:

POKE 31000,57

akkor a 31000-es címen lévő byte új értéke 57 lesz. Ellenőrzésképpen írjuk be:

PRINT PEEK 31000

(Más értékekkel is kipróbálhatjuk!) Az új érték -255 és +255 közötti lehet, és ha negatív, értékéhez 256 adódik hozzá.
A memóriába való írás képessége óriási lehetőséget jelent számunkra, de csak akkor, ha ezzel a lehetőséggel helyesen élni is tudunk. Hibás használattal mindent tönkre tehetünk: egy rossz címen elhelyezett rossz értékkel hosszú órák munkájával kidolgozott programunkat ronthatjuk el. Szerencsére a számítógépben nem okozhatunk maradandó károsodást.

A következőkben a RAM terület működését vesszük kissé közelebbről szemügyre (akit ez a rész nem érdekel, nyugodtan kihagyhatja). A különböző fajta információk tárolása a memória különböző részeiben történik (ezt az ábra mutatja).

Ezek a területek az éppen bennük tárolt információ befogadására elegendőek csupán, így ha adott ponton újabb információt helyezünk el (például egy új programsort vagy változót írunk be), ennek helybiztosítása úgy történik, hogy az adott pont felett minden felfelé lép. Megfordítva: ha információt törlünk, minden lefelé lép.
A display file a televíziós képet tárolja. A képinformáció elrendezése meglehetősen különös, így itt a PEEK és a POKE használata nem sok haszonnal jár. A képernyő minden karakter-pozíciója egy 8*8 képelemből álló négyzet, és minden egyes képelem vagy 0 (paper) vagy 1 (ink) értéket vehet fel, így ezt a bitmintát bináris ábrázolásban 8 byte írja le (soronként egy-egy). Ám ez a nyolc byte nem együtt tárolódik! A képernyő egy teljes sorának 32 karakteréhez tartozó megfelelő sorokat tárolja együtt a memória (ez 32 byte), mivel a televízió elektronsugarának erre az információra van szüksége, amikor a képernyőt balról jobbra letapogatja. Mivel a teljes kép 24 sorból (soronként nyolc letapogatásból) áll, azt várnánk, hogy összesen 172 letapogatási sort tárol a memória egymás után sorrendben. Ez azonban nem így van. Először a képernyő 0-tól 7-es soráig terjedő részének legfelső letapogatási sorai következnek, majd ugyanezen képernyő sorok második letapogatási sorai, és így tovább egészen a legalsó letapogatási sorig. Ezután ugyanez ismétlődik a képernyő 8-as és 15-ös sorai közötti részre, majd a 16-os és 23-as sorok közötti rész következik. Mindennek az a következménye, hogy a képernyő tartalmával kapcsolatban a PEEK és a POKE helyett a SCREEN$ és a PRINT AT illetve a PLOT és a POINT használata a gyakorlatilag megvalósítható.
Az attributumok az egyes karakter-pozíciók színeit és egyéb jellemzőit tartalmazzák az ATTR függvény formátumának megfelelően. Ezeket a memória soronként, sorrendben tárolja.
A nyomtató puffer (átmeneti tár) a nyomtatóba küldendő karaktereket tárolja.
A rendszerváltozók a számítógép állapotára vonatkozó különféle információkat tárolnak. A következő fejezet ezek teljes felsorolását adja, most csak arra hívjuk fel a figyelmet, hogy ezek kézül néhány (például a CHANS, PROG, VARS, E_LINE stb.) a különböző memóriaterületek közötti határok pillanatnyi címeit tartalmazzák. A rendszerváltozók nem BASIC változók, és neveiket a számítógép nem ismeri fel.
A Microdrive terület csak a Microdrive egységgel használható. Egyéb esetben nem tartalmaz semmit.
A csatorna információ a bemeneti és kimeneti eszközökről tartalmaz információt, ilyen eszköz a billentyűzet (képernyő alsó részével együtt), a képernyő felső része és a nyomtató.
Minden BASIC programsor a következő alakú:

Vegyük észre, hogy a Z80 egyéb két byte-os számaival ellentétben, a sorszám fordított sorrendben tárolódik (előbb áll a nagyobb helyértékű byte), azaz abban a sorrendben, ahogy azt beírjuk.
Egy programbeli számkonstanst képi karakteres formája után bináris alakja követi, amely a CHR$ 14 elválasztó karakterből és az azt követő öt byte-ból áll (ez jelenti magát a számot).

A változók, típusuknak megfelelően, különböző formátumúak. A változók neveiben az első betű mindig kisbetű.

Aritmetikai változó, amelynek neve egy betűből áll:

Aritmetikai változó, amelynek neve egynél több karakterből áll:

Numerikus tömb:

 

A tömbelemek sorrendje a következő:
Először azok az elemek következnek, amelyek első indexe 1 ezután következnek azok az elemek, amelyek első indexe 2 ezután következnek azok az elemek, amelyek első indexe 3 és így tovább az első index valamennyi értékére.
Egy adott első index mellett a tömbelemek sorbaállítasa a fenti módszer szerint a második index alapján történik, és így tovább egészen az utolsó indexig. Például a 12. fejezetben megadott 3*6-os "b" tömb elemeit a következő sorrendben tárolja a memória:
b(1,1), b(1,2), b(1,3), b(1,4), b(1,5), b(1,6), b(2,1), b(2,2), ..., b(2,6), b(3,1), b(3,2), ..., b(3,6).

Egy FOR - NEXT ciklus ciklusváltozója:

String:

Stringtömb:

A kalkulátor a BASIC rendszer aritmetikával foglalkozó része, és azokat a számokat, amelyeken a műveleteket végzi, általában a kalkulátor stackben tárolja.
A tartalék terület az egyelőre még fel nem használt részt foglalja magába.
A processzor stacket a Z80 használja például visszatérési címek stb. tárolására.
A GO SUB stackről az 5. fejezetben már volt szó.

A RAMTOP rendszerváltozóval megjelölt byte a BASIC rendszer által használt legnagyobb című memóriabyte-ot jelenti. Láttuk, hogy a NEW törli a RAM memóriát, de a törlés csak eddig a címig tart, tehát a felhasználói grafikus karaktereket nem érinti. A RAMTOP cím a CLEAR utasítással és egy szám megadásával megváltoztatható:

CLEAR új ramtop

Ennek hatásai a következők:

A RUN is végrehajt törlést, de a RAMTOP címet sohasem változtatja meg.
A CLEAR fenti alkalmazásának két célja lehet: a RAMTOP címet vagy följebb helyezzük, hogy még több helyet biztosítsunk a BASIC rendszernek (ez a felhasználói grafikus karakterek felülírásával jár); vagy lejjebb helyezzük a RAMTOP címet, és így megnöveljük a NEW által nem törölhető RAM területet.
Vizsgáljuk most azt az esetet, amikor a számítógép memóriája megtelik. Ennek gyorsabb elérése érdekében írjuk be a NE W parancsot, majd a CLEAR 23800 utasítást. Ha ezután egy programot írunk be, a számítógép egy idő után nem fogad el több sort és a hangszóróból búgó hangot hallunk. Két idevágó, közel azonos jelentésű hibaüzenetet is kiírhat a számítógép (4 Memory full illetve G No room for line). A búgó hangot akkor is halljuk, ha a beírt programsor a képernyőn 23 sornál hosszabb - ekkor a beírt rész nem vész el, csak nem látjuk. A búgás arra figyelmeztet, hogy zárjuk le a sort. A búgás hosszúságát a 23608-as című rekeszbe írt számmal beállíthatjuk. A szokásos hosszúsághoz a 64-es érték tartozik.

A 0 kivételével tetszőleges szám leírható a következő alakban:

+-m * 2^e

ahol

+- az előjel
m a mantissza, amely 1/2 és 1 közé eső érték (1 nem lehet)
e az exponens, amely pozitív vagy negatív egész szám.

Az m leírására használjuk a bináris számrendszert! Mivel m törtszám, a bináris pont is szerepelni fog benne (hasonlóan a tízes számrendszer tizedespontjához), majd ezt követi a bináris törtrész (hasonlóan a tizedestörthöz). Így a bináris számrendszerben

a fél megfelelője .1
a negyed megfelelője .01
a háromnegyed megfelelője .11
a tized megfelelője .0001100110011...

Mivel az m szám 1-nél kisebb, a bináris pont előtt nem szerepelnek bitek, illetve mivel értéke legalább 1/2, a bináris pont utáni bit mindig 1. A számítógépben egy szám tárolására öt byte szolgál a következő kiosztásban:

  1. A mantissza első nyolc bitje kerül a második byte-ba (tudjuk, hogy az első bit mindig 1) , a második nyolc bit a harmadik byte-ba, a harmadik nyolc bit a negyedik byte-ba, míg a negyedik nyolc bit az ötödik byte-ba kerül.
  2. második byte első bitjébe (amely egyébként mindig 1 lenne) az előjel bit kerül: 0 ha az előjel plusz, 1 ha az előjel mínusz.
  3. Az első byte-ba az exponens+128 kerül. Például legyen a szám 1/10:
    1/10 = 4/5 * 2^-3
    tehát bináris számrendszerben az m mantissza =.110011001100 ... ( mivel a 33. bit 1, a 32. bitet 0 - ról 1-re kerekítjük ) . Az e exponens = -3

A fenti három szabály alkalmazásával az öt byte a következő:

A -65535 és +65535 közötti egész számok tárolására egy másik módszer a következő:

  1. az első byte 0.
  2. A második byte pozitív számnál 0, negatív számnál FFh.
  3. A harmadik és negyedik byte a szám (ill . a szám+131072, ha negatív) kisebb és nagyobb helyértékű byte-ja.
  4. Az ötödik byte 0.

A rendszerváltozók

A memória 23552-től 23733-ig című byte-jait a számítógép speciális célokra használja. Ezeket a tartalmakat kiolvashatjuk (PEEK), és így hasznos dolgokat tudhatunk meg a rendszerről, illetve néhány tartalmát át is írhatjuk (POKE). Ezeket a byte-okat rendszerváltozóknak nevezzük, nevük is van, de ezeket nem szabad összetéveszteni a BASIC nyelvben használt változókkal. A számítógép a rendszerváltozókra való hivatkozásként ezeket a neveket nem fogja felismerni (a megadott mnemotechnikai rövidítések csupán a jobb megértést szolgálják).
A következő táblázatban a rendszerváltozókat és felhasználásukat adjuk meg. Az első oszlopban megadott rövidítések jelentése a következő:

X

- ezt a változót nem szabad megváltoztatni, mert ez a rendszer összezavarodását vonhatja maga után

N - a változó átírása nem befolyásolja a rendszer helyes működését

Az első oszlopban megadott számok azt mutatják, hogy a változó hány byte-ból áll. Két byte esetében az első byte a kisebb helyértékű byte (ez a szokásos forma megfordítottja). Így például az "n" címen elhelyezkedő kétbyte-os változóba a "v" érték beírását a következő módon hajthatjuk végre:

POKE n,v-256*INT (v/256)
POKE n+1,INT (v/256)

A változó kiolvasására a következő kifejezést használhatjuk:

PEEK n+256*PEEK (n+1)

Megkegyzés Cím Név Tartalom (jelentés)
N8 23552 KSTATE

A billentyűzet leolvasásában használatos.

N1 23560 LAST K Az éppen megnyomott gombot tárolja.
1 23561 REPDEL

Az az idő (50-ed másodpercben), amíg egy gombot lenyomva kell tartani, mielőtt a funkciója ismétlődne. Beállított értéke 35, de a POKE utasítással ez megváltoztatható.

1 23562 REPPER

Egy lenyomott gomb funkciójának két egymás utáni ismétlése között eltelt idő (50-ed másodpercben). Beállított értéke 5.

N2 23563 DEFADD

A felhasználó által definiált függvények kiértékelésékor az argumentumok címe (értéke egyébként 0).

N1 23565 K DATA

A billentyűzetről bevitt színvezérlések második byte-ját tárolja.

N2 23566 TVDATA

A televízióba menő szín-, AT és TAB vezérlések byte-jait tárolja.

X38 23568 STRMS Az "élő" csatornák címei.
2 23606 CHARS

A karakterkészlet (a betűköztől a copyright szimbólumig) címénél 256-tal kisebb érték. Eredetileg ez ROM-cím, de saját karakterkészlet is meghatározható egy RAM-ban, és a CHARS beállítható ennek a címére.

1 23608 RASP A figyelmeztető búgás hosszúsága.
1 23609 PIP

A gomb elfogadását jelző hang hosszúsága.

1 23610 ERR NR

Az üzenetkódnál eggyel kisebb érték. Kezdetben 255 (a -1 miatt), így a PEEK 23610 eredménye 255.

X1 23611 FLAGS

A BASIC rendszer vezérlésére szolgáló jelzőbitek (flag).

X1 23612 TV FLAG

A televízióval kapcsolatos jelzőbitek.

X2 23613 ERR SP

Ez a processzor stack azon elemének címe, amely hiba esetén visszatérési címként szolgál.

N2 23615 LIST SP

Automatikus listázás visszatérési címének címe.

N1 23617 MODE

A K, L, C, E vagy G kurzort határozza meg.

2 23618 NEWPPC

Az ugrás sorszáma.

1 23620 NSPPC

A soron belül az utasítás száma ugrásnál. Átírási sorrend: előbb NEWPPC, majd NSPPC, ami az adott sor adott utasítására ugrást eredményez.

2 23621 PPC

A végrehajtás alatt álló utasítás sorának száma.

1 23623 SUBPPC

A végrehajtás alatt álló utasítás soron belüli száma.

1 23624 BORDOR

Border szín*8; ez egyúttal a képernyő alsó részének attributumait is tartalmazza.

2 23625 E PPC

Az aktuális sor (amelyet a programkurzor jelez) száma.

X2 23627 VARS

A változók címe.

N2 23629 DEST

Az értékadás alatt álló változók címe.

X2 23631 CHANS Csatorna-adatok címe.
X2 23633 CURCHL Az aktuális bemeneti és kimeneti információ címe.
X2 23635 PROG A BASIC program címe.
X2 23637 NXTLIN A program következő sorának címe.
X2 23639 DATADD

Az utolsó DATA listaelem címe.

X2 23641 E LINE A beírás alatt álló parancs címe.
2 23643 K CUR

A kurzor címe.

X2 23645 CH ADD

A következő értelmezendő karakter címe: a PEEK argumentuma utáni karakter vagy egy POKE utasítás végén lévő ENTER.

2 23647 X PTR

A ? utáni karakter címe.

X2 23649 WORKSP A munkaterület címe.
X2 23651 STKBOT A kalkulátor stack legalsó címe.
X2 23533 STKEND A tartalék memóriaterület címe.
N1 23655 BREG

A kalkulátor "b" regisztere.

N2 23656 MEM

A kalkulátor memóriájaként használt tárterület címe (általában MEMBOT, de nem mindig).

1 23658 FLAGS2

További jelzőbitek.

X1 23659 DF SZ

A képernyő alsó részében lévő sorok száma (beleértve egy üres sort is).

2 23660 S TOP

Automatikus listázásnál a legfelső programsor száma.

2 23662 OLDPPC Annak a sornak a száma, amelyre a CONTINUE után ugrás történik.
1 23664 OSPCC Annak az utasításnak a soron belüli száma, amelyre a CONTINUE esetén az ugrás történik.
N1 23665 FLAGX Jelzőbitek.
N2 23666 STRLEN A string hossza értékadásnál.
N2 23668 T ADDR

A szintaktikai táblázat következő elemének címe (agyon ritkán használatos).

2 23670 SEED

Az RND induló értéke. A RANDOMIZE ezt a változót állítja be.

3 23672 FRAMES

Három byte (legelöl a legkisebb helyértékű), 20 ms-onként értéke eggyel nő, kivéve a perifériakommunikációs utasítások végrehajtásának idejét. (Lásd 18. fejezet)

2 23675 UDG

Az első felhasználói grafikus karakter címe. Megváltoztatható például úgy, hogy a felhasználói grafikus karakterek számának csökkentésévei nagyobb memóriaterülethez jutunk.

1 23677 COORDS Az utoljára felrajzolt képelem x-koordinátája.
1 23678  

Az utoljára felrajzolt képelem y-koordinátája.

1 23679 P POSN

33 - (a kiírási pozíció oszlopszáma)

1 23680 PR CC Az LPRINT esetében a következő nyomtatási pozíció címének kisebb helyértékű byte-ja. (Nyomtatópuffer mutatója)
1 23681  

Az LPRINT esetében a következő nyomtatási pozíció címének nagyobb helyértékű byte-ja.

2 23682 ECHO E

33 - (oszlopszám) és 24 - (sorszám) (a képernyő alsó része) a bemeneti puffer végétől számítva.

2 23684 DF CC

A PRINT pozíció címe a display file-ban.

2 23686 DFCCL

A képernyő alsó részének megfelelő DF CC.

X1 23688 S POSN

33 - (PRINT pozíció oszlopszáma)

X1 23689   24 - (PRINT pozíció sorszáma)
X2 23690 SPOSNL

A képernyő alsó részének megfelelő S POSN.

1 23692 SCR CT

A felfelé léptetéseket (scrolling) számlálja: a leállásig (scroll?) végrehajtandó felfelé léptetések számánál eggyel nagyobb érték. Ha az egyes kiíratások előtt egynél nagyobb számot írunk erre a címre, a képernyőn folyamatos felfelé léptetés történik leállás nélkül.

1 23693 ATTR P

A tényleges, állandó színek és egyéb jellemzők (a jellemzőket megadó utasításoknak megfelelően).

1 23694 MASK P

Az "átlátszó" színek és egyéb jellemzők. Az 1 értékű attributum bitek azt jelzik, hogy a megfelelő jellemző bitjét nem az ATTR P határozza meg, hanem a képernyő jellemzője változatlan marad.

N1 23695 ATTR T

Ideiglenes színek és egyéb jellemzők; az utasításokban használható színtételeknek megfelelően.

N1 23696 MASK T

A MASK P ideiglenes megfelelője.

1 23697 P FLAG Jelzőbitek.
N30 23698 MEMBOT

A kalkulátor memóriaterülete; a kalkulátor stackben el nem helyezhető számokat tárolja.

2 23728  

Nem használt.

2 23730 RAMTOP

A BASIC rendszer utolsó byte-jának címe.

2 23732 P-RAMT

A RAM-terület utolsó byte-jának címe.

A következő program a változók területének első 22 byteját írja ki:

10 FOR n=0 TO 21
20 PRINT PEEK (PEEK 23627+256*PEEK 23628+n)
30 NEXT n

Hasonlítsuk össze az "n" ciklusváltozó értékeit a fenti programban kiadódó értékekkel!
Cseréljük ki a 20-as sort:

20 PRINT PEEK (23755+n)

Ekkor a program-terület első 22 byte-ját kapjuk. Az eredményt hasonlítsuk össze magával a programmal!

A gépi kód használata

Ez a fejezet azok számára készült, akik ismerik a Z80-as mikroprocesszor gépi kódját, vagyis a Z80-as processzor utasításkészletét . Ezeket az ismereteket számos könyvből megszerezhetjük. (Lásd pl.: Z80-as sorozat -VIII. rész: CPU utasításkészlet) , a kezdők számára is készült több. (Ha ilyen könyvet keresünk, a cím valami ilyen lehet: "A Z80 gépi kódja ( vagy assembler nyelve ) kezdőknek"). Ha ezekben a könyvekben a ZX Spectrumot is említik, annál jobb.
Ezeket a programokat általában assembler nyelven írták, amely első látásra rejtélyesnek tűnik, de néni gyakorlattal megértésük már nem olyan nehéz. (Az assembler nyelv utasításait az A. függelékben találjuk.) Ahhoz, hogy ezeket a programokat a számítógépen futtathassuk, előbb byte-ok sorozatává kell alakítanunk (kódolás): a programnak ezt a formáját gépi kódnak nevezzük. Ezt a fordítást általában maga a számítógép végzi egy assemblernek nevezett program segítségével. A Spectrumba nincs beépítve assembler, de ez kazettán megvásárolható. Ennek hiányában a fordítást magunknak kell elvégezni (feltéve, ha a program nem túl hosszú).
Vegyük például a következő rövid programot:

ld bc,99
ret

amely a "bc" regiszterpárt a 99-es értékkel tölti fel. Ez lefordítva a következő négy gépi kódú byte-ot adja:

1, 99, 0, 201

( az 1, 99, 0 az "ld bc,99" megfelelője, a 201 a " ret" megfelelője).

Ha rendelkezésre áll a gépi kódú program, a következő lépés ennek bevitele a számítógépbe. (Egy assembler ezt általában automatikusan elvégzi.) El kell döntenünk, hogy a memóriában hol helyezzük el: a leghelyesebb, ha a BASIC terület és a felhasználói grafikus karakterek között biztosítunk helyet. Tegyük fel, hogy 16K memóriával rendelkező Spectrttmmal dolgozunk. Ebben a RAM magasabb címekhez tartozó területének felosztása a következő:

Írjuk be:

CLEAR 32499

Ezzel a 32500 címmel kezdődően 100 byte-os területet kapunk.

A gépi kódú program bevitelére egy BASIC programot futtathatunk, például a következőt:

10 LET a=32500
20 READ n: POKE a,n
30 LET a=a+1: GO TO 20
40 DATA 1,99,0,201

(Ez a program a négy meghatározott byte bevitele után az E Out of DATA üzenettel leáll.)
A gépi kódú program futtatásához az USR függvényt használjuk, de ezúttal numerikus argumentummal, amely a kezdőcím. A függvény értéke a "bc" regiszterpár értéke lesz a gépi kódú programról való visszatéréskor. Így ha ezt írjuk:

PRINT USR 32500

eredményül 99-et kapunk.
A BASIC rendszerre való visszatérési cím tárolása a szokásos módon történik, így a visszatérést a Z80 "ret" utasítása végzi. Egy gépi kódú programban az IY és az I regisztereket csak különösen körültekintően használhatjuk.
A gépi kódú program kazettán is tárolható a következő módon:

SAVE "név" CODE 32500,4

A tárolás viszont nem olyan, hogy a visszatöltésnél a program automatikusan futtassa is önmagát: ez nem valósítható meg a tárolásnál, viszont egy egyszerű BASIC programmal igen:

10 LOAD "" CODE 32500,4
20 PRINT USR 32500

Először írjuk be:

SAVE "név" LINE sorszám

majd

SAVE "xxx" CODE 32500,4
LOAD "név"

Ez visszatölti és automatikusan futtatja a BASIC programot, ami viszont betölti és futtatja a gépi kódú programot.

Függelék

A karakterkészlet

Vezérlő karakterek
0-5
-
6
,
7
EDIT
8
kurzor balra
9
kurzor jobbra
10
kurzor le
11
kurzor fel
12
DELETE
13
ENTER
14
NUMBER
15
-
16
INK
17
PAPER
18
FLASH
19
BRIGHT
20
INVERSE
21
OVER
22
AT
23
TAB
24-31
-

Látható karakterek

A számítógép üzenetei

Ezek az üzenetek a képernyő alsó részén akkor jelennek meg, amikor a számítógép BASIC parancsok vagy program végrehajtását akár helyes működés után, akár valamilyen hiba következtében befejezi. Az üzenet részei a következők: kódszám vagy -betű; a leállás körülményeit, okait megvilágító rövid magyarázat; a leállás helyét megadó sorszám és a soron belüli utasításszám. (egy közvetlen parancsnál a sorszám 0. A soron belül az első utasítás a sor elején álló, a második utasítás az első kettőspont vagy a THEN után következő, stb.)
A CONTINUE működése nagy mértékben függ az üzenettől. Általános esetben a CONTINUE az utolsó üzenetben megadott sornál illetve soron belüli utasításnál folytatja a végrehajtást, de a 0, 9 és D kódú üzenetek kivételek ez alól (lásd még a 4. függeléket).
A következő táblázat az üzeneteket tartalmazza. A harmadik oszlopban megadjuk, hogy milyen körülmények között fordulnak elő az egyes üzenetek; ehhez a részhez a C. függelékben találunk kiegészítő információkat. Például az A Invalid argument üzenet az SQR, LN, ACS és ASN függvényeknél fordulhat elő, míg a C. függelék pontosan leírja, hogy mely argumentumok érvénytelenek.

 

Kód Jelentése Körümények
0 OK
Sikeres végrehajtás után, vagy egy olyan sorra ugratásnál, amelynek száma nagyobb, mint a létező programsorok száma. Ez az üzenet nem változtatja meg azt a sort és azon belüli utasítást, amelyre a CONTINUE, hatására az ugrás történik.
tetszőleges
1

NEXT without FOR
(NEXT utasítás FOR nélkül) Nincs ciklusváltozó (létrehozása a FOR utasítással nem történt meg), viszont szerepel egy egyszerű változó ugyanezen a néven.

NEXT
2

Variable not found
(Nincs ilyen változó) Egyszerű változónál ezt a hibaüzenetet kapjuk, ha a változót azelőtt használjuk, mielőtt értékadása egy LET, READ vagy INPUT utasításban ill. kazettáról beolvasva megtörtént volna vagy egy FOR utasítással létrehoztuk volna. Indexes változónál ez a hibaüzenet, ha a változót azelőtt használjuk, mielőtt dimenzióit egy DIM utasításban megadtuk volna vagy kazettáról beolvastuk volna.

tetszőleges
3

Subscript wrong
(Helytelen index) Az index túlmutat a tömb méretén ill. helytelen számú index szerepel. Ha az index negatív vagy 65535-nél nagyobb, "B" hiba.

indexes változók, részstringek
4

Out of memory
(Nincs hely a memóriában) A számítógépben nincs elegendő hely a végrehajtandó művelet számára. Ha a számítógép ebben az állapotában marad, a DELETE segítségével törölhetjük a parancsot, majd a programból is törölhetünk néhány sort (később ezeket visszaírhatjuk), így lesz helyünk pl. a CLEAR használatával a memóriaterület átrendezésére.

LET, INPUT, FOR, DIM, GO SUB, LOAD, MERGE, esetleg kifejezések kiértékelésénél
5

Out of screen
(Nincs hely a képernyőn) Egy INPUT utasítás a képernyő alsó részén 23 sornál több sort akar létrehozni. Ugyanez a hibaüzenet pl. a következőnél is: PRINT AT 22,...

INPUT, PRINT AT
6

Number too big
(Túl nagy szám) A számítások során kb. 10^38-nál nagyobb szám keletkezett.

tetszőleges aritmetikai művelet
7

RETURN without GO SUB
(RETURN utasítás GO SUB nélkül) A GO SUB utasítások számánál logikailag több RETURN van.

RETURN
8 End of file
(File vége)
Microdrive stb. műveletek
9

STOP statement
(STOP utasítás) Ezután a CONTINUE nem a STOP utasítást ismétli, hanem az azutáni utasításnál folytatja a végrehajtást.

STOP
A

Invalid argument
(Érvénytelen argumentum) Egy függvény argumentuma valamilyen okból nem megfelelő.

SQR, LN, ASN, ACS, USR (string argumentummal)
B

Integer out of range
(A megengedett tartományon kívül eső egész szám) Ha egy egész számot kell megadni, a lebegőpontos argumentumot a gép a legközelebbi egész értékre kerekíti. Ha ez a megfelelő tartományon kívülre esik, akkor ez a hibaüzenet jelenik meg. Tömbökre lásd még a 3-as hibát.

RUN, RANDOMIZE, POKE, DIM, GO TO, GO SUB, LIST, LLIST, PASUE, PLOT, CHR$, PEEK, USR (numerikus argumentummal)
C

Nonsense in BASIC
(A BASIC-ben ilyen nem fordul elő) A (string)argumentum szövege nem alkot érvényes kifejezést.

VAL, VAL$
D

BREAK - CONT repeats
(Megszakítás - a CONT ismétel) A BREAK lenyomására perifériás művelet közben. A hibaüzenet után a CONTINUE működése normális: megismétli az utasítást. (Vesd össze az "L" hibaüzenettel!)

LOAD, SAVE, VERIFY, MERGE, LPRINT, LLIST, COPY. Akkor is, ha a scroll? kérdésre az N, SPACE vagy STOP gombot nyomjuk meg.
E

Out of data
(Nincs több adat a DATA listában) A READ utasítással beolvasni akarunk, de a DATA lista már véget ért.

READ
F

Invalid file name
(Érvénytelen file-név) kazettára vétel (SAVE) üres vagy 10 karakternél hosszabb néven.

SAVE
G

No room for line
(Nincs hely egy programsor számára) A memóriában nincs már elég hely egy újabb programsor elhelyezésére.

Egy sor bevitele a programba.
H

STOP in INPUT
(STOP az INPUT utasítás közben) Egy INPUT adat a STOP paranccsal kezdődik, ill. az INPUT LINE esetében a gomb lett megnyomva.

INPUT
I

FOR without NEXT
(FOR utasítás NEXT nélkül) Egyszer sem végrehajtandó FOR ciklus (pl. FOR a=l TO 0) után a megfelelő NEXT utasítás nem szerepel.

FOR
J

Invalid I/O device
(Érvénytelen I/O eszköz)

Microdrive, stb. műveletek
K

Invalid colour
(Érvénytelen szín) A megadott számkód nem megfelelő érték.

INK, PAPER, BORDER, FLASH, BRIGHT, OVER, INVERSE; valamint a megfelelő vezérlő karakterek után
L

BREAK into program
(Megszakítás a program futása közben) A BREAK lenyomása két utasítás között történt. Az üzenetben megadott sor- és utasításszám a BREAK lenyomása előtti utasítást jelzi. A CONTINUE a következő utasításnál folytatja a végrehajtást (lehetővé téve esetleges ugrásokat is) vagyis utasítást nem ismétel meg.

tetszőleges
M

RAMTOP no good
(Helytelen RAMTOP érték) A RAMTOP rendszerváltozó értékére megadott szám túl nagy vagy túl kicsi.

CLEAR; esetleg RUN
N

Statement lost
(Már nem létező utasítás) Ugrás olyan utasításra, amely már nem létezik.

RETURN, NEXT, CONTINUE
O

Invalid stream
(Érvénytelen stream)

Microdrive, stb. műveletek
P

FN without DEF
(FN DEF nélkül)

FN
Q

Parameter error
(Paraméter hiba) Az argumentumok száma helytelen, ill. valamelyik nem megfelelő típusú (szám helyett string vagy megfordítva)

FN
R

Tape loading error
(Hiba a kazettáról való betöltésnél) A kazettán megvan a file, de valamilyen okból nem olvasható be, vagy az ellenőrzésnél hiba van.

VERIFY, LOAD, MERGE

A ZX Spectrum leírása

A billentyűzet
A ZX Spectrum karakterei nem csak egyszerű jeleket (betűk, számjegyek stb.), hanem összetett szimbólumokat (kulcsszók, függvény-nevek stb.) is magukba foglalnak, és ezeket egy gombnyomással, a bennük szereplő egyes betűk egyenkénti lenyomása nélkül beírhatjuk. Valamennyi függvény és parancs megvalósítása érdekében néhány billentyűnek öt vagy még több különböző jelentése lehet, ezek megkülönböztetése a SHIFT billentyűkkel (a CAPS SHIFT, vagy a SYMBOL SHIFT és a kérdéses gomb egyidejű megnyomása) vagy a számítógép különböző üzemmódjaival történik. Az üzemmódot a kurzor jelzi: ez egy villogó betű, amely egyúttal a következő beírásra kerülő karakter helyét is jelzi.
A K (Keyword - kulcsszó) üzemmód automatikusan felváltja az L üzemmódot, ha a számítógép parancsot vagy programsort vár (adatbevitel helyett); a sorban elfoglalt pozíciójából pedig következik, hogy sorszám vagy kulcsszó következik-e. Ez történik a sor elején, közvetlenül a THEN után, vagy a kettőspont után (kivéve egy karaktersorozatban). Ha SHIFT nincs, a következő gombnyomás vagy a gombra írt kulcsszóként, vagy számjegyként lesz értelmezve.
Minden más esetben az L (Letters - betű) üzemmód fog előfordulni. Ha SHIFT nincs, a következő gombnyomás a gombra irt fő szimbólumként lesz értelmezve, a betűknél ez kisbetűt jelent.
Mind a K, mind az L üzemmódban a SYMBOL SHIFT és egy további gomb megnyomása a gombra pirossal írt kiegészítő karakterként lesz értelmezve, míg a CAPS SHIFT és egy számjegy gomb egyidejű megnyomása a gomb fölé fehér színnel irt vezérlő funkciókat jelenti. A CAPS SHIFT a többi gombbal egyidejűleg használva a K üzemmódban nem befolyásolja a kulcsszót, míg az L üzemmódban a kisbetű helyett nagybetűt jelent.
A C (Capitals - nagybetű) üzemmód az L üzemmód egyik változata, amelyben a betűk nagybetűként jelennek meg. A CAPS LOCK alkalmazásával e két üzemmód közötti átmenetet hajthatjuk végre.
Az E (Extended - kiterjesztett) üzemmódot további karakterek (elsősorban összetett szimbólumok) elérésére használjuk. Ebbe az üzemmódba a két SHIFT gomb egyidejű megnyomásával térhetünk át, érvényessége csak egy gomb lenyomásáig tart. Ebben az üzemmódban egy betű, ha SHIFT nincs, a gomb fölé zöld színnel írt karaktert vagy összetett szimbólumot jelenti, míg ha valamelyik SHIFT gombot is egyidejűleg megnyomjuk, jelentése a gomb alá pirossal írt karakter vagy szimbólum. A számjegy gombok jelentése E üzemmódban: a SYMBOL SHIFT egyidejű lenyomásánál egy összetett szimbólum, egyébként színvezérlés.
A G (Graphics - grafikus) üzemmód a GRAPHICS (CAPS SHIFT és 9) megnyomásával érhető el, és mindaddig érvényben marad, míg ezeket a gombokat (vagy csak a 9-es gombot) újra meg nem nyomjuk. Ebben az üzemmódban a számjegy gombok (kivéve a GRAPHICS és a DELETE gombokat) mozaikszerű ábrát jelentenek, míg a betűk (a V, W, X, Y és Z gombok kivételével) a felhasználó által definiált grafikus karaktereket.

Ha bármelyik gombot egy másodpercnél tovább lenyomva tartjuk, funkcióját folyamatosan ismétli.
A billentyűzetről bevitt karakterek a képernyő alsó részén jelennek meg, közvetlenül a kurzor előtt. A kurzor mozgatása a CAPS SHIFT, és 5 (balra) ill. a CAPS SHIFT és 8 (jobbra) gombokkal történhet. A kurzor előtti karaktert a DELETE (CAPS SHIFT és 0) törli. Az egész sor törlése az EDIT (CAPS SHIFT és 1), majd ezt követően az ENTER megnyomásával lehetséges. Az ENTER megnyomására a szintaktikailag helyes sor vagy végrehajtódik, vagy programsorként tárolódik, vagy, adatbevitelként lesz értelmezve. A szintaktikai hibát előfordulása közelében egy villogó ? jelzi.
Programsorok bevitelénél ezek listája a képernyő felső részén jelenik meg. Az utolsóként bevitt sort aktuális sornak (Current line) nevezzük, ezt egy > jelzi, amit a (CAPS SHIFT és 6) és a (CAPS SHIFT és 7) gombokkal mozgathatunk. Az EDIT (CAPS SHIFT és 1) hatására az aktuális sor a képernyő aljára kerül és szerkeszthető.
Egy parancs vé g rehajtásán á l illetve egy program futtat á sánál az eredmények a képernyő felső részén jelennek meg, és mindaddig ott maradnak, míg vagy egy programsort be nem léptetünk, vagy üres sornál az ENTER gombot meg nem nyomjuk, vagy a illetve jeleket nem használjuk. A képernyő alsó részén jelennek meg a számítógép üzenetei is, ezek kódjait (egy számjegy vagy egy betű) a B. függelék tartalmazza. Az üzenet a következő gomb megnyomásáig marad a képernyőn (és K üzemmódot jelent).
Bizonyos feltételek mellett a CAPS SHIFT és SPACE gombok egyidejű megnyomása BREAK jelentésű, ami D vagy L üzenet kiadásával leállítja a számítógép működését. A gép ezt a jelet
1. egy utasítás végrehajtásának befejezése után vagy
2. magnetofon ill. nyomtató működtetése közben fogadja el.

A televíziós képernyő
A képernyő 24, egyenként 32 karakter hosszúságú sorbál áll, és két részre oszlik: a felső rész legfeljebb 22 sort tartalmazhat, és programlisták vagy eredmények kijelzésére szolgál. Ha a képernyő felső 22 sora betelik, az egész rész egy sorral feljebb lép. Ha így olyan sor tűnne el, amelyet még nem láthattunk, a számítógép a scroll? üzenet kiadásával leáll. Az N, a SPACE vagy a STOP gombok megnyomása a program futását a D BREAK - CONT repeats üzenettel leállítja; az összes többi gomb a felfelé léptetés (scrolling) művelet folytatását tovább engedi. A képernyő alsó része parancsok, programsorok és adatok (INPUT) bevitelére szolgál, illetve a számítógép üzenetei is itt jelennek meg. Az alsó rész kezdetben két sorból áll (ebből a felső üres), de a beírt szöveg méretének megfelelően bővül. Ha eléri a felső részben kijelzett szöveget, azt felfelé lépteti.
Minden karakter-pozícióhoz attributumok (jellemzők) tartoznak, amelyek a paper (háttér) és az ink színt, a két fényességi szint valamelyikét és a karakter villogását (vagy normál kiíratását) határozzák meg. A következő színek adhatók meg: fekete, kék, piros, bíbor, zöld, vigágoskék, sárga és fehér. A képernyő keretének színe a BORDER utasítás segítségével szintén megváltoztatható.
Minden karakter-pozíció 8*8 képelemből áll, és egy adott karakter-pozícióban minden képelem egyenként paper vagy ink színűre állítható, így nagy felbontású képet kapunk.Egy karakter-pozíció attributumai egy karakter beírásakor vagy egy képelem kirajzolásakor állíthatók be. A beállítás két módon (állandó ill. ideiglenes) a következő hat kiíratási paraméter segítségével végezhető el: PAPER, INK, FLASH, BRIGHT, INVERSE és OVER. A képernyő felső részének állandó paramétereit a PAPER, INK stb. utasításokkal adjuk meg, és hatásuk a következő megfelelő utasításig érvényes. (A számítógép bekapcsolása után e paraméterek értékei a következők: fekete ink és fehér paper szín, normál fényesség, villogás nincs, normál video és felülírás nincs.) A képernyő alsó részén az állandó paraméterek a következők: a paper színt a border szín adja, az ink szín ennek kontrasztja (fekete vagy fehér), normál fényesség, nincs villogás, normál video és nincs felülírás.
Az ideiglenes paramétereket a PRINT, LPRINT, INPUT, PLOT, DRAW és CIRCLE utasításokba ágyazott PAPER, INK stb. listaelemek segítségével ill. a PAPER, INK stb. vezérlő karakterekkel állíthatjuk be. (Utóbbiak után egy további byte adja meg a paraméter értékét.) Az ideiglenes paraméterek hatása csak a PRINT stb. utasítások végéig tart, illetve az INPUT utasításokban addig, amíg a billentyűzetről adatot vár a számítógép. Ezután az állandó paraméterek lesznek érvényesek.
A PAPER és az INK paraméterek értékei 0 és 9 közé esnek.
A 0...7 értékek a karakterek kiírásakor a színeket adják meg:

0 - BALCK fekete
1 - BLUE kék
2 - RED piros
3 - MAGENTA bíbor
4 - GREEN zöld
5 - CYAN világoskék
6 - YELLOW sárga
7 - WHITE fehér

Ha a paraméter értéke 8 ("átlátszó"), ez azt jelenti, hogy egy karakter kiírásakor a képernyő színe változatlan marad.
Ha a paraméter értéke 9 ("kontraszt"), ez azt jelenti, hogy a kérdéses szín (ink vagy paper) fehér vagy fekete, vagyis a másik szín kontrasztja lesz.
A FLASH és a BRIGHT paraméterértéke 0, 1 vagy 8. Az 1 a villogást ill. az extra fényességet, a 0 a normál állapotot jelenti, míg a 8 ("átlátszó") esetében tetszőleges karakter-pozícióban a kérdéses jellemző változatlan marad.
Az OVER és az INVERSE két értéket vehet fel:

OVER 0 az új karakterek átírják a régieket
OVER 1 a régi és az új karakterek bitmintái egyszerre, a kizáró VAGY függvénykapcsolatnak megfelelően jelennek meg (felülírás)
INVERSE 0

az új karakterek kiírása a paper színen az ink színnel történik (normál video)

INVERSE 1

az új karakterek kiírása az ink színen a paper színnel történik (inverz video)

Ha a televízióba egy TAB vezérlő karakter érkezik, két további byte is szükséges a tabulátor "n" végpontjának megadására (a kisebb helyértékű byte áll elől). Ebből a számítógép kiszámítja az "n modulo 32" értéket (n0), majd az ennek megfelelő számú betűköz kiíratásával a kiíratási pozíciót az n0-s oszlopba helyezi.
A vessző vezérlő karakter esetében megfelelő számú (legalább egy) betűköz kiíratásával a kiíratási pozíció a 0-s vagy a 16-os oszlopba kerül. Ha a televízióba az ENTER vezérlő karakter érkezik, a kiíratási pozíció a következő sorba kerül.

A nyomtató
A ZX nyomtatóhoz az információ kivitele egy 32 karakter (egy képernyő-sor) tárolására alkalmas átmeneti táron (pufferen) keresztül történik. Egy sor kiküldése és így a nyomtatás a következő esetekben történik:

  1. ha a puffer megtelik (a kiírandó rész átnyúlik a következő sorba),
  2. ha ENTER karakter érkezik,
  3. a program végén, ha még további nyomtatandó karakterek vannak,
  4. a a TAB vagy a vessző a nyomtatási pozíciót új sorba helyezi.

A TAB ill. a vessző vezérlő karakter hatása megegyezik a képernyőre íratásnál megismertekkel.
Az AT vezérlő karakter esetében a nyomtatási pozíció meghatározásában csak az oszlopszámot veszi figyelembe a számítógép, a sorszámot figyelmen kívül hagyja.
A nyomtatásnál az INVERSE és OVER vezérlő karakterek (ill. utasítások) hatása ugyanaz, mint a képernyőre íratásnál, míg a PAPER, INK, FLASH vagy BRIGHT hatástalan.
A BREAK megnyomására a nyomtató leáll, a hibaüzenet "D"
Ha a nyomtató nincs a számítógéphez csatlakoztatva, a kimeneti információ elvész.

A ZX Spectrum BASIC

A számok tárolása 9 vagy 10 sz á mjegy pontosságú. A legnagyobb használható szám kb. 10^38, míg a legkisebb (pozitív) kb. 4*10^-39. A számok tárolása a ZX Spectrumban lebegőpontos bináris alakban történik egy "e" exponens byte (1<= e <= 255) és négy "m" mantissza byte (1/2 <= m <= 1) segítségével. Ez az m*2^(e-128) számot jelenti.
Mivel 1/2 <= m <= 1, az "m" mantissza legnagyobb helyértékű bitje mindig 1 értékű lenne. Éppen ezért a gyakorlatban ezt a bitpozíciót az előjel jelzésére használjuk: ez pozitív számoknál 0, negatív számoknál 1.
Kis egész számok ábrázolása speciális alakban történik: az első byte 0, a második az előjel byte (értéke 0 vagy FFh), míg a harmadik és negyedik byte az egész szám kettes komplemens alakban (előbb a kisebb helyértékű byte következik).

Az aritmetikai változók nevei tetszőleges hosszúságúak, az első karakter mindig egy betű, a többi betű vagy azám lehet. A betűközöket és a színvezérlő karaktereket a számítógép figyelmen kívül hagyja, és a betűket mindig kisbetűkké alakítja.
A FOR - NEXT ciklusok ciklusváltozóinak nevei egy betűből állhatnak.
A numerikus tömbök nevei szintén egybetűsek lehetnek, és ez azonos is lehet egy egyszerű változó nevével. A dimenziók számára és méretére nincs megkötés. Az index számozása az 1-es értéknél kezdődik.
A stringek hosszúsága nem korlátozott. A stringnév egy betűből és az azt követő $-jelből áll.
A stringtömbök dimenziója és ezek mérete szintén tetszőleges lehet. Nevük egy betűből és az azt követő $-jelből áll, de azonos nevű string és stringtömb nem fordulhat elő. Egy adott tömb valamennyi stringje azonos hosszúságú, amelyet a DIM utasítás utolsó dimenziója határoz meg. Az index számozása az 1-es értéknél kezdődik.
Részstring-képzés: stringek részstringjeit a részstringképző formula segítségével adhatjuk meg. Részstringképző lehet:

  1. üres
  2. aritmetikai kifejezés
  3. aritmetikai kifejezés TO aritmetikai kifejezés

A részetringek megadásában a részstringképző két módon használható:

  1. stringkifejezés (részstringképző)
  2. stringtömb változó (index, ..., index, részstringképző)

Utóbbi jelentése megegyezik a következővel:

stringtömb változó (index, ..., index) (részstringképző)

Az 1. esetben legyen a stringkifejezés értéke s$. Ha a részstringképző üres, az eredmény s$, azaz a részstring megegyezik az eredeti stringgel. Ha a részstringképző egy m értékű aritmetikai változó, az eredmény az s$ m-edik karaktere (azaz a részstring hosszúsága 1) . Ha a részstringképző a 3. pontban megadott alakú, legyen az elől álló aritmetikai kifejezés értéke m (ennek feltételezett értéke 1) , míg a második kifejezésé n (feltételezett értéke az s$ hosszúsága). Ha 1<= m ,<= n, az a$ hosszúsága, akkor az eredmény az s$ azon részstringje, amely az m-edik karakterrel kezdődik, és az n-edik karakterrel fejeződik be. Ha 0 <= n <= m, az eredmény üres string. Minden más esetben 3-as hibakódot ad a rendszer. A részstring-képzés végrehajtása (ha zárójelekkel más sorrendet nem jelölünk ki) megelőzi a függvények vagy a műveletek végrehajtását. A részstringek értékadását lásd a LET utasításnál!
Ha egy string karakterei idézőjelet is tartalmaznak, azt megkettőzve kell beírni.

Függvények
A függvények argumentumát nem szükséges zárójelbe tenni, ha az konstans vagy egy (akár indexes vagy részstringképző formulával képzett) változó.

Függvény Az argumentum típusa Függvényérték
ABS szám

abszolút-érték

ACS szám arkusz-koszinusz (radiánban)
"A" hiba, ha x<-1 vagy x>1
AND

bináris művelet, a jobb oldali operaadus mindig szám. A bal oldali operandus szám:

A AND B = A ha B<>A
A AND N = 0 ha B=0
A bal oldali operandus string: A$ AND B = A$ ha B <>0
A$ AND B = "" ha B=0
ASN szám

arkusz-szinusz (radiánban)
"A" hiba, ha x<-1 vagy x>1

ATN szám arkusz-tangens (radiánban)
ATTR két argumentum (x és y), mindkettő más szám; zárójelbe kell tenni

Olyan szám, amelynek bináris alakja a televíziós képernyő x sorának és y oszlopának attributumait tartalmazza kódolt formában. Ha a 7-es bit (legnagyobb helyértékű) értéke 1, villogást, 0 értéke normál állapotot jelöl. Ha a 6-os bit értéke 1, extra fényességet, 0 értéke normál fényességet jelöl. Az 5...3 bitek a paper színt, a 2...0 bitek az ink színt jelölik.
Ha a 0<=x<=23 és a 0<=y<=31 feltételek nem teljesülnek, "B" hiba.

BIN bináris kifejezés

Valójában nem függvény, hanem számok jelölésének egy módja. A BIN utáni 0-kból és 1-esekből álló sorozat a számot jelöli bináris formában.

CHR$ szám

Az a karakter, amelynek kódja x (a legközelebbi egész számra kerekítve).
Ha a 0<=x<=255 feltétel nem teljesül, "B" hiba.

CODE string Az x első karakterének kódja, (ill . 0 , ha az x üres string ).
COS szám (radiánban)

koszinusz x

EXP szám e^x (exponenciális)
FN  

Az FN és az utána álló betű a felhasználó által definiált függvényt jelent (lásd DEF). Az argumentumokat zárójelbe kell tenni; a zárójel akkor is kell, ha argumentum nincs.

IN szám Az x portról (processzor szinten) beolvasott byte (ahol 0<=x<=FFFFh). A bc regiszterpárba az x értéket tölti, és az in a(c) assembler nyelvű utasítást hajtja végre.
INKEY$ nincs

A billentyűzetet olvassa le. Az eredmény az a karakter, amelyet az utasítás végrehajtásának pillanatában lenyomva tartott gomb L vagy C üzemmódban jelent, egyébként üres string.

INT szám egész rész (mindig lefelé kerekít)
LEN string

a string hosszúsága

LN szám természetes alapú logaritmus (az alap "e") Ha x<=0, "A" hiba
NOT szám 0 ha x<>0; 1 ha x=0. A NOT prioritása 4.
OR bináris művelet, mindkét operandus szám a OR b = 1 ha b<>0
a OR b = a ha b=0
Az OR prioritása 2.
PEEK szám

A memória azon byte-jának tartalma, amelynek címe x (a legközelebbi egész számra kerekítve).
"B" hiba, ha x nincs a 0...65535 tartományban.

PI nincs

A PI megközelítő értékét adja (3.14159265...)

POINT két argumentum (x,y), mindkettő szám; zárójelbe kell tenni 1 ha az (x,y) képelem ink színű, 0 ha paper színű .
Ha a 0<=x<=255 és a 0<=y<=175 feltételek nem teljesülnek, "B" hiba.
RND nincs (a gép által adott belső argumentum) A következő álvéletlen szám abban a sorozatban, amelynek előállítása a következő: 75 hatványai modulo 65537, levonva 1, osztva 65536-tal. Az y eredményre igaz: 0<=y<=1
SCREEN$ két argumentum (x és y), mindkettő szám

Az a karakter, amely normál vagy invertált formában a képernyő x sorú és y oszlopú pozíciójában megjelenik. Az eredmény üres string, ha a karakter nem felismerhető.
Ha 0<=x<=23 és a 0<=y<=31 feltételek nem teljesülnek, "B" hiba.

SGN szám

előjelfüggvény. -1 negatív, 0 a zérus és +1 pozitív x esetében.

SIN szám (radiánban)

szinusz x

SQR szám

négyzetgyök. Ha x<0, "A" hiba.

STR$ szám

Az a karaktersorozat, amely az x kiíratásánál jelenne meg.

TAN szám (radiánban)

tangens x

USR szám

Az x kezdőcímű gépi kódú szubrutint hívja. Visszatéréskor az eredményt a BC regiszterpár tartalma adja.

USR string

Az x-hez tartozó felhasználói grafikus karakter bitmintájának címe.
"A" hiba, ha az x nem "a" és "u" közötti (egyetlen) betű vagy nem felhasználói grafikus karakter.

VAL string

Az idézőjelek nélküli x aritmetikai kifejezésként történő kiértékelése.
"C" hiba, ha az x szintaktikai hibát tartalmaz vagy stringértéket ad. A kifejezéstől függően más hibák is előfordulhatnak.

VAL$ string

Az idézőjelek nélküli x stringkifejezésként való kiértékelése.
"C" hiba, ha az x szintaktika hibát tartalmaz vagy numerikus értéket ad. A kifejezéstől függően más hibák is előfordulhatnak.

- szám

negálás

Bináris műveletek

+ összeadás ( számoknál ) vagy konkatenáció (stringeknél)  
- kivonás
*

szorzás

/ osztás
^ hatványozás. "B" hiba, ha a bal oldali operandus negatív.)
= egyenlő

A két operandusnak azonos típusúnak kell lenni. Az eredmény szám:
1 ha a reláció igaz,
0 ha a reláció hamis.

> nagyobb
< kisebb
<= kisebb egyenlő
>= nagyobb egyenlő
<> nem egyenlő

Függvények és műveletek prioritása

Művelet prioritás
index-számítás és részstring-képzés 12
valamennyi függvény a NOT és az unáris minusz kivételével 11
^ (hatványozás) 10
unáris minusz (a minusz használata megatív számok jelzésére) 9
*, / 8
+, - (a minusz itt kivonást jelent) 6
=, >, <, >=, <=, <> 5
NOT 4
AND 3
OR 2

Utasítások

A felsorolásban használt betűk jelentése:

a egyetlen betű
v változó
x, y, z aritmetikai kifejezések
m, n

a legközelebbi egész számra kerekített aritmetikai kifejezések

e kifejezés
f stringet adó kifejezés
s egymástól kettősponttal elválasztott kifejezések sorozata
c listaelemek. Az egyes listaelemeket vessző vagy pontosvessző választja el egymástól. Egy szín-listaelem alakja megegyezik egy PAPER, INK, FLASH, BRIGHT, INVERSE vagy OVER utasítás alakjával.

Bárhol tetszőleges kifejezéseket használhatunk, ez alól az egyetlen kivétel egy utasítás elején álló sorszám. Az INPUT, a DEF és a DATA kivételével valamennyi utasítás parancsként vagy programban is használható (bár némelyik parancsként ill. programban való használata nem sok haszonnal jár). Egy parancs- vagy programsor több utasítást is tartalmazhat, ezeket kettősponttal kell elválasztani egymástál. Egy soron belül egy utasítás helyére semmiféle megkötés sincs (ez alól kivétel az IF és a REM, lásd ott).

BEEP x,y
Hatására a beépített hangszórón x másodpercig y félhanggal a közép C feletti hangmagasságú hang szólal meg (ha az y negatív, a hang adott számú félhanggal a közép C alatti).

BORDER m
A képernyő keretének színét valamint a képernyő kihasznált területén az alsó rész paper színét határozza meg.
"K" hiba, ha m nincs a 0...7 tartományban.

BRIGHT n
A következő kiírt karakter fényességét határozza meg. Az n=0 normál, az n=1 extra fényességet jelent, az n=8 "átlátszó".
"K" hiba, ha n nem 0, 1 vagy 8.

CAT
A Microdrive vagy más külső berendezés nélkül hatástalan.

CIRCLE x,y,z
Olyan z sugarú kört rajzol, amelynek középpontja (x, y).

CLEAR
Az összes változót törli, az ezek által elfoglalt memóriaterületet felszabadítja. RESTORE és CLS műveletet hajt végre, a PLOT pozíciót a bal alsó sarokba helyezi, és törli a GO SUB stacket.

CLEAR n
Lásd CLEAR, de azon kívül a RAMTOP rendszerváltozót az n értékre állítja, és az új GO SUB stacket ide helyezi.

CLOSE
A Microdrive vagy más külső berendezés nélkül hatástalan.

CLS
(Töröld a képernyőt!) Törli a display file-t.

CONTINUE
A programot onnan folytatja, ahol a legutóbbi, nem 0 üzenetű leállás történt. Ha az üzenet 9 vagy L volt, a következő utasítással folytatódik a végrehajtás (beleértve az esetleges ugrásokat is). A többi esetben a leállást okozó utasítást ismétli meg. Ha az utolsó üzenet egy parancssorban volt, a CONTINUE, megkísérli folytatni a parancssort, és vagy ciklusba kerül (ha a hiba a 0:1-ben volt), vagy a 0-ás üzenetet adja ki (ha a hiba a 0:2-ben volt), vagy "N" hiba keletkezik (ha a hiba a 0:3-ban vagy ennél nagyobb helyen történt).
A CONTINUE a billentyűzeten a CONT rövidítésként szerepel.

COPY
A képernyő felső 22 sorának másolatát küldi a nyomtatóba (ha a nyomtató nincs a számítógéphez csatlakoztatva, az utasítás hatástalan). A COPY nem használható a képernyőn megjelenő automatikus listázások kinyomtatására.
A BREAK megnyomására "D" hiba.

DATA e1, e2,e3,...
A DATA lista része. Programban használható.

DEF FN a(a1, ...,ak)=e
A felhasználó által definiált függvény megadása. Programban használható. Valamennyi a és a1...ak vagy egyetlen betű, vagy egy betű és az utána álló $-jel (utóbbi string argumentumot vagy string eredményt jelöl).
Ha argumentum nincs, alakja: DEF FN a()=e.

DELETE f
A Microdrive vagy más külső berendezés nélkül hatástalan.

DIM a(n1.nk)
Az esetleges a nevű tömböt törli, és létrehozza a "k" dimenziójú (n1,...nk) a nevű tömböt. A tömbelemek kezdeti értéke 0.

DIM a$(n1,...nk)
Az esetleges a$ nevű tömböt vagy stringet törli, és létrehozza a "k" dimenziójú a$ nevű tömböt (n1,...nk). A stringtömb elemeinek kezdeti értéke a " ". Olyan fix hosszúságú (nk) stringek tömbjeként fogható fel, amely k-1 dimenziójú (n1,...nk-1).
4-es hiba, ha a tömb számára nincs elegendő hely a memóriában. Egy tömb mindaddig definiálatlan, míg dimenzióit egy DIM utasításban meg nem adjuk.

DRAW x,y
DRAW x,y,0. Az aktuális rajzolási pozícióból kiindulva egyenest rajzol, amelynek végpontja vízszintesen x, függőlegesen y távolságra van a kezdőponttól.
Ha a vonal kifutna a képernyőről, "B" hiba.

DRAW x,y,z
Az aktuális rajzolási pozícióból kiindulva, olyan z nyílásszögű körívet rajzol, amelynek végpontja vízszintesen x, függőlegesen y távolságra van a kezdőponttól.
Ha a vonal kifutna a képernyőről, "B" hiba.

ERASE
A Microdrive vagy más külső berendezés nélkül hatástalan.

FLASH n
A karakterek villogását vagy normál állapotát határozza meg. n=0: normál állapot; n=1: villogás; n=8: változatlan.
"K" hiba, ha n nem 0, 1 vagy 8.

FOR a=x TO y
FOR a=x TO y STEP z

Az esetleges a nevű egyszerű változót törli, és létrehozza az ilyen nevű ciklusváltozót x kezdőértékkel, y végértékkel és z lépésközzel, illetve a FOR utáni utasításra mutató ugrási címet. Ellenőrzi, hogy a kezdőérték nagyobb-e (a lépésköz pozitív értékénél) vagy kisebb-e (a lépésköz negatív értékénél) a végértéknél, és ha igen, a NEXT a utasításig kihagyja az utasításokat. Ha a NEXT hiányzik, "I" hiba. Lásd még a NEXT utasítást!
4-es hiba, ha a ciklusváltozó számára nincs hely a memóriában.

FORMAT f
A Microdrive vagy más külső berendezés nélkül hatástalan.

GO SUB n
A GO SUB utasítás sorszámát egy stackbe tölti, majd úgy működik, mint a GO TO n. RETURN hatására visszatér a GO SUB utasítást követő utasításra (a stackben tárolt sorszám alapján).
4-es hiba, ha nincs elegendő számú RETURN.

GO TO n
Az n számú sorra ugrik (ha ilyen nincs a programban, az ezutáni első sorra).

IF x THEN s
Ha x igaz (nem zérus), akkor az s végrehajtásra kerül. Az s magába foglalja a sor végéig beirt összes utasítást. Az "IF x THEN sorszám" alak nem megengedett.

INK n
Az ezután kiíratásra kerülő karakterek ink színét állítja be. A 0...7 tartományba eső n a szint jelenti, az n=8 jelentése "átlátszó", az n=9 jelentése kontraszt.
Ha az n nem a 0 ...9 tartományba esik, "K" hiba.

INPUT ...
A pontok helyére INPUT listaelemek sorozatát írhatjuk. Az egyes tételek közé (hasonlóan, mint a PRINT utasításban) vesszőt, pontosvesszőt vagy aposztrófot kell tenni. INPUT listaelem lehet:
1. tetszőleges, de nem betűvel kezdődő PRINT listaelem
2. változónév
3. LINE, amely után egy stringváltozó neve áll.
Az 1. pontban az egyes tételek és az elhatárolt jelek hatása ugyanaz, mint a PRINT utasításban. Az egyetlen különbség, hogy a kiírás a képernyő alsó részében kezdődik.
A 2. esetben a számítógép leáll, és a billentyűzetről kell beírni egy kifejezést, amelynek értékét az adott változó felveszi. A billentyűzeten beírtak a szokásos módon a képernyőn is megjelennek, a szintaktikai hibát egy villogó ? jelzi. Stringváltozók esetében a bemeneti puffer két idézőjelet is tartalmazni fog (ezek azonban törölhetők). Ha a beolvasandó rész első karaktere a STOP, a program "H" hibaüzenettel leáll.
A 3. pont működése megegyezik a 2. pontban leírtakkal azzal a különbséggel, hogy a beolvasandó részt, idézőjelek nélkül, stringként kezeli a számítógép. A STOP mechanizmus itt nem működik.

INVERSE n
Az ezután megjelenő karakterek inverz vagy normál megjelenítését vezérli. Ha n=0, a kiírás normál video, azaz a paper színű háttérben ink színű karakter. Ha n=1, a kiírás inverz video, azaz ink színű háttérben paper színű karakter.
Ha n nem 0 vagy 1, "K" hiba.

LET v=e
A v változónak az e értéket adja. A LET kulcsszó nem hagyható el. Az egyszerű változók mindaddig definiálatlanok, míg egy LET, READ vagy INPUT utasításban nem adunk értéket azoknak. Ha a v indexes stringváltozó vagy a részstringképzővel előállított stringváltozó (részstring), az értékadás a Prokrusztész módszerrel történik (rögzített hosszúság): a számítógép az e stringértékből jobbról megfelelő számú karaktert elhagy, vagy az e értéket megfelelő számú betűközzel feltölti, így hosszúsága meg fog egyezni a v változóéval.

LIST
LIST n

A programot a képernyő felső részére listázza. A lista az első képernyő sorban kezdödik; ennek sorszáma n, vagy ha ilyen számú programsor nincs, az ezt követő első létező sorszám. Az aktuális sor az n lesz.

LLIST
LLIST n

Lásd LIST n, de a listázás a nyomtatóra, történik.

LOAD f
Program és változók betöltése.

LOAD f DATA a()
Numerikus tömb betöltése.

LOAD f DATA a$()
Az a$ stringtömb betöltése.

LOAD f CODE m,n
Az m címről kezdve maximálisan n byte betöltése.

LOAD f CODE m
Byte-ok betöltése az m címről kezdve.

LOAD f CODE
Byte-ok visszatöltése azokra a címekre, ahonnan kazettára vételük történt.

LOAD f SCREEN$
LOAD f CODE 16384,6912

A kazettán megkeresi a megfelelő file-t, és betölti a számítógépbe a képernyőállományt; a memória előző tartalmát törli. (Lásd 20. fejezet!)

LPRINT
Lásd PRINT, de a ki í ratás a nyomtatóra történik.

MERGE f
Hasonló a LOAD működéséhez azzal a különbséggel, hogy csak akkor töröl egy régi sort ill. változót, ha a kazettáról betöltendő új programban is van ilyen számú sor ill. ilyen nevű változó.

MOVE f1,f2
A Microdrive vagy más külső berendezés nélkül hatástalan.

NEW
Újraindítja a BASIC rendszert, a programokat és változókat törli; a memóriát a RAMTOP rendszerváltozóban lévő címmel bezárólag használja) az UDG, P RAMT, RASP és PIP rendszerváltozók értékét megtartja.

NEXT
1. megkeresi az a ciklusváltozót
2. értékéhez hozzáadja a lépésközt
3. ha a lépésköz >= 0 és az a értéke nagyobb a végértéknél ill. ha a
lépésköz < 0 és az a értéke kisebb a végértéknél, akkor a FOR utáni utasításra ugrik.
Ha nincs a nevű változó, 2-es hiba. Ha van a nevű változó, de az nem ciklusváltozó, 1-es hiba.

OPEN #
A Microdrive vagy más külső berendezés nélkül hatástalan.

OUT m,n
Processzor szinten az m portra az n byte-ot adja ki. (A BC regiszterpárt feltölti az m címmel, az A regiszterbe az n értékét tölti, majd az out(c),a assembler utasítást hajtja végre.)
Ha 0<=m<=65535 és a -255<=n<=255 feltételek nem teljesülnek, "B" hiba.

OVER n
Az ezután kiírandó karakterek felülírását vezérli. Ha n=0, az új karakterek az előzőeket teljesen eltüntetik, és csak az új látszik. Ha n=1, az új és a régi karakterek keveréke látszik: ink színű lesz a képelem, ha ott valamelyik (de nem mindkettő) ink színű; paper színű lesz a képelem ott, ahol mindkettő paper vagy mindkettő ink színű.
Ha n nem 0 vagy 1 "K" hiba.

PAPER n
Lásd INK, csak ez a paper (háttér) színt állítja be.

PAUSE n
Leállítja a számításokat, és a képernyőn n képváltás idejéig a display file jelenik meg (másodpercenként 50 kép). A szünet, megkezdése után, egy gomb megnyomásával megszüntethető.
Ha a 0<=n<=65535 feltétel nem teljesül, "B" hiba. Ha n=0, a szünet nem időzített, és egy gomb megnyomásáig tart.

PLOT c;m,n
Egy ink színű képelemet ír ki az (m, n) koordinátájú pozícióban (a színt az OVER és az INVERSE befolyásolhatja). A PLOT pozíciót megváltoztatja. Ha a c szín-listaelemek másképp nem határozzák meg, az adott képelemet magába foglaló karakter-pozíció ink színe a jelenlegi állandó ink színre változik, míg a többi színjellemző (paper szín, villogás és fényesség) változatlan marad.
Ha a 0<=m<=255 és a 0<=n<=175 feltételek nem teljesülnek, "B" hiba.

POKE m,n
A memória m című rekeszébe az n értéket írja.
Ha a 0<=m<=65535 és a -255<=n<=255 feltételek nem teljesülnek, "B" hiba.

PRINT ...
A pontok helyére PRINT-listaelemek sorozatát írhatjuk. Ezek elválasztására vessző, pontosvessző vagy aposztróf szolgál. Ez az információ a display file-ba, és onnan a képernyőre kerül. Két listaelem közötti pontosvesszőnek nincs különösebb hatása, mindössze elválasztásra szolgál. A vessző a "vessző" vezérlő karaktert, míg az aposztróf az "ENTER" vezérlő karaktert adja ki. Ha egy PRINT utasítás végén sem pontosvessző, sem vessző, sem aposztróf nincs, akkor az ENTER karakter kerül kiadásra. PRINT tétel lehet:

  1. üres (azaz semmi)
  2. aritmetikai kifejezés
    Ha a kifejezés értéke negatív, először a minusz jel kerül kiírásra. Legyen x az érték modulusa.
    Ha x<=10^(-5) vagy x>=10^15, akkor a kiírás exponenciális alakban történik. A mantissza maximálisan nyolc számjegyből áll (az értéktelen nullák nélkül), a tizedespont az első számjegy után áll (ha csak egy számjegy van, tizedespont nincs). Az exponenciális rész az E betűből, az ezután következő + vagy - jelből, és az előjel utáni egy vagy két számjegyből áll. Ha az x-re felírt fenti két feltétel nem teljesül, az x kiírása a szokásos decimális alakban történik, amely nyolc értékes jegyből állhat, és a tizedespont után nincsenek értéktelen nullák. A tizedespont áll legelöl, ha utána zérus következik, például: .03, 0.3. A zérus kijelzése egyetlen 0 számjegy.
  3. string-kifejezés
    A stringben az összetett szimbólumok elé vagy után automatikusan egy betűköz kerül. A vezérlő karakterek hatása érvényesül. A fel nem ismerhető karakterek helyére ? kerül.
  4. AT m,n
    Az AT vezérlő karaktert majd két byte-ot küld ki (az első az m, azaz a sorszám; a második az n, azaz az oszlopszám).
  5. TAB n
    A TAB vezérlő karaktert majd két byte-ot küld ki (amelyek az n tabulátor értéket adják; a kisebb helyértékű byte áll elöl).
  6. Egy szín-listaelem, amelynek alakja megegyezik a PAPER, INK, FLASH, BRIGHT, OVER vagy INVERSE utasítás alakjával.

RANDOMIZE
RANDOMIZE 0
RANDOMIZE n

Az RND következő értékének előállítására használt SEED rendszerváltozót állítja be. Ha n<>0, a SEED értéke n lesz; ha n=0, a SEED értéke egy másik rendszerváltozó értékét veszi fel (ez a FRAMES), amely a képernyőn a bekapcsolás óta kijelzett képeket számlálja (bár a periféria-kommunikációs utasítások végrehajtása alatt a képek továbbra is megjelennek, de számlálásuk leáll), így ekkor a SEED értéke véletlennek tekinthető.
A RANDOMIZE jelölése a billentyűzeten RAND. Ha n kívül esik a 0...65535 tartományon, "B" hiba.

READ v1,v2,...,vk
A DATA lista egymás utáni kifejezéseit a változókhoz rendeli.
Ha a kifejezés nem megfelelő típusú, "C" hiba.
"E" hiba, ha a DATA lista kevesebb kifejezést tartalmaz, mint ahány változó van.

REM ...
Nincs hatása a programra. A pontok helyére az ENTER kivételével tetszőleges karaktersorozatot írhatunk, vagyis szerepelhet a kettőspont is, így a REM utasítás után abban a sorban nem állhat újabb utasítás.

RESTORE
RESTORE 0
RESTORE n

A DATA adatmező mutatóját arra az első DATA utasításra állítja, amely az n sorszámú sorban van (ha ilyen sorszám nincs, az ez utáni első, DATA utasítást is tartalmazó sorra). A következő READ utasítás az adatok beolvasását innen fogja kezdeni. Ez eltérő a más számítógépeken megvalósított BASIC-ekben.

RETURN
Veszi a GO SUB stackben tárolt legfelső visszatérési címet, és az ez utáni utasításra ugratja a programot.
7-es hiba, ha a stackben nincs megfelelő adat. Ekkor a programban a GO SUB és a RETURN utasítások száma logikailag nem egyezik.

RUN
RUN n

CLEAR, majd GO TO n

SAVE f
Kazettára veszi a programot és a változókat.

SAVE f LINE m
Kazettára veszi a programot és a változókat úgy, hogy a visszatöltés után automatikus ugrás történik az m sorra.

SAVE f DATA a()
Numerikus tömböt vesz kazettára.

SAVE f DATA a$()
Az a$ nevű stringtömböt veszi kazettára.

SAVE f CODE m,n
Az m címtől kezdve n számú byte-ot kazettára vesz.

SAVE f SCREEN$
SAVE f CODE 16384,6912

Az f néven képernyő-információt vesz kazettára.
"F" hiba, ha az f üres string, vagy ha tíznél több karakterből áll. Lásd a 20. fejezetet!

STOP
A 9-es üzenettel leállítja a program futását. A CONTINUE a következő utasításnál folytatja a végrehajtást.

VERIFY
Ugyanaz, mint a LOAD, de az adatokat nem tölti a RAM-ba, hanem a már ott lévőkkel összehasonlítja.
"R" hiba, ha az összehasonlításnál eltérés adódik.

A bináris és hexadecimális számrendszer

Ebben a függelékben a számítógép által használt bináris számrendszert ismertetjük. A legtöbb európai nyelvben a számolás (az arab számjegyeknek ill. a tízes számrendszernek megfelelően) többé-kevésbé szabályos tízes csoportokban történik. A magyar nyelvben is megfigyelhető ez a szabályosság (az angolban a tíz utáni eltérésektől eltekintve hasonló a helyzet):
nulla, egy, kettő, ..., kilenc
tíz, tizenegy, tizenkettő, ..., huszonkilenc
harminc, harmincegy, harminckettő, ..., harminckilenc stb.
A tízes számrendszer használaténak csak egyetlen gyakorlati oka van: kezeinken összesen tíz ujj van.
A számítógépek a decimális (tízes) számrendszer helyett a bináris számrendszert használják. Ezt azonban az emberek számára könnyebben kezelhető új formában szokás felírni, amelyet hexadecimális (rövidítve hex vagy h) rendszernek nevezünk, és alapszáma tizenhat. Mivel a tízes számrendszerben csak tíz számjegy van, a hexadecimális rendszerben való számolásra további hat számjegy szükséges még. Erre a célra az A, B, C, D, E, F betűket használjuk. És mi következik az F után? Hasonlóan, ahogy a tízes számrendszerben a tizet 10-nek írjuk, a hexadecimális rendszerben a 10-nek tizenhat fog megfelelni. Így a hexadecimális számrendszerben a számok a következők:

0 - nulla
1 - egy
2 - kettő
3 - három
4 - négy
5 - öt
6 - hat
7 - hét
8 - nyolc
9 - kilenc

Eddig megegyezik a tízes számrendszerrel, a folytatás azonban már eltérő:

A - tíz
B - tizenegy
C - tizenkettő
D - tizenhárom
E - tizennégy
F - tizenöt
10 - tizenhat
11 - tizenhét
...
19 - huszonöt
1A - huszonhat
1B - huszonhét
...
1F - harmincegy
20 - harminckettő
21 - harminchárom
...
9E - százötvennyolc
9F - százötvenkilenc
A0 - százhatvan
A1 - százhatvanegy
...
B4 - száznyolcvan
...
FE - kétszázötvennégy
FF - kétszázötvenöt
100 - kétszázötvenhat

 

A hexadecimális jelölés használatakor a szám után, h betűt írunk, így például a százötvennyolc megfelelője 9Eh (kiejtve "kilenc E hex").
Kérdés ezután, hogy a számítógép mit tud kezdeni a hexadecimális számokkal. Valójában a számítógépben két számjegy kezelhető csak, mivel két állapot megkülönböztetése egyszerű: alacsony feszültségszint (vagy kikapcsolt állapot) a 0-ás számjegy, ill. magas feszültségszint (vagy bekapcsolt állapot) az 1-es számjegy számára. Ezt bináris rendszernek nevezzük, és a két bináris számjegyet (digit) bitnek nevezzük: így egy bit értéke vagy 0 vagy 1.
A különböző számrendszerekben az első tizenhét szám a következő:

magyarul decimális hexadecimális bináris
nulla 0 0 0 vagy 0000
egy 1 1 1 vagy 0001
kettő 2 2 10 vagy 0010
három 3 3 11 vagy 0011
négy 4 4 100 vagy 0100
öt 5 5 101 vagy 0101
hat 6 6 110 vagy 0110
hét 7 7 111 vagy 0111
nyolc 8 8 1000
kilenc 9 9 1001
tíz 10 A 1010
tizenegy 11 B 1011
tizenkettő 12 C 1100
tizenhárom 13 D 1101
tizennégy 14 E 1110
tizenöt 15 F 1111
tizenhat 16 10 10000

A hexadecimális és a bináris rendszer közötti átszámítást megkönnyíti az a tény, hogy tizenhat a kettő negyedik hatványával egyenlő. Egy hexadecimális szám bináris megfelelőjét úgy kapjuk, hogy valamennyi számjegyét a fenti táblázat alapján négy bites bináris alakra változtatjuk. Bináris számok hexadecimálissá alakításánál négy bites csoportokat képezünk, majd ezeket a csoportokat jobbról kezdve a megfelelő hexadecimális számjeggyé alakítjuk. Bár a számítógépek a tisztán bináris számrendszert használják, a bennük tárolt számok (vagy a kódok stb.) felírására a hexadecimális jelölésmódot is használhatjuk.
A számítógép a biteket általában csoportokba szervezve kezeli: a leggyakrabban használt csoport nyolc bitből áll, elnevezése byte. Egy byte 0 és 255 (1111 1111 bináris, FF hex) közötti tetszőleges számot jelenthet, ez pedig megfelelhet például a ZX Spectrum karakterkészlete valamelyik karakterének. Egy byte értéke két hexadecimális számjeggyel írható le. Két byte általában egy szót alkot. Egy szó leírásához tizenhat bit ill. négy hexadecimális számjegy szükséges. Egy szó 0 és a decimális 2^16-1=65535 között vehet fel tetszőleges értéket. Egy byte mindig 8 bitből áll, míg a szó hosszúsága a számítógéptől függően változhat.

A 14. fejezetben ismertetett BIN kulcsszó lehetővé teszi, hogy a ZX Spectrumba bináris formában írjunk be számokat: a BIN 0 jelentése 0, a BIN 1 jelentése 1, a BIN 10 jelentése 2 stb. A BIN után csak 0-ás és 1-es számjegyek állhatnak, vagyis az általuk képviselt szám csak nem-negatív, egész szám lehet. Így például nem írható a -3 kifejezésére a BIN -11, ehelyett a -BIN 11 alakot kell írni. A BIN utáni szám nem lehet nagyobb a decimális 65 535-nél, azaz tizenhat bitnél nem lehet több.
Az ATTR függvény eredménye valójában bináris. Ha elvégezzük ezt a visszaalakítást, a nyolc bit jelentése a következő:

A színkódok szintén a bináris alakot használják: minden kód három bittel írható le, az első bit a zöld, a második a piros, a harmadik a kék alapszínt jelenti. Ezek alapján a fekete szín kódja 000, mivel egyik színt sem tartalmazza, vagyis mindhárom bit 0 (kikapcsolt állapot). Az alapszíneknél mindig csak egy bit a három közül 1 értékű, így kódjaik bináris alakban 100, 010 ill. 001, ami decimálisan 4,2 ill. 1. A többi szín a fentiek kombinációjából áll, így kódjaik bináris alakja kettő vagy három (a fehér színnél) 1 értékű bitet tartalmaz.

Vissza