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

  1.  
  2. ; Listing7t2.s    Langsame Sterne
  3.  
  4. ;    In diesem Listing machen wir einen Sternenhimmel,
  5. ;    der sich jedoch in 1-Pixel-Schritten bewegt
  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    ; Name lib
  13.     jsr    -$198(a6)    ; OpenLibrary
  14.     move.l    d0,GfxBase
  15.     move.l    d0,a6
  16.     move.l    $26(a6),OldCop
  17.  
  18.  
  19.     MOVE.L    #BITPLANE,d0
  20.     LEA    BPLPOINTERS,A1
  21.     move.w    d0,6(a1)
  22.     swap    d0
  23.     move.w    d0,2(a1)
  24.  
  25. ;    Pointen auf die Sprites
  26.  
  27.     MOVE.L    #SPRITE,d0        ; Adresse des Sprite in d0
  28.     LEA    SpritePointers,a1    ; Pointer in der Copperlist
  29.     move.w    d0,6(a1)
  30.     swap    d0
  31.     move.w    d0,2(a1)
  32.  
  33.     move.l    #COPPERLIST,$dff080    ; unsere COP
  34.     move.w    d0,$dff088        ; START COP
  35.     move.w    #0,$dff1fc        ; NO AGA!
  36.     move.w    #$c00,$dff106        ; NO AGA!
  37.  
  38. mouse:
  39.     cmpi.b    #$ff,$dff006    ; Zeile 255?
  40.     bne.s    mouse
  41.  
  42.     bsr.s    BewegeSterne    ; diese Routine bewegt die Sterne
  43.  
  44. Warte:
  45.     cmpi.b    #$ff,$dff006    ; Zeile 255?
  46.     beq.s    Warte
  47.  
  48.     btst    #6,$bfe001    ; Maus gedrückt?
  49.     bne.s    mouse
  50.  
  51.     move.l    OldCop(PC),$dff080    ; Pointen auf die SystemCOP
  52.     move.w    d0,$dff088        ; starten die alte COP
  53.  
  54.     move.l    4.w,a6
  55.     jsr    -$7e(a6)    ; Enable
  56.     move.l    gfxbase(PC),a1
  57.     jsr    -$19e(a6)    ; Closelibrary
  58.     rts
  59.  
  60. ;    Daten
  61.  
  62. GfxName:
  63.     dc.b    "graphics.library",0,0
  64.  
  65. GfxBase:
  66.     dc.l    0
  67.  
  68. OldCop:
  69.     dc.l    0
  70.  
  71. ; Diese einfache Routine läßt den Sprite weitergehen, der die Sterne
  72. ; darstellt. Er agiert auf jedes HSTART mit dem STERNEN_LOOP
  73.  
  74. BewegeSterne:
  75.     lea    Sprite,A0        ; a0 pointet auf den Sprite
  76. STERNEN_LOOP:
  77.     CMPI.B    #$f0,1(A0)        ; hat der Stern den rechten Rand
  78.                     ; des Bildschirmes erreicht?
  79.     BNE.S    nicht_Rand        ; nicht, dann überspringe
  80.     MOVE.B    #$30,1(A0)        ; ja, setze den Stern nach links
  81. nicht_Rand:
  82.     BCHG    #0,3(A0)        ; agiere auf das Byte VHBITS
  83.     BEQ.S    Gerade
  84.     ADDQ.B    #$1,1(A0)        ; bewege den Sprite um 2 Pixel
  85. Gerade:
  86.     ADDQ.w    #8,A0            ; nächster Stern
  87.     CMP.L    #SpriteEnd,A0        ; haben wir das Ende erreicht?
  88.     BLO.S    STERNEN_Loop        ; wenn nicht, wiederhole den Loop
  89.     RTS                ; Ende Routine
  90.  
  91.  
  92.     SECTION GRAPHIC,DATA_C
  93.  
  94. COPPERLIST:
  95. SpritePointers:
  96.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  97.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  98.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  99.     dc.w    $13e,0
  100.  
  101.     dc.w    $8E,$2c81    ; DiwStrt
  102.     dc.w    $90,$2cc1    ; DiwStop
  103.  
  104.     dc.w    $92,$38        ; DdfStart
  105.     dc.w    $94,$d0        ; DdfStop
  106.     dc.w    $102,0        ; BplCon1
  107.     dc.w    $104,0        ; BplCon2
  108.     dc.w    $108,0        ; Bpl1Mod
  109.     dc.w    $10a,0        ; Bpl2Mod
  110.  
  111.     dc.w    $100,%0001001000000000    ; Bit 12 an!! 1 Bitplane Lowres
  112.  
  113. BPLPOINTERS:
  114.     dc.w $e0,0,$e2,0    ;erstes    Bitplane
  115.  
  116.     dc.w    $180,$000    ; Color0    ; Hintergrund Schwarz
  117.     dc.w    $182,$123    ; Color1    ; Farbe 1 des Bitplane, die
  118.                         ; in diesem Fall leer ist,
  119.                         ; und deswegen nicht erscheint
  120.  
  121. ; der Sprite verwendet nur eine Farbe, COLOR17
  122.  
  123.     dc.w    $1A2,$ddd    ; COLOR17, - COLOR1 deso Sprite0 - weiß
  124.  
  125.     dc.w    $FFFF,$FFFE    ; Ende der Copperlist
  126.  
  127. ;    -    -    -    -    -    -    -
  128.  
  129. ; Wie ihr sehen könnt wurde dieser Sprite ganz schön oft wiederverwendet,
  130. ; um genau zu sein 127 Mal. Er besteht aus vielen Word-Kontrollpaaren, die
  131. ; von einem $1000,$0000 gefolgt werden, also den Daten, die einen einzelnen
  132. ; Stern ergeben. Die vertikalen Positionen gehen in Zweierschritten, es gibt
  133. ; also einen Stern alle zwei vertikalen Zeilen, bei einer immer anderen
  134. ; horizontalen Position. Die erste Wiederverwertung des Sprite ist
  135. ; $307a,$3100,$1000,$0000
  136. ; die zweite $3220,$3300,$1000,$0000
  137. ; und so weiter. Die verschiedenen VSTART gehen in Schritten zu 2, also $30,
  138. ; $32, $34, $36 ...
  139. ; Die HSTART sind zufällig positioniert ($7a, $20, $c0, $50,...)
  140. ; Die VSTOP befinden sich natürlich eine Zeile nach VSTART ($31, $33, $35,...),
  141. ; da die Sterne ja 1 Pixel hoch sind.
  142. ; Die Routine agiert bei jedem Fotogramm auf alle HSTART, und verstellt
  143. ; somit die Sterne nach vorne.
  144.  
  145. Sprite:
  146.     dc.w    $307A,$3100,$1000,$0000,$3220,$3300,$1000,$0000
  147.     dc.w    $34C0,$3500,$1000,$0000,$3650,$3700,$1000,$0000
  148.     dc.w    $3842,$3900,$1000,$0000,$3A6D,$3B00,$1000,$0000
  149.     dc.w    $3CA2,$3D00,$1000,$0000,$3E9C,$3F00,$1000,$0000
  150.     dc.w    $40DA,$4100,$1000,$0000,$4243,$4300,$1000,$0000
  151.     dc.w    $445A,$4500,$1000,$0000,$4615,$4700,$1000,$0000
  152.     dc.w    $4845,$4900,$1000,$0000,$4A68,$4B00,$1000,$0000
  153.     dc.w    $4CB8,$4D00,$1000,$0000,$4EB4,$4F00,$1000,$0000
  154.     dc.w    $5082,$5100,$1000,$0000,$5292,$5300,$1000,$0000
  155.     dc.w    $54D0,$5500,$1000,$0000,$56D3,$5700,$1000,$0000
  156.     dc.w    $58F0,$5900,$1000,$0000,$5A6A,$5B00,$1000,$0000
  157.     dc.w    $5CA5,$5D00,$1000,$0000,$5E46,$5F00,$1000,$0000
  158.     dc.w    $606A,$6100,$1000,$0000,$62A0,$6300,$1000,$0000
  159.     dc.w    $64D7,$6500,$1000,$0000,$667C,$6700,$1000,$0000
  160.     dc.w    $68C4,$6900,$1000,$0000,$6AC0,$6B00,$1000,$0000
  161.     dc.w    $6C4A,$6D00,$1000,$0000,$6EDA,$6F00,$1000,$0000
  162.     dc.w    $70D7,$7100,$1000,$0000,$7243,$7300,$1000,$0000
  163.     dc.w    $74A2,$7500,$1000,$0000,$7699,$7700,$1000,$0000
  164.     dc.w    $7872,$7900,$1000,$0000,$7A77,$7B00,$1000,$0000
  165.     dc.w    $7CC2,$7D00,$1000,$0000,$7E56,$7F00,$1000,$0000
  166.     dc.w    $805A,$8100,$1000,$0000,$82CC,$8300,$1000,$0000
  167.     dc.w    $848F,$8500,$1000,$0000,$8688,$8700,$1000,$0000
  168.     dc.w    $88B9,$8900,$1000,$0000,$8AAF,$8B00,$1000,$0000
  169.     dc.w    $8C48,$8D00,$1000,$0000,$8E68,$8F00,$1000,$0000
  170.     dc.w    $90DF,$9100,$1000,$0000,$924F,$9300,$1000,$0000
  171.     dc.w    $9424,$9500,$1000,$0000,$96D7,$9700,$1000,$0000
  172.     dc.w    $9859,$9900,$1000,$0000,$9A4F,$9B00,$1000,$0000
  173.     dc.w    $9C4A,$9D00,$1000,$0000,$9E5C,$9F00,$1000,$0000
  174.     dc.w    $A046,$A100,$1000,$0000,$A2A6,$A300,$1000,$0000
  175.     dc.w    $A423,$A500,$1000,$0000,$A6FA,$A700,$1000,$0000
  176.     dc.w    $A86C,$A900,$1000,$0000,$AA44,$AB00,$1000,$0000
  177.     dc.w    $AC88,$AD00,$1000,$0000,$AE9A,$AF00,$1000,$0000
  178.     dc.w    $B06C,$B100,$1000,$0000,$B2D4,$B300,$1000,$0000
  179.     dc.w    $B42A,$B500,$1000,$0000,$B636,$B700,$1000,$0000
  180.     dc.w    $B875,$B900,$1000,$0000,$BA89,$BB00,$1000,$0000
  181.     dc.w    $BC45,$BD00,$1000,$0000,$BE24,$BF00,$1000,$0000
  182.     dc.w    $C0A3,$C100,$1000,$0000,$C29D,$C300,$1000,$0000     
  183.     dc.w    $C43F,$C500,$1000,$0000,$C634,$C700,$1000,$0000     
  184.     dc.w    $C87C,$C900,$1000,$0000,$CA1D,$CB00,$1000,$0000     
  185.     dc.w    $CC6B,$CD00,$1000,$0000,$CEAC,$CF00,$1000,$0000
  186.     dc.w    $D0CF,$D100,$1000,$0000,$D2FF,$D300,$1000,$0000     
  187.     dc.w    $D4A5,$D500,$1000,$0000,$D6D6,$D700,$1000,$0000     
  188.     dc.w    $D8EF,$D900,$1000,$0000,$DAE1,$DB00,$1000,$0000     
  189.     dc.w    $DCD9,$DD00,$1000,$0000,$DEA6,$DF00,$1000,$0000     
  190.     dc.w    $E055,$E100,$1000,$0000,$E237,$E300,$1000,$0000     
  191.     dc.w    $E47D,$E500,$1000,$0000,$E62E,$E700,$1000,$0000
  192.     dc.w    $E8AF,$E900,$1000,$0000,$EA46,$EB00,$1000,$0000
  193.     dc.w    $EC65,$ED00,$1000,$0000,$EE87,$EF00,$1000,$0000
  194.     dc.w    $F0D4,$F100,$1000,$0000,$F2F5,$F300,$1000,$0000
  195.     dc.w    $F4FA,$F500,$1000,$0000,$F62C,$F700,$1000,$0000
  196.     dc.w    $F84D,$F900,$1000,$0000,$FAAC,$FB00,$1000,$0000
  197.     dc.w    $FCB2,$FD00,$1000,$0000,$FE9A,$FF00,$1000,$0000
  198.     dc.w    $009A,$0106,$1000,$0000,$02DF,$0306,$1000,$0000
  199.     dc.w    $0446,$0506,$1000,$0000,$0688,$0706,$1000,$0000
  200.     dc.w    $0899,$0906,$1000,$0000,$0ADD,$0B06,$1000,$0000
  201.     dc.w    $0CEE,$0D06,$1000,$0000,$0EFF,$0F06,$1000,$0000
  202.     dc.w    $10CD,$1106,$1000,$0000,$1267,$1306,$1000,$0000
  203.     dc.w    $1443,$1506,$1000,$0000,$1664,$1706,$1000,$0000
  204.     dc.w    $1823,$1906,$1000,$0000,$1A6D,$1B06,$1000,$0000
  205.     dc.w    $1C4F,$1D06,$1000,$0000,$1E5F,$1F06,$1000,$0000
  206.     dc.w    $2055,$2106,$1000,$0000,$2267,$2306,$1000,$0000
  207.     dc.w    $2445,$2506,$1000,$0000,$2623,$2706,$1000,$0000
  208.     dc.w    $2834,$2906,$1000,$0000,$2AF0,$2B06,$1000,$0000
  209.     dc.w    $2CBC,$2D06,$1000,$0000
  210. SpriteEnd
  211.     dc.w    $0000,$0000  ; Endlich ist der wiederverwertete Sprite fertig
  212.  
  213.      SECTION LEERESPLANE,BSS_C ; Ein auf 0 gesetztes Bitplane, wir
  214.                    ; müssen es verwenden, denn ohne Bitplane
  215.                    ; ist es nicht möglich, die Sprites
  216.                    ; zu aktivieren
  217. BITPLANE:
  218.     ds.b    40*256        ; Bitplane auf 0 Lowres
  219.  
  220.     end
  221.  
  222. In diesem Listing bewegen wir die Sterne jeweils um 1 Pixel. Das  Programm
  223. ist  identisch  mit  dem  vorigem,  nur  erhöhen  wir hier die horizontale
  224. Position um 1 Pixel statt um 2. Das Problem ist nur, daß das niederwertige
  225. der  horizontalen  Koordinate  in einem anderen Byte geschrieben steht als
  226. die restlichen acht, deswegen können wir  den  Sprite  nicht  einfach  mit
  227. einem  ADD verstellen. Eine Möglichkeit wäre, die horizontalen Koordinaten
  228. als Word separat abzuspeichern, also mit allen  Bits  zusammen,  und  dann
  229. immer  1  dazuzählen  und  sie  in  das Byte HSTART und das Bit im vierten
  230. kontrollwort schreiben. Dafür könnten wir dann die selbe Routine verwenden
  231. wie in den letzten Beispielen, UniMoveSprite. Das würde aber bedeuten, daß
  232. wir 127 Word abspeichern müßten, eines für jede horizontale  Position.  In
  233. der Routine haben wir eine bessere Methode verwendet.
  234.  
  235.     BCHG    #0,3(A0)    ; agiere auf das Byte VHBITS
  236.     BEQ.S    Gerade
  237.     ADDQ.B    #$1,1(A0)    ; bewege den Sprite um 2 Pixel
  238. Gerade:
  239.  
  240. sehen wir Schritt für Schritt was getan wird:
  241.  
  242.     BCHG    #0,3(A0)    ; agiere auf das Byte VHBITS
  243.  
  244. Dieser Befehl arbeitet genau gleich wie  das BSET oder das BCLR.  Nur  daß
  245. das  BSET  ein  Bit  immer  auf  1 setzt, und das BCLR immer auf 0, dieser
  246. hingegen vertauscht seinen Zustand: wenn es auf 1 war wird es 0, und  wenn
  247. es  0  war  wird es 1. In unserem Fall ist das Bit genau das niederwertige
  248. der horizontalen Position. Weiters kontrolliert BCHG VOR  DEM  INVERTIEREN
  249. DAS  BIT,  also  ob es auf 0 war, genau gleich wie ein BTST. Also wird die
  250. Anweisung
  251.  
  252.     BEQ.S    Gerade
  253.  
  254. einen Sprung machen, wenn das NIEDERWERTIGE BIT VON HSTART  VOR  DEM  BCHG
  255. AUF 0 WAR.
  256. Die folgende Anweisung verstellt den Sprite um 2 Pixel, wenn die  Position
  257. "ungerade" war:
  258.  
  259.     ADDQ.B    #$1,1(A0)    ; bewege den Sprite um 2 Pixel
  260.  
  261. Diese drei Befehle lösen unser Problem. Denn es können 2 Fälle auftreten:
  262.  
  263. Wenn das niederwertige Bit 0 WAR, dann wird das BCHG es auf 1 setzen,  was
  264. einer  Addition  von 1 gelichkommt. Da in diesem Fall das BEQ einen Sprung
  265. vornimmt, wird das Byte HSTART nicht verändert. Wenn wir praktisch gesehen
  266. im  Byte  HSTART=%0110010  hatten  und  das  niederwertige Bit =0 war (was
  267. zusammengesetzt die horizontale Position %01100100=100 ergibt), dann  wird
  268. nach  der  Routine  das HSTART unverändert sein, und das niederwertige Bit
  269. auf 1 sein. Das Byte HSTART  wird  immer  =%0110010  darstellen,  das  Bit
  270. hingegen 1, zusammengesetzt ergibt es die Zahl =%01100101=101. Wie gewollt
  271. wurde die Position um 1 erhöht.
  272.  
  273. Wenn das niederwertige Bit aber auf 1 WAR, dann bringt es das BCHG auf  0,
  274. was  einer Subtraktion von 1 bei der horizontalen Position gleichkommt. In
  275. diesem Fall aber wird das BEQ KEINEN Sprung vornehmen,  und  deshalb  wird
  276. zum  Byte  HSTART  1  dazugezählt;  und  das entspricht einem Sprung von 2
  277. Pixel. Wenn wir  nun  die  Subtraktion  von  1  und  die  Addition  von  2
  278. zusammennehmen,  dann  ergibt  sich  auch  in diesem Fall ein Sprung von 1
  279. Pixel nach rechts.
  280.  
  281. Auch hier können wir ein praktisches Beispiel annehmen.  Das  Byte  HSTART
  282. =%0110010  und  das  niederwertige  Bit  =  1(zusammen  ergibt  sich
  283. %01100101=101). Nach der Routine wird das Bit auf 0 gegangen sein,  HSTART
  284. wurde  jedoch  um  1  erhöht:  %0110011.  Wenn  wir  nun  die beiden Teile
  285. zusammensetzen ergibt sich die Zahl %01100110=102.  Auch  hier  wurde  der
  286. Sprite um eine Position vertikal verstellt.
  287.  
  288.