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

  1.  
  2. ; Lezione10s.s    Riempimento corretto di un poligono chiuso
  3. ;        tasto destro per blittare, 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. ;    Puntiamo la PIC "vuota"
  19.  
  20.     MOVE.L    #BITPLANE,d0    ; dove puntare
  21.     LEA    BPLPOINTERS,A1    ; puntatori COP
  22.     move.w    d0,6(a1)
  23.     swap    d0
  24.     move.w    d0,2(a1)
  25.  
  26.     lea    $dff000,a5        ; CUSTOM REGISTER in a5
  27.     MOVE.W    #DMASET,$96(a5)        ; DMACON - abilita bitplane, copper
  28.     move.l    #COPPERLIST,$80(a5)    ; Puntiamo la nostra COP
  29.     move.w    d0,$88(a5)        ; Facciamo partire la COP
  30.     move.w    #0,$1fc(a5)        ; Disattiva l'AGA
  31.     move.w    #$c00,$106(a5)        ; Disattiva l'AGA
  32.     move.w    #$11,$10c(a5)        ; Disattiva l'AGA
  33.  
  34.     bsr.w    InitLine    ; inizializza line-mode
  35.  
  36.     move.w    #$ffff,d0    ; linea continua
  37.     bsr.w    SetPattern    ; definisce pattern
  38.  
  39.     move.w    #30,d0        ; x1
  40.     move.w    #125,d1        ; y1
  41.     move.w    #130,d2        ; x2
  42.     move.w    #180,d3        ; y2
  43.     lea    bitplane,a0
  44.     bsr.w    DrawlineFill
  45.  
  46.     move.w    #220,d0        ; x1
  47.     move.w    #105,d1        ; y1
  48.     move.w    #130,d2        ; x2
  49.     move.w    #180,d3        ; y2
  50.     lea    bitplane,a0
  51.     bsr.w    DrawlineFill
  52.  
  53.     move.w    #220,d0        ; x1
  54.     move.w    #105,d1        ; y1
  55.     move.w    #150,d2        ; x2
  56.     move.w    #60,d3        ; y2
  57.     lea    bitplane,a0
  58.     bsr.w    DrawlineFill
  59.  
  60.     move.w    #30,d0        ; x1
  61.     move.w    #125,d1        ; y1
  62.     move.w    #150,d2        ; x2
  63.     move.w    #60,d3        ; y2
  64.     lea    bitplane,a0
  65.     bsr.s    DrawlineFill
  66.  
  67. mouse1:
  68.     btst    #2,$dff016    ; tasto destro del mouse premuto?
  69.     bne.s    mouse1
  70.  
  71.     move.w    #0,d0            ; inclusivo
  72.     move.w    #0,d1            ; CARRYIN = 0
  73.     lea    bitplane+180*40+28,a0
  74.     bsr.s    Fill
  75.  
  76. mouse2:
  77.     btst    #6,$bfe001    ; mouse premuto?
  78.     bne.s    mouse2
  79.  
  80.  
  81.     rts
  82.  
  83.  
  84. ;****************************************************************************
  85. ; Questa routine copia un rettangolo di schermo da una posizione fissa
  86. ; ad un indirizzo specificato come parametro. Il rettangolo di schermo che
  87. ; viene copiato racchiude interamente le 2 linee.
  88. ; Durante la copia viene effettuato anche il riempmento. Il tipo di riempimento
  89. ; e` specificato tramite i parametri.
  90. ; I parametri sono:
  91. ; A0 - indirizzo destinazione
  92. ; D0 - se vale 0 allora effettua fill inclusivo, altrimenti fa fill esclusivo
  93. ; D1 - se vale 0 allora effettua FILL_CARRYIN=0, altrimenti FILL_CARRYIN=1
  94. ;****************************************************************************
  95.  
  96. Fill:
  97.     btst    #6,2(a5) ; dmaconr
  98. WBlit1:
  99.     btst    #6,2(a5) ; dmaconr - attendi che il blitter abbia finito
  100.     bne.s    wblit1
  101.  
  102.     move.w    #$09f0,$40(a5)        ; BLTCON0 copia normale
  103.  
  104.     tst.w    d0            ; testa D0 per decidere il tipo di fill
  105.     bne.s    fill_esclusivo
  106.     move.w    #$000a,d2        ; valore di BLTCON1: settati i bit del
  107.                     ; fill inclusivo e del modo discendente
  108.     bra.s    test_fill_carry
  109.  
  110. fill_esclusivo:
  111.     move.w    #$0012,d2        ; valore di BLTCON1: settati i bit del
  112.                     ; fill esclusivo e del modo discendente
  113.  
  114. test_fill_carry:
  115.     tst.w    d1            ; testa D1 per vedere se deve settare
  116.                     ; il bit FILL_CARRYIN
  117.  
  118.     beq.s    fatto_bltcon1        ; se D1=0 salta..
  119.     bset    #2,d2            ; altrimenti setta il bit 2 di D2
  120.  
  121. fatto_bltcon1:
  122.     move.w    d2,$42(a5)        ; BLTCON1
  123.  
  124.     move.w    #12,$64(a5)        ; BLTAMOD larghezza 14 words (40-28=12)
  125.     move.w    #12,$66(a5)        ; BLTDMOD (40-28=12)
  126.  
  127.     move.l    #bitplane+180*40+28,$50(a5)
  128.                     ; BLTAPT (fisso al rettangolo sorgente)
  129.                     ; il rettangolo sorgente racchiude
  130.                     ; interamente le 2 linee.
  131.                     ; puntiamo l'ultima word del rettangolo
  132.                     ; per via del modo discendente
  133.  
  134.     move.l    a0,$54(a5)        ; BLTDPT  carica il parametro
  135.     move.w    #(64*121)+14,$58(a5)    ; BLTSIZE (via al blitter !)
  136.                     ; larghezza 14 words
  137.                     ; altezza 121 righe (1 plane)
  138.     rts
  139.  
  140.  
  141. ;******************************************************************************
  142. ; Questa routine effettua il disegno di una linea, usando la speciale modalita`
  143. ; che consente di effettuare correttamente il fill. Inoltre la linea e`
  144. ; disegnata dall'alto verso il basso e il primo bit viene lasciato immutato.
  145. ; Prende come parametri gli estremi della linea P1 e P2, e l'indirizzo del
  146. ; bitplane su cui disegnarla.
  147. ; D0 - X1 (coord. X di P1)
  148. ; D1 - Y1 (coord. Y di P1)
  149. ; D2 - X2 (coord. X di P2)
  150. ; D3 - Y2 (coord. Y di P2)
  151. ; A0 - indirizzo bitplane
  152. ;******************************************************************************
  153.  
  154. ;       ("`-/")_.-'"``-._
  155. ;        . . `; -._    )-;-,_`)
  156. ;       (v_,)'  _  )`-.\  ``-'
  157. ;      _.- _..-_/ / ((.'
  158. ;    ((,.-'   ((,/
  159.  
  160. DrawlineFill:
  161.     cmp.w    d1,d3        ; se D3>D1 i punti sono gia` nell'ordine giusto
  162.     bge.w    Ordinati
  163.     exg.l    d1,d3        ; altrimenti scambiali
  164.     exg.l    d0,d2
  165.  
  166. Ordinati:
  167.     sub.w    d1,d3        ; D3=DiffY  (e` sicuramente positivo)
  168.  
  169. * scelta ottante
  170.  
  171.     sub.w    d0,d2        ; D2=X2-X1
  172.     bmi.s    DRAW4        ; se negativo salta, altrimenti D2=DiffX
  173.     cmp.w    d3,d2        ; confronta DiffX e DiffY
  174.     bmi.s    DRAW1        ; se D2<D3 salta..
  175.                 ; .. altrimenti D3=DY e D2=DX
  176.     moveq    #$10,d5        ; codice ottante
  177.     bra.s    DRAWL
  178. DRAW1:
  179.     exg.l    d2,d3        ; scambia D2 e D3, in modo che D3=DY e D2=DX
  180.     moveq    #$00,d5        ; codice ottante
  181.     bra.s    DRAWL
  182. DRAW4:
  183.     neg.w    d2        ; rende D2 positivo
  184.     cmp.w    d3,d2        ; confronta DiffX e DiffY
  185.     bmi.s    DRAW5        ; se D2<D3 salta..
  186.                 ; .. altrimenti D3=DY e D2=DX
  187.     moveq    #$14,d5        ; codice ottante
  188.     bra.s    DRAWL
  189. DRAW5:
  190.     exg.l    d2,d3        ; scambia D2 e D3, in modo che D3=DY e D2=DX
  191.     moveq    #$08,d5        ; codice ottante
  192.     bra.w    DRAWL
  193.  
  194. ; Quando l'esecuzione raggiunge questo punto, abbiamo:
  195. ; D2 = DX
  196. ; D3 = DY
  197. ; D5 = codice ottante
  198.  
  199. DRAWL:
  200.     mulu.w    #40,d1        ; offset Y
  201.     add.l    d1,a0        ; aggiunge l'offset Y all'indirizzo
  202.  
  203.     move.w    d0,d1        ; copia la coordinata X
  204.     lsr.w    #4,d1        ; cancella i 4 bit bassi della X
  205.     add.w    d1,d1        ; ottiene l'offset X in bytes
  206.     add.w    d1,a0        ; aggiunge l'offset X all'indirizzo
  207.  
  208.     and.w    #$000F,d0    ; seleziona i 4 bit piu` bassi della X..
  209.     move.w    d0,d1        ; .. li copia in D1..
  210.     ror.w    #4,d0        ; .. e li sposta nei bit da 12 a 15
  211.     or.w    #$0B4A,d0    ; con un OR ottengo il valore da scrivere
  212.                 ; in BLTCON0. Con questo valore di LF ($4A)
  213.                 ; si disegnano linee in EOR con lo sfondo.
  214.  
  215.     move.l    a0,a1        ; copia l'indirizzo
  216.     cmp.w    #7,d1        ; il numero del bit e` > 7 ?
  217.     ble.s    NonCorreggi    ; se no salta
  218.  
  219.     addq.w    #1,a1        ; ..altrimenti punta al prossimo byte
  220.     subq.w    #8,d1        ; e rendi il numero del bit < 7
  221. NonCorreggi:
  222.     not.b    d1        ; inverti la numerazione dei bit
  223.                 ; questa istruzione e` necessaria perche`
  224.                 ; all'interno del byte i bit sono numerati 
  225.                 ; da destra a sinistra, mentre le coordinate
  226.                 ; dei pixel vanno da sinistra a destra
  227.     bchg    d1,(a1)        ; inverti il primo pixel della linea
  228.  
  229.     move.w    d2,d1        ; copia DX in D1
  230.     addq.w    #1,d1        ; D1=DX+1
  231.     lsl.w    #$06,d1        ; calcola in D1 il valore da mettere in BLTSIZE
  232.     addq.w    #2,d1        ; aggiunge la larghezza, pari a 2 words
  233.  
  234.     lsl.w    #$02,d3        ; D3=4*DY
  235.     add.w    d2,d2        ; D2=2*DX
  236.  
  237.     btst    #$06,$02(a5)
  238. WaitLine:
  239.     btst    #$06,$02(a5)    ; aspetta blitter fermo
  240.     bne.s    WaitLine
  241.  
  242.     move.w    d3,$62(a5)    ; BLTBMOD=4*DY
  243.     sub.w    d2,d3        ; D3=4*DY-2*DX
  244.     move.w    d3,$52(a5)    ; BLTAPTL=4*DY-2*DX
  245.  
  246.                 ; prepara valore da scrivere in BLTCON1
  247.     or.w    #$0003,d5    ; setta bit 0 (attiva line-mode), e
  248.                 ; il bit 1 (linee speciali per fill)
  249.  
  250.     tst.w    d3
  251.     bpl.s    OK1        ; se 4*DY-2*DX>0 salta..
  252.     or.w    #$0040,d5    ; altrimenti setta il bit SIGN
  253. OK1:
  254.     move.w    d0,$40(a5)    ; BLTCON0
  255.     move.w    d5,$42(a5)    ; BLTCON1
  256.     sub.w    d2,d3        ; D3=4*DY-4*DX
  257.     move.w    d3,$64(a5)    ; BLTAMOD=4*DY-4*DX
  258.     move.l    a0,$48(a5)    ; BLTCPT - indirizzo schermo
  259.     move.l    a0,$54(a5)    ; BLTDPT - indirizzo schermo
  260.     move.w    d1,$58(a5)    ; BLTSIZE
  261.     rts
  262.     
  263.  
  264. ;******************************************************************************
  265. ; Questa routine setta i registri del blitter che non devono essere
  266. ; cambiati tra una line e l'altra
  267. ;******************************************************************************
  268.  
  269. InitLine:
  270.     btst    #6,2(a5) ; dmaconr
  271. WBlit_Init:
  272.     btst    #6,2(a5) ; dmaconr - attendi che il blitter abbia finito
  273.     bne.s    Wblit_Init
  274.  
  275.     moveq    #-1,d5
  276.     move.l    d5,$44(a5)        ; BLTAFWM/BLTALWM = $FFFF
  277.     move.w    #$8000,$74(a5)        ; BLTADAT = $8000
  278.     move.w    #40,$60(a5)        ; BLTCMOD = 40
  279.     move.w    #40,$66(a5)        ; BLTDMOD = 40
  280.     rts
  281.  
  282. ;******************************************************************************
  283. ; Questa routine definisce il pattern che deve essere usato per disegnare
  284. ; le linee. In pratica si limita a settare il registro BLTBDAT.
  285. ; D0 - contiene il pattern della linea 
  286. ;******************************************************************************
  287.  
  288. SetPattern:
  289.     btst    #6,2(a5) ; dmaconr
  290. WBlit_Set:
  291.     btst    #6,2(a5) ; dmaconr - attendi che il blitter abbia finito
  292.     bne.s    Wblit_Set
  293.  
  294.     move.w    d0,$72(a5)    ; BLTBDAT = pattern della linea
  295.     rts
  296.  
  297.  
  298. ;****************************************************************************
  299.  
  300.     SECTION    GRAPHIC,DATA_C
  301.  
  302. COPPERLIST:
  303.     dc.w    $8E,$2c81    ; DiwStrt
  304.     dc.w    $90,$2cc1    ; DiwStop
  305.     dc.w    $92,$38        ; DdfStart
  306.     dc.w    $94,$d0        ; DdfStop
  307.     dc.w    $102,0        ; BplCon1
  308.     dc.w    $104,0        ; BplCon2
  309.     dc.w    $108,0        ; Bpl1Mod
  310.     dc.w    $10a,0        ; Bpl2Mod
  311.  
  312.     dc.w    $100,$1200    ; Bplcon0 - 1 bitplane lowres
  313.  
  314. BPLPOINTERS:
  315.     dc.w    $e0,$0000,$e2,$0000    ;primo     bitplane
  316.  
  317.     dc.w    $0180,$000    ; color0
  318.     dc.w    $0182,$eee    ; color1
  319.     dc.w    $FFFF,$FFFE    ; Fine della copperlist
  320.  
  321. ;****************************************************************************
  322.  
  323.     Section    IlMioPlane,bss_C
  324.  
  325. BITPLANE:
  326.     ds.b    40*256        ; bitplane azzerato lowres
  327.  
  328.     end
  329.  
  330. ;****************************************************************************
  331.  
  332. In questo esempio vediamo come risolvere il problema delle linee chiuse.
  333. Come abbiamo spiegato nella lezione, modifichiamo la routine di tracciamento
  334. linee in modo che essa disegni dall'alto in basso. Per questo all'inizio
  335. vengono confrontate le coordinate Y dei 2 punti, e se necessario i 2 punti
  336. vengono scambiati. In questo modo tra l'altro si semplifica il calcolo
  337. dell'ottante in quanto siamo limitati a 4 sole possibilita`.
  338. Inoltre il primo punto della linea viene invertito mediante una BCHG in
  339. modo da annullare l'effetto del tracciamento. Per questo scopo sono necessari
  340. un po' di calcoli in piu` al fine di determinare il numero del bit e il
  341. giusto indirizzo. Infatti, a differenza del blitter, la BCHG opera un byte
  342. alla volta, quindi se necessario bisogna puntare il byte basso della word
  343. puntata dall'indirizzo. Inoltre bisogna anche invertire (con la NOT) la
  344. numerazione dei bit perche` la BCHG numera i bit da destra a sinistra e
  345. invece le coordinate sono numerate da sinistra a destra.
  346. Le altre routines sono identiche.
  347.  
  348.