home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti_darkcoder / skip / skip.txt < prev    next >
Encoding:
Text File  |  1995-12-06  |  6.8 KB  |  136 lines

  1.  
  2. Come usare l'istruzione SKIP del copper, by The Dark Coder.
  3.  
  4. L'istruzione SKIP fa saltare al copper l'istruzione seguente se il pennello
  5. elettronico ha superato la posizione specificata. Per esempio consideriamo
  6. le seguenti istruzioni:
  7.  
  8.     dc.w    $4037,$ffff    ; SKIP (salta) se si supera la linea $40
  9. ISTR1:    dc.w    $182,$0456    ; istruzione move del copper
  10. ISTR2:    dc.w    $182,$0fff    ; istruzione move del copper
  11.  
  12. Quando il copper esegue l'istruzione SKIP controlla dove si trova il pennello
  13. elettronico. Se esso ha superato la posizione specificata (nell'esempio X=$36
  14. e Y=$40) salta l'istruzione seguente (all'indirizzo ISTR1) ed esegue
  15. l'istruzione successiva ad essa (cioe` l'istruzione all'indirizzo ISTR2).
  16. Se invece il pennello elettronico non ha ancora raggiunto la posizione indicata
  17. viene eseguita nomalmente l'istruzione successiva come se la SKIP non ci fosse.
  18.  
  19. Mediante la SKIP si possono realizzare dei loop nella copperlist. Un loop nella
  20. copperlist e` un insieme di istruzioni copper che viene ripetuto fino a che 
  21. il pennello elettronico non raggiunge una determinata posizione. Per realizzare
  22. il loop si usa anche il registro COP2LC. Il meccanismo e` illustrato dal
  23. seguente esempio:
  24.  
  25. nel programma principale si esegue una
  26.  
  27.     move.l    #Copperloop,$dff084    ; scrive l'indirizzo del loop
  28.                     ; nel registro COP2LC
  29.  
  30. e nella copperlist si mettono le seguenti istruzioni:
  31.  
  32.     dc.w    $2007,$FFFE    ; WAIT linea $20
  33. Copperloop:
  34.     dc.w    $180,$F00    ; istruzioni copper del loop
  35.     dc.w    $180,$0F0
  36.     dc.w    $180,$00F
  37.  
  38.     .
  39.     .
  40.  
  41.     dc.w    $180,$F0F    ; ultima istruzione del loop
  42.     dc.w    $4007,$ffff    ; SKIP (salta) se si supera la linea $40
  43.     dc.w    $8a,0        ; COPJMP2 salta all'inizio del loop
  44.  
  45.     dc.w    $182,$00F    ; istruzione fuori dal loop
  46.  
  47. Il funzionamento e` molto semplice. Dopo la linea $20, il copper entra nel loop
  48. Dopo aver eseguito tutte le istruzioni del loop arrivera` alla SKIP. A questo
  49. punto se il pennello elettronico NON ha ancora superato la linea $40 (cioe` si
  50. trova piu` in alto sullo schermo) il copper NON saltera` l'istruzione seguente.
  51. L'istruzione seguente, pero` scrive in COPJMP2 provocando un salto del copper
  52. all'indirizzo scritto in COP2LC, ovvero all'indirizzo della prima istruzione
  53. del loop. In questo modo il loop viene ripetuto. Dopo un certo numero di
  54. ripetizioni, il pennello elettronico raggiungera` la linea $40. A questo punto
  55. quando viene eseguita di nuovo la SKIP, essa fara` saltare al copper
  56. l'istruzione che scrive in COPJMP2; in questo modo esso non fa piu` il salto
  57. all'inizio del loop ma passa ad eseguire la prima istruzione esterna al loop.
  58.  
  59. A cosa servono i loop nella copperlist? E` chiaro, che possiamo sempre farne
  60. a meno: invece di fare il loop scriviamo tante volte quante ci servono la
  61. parte di copperlist da ripetere. In questo modo ci risparmiamo la SKIP e 
  62. l'istruzione che scrive in COPJMP2, che rallentano un pochettino il copper.
  63. L'uso dei loop presenta pero` dei vantaggi: in primo luogo risparmiamo
  64. memoria, perche` scrivaimo una volta sola il pezzo di copperlist. In secondo
  65. luogo, se il pezzo di copperlist ripetuto deve essere modificato dal processore
  66. per realizzare qualche effetto, naturalmente facendo il loop il pezzo di
  67. copperlist dovra` essere modificato una sola volta, velocizzando moltissimo
  68. il lavoro del processore.
  69.  
  70. L'utilizzo di istruzioni WAIT all'interno dei loop presenta alcuni problemini.
  71. supponiamo di avere un loop che si ripete dalla riga $20 alla riga $70, e
  72. che all'interno del loop ci sia una WAIT alla riga $38. Che succede?
  73. La prima volta che il loop viene eseguito, la WAIT blocca il copper.
  74. Dopo la linea $38 il copper si sblocca, arriva alla fine del loop e lo
  75. ripete. A questo punto, siccome il pennello elettronico ha superato la
  76. riga $38, la WAIT non blocca piu` il copper. Come risultato, l'esecuzione
  77. della prima iterazione del loop produrra` risultati molto diversi dalle
  78. iterazioni successive. Di solito questo non e` cio` che si vuole. Nei loop
  79. con il copper sarebbe desiderabile poter aspettare una determinata riga
  80. del loop ad ogni iterazione. Per esempio si potrebbe volere qualcosa del
  81. genere:
  82.  
  83. CopperLoop:    
  84.         ; istruzioni varie
  85.  
  86.         aspetta 4 righe dall'inizio dell'iterazione
  87.  
  88.         ; istruzioni varie
  89.  
  90.         ripeti il loop fino ad una certa riga.
  91.  
  92. Come si puo` realizzare un meccanismo del genere? E` necessario utilizzare
  93. delle WAIT con mascherati alcuni bit della posizione verticale.
  94. Per esempio supponiamo di avere un loop che si estende per 16 righe di raster
  95. e che vogliamo ripetere dalla riga $10 alla riga $70, ovvero per 96 righe.
  96. Poiche` 96/16=6 il copper eseguira` 6 iterazioni. Notate che 96 e` divisibile
  97. per 16 (non c'e` resto), il che vuol dire che il pennello elettronico
  98. raggiungera` la riga 96 esattamente nel momento in cui il copper finisce
  99. la sesta iterazione. Vogliamo che in ogni iterazione del loop il copper si
  100. blocchi alla quarta riga a partire dall'inizio dell'iterazione. Per ottenere
  101. cio` usiamo una WAIT in cui mascheriamo i bit piu` significativi della
  102. posizione verticale. In questo caso poiche` il loop si ripete ogni 16 righe,
  103. la WAIT si deve comportare allo stesso modo ogni 16 righe, e non deve
  104. considerare le differenze di posizione tra un gruppo di 16 righe e l'altro.
  105. Quindi e` necessario considerare solo i 4 bit meno significativi (che formano
  106. appunto un gruppo di 16 linee). Per mascherare i bit della posizione verticale
  107. si agisce sulla seconda word della WAIT:
  108.  
  109.     dc.w    $0301,$0FFE
  110.  
  111. questa istruzione aspetta la quarta riga di un gruppo di 16 linee.
  112. Vediamo cosa accade nel nostro esempio. Il loop inizia alla riga $20.
  113. Il copper esegue le prime istruzioni e incontra la WAIT. Essa considera
  114. solo i 4 bit meno significativi della posizione per cui si mette ad aspettare
  115. una riga che abbia tali 4 bit al valore $3. Cio` accade alla riga $23. A questo
  116. punto il copper si sblocca. La seconda iterazione del loop inizia alla riga
  117. $30. Anche qui il copper arriva alla WAIT e aspetta una riga che abbia i 4 bit
  118. meno significativi al valore $3, cosa che accade alla riga $33, ovvero ancora
  119. alla quarta riga del loop. Questo comportamento si ripete ad ogni successiva
  120. iterazione. Se volessimo delle iterazioni lunghe 8 righe con delle WAIT di
  121. questo tipo dovremmo lasciare abilitati solo i 3 bit meno significativi della
  122. posizione. Notate che questa tecnica si implementa facilmente solo se la
  123. lunghezza di un iterazione e` una potenza di 2.
  124.  
  125. Un esempio e` in lezioneskip.s
  126.  
  127. Una limitazione all'uso delle WAIT nella maniera che abbiamo mostrato e` dovuta
  128. al fatto che il bit piu` significativo della posizione verticale non e`
  129. mascherabile. Cio` ci impedisce di realizzare loop che si comportino nella
  130. stessa maniera sia al di sopra della riga $80, dove il bit piu` significativo
  131. vale 0, sia al di sotto, dove il bit piu` significativo vale 1, proprio
  132. perche` non possiamo ignorare questa differenza mascherando il bit.
  133. L'unica soluzione e` di fare 2 loop, uno da eseguire al di sopra di $80
  134. e uno al di sotto, come mostrato in lezioneskip2.s
  135.  
  136.