home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / Asm-Course2.lha / Teil19.TXT < prev    next >
Encoding:
Text File  |  1993-09-01  |  11.9 KB  |  325 lines

  1.           A S S E M B L E R - K U R S       (c)  Jeff Kandle 1990
  2.  
  3.                                 19.Teil...
  4.  
  5. Nun denn, jetzt kommen die vorbereitenden Sachen zur Laufschrift.
  6. Wir haetten das auch schon viel frueher machen koennen, mit dem Rol oder
  7. Asl befehl...Aber das ist echt Arbeit. Und mit dem Blitter ist es ein
  8. Klacks einen Text ueber den Screen zu scrollen.
  9. Kommen wir nun zu einer moeglichkeit die uns der Blitter bietet, und die
  10. wir fuer Laufschriften sehr gut gebrauchen koennen. Aber erstmal will ich
  11. es ohne erklaeren, dann erkennt ihr den Nutzen wirklich.
  12.  
  13. 18.Realisation einer Laufschrift mit Hilfe des Blitters
  14.  
  15. Also wie sieht eine Laufschrift den theoretisch aus.
  16.  
  17. ...Ein Buchstabe wird auf den Bildschirm geschrieben. Er wird stetig nach
  18. Links verschoben, auf den Linken rand zu. Sobald neben ihm Platz fuer einen
  19. neuen ist, wird der naechste Buchstaben dargestellt. Das geht immer weiter
  20. so..Sobald einer der Buchstaben den linken rand erreicht hat, wird er immer
  21. mehr herrausgeschoben, bis er nicht mehr zu sehen ist. So einfach ist das.
  22.  
  23. Damit die Buchstaben sich aber nicht ruckartig weiterbewegen, mueesen wir
  24. erstmal softscrolling mit dem Blitter verstehen und anwenden.
  25. Denn Hardscrolling hiess mit dem Blitter immer 16 Pixel weiter, weil er ja
  26. als kleinste Einheit, nur das Wort kennt. Und das waere ja ein bisschen
  27. viel, gell ?
  28.  
  29. Zum Glueck haben die Erbauer des Blitter uns da etwas eingebaut was uns
  30. dabei hilft.
  31.  
  32. Der Blitter ist in der Lage, die von Quelle A oder B kommenden Daten Pixel-
  33. weise zu verschieben, und verschoben zu schreiben. Man muss ihm den wert
  34. nur in eines der Kontrollworte BLTCON0 oder BLTCON1 zu schreiben. Dann wird
  35. der Wert beim lesen verschoben und dann in das Ziel geschrieben.
  36.  
  37. Den Verschiebungswert fuer die Quelle A, schreiben wir in die obersten 4
  38. Bits des BLTCON0 registers. Den Verschiebungswert fuer die Quelle B,
  39. schreiben wir in die obersten 4 Bit des BLTCON1 registers.
  40.  
  41. Man setzt die anzahl der Pixels die nach rechts geschoben werden soll in
  42. das register, mit dessen Quelle wir Arbeiten. Ich nehme bei einfachen
  43. sachen sowieso immer A, also bleiben wir dabei.
  44.  
  45. Verschieben ist allerdings nicht das richtige Wort fuer die Sache. Es
  46. muesste eigentlich `Rotieren` heissen. Denn was rechts rausfaellt, wird
  47. links wieder reingesetzt.
  48.  
  49. Es gibt allerdings noch andere Probleme. Wie gesagt, man gibt den Wert der
  50. Pixelverschiebung nach rechts an. Aber so eine Laufschrift laeuft aber
  51. immer von Rechts nach Links...Es sei den wir Schreiben in Arabisches intro,
  52. aber das wollen wir ja nicht, oder. Wie kriegen wir also ein Verschiebung
  53. nach links hin. Es ist nicht schwer, aber ihr muesst jetzt genau lesen.
  54.  
  55. Eine verschiebung um einen Pixel nach links, ist moeglich wenn wir als
  56. verschiebungs wert 15 eingeben, und als  Ziel 1 Wort vorher Waehlen.
  57.  
  58. Bildlich...
  59.  
  60.  
  61.    1 Wort           2 Wort         3 Wort
  62. I               I              I
  63. 00000000000000001111111111111110000000000000000
  64.  
  65. Wenn wir nun die ganzen Einsen, eins nach Links kopieren wollen, kopieren
  66. wir einfach alles in das Erste wort.
  67.  
  68.  
  69.    1 Wort           2 Wort         3 Wort
  70. I               I              I
  71. 11111111111111110000000000000000000000000000000
  72.  
  73. Und jetzt verschieben wir es einfach 15 Pixel nach rechts..
  74.  
  75.    1 Wort           2 Wort         3 Wort
  76. I               I              I
  77. 0000000000000001111111111111110000000000000000
  78.  
  79. Das ist dasselbe als wenn wir es direkt eins nach links schieben, oder ?
  80.  
  81. Wenn wir also einen Teil des Bildschirms Softscrollen wollen, muessen wir
  82. einfach das gesamte rechteck ein Wort frueher wieder hinschreiben und die
  83. Verschiebung auf 15 Pixel stellen.
  84.  
  85. Allerdings muessen wir noch einen Sicherheits bereich erschaffen, in dem
  86. die sachen die Links rausfallen wieder reingeschoben werden koennen ohne
  87. das sie auf dem Bildschirm sichtbar werden. Dazu koennen wir wieder die
  88. Modulowerte der Bitplanes gebrauchen. Mit ihnen koennen wir uns diesen
  89. bereich schaffen. Normalerweise waehlt man die groesse eines Buchstaben als
  90. sicherheits abstand. Gehen wir mal von einen 16*16 Zeichensatz aus, das
  91. saehe dann ungefaehr so aus.
  92.  
  93. I                                          I    I
  94. I  Normaler Sichtbarer                     I    I  Sicherheitsbereich
  95. I  Bildschirm                              I    I /
  96. I                                          I    I/
  97. I                                          I    /
  98. I                                          I   /I
  99. I                                          I  / I
  100. I                                          I    I
  101. I                                          I    I
  102.  
  103. Bei dem erwaehnten 16 mal 16 Font, muessten wir also Modulowert 2, fuer
  104. zwei Bytes eingeben, dann haetten wir die Zone erstellt.
  105. Hier koennen dann die Truemmer von Links hereingeschoben werden. Sobald
  106. aber der Buchstabe den ich waehrend des Scrollens dort rausgeschoben habe,
  107. ich setzte die Buchstaben ebenfalls in diese Zone, damit sie in den
  108. Bildschirm hereingeschoben werden, muss ich allerdings direkt den neuen
  109. dort reinsetzen, da sonst der muell von eben zwischen den buchstaben
  110. landet, und das wollen wir ja nicht.
  111.  
  112. Wie muss ich jetzt diese beiden bereiche verwalten ?
  113. Der gesamte rechteckige bereich ist samt Sicherheitszone 21*17 Worte gross.
  114. Eine Zeile muss ich oben auch als Sicherheitszone eingeben.
  115.  
  116. Zuerst muessen wir uns mal um die routine Kuemmern die den ganzen bereich
  117. verschiebt. Wenn wir davon ausgehen das die Plane bei $40000 anfaengt saehe
  118. das dann so aus.
  119.  
  120.         Move.w #$ffff,BLTAFWM           ; Masken setzen
  121.         Move.w #$ffff,BLTALWM
  122.         Move.w #$0000,BLTAMOD           ; Modulowerte noch nicht von
  123.                                         ; bedeutung
  124.         Move.w #$0000,BLTDMOD
  125.         Move.w #%1111100111110000,BLTCON0
  126.                                         ; Quelle und Ziel festlegen, und
  127.                                         ; Verschiebungswert fuer A angeben
  128.         Move.l #$40000,BLTAPT           ; Quelle Normal
  129.         Move.l #$3fffe,BLTDPT           ; Ziel 2 Bytes frueher
  130.         Move.w #21*64+17,BLTSIZE        ; Groesse und LOS!
  131.  
  132. Ich schreibe die WaitBlitter routine und das RTS nicht mehr dabei. Es
  133. muesste jedem klar sein das das kommen muss wenn man die Routine selbst
  134. benutzt.
  135.  
  136. So mit der Routine haetten wir alles um einen Pixel nach Links gesetzt.
  137.  
  138. Sobald das aber 16 mal passiert ist, muss der Puffer wieder mit dem
  139. Naechsten zeichen gefuellt werden, damit wenn wir weiterschieben der neue
  140. Buchstabe reingeschoben werden kann.
  141. Das Aussehen des Buchstaben koennen wir im Source unterbringen, mit der
  142. DC.w anweisung geht das ziemlich einfach.
  143.  
  144. Jetzt kommen auch die Modulo werte des Blitter auf die Buehne. Wenn ich das
  145. aussehen nun in den Puffer kopiere, kann die Quelle ohne Modulowert sein,
  146. weil die Daten ja alle hintereinander liegen. Aber in der Quelle kann ich
  147. sie nicht hintereinander schreiben, sonst wuerden wir sie ja auf den
  148. bildschirm setzen. Wir muessen also gucken wo die Linke obere Ecke der
  149. Sicherheitszone ist, als Breite die Breite des Puffers angeben, und als
  150. Modulo wert fuer das Ziel, die Breite des Sichtbaren bereiches angeben,
  151. damit wenn eine Zeile des neuen Buchstaben geschrieben ist, der anfang der
  152. Zeile, der ja sichtbar ist, uebersprungen wird, und erst weitergeschrieben
  153. wird wenn der Puffer wieder erreicht ist. Das saehe dann so aus...
  154.  
  155.         Move.w #$ffff,BLTAFWM           ; Immer noch keine Maske
  156.         Move.w #$ffff,BLTALWM
  157.         Move.w #$0000,BLTAMOD           ; Modulo A ist null
  158.         Move.w #$0028,BLTDMOD           ; Modulo D ist 40 ($28)
  159.         Move.w #%0000100111110000,BLTCON0
  160.                                         ; Keine Verschiebung, A und D an
  161.         Move.l #Definiton im Source,BLTAPT
  162.         Move.l #$40028,BLTDPT           ; Linke obere Ecke des Puffers
  163.         Move.w #1*64+16,BLTSIZE         ; Groesse und los...
  164.  
  165. Das waren die beiden Wichtigsten routinen die der Blitter bei der
  166. Programmierung einer Laufschrift ausfuehren muss.
  167.  
  168. Das schwierige an einer laufschrift ist die verwaltung der Buchstaben
  169. definitionen, und das setzen der neue Buchstaben, die auswahl der
  170. richtigen Buchstaben anhand eines Ascii wertes und so weiter...
  171.  
  172. Schreiben wir aber erstmal ein Prograemmchen das einen bestimmten bereich
  173. immer weiter nach links Scrollt, und wenn ein zeichen draussen ist, ein
  174. neues reinsetzt...
  175.  
  176. Dort setze ich diese beiden routinen ein....Achtet aber mehr auf die art
  177. und weise wie ich auf den Zeitpunkt warte an dem ich den Puffer mit dem
  178. Neuen zeichen fuellen muss...
  179.  
  180. Hier das Listing..
  181.  
  182. Execbase=       4
  183. Openlibrary=    -408
  184. Vhposr=         $dff006
  185. Forbid=         -30-102
  186. Permit=         -30-108
  187. Bltafwm=        $dff044
  188. Bltalwm=        $dff046
  189. Bltcon0=        $dff040
  190. Bltcon1=        $dff042
  191. Bltamod=        $dff064
  192. Bltdmod=        $dff066
  193. Bltapt=         $dff050
  194. Bltdpt=         $dff054
  195. Dmacon=         $dff096
  196. Intena=         $dff09a
  197. Dmaconr=        $dff002
  198. Bltsize=        $dff058
  199.  
  200.  
  201.         Move.w  #$0020,dmacon
  202.         Move.w  #$4000,intena
  203.         Move.l  execbase,a6
  204.         Jsr     forbid(a6)
  205.  
  206.  
  207.         Move.l  #$40000,a0
  208.         Move.l  #$2800/4,d0
  209. clearloop:
  210.         Move.l  #0,(a0)+
  211.         Dbf     d0,clearloop
  212.  
  213.         Bsr.l   Set_letter
  214.         Bsr.l   Makecl
  215.  
  216. Wait:
  217.         Cmpi.b  #$80,vhposr
  218.         Bne.s   Wait
  219.         Bsr.l   Scroll
  220.         Sub.w   #1,Lettercount
  221.         Bne.s   Weiter
  222.         Bsr.l   Set_letter
  223. Weiter: Btst    #6,$bfe001
  224.         Bne     Wait
  225.  
  226.         Move.l  Execbase,a6
  227.         Jsr     Permit(a6)
  228.         Lea     Gfxname(pc),a1
  229.         Jsr     Openlibrary(a6)
  230.         Move.l  d0,a6
  231.         Move.w  #$83e0,dmacon
  232.         Move.w  #$c000,intena
  233.         Move.l  38(a6),$dff080
  234.         Moveq   #0,d0
  235.         Rts
  236. Makecl:
  237.         Lea     $05f000,a0
  238.         Move.l  a0,$dff080
  239.  
  240.         Move.l  #$00e00004,(a0)+
  241.         Move.l  #$00e20000,(a0)+
  242.         Move.l  #$008e3081,(a0)+
  243.         Move.l  #$009030c1,(a0)+
  244.         Move.l  #$00920038,(a0)+
  245.         Move.l  #$009400d0,(a0)+
  246.         Move.l  #$01001200,(a0)+
  247.         Move.l  #$01080002,(a0)+
  248.         Move.l  #$01800000,(a0)+
  249.         Move.l  #$018200ff,(a0)+
  250.         Move.l  #$fffffffe,(a0)+
  251.         Rts
  252.  
  253. Waitblit:
  254.         Btst    #6,dmaconr
  255.         Bne.s   Waitblit
  256.         Rts
  257.  
  258. Set_lettEr:
  259.         Bsr.s   Waitblit
  260.         Move.w  #$ffff,bltafwm
  261.         Move.w  #$ffff,bltalwm
  262.         Move.w  #%0000100111110000,bltcon0
  263.         Move.w  #0,bltamod
  264.         Move.w  #40,bltdmod
  265.         Move.l  #Smiledefi,bltapt
  266.         Move.l  #$40028,bltdpt
  267.         Move.w  #15*64+1,bltsize
  268.         Move.w  #$10,lettercount
  269.         Rts
  270. Scroll:
  271.         Bsr.s   Waitblit
  272.         Move.w  #$ffff,bltafwm
  273.         Move.w  #$ffff,bltalwm
  274.         Move.w  #%1111100111110000,bltcon0
  275.         Move.w  #0,bltamod
  276.         Move.w  #0,bltdmod
  277.         Move.l  #$40000,bltapt
  278.         Move.l  #$3fffe,bltdpt
  279.         Move.w  #16*64+21,bltsize
  280.         Rts
  281.  
  282. Gfxname:        dc.b "graphics.library",0
  283.  
  284. even
  285.  
  286. Lettercount: dc.w 0
  287.  
  288. Smiledefi:
  289.  
  290. dc.w %0000111111110000
  291. dc.w %0011000000001100
  292. dc.w %0100000000000010
  293. dc.w %0100000000000010
  294. dc.w %1001110000111001
  295. dc.w %1001010000101001
  296. dc.w %1001110110111001
  297. dc.w %1000000110000001
  298. dc.w %1000001111000001
  299. dc.w %1000000110000001
  300. dc.w %1001100000011001
  301. dc.w %0100011111100010
  302. dc.w %0100000000000010
  303. dc.w %0011000000001100
  304. dc.w %0000111111110000
  305.  
  306.  
  307. So, kurz mal zu der Routine die den Zeitpunkt fuer das Neu-Fuellen des
  308. Puffers bestimmt. Sie Arbeitet sehr einfach...Bevor ich in die
  309. Endlosschleife springe, setze ich das Zeichen schon einmal in den Puffer.
  310. Gleichzeitg mit diesem Aufruf wird das Wort Lettercount auf 16 gesetzt.
  311. Sobald ich mit der Endlosschleife die Zeile $80 erreicht habe, wird der
  312. Bereich einmal nach links geSoftscrollt. Dann wird der Zaehler in
  313. Lettercount eins runtergesetzt, war das ergebnis nicht null, sind die 16
  314. noch nicht abgezaehlt und er springt direkt zur mausabfrage, und von da
  315. wieder in die Endlosschleife. Sobald die 0 aber erreicht ist, verzweigt der
  316. bne befehl nicht und arbeitet weiter. Nach dem Bne befehl steht dann der
  317. Aufruf der PufferFuellroutine, sie setzt auch den Zaehler in lettercount
  318. wieder auf 16.
  319.  
  320. Wie ihr seht, ist es alles sehr einfach...
  321.  
  322. Viel Spass beim Expirientieren...
  323.  
  324.                 Jeff Kandle
  325.