You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
2:v=O<br />
3: for y=yO to yO+OnScreenDim-1<br />
4: u = o<br />
5: screen = ScreenBase + 320 * y<br />
6: texture = TextureBase + TextureDim*int(v)<br />
7: for x=xO to xO+OnScreenDim-1<br />
8: screen[x] = texture[u]<br />
9: u += Step<br />
10: endfor<br />
11: v+=Step<br />
12: endfor<br />
Per facilitare la comprensione abbiamo inserito dei nu-<br />
meri di riga, per mettere in evidenza come le istruzioni in<br />
pseudo-linguaggio vengono tradotte in assembly:<br />
;a0 = ptr alla texture<br />
;al = ptr allo schermo chunky<br />
;dO = u (nel formato 16.16)<br />
;dl = v (nel formato 16.16)<br />
;d2 = xO + OnScreenDim - 1<br />
;d3 = yO + OnScreenDim - 1<br />
;d4 = Step (nel formato 16.16)<br />
;d6 = x<br />
;d7 = y<br />
1: moveq #0,d4<br />
m0ve.w TextureDim,d4<br />
swap d4<br />
moveq #0,d5<br />
m0ve.w OnScreenDim,d5<br />
divu.1 d5,d4 ;d4=Step<br />
2: moveq #O,dl ;dl=v<br />
3: m0ve.w yO,d7 ;d7=y<br />
m0ve.w d7,d3<br />
add.w OnScreenDim,d3<br />
subq.w #l,d3<br />
loopy :<br />
4: moveq #O,dO ; dO=u<br />
5: m0ve.w d7,d5<br />
mu1u.w #320,d5<br />
;al=ptr alla riga attuale dello schermo<br />
move.1 ScreenBase,al<br />
adda.1 d5,al<br />
6: move.1 dl,d5<br />
swap d5<br />
mu1u.w TextureDim,d5<br />
move.1 TextureBase,aO<br />
;aO=ptr alla riga attuale della texture<br />
adda.1 d5,aO<br />
7: m0ve.w xO,d6 ;d6=x<br />
m0ve.w d6,d2<br />
add.w OnScreenDim,d2<br />
subq.w #l,d2<br />
loopx:<br />
8: swap do<br />
m0ve.b (aO,dO.w),(al,d6.w) ;Scrive il pixel<br />
swap do<br />
9: add.1 d4,dO ; u+=Step<br />
10: addq.w #l,d6<br />
cmp.w d2,d6<br />
b1e.s loopx<br />
11: add.1 d4,dl ;v+=Step<br />
12: addq.w #l,d7<br />
cmp.w d3,d7<br />
b1e.s loopy<br />
Analizziamone le parti più importanti. La riga numero 1<br />
esegue la divisione tra due numeri interi, con risultato in<br />
virgola fissa. Questo significa che il dividendo deve esse-<br />
re preventivamente convertito nel formato 16.16 (con l'i-<br />
struzione swap), al contrario del divisore che rimane in<br />
formato intero. Alla riga numero 5 c'è una moltiplicazio-<br />
ne per 320 che serve per calcolare l'offset alla riga di<br />
schermo in cui bisogna scrivere. Immagino sia noto che<br />
è possibile ottimizzare tale operazione in almeno due<br />
modi. I1 primo consiste nel convertire la moltiplicazione<br />
in una serie di operazioni più semplici:<br />
che in assembly può essere scritto come:<br />
I1 secondo metodo è quello più efficiente se si dispone<br />
di fast RAM, e consiste nell'accedere a una tabella precal-<br />
colata di tutte le moltiplicazioni per 320 che ci interessa-<br />
no.<br />
Nel caso di uno schermo da 320x200, una tabella costi-<br />
tuita da 200 long (800 byte) è quello che serve, e la mol-<br />
tiplicazione si scrive semplicemente:<br />
dove a0 contiene l'indirizzo della tabella. La moltiplica-<br />
zione per TextureDim presente alla linea 6 può essere<br />
sostituita con una più veloce istruzione di shift. Le di-<br />
mensioni delle texture sono sempre delle potenze di 2<br />
(nel nostro caso, 128) proprio per permettere ottimizza-<br />
zioni di questo genere.<br />
Come i più esperti avranno notato, il precedente listato<br />
assembly è tradotto direttamente da quello in pseudo-lin-<br />
guaggio, e non è in alcun modo ottimizzato. È decisa-<br />
mente il caso di migliorarlo, portando fuori dai cicli i cal-<br />
coli ridondanti e utilizzando le istruzioni di decremento e<br />
salto (dbra) per la chiusura dei cicli:<br />
moveq #0,d4