Come suggerisce Jester, come prima ottimizzazione basta ripetere lo lda
, and
, sta
e dey
otto volte. Elimina cpy
e bne
. Questo salverà immediatamente 103 cicli. Anche se si desidera mantenere il loop formale, notare che dey
imposta il flag di zero in modo che non sia necessario lo cpy
.
Come seconda ottimizzazione, prendere in considerazione uno sprite compilato. Invece di eseguire la lettura da sprite, x
, avresti quei valori codificati direttamente nella tua routine, creando una routine distinta per ogni sprite. Questo avrebbe tagliato altri 16 cicli.
Detto questo, il tuo lda
sarebbe 4 cicli in una tabella allineata, non 3. Quindi ci sono 8 che non hai tenuto conto. Ciò significa che srotolato più specializzato per il tuo sprite = 102 cicli (avendo omesso l'ultimo dey
).
Senza conoscere l'architettura C64 e/o il resto del codice, se qualcuno ingerisce SUPERIMPOSED
dalla pagina dello stack, prendere in considerazione la scrittura dell'output nello stack anziché tramite l'indirizzamento indicizzato. È sufficiente caricare s
con un valore seme appropriato e memorizzare nuovi risultati tramite pha
. Ciò consentirà di risparmiare due cicli per archivio al costo di 12 cicli aggiuntivi di installazione e ripristino.
Seguendo questo pensiero, se si ha la libertà di osservare queste tabelle, allora si consiglia di cambiare il loro formato - invece di una tabella che contiene tutti gli otto byte di TILESET
, utilizzare otto tabelle, ognuna delle quali contiene un byte di esso. Ciò eliminerebbe la necessità di regolare y
nel ciclo; basta usare una tabella di destinazione diversa in ciascuna iterazione srotolata.
Supponendo sia TILESET
e SUPERIMPOSED
può essere otto tabelle che si scende a:
LDA TILESET1, x
AND #<value>
STA SUPERIMPOSED1, x ; * 8
[... LDA TILESET2, x ...]
... che è un totale di 88 cicli. Se SUPERIMPOSED
è lineare, ma nella pagina pila poi:
TSX
TXA
LDX #newdest
TXS
TAX ; adds 10
LDA TILESET1, y
AND #<value>
PHA ; * 8
[... LDA TILESET2, y ...]
TXS ; adds 2
... che è di 84 cicli.
Dopo aggiunta:
Se siete disposti a premoltiplicazione dell'indice in x
da 8, riducendo l'intervallo indicizzabile a 32 piastrelle, quindi si può procedere riempimento di una matrice di uscita lineare senza regolazione y, come da:
LDA TILESET, x
AND #<value1>
STA SUPERIMPOSED, x
LDA TILESET+1, x
AND #<value2>
STA SUPERIMPOSED+1, x
... etc ...
Così avresti bisogno di otto copie di quella routine con diversi indirizzi di base tavolo ancora in grado di colpire 256 piastrelle di uscita. Supponendo che tu abbia 20 sprite, questo fa un totale di 20 * 8 = 160 copie della tua routine di plottaggio dello sprite, ognuna delle quali è probabilmente dell'ordine di 100 byte, quindi stai spendendo circa 16kb.
Se il tuo gioco è molto più pesante su un tipo di folletto che su altri - ad es. di solito sono due o tre astronavi che sparano migliaia di proiettili l'uno contro l'altro, quindi ovviamente è possibile ottimizzare in maniera molto selettiva e mantenere basso l'impatto totale.
Srotolare il ciclo per eliminare l'overhead al costo di un aumento del codice. Inoltre sembra che tu stia usando 'x' per l'indicizzazione ma' y' per il ciclo? – Jester
Se il tuo sprite ha più di un pixel di dimensioni e vuoi essere in grado di posizionarlo su qualsiasi pixel hai bisogno di molto più codice, inclusa la possibilità di sovrapporre 2 o 4 caratteri (tessere). Se lo sprite è solo un pixel, puoi semplificare un po 'il codice. –
@RossRidge Non ho ancora finito gli sprite. Quindi non sono sicuro delle dimensioni ma andrà attorno ai 4x4. – wizofwor