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

  1.  
  2. ; Lezione9i3.s    BOB con ripristino dello sfondo.
  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.w    LeggiMouse        ; leggi coordinate
  42.     bsr.s    ControllaCoordinate    ; evita che il bob esca dallo schermo
  43.     bsr.w    SalvaSfondo        ; salva lo sfondo
  44.     bsr.s    DisegnaOggetto        ; disegna il bob
  45.  
  46.     MOVE.L    #$1ff00,d1    ; bit per la selezione tramite AND
  47.     MOVE.L    #$13000,d2    ; linea da aspettare = $130, ossia 304
  48. Waity1:
  49.     MOVE.L    4(A5),D0    ; VPOSR e VHPOSR - $dff004/$dff006
  50.     ANDI.L    D1,D0        ; Seleziona solo i bit della pos. verticale
  51.     CMPI.L    D2,D0        ; aspetta la linea $130 (304)
  52.     BNE.S    Waity1
  53.  
  54.     bsr.w    RipristinaSfondo    ; ripristina lo sfondo
  55.  
  56.     btst    #6,$bfe001        ; tasto sinistro del mouse premuto?
  57.     bne.s    mouse            ; se no, torna a mouse:
  58.  
  59.     rts
  60.  
  61.  
  62. ;****************************************************************************
  63. ; Questa routine fa in modo che le coordinate del bob rimangano sempre
  64. ; all'interno dello schermo.
  65. ;****************************************************************************
  66.  
  67. ControllaCoordinate:
  68.     tst.w    ogg_x        ; controlla X
  69.     bpl.s    NoMinX        ; controlla bordo sinistro
  70.     clr.w    ogg_x        ; se X e` negativa, pone X=0
  71.     bra.s    controllaY    ; va a controllare la Y
  72.  
  73. NoMinX:
  74.     cmp.w    #319-32,ogg_x    ; controlla il bordo destro. In X_OGG
  75.                 ; e` memorizzata la coordinata del bordo
  76.                 ; sinistro del bob. Se esso ha raggiunto
  77.                 ; 319-32, allora il bordo destro ha raggiunto
  78.                 ; la coordinata 319
  79.     bls.s    controllaY    ; se e` minore tutto bene, controlla la Y
  80.     move.w    #319-32,ogg_x    ; altrimenti fissa la coordinata sul bordo.
  81.  
  82. controllaY:
  83.     tst.w    ogg_y        ; controlla bordo in alto
  84.     bpl.s    NoMinY        ; se e` positiva controlla in basso
  85.     clr.w    ogg_y        ; altrimenti poni Y=0
  86.     bra.s    EndControlla    ; ed esci
  87.  
  88. NoMinY:
  89.     cmp.w    #255-11,ogg_y    ; controlla il bordo basso. In Y_OGG
  90.                 ; e` memorizzata la coordinata del bordo
  91.                 ; alto del bob. Se esso ha raggiunto
  92.                 ; Y=255-11, allora il bordo basso ha raggiunto
  93.                 ; la coordinata Y=255
  94.     bls.s    EndControlla    ; se e` minore tutto bene, controlla la Y
  95.     move.w    #255-11,ogg_y    ; altrimenti fissa la coordinata sul bordo.
  96. EndControlla:
  97.     rts
  98.  
  99. ;***************************************************************************
  100. ; Questa routine disegna il BOB alle coordinate specificate nelle variabili
  101. ; X_OGG e Y_OGG. Il BOB e lo schermo sono in formato normale, e pertanto
  102. ; sono utilizzate le formule relative a questo formato nel calcolo dei
  103. ; valori da scrivere nei registri del blitter. Inoltre viene impiegata la
  104. ; tecnica di mascherare l'ultima word del BOB vista nella lezione
  105. ;****************************************************************************
  106.  
  107. ;         _, ,. ,_
  108. ;         ////;\\\
  109. ;        /'__  __`\
  110. ;      _/  ______  \_
  111. ;     (_   `°'`°'   _)
  112. ;      /  _ (__) _  \ xCz
  113. ;     / _ l______| _ \
  114. ;    /  (  `----'  )  \
  115. ;    \_____      _____/
  116. ;        `--------'
  117.  
  118. DisegnaOggetto:
  119.     lea    bitplane,a0    ; destinazione in a0
  120.     move.w    ogg_y(pc),d0    ; coordinata Y
  121.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  122.                 ; 40 bytes
  123.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  124.  
  125.     move.w    ogg_x(pc),d0    ; coordinata X
  126.     move.w    d0,d1        ; copia
  127.     and.w    #$000f,d0    ; si selezionano i primi 4 bit perche' vanno
  128.                 ; inseriti nello shifter del canale A 
  129.     lsl.w    #8,d0        ; i 4 bit vengono spostati sul nibble alto
  130.     lsl.w    #4,d0        ; della word...
  131.     or.w    #$09f0,d0    ; ...giusti per inserirsi nel registro BLTCON0
  132.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  133.                 ; arrotonda ai multipli di 8 per il puntatore
  134.                 ; allo schermo, ovvero agli indirizzi dispari
  135.                 ; (anche ai byte, quindi)
  136.                 ; x es.: un 16 come coordinata diventa il
  137.                 ; byte 2 
  138.     and.w    #$fffe,d1    ; escludo il bit 0 del
  139.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  140.                 ; l'indirizzo giusto di destinazione
  141.  
  142.     lea    figura,a1    ; puntatore sorgente
  143.     moveq    #3-1,d7        ; ripeti per ogni plane
  144. PlaneLoop:
  145.     btst    #6,2(a5)
  146. WBlit2:
  147.     btst    #6,2(a5)         ; attendi che il blitter abbia finito
  148.     bne.s    wblit2
  149.  
  150.     move.l    #$ffff0000,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  151.                     ; BLTALWM = $0000 azzera l'ultima word
  152.  
  153.  
  154.     move.w    d0,$40(a5)        ; BLTCON0 (usa A+D)
  155.     move.w    #$0000,$42(a5)        ; BLTCON1 (nessun modo speciale)
  156.     move.l    #$fffe0022,$64(a5)    ; BLTAMOD=$fffe=-2 torna indietro
  157.                     ; all'inizio della riga.
  158.                     ; BLTDMOD=40-6=34=$22 come al solito
  159.     move.l    a1,$50(a5)        ; BLTAPT  (fisso alla figura sorgente)
  160.     move.l    a0,$54(a5)        ; BLTDPT  (linee di schermo)
  161.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  162.  
  163.     lea    4*11(a1),a1        ; punta al prossimo plane sorgente
  164.                     ; ogni plane e` largo 2 words e alto
  165.                     ; 11 righe
  166.  
  167.     lea    40*256(a0),a0        ; punta al prossimo plane destinazione
  168.     dbra    d7,PlaneLoop
  169.  
  170.     rts
  171.  
  172. ;****************************************************************************
  173. ; Questa routine copia il rettangolo di sfondo che verra` sovrascritto dal
  174. ; BOB in un buffer
  175. ;****************************************************************************
  176.  
  177. SalvaSfondo:
  178.     lea    bitplane,a0    ; destinazione in a0
  179.     move.w    ogg_y(pc),d0    ; coordinata Y
  180.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  181.                 ; 40 bytes
  182.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  183.  
  184.     move.w    ogg_x(pc),d1    ; coordinata X
  185.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  186.                 ; arrotonda ai multipli di 8 per il puntatore
  187.                 ; allo schermo, ovvero agli indirizzi dispari
  188.                 ; (anche ai byte, quindi)
  189.                 ; x es.: un 16 come coordinata diventa il
  190.                 ; byte 2 
  191.     and.w    #$fffe,d1    ; escludo il bit 0 del
  192.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  193.                 ; l'indirizzo giusto di destinazione
  194.  
  195.     lea    Buffer,a1    ; indirizzo destinazione
  196.     moveq    #3-1,d7        ; ripeti per ogni plane
  197. PlaneLoop2:
  198.     btst    #6,2(a5) ; dmaconr
  199. WBlit3:
  200.     btst    #6,2(a5) ; dmaconr - attendi che il blitter abbia finito
  201.     bne.s    wblit3
  202.  
  203.     move.l    #$ffffffff,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  204.                     ; BLTALWM = $ffff fa passare tutto
  205.  
  206.  
  207.     move.l    #$09f00000,$40(a5)    ; BLTCON0 e BLTCON1 copia da A a D
  208.     move.l    #$00220000,$64(a5)    ; BLTAMOD=40-4=36=$24
  209.                     ; BLTDMOD=0 nel buffer
  210.     move.l    a0,$50(a5)        ; BLTAPT - ind. sorgente
  211.     move.l    a1,$54(a5)        ; BLTDPT - buffer
  212.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  213.  
  214.     lea    40*256(a0),a0        ; punta al prossimo plane sorgente
  215.     lea    6*11(a1),a1        ; punta al prossimo plane destinazione
  216.                     ; ogni blittata e` larga 3 words e alto
  217.                     ; 11 righe
  218.     dbra    d7,PlaneLoop2
  219.  
  220.     rts
  221.  
  222. ;****************************************************************************
  223. ; Questa routine copia il contenuto del buffer nel rettangolo di schermo
  224. ; che lo conteneva prima del disegno del BOB. In questo modo viene anche
  225. ; cancellato il BOB dalla vecchia posizione.
  226. ;****************************************************************************
  227.  
  228. RipristinaSfondo:
  229.     lea    bitplane,a0    ; destinazione in a0
  230.     move.w    ogg_y(pc),d0    ; coordinata Y
  231.     mulu.w    #40,d0        ; calcola indirizzo: ogni riga e` costituita da
  232.                 ; 40 bytes
  233.     add.w    d0,a0        ; aggiungi all'indirizzo di partenza
  234.  
  235.     move.w    ogg_x(pc),d1    ; coordinata X
  236.     lsr.w    #3,d1        ; (equivalente ad una divisione per 8)
  237.                 ; arrotonda ai multipli di 8 per il puntatore
  238.                 ; allo schermo, ovvero agli indirizzi dispari
  239.                 ; (anche ai byte, quindi)
  240.                 ; x es.: un 16 come coordinata diventa il
  241.                 ; byte 2 
  242.     and.w    #$fffe,d1    ; escludo il bit 0 del
  243.     add.w    d1,a0        ; somma all'indirizzo del bitplane, trovando
  244.                 ; l'indirizzo giusto di destinazione
  245.  
  246.     lea    Buffer,a1    ; indirizzo sorgente
  247.     moveq    #3-1,d7        ; ripeti per ogni plane
  248. PlaneLoop3:
  249.     btst    #6,2(a5)     ; dmaconr
  250. WBlit4:
  251.     btst    #6,2(a5)     ; attendi che il blitter abbia finito
  252.     bne.s    wblit4
  253.  
  254.     move.l    #$ffffffff,$44(a5)    ; BLTAFWM = $ffff fa passare tutto
  255.                     ; BLTALWM = $ffff fa passare tutto
  256.  
  257.  
  258.     move.l    #$09f00000,$40(a5)    ; BLTCON0 e BLTCON1 copia da A a D
  259.     move.l    #$00000022,$64(a5)    ; BLTAMOD=0 (buffer)
  260.                     ; BLTDMOD=40-6=34=$22
  261.     move.l    a1,$50(a5)        ; BLTAPT (buffer)
  262.     move.l    a0,$54(a5)        ; BLTDPT (schermo)
  263.     move.w    #(64*11)+3,$58(a5)    ; BLTSIZE (via al blitter !)
  264.  
  265.     lea    40*256(a0),a0        ; punta al prossimo plane destinazione
  266.     lea    6*11(a1),a1        ; punta al prossimo plane sorgente
  267.                     ; ogni blittata e` larga 3 words e alto
  268.                     ; 11 righe
  269.     dbra    d7,PlaneLoop3
  270.     rts
  271.  
  272. ;****************************************************************************
  273. ; Questa routine legge il mouse e aggiorna i valori contenuti nelle
  274. ; variabili OGG_X e OGG_Y
  275. ;****************************************************************************
  276.  
  277. LeggiMouse:
  278.     move.b    $dff00a,d1    ; JOY0DAT posizione verticale mouse
  279.     move.b    d1,d0        ; copia in d0
  280.     sub.b    mouse_y(PC),d0    ; sottrai vecchia posizione mouse
  281.     beq.s    no_vert        ; se la differenza = 0, il mouse e` fermo
  282.     ext.w    d0        ; trasforma il byte in word
  283.                 ; (vedi alla fine del listato)
  284.     add.w    d0,ogg_y    ; modifica posizione oggetto
  285.  
  286. no_vert:
  287.       move.b    d1,mouse_y    ; salva posizione mouse per la prossima volta
  288.  
  289.     move.b    $dff00b,d1    ; posizione orizzontale mouse
  290.     move.b    d1,d0        ; copia in d0
  291.     sub.b    mouse_x(PC),d0    ; sottrai vecchia posizione
  292.     beq.s    no_oriz        ; se la differenza = 0, il mouse e` fermo
  293.     ext.w    d0        ; trasforma il byte in word
  294.                 ; (vedi alla fine del listato)
  295.     add.w    d0,ogg_x    ; modifica pos. oggetto
  296. no_oriz
  297.       move.b    d1,mouse_x    ; salva posizione mouse per la prossima volta
  298.     RTS
  299.  
  300. OGG_Y:        dc.w    0    ; qui viene memorizzata la Y dell'oggetto
  301. OGG_X:        dc.w    0    ; qui viene memorizzata la X dell'oggetto
  302. MOUSE_Y:    dc.b    0    ; qui viene memorizzata la Y del mouse
  303. MOUSE_X:    dc.b    0    ; qui viene memorizzata la X del mouse
  304.  
  305. ;****************************************************************************
  306.  
  307.     SECTION    GRAPHIC,DATA_C
  308.  
  309. COPPERLIST:
  310.     dc.w    $8E,$2c81    ; DiwStrt
  311.     dc.w    $90,$2cc1    ; DiwStop
  312.     dc.w    $92,$38        ; DdfStart
  313.     dc.w    $94,$d0        ; DdfStop
  314.     dc.w    $102,0        ; BplCon1
  315.     dc.w    $104,0        ; BplCon2
  316.     dc.w    $108,0        ; VALORE MODULO = 0
  317.     dc.w    $10a,0        ; ENTRAMBI I MODULI ALLO STESSO VALORE.
  318.  
  319.     dc.w    $100,$3200    ; bplcon0 - 3 bitplanes lowres
  320.  
  321. BPLPOINTERS:
  322.     dc.w $e0,$0000,$e2,$0000    ;primo     bitplane
  323.     dc.w $e4,$0000,$e6,$0000
  324.     dc.w $e8,$0000,$ea,$0000
  325.  
  326.     dc.w    $0180,$000    ; color0
  327.     dc.w    $0182,$475    ; color1
  328.     dc.w    $0184,$fff    ; color2
  329.     dc.w    $0186,$ccc    ; color3
  330.     dc.w    $0188,$999    ; color4
  331.     dc.w    $018a,$232    ; color5
  332.     dc.w    $018c,$777    ; color6
  333.     dc.w    $018e,$444    ; color7
  334.  
  335.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  336.  
  337. ;****************************************************************************
  338.  
  339. ; Questi sono i dati che compongono la figura del bob.
  340. ; Il bob e` in formato normale, largo 32 pixel (2 words)
  341. ; alto 11 righe e formato da 3 bitplanes
  342.  
  343. Figura:    dc.l    $007fc000    ; plane 1
  344.     dc.l    $03fff800
  345.     dc.l    $07fffc00
  346.     dc.l    $0ffffe00
  347.     dc.l    $1fe07f00
  348.     dc.l    $1fe07f00
  349.     dc.l    $1fe07f00
  350.     dc.l    $0ffffe00
  351.     dc.l    $07fffc00
  352.     dc.l    $03fff800
  353.     dc.l    $007fc000
  354.  
  355.     dc.l    $00000000    ; plane 2
  356.     dc.l    $007fc000
  357.     dc.l    $03fff800
  358.     dc.l    $07fffc00
  359.     dc.l    $0fe07e00
  360.     dc.l    $0fe07e00
  361.     dc.l    $0fe07e00
  362.     dc.l    $07fffc00
  363.     dc.l    $03fff800
  364.     dc.l    $007fc000
  365.     dc.l    $00000000
  366.  
  367.     dc.l    $007fc000    ; plane 3
  368.     dc.l    $03803800
  369.     dc.l    $04000400
  370.     dc.l    $081f8200
  371.     dc.l    $10204100
  372.     dc.l    $10204100
  373.     dc.l    $10204100
  374.     dc.l    $081f8200
  375.     dc.l    $04000400
  376.     dc.l    $03803800
  377.     dc.l    $007fc000
  378.  
  379. ;****************************************************************************
  380.  
  381. BITPLANE:
  382.     incbin    "assembler2:sorgenti6/amiga.raw"
  383.                     ; qua carichiamo la figura in
  384.                     ; formato RAWBLIT (o interleaved),
  385.                     ; convertita col KEFCON.
  386.  
  387. ;****************************************************************************
  388.  
  389.     SECTION    BUFFER,BSS_C
  390.  
  391. ; Questo e` il buffer nel quale salviamo di volta in volta lo sfondo.
  392. ; ha le stesse dimensioni di una blittata: altezza 11, larghezza 3 words
  393. ; 3 bitplanes
  394.  
  395. Buffer:
  396.     ds.w    11*3*3
  397.  
  398.     end
  399.  
  400. ;****************************************************************************
  401.  
  402. In questo esempio affrontiamo il problema dello sfondo con i BOB.
  403. Non forniremo ancora la soluzione definitiva che richiede la comprensione di
  404. caratteristiche del blitter ancora non spiegate nel corso. Comunque faremo
  405. un primo passo. L'idea e` la seguente: prima di disegnare il BOB sullo schermo
  406. copiamo la parte di sfondo che verrebbe sovrascritta dal BOB in un buffer.
  407. Poi disegnamo normalmente il BOB. Dopo il vertical blank dobbiamo cancellare
  408. il BOB prima di ridisegnarlo nella nuova posizione. Invece di cancellare
  409. semplicemente (cosa che lascerebbe il pezzo di schermo vuoto) ci ricopiamo
  410. sopra lo sfondo che c'era prima. In questo modo cancelliamo la vecchia copia
  411. del BOB e rimettiamo lo sfondo che c'era prima del suo passaggio.
  412. Il problema di questa tecnica, come potete vedere, e` che non si vede lo sfondo
  413. nelle zone nel rettangolo che racchiude il BOB. Questo e` dovuto al fatto
  414. che le parti del BOB colorate con il colore 0 non sono trasparenti come
  415. accadeva per gli sprite, ma rappresentano il colore di sfondo.
  416. Vedremo successivamente la soluzione a questo problema.
  417.  
  418.