home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti6 / lezione10h1.s < prev    next >
Text File  |  1995-10-23  |  14KB  |  466 lines

  1.  
  2. ; Lezione10h1.s    Collisione tra BOB e sfondo mediante il flag ZERO del blitter.
  3. ;        Tasto sinistro per uscire.
  4.  
  5.     SECTION    CiriCop,CODE
  6.  
  7. ;    Include    "DaWorkBench.s"    ; togliere il ; prima di salvare con "WO"
  8.  
  9. *****************************************************************************
  10.     include    "startup1.s"    ; Salva Copperlist Etc.
  11. *****************************************************************************
  12.  
  13.         ;5432109876543210
  14. DMASET    EQU    %1000001111000000    ; copper,bitplane,blitter DMA
  15.  
  16.  
  17. START:
  18.  
  19.     MOVE.L    #BITPLANE,d0    ; dove puntare
  20.     LEA    BPLPOINTERS,A1    ; puntatori COP
  21.     MOVEQ    #3-1,D1        ; numero di bitplanes (qua sono 3)
  22. POINTBP:
  23.     move.w    d0,6(a1)
  24.     swap    d0
  25.     move.w    d0,2(a1)
  26.     swap    d0
  27.     ADD.L    #40*256,d0        ; + LUNGHEZZA DI UNA PLANE !!!!!
  28.     addq.w    #8,a1
  29.     dbra    d1,POINTBP
  30.  
  31.     lea    $dff000,a5        ; CUSTOM REGISTER in a5
  32.     MOVE.W    #DMASET,$96(a5)        ; DMACON - abilita bitplane, copper
  33.     move.l    #COPPERLIST,$80(a5)    ; Puntiamo la nostra COP
  34.     move.w    d0,$88(a5)        ; Facciamo partire la COP
  35.     move.w    #0,$1fc(a5)        ; Disattiva l'AGA
  36.     move.w    #$c00,$106(a5)        ; Disattiva l'AGA
  37.     move.w    #$11,$10c(a5)        ; Disattiva l'AGA
  38.  
  39. mouse:
  40.  
  41.     bsr.s    MuoviOggetto        ; sposta il bob
  42.     bsr.w    ControllaCollisione    ; controlla e segnala eventuali
  43.                     ; collisioni tra bob e sfondo
  44.                     
  45.     bsr.w    SalvaSfondo        ; salva lo sfondo
  46.     bsr.w    DisegnaOggetto        ; disegna il bob
  47.  
  48.     MOVE.L    #$1ff00,d1    ; bit per la selezione tramite AND
  49.     MOVE.L    #$13000,d2    ; linea da aspettare = $130, ossia 304
  50. Waity1:
  51.     MOVE.L    4(A5),D0    ; VPOSR e VHPOSR - $dff004/$dff006
  52.     ANDI.L    D1,D0        ; Seleziona solo i bit della pos. verticale
  53.     CMPI.L    D2,D0        ; aspetta la linea $130 (304)
  54.     BNE.S    Waity1
  55.  
  56.     bsr.w    RipristinaSfondo    ; ripristina lo sfondo
  57.  
  58.     btst    #6,$bfe001        ; tasto sinistro del mouse premuto?
  59.     bne.s    mouse            ; se no, torna a mouse:
  60.  
  61.     rts
  62.  
  63.  
  64. ;****************************************************************************
  65. ; Questa routine muove il bob sullo schermo.
  66. ;****************************************************************************
  67.  
  68. MuoviOggetto
  69.     addq.w    #1,ogg_y    ; sposta in basso il bob
  70.     cmp.w    #256-11,ogg_y    ; e` arrivato al bordo basso ?
  71.     bls.s    EndMuovi    ; se no fine
  72.     clr.w    ogg_y        ; altrimenti riparti dall'alto
  73. EndMuovi
  74.     rts
  75.  
  76. ;***************************************************************************
  77. ; Questa routine disegna il BOB alle coordinate specificate nelle variabili
  78. ; X_OGG e Y_OGG.
  79. ;****************************************************************************
  80.  
  81. ;     ||||||||
  82. ;     | =  = |
  83. ;    @| O  O |@
  84. ;     |  ()  |
  85. ;     ((\__/))
  86. ;      ((()))
  87. ;       ))((
  88. ;        ()
  89.  
  90. DisegnaOggetto:
  91.     lea    bitplane,a0    ; destinazione in a0
  92.     move.w    ogg_y(pc),d0    ; coordinata Y
  93.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  94.                 ; 40 bytes
  95.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  96.  
  97.     move.w    ogg_x(pc),d0    ; coordinata X
  98.     move.w    d0,d1        ; copia
  99.     and.w    #$000f,d0    ; si selezionano i primi 4 bit perche' vanno
  100.                 ; inseriti nello shifter del canale A 
  101.     lsl.w    #8,d0        ; i 4 bit vengono spostati sul nibble alto
  102.     lsl.w    #4,d0        ; della word...
  103.     move.w    d0,d2
  104.  
  105.     or.w    #$0FCA,d0    ; ...giusti per inserirsi nel registro BLTCON0
  106.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  107.                 ; arrotonda ai multipli di 8 per il puntatore
  108.                 ; allo schermo, ovvero agli indirizzi dispari
  109.                 ; (anche ai byte, quindi)
  110.                 ; x es.: un 16 come coordinata diventa il
  111.                 ; byte 2 
  112.     and.w    #$fffe,d1    ; escludo il bit 0 del
  113.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  114.                 ; l'indirizzo giusto di destinazione
  115.  
  116.     lea    figura,a1    ; puntatore sorgente
  117.     moveq    #3-1,d7        ; ripeti per ogni plane
  118. PlaneLoop:
  119.     btst    #6,2(a5)
  120. WBlit2:
  121.     btst    #6,2(a5)         ; attendi che il blitter abbia finito
  122.     bne.s    wblit2
  123.  
  124.     move.l    #$ffff0000,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  125.                     ; BLTALWM = $0000 azzera l'ultima word
  126.  
  127.  
  128.     move.w    d0,$40(a5)        ; BLTCON0 (usa A+D)
  129.     move.w    d2,$42(a5)        ; BLTCON1 (nessun modo speciale)
  130.     move.l    #$0022fffe,$60(a5)
  131.     move.l    #$fffe0022,$64(a5)    ; BLTAMOD=$fffe=-2 torna indietro
  132.                     ; all'inizio della riga.
  133.                     ; BLTDMOD=40-6=34=$22 come al solito
  134.     move.l    #Maschera,$50(a5)    ; BLTAPT  (fisso alla figura sorgente)
  135.     move.l    a0,$54(a5)        ; BLTDPT  (linee di schermo)
  136.     move.l    a0,$48(a5)        ; BLTCPT  (linee di schermo)
  137.     move.l    a1,$4c(a5)
  138.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  139.  
  140.     lea    4*11(a1),a1        ; punta al prossimo plane sorgente
  141.                     ; ogni plane e` largo 2 words e alto
  142.                     ; 11 righe
  143.  
  144.     lea    40*256(a0),a0        ; punta al prossimo plane destinazione
  145.     dbra    d7,PlaneLoop
  146.  
  147.     rts
  148.  
  149. ;****************************************************************************
  150. ; Questa routine copia il rettangolo di sfondo che verra` sovrascritto dal
  151. ; BOB in un buffer
  152. ;****************************************************************************
  153.  
  154. SalvaSfondo:
  155.     lea    bitplane,a0    ; destinazione in a0
  156.     move.w    ogg_y(pc),d0    ; coordinata Y
  157.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  158.                 ; 40 bytes
  159.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  160.  
  161.     move.w    ogg_x(pc),d1    ; coordinata X
  162.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  163.                 ; arrotonda ai multipli di 8 per il puntatore
  164.                 ; allo schermo, ovvero agli indirizzi dispari
  165.                 ; (anche ai byte, quindi)
  166.                 ; x es.: un 16 come coordinata diventa il
  167.                 ; byte 2 
  168.     and.w    #$fffe,d1    ; escludo il bit 0 del
  169.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  170.                 ; l'indirizzo giusto di destinazione
  171.  
  172.     lea    Buffer,a1    ; indirizzo destinazione
  173.     moveq    #3-1,d7        ; ripeti per ogni plane
  174. PlaneLoop2:
  175.     btst    #6,2(a5) ; dmaconr
  176. WBlit3:
  177.     btst    #6,2(a5) ; dmaconr - attendi che il blitter abbia finito
  178.     bne.s    wblit3
  179.  
  180.     move.l    #$ffffffff,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  181.                     ; BLTALWM = $ffff fa passare tutto
  182.  
  183.  
  184.     move.l    #$09f00000,$40(a5)    ; BLTCON0 e BLTCON1 copia da A a D
  185.     move.l    #$00220000,$64(a5)    ; BLTAMOD=40-4=36=$24
  186.                     ; BLTDMOD=0 nel buffer
  187.     move.l    a0,$50(a5)        ; BLTAPT - ind. sorgente
  188.     move.l    a1,$54(a5)        ; BLTDPT - buffer
  189.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  190.  
  191.     lea    40*256(a0),a0        ; punta al prossimo plane sorgente
  192.     lea    6*11(a1),a1        ; punta al prossimo plane destinazione
  193.                     ; ogni blittata e` larga 3 words e alto
  194.                     ; 11 righe
  195.     dbra    d7,PlaneLoop2
  196.  
  197.     rts
  198.  
  199. ;****************************************************************************
  200. ; Questa routine copia il contenuto del buffer nel rettangolo di schermo
  201. ; che lo conteneva prima del disegno del BOB. In questo modo viene anche
  202. ; cancellato il BOB dalla vecchia posizione.
  203. ;****************************************************************************
  204.  
  205. RipristinaSfondo:
  206.     lea    bitplane,a0    ; destinazione in a0
  207.     move.w    ogg_y(pc),d0    ; coordinata Y
  208.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  209.                 ; 40 bytes
  210.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  211.  
  212.     move.w    ogg_x(pc),d1    ; coordinata X
  213.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  214.                 ; arrotonda ai multipli di 8 per il puntatore
  215.                 ; allo schermo, ovvero agli indirizzi dispari
  216.                 ; (anche ai byte, quindi)
  217.                 ; x es.: un 16 come coordinata diventa il
  218.                 ; byte 2 
  219.     and.w    #$fffe,d1    ; escludo il bit 0 del
  220.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  221.                 ; l'indirizzo giusto di destinazione
  222.  
  223.     lea    Buffer,a1    ; indirizzo sorgente
  224.     moveq    #3-1,d7        ; ripeti per ogni plane
  225. PlaneLoop3:
  226.     btst    #6,2(a5)     ; dmaconr
  227. WBlit4:
  228.     btst    #6,2(a5)     ; attendi che il blitter abbia finito
  229.     bne.s    wblit4
  230.  
  231.     move.l    #$ffffffff,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  232.                     ; BLTALWM = $ffff fa passare tutto
  233.  
  234.  
  235.     move.l    #$09f00000,$40(a5)    ; BLTCON0 e BLTCON1 copia da A a D
  236.     move.l    #$00000022,$64(a5)    ; BLTAMOD=0 (buffer)
  237.                     ; BLTDMOD=40-6=34=$22
  238.     move.l    a1,$50(a5)        ; BLTAPT (buffer)
  239.     move.l    a0,$54(a5)        ; BLTDPT (schermo)
  240.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  241.  
  242.     lea    40*256(a0),a0        ; punta al prossimo plane destinazione
  243.     lea    6*11(a1),a1        ; punta al prossimo plane sorgente
  244.                     ; ogni blittata e` larga 3 words e alto
  245.                     ; 11 righe
  246.     dbra    d7,PlaneLoop3
  247.     rts
  248.  
  249. OGG_Y:        dc.w    0    ; qui viene memorizzata la Y dell'oggetto
  250. OGG_X:        dc.w    100    ; qui viene memorizzata la X dell'oggetto
  251.  
  252.  
  253. ;****************************************************************************
  254. ; Questa routine controlla il verificarsi di una collisione
  255. ;****************************************************************************
  256.  
  257. ControllaCollisione
  258.  
  259.     lea    bitplane,a0    ; indirizzo bitplane a0
  260.     move.w    ogg_y(pc),d0    ; coordinata Y
  261.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  262.                 ; 40 bytes
  263.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  264.  
  265.     move.w    ogg_x(pc),d0    ; coordinata X
  266.     move.w    d0,d1        ; copia
  267.     and.w    #$000f,d0    ; si selezionano i primi 4 bit perche' vanno
  268.                 ; inseriti nello shifter del canale A 
  269.     lsl.w    #8,d0        ; i 4 bit vengono spostati sul nibble alto
  270.     lsl.w    #4,d0        ; della word...
  271.     move.w    d0,d2
  272.  
  273.     or.w    #$0AA0,d0    ; ...giusti per inserirsi nel registro BLTCON0
  274.                 ; sono attivi solo i canali A e C (no D)
  275.                 ; esegue un AND tra A e C
  276.  
  277.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  278.                 ; arrotonda ai multipli di 8 per il puntatore
  279.                 ; allo schermo, ovvero agli indirizzi dispari
  280.                 ; (anche ai byte, quindi)
  281.                 ; x es.: un 16 come coordinata diventa il
  282.                 ; byte 2 
  283.     and.w    #$fffe,d1    ; escludo il bit 0 del
  284.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  285.                 ; l'indirizzo giusto di destinazione
  286.  
  287. ; attende che il blitter abbia finito prima di modificare i registri
  288.     btst    #6,2(a5)
  289. WBlit_coll:
  290.     btst    #6,2(a5)
  291.     bne.s    wblit_coll
  292.  
  293.     lea    Maschera,a1    ; puntatore maschera collisione
  294.     moveq    #3-1,d7        ; ripeti per ogni plane
  295. CollLoop:
  296.  
  297.     move.l    #$ffff0000,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  298.                     ; BLTALWM = $0000 azzera l'ultima word
  299.  
  300.  
  301.     move.w    d0,$40(a5)        ; BLTCON0 
  302.                     ; sono attivi solo i canali A e C
  303.                     ; (non D). Esegue un AND tra A e C
  304.     move.w    #$0000,$42(a5)        ; BLTCON1 (nessun modo speciale)
  305.     move.w    #$0022,$60(a5)        ; BLTCMOD=40-6=34=$22
  306.     move.w    #$fffe,$64(a5)        ; BLTAMOD=$fffe=-2 torna indietro
  307.                     ; all'inizio della riga.
  308.     move.l    a1,$50(a5)        ; BLTAPT  (fisso alla figura sorgente)
  309.     move.l    a0,$48(a5)        ; BLTCPT  (posizione sullo schermo)
  310.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  311.  
  312.     lea    40*256(a0),a0        ; punta al prossimo plane sullo schermo
  313.  
  314.     btst    #6,2(a5)
  315. WBlit_coll2:
  316.     btst    #6,2(a5)        ; attendi che il blitter abbia finito
  317.     bne.s    wblit_coll2        ; prima di testare il flag ZERO
  318.  
  319.     btst    #5,2(a5)        ; testa il flag ZERO.
  320.     beq.s    SiColl            ; Se il flag e` diverso da zero c'e`
  321.                     ; stata una collisione, segnala.
  322.                     ; Altrimenti controlla prossimo plane
  323.  
  324.     dbra    d7,CollLoop        ; se per nessun plane si verifica la
  325.                     ; collisione, esci dal loop
  326.  
  327. NoColl
  328.     move.w    #$000,$180(a5)    ; non si sono verificate collisioni:
  329.                 ; schermo nero
  330.     bra.s    EndColl        ; salta alla fine della routine
  331.  
  332. SiColl    move    #$F00,$180(a5)    ; e` stata rilevata una collisione:
  333.                 ; schermo rosso
  334.  
  335. EndColl
  336.     rts
  337.  
  338. ;****************************************************************************
  339.  
  340.     SECTION    GRAPHIC,DATA_C
  341.  
  342. COPPERLIST:
  343.     dc.w    $8E,$2c81    ; DiwStrt
  344.     dc.w    $90,$2cc1    ; DiwStop
  345.     dc.w    $92,$38        ; DdfStart
  346.     dc.w    $94,$d0        ; DdfStop
  347.     dc.w    $102,0        ; BplCon1
  348.     dc.w    $104,0        ; BplCon2
  349.     dc.w    $108,0        ; VALORE MODULO = 0
  350.     dc.w    $10a,0        ; ENTRAMBI I MODULI ALLO STESSO VALORE.
  351.  
  352.     dc.w    $100,$3200    ; bplcon0 - 3 bitplanes lowres
  353.  
  354. BPLPOINTERS:
  355.     dc.w $e0,$0000,$e2,$0000    ;primo     bitplane
  356.     dc.w $e4,$0000,$e6,$0000
  357.     dc.w $e8,$0000,$ea,$0000
  358.  
  359.     dc.w    $0182,$475    ; color1
  360.     dc.w    $0184,$fff    ; color2
  361.     dc.w    $0186,$ccc    ; color3
  362.     dc.w    $0188,$999    ; color4
  363.     dc.w    $018a,$232    ; color5
  364.     dc.w    $018c,$777    ; color6
  365.     dc.w    $018e,$444    ; color7
  366.  
  367.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  368.  
  369. ;****************************************************************************
  370.  
  371. ; Questi sono i dati che compongono la figura del bob.
  372. ; Il bob e` in formato normale, largo 32 pixel (2 words)
  373. ; alto 11 righe e formato da 3 bitplanes
  374.  
  375. Figura:    dc.l    $007fc000    ; plane 1
  376.     dc.l    $03fff800
  377.     dc.l    $07fffc00
  378.     dc.l    $0ffffe00
  379.     dc.l    $1fe07f00
  380.     dc.l    $1fe07f00
  381.     dc.l    $1fe07f00
  382.     dc.l    $0ffffe00
  383.     dc.l    $07fffc00
  384.     dc.l    $03fff800
  385.     dc.l    $007fc000
  386.  
  387.     dc.l    $00000000    ; plane 2
  388.     dc.l    $007fc000
  389.     dc.l    $03fff800
  390.     dc.l    $07fffc00
  391.     dc.l    $0fe07e00
  392.     dc.l    $0fe07e00
  393.     dc.l    $0fe07e00
  394.     dc.l    $07fffc00
  395.     dc.l    $03fff800
  396.     dc.l    $007fc000
  397.     dc.l    $00000000
  398.  
  399.     dc.l    $007fc000    ; plane 3
  400.     dc.l    $03803800
  401.     dc.l    $04000400
  402.     dc.l    $081f8200
  403.     dc.l    $10204100
  404.     dc.l    $10204100
  405.     dc.l    $10204100
  406.     dc.l    $081f8200
  407.     dc.l    $04000400
  408.     dc.l    $03803800
  409.     dc.l    $007fc000
  410.  
  411. Maschera:
  412.     dc.l    $007fc000
  413.     dc.l    $03fff800
  414.     dc.l    $07fffc00
  415.     dc.l    $0ffffe00
  416.     dc.l    $1fe07f00
  417.     dc.l    $1fe07f00
  418.     dc.l    $1fe07f00
  419.     dc.l    $0ffffe00
  420.     dc.l    $07fffc00
  421.     dc.l    $03fff800
  422.     dc.l    $007fc000
  423.  
  424. ;****************************************************************************
  425.  
  426. BITPLANE:
  427.     incbin    "amiga.raw"        ; qua carichiamo la figura in
  428.                     ; formato RAWBLIT (o interleaved),
  429.                     ; convertita col KEFCON.
  430.  
  431. ;****************************************************************************
  432.  
  433.     SECTION    BUFFER,BSS_C
  434.  
  435. ; Questo e` il buffer nel quale salviamo di volta in volta lo sfondo.
  436. ; ha le stesse dimensioni di una blittata: altezza 11, larghezza 3 words
  437. ; 3 bitplanes
  438.  
  439. Buffer:
  440.     ds.w    11*3*3
  441.  
  442.     end
  443.  
  444. ;****************************************************************************
  445.  
  446. In questo esempio mostriamo come rilevare le collisioni tra il bob e lo sfondo.
  447. Per rilevare la collisione si usa il flag Zero del blitter. La tecnica e` la
  448. seguente: si esegue una blittata che fa un AND tra la maschera del bob e lo
  449. sfondo, senza pero` scrivere il risultato in uscita. Se l'operazione di AND
  450. fornisce un risultato di zero per tutti i bit della blittata, il flag Zero
  451. assume valore 1. Il fatto che l'operazione di AND abbia fornito risultato 0,
  452. vuol dire che in nessun caso un bit della maschera coincide con uno dello
  453. sfondo, quindi non c'e` collisione.
  454. Se invece almeno un bit della maschera coincide con uno dello sfondo, vuol dire
  455. che si verifica una collisione. In questo caso, siccome facendo l'AND tra
  456. questi 2 bit il risultato e` 1, il Flag ZERO assumera` valore 0, e da questo
  457. fatto possiamo capire che c'e` stata una collisione.
  458. Notate che mentre per il bob abbiamo la maschera, non e` cosi` per lo sfondo.
  459. Questo fatto ci costringe a controllare la collisione tra la maschera del bob
  460. e tutti i planes della figura. Disponendo della maschera dello sfondo, si
  461. potrebbe testare la collisione mediante una sola blittata tra le maschere.
  462. Fatelo per esercizio.
  463. Notate anche che prima di testare il flag Zero, e` necessario attendere la
  464. fine della blittata.
  465.  
  466.