Sinclair Spectrum Játék és Program 2.

Bevezetés

A "Sinclair Spectrum játék és program" c. könyv megjelenése után - a nagy érdeklődésre való tekintettel - vetődött fel az újabb kötet elkészítésének gondolata. Ennek tartalmát elsősorban a felhasználók igénye szerint állítottuk össze, követve persze az előző könyv szerkezetét.
A terjedelem viszont csökkent, elsősorban azért, mert úgy érezzük az olcsóbb, de tartalmas könyvek népszerűbbek a felhasználók körében, ugyanakkor igyekeztünk arra vigyázni, hogy az oldalszám csökkentése ne menjen a tartalom rovására, melynek törzsét a játékleírások mellett most is a felhasználói programok és egyéb rutinok alkotják.
Mikrolexikonunk azonban megváltozott! Elmaradtak az egyértelműen "szubjektív" osztályzatok, és nem volt célunk a legutolsó "salátáig" az összes olyan játékot felsorolni, amelyik kimaradt az előző lexikonból. Ebből a megfontoláshól a lexikon nagyobb részét azok a programok alkotják, amelyek zöme a könyv megjelenésével párhuzamosan terjed el a Spectrumosok táborában.
A "Mit játsszunk, hogy játsszunk?" c. fejezet összeállításánál természetesen előnyben részesítettük az 1986-os év legnépszerűbb játékait. Célunk most sem az volt, hogy leírjuk egy-egy játék folyamatát elejétől a végéig, hanem az, hogy lehetőséget biztosítsunk a játékban való nagyobb elmélyedésre. A leírások mélysége - úgy érezzük - ehhez éppen elegendő.
A Mega Basic a Beta Basic után az egyik legelterjedtebb Basic bővítő. A felhasználók igényén túlmenően mi is úgy éreztük, hogy ennek. a programnak az ismertetésére szükség van. A demo lista szemléletesen bemutatja a program néhány fontosabb alkalmazási lehetőségét.
A Spectrumon alkalmazott Compiler-ek ismertetése idáig kimaradt a megjelent szakirodalmakból. Ötödik fejezetünk egy összehasonlító ismertetőt közöl arról az 5 compiler-ről, melyek jelenleg a legelterjedtebbek a felhasználók körében.
A könyv utolsó fejezete azoknak szól, akik számára eddig megközelíthetetlen volt a LOAD/SAVE rutinokba történő beavatkozás. Megismerhetjük a "trükkös" betöltők titkait, és tippeket kapunk a turbósításra is.


Tartalom


Műveletek a magnetofont kezelő LOAD / SAVE rutinokkal

A fejezet első részében a ROM-ban található LOAD/SAVE rutinok elhelyezkedését, működését, hívási lehetőségeit ismertetjük. A későbbi felhasználás céljából elsősorban a végrehajtó rutinra lesz szükségünk, így annak közöljük a teljes assembly listáját, az utasítás értelmező és vezérlő rutinok részletes ismertetésére nem térünk ki. Tesszük ezt azért, mert bármikor disassemblálható a ROM területről, másrészt a kommentált lista megtalálható a "ZX Spectrum ROM Programja" c. könyvben - Ipari Informatikai Központ 1985.
A fejezet második részében néhány programozástechnikai tanácsot adunk arra, hogyan lehet a LOAD/SAVE rutinokba "belepiszkálni", elérve a játékprogramokból is jól ismert "trükkös" keret-csíkozást, visszafelé töltést, stb.
A harmadik rész a turbósításhoz ad segítséget, lehetőséget nyújt bárki számára, hogy egyszerű módon turbo programot készítsen, és azt alkalmazni is tudja.
A fejezet végén néhány tanáccsal szolgálunk a LOAD/SAVE rutinok felhasználását illetően.

A ROM LOAD/SAVE rutin felépítése

A ROM-ban elhelyezett rutin az 1218-as (HEX 04C2) címtől tart egészen a 2547-es (HEX 09F3) címig, és három eltérő blokkra bontható:

Most tekintsük át az egyes blokkokat külön-külön.

1. blokk:
A végrehajtó szakasz önmagában is futtatható, de elsősorban csak adott címen és adott hosszon elhelyezkedő adatblokk fejléc nélküli kimentésére/betöltésére. A gyakorlatban ennek a rutinnak a hívását igen sokszor használják főként a játékprogramokban. Mielőtt a konkrét hívási lehetőségeket áttekintenénk, nézzük meg az első blokk részletes assembly listáját (erre még szükségünk lesz a későbbiekben is).

A SAVE-BYTES (adatok magnetofonra mentése) szubrutin:
1218
1221
1222
1225
1227
1229
1232
1233
1234
1236
1237
1239
33, 63, 5
229
33,128,31
203,127
40, 3
33, 152, 12
8
19
221, 43
243
62, 2
71
LD HL,1343
PUSH HL
LD HL,8064
BIT 7,A
JR Z,1232
LD HL,3224
EX AF,AF'
INC DE
DEC IX
DI
LD A,2
LD B,A
; Kimentjük a verembe a SAVE/LOAD-RETURN
; kezdőcímét.
; A megadott konstans alapján kb. 5 sec. bevezető a fejléchez
; Fejléc tárolásnál ugrás történik.
; A konstans alapján kb. 2 sec. bevezető szakasz
; program, ill. adatblokk esetén.
; Tároljuk a jelzőbiteket.
; Növeljük a hosszt és csökkentjük a báziscímet.
; A tárolás helyére tiltjuk a maszkolható
; megszakítást.
; Piros BORDER szín.
; Ezt áttöltjük B-be.
Most következik a bevezető szinkron-jel impulzusainak előállítása:
1240
1242
1244
1246
1248
1249
1251
1252
1253
16, 254
211, 254
238, 15
6, 164
45
32, 245
5
37
242, 216, 4
DJNZ 1240
OUT (254),A
XOR 15
LD B,164
DEC L
JR NZ,1240
DEC B
DEC H
JP P,1240
; Időzítő ciklus.
; A BORDER szín végrehajtásonként piros és
; világoskék között vált.
; Időzítő konstans
; Csökkentjük a számláló alsó byte-ját.
; Ugrás vissza a következő impulzushoz.
; A hosszabb ciklus esetén csökkentjük
; a számláló felső byte-ját.
; Ha a bevezető rész még nem ért véget, ugrás vissza.
Ezután történik a szinkronizáló impulzus kiadása:
1256
1258
1260
1262
1264
1266
1268
6, 47
16, 254
211, 254
62, 13
6, 55
16, 254
211, 254
LD B,47
DJNZ 1258
OUT (254),A
LD A,13
LD B,55
DJNZ 1266
OUT (254),A
; A MIC kimenet kikapcsolt 667 T ideig.
;
; A MIC kimeneten aktív jel, a BORDER piros.
; Az inaktív kimeneti jel, a BORDER világoskék jelzése.
; A MIC kimenet aktív 735 T ideig.
;
;A MIC kimeneten inaktív jel, a BORDER szín világoskék
A következőkben tárolódik az azonosító állapotbíte:
1270

1273
1274
1275
1, 14, 59

8
111
195, 7, 5
LD BC,15118

EX AF,AF'
LD L,A
JP 1287
; A 14 alapján a MIC kimeneten aktív a jel és
; sárga a BORDER szín, míg az 59 egy időzítési konstans.
; Visszahívjuk a jelzőbiteket, és A-t áttöltjük
; L-be.
; Előre ugrunk a mentési ciklusra.
A szinkronizáló impulzust kimentettük, következhet a byte-ok magnetofonra mentése:
1278
1279
1280
1282
1285
1286
1288
1290

1291
1294
1295
122
179
40, 12
221, 110, 0
124
173
62, 1
55

195, 37, 5
108
24, 244
LD A,D
OR E
JR Z,1294
LD L,(IX+00)
LD A,H
XOR L
LD A,1
SCF

JP 1317
LD L,H
JR 1285
; Ellenőrizzük a hossz-számlálót.
; Abban az esetben, ha eléri a zérust,
; ugrás történik.
; Lehívjuk a soron következő tárolandó adat-byte-ot,
; majd az aktuális paritást is,
; és annak vizsgálata után visszatöltjük.
; A MIC kimeneten aktív jel van, és a BORDER kék.
; Az egyes byte-ok nyolc bites határainak jelzéséhez
; az átviteli jelzőbitet 1-re állítjuk.
; ugrás történik előre.
; Beállítjuk a paritás végső értékét,
; és ugrás vissza.
Belső ciklus az aktuális impulzusok előállítására:
1297
1298

1300
1302
1304
1306
1308


1310
1312
1314
1315
1316
121
20, 120

16, 254
48, 4
6, 66
16, 254
211, 254


6, 62
32,239
5
175
60
LD A,C
BIT 7,B

DJNZ 1300
JR NC,1308
LD B,66
DJNZ 1306
OUT (254),A


LD B,62
JR NZ,1269
DEC B
XOR A
INC A
; A MIC kimeneten inaktív jel, a BORDER szín sárga
; A zérus jelzőbit 1 állapota jelzi a ciklus második
; végrehajtását.
; Időzítő ciklus (a második végrehajtásnál 801 T idő)
; Ugrás a rövidebb ciklusra, ha zérust kell magnóra menteni.
; Ha 1-et kell tárolni, hozzáadunk 855 T időt
;
; A végrehajtás első részében a MIC kimeneten aktív a jel
; és a BORDER szín kék, a második részben a MIC kimeneten
; inaktív jel, és a BORDER szín sárga.
; Beállítjuk az időzítő konstans második végrehajtásához.
; Az első végrehajtás után ugrás vissza.
; Máskülönben csökkentjük a konstanst T idővel.
; Az átviteli jelzőbitet töröljük, A-t 1-re
; állítjuk (aktív MIC kimenet, és kék BORDER szín).
Itt lépünk be a "8 bites ciklus" szubrutinba:

1317

1319
1322

1323
1325
1327
1329
1331
1332
1333
1334

1338
1340
1342

203, 21

194, 20, 5
27

221, 35
6, 49
62, 127
219, 254
31
208
122
60

6, 59
16, 254
201

RL L

JP NZ,1300
DEC DE

INC IX
LD B,49
LD A,127
IN A,(254)
RRA
RET NC
LD A,D
INC A

LD B,59
DJNZ 1340
RET

; A "Byte vége" jelző balra lép 8 bit után tehát az
; átviteli jelzőbitbe.
; Ha még nincs kész a byte, akkor tároljuk az aktuális bitet.
; A ciklusszámlálót (melynek alapértéke a kimentendő byte-ok
; hossza) csökkentjük, a báziscímet pedig növeljük.
;
; Az időzítő konstanssal beállunk a következő byte első bitjéhez.
; BREAK-vizsgálat. Ha a BREAK-et megnyomtuk kimentés közben
; akkor átlépünk a SAVE/LOAD RETURN-be,
; és a kimentésnek vége.
;
; Máskülönben megvizsgáljuk a ciklusszámlálót és még akkor is
; visszaugrunk, ha elértük a zérust, mivel a paritást is ki kell
; küldeni a szalagra az adatok végén.
; Visszatérés előtt rövid szünet.
;
; szubrutin vége
A LOAD/SAVE szubrutin:
1343
1344
1347
1349
1350
1351
1352
1354
1356
1358
1359
1360
1362
1363
1364
1365
245
58, 72, 92
230, 56
15
15
15
211, 254
62, 127
219, 254
31
251
56, 2
207
12
241
201
PUSH AF
LD A,(23624)
AND 56
RRCA
RRCA
RRCA
OUT (254),A
LD A,127
IN A,(254)
RRA
EI
JR C,1364
REST 08
DEFB 12
POP AF
RET
; Tároljuk az átviteli jelzőbitet,
; a BORDER rendszerváltozóból lehívjuk az eredeti
; BORDER színt, majd azt a 2-es, 1-es és a 0-és bitekbe
; töltjük
;
;
; A BORDER-t beállítjuk az eredeti színértékre.
; A BREAK leolvasása.
;
;
; Engedélyezzük a megszakítást.
; Ha nincs megszakítás, ugrás történik.
; Meghívjuk a hibakezelő rutint, és megjelenik
; a D BREAK-CONT repeats hibaüzenet.
; Visszaírjuk az átviteli jelzőbitet és
; visszatérünk a programból.
A LOAD-BYTES (adatok betöltése magnetofonról) szubrutin
(HEX kezdőcim-0556)
1366
1367


1368
1369
1370
1372
1374
1377
1378
1380
1381
1383
1385
1386
20
8


21
243
62, 15
211, 254
33, 63, 5
229
219, 254
31
230, 32
246, 2
79
191
iNC D
EX AF,AF'


DEC D
DI
LD A,15
OUT (254),A
LD HL,1343
PUSH HL
IN A,(254)
RRA
AND 32
OR 2
LD C,A
CP A
; Töröljük A zérus jelzőbitet
; Fejléc esetén 0, adatblokk esetén 255 az "A" regiszter
; tartalma, míg az átviteli jelzőbit 0 esetén VERIFY-t
; 1 esetén LOAD-ot jelent.
; D eredeti értéke
; Tiltjuk a maszkolható megszakítást.
; Fehér BORDER szín.

; A veremben tároljuk a SAVE/LOAD RETURN kezdőcímét.

; Előzetesen leolvastuk a 254-es port-ot.
; Ciklikus léptetés. Nem tartjuk meg, csak az
; EAR bitet (6. bit)
; A BORDER szín piros
; C-ben tároljuk. (02-"be", 34-"ki" állapot)
; A zérus jelzőbitet 1-be állítjuk.
A jelváltás vizsgálata:
1387
1388

1391

1393
1396
1398
1399
1400
1401
1403
1406
192
205, 231, 5

48, 250

33, 21, 4
16, 254
43
124
181
32, 249
205, 227, 5
48, 235
RET NZ
CALL 1511

JR NC,1387

LD HL,1045
DJNZ 1396
DEC HL
LD A,H
OR L
JR NZ,1396
CALL 1507
JR NC,1387
; BREAK esetén visszatérés
; Meghívjuk az 1511-es címen lévő szubrutint a következő élig
; terjedő időzítéshez
; Visszatéréskor ha 14000 T ideig nem volt jelváltás, az átviteli
; jelzőbit zérus, máskülönben világoskékre vált a BORDER.
; Beállítjuk a várakozás hosszát, ez kb 1 sec
; Ezt a láncot addig végzi, amíg a megadott
; időben két jelváltást nem talál.
;
;
; Ha talál, ugrás történik.

; BREAK esetén megáll
Bevezető jel fogadása:
1408
1410

1413
1415

1417
1418
1420
1421
6, 156
205, 227, 5

48, 228
62, 198

184
48, 224
36
32, 241
LD B,156
CALL 1507

JR NC,1387
LD A,198

CP B
JR NC,1388
INC HJR NZ,1408
; Időzítési állandó.
; Itt csak akkor folytatja ha a megadott időben
; két jelváltást talál.
; BREAK esetén megáll.
; A jelváltások elhelyezkedése kb 3000 T időn
; belül kell hogy legyen
;
; Máskülönben ugrás vissza.
; A "H" regiszter tárolja a jelváltás-párokat
; egészen 255 párig.
A szinkronizáló impulzus "ki"/"be" részei
1423
1425
1428
1430
1431
1433
1435
1438

6, 201
205, 231, 5
48, 213
120
254, 212
48, 244
205, 231, 5
208

LD B, 201
CALL 1511
JR NC,1387
LD A,B
CP 212
JR NC,1423
CALL 1511
RET NC
; Időzítési állandó.
; A jelváltásokat addig vizsgálja amíg
; két egymáshoz közeli élt nem talál.
; Ezek az impulzis "ki"
; kezdő és befejező élei.

; Meg kell jelennie a "be" impulzus
; befejező élének is.
Fejléc ill. program byte-ok adatainak betöltése:
1439
1440
1442
1443
1445
1447
121
238, 3
79
38, 0
6, 176
24, 31
LD A,C
XOR 3
LD C,A
LD H,0
LD B,176
JR 1480
; A BORDER szín kék/sárga.
;
;
; Zérusra állítjuk a paritás-ellenőrző byte-ot
; A jelzőbit időzítő konstansa.
; Ugrás előre
Byte-betöltő ciklus:
1449
1450
1452
1454
1457
1459
1461
1462
1463
1464
1465
1466
1467
8
32, 7
48, 15
221, 117, 0
24, 15
203, 17
173
192
121
31
79
19
24, 7
EX AF,AF'
JR NZ,1459
JR NZ,1469
LD (IX+00),L
JR 1474
RL C
XOR L
RET NZ
LD A,C
RRA
LD C,A
INC DE
JR 1476

; Lehívjuk a jelzőbiteket.
; Az első byte esetén ugrás előre.
; VERIFY esetén ugrás előre.
; Ténleges betöltés
; Ugrás a következő byte betöltéséhez.
; Az átviteli jelzőbitet "átmenetiéeg megőrizzük"
; Ha a szalagon lévő első byte (típus jelző)
; hamis, akkor visszatérés történik.
; Az átviteli jelzőbitet visszatöltjük.
;
;
; A ciklusszámlálót növeljük.
; Ugrás előre.

VERIFY összehasonlító művelet:
1469
1472
1473
221, 126, 0
173
192
LD A,(IX+00)
XOR L
RET NZ
; Az eredeti byte behívása.
; Összehasonlítjuk a behívott byte-tal.
; Visszatérés, ha a kettő nem egyezik.
Újabb byte behívása szalagról:
1474
1476
1477
1478
1480
221, 35
27
8
6, 178
46, 1
INC IX
DEC DE
EX AF,AF'
LD B,178
LD L,1
; Növeljük a célhely címét és
; csökkentjük a ciklusszámlálót.
; A jelzőbiteket tároljuk.
; Időzítési állandó.
; A jelzőbit kivételével töröljük az aktuális regisztert.
Egy byte felépítése - ciklus:
1482
1485
1486
1488
1489
1491
1493
205, 227, 5
208
62, 203
184
203, 21
6, 176
210, 202, 5
CALL 1507
RET NC
LD A,203
CP B
RL L
LD B,176
JP NC,1482
; Megállapítjuk a következő bit "ki" és "be" impulzusának hosszát.
; Visszatérés ha az időtatam nagyobb.
; Összehasonlítjuk 2400 T ciklussal.
; Zérus eseténtörli, 1-esetén 1-be állítja az
; átviteli jelzőbitet, majd új bitet küld az "L" regiszterbe.
; Időzítési állandó beállítása a következő bitre
; Ha van még hátra a 8 bitből akkor ugrás vissza.
Paritás ellenőrző byte frissítése:
1496
1497
1498
124
173
103
LD A,H
XOR L
LD H,A
; A pritás-ellenőrző byte-ot lehívjuk,
; ráillesztjük az új byte-ot,
; és visszatöltjük.
Ciklus lezárása:
1499
1500
1501
1503
1504
1506

122
179
32, 202
124
254
201
LD A,D
OR E
JR NZ,1449
LD A,H
CP 1
RET
; Ha DE még nem érte el a zérust,
; úgy a ciklus újra végrehajtódik.

; A paritás ellenőrző byte-ot lehívjuk.
; Visszatéréskor az átviteli jelzőbit annak ; megfelelően alakul.
; Ha a paritás ellenőrző byte zérus, az átviteli jelzőbit
; "1" lesz, és fordítva.
A LOAD rutin törzse:
(Belépéskor az időzítési állandó a "B" regiszterben, BORDER szín ill. "impulzus"-él típusa "C" regiszterben található.)
1507
1510
1511
1513
1514
1516
205, 231, 5
208
62, 22
61
32, 253
167
CALL 1511
RET NC
LD A,22
DEC A
JR NZ,1513
AND A
; Az 1511-es címen kezdődő szubrutin kétszer lesz fittatva.
; Hiba esetén visszatérés.
; Várakozás 358 T ideig,
; a mintavételezési ciklus
; indítása előtt.
Mintavételezési ciklus:
1517
1518
1519
1521
1523
1524
1525
1526
1528
4
200
62, 127
219, 254
31
208
169
230, 32
40, 243
INC B
RET Z
LD A,127
IN A,(254)
RRA
RET NC
XOR C
AND 32
JR Z,1517

; Számoljuka ciklusokat.
; Az idő túllépésekor visszatérés.
; Beolvasás történik a
; port-ról (BREAK vizsgálat és EAR jel).
; Léptetjük a byte-ot.
; BREAK esetén visszatérés.
; A byte ellenőrzése az
; utolsó él szempontjából.
; Ugrás vissza, ha nincs jel-váltás.

Módosítás egy új él találása esetén:
1530
1531
1532
1533
1535
1537
1539
1540

121
47
79
230, 7
246, 8
211, 254
55

204

LD A,C
CPL
LD C,A
AND 7
OR 8
OUT (254),A
SCF
RET

; Az "utolsó él" típusát megváltoztatja,
; és módosítja a BORDER színt.
; Csak a BORDER színt tartja meg.
;
;
; A BORDER szín beállítása.
; Visszatérés előtt kiadjuk a "sikeres keresés" jelet.

Mint ahogy az a rutinból is szemléletesen látható, az adatok magnetofonra mentéséhez az 1218-as (HEX 04C2) címen kell belépnünk, míg az adatok magnetofonról történő betöltésére az 1366 (HEX 0556) címen van lehetőség.
Az első blokk több különálló szubrutinból tevődik össze, néhány szubrutint (pl. SAVE/LOAD-RETURN) a SAVE és a LOAD művelet is használ. Az adatok elmentéséhez ill. betöltéséhez nem elegendő meghívni a megadott címet, előtte néhány regiszter tartalmát megfelelően be kell állítani.
Ezek sorban:

Ezen kívül betöltés esetén az átviteli jelzőbitet 1-re kell átváltani egy megfelelő SCF utasítással.
Nézzünk egy mintapéldát:

Fejléc nélküli adatblokk formájában akarjuk kimenteni a képernyő-memória tartalmát. A mentő rutint (amely majd a ROM rutint is hívja) helyezzük el a 60000. címtől. A szinkron-byte értéke 255, a startcím (IX tartalma) 16384, a hossz (DE tartalma) pedig 6912. A mentő rutin tehát a következő formájú lesz:

60000
60002
60006
60009

60012

62, 255
221, 33, 0, 64
17, 0, 27
205, 194, 4

201

LD A,255
LD (IX+00),16384
LD DE,6912
CALL 1218

RET

; szinkron-byte
; kezdőcím
; hossz
; meghívjuk az adatok magnetofonra
; mentését megoldó rutint.
; Vége.

Néhány byte-ról lévén szó, az adatok beolvasása BASIC utasítások segítségével egyszerűen elvégezhető:

10 FOR i=60000 T0 60012
20 READ a: POKE i,a: NEXT i
30 DATA 62,255,221,33,0,64,17,0,27,205,194,4,201

Adjuk ki RUN (ENTER), és a mentő rutin a memóriában van. Készítsünk egy tetszőleges színes grafikát a képernyőre, majd adjuk ki 'RANDOMIZE USR 60000', de még ne nyomjuk meg az ENTER-t! Előbb indítsuk el a magnetofont felvétel üzemmódban, és csak ezután ENTER, mert a kitöltés azonnal indul. Itt egy apró probléma felvetődhet, a kép kimentésekor az alsó két sor lemarad az utasítás kiadása miatt. Ez elkerülhető, ha teljes képernyős (24 soros) grafikánkat előbb eltesszük a memória hátrébb eső területére pl. az LDIR utasítás segítségével, és onnan mentjük ki. Az itt említett műveletre szemléletes példát találunk a "RUTINRÓL-RUTINRA" c. könyvben - LSI ATSz.1986. A képünk most már a magnetofonon található, fejléc nélkül. Behívásához meg kell írnunk a betöltő rutint, az egyszerűség kedvéért ez a mentő rutin után közvetlenül helyezkedjen el.
Formája a következő lesz:

60013
60015
60016
60020
60023

60026

62. 255
55
221, 33, 0, 64
17, 0, 27
205, 86, 5

201

LD A,255
SCF
LD (IX+00),16384
LD DE,6912
CALL 1366

RET

; szinkron-byte
; az átviteli jelzőbitet 1-re állítjuk
; kezdőcím
; hossz
; meghívjuk az adatok magnetofonról
; történő bevitelét megoldó rutint
; Vége.

Az előbbihez hasonló módon olvassuk be ezt a rutint is a memóriába, majd csévéljük vissza a kazettát és adjuk ki: RANDOMIZE USR 60013 (ENTER). Indítsuk el a magnetofont, s előzőleg kimentett képünk megjelenik a képernyőn.

2.blokk:
Ez a szintaktikai vizsgáló és vezérlő szakasz. Mind a négy szalag-kezelő utasítás esetén (LOAD/SAVE/VERIFY ill. MERGE) a belépés helye az 1541-es (HEX 0605) cím. A rutinba való belépés előtt az utasításnak megfelelően beállítódik a 23668-as (T-ADDR-lo) rendszerváltozó. Értéke:

Ez a belépés után automatikusan kiolvasásra kerül, és meghatározza az utasítás jellegét. A 2. blokk a megfelelő ellenőrzések és beállítások után szubrutinként adja át a vezérlést a már előbb megismert 1. blokknak, és az adott művelet elvégződik.
A 2. blokk részletes assembly listáját nem közöljük, csak a fontosabb belépési címeket ismertetjük, megnevezés-decimális cím-hexadecimális cím formában.

Megnevezés
DEC cím
HEX cím
Fejléc információ előállítása a munkaterületen
1541
0605
Programnév vizsgálata
1604
0644
Név áttöltése a munkaterületre
1611
0648

Utasítások után álló paraméterek vizsgálata

  • xxx "név" DATA szerkezet vizsgálata
  • létező tömb kezelése
  • a tömbutasítás utolsó részének vizsgálata
  • a SCREEN$ vizsgálata
  • a CODE szerkezet vizsgálata
  • kezdőcím megkeresése a CODE szerkezetben
  • "hossz" és "kezdőcím" paraméterek kezelése a DATA szerkezetben
  • a LINE vizsgálata
  • a LINE utáni sorszám vizsgálata
  • program és változói adatok tárolása a munkaterület fejléc részében
  • SAVE különválasztása a másik három utasítástól
  • LOAD/VERIFY és MERGE esetén a fejléc információ behívása a szalagról
  • új fejléc kijelzése a képernyőn

 

1618
1650
1682
1696
1731
1761
1785
1814
1827
1854
1882
1889
1908

 

0652
0672
0692
06A0
06C3
06E1
06F9
0716
0723
073E
075A
0761
0774

A VERIFY vezérlő rutinja

  • szintaktikai vizsgálat
  • a célrekesz címének vizsgálata
  • tényleges betöltés

 

1995
2025
2036

 

07CB
07E9
07F4

Egy adatblokk betöltése
2050
0802

A LOAD vezérlő rutinja

  • adatok beállítása
  • memóriahely vizsgálat
  • tényleges ellenőrzés
  • tömb betöltése
  • helybiztosítás új tömb számára
  • BASIC program és változói betöltése

 

2056
2073
2085
2094
2124
2163

 

0808
0819
0825
082E
084C
0873

A MERGE vezérlő rutinja

  • adatblokk betöltése
  • összehasonlítás és szükség szerinti betöltés
  • ciklus az új programsorok kezelésére
  • ciklus a memória kezelésére
  • változók összehasonlítása ill. szükség szerinti betöltése
  • egy sor vagy egy változó szükség szerinti betöltése

 

2230
2253
2258
2263
2288
2348

 

08B6
08CD
08D2
08D7
08F0
092C

A SAVE vezérlő rutinja

  • csatorna megnyitása, üzenet kiírása
  • fejléc magnetofonra küldése
  • rövid szünet és az adatok magnetofonra küldése

 

2416
2436
2445

 

0970
0984
098E

3. blokk:
Ebben a blokkban tárolták el a magnetofon kezelésével kapcsolatos üzeneteket. (CR=kocsi vissza-soremelés) Az egyes üzenetek elhelyezkedését az előző felosztáshoz hasonlóan közöljük:

"Start tape then press any key" üzenet
2466
09A2
CR+"Program:"
2497
09C1
CR+"Number array:"
2507
09CB
CR+"Character array:"
2522
09DA
CR+"Bytes:"
2540
09EC

Az üzenettáblázat elején, és az egyes üzenetek után un. delimiter (elhatárolójel) lett elhelyezve.

Manipulációk a LOAD/SAVE rutinnal

Először is ahhoz, hogy a LOAD/SAVE rutinban bármit is megváltoztatnánk, azt ki kell menteni RAM területre. Célszerű a ROM rutint a memória végére átmenteni. Egyenlőre csak az 1.blokkra lesz szükségünk, de mivel a későbbiekben a turbo-manipulációkhoz kell majd a 2. és a 3. blokk is, így célszerű az új területen elhelyezkedő rutin kezdőcímét ezek figyelembevételével megválasztani. Válasszuk kezdőcímnek a 63962-t. Az 1. blokk áthelyezési rutinját pedig olvassuk be az 50000. címtől:

50000
50003
50006
50009
50011

33, 194, 4
17, 218, 249
1, 67, 1
237, 176

201

LD HL,1218
LD DE,63962
LD BC, 323
LDIR
RET

; az átmozgatandó blokk kezdőcíme
; a célhely kezdőcíme
; az 1. blokk hossza
; a blokk átmozgatása
; vége

A beolvasáshoz egyszerűen készítsünk egy BASIC programot:

10 FOR i=50000 TO 50011
20 READ a: POKE i,a: NEXT i
30 DATA 33,194,4,17,218,249,1,67,1,237,176,201

Adjuk ki: RUN (ENTER), majd RANDOMIZE USR 50000 (ENTER) és az 1. blokk átíródik a 63962. címtől.

Az 1. blokk az új helyen egyenlőre még futásképtelen, az abszolút címhivatkozásokat át kell írnunk. Gépeljük be és futtassuk az 50. sortól a következőt:

50 POKE 63963,87: POKE 63964,250:
POKE 63998,240: POKE 63999,249:
POKE 64020,31: POKE 64021,250
60 POKE 64036,61: POKE 64037,250:
POKE 64064,44: POKE 64065,250:
POKE 64080,22: POKE 64081,250
70 POKE 64133,255: POKE 64134,250:
POKE 64148,251: POKE 64149,250:
POKE 64155,251: POKE 64156,250
80 POKE 64170,255: POKE 64171,250:
POKE 64180,255: POKE 64181,250:
POKE 64227,251: POKE 64228,250
90 POKE 64238,226: POKE 64239,250:
POKE 64252,255: POKE 64253,250

Adjuk ki: RUN 50 (ENTER)

Az 1. blokk az új helyen most már futtatható. Felvetődhet a kérdés, mi az oka annak, hogy teljesen logikátlanul hol relatív, hol abszolút ugrások lettek elhelyezve a rutinban, amikor mindegyik abszolút hivatkozás kiváltható lenne relatív címzéssel. Erre mi sem tudjuk a pontos választ, de az biztos hogy ezzel megnehezítik azoknak a dolgát, akik a ROM-ból bármit is ki akarnak másolni.
Egy fontos dolog! Ha még idáig nem történt meg, akkor még most feltétlenül adjuk ki: CLEAR 63000 (ENTER), mert a későbbiekben problémába ütközünk.
Ha megvolt a CLEAR a RAMTOP áthelyezéséhez, nyugodt szívvel adjunk egy NEW-t, az eddigi BASIC törléséhez. Első lépésként nézzük meg, hogyan lehetséges a jól ismert piros/világoskék ill. a kék/sárga BORDER csíkok színeinek megváltoztatása.

Ahhoz, hogy a csík-effektus változatlanul maradjon, csak a színek változzanak, a következőket tehetjük.
Feltétlenül helyezzünk el megint a memóriában egy segéd-mentő/töltő rutint, amely beállítja a kezdőcímet és a hosszt a már megismert módon. Az egyszerűség kedvéért helyezzük el ismét az előző fejezetpontban ismertetett rutinokat a 60000-60026. címek között a képernyőmemória mentésére ill. töltésére.
Természetesen most már két sort ki kell cserélnünk:

60009

60023

205, 218, 249

205, 110, 250

CALL 63962

CALL 64110

; az adatok magnetofonra mentése a
; RAM rutin segítségével
; az adatok betöltése a RAM rutin
; segítségével

Ha ezek a rutinok is a memóriában vannak, próbáljuk ki őket:

RANDOMIZE USR 60000
problémamentesen a magnetofonra küldi az adatokat, ill.

RANDOMIZE USR 60013
segítségével ezek visszahívhatók.

Azt, hogy a keret-csíkozás ne a hagyományos színkombinációban, vagy érdekes hatásokkal jelenjen meg, csak a töltő rutinban érdemes kiváltani, hiszen általában egy kész program betöltését színesítik. Annak sok értelme nincs, hogy kész programunk saját magunk szórakoztatására úgy kerüljön kazettára, hogy közben a képernyő-keret a szivárvány színeiben tündököl.
A töltő rutinban (1366-1540 ; HEX 0556-0604) több helyen is eszközölhetünk változtatást.
Az eredeti rutinban az 1384-es címen, az áthelyezett kódban így a 64128-as címen található az a konstans, amelyik a bevezető TONE alaptónusát meghatározza (alapértéke = 2). Próbáljuk megváltoztatni ezt az értéket, és ismételjük meg a betöltést. Láthatjuk, hogy a csíkok színe megváltozik. Pl. 1 esetén a TONE kék/sárga lesz, 0 esetén pedig fekete/fehér.
A ROM rutin 1441-es, így az áthelyezett kód 64185-ös címén az alapérték 3. Próbáljuk meg ezt is megváltoztatni. A két cím együttes változtatása újabb kombinációkat eredményez.
Felvetődik a kérdés, de vajon hogyan lehet megvalósítani azt, amikor betöltés közben a keret egy színű, vagy szivárványosan tölt ?
Tekintsünk vissza ismét a ROM rutin assembly listájára. A BORDER szín végleges beállítása és megjelenítése az 1530-1538 címek között
történik. Az 1532. és 1533. címek közé kell beszúrnunk egy vagy több olyan utasítást, amely a BORDER-t megfelelően módosítja. Ehhez először is az 1. blokk végét az 1533. címtől arrébb kell tolnunk.

Ezt a vágást ennek megfelelően a RAM rutinban a 64276/64277 között kell elvégezni, és az attól jobbra levő byte-okat két byte-tal jobbra pakoljuk.
Ehhez gépeljük be a következőt:

100 POKE 64277,0: POKE 64278,0:
POKE 64279,230: POKE 64280,7:
POKE 64281,246: POKE 64282,8:
POKE 64283,211: POKE 64284,254:
POKE 64285,55: POKE 64286,201

Ezután RUN 100 (ENTER).
Próbáljunk ismét betölteni, egyenlőre semmi változást nem tapasztalunk. A 64277-64278-as címekre tetszés szerint beírhatjuk a megfelelő kódokat.
Csak néhány variációt közlünk, a további próbálgatást az olvasóra bízzuk.

POKE 64277,62: POKE 64278,szín
(LD A,szín)
- ahol szín=0-7 és az adott színt megtartja "csíkozás" nélkül betöltés közben a képernyő-keretre.
POKE 64277,120: POKE 64278,0
(LD A,B)
- szép, szivárványos betöltés
POKE 64277,122: POKE 64278,0
(LD A,D)
- nincs "csíkozás", a színek a teljes keretre 256 byte-onként váltják egymást.
POKE 64277,123: POKE 64278,0
(LD A,E)
- szivárványszerű betöltés, változó, igen érdekes "csík"-hatásokkal.
POKE 64277,124: POKE 64278,0
(LD A,H)
- különleges hatás
POKE 64277,237: POKE 64278,95
(LD A,R)
- szivárványszerű (ezt alkalmazták pl. a COMMANDO c. játékban).
POKE 64277,170: POKE 64278,0
(XOR D)
- a csíkozás színeinek 256 byte-onként periódikus változása.
POKE 64277,166: POKE 64278,0
(AND (HL))
- fekete tónusú, vibráló keret.

Ezek után bizonyára többekben felvetődik a kérdés. Van-e lehetőség kikapcsolni software úton betöltéskor a belső hangszórót. A belső huzalozás révén erre software oldalról nincs lehetőség, de nem is lenne sok értelme lekapcsolni.
Bizonyára több játékban találkozott már a felhasználó olyan hatással, hogy a képernyő nem hagyományos módon töltődött be, hanem pl. alulról felfelé stb.
A legegyszerűbb variáció az, amikor un. visszafele töltést valósítunk meg, vagyis a memóriában nem a növekvő, hanem a csökkenő címek felé töltjük a programot. Ennek az egyik alapfeltétele, hogy azt már eleve ilyen formában kell kazettára is mentenünk.
Az eredeti ROM rutinban az 1323/24 címeken található INC IX utasítás a kimentéshez, ill. betöltéshez az 1474/75 címeken. Ezt mindkét helyen egy DEC IX utasítással kell helyettesítenünk, vagyis az áthelyezett blokkban a 64068. és a 64219-es címek tartalmát kell 35-ről 43-ra megváltoztatnunk.
Gépeljük be:

POKE 64068,43: POKE 64219,43

Nézzünk a visszafelé töltésre is mintapéldát, látványosan természetesen most is használjuk a képernyőmemóriát. Használjuk fel ismét a 60000. címtől elhelyezett mentő, és 60013. címtől elhelyezett töltő rutint. Most IX-be tehát nem a kezdő, hanem a végcímet kell megadnunk, a többi paraméter nem változik. A változás tehát:

60002
60016

221, 33, 255, 90
221, 33, 255, 90

LD (IX+00),23295
LD (IX+00),23295

; IX-ben a végcím
; IX-bena végcím

Készítsünk ismét egy tetszőleges grafikát, és mentsük ki:

RANDOMIZE USR 60000

Csévéljük vissza a kazettát, és a RANDOMIZE USR 60013 (ENTER) utasítással töltsük vissza a képet. Láthatjuk, a töltés visszafelé indul meg, ezt még szivárványos kerettel is kombinálhatjuk, úgy mint a HIGHWAY ENCOUNTER c. játékban.
Tegyünk egy próbát is, töltsük be előző képünket, láthatjuk meglehetős zagyvaság jelenik meg a képernyőn. A visszafelé töltést előnyessen alkalmazzák nagyobb kódok töltésére, hogy a "kíváncsiak" a kód önmagában történő betöltésekor csak értelmetlen adathalmazt találjanak. Mielőtt a turbo-ra rátérünk, még egy kitérőt teszünk a betöltök egy speciális változatára.
Több programban (pl. ROMMEL'S REVENGE, MIKIE stb.) találkozunk a képernyő betöltés teljesen szabálytalan megoldásával. A CRYSTAL Software által ismert variáció, amikor a képernyőt képpontsoronként lefelé haladva tölti be a betöltő rutin. Ma a leggyakoribb forma, amikor a karakternek egymás után betöltődik az egymás alatti 8 byte-ja, majd ráhívódik az ATTR byte is, és következik az újabb karakter. Igen látványos, de időigényes manipuláció. Mindenekelőtt szét kell bontani a betöltő rutint ott, ahol az IX (aktuális báziscím) növelése (INC IX) történik. Ez a hely a ROM-ban az 1474-es cím, az áthelyezett kódban tehát 64218. Ezen a ponton meg kell oldani a mindenkori aktuális báziscím előállítását. A báziscímeket célszerű egy adattömb formájában külön eltenni a memóriában, olyan sorrendben, ahogyan majd a kiolvasás történik. Kiolvasáskor a mutató tovább lép a következő báziscímre. Az adattömb elkészítésére célszerű egy egyszerű BASIC programot írnunk. Természetesen a mentő rutint is ennek megfelelően kell módosítanunk, hiszen az adatokat is ilyen sorrendben kell a magnetofonra kiküldeni.

Több fokozatú TURBO készítése

A TURBO program közismert más géptípusra is. A jel-átviteli sebesség (BAUD RATE) megnövelését segíti elő. Ez előnyös a gazdaságos tárolás ill. töltési/mentési idők csökkentése szempontjából, de hátrányos is, mert a kazettás magnetofonnal bizonytalanabbá válik a hibátlan adatrögzítés.
A Spectrum alaphelyzetben 1500 baud (bd) jel-átviteli sebességgel dolgozik. A baud egy mértékegység, a másodpercenként átvitt bitek számát fejezi ki (bit/sec).
Egy turbo csak akkor hatékony, ha lehetővé teszi nem csak a gépi kód, hanem BASIC program ill. adat-és stringtömb gyorsítását is. Ehhez először is ki kell menteni a RAM-ba a 2. és 3. blokkot is. Eddigi rutinunk a RAM-ban a 64286-os címig tart, vagyis a 2. és 3. blokk áthelyezésének startcíme: 64287.
Az áthelyező mechanizmus a következő:

51000
51003
51006
51009
51011

33, 5, 6
17, 31, 251
1, 239, 9
237, 176
201

LD HL,1541
LD DE,64287
LD BC,1007
LDIR
RET

; a 2-3. blokk kezdőcíme
; a célhely kezdőcíme
; az 2-3. blokk hossza
; a blokk átmozgatása
; vége

Olvassuk be a kódot, majd adjuk ki: RANDOMIZE USR 51000 (ENTER) és a 2. ill. 3. blokk is a RAM memóriába kerül.

Egyenlőre a 2. és 3. blokk is futásképtelen az új helyen, az abszolút címhivatkozásokat megfelelően át kell írni. Gépeljük be és futtassuk a következő sorokat:

200 POKE 64440,116: POKE 64441,252:
POKE 64633,138: POKE 64634,254:
POKE 64649,110: POKE 64650,250
210 POKE 64734,34: POKE 64735,253:
POKE 64739,208: POKE 64740,253:
POKE 64797,110: POKE 64798,250
220 POKE 64907,28: POKE 64908,253:
POKE 64974,28: POKE 64975,253:
POKE 64997,28: POKE 64998,253
230 POKE 65030,70: POKE 65031,254:
POKE 65090,70: POKE 65091,254:
POKE 65189,218: POKE 65190,249
240 POKE 65209,218: POKE 65210,249

ezután RUN 200 (ENTER).
Az új területen helyet foglaló rutint is a hagyományos Spectrum BASIC utasításokkal fogjuk kezelni, de ezt meg kell előznie egy USR hivatkozásnak, mert máskülönben a ROM-beli rutinokra adódna át a vezérlés.
Az utasítás szerkezete a következő lesz:

LET a=USR xxxx: aaaa "név" stb. (ENTER)

A kettőspont után a hagyományos töltési/mentési parancs szerkezeteket kell alkalmazni (aaaa = LOAD/SAVE/VERIFY/MERGE ). A belépés viszont nem ilyén egyszerű. Egy külön belépési rutint kell írnunk, melynek kezdőcíme az xxxx cím, és innen adjuk át a vezérlést a RAM-beli 2.blokk kezdetének, ami jelenleg a 64287. címen található.
A kiegészítő-belépési rutinnak meg kell oldania a mutatók megfelelő átállítását, és az utasítás típusának megfelelően a T-ADDR rendszerváltozó beállítását. A kiegészítő rutint az 1. blokk elé érdemes elhelyezni. Hossza 57 byte, vagyis xxxx=63905.

A kiegészítő rutin a következő:

63905
63908
63909
63912
63915
63918
63921
63922
63925

63928

93929
93930
63933
63935
63937
63938
63940
63942
63943
63945
63947
63948
63950
63952

63955
63959

58, 71, 92
60
50, 71, 92
33, 0, 0
34, 11, 92
42, 93, 92
35
34, 93, 92
1, 224, 26

223

35
34, 93, 92
254, 248
40, 13
3
254, 239
40, 13
3
254, 214
40, 8
3
254, 213
40, 3
195, 138, 28

237, 67, 116, 92
195, 31, 251

LD A,(23623)
INC A
LD (23623),A
LD HL,0
LD (23563),HL
LD HL,(23645)
INC HL
LD (23645),HL
LD BC,6880

RST 18

INC HL
LD (23645),HL
CP 248
JR Z,63955
INC BC
CP 239
JR Z,63955
INC BC
CP 214
JR Z,63955
INC BC
CP 213
JR Z,63955
JP 7306

LD(23668),BC
JP 64287

; a SUBPPC mutató
; léptetése
;
; a DEF ADD rendszerváltozó
; törlése
; a CH ADD címmutató
; léptetése
;
; BC alapértékének beállítása
; a T-ADDR rendszerváltozóhoz
; karaktervizsgálat (a végén az 'A'
;
regiszter tartalmazza a karakter kódját)
; CH ADD tovább lép
;
; SAVE utasítás?
; ugrás, ha igen
; BC tovább lép
; LOAD utasítás?
; ugrás, ha igen
; BC tovább lép
; VERIFY utasítás?
; ugrás, ha igen
; BC tovább lép
; MERGE utasítás?
; ugrás, ha igen
; a "Nonsense in BASIC" hibaüzenet
; meghívása
; a T-ADDR rendszerváltozó beállítása
; ugrás a belépési pontra (a 2. blokk eleje)

Ha a kódot beolvastuk a memóriába, ki is próbálhatjuk a rendszer jelenlegi működését. Pl.:

LET a=USR 63905: SAVE "név"

egy tetszőleges és éppen a memóriában levő BASIC elmentéséhez, vagy pl.:

LET a=USR 63905: SAVE "név" CODE 0,1000

egy tetszőleges memóriaterület kimentéséhez.

A mentés és a töltés ebben a formájában semmiben nem különbözik a ROM-beli állapottól.
Most egy táblázatot közlünk, amely 24 különböző sebességi fokozatra adja meg a megváltoztatandó byte-ok értékeit.
Az egyes oszlopok a baud sebességekre vonatkoznak, a sorok pedig az adott címen beállítandó értéket határozzák meg. Itt zárójelben megjegyeztük a ROM rutinban megfelelő címet is, hogy az ismertetett assembly listában megkönnyítsük az eligazodást.

cím / baud
1500
1600
1700
1800
1900
2000
2100
2200
64049 (1305)
66
62
58
55
52
49
47
45
64055 (1311)
62
57
52
48
46
45
42
40
64070 (1326)
49
43
39
36
33
31
29
27
64190 (1446)
176
181
186
191
197
202
206
209
64223 (1479)
178
183
188
193
199
204
208
211
64231 (1487)
203
207
211
215
217
219
221
223
64236 (1492)
176
181
186
191
197
202
206
209
64256 (1512)
22
22
21
21
21
20
19
18
cím / baud
2300
2400
2500
2600
2700
2800
2900
3000
64049 (1305)
43
41
39
37
35
33
32
31
64055 (1311)
38
36
34
32
30
29
28
26
64070 (1326)
25
23
21
19
17
15
14
13
64190 (1446)
211
212
214
215
216
217
219
220
64223 (1479)
213
215
216
217
218
219
221
222
64231 (1487)
225
227
228
229
230
231
232
233
64236 (1492)
211
212
214
215
216
217
219
220
64256 (1512)
17
16
15
14
13
12
11
10
cím / baud
3100
3200
3300
3400
3500
3600
4500
7500
64049 (1305)
30
29
28
27
27
26
21
16
64055 (1311)
25
24
23
22
22
21
18
12
46070 (1326)
12
11
10
10
9
8
5
2
64190 (1446)
221
223
224
225
225
226
230
240
64223 (1479)
223
225
226
226
227
228
232
242
64231 (1487)
234
235
236
236
237
237
240
248
64236 (1492)
221
223
224
225
225
226
230
240
64256 (1512)
9
9
8
8
7
7
4
2

Az igaz, hogy a 4500 bd. érték 3-szoros, a 7500 pedig 5-szörös sebességgyorsulást eredményez, de ha kipróbáljuk ezeket az értékeket, azt fogjuk tapasztalni, hogy a magnetofon ill. a kazetta minőségétől függően max. csak 2400-2700 baud sebességre tudunk gyorsítani, és sajnos már ezeknél az értékeknél is igen nagy a hibázás lehetősége. A gyakorlat azt mutatja, hogy kisebb hordozható kazettás magnetofonnal még elfogadhatóan visszatölthető a 2000-2200 bd. gyorsítás, jobb minőségű deck + jó minőségű kazetta együttes eredménye "néha" elviszi a 2700 bd. értéket is.
Próbálkozhatunk szalagos magnetofonnal ill. video készülékkel is több kevesebb sikerrel, de nagy eredményeket ne várjunk! Akik úgy gondolják, hogy eddigi programjaik sebességét 1500 bd.-ról 2200-ra kívánják megnövelni igaz hogy nagy helymegtakarítást érnek el (több kazetta felszabadulhat), de jól fontoljuk meg, hogy megéri-e a fáradtságot, hiszen a legtöbb játék memóriabeli méreténél fogva meg sem engedi a turbo használatát, másrészt a megbízhatóság jelentősen romlik.

Egy utolsó javaslat a töltési idő ill. helyigény csökkentésére. Ha fejléccel mentünk ki valamit, a fejléc és a byte-ok között kb. 1 másodperc szünetet hagy a gép. Ezt az időtagot kivehetjük a RAM-beli rutinból:

POKE 65194,1: POKE 65195,0

Ekkor a késleltetés elmarad, és szinte folyamatosan menti ki a byte-okat a fejléccel együtt a rutin.

Néhány hasznos tanács

Gyakran problémába ütközhetünk, ha fejléces blokkokat használunk, és betöltött SCREEN$ file-unk épségét meg akarjuk őrizni. Természetesen azt mondhatjuk, ez kikerülhető, ha a képernyő felrajzolása után a többi blokkot fejléc nélkül hívjuk be.
Ennél viszont van egyszerűbb módszer is, nézzünk egy mintapéldát:

Programunk három részbál áll:
- BASIC betöltő
- SCREEN$ file
- gépi kódú rutin(ok)
A file-ok mind fejléccel rendelkeznek, képünk viszont a teljes képernyőt, vagyis mind a 24 sort kihasználja. Valamilyen módon meg kell akadályoznunk, hogy a harmadik file fejléc információja "belevágjon" a képernyőbe.
A BASIC betöltő legyen a következő:

10 CLEAR xxxx
20 LOAD""SCREEN$
30 POKE 23739,111
40 LDAD""CODE: POKE 23739,244
50 RANDOMIZE USR nnnn

A 30. sorban elhelyezett utasítás a megoldás kulcsa. A 23739/40 címek a CHANNEL INFORMATION (csatorna információk) területéhez tartoznak. Ez a két cím a mindenkori PRINT-OUT mutató. A PRINT-OUT rutin a 2548-as (HEX 09F4) címen kezdődik, vagyis alaphelyzetben a 23739/40 címek tartalma 244/9. Ha a 23739. cím tartalmát 111-re változtatjuk meg, a mutató a 2415-ös ROM címre mutat, ahol 201-es (RET) kód van, és az üzenet nem jelenik meg a képernyőn. Természetesen a mutatót adott helyen célszerű visszaállítani.

Hasonló módszerrel lehetséges a másoló-programokból is ismert auto-kimentés megoldása is. Több programrészt vagy adatblokkot úgy tudunk kimenteni, hogy az egyes blokkok között a gép nem vár billentyű megnyomásra. Igaz egy pillanatra megjelenik a képernyőn a "Start tape..." felirat, de azonnal törlődik is.
Nézzünk erre is egy mintapéldát. Mentsünk ki egymás után egy BASIC-et, egy SCREEN$ file-t és egy gépi kódú rutint egyfolytában, minden beavatkozás nélkül.

9000 SAVE "program" LINE nnnn
9010 POKE 23736,181
9020 SAVE "SCREEN$"SCREEN$
9030 POKE 23736,181
9040 SAVE "kód"CODE nnnn,mmmm

A 23736/37 címek is a csatorna-információk területének elemei. Alaphelyzetben tartalmuk: 168/16, azaz a két cím tartalma a 4264-es (HEX 10A8) KEY INPUT rutin mutatója. Ez a rutin vár egy billentyű megnyomására. Ha ezt átlépjük, vagyis a 4264. helyett a 4277. címen lépünk be a rutinba, akkor a várakozást kikerültük, és minden automatikusan onnan folytatódik tovább, mint amikor a várakozás után egy billentyűt megnyomunk. Kimentés után az alapérték (168) visszaíródik, vagyis minden file kimentése előtt újra és újra át kell írni a cím tartalmát, ha folyamatos mentést akarunk.

Ebben a fejezetben még nagyon sok mindent le lehetett volna írni a LOAD/SAVE rutinokkal megvalósítható trükkökről, reméljük az itt közölt információk lehetőséget adnak a felhasználó számára a témában való bővebb elmélyedéshez.

Vissza