home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti3 / lezione7t2.s < prev    next >
Text File  |  1995-09-29  |  11KB  |  286 lines

  1.  
  2. ; Lezione7t2.s    stelle lente
  3.  
  4. ;    In questo listato facciamo un cielo stellato
  5. ;    con stelle che si muovono di un pixel per volta
  6.  
  7.  
  8.     SECTION    CiriCop,CODE
  9.  
  10. Inizio:
  11.     move.l    4.w,a6        ; Execbase
  12.     jsr    -$78(a6)    ; Disable
  13.     lea    GfxName(PC),a1    ; Nome lib
  14.     jsr    -$198(a6)    ; OpenLibrary
  15.     move.l    d0,GfxBase
  16.     move.l    d0,a6
  17.     move.l    $26(a6),OldCop
  18.  
  19.  
  20.     MOVE.L    #BITPLANE,d0
  21.     LEA    BPLPOINTERS,A1
  22.     move.w    d0,6(a1)
  23.     swap    d0
  24.     move.w    d0,2(a1)
  25.  
  26. ;    Puntiamo gli sprite
  27.  
  28.     MOVE.L    #SPRITE,d0        ; indirizzo dello sprite in d0
  29.     LEA    SpritePointers,a1    ; Puntatori in copperlist
  30.     move.w    d0,6(a1)
  31.     swap    d0
  32.     move.w    d0,2(a1)
  33.  
  34.     move.l    #COPPERLIST,$dff080    ; nostra COP
  35.     move.w    d0,$dff088        ; START COP
  36.     move.w    #0,$dff1fc        ; NO AGA!
  37.     move.w    #$c00,$dff106        ; NO AGA!
  38.  
  39. mouse:
  40.     cmpi.b    #$ff,$dff006    ; Linea 255?
  41.     bne.s    mouse
  42.  
  43.     bsr.s    MuoviStelle    ; questa routine muove le stelle
  44.  
  45. Aspetta:
  46.     cmpi.b    #$ff,$dff006    ; linea 255?
  47.     beq.s    Aspetta
  48.  
  49.     btst    #6,$bfe001    ; mouse premuto?
  50.     bne.s    mouse
  51.  
  52.     move.l    OldCop(PC),$dff080    ; Puntiamo la cop di sistema
  53.     move.w    d0,$dff088        ; facciamo partire la vecchia cop
  54.  
  55.     move.l    4.w,a6
  56.     jsr    -$7e(a6)    ; Enable
  57.     move.l    gfxbase(PC),a1
  58.     jsr    -$19e(a6)    ; Closelibrary
  59.     rts
  60.  
  61. ;    Dati
  62.  
  63. GfxName:
  64.     dc.b    "graphics.library",0,0
  65.  
  66. GfxBase:
  67.     dc.l    0
  68.  
  69. OldCop:
  70.     dc.l    0
  71.  
  72. ; Questa semplice routine fa avanzare lo sprite che costituisce le stelle
  73. ; agendo su ogni HSTART (e sul byte VHBITS per lo scroll fluido di 1 pixel
  74. ; anziche' 2) tramite il loop STELLE_LOOP
  75.  
  76. MuoviStelle:
  77.     lea    Sprite,A0        ; a0 punta allo sprite
  78. STELLE_LOOP:
  79.     CMPI.B    #$f0,1(A0)        ; la stella ha raggiunto il bordo
  80.                     ; destro dello schermo ?
  81.     BNE.S    no_bordo        ; no, allora salta
  82.     MOVE.B    #$30,1(A0)        ; si, rimetti la stella a sinistra  
  83. no_bordo:
  84.     BCHG    #0,3(A0)        ; agisci sul byte VHBITS
  85.     BEQ.S    pari
  86.     ADDQ.B  #$1,1(A0)        ; sposta di 2 pixel lo sprite
  87. pari:
  88.     ADDQ.w    #8,A0            ; prossima stella
  89.     CMP.L    #SpriteEnd,A0        ; abbiamo raggiunto la fine?
  90.     BLO.S    STELLE_LOOP        ; se no rifai il loop
  91.     RTS                ; fine routine
  92.  
  93.  
  94.     SECTION    GRAPHIC,DATA_C
  95.  
  96. COPPERLIST:
  97. SpritePointers:
  98.     dc.w    $120,0,$122,0,$124,0,$126,0,$128,0 ; SPRITE
  99.     dc.w    $12a,0,$12c,0,$12e,0,$130,0,$132,0
  100.     dc.w    $134,0,$136,0,$138,0,$13a,0,$13c,0
  101.     dc.w    $13e,0
  102.  
  103.     dc.w    $8E,$2c81    ; DiwStrt
  104.     dc.w    $90,$2cc1    ; DiwStop
  105.  
  106.     dc.w    $92,$38        ; DdfStart
  107.     dc.w    $94,$d0        ; DdfStop
  108.     dc.w    $102,0        ; BplCon1
  109.     dc.w    $104,0        ; BplCon2
  110.     dc.w    $108,0        ; Bpl1Mod
  111.     dc.w    $10a,0        ; Bpl2Mod
  112.  
  113.             ; 5432109876543210
  114.     dc.w    $100,%0001001000000000
  115.  
  116. BPLPOINTERS:
  117.     dc.w $e0,0,$e2,0    ;primo     bitplane
  118.  
  119.     dc.w    $180,$000    ; color0    ; sfondo nero
  120.     dc.w    $182,$000    ; color1    ; colore 1 del bitplane, che
  121.                         ; in questo caso e' vuoto,
  122.                         ; per cui non compare.
  123. ; lo sprite usa un solo colore, il 17
  124.  
  125.     dc.w    $1A2,$ddd    ; color17, - COLOR1 dello sprite0 - bianco
  126.  
  127.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  128.  
  129. ;    -    -    -    -    -    -    -    
  130.  
  131. ; Come potete notare, questo sprite e' riutilizzato un bel po' di volte, per
  132. ; la precisione 127. E' composto di tante coppie di word di controllo seguite
  133. ; da un $1000,$0000, ossia la linea di dati che compone ogni singola stella.
  134. ; Le posizioni verticali vanno di 2 in 2, per cui c'e' una stella ogni 2
  135. ; linee verticali, ad una posizione orizzontale diversa per ogni stella.
  136. ; il primo utilizzo dello sprite e' $307a,$3100,$1000,$0000
  137. ; il secondo e' $3220,$3300,$1000,$0000
  138. ; E cosi' via. I vari VSTART vanno di 2 in 2, infatti sono $30,$32,$34,$36...
  139. ; Gli HSTART sono posizionati casualmente ($7a,$20,$c0,$50...)
  140. ; I Vstop sono chiaramente 1 linea dopo lo start ($31,$33,$35..) essendo le
  141. ; stelle alte 1 pixel.
  142. ; La routine agisce ogni fotogramma su tutti gli HSTART spostando avanti le
  143. ; stelle.
  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    ; fine sprite
  212.  
  213.  
  214.     SECTION    PLANEVUOTO,BSS_C
  215. BITPLANE:
  216.     ds.b    40*256
  217.  
  218.     end
  219.  
  220. In questo listato facciamo muovere le stelle a passi di un pixel.
  221. Il programma e` identico all'esempio precedente, la sola cosa che cambia e`
  222. che dobbiamo aumentare di 1 pixel invece che di 2 le posizioni orizzontali
  223. delle stelle quando le mouviamo. Il problema e` che come sapete il bit basso
  224. della posizione orizzontale di uno sprite e` scritto separatamente dagli
  225. altri, quindi non possiamo spostare di 1 pixel uno sprite con una semplice
  226. ADD. Una possibile soluzione sarebbe quella di tenere memorizzate a parte le
  227. posizioni orizzontali in forma di word, cioe` con tutti i bit insieme,
  228. aggiungere 1 alle word e poi scriverle nel byte HSTART e nel bit basso
  229. mediante la stessa procedura che abbiamo usato nella routine UniMuoviSprite.
  230. Questa soluzione ci costringerebbe pero` a memorizzare ben 127 word, una per
  231. ogni posizione orizzontale. Nella routine abbiamo usato un metodo migliore.
  232.  
  233.     BCHG    #0,3(A0)        ; agisci sul byte VHBITS
  234.     BEQ.S    pari
  235.     ADDQ.B  #$1,1(A0)        ; sposta di 2 pixel lo sprite
  236. pari:
  237.  
  238. vediamo passo per passo cosa succede
  239.  
  240.     BCHG    #0,3(A0)        ; agisci sul byte VHBITS
  241.  
  242. questa istruzione funziona esattamente come il BSET o il BCLR, solo che
  243. mentre BSET pone sempre a 1 il bit indicato e BCLR lo pone sempre a 0,
  244. BCHG lo inverte: se prima era 0 lo trasforma in 1 e viceversa. In questo caso
  245. il bit in questione e` proprio il bit basso della posizione della stella.
  246. Inoltre BCHG PRIMA DI INVERTIRE IL BIT, controlla se esso e` a 0, esattamente
  247. come fa il BTST. Quindi l'istruzione
  248.  
  249.     BEQ.S    pari
  250.  
  251. effettua il salto se il bit basso di HSTART ERA A 0 PRIMA DI ESEGUIRE IL BCHG.
  252.  
  253. L'istruzione seguente sposta di 2 pixel lo sprite, se la posizione era dispari
  254.  
  255.     ADDQ.B  #$1,1(A0)  ; sposta di 2 pixel lo sprite.
  256.  
  257. Queste 3 istruzioni risolvono il nostro problema. Infatti si possono
  258. verificare 2 casi:
  259.  
  260. Se il bit basso ERA a 0, il BCHG lo porta a 1, il che equivale ad aggiungere
  261. 1 alla posizione orizzontale. Poiche` in questo caso il BEQ effettua il
  262. salto, il byte HSTART non viene modificato. In pratica se per esempio avevamo
  263. byte HSTART=%0110010 e bit basso = 0 (che messi insieme formavano per la
  264. posizione orizzontale il numero %01100100=100), dopo aver eseguito la routine
  265. ci ritroviamo con HSTART uguale e il bit basso=1, ovvero
  266. byte HSTART=%0110010 e bit basso = 1 (che messi insieme formano per la
  267. posizione orizzontale il numero %01100101=101).
  268. Come volevamo abbiamo aumentato di 1 la posizione orizzontale.
  269.  
  270. Se invece il bit basso ERA a 1 la  BCHG lo porta a 0, il che equivale a
  271. sottrarre 1 alla posizione orizzontale. In questo caso pero` il BEQ
  272. NON effettua il salto, e pertanto viene aggiunto 1 al il byte HSTART il che
  273. come sapete equivale ad aggiungere 2 alla posizione orizzontale. Combinando
  274. insieme la sottrazione di 1 fatta dal BCHG con la somma di 2 fatta dalla
  275. ADD, abbiamo aggiunto 1 alla posizione orizzontale.
  276.  
  277. In pratica se per esempio prima di eseguire la routine avevamo
  278. byte HSTART=%0110010 e bit basso = 1 (che messi insieme formavano per la
  279. posizione orizzontale il numero %01100101=101), dopo aver eseguito la routine
  280. ci ritroviamo con HSTART aumentato di 1 e il bit basso=0, ovvero
  281. byte HSTART=%0110011 e bit basso = 0 che messi insieme formano per la
  282. posizione orizzontale il numero %01100110=102).
  283. Come volevamo anche in questo caso abbiamo aumentato di 1 la posizione
  284. orizzontale dello sprite.
  285.  
  286.