· ąF.Codeł ° » ľSzevasztok!Ľ Nem sok visszajelzést kaptam, ezért arra támaszkodok, ami van... (Emberek! Levelekkel bombázni! ;) Mégpedig az volt a visszajelzés, hogy "nem kéne annyit foglalkozni kezdő kódolással". Igaz ez? Jó. Szerintem sincs valami sok kezdő kóder Amigán. Szerintem aki megmaradt az Amiga mellett, az valamilyen szinten komolyan foglalkozik vele... csak a lamerek nem tudják értékelni az Amigát ˝(Ezek a lamerok már peecee-n dúmoznak...).Ľ Nekem nagyrészt csak olyan infóim voltak (vannak) a kódolással kapcsolatban, amik részletekig kivesézték az adott témát, de egyetlen példát sem tartalmaztak (vagy csak nagyon keveset). Van egy olyan mondás, hogy "soxor egy példa többet ér bármilyen magyarázásnál". Ez szerintem is igaz. Hát én főleg ezt a "példát" fogom szolgáltatni, a már meglévő leírások mellé, ezzel is érthetőbbé téve ezt a nehéz témát (mármint az assembly-t Amigán). Mielőtt továbbmennél, ajánlom legalább a futólagos tanulmányozását a Hardware_Manual-nak és az MC680x0.guide-nak. Még talán egy fontos dolgot mondanék ide a bevezető végére: ˝ NE ADD FEL!Ľ Akkor lássuk a mai menü-t: mivel ez a code-rovat végülis egy demó-code-rovat akar lenni, ilyen irányban haladunk tovább... (ügyelek azért arra, hogy ne nagyon szakadjon meg a vonal a kezdőknek sem...) Ha valami kérdés, észrevétel, stb. van, akkor jelezzétek! Tehát: demóknál, intróknál az az általános, hogy lelőjük a rencert, hogy többé ne legyen a terhünkre :). Ez lesz a mai téma. Ez annyiból áll, hogy letiltjuk a megszakításokat, a DMA-kat, és utána már szabadon garázdálkodhatunk a gépben. Megjegyzem még, hogy általában egy adott feladathoz több helyes megoldás is létezik... Akkor következzen a lényeg: ;---8<----------------------------------------------------------------------- ; ^^-ez itt egy olló akar lenni... ;-) ; Ha valami kettőspont után van egy sorban a forráslistában, akkor azt a ; fordításkor a fordító figyelmen kívül hagyja. Ez ideális saját emlékeztető ; kommentjeinknek, amik arra jók, hogy akár évek múlva is tudjuk, hogy az ; adott programrészlet mit is csinál. Én meg a magyarázáshoz fogom ; használni. ; ; Ezek a sorok itt lejjebb az ún. offsetek, amik az ún. könyvtárak ; rutinjainak (függvényeinek) az ún. báziscímhez képesti különbségét ; tartalmazzák. Ha az OpenLibrary() függvénnyel megnyitottunk egy ; könyvtárat, akkor megkapjuk annak báziscímét, amihez ha hozzáadjuk az ; offsetet, akkor megkapjuk az adott függvény ugrási címét (Ne aggódj, lesz ; ez még bonyolultabb is! ;-)). A függvények részletes leírását megtalálod ; az autodocs doksiban. Ezeket az offseteket itt eltároljuk az ún. ; változókban, és ezután már erre is hivatkozhatunk a forráslistában. ; Ezeket, és az összes többi offseteket egyébként megtalálod az includes ; arhívban, de most úgyis csak 5 offsetet használunk, ezért nem inklúdolom az ; egészet... (Majd arra is csinálok egy példát... de ne vágjunk a dolgok ; elébe!) _LVOOldOpenLibrary EQU -408 _LVOLoadView EQU -222 _LVOWaitTOF EQU -270 _LVOCloseLibrary EQU -414 _LVORethinkDisplay EQU -390 section code,code ; ez a sor határozza meg, hogy az adott hunk ; mi is legyen. Ez lehet code, data és bss. s: ; ez egy címke. sok értelme nincs itt a forrás elején, de sokszor jól ; jöhet debuggoláskor... move.l 4.w,a6 ; a 4-es memóriacímről betöltjük az a6 ; regiszterbe az ott levő longwordot. ez ; tulajdonképpen az exec library báziscíme. ; Ez egy biztos pont a többi library ; megnyitásához is. lea gfxname,a1 ; a gfx library nevének kezdőcímét betöltjük ; az a1 regiszterbe (az OldOpenLibrary ; függvényhez). jsr _LVOOldOpenLibrary(a6) ; az a6 regiszterben az exec báziscím ; van, az _LVOOldOpenLibrary változóban az ; OldOpenLibrary függvény offsetje, tehát ; adott a függvény ugrási címe... ez a sor ; meghívja az OldOpenLibrary fügvényt, amely ; megnyitja a graphics.library-t. move.l d0,a6 ; a d0 regiszterben visszakapjuk a ; graphics.library báziscímét, ezt töltjük az ; a6 regiszterbe. sub.l a1,a1 ; az a1 regiszter tartalmát kivonjuk önmagból, ; tehát nulla lesz benne. Ez így gyorsabb, ; mint a 'clr.l a1' utasítás. jsr _LVOLoadView(a6) ; a graphics.library LoadView függvényét ; hívjuk meg. Ez megnyit egy olyan screen-t, ; amin semmi sincs. Ez azért jó, mert ha pl. ; valaki multisync-ben vagy ntsc-ben nézi a ; gépét, akkor is visszavált pal-ra a ; megjelenítés, és ekkor már nem kell nekünk ; figyelni erre. jsr _LVOWaitTOF(a6) ; gfx-WaitTOF függvény. vár, hogy az ; elektronsugár elérjen a kép tetejére. jsr _LVOWaitTOF(a6) ; Kétszer várunk, hogy az előbb megnyitott ; screen biztos nyitva legyen már. move.l a6,a1 ; a6 tartalmát átmásoljuk az a1-be (gfx.lib ; báziscíme) move.l 4.w,a6 ; exec.lib báziscíme az a6-ba jsr _LVOCloseLibrary(a6) ; bezárjuk a gfx.lib-et lea $dff000,a6 ; a memóriában a $dff000 címtől kezdődnek a ; kép-hang-miegymás hardver elemek vezérlő- ; regiszterei (custom registers), amivel mi is ; direkt módon tudjuk manipulálni az Amigánkat ; A kompatibilitás megtartása végett viszont ; ettől óvnak minket a rendszerfejlesztők. ; Na mindegy, most így csináljuk.... ; Tehát: bázisregiszternek használjuk az a6 ; regisztert a custom regiszterekhez. move.w $2(a6),-(a7) ; a $dff002 címről ($2(a6) az egyenlő a6+2-vel ; bemásoljuk a verembe az ott levő word-öt. Ez ; a DMA control register olvasható regisztere ; (a regiszterek nagy részének külön van az ; olvasható és írható része). Ez azért kell, ; hogy kilépéskor vissza tudjuk állítani az ; eredeti állapotot, hogy a rendszer tovább ; tudjon működni. move.w $1c(a6),-(a7) ; $dff01c regiszter tartalmát mentjük ezzel el ; a verembe, amiben a megszakítás engedényező ; bitek vannak. Szintén a kilépéshez kell. move.w #$7fff,$9a(a6) ; Töröljük a megszakításokat. Ez a ; megszakítást engedélyező-törlő regiszter ; írható regisztere, amely úgy működik, hogy a ; legfelső helyiértékű bittel határozzuk meg, ; hogy bit törlést, vagy bit beállítást ; végezzenek a magasra állított bitek a ; word-ben. Ha a legfelső helyiértékű bit ; magas, akkor engedélyezve lesznek azok a ; megszakítasok, amelyiknek a bitje magas. A ; többi megszakítás érintetlenül marad. Ha ; alacsony (0) a legfelső helyiértékű bit, ; akkor törölve lesznek azok a megszakítasok, ; amelyiknek a bitje magas. a többi megszakí- ; tás érintetlen marad. Ha tehát a legfelső ; bit alacsony, és a többi magas ($7fff) ; akkor az összes megszakítás törlődik. Hogy ; mi is az a megszakítás? Az megér egy külön move.w #$7fff,$96(a6) ; misét... A DMA-kat is töröljük... ez a ; regiszter is úgy működik, mint a ; megszakítást vezérlő regiszter. move.l #copperlist,$80(a6) ; A saját kopperlistánk kezdőcímét beírjuk ; a kopperlista cím mutató regiszterbe. move.w #$8280,$96(a6) ; Engedélyezzük a kopperlista DMA-t, tehát ; elindul a saját kopperlistánk (leírását lásd ; ott!). ;---------------------------- <- ezeket a sorokat csak azért szúrom be, ; hogy sokkal áttekinthetőbb legyen a ; forráslista. pang: btst #6,$bfe001 ; teszteljük a bal egérgombot, bne.b pang ; ha a bit magas, még nem nyomtuk le a bal ; egérgombot, és visszaugrunk a pang: címkére. ;---------------------------- lea $dff000,a6 ; újra betöltjük az a6 regiszterbe a $dff000 ; számot, báziscím gyanánt. move.w #$7fff,$9a(a6) ; Lelőjük a mexakításokat (a miénket lőnénk ; le, de ilyen még (egyenlőre) nem volt). move.w #$7fff,$96(a6) ; Lelőjük a DMA-kat (ez egy copperlist DMA ; volt ez esetben). or.l #$80008000,(a7) ; a veremben "fel-or-oljuk" (vagy művelettel) ; az utolsó két word legfelső bitjét. Ugye a ; veremben a megszakítás, és DMA regiszterek ; olvasható részének a programunk előtti ; tartalma található. Ha magasra állítjuk a ; legfelső biteket az utolsó kettő word-ben a ; veremben, akkor egyszerűen csak vissza kell ; másolni azokat a megszakítas és DMA vezérlő ; regiszterek írható részébe, és visszaállí- ; tódnak a rencer-lelövés előtti megszakítások ; és DMA-k. move.w (a7)+,$9a(a6) ; visszamásoljuk a megszakítás-vezérlő ; regiszterbe a verem aktuális word-jét. Ugye ; ez volt utóbb elmentve a verembe, tehát ezt ; kell előbb visszamásolni. így műxik a verem. move.w (a7)+,$96(a6) ; Majd a DMA következik... ; A következő 3 sort én is úgy kaptam, ; úgyhogy nem nagyon értem hogy pontosan mit ; csinál... A lényege az, hogy valahonnan ; előkaparja a rendszerből a rendszer- ; kopperlista kezdőcímét, és azt visszamásolja ; a kopperlista-mutató regiszterbe. move.l 4.w,a5 ; execbase move.l $9c(a5),a5 ; search for move.l 38(a5),$80(a6) ; oldcopper, and reset. move.l 4.w,a6 ; megnyitjuk az intuition.library-t lea intname,a1 jsr _LVOOldOpenLibrary(a6) move.l d0,a6 jsr _LVORethinkDisplay(a6) ; Az intuition-nel végrehajtunk egy ; RethinkDisplay-t, ami visszaállítja ; a régi kopperlistát is. move.l a6,a1 move.l 4.w,a6 jsr _LVOCloseLibrary(a6) ; Majd lezárjuk az intuition-t. moveq #0,d0 ; Nullát írunk a d0 regiszterbe, hogy ne le- ; gyen mindenféle zavaró returncode, ha ; cli-ből futtatjuk a kódunkat. rts ; Visszaadjuk a vezérlést a rencernek ; (cli-nek). gfxname: dc.b 'graphics.library',0 ; graphics.library neve, a ; megnyitásához. intname: dc.b 'intuition.library',0 ; intuition.library neve a ; megnyitásához. even ; Ez egy pszeudo-utasítás (ál-utasítás), ami annyit csinál, ; hogy ha páraltan bájtra jön ki a fenti karaktersorozat, ; akkor beszúr még egy bájtot, hogy párosra jöjjön ki az ; esetleges következő utasítások kezdőcíme. ;---------------------------- section copper,data_c ; most adat-szekció jön, amit a Chip-RAM-ba ; kell fordítani. Azért van a data_c opció. ; Ez az adat nem más, mint a kopperlistánk. copperlist: ; Ez a mai példánk lényege. A copper nevű chip nem más, mint ; egy programozható processzor, ami a programjának megfelelően ; a processzortól függetlenül végzi a dolgát. Az ún. ; kopperlista ennek a procinak a programja. Három utasítást ; ismer: move, wait és skip. Ezek részletes leírását ; megtalálod a hardware manual-ban. ; a kopper utasításokat közvetlenül adat-word-ökkel határozzuk meg: "dc.w". ; Ami a dc.w után áll, az fordítaskor egy az egyben belemásolódik a memóriába ; word-önként folytonosan egymás után (persze nem az ASCII karakterek, hanem a ; hexa számok... ami kicsit feljebb van a gfxname: intname: címkék utáni dc.b, ; ott tényleg egy az egyben bemásolódik a memóriába az idézőjelek, vagy az ; aposztrófok közötti rész.) dc.w $3007,$fffe ; Várakozunk a $30 függőleges, és $07 vízszintes ; elektronsugár pozícióra. dc.w $0180,$0200 ; a $dff180 custom regiszterbe, ami a nullás (háttér) ; szín-regiszter, $200 írunk, ami egy halvány piros ; szín. Azért jó, ha a $07 vízszintes pozícióra ; várunk a $01 pozíció helyett, mert akkor overscan ; monitoron se fog a jobb oldalon látszódni a ; következő rasztersor színe. dc.w $3107,$fffe ; $31 függőleges elektronsugár pozícióra ; (rasztersorra) várunk. dc.w $0180,$0400 ; Háttérszínt megint állítjuk kicsit világosabb ; pirosra. dc.w $3207,$fffe ; $32 rasztersorra várunk... dc.w $0180,$0600 ; piros szín... dc.w $3307,$fffe ; bla-bla... dc.w $0180,$0800 ; bla-bla... dc.w $3407,$fffe dc.w $0180,$0a00 dc.w $3507,$fffe dc.w $0180,$0c00 dc.w $3607,$fffe dc.w $0180,$0e00 dc.w $3707,$fffe dc.w $0180,$0c00 dc.w $3807,$fffe dc.w $0180,$0a00 dc.w $3907,$fffe dc.w $0180,$0800 dc.w $3a07,$fffe dc.w $0180,$0600 dc.w $3b07,$fffe dc.w $0180,$0400 dc.w $3c07,$fffe dc.w $0180,$0200 dc.w $3d07,$fffe dc.w $0180,$0000 dc.w $3e07,$fffe dc.w $4007,$fffe ; a $40 rasztersorra várunk... dc.w $0180,$0222 ; a szürke árnyalatokkal variálunk most... dc.w $4107,$fffe dc.w $0180,$0444 dc.w $4207,$fffe dc.w $0180,$0666 dc.w $4307,$fffe dc.w $0180,$0888 dc.w $4407,$fffe dc.w $0180,$0aaa dc.w $4507,$fffe dc.w $0180,$0ccc dc.w $4607,$fffe dc.w $0180,$0eee dc.w $4707,$fffe dc.w $0180,$0ccc dc.w $4807,$fffe dc.w $0180,$0aaa dc.w $4907,$fffe dc.w $0180,$0888 dc.w $4a07,$fffe dc.w $0180,$0666 dc.w $4b07,$fffe dc.w $0180,$0444 dc.w $4c07,$fffe dc.w $0180,$0222 dc.w $4d07,$fffe dc.w $0180,$0000 dc.w $4e07,$fffe dc.w $5007,$fffe ; a $50 rasztersorra várunk most... dc.w $0180,$0020 ; a zöld színekkel variálunk most... dc.w $5107,$fffe dc.w $0180,$0040 dc.w $5207,$fffe dc.w $0180,$0060 dc.w $5307,$fffe dc.w $0180,$0080 dc.w $5407,$fffe dc.w $0180,$00a0 dc.w $5507,$fffe dc.w $0180,$00c0 dc.w $5607,$fffe dc.w $0180,$00e0 dc.w $5707,$fffe dc.w $0180,$00c0 dc.w $5807,$fffe dc.w $0180,$00a0 dc.w $5907,$fffe dc.w $0180,$0080 dc.w $5a07,$fffe dc.w $0180,$0060 dc.w $5b07,$fffe dc.w $0180,$0040 dc.w $5c07,$fffe dc.w $0180,$0020 dc.w $5d07,$fffe dc.w $0180,$0000 dc.w $5e07,$fffe dc.w $ffff,$fffe ; Egy nem létező sorra várunk. Ez a kopperlistánk ; végét jelenti. Innentől már csak akkor kezdődik ; újra kopperlista feldolgozása, ha újabb képet kezd ; kirajzolni az elektronsugár. Ekkor elölről kezdi a ; kopperlista feldolgozását a kopper. END ; Itt a vége! Ez is egy pszeudo-utasítás. Ami utána áll, az ; már nem kerül lefordításra. ;--------------------------------------------------------------->8------------ Tehát röviden összefoglalva: lelőjük a rendszert, beállítjuk a saját kopperlistánkat, majd várunk a bal egérgombra. Ha lenyomtuk, lelőjük a saját kopperlistánkat, visszaállítjuk a rendszer dolgait (DMA, IRQ..), és kilépünk a programunkból. Ennyi... Ezt a forráslistát megtalálod külön is a bonus könyvtárban example_02.s.lha néven. Házi feladat gyanánt próbálgathatjátok átállítani a színeket! ;-) Remélem minden világos volt. Ha nem, akkor jelezzétek azt! Különben csak beszélek a vakvilágba! (Legalábbis nekem úgy tűnik.) Bye! ľRayĽ