1   2   3   4   5   6   7   8   9

 

 

Az ENTERPRISE gép piacra kerülésekor, és azóta is nagy probléma a programok hiánya (akár játék-, akár felhasználói programról is legyen szó). Ezzel szemben ott van pl. a SPECTRUM, amely a maga néhány ezer (!) software termékével a viszonylag jól ellátott gépek közé tartozik. Előbb-utóbb mindenkiben felvetődik a kérdés: hogy lehet a SPECTRUM programokat futtatni az ENTERPRISE gépen?

 

A futtatásra több módszer is lehetséges

 

 • A legegyszerűbb venni egy SPECTRUM-EMULÁTOR-t. Ennek a módszernek vannak előnyei, de vannak hátrányai is. Előnye, hogy egyszerű, különösebb szakértelmet nem igényel. Hátránya, hogy egyrészt relatíve drága, másrészt nem kezeli a floppy egységet, így aki rendelkezik lemezmeghajtó egységgel, kénytelen minden alkalommal EMULÁTOR-EXDOS cserét végrehajtani, ez pedig jelentősen igénybe veszi a gép fólia-érintkezőit, arról nem is beszélve, hogy aki hozzászokott a floppy sebességéhez, az elég nehezen tűri a 'hosszú, méla lest'. Mindemellett a programoknak csak bizonyos százaléka futtatható ezzel a módszerrel.

 

• Bonyolultabb, de eredményesebb módszer az, amikor a felhasználó fogja a SPECTRUM programot, és elmélyült programozással futtathatóvá teszi azt az ENTERPRISE gépen. Ennek a módszernek is van hátránya, történetesen az, hogy elég jól kell ismerni a gépi kódú programozást, valamint mindkét gép lelkivilágát (HARDWARE), viszont sokkal több előnye van, mint hátránya: bármilyen program átírható ezzel a módszerrel, az átírt programok lemezről is betölthetők, és nem utolsó sorban a program-átíró szellemi épülését is segíti.

 

Mi a most induló módszertani segédletben a második módszerrel szeretnénk foglalkodni, hasznos tanácsokat adva a kedves Olvasónak, azoknak akik elég önbizalommal (és tudással) rendelkeznek ahhoz, hogy egyénileg nekivágjanak egy ilyen mélységű munkának.

 

Általános áttekintés

 

Mindenekelőtt azt kell tisztáznunk, hogy mi szükséges egy valamely gépen futó program másik gépre történő átkonvertálásához:

 

• Gépi kódú program esetén a két gép központi egységének ugyanolyan nyelven kell 'beszélnie', vagy a fogadógépnek legalább szimulálnia kell tudni a forrásgép nyelvét (ettől eltérő esetben is átírható egy program, de a módszer sokkal bonyolultabb). Más (magas szintű) nyelvek esetén nem fontos a kód-kompatibilitás, elég, ha a két fordítóprogram (legyen az akár interpreter, akár compiler) azonos nyelvjárást ismer (Ilyen pl. a CP/M alatt, és az IBM PC-n is futó TURBO-PASCAL is. Az IBM PC-n futó TURBO PASCAL megérti a CP/M alatt futó TURBO PASCAL forrásszövegét, fordítás után futtatható is.) Visszatérve a gépi kódhoz, ez a mi esetünkben biztosítva van, mivel mindkét gép szíve egy Z-80-as mikroprocesszor. Ez azt jelenti, hogy a SPECTRUM-ról átvitt kód minden változtatás nélkül futtatható az ENTERPRISE-on is, természetesen ez még nem jelenti azt, hogy működni is fog. A működés biztosításához több feltételnek teljesülnie kell.

 

• Amennyiben a két gép gépi kódja megegyezik, a következő probléma a program átvitele egyik gépről a másikra. Esetünkben a megoldást a két gép magnetofon-illesztőjének hasonlósága adja. Tekintettel arra, hogy a SPECTRUM programok nagy része audio kazettán terjed, kézenfekvő az, hogy az átírni kívánt programot magnetofonról olvassuk be.

 

• Ha a kód már a célgépen található, újabb probléma vetődik fel: a gépek közötti hardware különbség. Ez a mi esetünkben is probléma. Ez az oka annak, hogy programunkat erőteljesen módosítani kell.

 

• A felépítésbeli különbség maga után vonja az operációs rendszerek különbségét is. A SPECTRUM programok esetében elég népszerű a BASIC-ROM egyes szubrutinjainak hívása. ENTERPRISE gépen ez másképp van megoldva, így más utat kell választanunk. A ROM rutinok hívása különösen a felhasználói programok esetében elterjedt. Játékprogramok ritkán hívják meg ezeket a rutinokat, így a játékprogramok átírásához kijelölhetjük a követendő irányvonalat:

 

1. A program kódját át kell vinnünk az ENTERPRISE gépre.

2. Az átvitt kódot hardware szempontból módosítanunk kell.

3. A módosított programot el kell látni egy betöltővel, amely hivatott a programot beolvasni a megfelelő memóriahelyekre, valamint az alapvető hardware emulációt végrehajtani.

 

Módosítás hardware oldalról

 

Egy játékprogram esetében három dolgot kell megfelelően átalakítanunk: grafika, hang, irányítás.

 

Grafika: Készíteni kell egy olyan képernyő üzemmódot, ami megegyezik a SPECTRUM-éval. Mint bizonyára minden Olvasó tudja, a SPECTRUM ún. attribútum üzemmódban dolgozik. Ez azt jelenti, hogy van egy bittérképe, ahol minden képpontnak egy bit felel meg. Azt, hogy az 1-es ill. 0-ás bit milyen színű legyen, az attribútum byte határozza meg. Nyolc egymás alatti képernyő byte-hoz tartozik egy attribútum byte, vagyis egy attribútum bytetal egyidőben 8x8=64 bit színét állíthatjuk be. A bittérképben lévő 0 biteket háttér, vagy papír színnek (PAPER), az 1 biteket pedig kiíró, vagy tinta színnek (INK) nevezzük.

Legnagyobb szerencsénkre az ENTERPRISE gép video chip-je (NICK chip) szintén ismeri az attribútum üzemmódot, igaz egy kicsit másképpen. Ezentúl - hogy ne legyen azért olyan egyszerű a dolgunk - a SPECTRUM meglehetősen egyéni módon helyezi el a memóriában a képpont sorokat, valamint speciális a színösszeállítása is.

Készítenünk kell egy olyan LPT-t (Line Parameter Table - sorparaméter tábla), amely ilyen felbontással, ilyen színösszeállítással, stb. generál egy SPECTRUM képernyőt. A színek miatt később még egy elég nehéz konvertálás is vár ránk.

 

Hang: A SPECTRUM (a normál 48K-s gép) egy egyszerű BEEP hangkeltéssel rendelkezik, vagyis egy biten történik a hanggenerálás. Ha a bit 1 értékű, akkor a hangszóró kimozdul, míg ha 0, akkor visszahúzódik, így ha ezt a bitet valaki megfelelő frekvenciával billentgeti, akkor megszólal a gép. Ezt az ENTERPRISE gépen elég egyszerű szimulálni, mivel a hanggenerálásért felelős alkatrész (DAVE chip) rendelkezik egy un. D/A üzemmóddal. Ez azt jelenti, hogy ilyenkor a hangerőregiszterben megadott nagyságú szint rákerül a hangszóróra, és ott is marad. Gyakorlatilag ez ugyanaz, mint a SPECTRUM módszere, de itt nem egy bitet kell billegtetni, hanem felváltva 0, és egy 0-nál nagyobb szintet kell a hangerőregiszterbe írni, így még a hangerő is módosítható. Természetesen a programban meg kell keresni az összes hanggenerálással foglalkozó rutint, és a fent leírtaknak megfelelő formára kell hozni.

 

Irányítás: Ez természetesen már egy extra szolgáltatás, annak van rá szüksége, aki használni is szeretné a programot. A problémát itt is az okozza, hogy a SPECTRUM egyéni billentyűzet-figyelést alkalmaz. Itt többféle megoldást is alkalmazhatunk: írhatunk egy általános szubrutint, amely szimulálja az eredeti billentyűzetet, vagy pedig magában a programban kielemezzük a billentyűzet-figyelő rutin működését, és írunk helyette egy másikat. Az utóbbi megoldás elegánsabb, gyorsabb és jobban próbára teszi a programozó képességeit. Az első megoldás kényelmesebb, de alacsonyabb színvonalú.

 

Egyéb akadályok

 

Fejtörést okozhat több dolog is, pl. az IM2-es megszakítás szimulálása. Ez az a dolog, ami miatt több program nem fut az EMULÁTOR-on sem. Problémát okoz az 'EI' utasítás is (ENTERPRISE-on másképp kell végrehajtani), a 128K memórialapozás, a 128K zene (AY-3 8912 chip szimulálása), egyes ROM hívások, stb. Az ilyen speciális problémákra egy-egy aktuális rész kifejtése során fogunk kitérni.

 

Hasznos tanácsok

 

A program átírási manipulációhoz nem árt beszerezni egy disassembler-monitor programot, mivel e nélkül kicsit nehézkes lenne a dolgunk. Mi a SIMON (ASMON) nevű Z-80 fejlesztő-rendszert használtuk, ugyanis ez nem csak disassembler, hanem assembler is. Minden - később ismertetésre kerülő - példaprogram ezzel a rendszerrel lett előállítva.

Az sem árt, ha van a közelünkben egy SPECTRUM, persze ez nem létszükséglet, csak az eredetivel való egybevetéshez, ill. a BASIC betöltök listázásához kell. Célszerű egy software SPECTRUM EMULÁTOR beszerzése is, mivel a BASIC listázására ez is alkalmas.

Miért kell listázni a SPECTRUM verzió BASIC betöltőjét? Nos, a SPECTRUM programok általában egy BASIC betöltővel indulnak, a betöltő (LOADER) tölti be a program további részét (részeit). Ez egyrészt kényelmi szempontból jó (elég a LOAD"" utasítás, nem kell kiírni mögé a CODE függvényt), másrészt így egyszerien biztosítható az AUTOSTART). Ha nem listázzuk ki a BASIC betöltőt, akkor nem tudjuk a blokkok számát, az egyes blokkok betöltési címét, hosszát, s nem utolsó sorban a legfontosabbat, a program indítási címét. Természetesen a programok többsége nem engedi magát listázni, esetleg a betöltő maga is gépi kódú, vagy rejtett, ezekre a speciális esetekre is a megfelelő módszer ismertetésénél fogunk kitérni.

 

A következő részben az első lépésről, a SPECTRUM program ENTERPRISE gépbe való átgyötréséről fogjuk a fátylat lerántani.

 

A SPECTRUM programok átírásának első lépcsőfoka magának a kódnak az átvitele egyik gépről a másikra. Ez esetünkben kézenfekvő, mivel a programok elnyomó többsége kazettán kerül az amatőrök kezébe. A feladat tehát az, hogy a SPECTRUM által felírt kazettákat elolvassuk. Szerencsére mindkét gépnek hasonló a kazettás magnót kezelő hardware felépítése.

Kicsit konkrétabban: a SPECTRUM 254-es (0FEH) porijának 5. bitje a kazettás adatrögzítés bemeneti bitje. A szalagról bejövő jel nagyságától függően vagy 1-be, vagy 0-ba állítja ezt a bitet.

ENTERPRISE-on a 182-es (0B6H) porton a 7. bit nagyjából hasonló feladatot lát el. Vagyis feladatunk eléggé leegyszerűsödik, mivel az eredeti loader-t kivehetjük a SPECTRUM ROM programjából, csak a hardware különbségeket kell korrigálni. Mi is ezt tettük a közölt programban. A példaprogram egy kicsit bonyolultabb, mert különböző luxusszolgáltatásai is vannak. Megértéséhez szükséges az EXOS (az ENTERPRISE operációs rendszere) ismerete.

Az EXOS használata a csatornák használatán alapul. Erre a SPECTRUM BASIC esetében is történtek próbálkozások, de korántsem sikerült annyira logikusan. A csatornák lényege az, hogy ha valamilyen egységet kezelni akarunk, akkor nem kezdünk el szeleburdi módon ROM-rutinokat hívni, hanem nyitunk számára egy kommunikációs csatornát. Azt, hogy milyen egységgel akarunk "szót váltani" a rendszer onnan tudja, hogy a csatorna megnyitásakor megadjuk az eszköz nevét. Ilyen eszközök a billentyűzet (KEYBOARD:), a nyomtató (PRINTER:) stb. Az EXOS onnan ismeri fel az eszközt, hogy kettőspont van a végén. Vannak olyan eszközök, amelyek file alapúak, és vannak olyanok is, amelyeknek csak a csatorna létrejötte szükséges. Például, ha kazettán létrehozunk egy file-t, akkor annak meg kell adnunk a nevét, adatokat kell beleírnunk, majd le kell zárni. A billentyűzet esetén nem akarunk file-t sem olvasni, sem írni, mi csak az éppen leütött billentyűre vagyunk kíváncsiak.

Egy csatorna, ha már létrejött, sok mindenre jó. Tudunk bele adatokat írni, adatokat olvasni. Csatornát EXOS funkcióhívással tehet megnyitni. Az EXOS funkcióhívás a következőképpen néz ki:

 

                           RST 30H

                           DEFB funkciókód

 

Általában az A regiszter tartalmazza a csaturna számot, DE-ben és BC-ben adunk át paramétereket. Visszatéréskor az "A" regiszter egy hibakódot tartalmaz, ami 0, ha sikeres volt a művelet. Mivel így elég nehézkes használni, ezért erre létrehoztak az ASMON-ban egy előre definiált makrót EXOS néven. Ennek használata: "EXOS funkciókód" ahol a funkciókód értelemszerűen a kívánt operációsrendszer szolgáltatás száma.

 

A programban használt EXOS hívások:

 

EXOS 1 - Csatorna megnyitás. Az "A" regiszterben a megnyitni kívánt csatorna száma, a "DE" regiszterpárban a nevének címe van. DE egy karaktersorozatra mutat, amelynek első byte-ja egy hosszúságbyte, ami megadja az utána következő karakterek számát. Ez a módszer általánosan használt az EXOS-ban, tehát jó vele tisztában lenni. Ez a név tartalmazhatja az eszköz nevét és a file-nevet egyaránt. Ha hiányzik az eszköznév, akkor kazettás rendszerben a "TAPE:" eszköz lesz behelyettesítve (ez a magnóillesztő). File alapú eszközök esetén ez a hívás olvasásra nyitja meg a csatornát.

EXOS 2 - Csatorna létrehozás. Hasonló, mint az előző hívás, de file alapú eszközök esetén írásra nyitja meg a csatornát. A programban ezt a hívást használjuk a betöltött SPECTRUM file-ok ENTERPRISE formában történő kimentésére.

EXOS 3 - Csatorna lezárása. Az "A" regiszterben van a csatornaszám.

EXOS 5 - Karakter olvasása. Az "A" regiszterben van a csatornaszám, visszatéréskor a "B" regiszter tartalmazza a beolvasott byte-ot.

EXOS 8 - Blokk írása. Ez nem egy byte-ot ír a csatornába, hanem egy byte-halmazt. A csatornaszám megadása hasonló az eddigiekhez. A DE regiszterpár tartalmazza azt a memóriacímet, ahol a kiírni kívánt adatok vannak, BC pedig ezen adatok számát tartalmazza.

EXOS 11 - Speciális funkció. Bizonyos feladatokat nem - vagy csak nagyon nehézkesen - lehet megoldani a csatorna írás-olvasás műveletekkel. Ilyen műveletek lebonyolítására szolgál ez a funkcióhívás. Programunk az 1. számú speciális funkciót használja egy video-lap képernyőn való megjelenítésére. A hívás paraméterei:

 

    A     a csatornaszám

    B=1   Az 1. funkció kijelölése

    C=1   A videolapon az 1.sortól kezdve legyen megjelenítés

    D=20  20 sort kell kijelezni

    E=1   A képernyőn az 1. sorban kezdődjön a videolap

 

EXOS 16 - EXOS változó írása/olvasása/átbillentése. A program a video és a szövegszerkesztő paramétereinek beállítására használja. Paraméterei:

 

    B=1         A változót írni óhajtjuk

    C=v         C regiszterben az EXOS változó száma

    D=új érték. A hívás után ez lesz a változó új értéke.

 

EXOS 24 - Szegmens kijelölés. Memóriát célszerű az EXOS-tól kérni, mivel így biztosan nem kezd el más program is az általunk használni kívánt memóriában dolgozni. C regiszterben a kiutalt szegmens száma lesz. Programunk 3 db szegmenst foglal le, ez 48k, így minden SPECTRUM program belefér a tárba.

EXOS 26 - Rendszerbővítő letapogatás. DE egy karaktersorozatra mutat. A BASIC is ezt a funkciót használja, amikor a felhasználó beüt például egy :HELP parancsot. Ez a kettőspont utáni parancshívás esetünkben is működik.

EXOS 28 - Hibakód értelmezése. Ha valakinek nem mond eleget az A regiszterben visszakapott hibakód, az EXOS mint egy jó tündér, a segítségére siet. A hívás előtt meg kell adni DE-ben egy olyan címet - ami lehetőleg másra nem használt -, ahová a rendszer nyugodt lélekkel felírhatja (a gyengébbek kedvéért) a hibakód magyarázó szövegét.

 

Az operációs rendszer nagy vívmánya a szövegszerkesztő (EDITOR:). Nagysága abban áll, hogy ha valaki valamilyen szöveget akar a felhasználótól kicsikarni, nem kell új adatbekérő programot írnia. Ilyen esetekben elég, ha nyit egy csatornát "EDITOR:" néven, és máris javában olvashat a felhasználótól. Csatornamegnyitás előtt be kell állítani néhány paramétert (EXOS változót). Ezek:

29 (VID EDIT) Itt kell megadni, hogy a szerkesztés során a szerkesztő melyik video-lapot használja.

30 (KEY EDIT) Hasonlóan a használt billentyűzetcsatornát kell megadni.

31 (BUF EDIT) A pufferméret 256 byte-os alapegységben. Tehát a pufferméret az itt megadott szám*256 byte lesz. Ez határozza meg, hogy hány karakter fér bele a szövegszerkesztőbe.

32 (FLG EDIT) A kiolvasás módját adja meg. A programban ez hasonló a BASIC sorbeolvasásához.

 

Ennyi kitérő után lássuk, mit is tud a program:

 

Indítás után megkérdezi az átvitel módját, folyamatos, vagy nem folyamatos. Folyamatos mód esetén betölt egy SPECTRUM file-t, majd ezt kimenti, és ezt addig csinálja, amíg le nem lövik. A nem folyamatos mód abban tér el, hogy minden kimentés előtt vár egy billentyűleütésre, így ilyenkor lehet kazettát cserélni. A program bekér egy nevet, mögé tesz egy kiterjesztést formában, ahol y és xx szimbólikus jelölés. "y" helyére egy 1 karakteres jelet tesz, ami az első file esetén 0, ezután 1,2 stb. "xx" a beolvasott blokk típusát adja hexadecimálisan. Innen lehet felismerni, hogy ez most fejléc volt avagy programblokk.

 

A program az "ASMON" nevű assemblerrel készült, ha valaki csak "HISOFT GEN ASSEMBELER"-rel rendelkezik, ne csüggedjen, hanem az első sorok elé írja be a következőket:

 

        EXOS      MACRO@1

                  RST 30H

                  DEFB @1

                  ENDM

 

Az EXOS a sor elején kezdődjön, a többi sor egy (vagy több) karakterrel beljebb. Ez érvényes az egész programban is. A szimbólumokat bevezető SPACE nélkül írjuk be, míg a többi sorban lévő utasítások elé legalább egy SPACE-t tegyünk. Ez a programlistából is előtűnik. A szimbólumok és a mögötte álló utasítások közé szintén legalább egy SPACE szükséges. A bevitel módja ASMON-ra: a program bejelentkezése után nyomjuk meg az "E" billentyűt. Ekkor bekerülünk egy szövegszerkesztőbe. Itt írjuk be programunkat, majd nyomjuk meg az "F8" funkcióbillentyűt. Ekkor visszakerülünk a monitorba. Itt a "Z" billentyű lenyomásával beállíthatjuk az assembler opciókat. Addig nyomjuk az ENTER-t, amíg el nem jutunk az "Object file name:" kérdéshez. Ekkor írjuk be a program nevét (mindenkinek az ízlésére van bízva a névválasztás). Ezután újra ENTER, ekkor az "EXOS module header NO" üzenet látható. Nyomjunk meg egy fekete billentyűt (tehát nem a STOP-ot!!!), ekkor változik a kép, most már az "EXOS module header YES" szöveg olvasható. Adjunk ENTER-t. Most azt olvashatjuk, hogy "EXOS module type 0". Üssük be az "5" számot, majd újra az ENTER-t. Visszatértünk a "Command>" módba. Már csak egy teendőnk van, lefordítani a forrásszöveget. Ezt az "A" billentyű leütésével eszközölhetjük. Előtte ne felejtsük el felvételre állítani a magnót. Ha lemezegységünk van, akkor készüljünk fel arra, hogy a lemezen létrejön a programunk olyan néven, amit megadtunk neki. Ha az assembler valamilyen hibaüzenettel leáll, akkor nézzük meg, mit rontottunk el. A forrásszöveget is kimenthetjük a "W" paranccsal. Ekkor meg kell adnunk a file nevét, majd ENTER-t kell nyomni. A kimentett forrásszöveg a "K" paranccsal tölthető vissza. A GEN esetén be kell írni a forrásszöveget, majd "A,,R 5" és ENTER, ekkor lefordítja. Ha rendben ment a fordítás, akkor beírhatjuk: "O„név" és kimentődik a használható program.

 

Eme módfelett magasröptű program beírása után már akadálytalanul tudunk áthozni mindenféle programterméket. Ez így nagyon szép, de még ezzel sem tudunk működő SPECTRUM átiratokat gyártani, mert egyrészt még SPECTRUM képernyőnk sincsen, másrészt nem tudjuk betölteni sem. Ez a nemes feladatot megvalósító programocska lesz következő értekezésünk tárgya.

 

A forrásszöveg - A program

 

Miután már mindenki profi módon tud SPECTRUM programokat beolvasni, jogosan vetődik fel a tisztelt felhasználókban a kérdés, hogy az átmenekített adatokkal mit kezdjen. Egyszóval: hogyan tovább? A következő lépcsőfok az előző részben leírt módon emberközelibbé tett programok olyan környezetbe helyezése, ami minél inkább emlékeztet egy SPECTRUM-ra. A környezet legfontosabb eleme a képernyő. Enélkül a programok nagy része meglehetősen egysíkúvá válik. Első és egyben legmagasztosabb feladatunk elkövetni egy olyan képernyő formációt, ami kísértetiesen hasonlít a SPECTRUM-ra. Ez meglehetősen nehéz feladat, mivel a SINCLAIR gép eléggé Istentől elrugaszkodott módon végzi a kép kirakását. Vegyük sorra a jellegzetességeket:

 

Attributum üzemmód. Ez magyarra fordítva annyit jelent, hogy a megjelenített kép két helyről épül fel. Az egyik hely az un. bittérkép. Ez a képernyőn látható információ kétszínű levonata. Mivel - mint köztudomású - a SPECTRUM színes számítógép, így kell egy másik adatmező is, ami a színinformációkat hordozza. Ezt a memóriaterületet hívják attribútummemóriának. Esetünkben nyolc egymás alatt elhelyezkedő bittérkép byte-hoz tartozik egy attribútum-byte. Ebből következően nyolcszor annyi bittérkep byte van, mint attribútum-byte. Az attribútum-byte megadja, hogy a bittérkép byte-okban lévő 0 és 1 értékű bitek milyen színt képviseljenek. A 0 értékű bitek színét szokás papírszínnek (PAPER), az 1 értékű bitek színét pedig tintaszínnek (INK) nevezni. Az ENTERPRISE szerencsére ismeri ezt a színüzemmódot.

A sorok elhelyezkedése. Nos, itt kezdődnek a problémák! Míg az ENTERPRISE esetében az első sor a 0-31 tartományban, a második a 32-63 tartományban van, addig a SPECTRUM egy sajátságos logika szerint kezeli a sorokat. Itt a képernyő fel van bontva látszólagos karakterekre, egy ilyen karaktersor függőlegesen 8 pixelsorból áll, a karaktersoron belül a sorok között 256 byte különbség van. Ez így szép és jó lenne, ha csak egy ilyen karaktersorból állna a képernyő (8 pixelsorból). A valóságban 192 pixel a függőleges felbontás, azaz 24 ilyen ál karaktersor van a képernyőn. Ez azért jó, mert osztható nyolccal, ily módon lehetőség volt a képernyőt harmadokra osztani. Egy harmadon belül az egyes karaktersorok első pixelsorai között pontosan 32 byte a különbség.

Ha ez így nem volt egészen világos - amit meg lehet érteni - tanulmányozzuk át ezt a kis táblázatot:

 

0.sor     0    8.sor     32

1.sor   256    9.sor    288

2.sor   512    10.sor   544

3.sor   768    11.sor   800

4.sor  1024    12.sor  1056

5.sor  1280    13.sor  1312

6.sor  1536    14.sor  1568

7.sor  1792    15.sor  1824

 

Ez két karaktersorra lebontva tartalmazza a pixelsorok relatív címeit.

A VIDEO memória címe. Az előzőekben bemutatott bittérkép a 16384-es (4000H), az attribútummemória a 22528 (5800H) címen helyezkedik el. A bittérkép hossza 6144, az attribútummemória hossza pedig 768 byte.

A papír- és a tintaszín byte-on belüli megoszlása:

        b5-b3 papírszín

        b2-b0 tintaszín.

        A b6 bit az un. BRIGHT,

        a b7 bit pedig a FLASH bit.

Ha a BRIGHT bit be van állítva, a megjelenő színek nem a normál színek lesznek, hanem valamivel fényesebbek. Ha a FLASH bit van beállítva, akkor a tinta és a papírszín ciklikusan váltakozik (villog).

 

Ennyi bevezető után térjünk rá programunk muködésére:

Először szerez egy kis memóriát, majd emulálja a SPECTRUM video üzemmódját. Ezt 192 db LPB segítségével teszi (az LPT felépítéséről már volt szó e hasábokon). Ezután betölt két file-t. Az ADDR1, BYTE1 ill. ADDR2, BYTE2 címkéket a betöltendő programtól függően kell értékkel feltölteni.

ADDR1 az első blokk, ADDR2 a második blokk betöltési címe. BYTE1 az első blokk, BYTE2 a második blokk hossza. A betöltött program indítási címe a USR szimbólumban kell hogy legyen tárolva.

Ha ezzel a betöltővel felfegyverkezve a vállalkozóbb szellemű Olvasó betölt egy játékprogramot, a betöltési képet meglátva valószínűleg elátkozza eme sorok íróját. Annak, hogy a tapasztalt szépséghibának mi az oka, hogyan lehet kiküszöbölni, a következő részben olvashatják a téma iránt érdeklődők!

 

A forrásszöveg

 

Az eddigiek során elfutottunk odáig, hogy fel tudunk építeni a SPECTRUM képernyőjéhez nagymértékben hasonlító SCREEN-t. Hogy ez miért csak hasonlító, és miért nem azonos, annak több oka van. Az előzőekben már volt szó az attribútum üzemmódról. Az attribútum memória az 5800H-5AFFH címtartományban helyezkedik el. Eme tartománynak a programátírások során igen nagy szerepe van, ezért érdemes jól megjegyezni. Vizsgáljunk meg egy attribútumbyte-ot! Kezdjük a legmagasabb helyiértékkel, a 7. bittel (b7)! Ha ez a bit be van állítva (értéke 1), akkor a papír és a tinta szín rövid időközönként invertálódik (magyarán: az adott karakter villog). Na ez az, amit az ENTERPRISE nem tud. Ha egyszer a sors szeszélye folytán olyan program kerül kezeink köze, amelyben létfontosságú a FLASH, akkor készüljünk fel a legrosszabbra. Nem lehetetlen ezt is szimulálni, de ez általában a programfutás sebességének rovására megy.) Tovább haladva, nézzük a 6. bitet (b6)! Ez a bit az un. BRIGHT (fényesség) bit. Ha ennek értéke 0, akkor a normál színek, míg a bit beállítása esetén a fényes színek jelennek meg. Az esetek túlnyomó többségében ez a bit okozza a galibát. A következő bitcsoport (b5,b4,b3) a papír színét (a nullás bitek a bittérképben), míg a legalsó 3 bit (b2,b1,b0) a tintaszínt (az egyes bitek a bittérképben) adja meg. Mivel ez 3 bit, így 8 szín kijelölésére van lehetőség. Ehhez jön még a BRIGHT bit, így kis jóindulattal azt mondhatjuk, hogy 16 szín között válogathat a felhasználó. A színképzést egyszerűen oldották meg: a három alapszínhez (vörös, zöld, kék) hozzárendeltek egy-egy bitet. A hozzárendelés: b0=kék: b1 =vörös, b2=zöld. (Ez így természetesen csak a tintaszínre igaz, papírszín esetén b0 helyett b3, b1 helyett b4 és b2 helyett b5 értendő.) Miután tisztáztuk a SPECTRUM színképzését, most a másik oldal következik. Az ENTERPRISE attribútum üzemmódja lényegesen egyszerűbb, nincsenek benne helyi specialitások (FLASH, BRIGHT). Az attribútumbyte két részre oszlik: alsó 4 bit és felső 4 bit. A felső 4 bit a papír, az alsó 4 bit a tinta színét jelöli ki (ahogy azt a logika diktálja). Látható tehát, hogy itt valóban 16 szín használatára van lehetőség. Ebből a 16 színből az alsó 8 (a 0xxx értékek) tetszőleges lehet. (A sorparaméter táblában, az LPB utolsó nyolc byte-ja éppen ezt a nyolc színt tartalmazza.) Előző mintaprogramunkban alkalmazott paletta jó közelítéssel megfelel a SPECTRUM normál színeinek. Amennyiben csak normál (nem fényes) színek fordulnak elő, akkor az egyedüli problémát az okozza, hogy a papír színek egy bittel alacsonyabban vannak, mint ahogy azt az ENTERPRISE megkívánná. Mielőtt bárki is fellelkesülne, sajnos le kell hűteni a kedélyeket. Már említettük a BRIGHT bitet. Nos, ha egy programban fényes színek is előfordulnak, akkor (mivel a b6 bit egyes állapotú) a fekete háttér helyett egy kellemes zöld alapszínt kapunk (no meg frászt, mivel semmit nem látunk a programból). Ilyen szempontból nagyon kellemes a fényes zöld tinta és a fekete papír kombinációja, ugyanis ennek értéke 44H. Ez azért jó, mert ez ENTERPRISE-on zöld papíron zöld tintát jelent, magyarán semmit. A megoldás bizonyára több olvasóban is felötlött: a fényes színeknek feleltessük meg a fennmaradó 8 színt (az 1xxx kombinációkat). Igen ám, de ez nem olyan egyszerű! Ezt a nyolc színt nem lehet csak úgy beállítani, használni kell a FIXBIAS regisztert. Ez a nevezetes regiszter a 128 (80h) port nagy részén terpeszkedik. Ez a port is bitenként értelmezett:

 

b7:     ha értéke 1, akkor a belső hangszóró néma.

b6,b5:  a külső színbemenetek prioritását szabályozza.

b4-b0:  FIXBIAS regiszter.

 

Mint látjuk ez a regiszter 5 bites. Tudni kell még azt is, hogy az ENTERPRISE a színeket 8 biten ábrázolja, így 256 színt képes használni. A felső nyolc szín (az 1xxx kombinációk) úgy képződik, hogy a FIXBIAS regiszter lesz a színbyte felső 5, míg a kiválasztott szín 3 bites érteke az alsó 3 bitje. A már említett programunk a FIXBIAS regiszterbe 0-t tölt. Az így előálló színkombinációk megfelelnek a SPECTRUM BRIGHT színeknek. A NICK-chip bit-szín hozzárendelése azonban különbözik a SPECTRUM-étól: b0-vörös. b1-zöld, b2-kék. Vagyis ami SPECTRUM-on kék, az ENTERPRISE-on vörös. A megoldás egyszerű: a biteket úgy kell megcserélni, hogy a színek azonosak legyenek. Ez annyit jelent, hogy a programban el kell mélyedni, a színkezeléseket felderíteni, majd a kívánt értékre módosítani. Általában a programátírásban ez a mozzanat tart a legtovább, ez igényli a legnagyobb gyakorlatot. Tehát összefoglalva: ahhoz, hogy egy SCREEN hasonló színekben pompázzon, mint az eredeti, a következő módosítások kellenek:

1. Ha az attribútumban a BRIGHT nincs beállítva, akkor a b3, b4, b5 biteket el kell mozdítani felfelé egy bittel, úgy, hogy az alsó 3 bit ne változzon.

2. Ha a BRIGHT bit be van állítva, akkor hasonló a procedúra, csak biteket is kell cserélgetni.

 

                          b7 b6 b5 b4 b3 b2 b1 b0

SPECTRUM attribútumbyte    0  1 s5 s4 s3 s2 s1 s0

ENTERPRISE attribútumbyte  1 s3 s5 s4  1 s0 s2 s1

 

E kis ábra után bizonyára mindenki tudna kreálni egy táblázatot, azonban, hogy az Olvasó idejét kíméljük íme az összes attribútumérték és a kiszámított ENTERPRISE megfelelő (forma: SPECTRUM-> Enterprise):

 

00=>00 01=>01 02=>02 03=>03 04=>04

05=>O5 06=>06 07=>07 08=>1O 09=>11

0A=>12 0B=>13 0C=>14 0D=>15 0E=>16

0F=>17 10=>20 11=>21 12=>22 13=>23

14=>24 15=>25 16=>26 17=>27 18=>30

19=>31 1A=>32 1B=>33 1C=>34 1D=>35

1E=>36 1F=>37 20=>40 21=>41 22=>42

23=>43 24=>44 25=>45 26=>46 27=>47

28=>50 29=>51 2A=>52 2B=>53 2C=>54

2D=>55 2E=>56 2F=>57 30=>60 31=>61

32=>62 33=>63 34=>64 35=>65 36=>66

37=>67 38=>70 39=>71 3A=>72 3B=>73

3C=>74 3D=>75 3E=>76 3F=>77 40=>88

41=>8C 42=>89 43=>8D 44=>8A 45=>8E

46=>8B 47=>8F 48=>C8 49=>CC 4A=>C9

4B=>CD 4C=>CA 4D=>CE 4E=>CB 4F=>CF

50=>98 51=>9C 52=>99 53=>9D 54=>9A

55=>9E 56=>9B 57=>9F 58=>D8 59=>DC

5A=>D9 5B=>DD 5C=>DA 5D=>DE 5E=>DB

5F=>DF 60=>A8 61=>AC 62=>A9 63=>AD

64=>AA 65=>AE 66=>AB 67=>AF 68=>E8

69=>EC 6A=>E9 6B=>ED 6C=>EA 6D=>EE

6E=>EB 6F=>EF 70=>B8 71=>BC 72=>B9

73=>BD 74=>BA 75=>BE 76=>BB 77=>BF

78=>F8 79=>FC 7A=>F9 7B=>FD 7C=>FA

7D=>FE 7E=>FB 7F=>FF               

 

Ennek segítségével már lehetséges a színek átalakítása, azonban hosszabb adatmezőket már nem érdemes kézzel konvertálni. Mivel a számítógép az ember barátja, illő, hogy dolgozzon is egy kicsit. Az alábbi kis programmal SPECTRUM SCREEN-eket lehet konvertálni:

 

A forrásszöveg

 

A program használata: írjuk be az ASMON szerkesztőjébe. Amennyiben nem akarjuk minden egyes alkalommal újragépelni, akkor mentsük ki a <W> billentyű segítségével. Ekkor a "File name:" kérdésre adjunk egy nevet (ezt az Olvasó fantáziájára bízzuk). Célszerű egy külön kazettát (vagy lemezt) fenntartani a segédprogramoknak. Ha már kimentettek, legközelebbi alkalommal a begépelés helyett töltsük be ASMON-ba a "K" parancs segítségével. Az ismételten megjelenő "File name:" kérdésre adjuk meg az általunk kreált fantázianevet. Betöltődés után állítsuk be az assembler opciókat ("Z' parancs) az alábbiakra:

 

Assembly listing OFF

List conditions NO

Force PASS 2 NO

Memory assembly YES

Memory offset 0

Object file name:

 

Ez utóbbi esetben egyszerűen adjunk <ENTER>-t a kérdésre. Ezután fordítsuk le ("A" parancs) a programot, majd töltsünk be egy SPECTRUM SCREEN-t. Ez a SPECTRUM-on a 4000H címre töltődik be ás 1B00H hosszú (6912). A betöltés az <R> (Read BIN file) billentyű leütésével kezdhető el. Ekkor megjelenik a "Start:" kérdés. Erre a 4000 begépelésével válaszoljunk, majd <ENTER>. Ezután a "End:" kérdésre 5AFF-el válaszoljunk, majd ismét <ENTER>. Most már csak a "File name:"-re kell megadnunk a SCREEN nevét, és elindul a betöltés. A töltés végén megjelenik az "End of file" hibaüzenet, alatta pedig (ha jó csináltunk mindent) a "Last address:5AFF" szöveg. Ekkor futtassuk a programunkat: "G". majd a "Start:" kérdésre válaszoljuk a kezdőcímet, vagyis a 3000-et, ismét <ENTER>. Ha jól fordítottunk, akkor rövidesen a "Returned from CALL at 3000" választ kapjuk. Ekkor a memóriában már ott a konvertált SCREEN, csak ki kell menteni. Nyomjuk le az <S> gombot (Save BIN file). A "Start"-ra adjuk meg a 4000-et, "Stop"-ra 5AFF-et,"File name:"-re egy nevet. Az így kimentett SCREEN-t visszatölthetjük az előző részben ismertetett LOADER-rel. Végezetül annyit, hogy a program nem csak SCREEN-ek konvertalására jó, de minden más esetben módosítani kell a kezdőcímet és a hosszt. Természetesen csak SPECTRUM formátumról már ENTERPRISE file-formátumra hozott SCREEN-ek konvertálhatók a leírt módszerrel.

Az eddigi számokban megpróbáltuk az alapokat tisztázni. Ezek megértése fontos a továbblépéshez. Az ASMON assembler-monitor program kezelését célszerű mihamarabb elsajátítani. Ezután a további fogásokat már egy konkrét példán keresztül fogjuk bemutatni. Az általunk választott program a "MOONCRESTA" nevet viseli, egy nemes mondanivalóval bíró űrhajós játékprogram. A választásnak több oka van:

 

1. A program 1984-ben készült, a programozástechnikája ember közeli, ami az újabb, "hiperszonikus" programokról már nem mondható el.

2. Terjedelme 20 kbyte alatt van, ami főleg a kazettás rendszerben dolgozók számára előnyösebb.

3. Bizonyos mértékben hasonlít az állatorvosi lóra, mivel a programátírás fő buktatói benne vannak.

4. Mivel régi program, így régi, rutinos SPECTRUM-osok való színűleg birtokolják.

 

Első lépésként próbáljuk kilistázni a BASIC részt (ha van rá lehetőségünk). Itt kezdődnek a problémák: a programot nem tudjuk leállítani. Ha valaki SPECTRUM-on próbálkozik, akkor szakirodalomban utána tud nézni az ilyen piszkos trükkök elleni védekezésnek. Mi ENTERPRISE-on, egy software SPECTRUM-emulátorral próbálkoztunk, ezeknek megvan az a jó tulajdonságuk, hogy le lehet BREAK-elni a programot közvetlenül betöltés után. Ha ez sikerült, még mindig nem érünk vele semmit, mert programlista helyett egy "O.K. boy" feliratot, és egy telefonszámot látunk. Megsúgjuk, hogy a sorszám nullára van állítva, ezért nem lehet vele mit kezdeni. Ezt a huncutságot egy POKE 23755,0:POKE 23756,1 parancssorral kivédhetjük. Ekkor az első sor száma 1 lesz. Ezt nyugodtan törölhetjük, mivel csak az üzenetet tartalmazza. Ha ezt megcsináltuk, akkor ismét nem tudunk mit kezdeni a programunkkal, mivel a védelem készítője a második sor sorszámát is kinullázta. Ezen a naivságon már csak gúnyosan mosolygunk, és megismételjük az előbbi POKE-okat. Most már van egy 1. sorszámú sorunk. Ezt a sort immáron önfeledten javíthatjuk. A sor elejéről a nem oda való grafikus karaktereket törölve előtűnik teljes pompájában a BASIC loader.

 

 1 CLS: PRINT AT 10,10; FLASH 1;

"loading"; FLASH 0;AT 12,9;"plea

se wait ;TAB 7;"cracked by zec":

POKE PEEK 23633+256*PEEK 23634,P

EEK 23647:POKE (PEEK 23633+256*P

EEK 23634)+1,PE K 23648          

 

Ebből megtudjuk azt a fontos információt, hogy egy "zec" nevű úriember törte fel az eredeti védelmet. Megnyugodhatunk tehát, a tolvajtól lopni nem bún. Ha ezt a sort is töröljük, akkor még mindig marad egy sor, amivel viszont már nem tudunk elbánni. Nem hát, mivel ez a gépi kódú loader, amit a BASIC igen rafináltan elindít. Disassemblálva a gépi kódú loader-t, a következű lista tárul ámuló szemünk elé:

 

LD    SP,5BFFH  

LD    A,0FFH    

SCF             

LD    IX,0B3B0H

LD    DE,0100H  

CALL  0556H     

JP    0B3B0H    

 

Egy ROM-listát előszedve tapasztalhatjuk, hogy ez nem csinál egyebet, mint beolvas egy fejléc nélküli programot a 0B3B0H címre, és ráugrik. Csavaros eszű Olvasóink bizonyára sejtik, hogy ez ismét egy loader lesz. A loader és az ezután következő viszontagságok ismertetésére legközelebb kerítünk alkalmat.

 

Elszántabb olvasóink okulva az előző részben leírtakból, már bizonyára betekintést nyertek a nevezetes 256 byte hosszú LOADER lelkivilágába. Aki még - kellő önbizalom hiányában - visszariadt ettől a lépéstől, annak megvilágítjuk e probléma hát terét. Mielőtt belemélyednénk, szeretnénk néhány tanácsot adni:

• Az ASMON-ban a gépi kódú programok betöltésére az "R", kimentésére az "S" parancs szolgál. Mindkettő rákérdez a start és a végcímre, valamint a betöltendő file nevére. A SPECTRUM programok átírásánál gondot okoz, hogy SPECTRUM-on a RAM terület 4000H és FFFFH között helyezkedik el, míg az ASMON csak 0801H-tól 0BFFFH-ig tud file-okat betölteni. A probléma abból származik, hogy ilyen felállásban az abszolút címhivatkozások nem érvényesek, nehezebb megtalálni az egyes szubrutinokat. A címek megtalálásának könnyítése érdekében érdemes 4000H-val alacsonyabb címre tölteni a programot. Ebben az esetben pl. a "CALL 7800H" utasítás által hívott szubrutin kezdőcíme esetünkben nem 7800H lesz, hanem ennél 4000H-val kevesebb, vagyis 3800H. Természetesen nem ez az egyedüli és üdvözítő megoldás, viszont a későbbiekben ilyen módszerrel fogjuk ismertetni az átírás egyes fázisait.

• Az "R" parancs végrehajtása után a monitor ad egy "Last address:" üzenetet, valamint egy címet. Ezt a címet érdemes felírni, a kimentéskor ez a cím lesz a végcím.

• Ha kazettás rendszerben dolgozunk, a javított programrészleteket ne az előző változat helyére mentsük ki. Az így előálló többletkereséseket a több kazettás módszerrel védhetjük ki, nevezetesen: külön kazettán legyen a betöltő, a forrásszöveg, a SCREEN, a program. Ez annyi kényelmetlenséget okoz, hogy kipróbáláskor cserélgetni kell a kazettákat, de ez mégis a kisebb baj. Ha lemezes rendszerünk van, akkor mindig készítsünk biztonsági másolatot, mivel a floppy az az eszköz, ahol kevés munkával igen sok adatot lehet elrontani. Ez csak az egyik ok. Előfordulhat olyan is, hogy az általunk kijavított program nem azonosul a feladatával, és utána nem is tudjuk visszajavítani a javítást. Ekkor kell visszamenni az előző, kevésbé jó, de még üzemképes változathoz.

 

Ennyi kis kitérő után térjünk rá a lényegre:

 

Töltsük be az eredeti helyére a LOADER-t (ez az a kivétel ami a szabályt erősíti). Az eredeti hely esetünkben 0B3B0H, ez még a szabad memória területen belül van. A betöltött programot listázzuk ki ("L" parancs). Mivel tudjuk az indítási címét, érdemes itt próbálkozni (aki kőkemény egyéniség, természetesen próbálkozhat máshol is, de kijelentjük, hogy igazat szóltunk). Az indítási cím esetünkben adódik magától, mivel megegyezik a betöltési címmel. Ha elkezdjük listázni, akkor a következő látvány tárul ámuló szemeink elé:

 

B3B0 31 FF 5B    LD SP,5BFF    ;A verem beállítása

B3B3 3E FF LD    A,FF          ;Annak jelzése, hogy nem fejléc

                               ;következik

B3B5 37          SCF           ;A töltés jelzése (ha CY=0, akkor

                               ;VERIFY)

B3B6 DD 21 00 40 LD IX,4000    ;Blokk kezdocíme

83BA 11 00 1B    LD DE,1B00    ;Blokk hossza

B3BD CD El B3    CALL B3E1     ;LOAD

B3C0 3E FF       LD A,FF

83C2 37          SCF

B3C3 DD 21 C4 E8 LD IX,E8C4    ;A lényeget lásd fent!

B3C7 11 3C 17 LD DE,173C

B3CA CD El B3    CALL B3E1

B3CD 3E FF       LD A,FF

B3CF 37          SCF

B3D0 DD 21 76 77 LD IX,7776

B304 11 A4 38    LD DE,38A4

B307 CD El B3    CALL B3E1

B3DA 31 77 E6    LD SP,E677    ;A verem bállítása (ismét)

B3DD F3          DI            ;Megszakítás tiltása

B30E C3 E8 EA    JP EAE8       ;Indítás

B3E1 14          INC D         ;Ez itt a LOAD szubrutín

 

Mielőtt valaki a szavahihetőségünket kétségbe vonná, sietünk leszögezni, hogy a megjegyzések, valamint a logikai egységelv szétválasztása a mi merényletünk. Látható, hogy a LOADER 6 logikai egységből áll. Az első egy normál vagy mezei LD SP,5BFF utasítás. Ennek a verem állításán kívül semmi szerepe sincs. A második egység már érdekesebb. Mivel látjuk, hogy 4000H-re töltődik, ráadásul 1B00H a hossza, besorolhatjuk a SCREEN skatulyába. A konvertálására az előző epizódban leírt játékszabályok érvényesek.

A harmadik és a negyedik egység végzi a munka oroszlánrészét: ők töltik be a tulajdonképpeni programot, ráadásul két részletben. Az egyik E8C4H-ra 173CH, a másik 7776H-ra 38A4H mennyiségű byte-ot tölt.

Az ötödik egység végzi a program végleges elindítását, érdemes megfigyelni, hogy EAE8H-n indul a MOONCRESTA.

Végül a hatodik egység, a LOAD szubrutin, amely a kazettáról betölti az egyes file-okat. Tévedés ne essék, ez nem egy sorból áll, sőt ez a leghosszabb szubrutin a LOADER-ben, viszont nerr láttuk értelmét teljes egészében közölni.

Akit érdekel, az tanulmányozhatja, nincs benne semmi extravagáns.

 

Ha valaki ennyi balszerencse ás sok-sok viszály után már a hetedik menyországban érezné magát, azt ki kelt ábrándítani. A cracker nagy showman lehetett, mivel még egy kis meglepetést tartogat a tarsolyában.

Töltsük be a két modult! Az elsőt A8C4H-ra (ez már a 4000H-va alacsonyabb cím!), a másodikat 3776H-ra. Az első BFFFH-ic tart, a második 7018H-ig, erre a kimentésnél legyünk tekintettel! Listázzuk ki a programot az indítási címtől kezdve!

 

AAE8 3E 00       LD A,00

AAEA D3 FE       OUT (FE),A    ;A keret (BORDER) fekete

AAEC CD C4 E8    CALL E8C4     ;Ellenorzo byte a SCREEN-bol

AAEF 21 D6 E8    LD HL,E8DE    ;Összehasonlítja az E8D6H

AAF2 BE          CP (HL)       ;memóriarekesz tartalmával

AAF3 CA 01 EB    JP Z,EB01     ;Ha egyezik,

                               ;EB01H-ra (AB01H) ugrik

AAF6 21 48 EE    LD HL,EE48    ;Ha nem egyezik

                               ;(változtattunk a SCREEN-en)

AAF9 01 FF FF    LD BC,FFFF    ;öngyilkos lesz

AAFC 11 49 EE    LD DE,EE49

AAFF ED B0       LDIR

ABO1 21 11 EB    LD HL,EB11    ;Itt folytatja, ha helyes

                               ;a SCREEN

AB04 01 4A 00    LD BC,004A    ;EB11H-n 4AH mennyiségű byte-ot

                               ;XOR-ol

AB07 7A          LD A,D        ;az ellenőrző összeggel

ABO8 AE          XOR (HL)

AB09 77          LD (HL),A

ABOA 23          INC HL

ABOB OB          DEC BC

ABOC 78          LD A,B

ABOD B1          OR C

ABOE C2 07 EB    JP NZ,EBO7

AB11 03          INC BC        ;Látszólag értelmetlen rész,

                               ;ezt a területet

AB12 55          LD D,L        ;módosítja az előző rutin

A8C4 21 00 40    LD HL,4000    ;Az ellenőrző összeget

                               ;képző szubrutin

A8C7 01 00 1B    LD BC,1B00

A8CA AF          XOR A

A8CB AE          XOR (HL)

ABCC 57          LD D,A        ;D-ben az ellenőrző összeg

A8CD 23          INC HL

A8CE 0B          DEC BC

A8CF 78          LD A,B

A8D0 B1          OR C

A8D1 7A          LD A,D

A8D2 C2 CB E8    JP NZ,E8CB

A8D5 C9          RET

 

Ezek után láthatjuk, milyen gonosz volt az illető. Nézzük végig a programot. Az E8C4H-n található rutin előállít egy számot. Ezt kiszámolhatjuk az eredeti SCREEN-ből, de felesleges, elég megnézni az E8D6H címen levő byte-ot. Az első néhány sort mindjárt megspórolhatjuk. EB01H-n van az első lényeges rész, a XORolás. Mivel tudjuk az ellenőrző kódot (ha valaki nem tudná, 22H), cselesen írhatunk egy kis szubrutint, ami elvégzi helyettünk eme nemes cselekedetet.

Mazochisták persze kézzel is megpróbálhatják. Mivel az elején található programrészre nem lesz szükségünk, ide beírhatjuk alkotásunkat. Ehhez szálljunk ki a listázásból (STOP vagy az ESC billentyű), majd nyomjuk meg az "M"-et. A módosítás címének kérésére adjuk az AAE8-at. Az ENTER lenyomása után kiíródik egy memóriadump, amiben tudunk módosítani. Szép sorban, az ENTER lenyomása nélkül írjuk be a következő számokat:

 

21 11 AB 06 4A 7E EE 22 77 23 10 F9 C9

 

Majd szálljunk ki a módosításból (STOP vagy ESC). Ha kilistázzuk ezt a kis programocskát, a következőket láthatjuk:

 

AAES 21 11 AB    LD HL,AB11

AAEB 06 4A       LD B,4A

AAED 7E          LD A,(HL)

AAEE EE 22       XOR 22

AAFO 77          LD (HL),A

AAF1 23          INC HL

AAF2 10 F9       DJNZ AAED

AAF4 C9          RET

 

Futtassuk le ("G" parancs, majd AAE8, ENTER), majd ha rendesen megkaptuk a "Retumed from CALL at AAE8" üzenetet, listázzuk ki az AB11 H címet. Micsoda változás!!

 

AB11 21 77 77    LD HL,7777

AB14 01 A4 38    LD BC,38A4

AB17 CD 47 EB    CALL EB47

AB1A 21 00 EE    LD HL,EEOO

AB1D 01 00 12    LD BC,1200

AB20 CO 47 EB    CALL EB47

AB23 21 77 77    LD HL,7777

AB26 01 A4 38    LD BC,38A4

AB29 CD 51 EB    CALL EB51

AB2C 21 00 EE    LD HL,EEOO

AB2F 01 00 12    LD BC,1200

AB32 CD 51 EB    CALL EB51

AB35 21 10 A7    LD HL,A710    ;A karakterkészlet kezdőcíme

AB38 22 36 5C    LD (506),H1   ;a megfelelő változóba

AB3B 01 5E 2F    LD BC,2F5E

AB3E AF          XOR A

AB3F ED 42       SBC HL,BC

AB41 31 2F 75    LD SP,752F

AB44 C3 6F 00    JP 006F

 

Tanulságul álljon itt a program által használt két szubrutin is!

 

AB47 7E          LD A,(HL)

AB48 ED 67       RRD

AB4A 23          INC HL

AB48 OB          DEC BC

AB4C 78          LD A,B

AB4D B1          OR C

AB4E 20 F7       JR NZ,AB47

AB50 C9          RET

 

AB51 7A          LD A,D

AB52 AE          XOR (HL)

AB53 77          LD (HL),A

AB54 23          INC HL

AB55 OB          DEC BC

AB56 78          LD A,B

AB57 B1          OR C

AB58 20 F7       JR NZ,AB51

AB5A C9          RET

 

Látható, hogy a program többi része itt is el van rejtve. Ismét módosítani vagyunk kénytelenek.

A módszer hasonló az előző programocska beviteléhez, de itt az AB0F címet kell módosítanunk az alábbi byte-okra:

 

16 22 21 77 37 01 A4 38

CD 47 AB 21 00 AE 01 00

12 CD 47 AB 21 77 37 01

A4 38 CD 51 AB 21 00 AE

01 00 12 0 51 AB C9     

 

Ha ezt kilistázzuk, a következőket kell látnunk:

 

AB0F 16 22       LD D,22

AB11 21 77 37    LD HL,3777

AB14 01 A4 38    LD BC,38A4

AB17 CD 47 AB    CALL AB47

AB1A 21 00 AE    LD HL,AE00

AB1D 01 00 12    LD BC,1200

AB20 CD 47 AB    CALL AB47

AB23 21 77 37    LD HL,3777

AB26 01 A4 38    LD BC,38A4

AB29 CD 51 AB    CALL AB51

AB2C 21 00 AE    LD HL,AE00

AB2F 01 00 12    LD BC,1200

AB32 CD 51 AB    CALL AB51

AB35 C9 RET

 

Ha nem ezt látjuk, akkor vagy valami belerepült a szemünkbe, vagy elírtunk valamit (minden bizonnyal a Tisztelt Olvasó). Miután ezzel megvagyunk, futtassuk le ezt is ("G" AB0F, ENTER), és már meg is van a futtatható (átírható) programunk. Már csak egy akadály van hátra, nevezetesen az indítási cím. Aki azt hiszi, hogy ilyet már találtunk eleget, téved. Meg kell keresnünk a - sorrendben a harmadik - helyes belépési pontot. További tortúrák helyett ezt már a tudomására hozzuk azoknak a fanatikus programozóknak, akik idáig kitartottak (jutalom): 77B2H (illetve a 4000H eltolásos módszer esetében 37B2H). Hogy ez honnan származik? Ezt az Olvasóra bízzuk (csak annyit segítségül, hogy A710H-2F5EH az pontosan 77B2H, valamint a SPECTRUM ROM-ban a 6FH címen egy szál utasítás van, ez pediglen egy JP (HL) ).

 

Miután így sikerült lefegyvereznünk a védelmet, akár rá is térhetnénk a program tulajdonképpeni átírására. Sajnos azonban ez a kis ujjgyakorlás sok helyet elvett, így a lényeg legközelebbre marad. Addig is, senki ne feledje el kimenteni a verejtékes munkával feltört programrészeket. Míg mindenki szívszorongva várja következő próféciánkat, el lehet kezdeni az ismerkedést a programozók stílusával, meg lehet próbálkozni egy ENTERPRISE LOADER készítésével.

 

Végezetül érdemes összefoglalni az eddigi file-ok adatait.

 

SCREEN  4000H-ra kell tölteni, 1B00H hosszban.

CODE1   7776H-ra kell tölteni, 38A4H hosszban.

CODE2   E8C4H-ra kell tölteni, 173CH hosszban.

 

Ha mindent betöltöttünk, el kell ugrani a 77B2H címre.

 

Kellemes bogarászást!

 

 

Ha valaki vette a fáradságot és előállította a program két blokkját, valamint átalakította a közölt betöltőt, csodálkozva tapasztalta, hogy a program nem igazán rendeltetésszerűen működik. Általánosságban elmondhatjuk, hogy ha egy program "elszáll", akkor annak két oka van:

 

1. A SPECTRUM ROM-ban lévő szubrutint hív.

2. Megszakítást alkalmaz.

 

Esetünkben mindkét esetre látunk majd példát, most foglalkozzunk a fontosabbal, a felhasználói megszakítással. A megszakítás olyan alprogram, amely a főprogram futása közben egy előre meghatározott esemény bekövetkeztekor hajtódik végre. Ez az esendő esemény esetünkben esetlegesen esik meg (jó mi?) mégpedig minden 1/50-ed másodpercben. A megszakítás elfogadásakor a processzor elmenti az aktuális programszámlálót (a PC regisztert), majd reagál, az üzemmódtól függően más ás más módon.

A Z80-as mikroprocesszornak 3 féle megszakításkezelése van:

1. A nullás üzemmód. Ekkor a processzor a következő utasításbyte-ot nem az aktuális memóriacímről veszi, hanem a megszakítást generáló eszköz adja. A Z80 felhasználók ezt a módszert szinte nem is használják, az INTEL 8080 miroprocesszorral való kompatibilitás miatt építették be. Beállítása az "IM 0" Z80 utasítással történik.

2. Az egyes üzemmód. Ekkor végrehajtódik egy "RST 38H" utasítás, vagyis meghívja a 38H-n lévő szubrutint. A SPECTRUM BASIC ezt használja. (Valamint az ENTERPRISE EXOS is!) Beállítása egy IM 1" (ED 56) utasítással történik.

3. A kettes üzemmód. Ez a legcifrább, de a leghasznosabb is. A megszakítási alprogram címének megtalálásához meg kell néznünk egy speciális Z80 regisztert, az "Interrupt vector register" névre hallató "I" regisztert. Ebben az üzemmódban ugyanis megszakításkérés esetén a mikroprocesszor beolvas az adatvezetékekről egy byte-ot, a felső 8 bitnek megfelelteti az "I" regiszter 8 bitjét, majd az így létrehozott 16 bites címről kiolvas egy byte-ot, majd a 16 bites címet megnövelve még egyet. Az első byte lesz az alprogram címének alsó, a második pedig a felső byte-ja. Mire jó ez? Például arra, hogy ha több egység kérhet megszakítást, akkor nem a processzor kezdi el találgatni a megszakítani kívánó személyét, hanem a periféria azonosítja magát az adatbuszra küldött byte-al. A beállítása az "IM 2" (ED 5E) utasítással történik. Ezt az utasítást mindenki jól jegyezze meg, ugyanis a programok 80-90 százaléka ilyen üzemmódot állít be.

FONTOS! A megszakítást kiszolgáló alprogramnak nem szabad megváltoztatni EGYETLEN regiszter értéket sem, amelyet a főprogram használ! A megszakítás elfogadásakor tiltódik a további megszakítások elfogadása, ezt általában az interrupt alprogram végén szokták engedélyezni. Ez mind nagyon szép - mondhatja az Olvasó - de mi szükség van ennek ismeretére? Nagyon is van, mivel az ENTERPRISE bonyolultabb megszakítás elektronikával rendelkezik. Nem egy-, hanem mindjárt négyféle megszakítási forrás áll rendelkezésre, amelyek külön-külön tilthatok, engedélyezhetők. Erre egy külön perifériacím szolgál, melynek címe a 0B4H. Ez különbözik OUT és IN műveletek esetén. Minket csak az OUT érdekel, ezért csak ezt részletezzük.

 

A port bitenként értelmezett:

 

b0 A hanggenerátor által adott megszakítás engedélyezése. (1 érték által)

b1 A hanggenerátor megszakítás tároló törlése.

b2 Az 1 Hz-es megszakítás engedélyezése.

b3 Az 1 Hz-es megszakítás tároló törlése.

b4 A video-megszakítás engedélyezése.

b5 A video-megszakítás tároló törlése.

b6 A soros vonal megszakításának engedélyezése.

b7 A soros vonal megszakítás tárolójának törlése.

 

Az, hogy az engedélyezésnek mi a szerepe, elég egyértelmű, ha a megfelelő helyre egy egyes bitet írunk, akkor az a forrás képes megszakítást generálni. Ha nullát írunk, akkor letiltottuk az eszközt. Az 50 Hz-es megszakítás generálásához célszerű a NICKchip által generált megszakítást használni, amit az LPT generálásakor beállítottunk.

 

A másik feladat - a megszakítás tároló törlése - már nem ilyen egyértelmű. A DAVE-chip (amely a megszakításrendszert istápolja) tárolja az interrupt kéréseket. Amíg nem töröltük a tárolóját, addig elnyom minden ilyen irányú próbálkozást. Tehát: ha azt akarjuk, hogy az 1/50 másodpercenként érkező megszakítások ne vesszenek el (vagyis ne "fagyjon le" a program), minden megszakítást kiszolgáló alprogram végén (vagy elején) törölnünk kell a DAVE-chip megfelelő tárolóját. A video-megszakítás újraengedélyezését végző rutin az alábbi:

 

LD A,30H        ;b4 +b5, video IT. engedélyezés, tároló törlése

OUT (OB4H),A    ;A DAVE-chip megfelelo regisztere

 

Arra természetesen figyeljünk, hogy mentsük az "A" regiszter a művelet előtt.

 

Most nézzük meg, hogy a nagy fáradsággal átmentett "MOON CRESTA" hogyan csinálja. A program indítási címe 77B2H.

 

7782 F3          DI             ;Megszakítás tiltása.

77B3 31 43 F6    LD SP,F643     ;Verem állítás.

77B6 21 10 A7    LD HL,A710     ;Karakterkészlet helyének

7789 22 36 5C    LD (5C36),HL   ;tárolása az 5C36H címen.

77BC 21 05 40    LD HL,4005     ;A betöltőkép tárolása

77BF 11 1B 5C    LD DE,5C7B

77C2 01 FB 1A    LD BC,lAFB

77C5 ED B0       LDIR

77C7 21 00 F5    LD HL,F500     ;Interrupt cím beállítása.

77CA 11 01 F5    LD DE,F501

77CD 01 01 01    LD BC,0101

77D0 36 77       LD (HL),77     ;A megszakítási rutin 7777H-n.

77D2 ED B0       LDIR

77D4 3E F5       LD A,F5        ;A táblázat felső byte-ja (F5H)

77D6 ED 47       LD I,A         ;az "I" regiszterben.

77D8 ED 5E       IM 2           ;Kettes mód beállítás.

77DA FB          EI             ;Megszakítás engedélyezése.

 

Biztos mindenki megdöbbent a 257 elemű táblázaton. Erre azért van szükség, mivel a táblázat alsó byte-ja (amit a periféria ad) nem eléggé biztos. (Általában FFH) Ezzel a módszerrel minden kombinációra bebiztosították magukat a programozók. Az ilyen táblázatos módszerek leggonoszabbja az, amikor a táblazat csupa 255-bol áll, tehát a megszakítási rutin címe 65535 (FFFFH). Erre az egy byte-ra leraknak egy "JR" utasításnak megfelelő 18H-t, amelynek operandusa a 0 címen lévő (SPECTRUM BASIC) 0F3H. Ez a relatív ugrás visszaugrik a 0FFF4H címre, ahol egy ugró utasítás visz a tulajdonképpeni megszakítási alprogramra. A következő LOADER a kész játék végső betöltője, ezért érdemes beírni. A megszakítási problémát úgy küzdöttek le, hogy 7777H-ra (az IT rutin) letettünk egy "JP" utasítást, előbb engedélyezzük a DAVE-chipben az interruptot, majd ráugrunk a tulajdonképpeni rutinra.

 

A forrásszöveg

 

Mint látható, a program két blokkját nemes egyszerűséggel csak "ALSO" és "FELSO" névvel illettük, ezáltal is jelezve az elhelyezkedésüket. A betöltő elején található rutinok méltatására a későbbiekben visszatérünk. Ezzel a betöltővel futtatva a "MOON CRESTA"-t már hajlandó elindulni. (Igaz sok köszönet nincs benne!)

És most essék néhány szó a SPECTRUM billentyűzetfigyeléséről: Az összes gomb egy mátrixba van kötve. A mátrix sorát mi közöljük a géppel igen ravasz módon, az oszlopot pedig szerény kérésünkre válaszként kapjuk. A sor kiválasztását igen érdekesen oldották meg. Kihasználták a mikroprocesszor ama tulajdonságát, hogy IN/OUT műveletek esetén a címbusz felső 8 bitjén is értékes adat van. Vegyünk példának egy IN A,(0FEH) utasítást!

Ekkor a címbusz alsó 8 bitje a periféria címét (jelen esetben a 0FEH-t), míg a felső 8 bit az "A" regiszter beolvasás előtti értékét tartalmazza. A másik fajta "IN" utasításcsoport esetén (az IN r,(C) ) a "B" regiszter kerül hasonló helyzetbe.

A SPECTRUM a billentyűket egy 8*5 elemű mátrixban kezeli. A 8 sor eléggé sokatmondó, mivel pontosan ennyi bit van egy byteban. A 8 sornak tehát megfelel 8 bit, amelyik bit 0 értékű, azt a sort olvassa be a processzor. Mivel egy byte-on belül bármelyik bit lehet 0, ezért egy utasítással több sort is le lehet kérdezni. A kiválasztott sort a 254-es (0FEH) porton lehet beolvasni, az alsó 5 bit hordozza a billentyűzet információit. Konkrétan: az 1,2,3,4,5 gombok vizsgálata az alábbi kis programocskával történhet.

 

1.variáció            2.variáció

LD A,0F7H             LD BC,OF7FEH

IN A,(0FEH)           IN A,(C)

 

Működés szempontjából a két módozat egyenértékű, a 2. variáció azonban használja a "BC" regiszterpárt. A gyakorlatban mindkét variáció előfordul.

Ha billentyűfigyelést keresünk egy programban, akkor a következő utasításokra figyeljünk fokozottan:

 

Utasítás             HEXA kód

IN A,(OFEH)          DB FE

IN A,(C)             E0 78

IN B,(C)             ED 40

IN C,(C)             ED 48

IN D,(C)             ED 50

IN E,(C)             ED 58

1N H,(C)             ED 60

IN L,(C)             ED 68

 

Mielőtt bárki azt hinné, hogy az első két utasításon kívül mást nem használnak, az nem jár messze az igazságtól, viszont elrettentésül megjegyeznénk, hogy leltünk mar IN C,(C) utasítást is, amely az irányítás nemes feladatát volt hivatva betölteni. Gyakran előfordul a teljes klaviatura lekérdezése is. Ez SPECTRUM-on egyszerű, ENTERPRISE-on viszont már nem. (Ha valaki nem tudna, egy

              XOR A

              IN A,(0FEH)

nagyon megfelelő ilyen célokra.)

A téma lezárásaként itt van a sokat emlegetett mátrix.

 

A SPECTRUM billentyűzetmátrix:

 

BIN      DEC HEX       1      2      4      8     16

                      b0     b1     b2     b3     b4

11111110 254  FE    Caps      Z      X      C      V

11111101 253  FD       A      S      D      F      G

11111011 251  FB       Q      W      E      R      T

11110111 247  F7       1      2      3      4      5

11101111 239  EF       0      9      8      7      6

11011111 223  DF       P      0      I      U      Y

10111111 191  BF   Enter      L      K      J      H

01111111 127  7F   Space Symbol      M      N      B

 

Miután a SPECTRUM klaviatura-kérdést ilyen jól helybenhagytuk, rátérhetünk az ENTERPRISE oldalára. A mátrix módszer itt is alkalmazott, viszont - a több gomb miatt - némileg eltér a fent említettől. Először is, nem 8 sor van, hanem 10. Ez előrevetíti ama szomorú tény árnyékát, hogy nem fér egy byte-ban (vagyis csak a külön bites módszerrel nem). Másodszor: nem 5 oszlopot olvasunk be, hanem 8-at. Ezzel a módszerrel 80 gomb figyelésére van mód, ebből néhány nem használt. Azt, hogy melyik sort (0-tól 9-ig számozva) akarjuk olvasni, a 0B5H című porton kell közölnünk. Miután ezt közöltük, rendelkezésünkre áll ugyanezen a porton az adat. Előző példánknál maradva az 1-5 billentyűket az

          LD A,3

          OUT (0B5H),A

          IN A,(0B5H)

utasításokkal figyelhetjük. Látható, hogy az előbbi 4 byte-tal szemben most ugyanez 6 byte hosszan sikerült. Vagyis nem fér be az eredeti helyére. Itt három dolgot tehetünk:

1. Hagyjuk az egészet és elmegyünk dominózni.

2. A memória egy nem használt helyére megírjuk szubrutinként, majd az eredeti programrészt lecseréljük egy "CALL" utasításra.

3. Addig erőltetjük (jó VOGON szokás szerint) amíg nem sikerül begyurna az eredeti helyére.

Kétségkívül az első módszer a legegyszerűbb, viszont a harmadik a legszimpatikusabb, ennek ellenére mi a másodikat fogjuk bemutatni. Ennek okai: minek riasszuk el az Olvasót ilyen korai stádiumban? Végezetül íme, az ENTERPRISE billentyűzetmátrix:

 

        b7    b6    b5    b4    b3    b2    b1    b0

       128    64    32    16     8     4     2     1

Sor    80H   40H   20H   10H   08H   04H   02H   01H

 0   B.SH.     Z     X     V     C     B     \     N

 1    CTRL     A     S     F     D     G  LOCK     H

 2     TAB     W     E     T     R     Y     Q     U

 3     ESC     2     3     5     4     6     1     7

 4      F1    F2    F7    F5    F6    F3    F8    F4

 5         ERASE     ^     0     -     9           8

 6             ]     :     L     ;     K           J

 7     ALT ENTER   BAL  HOLD   FEL  JOBB    LE  STOP

 8     INS SPACE J.SH.     .     /     ,   DEL     M

 9                   [     P     @     0           I

 

Miután sikerült leimádkoznunk a védelmet a programról, valamint tisztáztunk néhány alapfogalmat, rátérhetünk munkánk érdemi részére.

Az előző részben már elindítottuk a "MOON CRESTA"-t, de egy kis DEMO-n kívül mást nem hajlandó csinálni. Az ok kézenfekvő: azért nem reagál a billentyűkre, mivel még a SPECTRUM módszerével figyeli azokat!

 

Tehát a feladat:

 

1. Felkutatni a vitás részeket és

2. módosítani ENTERPRISE formára.

 

Töltsük be a két a programfile-t, majd használjuk az ASMON keresés funkcióját. (A funkció aktivizálására szolgáló billentyűt legcélszerűbb a "H" (HELP) billentyű lenyomása után megjelenő menüből kinézni. Angol gépeken a hatványjel.)

Először próbálkozzunk a legkézenfekvőbbel, az IN A,(0FEH) utasítással. A keresés billentyűjének lenyomása után megjelenik egy "Start:" kérdés, majd utána egy szám. Első kereséskor ide írjuk be a kezdőcímet, további keresésekhez elegendő "ENTER"-t nyomni, ekkor folytatja a keresést.

Miután kijelöltük a kezdőcímet, a "Search:" kérdésre írjuk be az IN utasítás Z80 kódját. Aki olvasta az előző részt, már fejből tudja, aki nem olvasta, az szégyellje magát! De már-már közmondásos nagylelkűségünknek engedve eláruljuk, hogy 0DBH. Tehát a "Search:" kérdésre gépeljük be azt, hogy "DB FE". Az idézőjel természetesen nem kell, mivel ha kitesszük az idézőjeleket, akkor azt a karaktersorozatot fogja keresni.

Miután leütöttük az "ENTER"-t, kis gondolkozás után a "Found at:" üzenet ás egy memóriacím, alatta pedig három sorban memóriadump jelenik meg. Ha nem ez történne, akkor áldásos tevékenységünk mégsem volt annyira áldásos.

Most vegyük a kedvezőbb esetet, tételezzük fel, hogy sikeres volt az akciónk. Közbevetőleg egy jótanács! Keresésnél a kiírt címnél mindig néhány byte-tal alacsonyabb címtől kezdjük a listázást!

Nos, nézzük, mit találtunk.

 

3887 06 00       LD B,00

3889 AF          XOR A

388A DB FE       IN A,(FE)

388C E6 1F       AND 1F

388E FE 1F       CP 1F

3890 C2 E3 79    JP NZ,79E3

3893 76          HALT

3894 10 F3       DJNZ 3889

 

(A memóriacímek természetesen 4000H-val magasabban értendők!)

Mit is csinál ez a kis rutin?

A lényeg a

            XOR A

            IN A,(FE)

rész. A "XOR A" utasítás saját magával végez "kizáró VAGY" kapcsolatot. Ezt bitenként végzi, vagyis a 0.bitet a 0.bittel stb... A "XOR" művelet akkor ad "1" értéket, ha a két bit különböző. Mivel az "A" regiszter teljesen illogikus módon megegyezik saját magával, ezért a "XOR A" művelet eredménye mindig 0-t ad. Egyébként ez a módszer nagyon elterjedt a "LD A,0" (2 byte) utasítás helyett (mivel ez csak egy byte). Az "IN A,(FE)" utasításról volt már szó. Ha az "A" regiszterben nulla van, az az összes sort kijelöli, vagyis a teljes billentyűzetet leolvassa.

A következő, "AND 1F" utasítás csak a billentyűzetről származó adatokat tartja meg. Ezután megnézi, hogy volt-e lenyomott billentyű (CP 1F). Ha volt, akkor az "A" nem 1FH lesz, ekkor elugrik a 79E3H címre, ha nem volt lenyomott billentyű, akkor vár 1/50 másodpercet, majd újra leolvassa a klaviatúrát, és ez így megy 256-szor. (A "DJNZ" utasítást illik ismerni!)

Miután így a felderítést letudtuk, a következő feladat a probléma leküzdése.

Ez már kicsit bonyolultabb, de nem kell kétségbe esni! Az valószínűleg világos, hogy ide nem fér be az általunk elkészíteni szándékozott helyettesítő szubrutin. Az előző számban közöltünk egy LOADER-t a programhoz. Annak az elején volt néhány szubrutin, amit nem részleteztünk kellőképpen (mondhatni sehogyan). Örömmel közöljük, hogy ez a felemelő pillanat most érkezett el! (Legalábbis részben.)

A betöltő így kezdődik:

 

        ORG 256

        JP CONT       ;100H

        JP KEY        ;103H

        JP ALLKEY     ;106H

        JP JOY        ;109H

        JP BEEP       ;10CH

 

A megjegyzés rovatban az egyes JP utasítások címei lettek feltüntetve hexadecimálisan. Az ilyen JP utasításokból álló programrészt hívják ugrótáblázatnak. Kicsit nagyképűen mi is ilyen névvel fogjuk illetni. Mint látható, mindegyik egy-egy rutinra ugrik. Teljesen jogos a kérdés, hogy mi szükség van erre, amikor a rutinokat direkten is lehetne hívni? Ez teljesen igaz, viszont, ha egy rutint megváltoztatunk (például beszúrunk egy byte-ot), az összes többi is megváltozik. Ekkor az összes hivatkozást meg kellene változtatni, ami esetünkben pI., az "ALLKEY" nevű szubrutin esetén eléggé munkaigényes (és felesleges). Az ugrótáblázat alkalmazásával ez a probléma elveszti jelentőségét, mivel itt csak az egyes JP-okat kell módosítani.

Természetesen, ha valaki úgy írja meg a kellő részeket, hogy azokat később nem kell módosítani, akkor nincs szükség az itt leírtakra. Azonban - minden ellenkező híreszteléssel ellentétben - senki sem tökéletes, mindenki követhet el hibákat (sőt, csak azt!), így szerény véleményünk szerint az általunk eloadott módszer a legkevésbé fáradságos!

Az imént már emlegettük az "ALLKEY" szubrutint, a szemfülesebbek biztosan kitalálták, hogy nem véletlenül! Mint neve is sejtetni engedi, ez a teljes billentyűzetet lekérdező rutin. vizsgáljuk meg a működését!

 

ALLKEY  PUSH BC        ;A BC regiszterpár elmentése

        LD BC,0AFFH    ;B=0AH, C=0FFH

                       ;B: 10 sor van a billentyűzeten

                       ;C: minden oszlop inaktív

                       ;(kezdetben)

A1      LD A,B         ;A=sor

        DEC A          ;A=A-1, mivel nem 10-től l-ig,

                       ;hanem 9-tol 0-ig van a

                       ;billentyűzet sorszámozása

        OUT (0B5H),A   ;A sorszám kiküldése a megfelelő

                       ;portra

        IN A,(0B5H)    ;Az oszlop érték visszaolvasása

                       ;0FFH, ha nincs lenyomva gomb

        AND C

        LD C,A         ;Ha valamelyik sorban volt lenyomva

                       ;billentyű, akkor a "C" regiszter

                       ;nem lehet 0FFH

        DJNZ A1        ;Mind a 10 sor leolvasása

                       ;Az "A" regiszterben is

                       ;megtalálható a végérték

        POP BC         ;A "BC" regiszterpár

                       ;visszatöltése

        RET            ;Visszatérés

 

Ezzel a kis programmal szimuláljuk a teljes billentyűzetleolvasást, egy "CALL 106H' utasítással hívhatjuk. Látható, hogy ez is három byte a

                    XOR A

                    IN A,(FE)

-hez hasonlóan, tehát gond nélkül elhelyezhető elődje helyén.

A "CALL 106H" utasítás gépi kódja: CD 06 01 (hexában), tehát az elozo programrészt módosítsuk a következőre:

 

3887 06 00       LD B,00

3889 CD 06 01    CALL 0106

388C E6 FF       AND FF

388E FE FF       CP FF

3890 C2 E3 79    JP NZ,79E3

3893 76          HALT

3894 10 F3       DJNZ 3889

 

Talán feltűnt, hogy az "AND 1F" utasítást "AND FF"-re és a "CP 1F"-et "CP FF"-re cseréltük, ez a teljes billentyűzet figyelése miatt szükséges.

Miután ily módon átestünk a tűzkeresztségen, folytathatjuk a keresést.

 

3967 06 14       LD B,14

3969 AF          XOR A

396A DB FE       IN A,(FE)

396C E6 1F       AND 1F

396E FE 1F       CP 1F

3970 C2 E3 79    JP NZ,79E3

3973 76          HALT

3974 10 F3       DJNZ 3969

3994 06 1E       LD B,1E

3996 AF          XOR A

3997 DB FE       IN A,(FE)

3999 E6 1F       AND 1F

399B FE 1F       CP 1F

399D C2 E3 79    JP NZ,79E3

39A0 76          HALT

39A1 10 F3       DJNZ 3996

39BF 06 64       LD B,64

39C1 AF          XOR A

39C2 DB FE       IN A,(FE)

39C4 E6 1F       AND 1F

39C6 FE 1F       CP 1F

39C8 C2 E3 79    JP NZ,79E3

39CB 76          HALT

39CC 10 F3       DJNZ 39C1

39D4 06 00       LD B,00

39D6 76          HALT

39D7 AF          XOR A

39D8 DB FE       IN A,(FE)

39DA E6 1F       AND 1F

39DC FE 1F       CP 1F

39DE C2 E3 79    JP NZ,79E3

39E1 10 F3       DJNZ 39D6

 

Ezek mind egy kaptafára készültek, kár is rájuk több szót vesztegetni, az eddigiek alapján csak rutinmunka az átírásuk.

A most következő viszont annál érdekesebb!

 

3C10 AF          XOR A

3C11 DB FE       IN A,(FE)

3C13 E6 1F       AND 1F

3C15 FE 1F       CP 1F

3C17 C2 10 7C    JP NZ,7C10

 

Ez, ugyebár ismerős?

 

3C1A 06 00       LD B,00

3C1C 3E EF       LD A,EF

3C1E DB FE       IN A,(FE)

3C20 CB 67       BIT 4,A

3C22 CA 31 81    JP Z,8131

 

Akik rendelkeznek az előző számban szereplő, nagy kaliberű SPECTRUM billentyű-táblázattal, már tudhatják, hogy ez a "6" billentyűt figyeli.

 

3C25 3E F7       LD A,F7

3C27 DB FE       IN A,(FE)

 

Az "A" regiszterben az "12345" billentyűknek megfelelő sor.

 

3C29 CB 47       BIT 0,A

3C2B C2 36 7C    JP NZ,7C36

3C2E 3E 01       LD A,01

3C30 32 C2 87    LD (87C2),A

3C33 C3 5E 7B    JP 7B5E

 

Az "1" billentyű esetén a 87C2H memóriacímre betölt 01H-t, majd ráugrik a 7B5EH címre.

 

3C36 CB 4F       BIT 1,A

3C38 C2 43 7C    JP NZ,7C43

3C3B 3E 02       LD A,02

3C3D 32 C2 87    LD (87C2),A

3C40 C3 5E 7B    JP 7B5E

 

A "2" billentyű hasonlóképpen.

 

3C43 CB 57       BIT 2,A

3C45 C2 4E 7C    JP NZ,7C4E

3C48 32 5E F3    LD (F35E),A

3C4B C3 5E 7B    JP 7B5E

 

A "3" billentyű.

 

3C4E CB 5F       BIT 3,A

3C50 C2 5A 7C    JP NZ,7C5A

3C53 AF          XOR A

3C54 32 5E F3    LD (F35E),A

3C57 C3 5E 7B    JP 7B5E

 

A "4" billentyű.

 

3C5A CB 67       BIT 4,A

3C5C CA DB 7C    JP Z,7CDB

 

"5" esetén folytatja a 7CDBH címen, egyébként várakozik, majd újraolvassa a billentyűzetet 256-szor.

 

3C5F 76          HALT

3C60 10 BA       DJNZ 3C1C

3C62 C3 52 78    JP 7852

 

7852H-n folytatja, ha több mint 5 másodpercig nem nyomjuk meg az 1-6 billentyűk közül valamelyiket.

Talán kitalálták már, hogy ez itt a menü volt.

Most mit tegyünk?

Az látható, hogy itt sem fér be a módosított rutin az eredeti helyére, viszont van a mi kis betöltőnkben egy "KEY" nevű szubrutin (103H a belépési pontja). Eléggé furcsán néz ki:

 

KEY     EX (SP),HL     ;HL és a STACK-ban lévő 16 bites

                       ;adat kicserélése

                       ;Ekkor (ha CALL-al hívjuk meg) a

                       ;visszatérési cím található itt

        LD A,(HL)      ;A visszatérési címen található

                       ;byte betöltése "A"-ba

        INC HL         ;A visszatérési cím növelése eggyel.

        EX (SP),HL     ;HL visszatöltése

        OUT (0B5H),A

        IN A,(0B5H)

        RET

 

A szubrutin hívása némi hasonlóságot mutat az EXOS hívásával:

 

        CALL 103H

        DEFB SOR

 

Például, ha a számok sorát akarjuk beolvasni, adjuk ki a

        CALL 103H

        DEFB 3

utasításokat.

Előző programrészletünk módosítva:

 

3C10 CD 06 01    CALL 0106

3C13 E6 FF       AND FF

3C15 FE FF       CP FF

3C17 C2 10 7C    JP NZ,7C10

3C1A 06 00       LD B,00

3C1C CD 03 01    CALL 0103

3C1F 03          INC BC          ;ADAT

3C20 CB 57       BIT 2,A         ;Megváltozik a ;bitkiosztás

3C22 CA 31 81    JP Z,8131

3C25 CD 03 01    CALL 0103

3C28 03          INC BC          ;ADAT

3C29 CB 4F       BIT 1,A         ;Az "1" billentyű

3C2B C2 36 7C    JP NZ,7C36

3C2E 3E 01       LD A,01

3C30 32 C2 87    LD (87C2),A

3C33 C3 5E 7B    JP 7B5E

3C36 CB 77       BIT 6,A          ;A "2" billentyű

3C38 C2 43 7C    JP NZ,7C43

3C3B 3E 02       LD A,02

3C3D 32 C2 87    LD (87C2),A

3C40 C3 SE 7B    JP 7B5E

3C43 CB 6F       BIT 5,A          ;A "3" billentyű

3C45 C2 4E 7C    JP NZ,7C4E

3C48 32 5E F3    LD (F35E),A

3C4B C3 5E 7B    JP 7B5E

3C4E CB 5F       BIT 3,A          ;A "4" billentyű

3C50 C2 5A 7C    JP NZ,7C5A

3C53 AF          XOR A

3C54 32 5E F3    LD (F35E),A

3C57 C3 5E 7B    JP 7B5E

3C5A CB 67       BIT 4,A          ;Az "5" billentyű

3C5C CA DB 7C    JP Z,7CDB

3C5F 76          HALT

3C60 10 BA       DJNZ 3C1C

3C62 C3 52 78    JP 7852

 

Ha ezzel is megvagyunk, folytathatjuk önfeledt módosítgatásainkat:

 

3D15 06 19       LD B,19

3D17 76          HALT

3D18 AF          XOR A

3D19 DB FE       IN A,(FE)

3D1B E6 1F       AND 1F

3D1D FE 1F       CP 1F

3D1F C2 27 7D    JP NZ,7D27

3D22 10 F3       DJNZ 3D17

3D24 C3 FE 7C    JP 7CFE

3DA2 06 19       LD B,19

3DA4 76          HALT

3DA5 AF          XOR A

3DA6 DB FE       IN A,(FE)

3DA8 E6 1F       AND 1F

3DAA FE 1F       CP 1F

3DAC C2 B4 7D    JP NZ,7DB4

3DAF 10 F3       DJNZ 3DA4

3DB1 C3 8A 7D    JP 7D8A

3E2F 06 19 LD    B,19

3E31 76          HALT

3E32 AF          XOR A

3E33 DB FE       IN A,(FE)

3E35 E6 1F       AND 1F

3E37 FE 1F       CP 1F

3E39 C2 41 7E    JP NZ,7E41

3E3C 10 F3       DJNZ 3E31

3E3E C3 18 7E    JP 7E18

3EBB 06 19 LD    B,19

3EBD 76          HALT

3EBE AF          XOR A

3EBF DB FE       IN A,(FE)

3EC1 E6 1F       AND 1F

3EC3 FE 1F       CP 1F

3EC5 C2 CD 7E    JP NZ,7ECD

3EC8 10 F3       DJNZ 3EBD

3ECA C3 A4 7E    JP 7EA4

3F4C 06 19       LD B,19

3F4E 76          HALT

3F4F AF          XOR A

3F50 DB FE       IN A,(FE)

3F52 E6 1F       AND 1F

3F54 FE 1F       CP 1F

3F56 C2 5E 7F    JP NZ,7F5E

3F59 10 F3       DJNZ 3F4E

3F5B C3 34 7F    JP 7F34

 

És most ismét kizökkent bennünket valami kedvenc szórakozásunkból!

 

3FD9 06 19       LD B,19

3FDB 76          HALT

3FDC 3E DF       LD A,DF

3FDE DB FE       IN A,(FE)

3FE0 CB 67       BIT 4,A

3FE2 CA F3 7F    JP Z,7FF3      ;Az "Y" billentyű

3FE5 3E 7F       LD A,7F

3FE7 DB FE       IN A,(FE)

3FE9 CB 5F       BIT 3,A

3FEB CA DB 7C    JP Z,7CDB      ;Az "N" billentyu

3FEE 10 EB       DJNZ 3FDB

3FFO C3 C3 7F    JP 7FC3

 

Ezt már akár bekötött szemmel is meg lehet csinálni!

 

3FD9 06 19       LD B,19

3FDB 76          HALT

3FDC CD 03 01    CALL 0103

3FDF 02          LD (BC),A      ;ADAT

3FEO CB 57       BIT 2,A        ;Az "Y" billentyű

3FE2 CA F3 7F    JP Z,7FF3

3FE5 CD 03 01    CALL 0103

3FE8 00          NOP            ;ADAT

3FE9 CB 47       BIT 0,A        ;A "N" billentyű

3FEB CA DB 7C    JP Z,7CDB

3FEE 10 EB       DJNZ 3FDB

3FFO C3 C3 7F    JP 7FC3

 

Ezután már csak egy fontos dolgunk van:

 

42A4 AF          XOR A

42A5 DB FE       IN A,(FE)

42A7 E6 1F       AND 1F

42A9 FE 1F       CP 1F

42AB CA B3 82    JP Z,82B3

 

Még ezután is van billentyűzetfigyelés, de azt már legközelebbre hagyjuk.

Ha az imént leírt módosításokat elvégezzük (és ki is mentjük!), már be tudjuk állítani a vezérlés módját, a játékosok számát, valamint mindezek méltó megkoronázásaként el is tudjuk indítani a programot. Játszani ugyan nem tudunk vele - mivel igen gyorsan lefagy -, de megtettük az első fontos lépést. Azt, hogy miért fagy le, valamint az egyéb ROM-hívások előtalálásának módozatait legközelebb ecseteljük.

 

Örömmel közölhetjük, hogy sorozatunk egy történelmi pillanathoz érkezett!

 

Az alábbiakban leírtak szerint eljárva végre működőképessé varázsolhatjuk mindenki szeretett MOON CRESTA-ját. Legutóbb odáig jutottunk, hogy elindul a játék, de rögvest meg is dermed. Már említettük - valamikor a múlt ködébe veszően - a "lefagyás" lehetséges okait. Mivel az első számú közellenséget (az interruptot) már kétvállra fektettük, marad a nem kevésbé alattomos ROM hívás. (Természetesen más ok előfordulhat, például elfelejtettük bekapcsolni a gépet.) Miután a követendő utat szellemünk lángoló fáklyaként már bevilágította, már csak elő kellene találni a hívások helyeit. Erre alkalmas az itt következő kis program:

 

        ORG 1000H         ;Ide fordítjuk

L1      LD A,(IX)

        INC IX

        CP 0CDH           ;CALL utasítás?

        JR Z,L2           ;Ha igen, akkor L2

        CP 0C3H           ;JP utasítás?

        JR NZ,L1          ;Ha nem, akkor következő byte

L2      LD L,(IX+0)       ;Operandusok vizsgálata

        LD H,(IX+1)

        LD BC,4000H       ;Ha nem a ROM-ra vonatkoznak

        OR A

        SBC HL,BC

        JR NC,L1          ;következő utasítás keresése

        RET               ;Ha egy ROM hívás, visszatérés

 

A program megértéséhez annyit kell tudni. hogy SPECTRUM-on a ROM a 0000H-3FFFH címtartományban helyezkedik el. A "CALL" Z80 utasítás kódja HEXA 0CDH, a "JP" kódja pedig 0C3H. Fordítsuk le a programot a memóriába 0 oflsettel. IX regiszterbe írjuk be a program kezdőcímét ("X" parancs, majd a "Registerpair:" kérdesre írjuk be az "IX"-et, a "Value:" kérdésre pedig a program kezdőcímét.) Ezután "G", majd a "Start:" kérdésre adjunk 1000-et. Amennyiben a program talált valamit, egy hanghatás után visszatér az ASMON-ba. Ekkor IX a ROM hívás operandusára fog mutatni.

 

FIGYELEM!

 

Nem mind arany, ami fénylik! Véletlenszemen is előfordulhatnak olyan byte kombinációk, amik megegyeznek a ROM hívással. Ezért amint találtunk valamit, a reménybeli hívás címétől számoljunk vissza néhány byte-ot, majd innen listázzuk ki a programot. Ha a listázás során értelmes kódot latunk, valamint a ROM hívás is látható, akkor valószínűleg megtaláltuk. A programban szereplő ÖSSZES hívást javítsuk ki.

 

Leggyakrabban eloforduló hívások:

 

006FH        Egy "JP (HL)" utasítás.

007CH        Egy "RET" utasítás.

028EH        KEY-SCAN rutin (billentyűzet leolvasó)

03R5H        BEEP rutin (hangkiadó rutin)

04C2H        SAVE rutin

055CH        LOAD rutin

22B0H        PIXEL-ADD rutin (képpont címének kiszámítása)

 

Kanyarodjunk vissza kedvenc MOON CRESTA programunkhoz. Ha itt keressük a ROM hívásokat, elég sokat találunk. Köszönhető ez annak, hogy a billentyű figyeléseket már kijavítottuk saját rutin hívásokra, amik az alsó 16k területen vannak, imigyen kimerítve a SPECTRUM ROM fogalmát. Viszont a sok álhívás mögött meglapulva akad néhány igazi is. Ezek:

 

5398 2A C4 87    LD HL,(87C4)

5398 23          INC HL

539C 22 C4 87    LD (87C4),HL

539F 11 01 00    LD DE,0001

53A2 CD B6 03    CALL 03B6

53A5 FD 21 48 89 LD IY,8948

 

(A címekhez 4000H-t hozzá kell adni!)

A 03B6H ugyan kimaradt a felsorolásból, de ez mégis a BEEP rutin, csak a kezdeti "DI" utasítást ugorja át a program. A LOADER-ben a 010CH címen kezdődik egy rutin amely feladatáról nem szóltunk, ez a BEEP rutin ENTERPRISE környezetre honosítva. Tehát a javítás így néz ki:

 

53A2 CD 0C 01    CALL 0100

 

Még két ilyen ilyen hívás van, ezeket nem részletezzük:

 

561A 11 01 00    LD DE,0001

561D 21 58 02    LD HL,0258

5620 CD B6 03    CALL 0386

5623 FO 6E 00    LD L,(IY)

5626 26 FF       LD H,FF

 

5620 CD OC 01    CALL 010C

 

6594 7A          LD A,D

6595 83          OR E

6596 CA A7 A5    JP Z,A5A7

6599 CB 7A       BIT 1,0

b59B CO          RET NZ

659C CD B6 03    CALL J3B6

659F 11 04 00    LD DE,0004

65A2 FD 19       ADD IY,DE

 

659C CD OC 01    CALL 010C

 

Ha a javításokat kimentjük, majd betöltjük a programot, már elindul, zenél és játszana, ha tudnánk irányítani. (A zene idézőjelben értendő, nem sokkal múlja felül pl. a BROS színvonalát)

 

Előfordulhat olyan Olvasó is, aki maga is szeretne aktív részese lenni a játéknak (elégedetlenek mindig vannak). Az ilyen extrém kívánságok teljesítését szolgálja a betöltőben lévő "JOY" nevezetű szubrutin. Működésérői csak annyit, hogy ENTERPRISE-on a két külső joystick leolvasása a 0B6H porton lehetséges. A módszer teljesen hasonló, mint a billentyűzet esetében. A kívánt iránynak megfelelő értéket a 0B5H portra kell kiküldeni, majd a választ a 0B6H port 0.bitjén olvashatjuk be. Ha aktív az irány, akkor a bit 0 értékű. Az irányoknak megfelelő értékek (a külső 1. joystick az EXT1, a külső 2. pedig az EXT2 nevet viseli).

 

 0     EXT1 tűz

 1     EXT1 fel

 2     EXT1 le

 3     EXT1 balra

 4     EXT1 jobbra

 

 5     EXT2 tűz

 6     EXT2 fel

 7     EXT2 le

 8     EXT2 balra

 9     EXT2 jobbra

 

A JOY rutin leolvassa mindkét joystick állapotát, majd ezt az értéket visszaadja az "A" regiszterben, a következő bitkiosztásban:

 

b0     jobbra

b1     balra

b2     le

b3     fel

b4     tűz

 

A rutin az "RST 28H" utasítással hívható, az aktív irányt a bit 1 állapota jelzi. Az egyszerűség kedvéért a játékban csak a joystick vezérlést írtuk át. A program SPECTRUM-on a KEMPSTON-rendszerű illesztővel üzemel (a JOYSTICK CONTROL územmódban). KEMPSTON joystick esetében a botkormány állapotát a decimális 31 (HEXA 1 FH) portról lehet beolvasni. A bitkiosztás megegyezik rutinunk bitkiosztásával, itt is az 1 állapot az aktív. Tehát nincs más teendőnk, mint előkeresni az összes "IN A,(1FH)" utasítást (2 byte) és kicserélni egy "RST 28H" utasításra (1 byte, a másik byte-ot 0-ra írjuk át).

 

A joystick figyelés előfordulási helyei:

 

502BH   6246H   Ezek az "ALSO" file-ban vannak

5032H   6259H

5039H   626EH

B023H           Ezek a "FELSO" file-ban vannak.

B053H

 

Például:

5028 DB lE       IN A,(1F)

Ezt kell

5028 EF 00       RST 28-ra

javítani.

 

Ha így felszereljük programunkat, betöltjük, majd a '4' billentyűvel JOYSTICK CONTROL opcióba állítjuk, végezetül pedig a '6' billentyűvel elindítjuk a játékot, már lőhetjük is önfeledten a gonosz ellenséges űrhajókat. Azaz...

A színek nem mondhatók éppen ideálisnak - sőt - és a harmadik pályán zöld alapon zöld szín adódik, amitől a zöld csillagokat is vörösnek látjuk. Ezen probléma (amely egyben az utolsó) leküzdéséhez legközelebb adunk tanácsokat...

 

Örömmel tudatjuk Olvasóinkkal, hogy elérkeztünk az utolsó, és egyben legnehezebb feladatunkhoz, Talán még emlékeznek, hogy kedvenc MOON CRESTA nevű programunk már elindul, játszani lehet vele, de a színek összeállítása meglehetősen avantgard. Az alábbiakban eme kellemetlenség megszüntetéséhez szeretnénk néhány ötletet közölni.

A színek megváltozásának okáról a betöltőkép javítása során már volt szó, így ezt nem részletezzük. A program által generált színek esetében csak annyival bonyolultabb a helyzet, hogy ilyenkor nem tudni, a program melyik részében foglalkozik az attributum memóriával. A sikeres színjavítás feltétele, hogy képesek legyünk a vitális részeket megkeresni a programban.

 

Hogyan lássunk neki?

 

Először is: meg kell keresni minden abszolút címhivatkozást, amely az attribútummemóriára mutat, pI.: LD HL,5800H stb. Általában a HL regiszterpárra hivatkoznak, a DE kevésbé népszerű, a BC pedig szinte elhanyagolható. A megfelelő hivatkozásokat a ROM hívás kereső programunk megfelelő átalakításával tehetjük meg. A LD HL,nn utasítás Z80 kódja: 21H. Ha megvan a hivatkozás, utána végig kell követni, mikor tölt adatot erre a helyre, Ez az adat az attribútum-byte. Kijavítása a korábbi számban közölt színtáblázat segítségével történik.

Másodszor: a színbeállítás történhet direkt töltéssel is (pI.: LD (5800H),A). Ezek keresésére és javítására ugyanazok vonatkoznak, mint az előzőekre.

Harmadszor: a bitmap címéből számítják ki a hozzátartozó attribútum címet.

Ennek két leggyakoribb változata (HL pixelcím):

 

LD A,H

RRA

RRA

RRA

AND 3

OR 58H

LD H,A

 

avagy

 

LD A,H

AND 18H

RRA

RRA

RRA

OR 58H

LD H,A

 

Ezt a módszert leggyakrabban a szövegkiíráskor használják. Megjegyeznénk, hogy az "OR 58H" utasítás helyett az "ADD A,58H" utasítást is előszeretettel alkalmazzák.

 

Természetesen akadnak ettől eltérő (klinikai) esetek is, de ezek a leggyakoribbak. Persze ez nem vigasztalja azt, aki mindjárt az elegyen egy ilyet fog ki.

 

Ennyi bevezető után lássuk konkrétan, szeretett programunk milyen módszerrel dolgozik.

Először próbálkozzunk az attribútumcím számolás keresésével. A jól ismert "FIND" parancs segítségével kereshetünk egy kombinációt. Az "OR 58H" utasítás gépi kódja: F6 58. Az alábbi rutinra bukkanunk: (a teljes rutin)

 

65AD El          POP HL        ;visszatérési cím

65AE D9          EXX

65AF D9          EXX

65B0 7E          LD A,(HL)     ;első karakter

65B1 23          INC HL

6582 A7          AND A

6583 CA FB A5    JP Z,A5FB

6586 FE 20       CP 20

6588 DA FC A5    JP C,A5FC     ;a SPACE

6588 D9          EXX           ;karakternél kisebb

65BC 6F          LD L,A

65BD 26 00       LD H,00

65BF 29          ADD HL,HL

65C0 29          ADD HL,HL

65C1 29          ADD HL,HL

65C2 ED 5B 36 5C LD DE,(5C36)

65C6 19          ADD HL,DE

65C7 EB          EX DE,HL

65C8 2A CF 87    LD HL,(87CF)

65CB 06 08       LD B,0

65CD 1A          LD A,(DE)     ;egy karakter

65CE AE          XOR (HL)      ;kiírása

65CF 77          LD (HL),A

65D0 13          INC E

65D1 24          INC H

65D2 10 F9       DJNZ 65CD

65D4 7C          LD A,H

65D5 OF          RRCA

65D6 OF          RRCA

65D7 OF          RRCA

65D8 3D          DEC A

65D9 E6 03       AND 03

65DB F6 58       OR 58         ;attribútumcím

65DD 67          LD H,A

65DE 3A BE 87    LD A,(87BE)   ;attr. byte

65E1 77          LD HL ,A      ;attr. tárolása

65E2 21 CF 87    LD HL, 87CF

65E5 34          INC (HL)

65E6 C2 AF A5    JP NZ,A5AF

65E9 23          INC HL

65EA 7E          LD A,(HL)

65EB C6 08       ADD A, 8

65ED 77          LD (HL),A

65EE E6 18       AND 18

65F0 FE 18       CP 18

65F2 C2 AF A5    JP NZ,A5AF

65F5 3E 40       LD A,40

65F7 77          LD (HL),A

65F8 C3 AF A5    JP A5AF

65FB E9          JP (HL)

65FC 7E          LD A,(HL)     ;a 20H-nál kisebb

65FD 32 BE 87    LD (87BE),A   ;karakter utáni byte

6600 23          INC HL        ;attribútumbyte

6601 09          EXX

6602 C3 AF A5    JP A5AF

 

Talán mindenki rájött, hogy ez egy kiíratórutin (PRINT), Hívása a "CALL A5AD" utasítással történik, utána DEFB utasításokkal definiálja a szöveget. A szövegben a 20H-nál kisebb karakterek után áll egy attribútumbyte. Esetünkben a programozók az 1 kódú karaktert használták kizárólagosan. Tehát adott a következő pont: fel kell deríteni a hívásokat, majd ki kell javítani a színeket.

 

Célszerűnek látszik az attribútumbyte tárolására szolgáló memóriaváltozó értékadásait is megvizsgálni. És valóban, találunk is ilyet:

 

5216 3E 43       LD A,43

5218 32 BE 87    LD (87BE),A

 

Miután kijavítottuk a szubrutinhívásokat, térjünk át a másik módszerre.

 

Ebből is akad néhány:

 

389B 21 00 58    LD HL,5800

389E 11 01 58    LD DE,5801

38A1 01 FF 2F    LD BC,02FF

38A4 36 47       LD (HL),47

38A6 ED B0       LDIR

 

Majd egy bonyolultabb:

 

385E 21 60 58    LD HL,5860

3B61 11 61 58    LD DE,5861

3B64 36 00       LD (HL),00

3B66 01 FF 00    LD C,00FF

3B69 ED B0       LDIR

3B6B 21 77 58    LD HL,5877

386E FD 21 81 58 LD IY,5881

3B72 06 12       LD B,12

3874 3A C2 87    LD A,(87C2)

3B77 CB 47       BIT 0,A

3B79 CA 91 7B    JP Z,7B91

3B7C FD 36 00 F8 LD (IY),F8       ;villogó fehér

3B80 FD 36 20 46 LD IY+20),46    ;sárga

3B84 FD 23       INC IY

3B86 10 F4       DJNZ 3B7C

3888 1E 03       LD E,03

3B8A 3E 47       LD A,47         ;fehér

3B8C OE 1D       LD C,1D

3B8E C3 A3 7B    JP 7BA3

3B91 FD 36 00 47 LD (IY),47      ;fehér

3B95 FD 36 20 FO LD (IY+20),F0   ;villogó sárga

3899 FD 23       INC IY

3B9B 10 F4       DJNZ 3B91

3B9D 1E 07       LD E,07

3B9F 3E 46       LD A,46         ;sárga

3BA1 OE 19       LD C,19

3BA3 06 04       LD B,04

3BA5 50          LD D,B

3BA6 43          LD B,E

3BA7 77          LD (HL),A

3BA8 2C          INC L

3BA9 10 FC       DJNZ 3BA7

3BAB 09          ADD HL,BC

3BAC 42          LD B,D

3BAD 10 F6       DJNZ 3BA5

3BAF 21 17 59    LD HL,5917

3BB2 FD 21 21 59 LD IY,5921

3BB6 06 13       LD B,13

3BB8 3A 5E F3    LD A,(F35E)

3BBB A7          AND A

3BBC CA D4 7B    JP Z,7BD4

3BBF FO 36 00 C5 LD (IY),C5      ;villogó kék

3BC3 FD 36 20 44 LD (IY+20),44   ;zöld

3BC7 FD 23       INC IY

3BC9 10 F4       DJNZ 3BBF

3BCB 1E 05       LD E,05

3BCD 3E 45       LD A,45         ;kék

3BCF OE 1B       LD C,1B

3BD1 C3 EA 7B    JP 7BEA

3BD4 FD 36 00 45 LD (IY),45      ;kék

3BD8 FD 36 20 C4 LD (IY+20),C4   ;villogó zöld

3BDC FD 23       INC IY

3BDE 10 F4       DJNZ 3BD4

3BEO 3E 44       LD A,44         ;zöld

3BE2 OE 1D       LD C,1D

3BE4 11 06 00    LD DE,0006

3BE7 19          ADD HL,DE

3BE8 1E 03       LD E,03

3BEA 06 03       LD B,03

3BEC 50          LD D,B

3BED 43          LD B,E

3BEE 77          LD (HL),A

3BEF 2C          INC L

3BFO 10 FC       DJNZ 3BEE

3BF2 09          ADD HL,BC

3BF3 42          LD B,D

3BF4 10 F6       DJNZ 3BEC

3BF6 21 9C 59    LD HL,599C

3BF9 11 90 59    LD DE,599D

3BFC 01 AO 00    LD BC,00A0

3BFF 36 43       LD (HL),43

3C01 ED BO       LDIR

3C03 21 57 5A    LD HL,5A57

3C06 11 58 5A    LD DE,5A58

3C09 36 42       LD (HL),42

3COB 01 84 00    LD BC,0084

3COE ED B0       LDIR

 

A rutin első fele az opciók beállítását szolgálja. A kiválasztott opció villog. (FLASH bit beállítva) Ezt úgy tudjuk kiküszöbölni a legegyszerűbben, hogy inverz hátteret állítunk be A második fél egyszerű színbeállítást végez.

 

Még van egy rejtett színállítás a 6643 címen:

 

6643 E6 47       AND 47

 

A programsor környezetének megvizsgálása után nyilvánvalóbb lesz a dolog, ezt az Olvasókra bízzuk. Ezek után a MOON CRESTA már színhelyesen kezdődik, de játék közben még bőven akadnak színhibák (a SPRITE-ok). A játék így még eléggé élvezhetetlen, de úgy gondoljuk, aki idáig szorgalmasan kitartott, annak egy egyszerű ujjgyakorlat a további munka, így nem lőjük le a poént.

 

Végezetül néhány szó a 128k SPECTRUM-ra írt programokról: Két nagy csoportra oszthatjuk a mezőnyt.

 

Egyrészt vannak a 48/128 fedőnevű programok. Ezek a mezei 48k-s SPECTRUM-on is működnek, általában a pályákat külön-külön töltik be. Ezek a 128-ason egy részletben betöltődnek, gyakran zenét, beszédet, plusz animációt stb. tartalmaznak. Ilyen pl. a ROBOCOP, amely zenét, valamint digitalizált (igen jó minőségű) beszédet is tartalmaz amellett, hogy minden szint a memóriában tartózkodik (nem ideiglenesen).

 

A másik csoport, amely kizárólag 128k-s gépen fut, esetleg 48k-s változata nem is létezik. Ezek a programok a legjobbak, mivel hosszuk többszöröse az előző csoporténak, így bonyolultabb a játék. Ezen csoport éllovasa a "WHERE TIME STOOD STILL" című program, amely bonyolultsága, grafikai kidolgozása. zenéje igazi mestermunka. Ide sorolható még a BEDLAM, THE MUNCHER, GHOULS 'n' GHOSTS, valamint a STARGLIDER 2 című program is.

 

Az ENTERPRISE szemszögéből az első csoport könnyen átírható, a második csoport pedig rizikós. Nehézséget az okoz, hogy míg SPECTRUM-on a teljes 128k kihasználható, addig ENTERPRISE-on az LPT-nek kell helyet hagyni. Ha nincs ennyi memória sem: akkor a reménybeli átíró makacsságán múlik a dolog.

 

Példaképpen: az említett WHERE TIME STODD STILL programban nem volt 200 byte szabad hely sem, de azért...

 

A 128k SPECTRUM memóriakezeléséről már volt szó. Ezt úgy lehet átírni, hogy minden SPECTRUM szegmenshez hozzárendelünk egy ENTERPRISE szegmenst, a

 

LD BC,7FFDH

LD A,x

OUT (C),A

 

utasításokat pedig átírjuk egy

 

LD A,y

OUT (0B3H),A

 

utasításcsoportra. x az eredeti, y a módosított szegmensszám.

 

A zene átírása már keményebb dió. Az AY-3-8912 regisztereinek leírása a SINCLAIR SPECTRUM JÁTÉK ÉS PROGRAM V. c. kötetében található (LSI ATSz. 1988.). A feladat az hogy olyan szubrutint készítsünk, amely a megfelelo AY és DAVE regisztereket egymáshoz rendeli. Ezt a problémát még egyeduli és údvozíto modon nem sikerült megoldani.

 

A problémák:

 

Hardware burkológörbe. Na ez az, ahol még nem Sikerült igazi áttörést végrehajtani. Szomorú tény, de ebben jobb az AY chip. Sajnos a "XENON" című játék ENTERPRISE zenéje csak nyomokban emlékeztet az eredetire.

Zajgenerátor. Abban az esetben, ha egy csatornán csak zaj szol, akkor majdnem teljes mértékben emulálható a zajeffekt. Ha egy csatornán egyszerre szól a zaj és a tiszta hang, akkor egyenlőre megáll a tudományunk.

 

Nos, ennyi lett volna ez a bűvös tudomány. Ha valaki végigolvasott minden részt, attól még nem biztos, hogy képes is önállóan végrehajtani egy ilyen műveletet (sőt!), de a kiindulás talán világosabb lett. Akit hidegen hagyott az a perspektíva, hogy saját maga írhat át programokat, esetleg az egyes rutinok programozási módszereibol okulhatott valamit, hiszen eléggé átfogó jelleggel kellett használni mind a gépet, mind az operációs rendszert.

 

Utolsó gondolatként annyit, hogy reményeink szerint sokan kaptak kedvet a témához, és futószalagon szállítják a jobbnál-jobb átiratokat. Mivel eredeti ENTERPRISE programok már nemigen készülnek és sok embernek van ilyen gépe, napjainkban egyre nagyobb szerepe lesz az amatőröknek.

 

VÉGE