Ciao AntonioMauro,
come hai già sottolineato tu nel programma usi dei cicli srotolati: considerato il fatto che ha poco senso ottimizzare la parte di impostazione che viene eseguita alla chiamata del raster interrupt (a spanne saranno al max una 50ina di cicli in tutto, stando abbondanti), direi che per il metodo utilizzato - double buffering - non credo ci siano ulteriori possibili ottimizzazioni. Meno di una coppia lda-sta da 8 cicli é proprio impossibile andare.
D'altra parte, come hai fatto giustamente notare, questa implementazione é piuttosto esosa in termini di memoria.
Tenendo dunque presente che qualsiasi compromesso si voglia utilizzare i cicli totali sono necessariamente destinati ad aumentare, ti propongo la mia modifica (trovi i commenti nel codice).
processor 6502
; Costanti
rastline = $B0;
finescrline = $FA;
screenD = $0400;
screen0 = $3800+$8000;
screen1 = $3C00+$8000;
color = $d800
; Variabili zero page
temp = $FF
joy2 = $FE
cscr = $FD
finescroll = $FC
page = $FB
org $0801
word eop
word 7102
byte $9e,"2061",0
eop word 0
org $080D;Inizio del programma
main
sei
;Imposto color MAP
ldx #$00
lpCmpC
lda colormap20X25,x
sta color,x
lda colormap20X25+$100,x
sta color+$100,x
lda colormap20X25+$100*2,x
sta color+$100*2,x
lda colormap20X25+$100*3,x
sta color+$100*3,x
inx
bne lpCmpC
lda #$36;Libero A000-BFFF dalla BASIC ROM RAM (Freshness79)
sta $01
lda #$15;Seleziono banco 2 ($8000-$BFFF 00010101)
sta $dd00
lda #$C4;Posizione di scrolling iniziale e scrolling HW nel mezzo
sta $D016
sta finescroll
lda #$E4;Attivo schermo 0 (11100100 E4)
sta $d018
sta page
lda #$00;Indicatore dello schermo corrente
sta cscr
jsr initIRQ
cli
jmp *;Loop infinito
rts
initIRQ
lda #<routineIRQ;Indirizzo codice (parte alta)
sta $0314
lda #>routineIRQ;Indirizzo codice (parte bassa)
sta $0315
lda #rastline;Raster line di attivazione IRQ raster
sta $d012
lda #$1b;Azzera il bit 7 che sarebbe il Raster Compare: (Bit 8) di $d012
sta $D011
lda #$7f;01111111 BIT 7 a 0
sta $dc0d;Azzera il bit 7 di CIA Interrupt Control Register (Read IRQs/Write Mask) per disattivarlo
sta $dd0d;Azzera il bit 7 di CIA Interrupt Control Register (Read NMls/Write Mask) per disattivarlo
lda $dc0d;Non so a che derve !?!
lda $dd0d;Non so a che derve !?!
lda #$01;Abilita IRQ raster
sta $d019;VIC Interrupt Flag Register (Bit = 1: IRQ Occurred)
sta $d01a;IRQ Mask Register: 1 = Interrupt Enabled
rts
routineIRQ
inc $d019;Dico al vic che la routine è sata eseguita
;Colora una raster line per capire quanto raster consumo per scrollare
inc $d020;riga 1
; ************
; **MODIFICA**
; ************
; Imposto il prossimo raster IRQ
lda #<secondirq
sta $0314
lda #>secondirq
sta $0315
lda #finescrline
sta $d012
; Leggo joy porta 2
lda $DC00
sta joy2;Salvo lo stato del joy2
;scrolla schermo a SX di un carattere
lda joy2;Superfluo in questo punto
and #%00001000;dx
bne lpExit;Se zero salta
;Se diverso da Zero Scroll
;X HW Scroll bit 2-0
ldx $D016
dex
cpx #$C3; - Copiare la prima parte da schermo a 3
bne lpCont1;NO
lda cscr
beq lpSCU;Screen 0
jsr scrollSsxU10
jmp lpCont1
lpSCU
jsr scrollSsxU01
lpCont1
cpx #$C1; - Copiare la seconda parte da schermo a 1
bne lpCont2;NO
lda cscr
beq lpSCD;Screen 0
jsr scrollSsxD10
jmp lpCont2
lpSCD
jsr scrollSsxD01
lpCont2
cpx #$BF;Superato il limite?
bne lpContE;NO
; ************
; **MODIFICA**
; ************
; Basta una sola chiamata allo scroller
; della memoria colore
jsr scrollCsx;Scrolla anche Color Memory
ldx #$C7;Riporta il bit di scroll a 7
lda cscr;Switch screens
beq lpSW1;Screen 0
lda #$E4;Attivo schermo 0
sta page
lda #$00;Indicatore dello schermo corrente
sta cscr
jmp lpContE
lpSW1
lda #$F4;Attivo schermo 1 (11110100 F4)
sta page
lda #$01;Indicatore dello schermo corrente
sta cscr
lpContE
stx finescroll;HW Scroll
lpExit
;Rimetto colore riga a posto
dec $d020
;Queste ultime 6 righe determinano il ritorno del codice all'interrupt HANDLER
;Se voglio creare una routine che venga eseguita mentre il basic è attivo
;sostituisco le 6 righe con JMP $ea31
iret
pla;Pull Accumulator from Stack
tay;transfer A to Y
pla;Pull Accumulator from Stack
tax;transfer A to X
pla;Pull Accumulator from Stack
;JMP $ea31
rti; return from interrupt
; ************
; **MODIFICA**
; ************
; (Da qua in poi e' tutto modificato a parte la mappa)
; IRQ di aggiornamento registri VIC
secondirq
; IRQ Acknowledge
lsr $d019
; Setto il prossimo raster interrupt
lda #<routineIRQ
sta $0314
lda #>routineIRQ
sta $0315
lda #rastline
sta $d012
; Imposto scrolling fine e pagina video:
; farlo in questo secondo interrupt handler
; garantisce di non creare garbage nello schermo
; perche' siamo sul bordo
lda finescroll
sta $d016
lda page
sta $d018
bne iret
; Questa funzione ora copia in un blocco
; unico tutti i byte necessari
scrollCsx
C01 SET 0
REPEAT 1000
lda color+C01+1
sta color+C01
C01 SET C01 + 1
REPEND
rts
; Ho modificato queste 4 funzioni:
; sono tutte e 4 parametriche, dipendono da FRAGMENT.
; FRAGMENT indica in sostanza il numero di cicli
; che deve fare ciascuna funzione.
; Con FRAGMENT alto la copia di impiega di piu' ma la funzione
; occupa meno spazio; con FRAGMENT basso vale il contrario
; i valori possibili per FRAGMENT sono $80,$40 ed $20 (per valori
; piu' bassi bisogna risistemare la bpl perche' diventa
; impossibile tornare all'inizio del ciclo con un branch)
; NB: in effetti, per semplicita', vengono copiati 512 byte
; al posto di 500 in ogni funzione. Su questo c'e' spazio per
; ottimizzare.
; Tieni pero' presente che quando si lavora con l'indirizzamento
; X indexed e' meglio allinearsi alle pagine, il page overflow
; si paga con un ciclo in piu'
FRAGMENT SET $20
scrollSsxU01
ldy #FRAGMENT-1
BASEADU01 SET 0
maincopyloopU01
REPEAT $100/FRAGMENT
lda screen0+BASEADU01+1,y
sta screen1+BASEADU01,y
lda screen0+$100+BASEADU01+1,y
sta screen1+$100+BASEADU01,y
BASEADU01 SET BASEADU01 + FRAGMENT
REPEND
dey
bpl maincopyloopU01
rts
scrollSsxD01
ldy #FRAGMENT-1
BASEADD01 SET 0
maincopyloopD01
REPEAT $100/FRAGMENT
lda screen0+$200+BASEADD01+1,y
sta screen1+$200+BASEADD01,y
lda screen0+$300+BASEADD01+1,y
sta screen1+$300+BASEADD01,y
BASEADD01 SET BASEADD01 + FRAGMENT
REPEND
dey
bpl maincopyloopD01
rts
scrollSsxU10
ldy #FRAGMENT-1
BASEADU10 SET 0
maincopyloopU10
REPEAT $100/FRAGMENT
lda screen1+BASEADU10+1,y
sta screen0+BASEADU10,y
lda screen1+$100+BASEADU10+1,y
sta screen0+$100+BASEADU10,y
BASEADU10 SET BASEADU10 + FRAGMENT
REPEND
dey
bpl maincopyloopU10
rts
scrollSsxD10
ldy #FRAGMENT-1
BASEADD10 SET 0
maincopyloopD10
REPEAT $100/FRAGMENT
lda screen1+$200+BASEADD10+1,y
sta screen0+$200+BASEADD10,y
lda screen1+$300+BASEADD10+1,y
sta screen0+$300+BASEADD10,y
BASEADD10 SET BASEADD10 + FRAGMENT
REPEND
dey
bpl maincopyloopD10
rts
colormap20X25
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $01,$01,$02,$02,$03,$03,$04,$04,$05,$05,$06,$06,$07,$07,$08,$08,$09,$09,$0a,$0a,$0b,$0b,$0c,$0c,$0d,$0d,$0e,$0e,$0f,$0f,$0a,$0a,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c