Kategória: Elektronika.
Table of Contents
|
Áttekintés
A '80-as évek ikonikus személyi számítógépei a Commodore 64, a ZX Spectrum és az Atari voltak. Nekem a '90-es évek elején volt szerencsém találkozni közelebbről is a ZX Spectrummal, azon tanultam meg programozni, és lényegében ez alapozta meg későbbi karrieremet.
The Spectrum
Megdobbantotta a szívemet az, amikor 2024-ben szembe jött egy reklám: a Retro Games kiadja a régi számítógépek retró változatait, többek között a ZX Spectrumot is, The Spectrum néven! Ráadásul elérhető áron, kb. 100 Euróért. Számos forgalmazója van.
A ZX Spectrum igazi különlegessége a gumi billentyűzet, ami azóta is egyedülálló. Mai szemmel nézve nem is túl praktikus, de mindenképp különleges, és szép élmények kapcsolódnak hozzá: az első programozási sikerek.
A készülék így néz ki:

(A kép forrása: https://mikeshouts.com/retro-games-ltd-the-spectrum-personal-computer/.)
Még meg van az eredeti ZX Spectrum is, de az ezer sebből vérzik:
- A billentyűzet valójában nem strapabíró, könnyen tönkre megy, és nem cserélhető. Rengeteget volt a készülék szervizben, ahol egy ügyes kezű ember rendre megforrasztotta, de azt nem tudom megmondani, hogy most működne-e.
- Ahhoz tévé kimenet volt; nem tudom, hogyan lehetne a mai képernyőkhöz csatlakoztatni.
- A játékokat kazettáról olvastuk be, és a programokat oda mentettük, de kérdés, hogy sikerülne-e ezeket működésre bírni.
Szóval annak ellenére, hogy a készülék még valahol meg van, a retró változat megvásárlása mellett döntöttem. Ehhez nem kell kazetta, USB pen drive-ot tudunk csatlakoztatni. A monitor kimenete HDMI (amit időnként nem talál, újra kell indítani). USB-C töltője van. Összesen 4 USB partja van, ahova elvileg akár joystickot és egyéb eszközöket is tudunk csatlakoztatni, ezeket nem próbáltam.
Szóval tisztára modern 2024! Vagy mégse? Ezen az oldalon a lehetőségeket járom körbe.
A beépített játékok
A konzol 48 beépített játékkal érkezik. Meglepő, de 47 közülük számomra ismeretlen, az egyetlen ismert játék a Manic Miner, amit annak idején végigjátszottam. Mondjuk nem is elsősorban a játék miatt vettem, de ha már rajta van, miért ne próbálnám ki?
Nem is olyan egyszerű a használata! Eltartott egy darabig, mire rájöttem, hogy az 5-ös és 8-as billentyűkkel tudok lépkedni. Játék indítása: M.

(A kép forrása: https://en.wikipedia.org/wiki/Manic_Miner.)
Mozogni a nyilakkal tudunk: balra 5, jobbra 8, az ugrás pedig vagy a felfele nyíl (7), vagy a SPACE. Amit nem is olyan egyszerű megnyomni. Eltartott egy darabig, mire sikerült végigjátszani az első pályát.
Visszatérni a főmenübe a konzol hátulján található HOME gomb megnyomásával lehet.
Játék betöltése USB-ről
Ez nem volt olyan egyszerű, mint gondoltam! Egy boot-olható, FAT32-vel formázott pen drive-ra van szükség. Egy 16 GB-os pen drive-ot formáztam FAT32-re. Letöltöttem a legfrissebb Ubuntut (https://ubuntu.com/download/desktop), a Rufus nevű alkalmazást (https://rufus.ie/), és ennek segítségével készítettem egy boot-olható Linux telepítőt.
A neten kerestem játékokat. Meglepő, hogy az ikonikus PacMan nincs a 48 játék között, így erre esett a választás. A következő oldalon találtam meg: https://worldofspectrum.org/archive/software/games/pac-man-atarisoft. Itt nem egyértelmű, hogy mit kell letölteni: a Files alatt a másodikat érdemes: "Atarisoft - (non-TZX) TAP tape image". (A "Atarisoft - Original release - Perfect TZX TAP tape" szimulálja a betöltést, azaz 5 percig nem történik semmi. Bár az igazi retró élményhez az is hozzátartozik.)
Ha esetleg elveszne, innen letölthető, ami az ottani másolata: PACMAN.TAP.
Ezt a fájlt másoljuk az USB meghajtó gyökerébe, majd a pen drive-ot dugjuk be a Spectrum baloldali USB meghajtójába. Betöltés: a játékok között meg kell keresni a pen drive ikont, majd betöltés (M), megjelenik a Media select, itt navigáljunk a nyilakkal (5, 6, 7, 8) a PACMAN-re, és ismét nyomjunk M-et, majd Enter. Játék indítása: S. Navigálni a nyilakkal tudunk.

(A kép forrása: https://en.wikipedia.org/wiki/Pac-Man.)
Hasznos weboldalak
Programozás BASIC-ben
Az igazán érdekes - számomra - a Spectrum programozása. Vajon mai (2025) fejjel, a mostani standardok birtokában mennyire használható, vagy máshonnan megközelítve: mennyire borzasztó a Spectrum programozása? Spoiler: NAGYON!
Az ikonikus barna színű könyvet sajnos nem adták ki újra, viszont letölthető több helyről is:
- Második kiadás (1982): https://zxnext.narod.ru/manuals/Basic_Programming.pdf
- Harmadik kiadás (1983): https://www.funspot.it/stuff/zx-spectrum-basic-programming.pdf
- Online: https://worldofspectrum.net/ZXBasicManual/
A The Spectrum felhasználói kézikönyve viszont azt a színvilágot tükrözi, és letölthető innen: https://retrogames.biz/support/thespectrum/manuals/
Csapjunk a lovak közé!
A programokat sajnos nem tudtam PC-n forráskódként megjeleníteni, így másoltam. Sajnos másolási hibák elvben előfordulhatnak.
Klasszikus módba lépés
Nem egyszerű megtalálni:
- SPACE (Options)
- Advance options: kétszer meg kell nyomni a 6-os gombon található lefele nyilat, majd M (Select)
- Switch to classic mode: mint az előző lépésben
És máris megjelenik a ZX Spectrum prompt!
A billentyűzet használata
Az elmúlt évtizedekben a PC-k billentyűzetéhez és a modern programozáshoz szokott ember számára akkor is idegen a Spectrum billentyűzete, ha annak idején évekig ezt használta. Néhány hasznos tudnivaló:
- Alapból egy K betű villog, ami a kulcsszóra (keyword) utal. Ekkor ha megnyomunk egy billentyűt, akkor a rajta, alul található kulcsszó jelenik meg, pl. P esetén a PRINT. (A Spectrum programozása során tehát a kulcsszavakat nem kell beírni, az automatikusan rajta van a billentyűzeten.) Ebben az állapotban számokat is be tudunk írni, ami az adott program adott sorát jelenti.
- Az utasítás mindenképp kulcsszóval kezdődik. Ha beírtunk egy kulcsszót, akkor több kulcsszót már nem lehet beírni, és a prompt átvált villogó L-re, ami a betűre (letter) utal. Ekkor tudunk normál betűket beírni: alapból kisbetűket, ill. a CAPS SHIFT-tel nagybetűket.
- A CAPS SHIFT + 2 megnyomásával C módba kerülünk, ami a csupa nagybetűs mód (CAPS LOCK). Ha még egyszer megnyomjuk, akkor visszatérünk L módba.
- A billentyűn található piros feliratot a SYMBOL SHIFT segítségével tudjuk beírni, és ez tetszőleges módban működik.
- A billentyű feletti zöld és alatti piros felirathoz E (extended) módba kell lépni, a CAPS SHIFT és a SYMBOL SHIFT (tehát a két shift) egyidejű lenyomásával. Ez egyetlen lenyomásig marad érvényben. Ebben az E módban alapból a billentyű feletti zöld szöveget tudjuk beírni, a SYMBOL SHIFT segítségével pedig a billentyű alatti pirosat.
- A CAPS SHIFT és a 9 lenyomásával jutunk grafikus módba, aminek a segítségével a számjegyeken található grafikus jeleket tudjuk beírni.
- Törölni a CAPS SHIFT és 0 együttes lenyomásával lehet.
Még van egy-két lehetőség, pl. színessel írni, de most azzal nem foglalkozunk.
Helló, világ!
Készítsük el első programunkat! A Spectrumban a sorokat sorszámozni kell. Konvencionálisan 10-esével sorszámozzuk, 10-zel kezdve, hogy ha be kell szúrni valamit, akkor legyen hely. És ez pont olyan rossz, mint amilyennek hangzik: túl sok kódot nem tudunk beszúrni, ha csak nem sorszámozzuk át egyesével a teljes programot. Mert alapból nem ad erre eszközt a Spectrum. Valójában talán ez az a legerősebb tulajdonsága, ami lehetetlenné teszi a komolyan vehető fejlesztést.
Írjuk be ezt:
10 PRINT "Hello, world!"
Segítség:
- Nem kell begépelni azt, hogy PRINT, elég a P-t megnyomni.
- Idézőjel: SYMBOL SHIFT + P
- Felkiáltójel: SYMBOL SHIFT + 1
- A végén ENTER-t kell ütnünk.
A program indítása:
RUN
Adott sor szerkesztése: a CAPS SHIFT + 6 és CAPS SHIFT + 7 segítségével tudunk a sorokon lépkedni (amit most nem tudunk megtenni, mert csak egyetlen sorunk van); egy > jel jelzi az aktuális sort. Az adott sor szerkesztése: CAPSH SHIFT + 1 (Edit). Ezen belül balra és jobbra a CAPS SHIFT + 5 ill. CAPS SHIFT + 8 kombinációkkal tudunk.
Ha új sorszámot adunk neki, akkor kétszer is szerepelni fog. Sort úgy tudunk törölni, hogy beírjuk a sorszámát és ENTER-t ütünk. Tehát átsorszámozni úgy tudjuk, hogy egyesével létrehozunk új sorokat, majd egyesével a régit kitöröljük. Tehát az átsorszámozás egy iszonyatosan lassú, nehézkes folyamat.
A programok mentése USB-re
A programok mentése nagyon nem egyszerű; ez a leírás segített a legtöbbet a megértésében: https://www.reddit.com/r/zxspectrum/comments/1h57f18/the_spectrum_and_saving_to_usb/.
Nulladik lépésben üresben létre kell hozni egy szalagot, azaz tape-et. Töröljük ki a programot (pl. CLEAR)
SAVE "fcstape"
Ezt írja ki:
Start tape, then press any key.
ENTER után ezt:
0 OK, 0:1
Ezt követően tegyük a következőt: HOME nyomógomb a hátulján -> Media select -> M -> fcstape_WR -> M -> ENTER
Most valósítsuk meg a programot:
10 PRINT "Hello, world!"
Mentsük le:
SAVE "hello"
Ez a korábban beállított tape-re mentette. A tapasztalatom szerint a név 10+ hosszú nem lehet, csak annál rövidebb. Nem találtam, hogy hogyan lehetne felülírni vagy törölni; egyből jól kell megírni, mert javításra nincs lehetőség.
Később ha be szeretnénk olvasni, akkor ki kell választani a Media select-ben a tape-et, és utána a következőképpen tudjuk beolvasni:
LOAD "hello"
Tapasztalatom szerint mentés után nem működik egyből; ekkor ki kell lépni a HOME-ba, Media select, majd vissza.
A programokat a szalag nevének újbóli megadásával lehet kilistázni:
LOAD "fcstape"
Ha kiadjuk egyesével a LOAD-ot üres stringgel, akkor kiírja a nevét és be is tölti a következőt:
LOAD ""
Számolás
Új programot a NEW segítségével tudunk létrehozni. Ez figyelmeztetés nélkül törli az előzőt, mintha újraindulna a gép.
Változókat a LET segítségével tudunk létrehozni. Típusok külön nincsenek. A változónév a tapasztalatom szerint bármi lehet
10 LET a=3
20 LET b=2
30 LET c=a+b
40 PRINT c
Az eredmény: 5.
Beolvasás
Kérjük be a felhasználó nevét, és köszönjünk neki!
A string típusú változók csak egybetűsek lehetnek, és $ jellel végződnek.
10 PRINT "What is your name?"
20 INPUT n$
30 PRINT "Hello, ";n$;"!"
A string konkatenálás a ; jellel történik.
Faktoriális
Számoljuk ki 5 faktoriálisát! Ehhez használnunk kell a FOR ciklust:
10 LET factorial=1
20 FOR i=2 TO 5
30 LET factorial=factorial*i
40 NEXT i
50 PRINT factorial
A FOR ciklusnál a TO a SYMBOL SHIFT + F, tehát nem szabad betűkkel beleírni. A NEXT a ciklus vége. A futtatás eredménye: 120.
Faktoriális paraméterrel
Számoljuk ki n!-t, ahol n egy globális változó. A Spectrumban eljárások vannak, aminek nincs paramétere és visszatérési értéke; az őt hívó programmal globális változókon keresztül kommunikál. Eljárás hívása: GO SUB. Visszaérés a szubrutinból: RETURN. Itt fontos a STOP utasítás is, amivel befejeződik a program, hogy nehogy ráfusson a szubrutinra. a REM a remark rövidítése, és megjegyzést jelent.
10 REM factorial with subroutine
20 LET n=6
30 GO SUB 1000
40 PRINT n;"!=";f
50 STOP
1000 REM f = n!
1010 LET f=1
1020 FOR i=2 TO n
1030 LET f=f*i
1040 NEXT i
1050 RETURN
Eredmény: 6!=120.
Ismétlés nélküli kombináció
Az n alatt a k képlete: n!/(k!*(n-k)!). Ez nem nagy dolog más nyelvekben, a Spectrumban viszont a sok globális változó miatt kihívás, de nem lehetetlenség. A programban a faktoriális az 1000- sortól indul, ahol az 'a' változó faktoriálisát számolja ki, az eredmény az 'f' változóba kerül. Az n alatt a k az 'n' és 'k' változókat kapja inputként, segédeljárásként a faktoriálist használja, az eredmény a 'c' változóba kerül.
10 REM 5 choose 2
20 LET n=5
30 LET k=2
40 GO SUB 2000
50 PRINT n;" choose ";k;"=";c
60 STOP
1000 REM f = a!
1010 LET f=1
1020 FOR i=2 TO a
1030 LET f=f*i
1040 NEXT i
1050 RETURN
2000 REM c = n choose k
2010 LET a=n
2020 GO SUB 1000
2030 LET c=f
2040 LET a=k
2050 Go SUB 1000
2060 LET c=c/f
2070 LET a=n-k
2080 Go SUB 1000
2090 LET c=c/f
2100 RETURN
Az eredmény: 5 choose 2=10.
Prímellenőrzés
Írjuk ki a prímszámokat 20 alatt!
10 REM primes <= 20
20 FOR n=2 TO 20
30 LET p=1
40 FOR i=2 TO SQR n
50 IF n/i=INT (n/i) THEN LET p=0
60 NEXT i
70 IF p=1 THEN PRINT n
80 NEXT n
Az eredmény: 2, 3, 5, 7, 11, 13, 17, 19, egymás alatt.
Legnagyobb közös osztó
Az Euklideszi algoritmust használjuk. A Spectrumban nincs WHILE ciklus sem modulo, így a megvalósításhoz trükkökhöz kell folyamodnunk.
10 REM greatest common divisor
20 LET a=30
30 LET b=12
40 IF b=0 THEN PRINT "GCD: ";A: STOP
50 LET r=a-INT (a/b)*b
60 LET a=b
70 LET b=r
80 GO TO 30
Az eredmény: 6.
Lista
A Spectrum BASIC rendkívül gyenge a modern adatszerkezetek területén. Mindössze egyetlen fix listát támogat, aminek még a hosszát sem lehet lekérdezni, és módosítani sem lehet, tehát tudását tekintve bőven a klasszikus tömb alatt van. Lássunk egy példát összeadásra!
10 REM sum numbers
20 RESTORE 1000
30 LET sum=0
40 FOR i=1 TO 3
50 READ d
60 LET sum=sum+d
70 NEXT i
80 print sum
1000 DATA 3,2,5
A RESTORE azt mondja meg, hogy hol található az adat; jelen esetben az 1000-es sorban. A READ ezeket olvassa be egyesével. Az eredmény: 10.
Rajzolás
A ZX Spectrum egyik erőssége a rajzolás volt, persze a '80-as évek mércéjével mérve. A koordináta rendszer mérete: x-tengely 0…255, y-tengely 0…175; a (0, 0) koordináta a bal alsó sarokban van. Pontot rajzolni a PLOT x,y, míg egyenest az adott pontból a DRAW dx,dy utasítással lehet. Láttunk egy példát, melyben egy sokszöget rajzolunk ki, és trigonometriai számításokkal határozzuk meg a vonal irányát!
10 REM draw polygon
20 LET n=7
30 LET pi=3.14
40 LET l=50: REM length
50 PLOT 150,20
60 FOR i=1 TO n
70 LET a=i*pi*2/n
80 DRAW l*COS a,l*SIN a
90 NEXT i
Programozás assembly-ben
Áttekintés
A legizgalmasabb, egyben a leginkább agyament dolog az assembly programozás. Valójában assembly-ben nem is lehet programozni, csak gépi kódban. Tekintsük a következő kódot:
10 DATA 4,1,5,0,201
20 LET s=32768
30 READ l
40 FOR n=0 to l-1
50 READ a
60 POKE s+n,a
70 NEXT n
80 PRINT USR s
Futáskor ezt kapjuk: 5.
De mi is történik ebben a fekete mágiában? A DATA sor a tulajdonképpeni gépi kód. Az első szám a program hossza, és utána jönnek a bájtok egymás után. A POKE utasítással tudunk beírni egy memóriahelyre adatot, tehát pl. a POKE 32768,201 azt jelenti, hogy a 32768. bájtba a 201 érték kerül. A kiolvasás egyébként a PEEK. A programban a 20-70 sorok írják be a memóriába egyesével a bájtokat.
A 80. sorban az USR az, amelyik meghívja a gépi kódú programot, az eredmény pedig a BC regiszter értéke lesz. A regiszterekről később lesz szó részletesebben. Ezt az értéke a PRINT utasítással kiírjuk. Tehát a gépi kód annyit csinál, hogy ebbe a regiszterbe 5-öt tesz, majd visszatér, amit kiírunk.
Az assembly kód a következő
LD BC, 5
RET
Magyarázat:
- LD BC, 5: a BC regiszterbe 5 kerül. ENnek a gépi kódja az 1, ami 2 paramétert vár, előbb a C majd a B értékét. Tehát a sorrend meg van fordítva. Így ennek az utasításnak a gépi kódja: 1, 5, 0.
- RET: visszatér a hívó oldalra, azaz BASIC módba. Ennek a gépi kódja a 201.
Az USR-t önmagában nem lehet meghívni, azt mindenképp egy utasítás paramétereként kell megadni. Ha nem szeretnénk semmit sem kezdeni, akkor a szokásos módszer a következő:
RANDOMIZE USR 32768
Ez a T billentyűn található (RAND), és ez állítja be a véletlen szám generátor magját.
Regiszterek
A regisztereket leginkább a magasabb programozási nyelvek változóihoz tudjuk hasonlítani, ám annál speciálisabbak, és a tulajdonképpeni változónak a memóriacím felel meg. Felfoghatjuk úgy is, mint előre létrehozott változók, speciális céllal. A Spectrumban az alábbi regisztereket használhatjuk:
- Fő regiszterek
- A: akkumulátor. A legtöbb művelet eredménye ide kerül.
- B, C: általános célú. Gyakran párban használják (BC) leginkább számlálásra és címzésre.
- D, E: általános célú. Párban (DE) adatok mozgatására használják a memóriában.
- H, L: általános célú. Párban (HL) címzési regiszter.
- Speciális regiszterek
- SP: stack pointer, azaz veremmutató.
- PC: program counter, azaz a végrehajtandó utasítás címe.
- IX, IY: index regiszterek; ritkábban használtak.
- Állapotregiszter: F, amelynek a bitjei a fontosak
- 7: S (sign); előjel bit. Negatív-e az utolsó művelet eredménye.
- 6: Z (zero); nulla bit. Nulla-e az utolsó művelet eredménye.
- 4: H (half carry); BCD számításoknál használatos.
- 2: P/V (parity/overflow); párosság vagy túlcsordulás.
- 0: C (carry); átvitel pl. összeadásánál.
Utasítások
A Spectrum utasításkészletének fontosabb elemei az alábbiak.
- Adatmozgatás (LD, load): az adott regiszterbe kerül az érték
- LD A, n: 62, n (A = n)
- LD B, n: 6, n (B = n)
- LD C, n: 14, n (C = n)
- LD D, n: 22, n (D = n)
- LD E, n: 30, n (E = n)
- LD H, n: 38, n (H = n)
- LD L, n: 46, n (L = n)
- LD BC, nn: 1, n2, n1 (BC = nn; előbb jön a C, utána a B)
- LD DE, nn: 17, n2, n1
- LD HL, nn: 33, n2, n1
- LD SP, nn: 49, n2, n1
- LD B, A: 71 (B = A)
- LD C, A: 79 (C = A)
- LD D, A: 87 (D = A)
- LD E, A: 95 (E = A)
- LD H, A: 103 (H = A)
- LD L, A: 111 (L = A)
- LD (HL), A: 119 (a HL által mutatott memóriacímbe kerül az A tartalma)
- LD A, (HL): 126 (az A regiszterbe kerül a HL által mutatott memóriacím tartalma)
- Aritmetikai műveletek
- ADD A, n: 198, n (A = A + n)
- ADD A, B: 128 (A = A + B)
- ADD A, C: 129 (A = A + C)
- ADD A, D: 130 (A = A + D)
- ADD A, E: 131 (A = A + E)
- ADD A, H: 132 (A = A + H)
- ADD A, L: 133 (A = A + L)
- SUB A, n: 214, n (A = A - n)
- INC A: 60 (A = A + 1)
- DEC A: 61 (A = A - 1)
- INC B: 4 (B = B + 1)
- DEC B: 5 (B = B - 1)
- INC C: 12 (C = C + 1)
- DEC C: 13 (C = C - 1)
- Logikai műveletek
- AND A, n: 230, n (A = A AND n)
- OR A, n: 246, n (A = A OR n)
- XOR A, n: 238, n (A = A XOR n)
- CP A, n: 254, n (A és n összehasonlítása; a megfelelő F jelzőbitek állítódnak be)
- Ugrások és hívások
- JP nn: 195, n2, n1 (ugrás abszolút címre)
- JP NZ, nn: 195, n2, n1 (ugrás abszolút címre, ha a Z jelzőbit nincs beállítva)
- JP Z, nn: 195, n2, n1 (ugrás abszolút címre, ha a Z jelzőbit be van állítva)
- JP NC, nn: 195, n2, n1 (ugrás abszolút címre, ha a C jelzőbit nincs beállítva)
- JP C, nn: 195, n2, n1 (ugrás abszolút címre, ha a C jelzőbit be van állítva)
- JR n: 195, n (rövid ugrás előre vagy hátra)
- JR NZ n: 195, n (rövid ugrás, ha nincs Z jelzőbit)
- CALL nn: 205, n2, n1 (függvényhívás)
- RET: visszatérés a hívásból.
Hasznos lehet még a NOP utasítás is, ami 0, egy órajelig tart, és nem csinál semmit.
A fenti utasítások és regiszterek segítségével tehát el kell készítenünk az assembly kódot, majd ki kell keresni az egyes utasítások gépi kódját, és ezt soroljuk fel a DATA utasításnál.
Két olyan könyvet találtam a neten, amely tartalmazza a teljes utasításkészletet:
- http://www.retro8bitcomputers.co.uk/Content/downloads/books/SpectrumMachineLanguageForTheAbsoluteBeginner.pdf
- https://ia802300.us.archive.org/view_archive.php?archive=/4/items/World_of_Spectrum_June_2017_Mirror/World%20of%20Spectrum%20June%202017%20Mirror.zip&file=World%20of%20Spectrum%20June%202017%20Mirror/sinclair/books/s/SpectrumMachineCodeMadeEasyVolume1.pdf (ez utóbbi tehát már csak mirrorban érhető el)
A memória felépítése
A ZX Spectrum 64 kB memóriája tartalmazza a ROM-ot (ahol az operációs rendszer található), a képernyő memóriát (amit ma videókártyának hívunk), egyéb fenntartott területet és a tulajdonképpeni RAM-ot, a következőképpen:
- 0-16383: ROM
- 16384-22527: képernyő memória
- 22528-23295: attribútummemória (színek és villogás)
- 23296-23733: fenntartott memóriaterület
- 23734-65535: program, adatok és stack (ez utóbbi felülről)
A példákban a 32768-as memóriaterülettől programozunk.
Összeadás
Valósítsuk meg azt a kódot, ami összeadja 3-at és 2-t. Műveletet az A regiszterben tudunk végrehajtani, tehát oda töltjük be a 3-at és adjuk hozzá a 2-t. Majd ezt át kell másolni a BC regiszterbe, mert azt írja ki a BASIC program. A BC regiszter 16 bit, az A pedig 8, emiatt közvetlenül nem tudjuk bemásolni. A B regiszter értéke 0 lesz a C regiszeré pedig az A értéke. Tehát a program:
LD A, 3
ADD A, 2
LD B, 0
LD C, A
RET
Most írjuk mellé a listából a gépi kódot:
LD A, 3 ; 62, 3
ADD A, 2 ; 198, 2
LD B, 0 ; 6, 0
LD C, A ; 79
RET ; 201
Ez tehát összesen 8 bájt. A DATA ezzel kezdődik, majd sorban a számok:
10 DATA 8,62,3,198,2,6,0,79,201
20 LET s=32768
30 READ l
40 FOR n=0 to l-1
50 READ a
60 POKE s+n,a
70 NEXT n
80 PRINT USR s
Futtatás eredménye: 5.
Kiírás
A fenti programban az eredményt a BASIC PRINT utasítása írta ki. Assembly-ben ez meglehetősen bonyolult. Ennek a szakasznak az elkészítésében a http://www.breakintoprogram.co.uk/hardware/computers/zx-spectrum/assembly-language/z80-tutorials/print-in-assembly-language oldal, a fent felsorolt könyvekben a gépi kódok táblázata, valamint a türelmem és a józan szem segített.
A módszer a következő:
- Töröljük a képernyőt, egyúttal megnyitjuk a csatornát.
- Az A regiszterbe beletesszük a kiírandó karakter ASCII kódját.
- Meghívjuk a RST 0x10 rutint.
- Az előző két lépéssel egyesével kiírjuk karakterenként a szöveget.
Képernyő törlése
A 0x0DAF memóriaterületet kell meghívni, itt van ugyanis megvalósítva a ROM-ban a törlés:
CALL 0x0DAF
A CALL gépi kódja a 205, és utána 2 bájtot vár: a fenti memóriacímet, és fordított sorrendben, azaz előbb jön az AF és utána a 0D hexacedimális értékek, azaz decimálisan a 175 és a 13 értékeket.
A karakterek kiírása egyesével
LD A, 72
RST 0x10
Azt szeretnénk kiírni, hogy "Hello". A H betű ASCII kódja a 72. Az LD A, 72 utasítás gépi kódja decimálisan a 62, 72. A RST 0x10 gépi kódja decimálisan a 215. Tehát a 62, x, 215 sorozatot kell megadni minden egyes betűhöz, ahol az x az aktuálisan kiírandó betű ASCII kódja.
A teljes assembly program és gépi kód
CALL 0x0DAF ; ROM_CLS
LD A, 72 ; 'H'
RST 0x10
LD A, 101 ; 'e'
RST 0x10
LD A, 108 ; 'l'
RST 0x10
LD A, 108 ; 'l'
RST 0x10
LD A, 111 ; 'o'
RST 0x10
RET
A RET kódja a 201. A teljes kód tehát a következő: 205, 175, 13, 62, 72, 215, 62, 101, 215, 62, 108, 215, 62, 108, 215, 62, 111, 215, 201. Ez 19 bájt
A BASIC program
A BASIC programot a fentiek alapján állítjuk össze, ahol a DATA most már 20 számot tartalmaz: a hosszt (19) és a fenti gépi kódot.
Másik változtatás az utolsó sor: ebben már maga a gépi kód írt ki, a BASIC nem, így az utolsó sor PRINT helyett a RANDOMIZE utasítást tartalmazza.
10 DATA 19, 205, 175, 13, 62, 72, 215, 62, 101, 215, 62, 108, 215, 62, 108, 215, 62, 111, 215, 201
20 LET s=32768
30 READ l
40 FOR n=0 to l-1
50 READ a
60 POKE s+n,a
70 NEXT n
80 RANDOMIZE USR s
Eredmény
Hello
Összefoglaló
Jó móka volt elővenni és eljátszani vele. Az egyértelműen elmondható, hogy modern szemmel a Spectrum egy katasztrófa. Nyilván az összesen 64 kB (amiben benne van az operációs rendszer, a képernyő memória és a teljes RAM) mai szemmel iszonyat kevés; ma már ennek a milliószorosával dolgozunk. De ettől eltekintve is igazi katasztrófaturizmussal felérő élmény volt:
- A sorszámozás egészen elképesztő, amit már a PC BASIC nyelvei is elengedtek.
- A billentyűzet használata rendkívül nehézkes, egyrészt a ritkásan elhelyezkedő gumi billentyűk, másrészt a nehézkes használata miatt. Például a módokat egy-két hónap elteltével is teljesen elfelejtettem; utána kellett néznem, hogy mit hogyan tudok elérni.
- Mivel be begépeljük a kulcsszavakat, hanem kikeressük, egy-egy kulcsszó megtalálása hosszú időt vehet igénybe.
- A modern programozási nyelvek konvencióit egyáltalán nem követi. Bizonyos szokásos műveletek vagy egyáltalán nem léteznek, vagy egészen máshogy.
- A változókezelés borzasztó. Az, hogy csak egybetűs a string, óriási korlát.
- Alapvető struktúrák hiányoznak, pl. nincs blokk, szinte mindent a GOTO-val kell megoldani, ami karbantarthatatlan kódot eredményez már nagyon kis programok esetén is.
- Nincsenek függvények. A szubrutinnak nincs paramétere és visszatérési értéke, csak globális változókkal dolgozik. Azon túl, hogy ez áttekinthetetlenné teszi a kódot, még az olyan alapvető műveleteket sem engedélyezi, mint pl. a rekurzió.
- Nincs védelem és visszavonás. Pl. egy hibásan beírt sorszám egyből törli a sort, a NEW egyből törli a programot.
- Az assembly programozás még assembly mércével mérve is különösen nehézkes. (Egy assembly fordítót igazán beletehettek volna a retró kiadásba!)
- És a The Spectrum kiadása sem egyszerűsítette az életet, gondoljunk csak az USB pen drive nehézkességére, a klasszikus módba lépés nehézkességére és egyebekre.