home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / assembler-kurs / listings2 / listing6n.s < prev    next >
Text File  |  1977-12-31  |  10KB  |  296 lines

  1.  
  2. ; Listing6n.s    HORIZONTALTER SCROLL ÜBER MEHR ALS 16 PIXEL, UNTER
  3. ;        VERWENDUNG DES BPLCON1 UND DER BITPLANEPOINTERS -
  4. ;        RECHTE TASTE UM NACH LINKS ZU SCROLLEN
  5.  
  6.  
  7.     SECTION    CIPundCOP,CODE
  8.  
  9. Anfang:
  10.     move.l    4.w,a6        ; Execbase
  11.     jsr    -$78(a6)    ; Disable
  12.     lea    GfxName(PC),a1    ; Namen der Lib
  13.     jsr    -$198(a6)    ; OpenLibrary
  14.     move.l    d0,GfxBase    ;
  15.     move.l    d0,a6
  16.     move.l    $26(a6),OldCop    ; speichern die alte COP
  17.  
  18. ;    POINTEN AUF UNSERE BITPLANES
  19.  
  20.     MOVE.L    #PIC,d0        ; wohin pointen
  21.     LEA    BPLPOINTERS,A1    ; COP - Pointers
  22.     MOVEQ    #2,D1        ; Anzahl der Bitplanes -1 (hier sind es 3)
  23.                 ; für den DBRA - Zyklus
  24. POINTBP:
  25.     move.w    d0,6(a1)
  26.     swap    d0
  27.     move.w    d0,2(a1)
  28.     swap    d0        ;
  29.     ADD.L    #40*256,d0    ; + Länge Bitplane
  30.     addq.w    #8,a1
  31.     dbra    d1,POINTBP
  32.  
  33.     move.l    #COPPERLIST,$dff080    ; COP1LC - unsere COP
  34.     move.w    d0,$dff088        ; COPJMP1 - Starten unsere COP
  35.     move.w    #0,$dff1fc        ; FMODE - Deaktiviert das AGA
  36.     move.w    #$c00,$dff106        ; BPLCON3 - Deaktiviert das AGA
  37.  
  38. mouse:
  39.     cmpi.b    #$ff,$dff006    ; Sind wir auf Zeile 255?
  40.     bne.s    mouse
  41.     
  42.     btst    #2,$dff016    ; Rechte Taste gedrückt?
  43.     beq.s    GehLinks    ; wenn ja, geh nach links!
  44.  
  45.     bsr.w    Rechts        ; Läßt das Bild rechts scrollen, indem es
  46.                 ; das BPLCON1 und die Pointer verändert
  47.     bra.s    Warte
  48.  
  49. GehLinks:
  50.     bsr.w    Links        ; Bewegt Bild nach links
  51.  
  52. Warte:
  53.     cmpi.b    #$ff,$dff006    ; Sind wir auf Zeile 255?
  54.     beq.s    Warte        
  55.  
  56.     btst    #6,$bfe001    ; linke Maustaste gedrückt?
  57.     bne.s    mouse
  58.  
  59.     move.l    OldCop(PC),$dff080    ; COP1LC - "Zeiger" auf die Orginal-COP
  60.     move.w    d0,$dff088        ; COPJMP1 - und starten sie
  61.  
  62.     move.l    4.w,a6
  63.     jsr    -$7e(a6)    ; Enable
  64.     move.l    GfxBase(PC),a1
  65.     jsr    -$19e(a6)    ; Closelibrary 
  66.     rts
  67.  
  68.  
  69. ; DATEN
  70.  
  71.  
  72. GfxName:
  73.     dc.b    "graphics.library",0,0
  74.  
  75. GfxBase:
  76.     dc.l    0
  77.  
  78. OldCop:
  79.     dc.l    0
  80.  
  81.  
  82. ; Diese Routine läßt das Bild nach Rechts scrollen, sie verwendet dazu das
  83. ; BPLCON1 und die Bitplanepointers in der Copperlist. MEINBPCON1 ist
  84. ; das Byte des BPLCON1.
  85.  
  86. Rechts:
  87.     CMP.B    #$ff,MEINBPCON1    ; sind wir bei maximalen Scroll angelangt (15)?
  88.     BNE.s    CON1ADDA    ; wenn nicht, weiter um ein weiteres
  89.  
  90.     LEA    BPLPOINTERS,A1    ; Mit diesen 4 Anweisungen holen wir aus der
  91.     move.w    2(a1),d0    ; Copperlist die Adresse, wohin das $dff0e0
  92.     swap    d0        ; gerade pointet und geben diesen Wert
  93.     move.w    6(a1),d0    ; in d0
  94.  
  95.     subq.l    #2,d0       ; pointet 16 Bit weiter nach hinten, das Bild
  96.                ; scrollt um 16 Pixel nach Rechts
  97.     clr.b    MEINBPCON1 ; löscht den Hardwarescroll des BPLCON1 ($dff102)
  98.                ; denn wir haben 16 Pixel schon mit den Bitplane-
  99.                ; Pointers "übersprungen", wir müssen wieder bei
  100.                ; NULL beginnen, um mit dem $dff102 um jeweils
  101.                ; 1 Pixel nach rechts zu gehen.
  102.  
  103.     LEA    BPLPOINTERS,A1    ; Pointer in der COPPERLIST
  104.     MOVEQ    #2,D1        ; Anzahl der Bitplanes -1 (hier sind es 3)
  105.  
  106. POINTBP2:
  107.     move.w    d0,6(a1)    ; kopiert das niederw. Word der Adress des Plane
  108.     swap    d0        ; vertauscht die 2 Word von d0 (z.B.: 1234 > 3412)
  109.     move.w    d0,2(a1)    ; kopiert das höherw. Word der Adresse des Plane
  110.     swap    d0        ; vertauscht die 2 Word von d0 (3412 > 1234)
  111.     ADD.L    #40*256,d0  ; + Länge Bitplane -> nächstes Bitplane
  112.     addq.w    #8,a1        ; zu den nächsten bplpointers in der Cop
  113.     dbra    d1,POINTBP2 ; Wiederhole D1 Mal POINTBP (D1=num of bitplanes)
  114.     rts
  115.  
  116. CON1ADDA:
  117.     add.b    #$11,MEINBPCON1 ; scrolle ein Pixel nach vorne
  118.     rts
  119.  
  120. ;    Routine, die nach Links scrollt, identisch mit der vorherigen:
  121.  
  122. LINKS:
  123.     TST.B    MEINBPCON1    ; sind wir bei minimalen Scroll angelangt (00)?
  124.     BNE.s    CON1SUBBA     ; wenn nicht, zurück um ein weiteres
  125.  
  126.     LEA    BPLPOINTERS,A1    ; Mit diesen 4 Anweisungen holen wir aus der
  127.     move.w    2(a1),d0    ; Copperlist die Adresse, wohin das $dff0e0
  128.     swap    d0        ; gerade pointet und geben diesen Wert
  129.     move.w    6(a1),d0    ; in d0
  130.     
  131.     addq.l    #2,d0        ; pointet 16 Bit weiter nach vorne, das Bild
  132.                 ; scrollt um 16 Pixel nach Links
  133.     move.b    #$FF,MEINBPCON1    ; Hardwarescroll auf 00 (BPLCON1, $dff102)
  134.  
  135.  
  136.     LEA    BPLPOINTERS,A1    ; Pointer in der COPPERLIST
  137.     MOVEQ    #2,D1        ; Anzahl der Bitplanes -1 (hier sind es 3)
  138. POINTBP3:
  139.     move.w    d0,6(a1)    ; kopiert das niederw. Word der Adress des Plane
  140.     swap    d0        ; vertauscht die 2 Word von d0 (z.B.: 1234 > 3412)
  141.     move.w    d0,2(a1)    ; kopiert das höherw. Word der Adresse des Plane
  142.     swap    d0        ; vertauscht die 2 Word von d0 (3412 > 1234)
  143.     ADD.L    #40*256,d0  ; + Länge Bitplane -> nächstes Bitplane
  144.     addq.w    #8,a1        ; zu den nächsten bplpointers in der Cop
  145.     dbra    d1,POINTBP3 ; Wiederhole D1 Mal POINTBP (D1=num of bitplanes)
  146.     rts
  147.  
  148. CON1SUBBA:
  149.     sub.b    #$11,MEINBPCON1 ; scrolle ein Pixel nach hinten
  150.     rts
  151.  
  152.  
  153.  
  154.     SECTION GRAPHIC,DATA_C
  155.  
  156. COPPERLIST:
  157.     dc.w    $120,$0000,$122,$0000,$124,$0000,$126,$0000,$128,$0000 ; SPRITE
  158.     dc.w    $12a,$0000,$12c,$0000,$12e,$0000,$130,$0000,$132,$0000
  159.     dc.w    $134,$0000,$136,$0000,$138,$0000,$13a,$0000,$13c,$0000
  160.     dc.w    $13e,$0000
  161.  
  162.     dc.w    $8E,$2c81    ; DiwStrt (Register mit Normalwerten)
  163.     dc.w    $90,$2cc1    ; DiwStop
  164.     dc.w    $92,$0038    ; DdfStart
  165.     dc.w    $94,$00d0    ; DdfStop
  166.     dc.w    $102        ; BplCon1
  167.     dc.b    0          ; hochwertiges Byte des $dff102, nicht verwendet
  168. MEINBPCON1:
  169.     dc.b    0        ; niederwertiges Byte des $dff102, verwendet
  170.     dc.w    $104,0        ; BplCon2
  171.     dc.w    $108,0        ; Bpl1Mod
  172.     dc.w    $10a,0        ; Bpl2Mod
  173.     
  174.             ; 5432109876543210
  175.     dc.w    $100,%0011001000000000  ; Bits 12 +13 an! (3 = %011)
  176.  
  177. BPLPOINTERS:
  178.     dc.w $e0,$0000,$e2,$0000    ;erstes  Bitplane
  179.     dc.w $e4,$0000,$e6,$0000    ;zweites Bitplane
  180.     dc.w $e8,$0000,$ea,$0000    ;drittes Bitplane
  181.  
  182.     dc.w    $0180,$000    ; Color0
  183.     dc.w    $0182,$475    ; Color1
  184.     dc.w    $0184,$fff    ; Color2
  185.     dc.w    $0186,$ccc    ; Color3
  186.     dc.w    $0188,$999    ; Color4
  187.     dc.w    $018a,$232    ; Color5
  188.     dc.w    $018c,$777    ; Color6
  189.     dc.w    $018e,$444    ; Color7
  190.  
  191.     dc.w    $FFFF,$FFFE    ; Ende der Copperlist
  192.     
  193.     dcb.b    80*40,0 ; auf NULL gesetzter Speicher vor dem Bitplane
  194.  
  195. PIC:
  196.     incbin    "amiga.320*256*3"    ; hier laden wir das Bild in RAW
  197.  
  198.     dcb.b    40,0            ; siehe oben
  199.  
  200.  
  201.     end
  202.  
  203. Furchtbar,  der  "Wackelkontakt" beim linken Rand des Monitors, gell?? Ihn
  204. zu  eliminieren  ist  nicht  schwierig,  einfach  zwei  Kleinigkeiten
  205. austauschen, schauen wir was und warum: das Warum ist darin zu suchen, daß
  206. die DMA-Kanäle nicht über die Bewegung des Bildes informiert sind und  sie
  207. somit unvorbereitet sind, und so nicht die Zeit haben, die ersten 16 Pixel
  208. ganz Links zu lesen. Was können wir dagegen tun? Nichts.
  209. Aber  wir  können  dieses  Mißgeschick  außerhalb  des  sichtbaren  Feldes
  210. ablaufen  lassen,  erinnert ihr euch an die Kollegen DIWSTART und DIWSTOP?
  211. Sie bestimmen die Größe des Bildschirmes,  auf  dem  die  Daten  angezeigt
  212. werden.  Es leuchtet ein, daß wenn wir das Videofenster um 16 Pixel weiter
  213. rechts starten lassen, das Problem "zugestopft" wird:
  214.  
  215.     dc.w    $8E,$2c91    ; DiwStrt ($81+16=$91)
  216.  
  217. Tauscht den Wert aus und startet erneut das Listing. Auch wenn wir  dieses
  218. Problem  beseitigt haben, jetzt tritt ein weiteres auf: wir haben nur mehr
  219. 304 Pixel zur Verfügung, und nicht mehr 320. Und dann ist alles auch  noch
  220. verschoben!!  Aber  die  Register DDFSTART und DDFSTOP eilen uns zu Hilfe!
  221. Diese Register kümmern sich um  die  Größe  des  Videofensters,  aber  auf
  222. andere  Art  und  Weise. Während das DIWSTART/STOP wie ein schwarzes Stück
  223. Papier ist, dessen rechteckigen Ausschnitt  wir  in  Dimension  und  Größe
  224. ändern können, wie das Bild unten zeigt,
  225.  
  226.  
  227.     #####################
  228.     #####################
  229.     #####        #####
  230.     #####    Bild    #####
  231.     #####        #####
  232.     #####        #####
  233.     #####        #####
  234.     #####        #####
  235.     #####        #####
  236.     #####################
  237.     #####################
  238.  
  239. ist das DDFSTART/STOP anders: damit verändern wir wirklich die Länge einer
  240. Videozeile;  wenn wir z.B. den Bildschirm um 16 Pixel verbreitern, und ihn
  241. somit 336 Pixel pro Zeile groß werden lassen,  also  42  Bytes  pro  Zeile
  242. statt  40,  dann  müssen  wir wirklich 42 Bytes pro Zeile verarbeiten. Der
  243. OVERSCAN-MODUS,  der  über  die  üblichen  320x256  bzw.  640x256  Pixel
  244. hinausreicht,  wird  genau  mit den DDFSTART und DDFSTOP erreicht, ohne zu
  245. vergessen, das Videofenster mit den DIWSTART und DIWSTOP zu "vergrößern".
  246.  
  247. Zurück  zu  unserem Problem: wir müssen zusehen, daß dieser Fehler, der 16
  248. Pixel breit ist, außerhalb unseres Sichtfeldes stattfindet. Wir müssen mit
  249. dem  DDFSTART  das Bild um 16 Pixel weiter rechts beginnen lassen, und ihn
  250. bei der selben Position enden lassen, und die  Werte  in  DIWSTART/DIWSTOP
  251. gleich  lassen.  Damit  werden  wir  immer  320x256  Pixel sehen, aber das
  252. Videofenster ist in Wirklichkeit 336 Pixel breit,  und  der  Fehler  tritt
  253. außerhalb  des  Bildschirmes  auf. Das Bild wird somit aber 42 Byte breit,
  254. und das müssen wir diese 2 Bytes ( 16 Pixel) für jede  Zeile  im  Programm
  255. ausgleichen.
  256. Wie schaffen wir es, bei Ende der Zeile (jetzt bei Byte  42)  um  2  Bytes
  257. zurückzugehen,  um  die Zeile korrekt anzuzeigen? Kurzum, daß die Rechnung
  258. aufgeht? Indem wie dem Modulo 2 abziehen. In unserem Fall, mit dem  Modulo
  259. auf NULL, einfach auf -2 setzen.
  260. Um den Bildschirm 16 Pixel  früher  starten  zu  lassen,  müssen  folgende
  261. Änderungen im DATA FETCH START (DDFSTART) vorgenommen werden:
  262.  
  263.  
  264.     dc.w    $92,$30        ; DDFSTART = $30 (Bildschirm startet
  265.                 ; 16 Pixel früher, er verbreitert sich
  266.                 ; also auf 42 Bytes pro Zeile, 336 Pixel
  267.                 ; Breite, aber das DIWSTART "versteckt"
  268.                 ; diese ersten 16 Pixel mit dem Fehler.
  269.  
  270.  
  271.     dc.w    $108,-2        ; MODULA = -2, wir müssen die ersten
  272.     dc.w    $10a,-2        ; 16 Pixel "überspringen", indem wir
  273.                 ; sie zwei Mal lesen lassen
  274.  
  275.  
  276. Bringt diese Änderungen an und stellt das DIWSTART wieder her:
  277.  
  278.     dc.w $8E,$2c81 ; DiwStrt
  279.  
  280. Jetzt  ist  der  Scroll PERFEKT. Einzig und allein ist jetzt der Nachteil,
  281. daß mit  vergrößern  des  Videofensters  der  Sprite7,  also  der  letzte,
  282. verschwindet.
  283.  
  284. P.S.:  Wenn ihr ein bißchen spionieren wollt, was der Fehler außerhalb des
  285. Bildes tut, und ob er noch existiert, lasst das DIWSTART 16  Pixel  früher
  286. starten:
  287.  
  288.     dc.w    $8E,$2c71    ; DiwStrt
  289.  
  290. Der ist immer noch da!!!!! Aber jetzt sieht ihn niemand.
  291.  
  292. Habt ihr gesehen, es war doch ein Kinderspiel, diesen Fehler aus der  Welt
  293. zu  schaffen.  Einfach  das DDFSTART um 16 Pixel (bei $30) beginnen lassen
  294. und 2 von den MODULA abziehen.
  295.  
  296.