home *** CD-ROM | disk | FTP | other *** search
- A S S E M B L E R - K U R S (c) Jeff Kandle 1990
-
- 27.Teil...
-
- Hat mal wieder etwas laenger gedauert, aber ich habe im moment sehr viel zu
- tun. Unter anderem muss ich mich um ein Netzteil fuer meine Festplatte
- kuemmern die ich mir gekauft habe. Das wird auch noch etwas dauern, und
- sobald ich alles fuer die Platte habe muss ich sie mir ja auch noch
- einrichten und mich damit bekannt machen. Also wenn die Teile jetzt
- Zeitlich ein bisschen mehr auseinander liegen, dann denkt nicht ich haette
- euch vergessen, es ist einfach nur die Platte.
-
- Aber weiter gehts...
-
- Das einfache setzen eines Bobs duerfte jetzt ja kein Problem mehr sein,
- oder ?
- Geben wir uns mal an eine Routine die aus einem Wort die X und Y
- Koordinaten errechnet und die Werte fuer den Blitter setzt.
- Allerdings treten da ein paar wichtige sachen auf die man beachten muss.
- Aber fangen wir mal Theoretisch an. Um das Programm einfach zu halten
- arbeiten wir nur mit PAL-Koordinaten. Das heisst das wir zwar einen
- Overscan Screen haben, aber nur Koordinaten von 0 bis 255 erlauben.
-
- Ich gehe diese Theoretischen durchlauf einer solchen Routine mit einem
- Beispielwert durch. Das erleichtert die sache.
-
- Der Beispielwert ist $5167, also Y = $51 und X = $67.
- Die Werte fuer den Bildschirm sind.
- Bitplanes bei $60000,$6002c,$60058 (Verschachtelt)
- Bytes pro Zeile = 44($2c)
-
- Rechnen wir erstmal den Y-Wert aus...
-
- Dazu muessen wir erstmal den anderen Krempel loswerden der noch in dem
- Kontrollwort steht. Das machen wir indem wir es durch $100 Dividieren. Dann
- steht nur noch die $0051 da.
- Also Zeile $51....Da muessten wir normalerweise zum Anfang der Plane nur
- $51 * $2c Addieren. Da wir aber drei verschachtelte Planes haben, muss man
- den ganzen Krempel noch mal drei nehmen. Damit wir uns eine Multiplikation
- zu ersparen nehmen wir die Zeilenzahl direkt mal $84 (3 * $2c).
- Bei Zeile $51 muesste dann $51 * $84 + $60000 gerechnet werden.
-
- Da kommt nach Adam`s Riesen $629c4 bei raus. Das ist also der Zeilenanfang
- an dem der Bobs steht.
-
- Gehen wir jetzt weiter zur Komplizierteren Routine. Holen wir uns erneut
- das Kontrollwort. Mit der Logischen Funktion AND koennen wir den Oberen
- Teil ausmaskieren. Bleibt noch die $67, die die X Koordinate in Pixeln
- angibt. Da wir aber immer nur 15 Pixel verschieben koennen muessen wir
- erstmal mit Hardscrolling so nah wie moeglich an den Punkt rankommen an dem
- der Bob dann hinterher steht. Also brauchen wir erstmal die 6. Teilen wir
- den Krempel durch $10. Jetzt steht die $6 im Wort. Da wir nicht Byteweise
- sondern Wortweise arbeiten, muessen wir die 6 noch verdoppeln. Dazu
- multiplizieren wir es nicht, sondern Addieren das Register zu sich selbst
- dazu. Denn die Multiplikation des MC 68000 sind eine sehr langsame sache.
- Nachdem wir es verdoppelt haben, koennen wir es zu der Adresse der Zeile
- dazuaddieren. Dann stehen wir schon sehr nah am Ziel.
-
- Jetzt muessen wir noch den Wert fuer das Softscrollen errechnen..
- Dazu maskieren wir alles ausser den Softwert mit AND aus. Nehmen den * $100
- um ihn in das Highbyte des hinteren Wortes zu kriegen, und Addieren dazu
- einfach den Rest des BLTCON0 Registers dazu.
-
- Diese Routine macht das eben besprochene. Am Ende der Routine steht in A0
- die Adresse an der der Bob dargestellt wird, und in D0 das Komplette Word
- fuer das BLTCON0 Register.
-
-
- ; Beim Aufruf der Routine muss das Kontrollwort schon feststehen und
- ; in D7 stehen.
-
- CoordCalc:
-
- Move.l d7,d1 ; Kontrollwort nach D1
- And.l #$ff00,d1 ; Alles ausser Y-Werte aus-
- ; maskieren !
- Divs #$100,d1 ; Nach unten schieben
- Muls #$84,d1 ; Wert auf dem Screen ermitteln
- Add.l #$60000,d1 ; Plus PlayfieldBase
- Move.l d1,a0 ; Nach A0 setzen.
-
- Move.l d7,d1 ; Erneut holen !
- And.l #$00f0,d1 ; Unwichtiges ausmaskieren
- Lsr.l #3,d1 ; Ersetzt Divs $10 und verdoppeln
- Add.l d1,a0
-
- Move.l d7,d1 ; !!!
- And.l #$f,d1 ; Ausmaskieren !
- Swap d1
- Lsr.l #4,d1
- Move.w #%0000100111110000,d0 ; BLTCON0-Wert ohne Scrollwert
- ; nach d0
- Add.w d1,d0 ; D1 zu D0 addiert ergibt BLTCON0
- Clr.l d1 ; Werte nur in D0 und A0 lassen
- Clr.l d7
-
- Bsr.l Set_bob ; Bob setzen.
- Rts
-
- So diese koennt ihr direkt hinter die Set_Bob-Routine setzen. Da diese
- Routine vor der Set_bob aufgerufen werden muss, muesst ihr in dem oberen
- Teil des Listings aus dem Bsr.l Set_Bob ein Bsr.l Coordcalc machen.
- Davor setzt ihr zum Probieren die Zeile
-
- Move.l #$5167,d7
-
- Damit es schonmal laeuft.
- Dann muesst ihr noch die Set_Bob Routine aendern, das nicht mehr die festen
- Werte geschrieben werden, sondern D0 nach BLTCON0 und A0 nach BLTDPT
- geschrieben wird, das muesstet ihr finden.
- Als letztes koennt ihr noch in der Clearschleife aus der -1 eine 0 machen,
- damit der Screen Schwarz wird und man die Raender links und rechts von Bob
- sehen, obwohl es ja auch ganz Interressant ist sie zu sehen.
-
- Um diesen Bob auf dem Screen rumflitzen zu lassen, muessen wir eigentlich
- nur noch eine Routine schreiben die der Coordcalc-Routine laufend neue
- Koordinaten uebergibt. Das sollte dann jeden Bildschirm aufbau passieren.
- Also muessen wir die abfrage der Bildschirmposition einbauen, die Tabelle
- mit den Positionen und die Routine die die Koordinaten uebergibt und die
- Tabelle rotiert.
- Allerdings fehlt dann noch etwas...Naemlich eine Routine die den alten Bob
- loescht damit die Reste nicht auf dem Bildschirm bleiben. Das ist zwar ein
- netter Effekt, aber auch nicht unbedingt das was wir wollen.
-
- So hier erstmal das Prograemmchen. Ich habe keine Koordinatentabelle
- benutzt weil sie Platz wegnimmt, und ich ausserdem keine lust habe mir die
- Finger an so einer Tabelle wund zu schreiben. Das Position des Bobs wird
- durch einen ADD befehl veraendert.
-
- Start:
- Execbase= 4
- Openlibrary= -408
- Vposr= $dff004
- Forbid= -30-102
- Permit= -30-108
- Bltafwm= $dff044
- Bltalwm= $dff046
- Bltcon0= $dff040
- Bltcon1= $dff042
- Bltamod= $dff064
- Bltdmod= $dff066
- Bltapt= $dff050
- Bltdpt= $dff054
- Dmacon= $dff096
- Intena= $dff09a
- Dmaconr= $dff002
- Bltsize= $dff058
- Cop1lc= $dff080
-
- Move.w #$0020,Dmacon
- Move.w #$4000,Intena
- Move.l Execbase.w,a6
- Jsr Forbid(a6)
-
-
- Move.l #$60000,a0
- Move.l #$9588/4,d0
- Clearloop:
- Move.l #0,(a0)+
- Dbf d0,Clearloop
-
- Bsr.l Makecl
-
-
- Wait: Move.l Vposr,d0
- And.l #$1ff00,d0
- Cmp.l #$1000,d0
- Bne.s Wait
- Bsr.l Kill_old
- Bsr.l Get_Pos
- Btst #6,$bfe001
- Bne.s Wait
-
- Move.l Execbase.w,a6
- Jsr Permit(a6)
- Lea Gfxname(pc),a1
- Jsr Openlibrary(a6)
- Move.l d0,a6
- Move.w #$83e0,Dmacon
- Move.w #$c000,Intena
- Move.l 38(a6),Cop1lc
- Moveq #0,d0
- Rts
- Makecl:
- Lea $05f000,a0
- Move.l a0,$dff080
-
- Move.l #$00e00006,(a0)+
- Move.l #$00e20000,(a0)+
- Move.l #$00e40006,(a0)+
- Move.l #$00e6002c,(a0)+
- Move.l #$00e80006,(a0)+
- Move.l #$00ea0058,(a0)+
- Move.l #$008e1a64,(a0)+
- Move.l #$009039d1,(a0)+
- Move.l #$00920030,(a0)+
- Move.l #$009400d8,(a0)+
- Move.l #$01003200,(a0)+
- Move.l #$01080058,(a0)+
- Move.l #$010a0058,(a0)+
- ;----------------------------------------------
- Move.l #$01800000,(a0)+
- Move.l #$0182071d,(a0)+
- Move.l #$0184088e,(a0)+
- Move.l #$0186044f,(a0)+
- Move.l #$0188000f,(a0)+
- Move.l #$018a000c,(a0)+
- Move.l #$018c0008,(a0)+
- Move.l #$018e0004,(a0)+
- ;----------------------------------------------
- Move.l #$fffffffe,(a0)+
- Rts
- Waitblit:
- Btst #6,Dmaconr
- Bne.s Waitblit
- Rts
- Set_bob:
- Bsr.s Waitblit
- Move.w #$ffff,Bltafwm
- Move.w #$ffff,Bltalwm
- Move.w d0,Bltcon0
- Move.w #0,Bltamod ; Quellmodulo = 0 (rawblit)
- Move.w #38,Bltdmod ; Zielmodulo = 38 (planes = $2c)
- Move.l #$5e000,Bltapt ; Quelladr.
- Move.l a0,Bltdpt ; Zieladr.
- Move.w #96*64+3,Bltsize ; Bltsize und Start
- Rts
-
- ; Beim Aufruf der Routine muss das Kontrollwort schon feststehen und
- ; in D7 stehen.
-
- CoordCalc:
-
- Move.l d7,d1 ; Kontrollwort nach D1
- And.l #$ff00,d1 ; Alles ausser Y-Werte aus-
- ; maskieren !
- Divs #$100,d1 ; Nach unten schieben
- Muls #$84,d1 ; Wert auf dem Screen ermitteln
- Add.l #$60000,d1 ; Plus PlayfieldBase
- Move.l d1,a0 ; Nach A0 setzen.
-
- Move.l d7,d1 ; Erneut holen !
- And.l #$00f0,d1 ; Unwichtiges ausmaskieren
- Lsr.l #3,d1 ; Ersetzt Divs $10 und verdoppeln
- Add.l d1,a0
-
- Move.l d7,d1 ; !!!
- And.l #$f,d1 ; Ausmaskieren !
- Swap d1
- Lsr.l #4,d1
- Move.w #%0000100111110000,d0 ; BLTCON0-Wert ohne Scrollwert
- ; nach d0
- Add.w d1,d0 ; D1 zu D0 addiert ergibt BLTCON0
- Clr.l d1 ; Werte nur in D0 und A0 lassen
- Clr.l d7
-
- Bsr.l Set_bob ; Bob setzen.
- Move.l a0,Old_Pos ; Position fuer loeschroutine
- ; merken !
- Rts
-
- Kill_Old:
- Bsr.l Waitblit
- Move.l #$-1,Bltalwm
- Move.w #38,Bltdmod
- Move.w #%0000000100000000,Bltcon0
- Move.l Old_Pos,Bltdpt
- Move.w #96*64+3,Bltsize
- Rts
-
- Get_Pos:
- Move.w Position,d7
- Add.w #$101,Position
- Bsr.l Coordcalc
- Rts
-
- Old_Pos: Dc.l $60000
- Position: Dc.w 0
- Gfxname: dc.b "graphics.library",0
-
- >Extern "bob.raw",$5e000
-
- Wichtig ist allerdings eines.
- Da ich die Kill_Old Routine vor der Get_Pos Routine aufrufe, und sie die
- Koordinaten erst beim Ersten Aufruf von Get_Pos kriegt muesst ihr das
- reservierte Langwort Old_pos mit irgendeiner Adresse fuellen.
- Ich hatte naemlich nur geschrieben
-
- Old_pos: Dc.l 0
-
- Und mein Amiga stuerzte jedesmal nach dem Druck auf die Maustaste ab.
-
- Was war passiert:
- Beim ersten Aufruf der Kill_Old Routine hat der Blitter als Destination
- fuer seine Loeschaktion die 0 als Adresse gekriegt. Und da bei 0 und $4
- sehr wichtige Daten liegen war das nicht so gut. Das Programm lief ohne
- Probs weiter. Sobald ich aber das Programm beenden wollte und auf die
- Maustaste drueckte stuerzte er ab. Ganz klar - er holte sich die Execbase
- nach A6 und sprang Openlibrary an. Da aber nicht mehr die Execbase sondern
- Irgendetwas in $4 stand, ging er daran zu grunde.
-
- Solche sachen bringen mich dann immer um denn Verstand. Ich sitze dann
- immer wie Apathisch vor der Kiste. Schreibe nach und nach alle Routinen neu
- und nicht passiert.
- Beim Essen ist es mir dann eingefallen was das schief gelaufen ist.
- So kanns gehen...
-
- Da ich wiegesagt keine Tabelle fuer die position dabei gesetzt habe,
- solltet ihr das mal selber versuchen. Es duerfte allerdings kein Problem
- fuer euch sein. Denn ihr habt das ja schon mehrmals gemacht.
- Ihr koennt auch mal versuchen die Routine auf mehrere Bobs um zu schreiben.
- Dabei werdet ihr dann auf eine Sache stossen die dem Thema Bobs einen sehr
- komplizierten Touch geben. Und wir werden uns damit sehr stark auseinander
- setzen muessen.
-
- Naja, ich will euch nicht den Mut nehmen....
-
- Schoenen Tag noch
-
- Jeff Kandle
-