Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: iAN CooG - 02 Giugno 2008, 11:35:11
-
Con l'occasione della festa della repubblica voglio proporre una simpatica bandiera realizzata coi rastersplit.
Che diamine sono i rastersplit?
Il raster impiega 63 cicli a passare da una riga all'altra, normalmente una rasterbar viene fatta settando $d020/$d021, aspettando 63 cicli per far si' che passi alla riga successiva, poi si setta un nuovo colore e cosi' via.
In questo lasso di tempo si puo' colorare lo schermo diverse volte, una STA $d020 impiega SOLO 4 cicli ad essere eseguita. Ogni cambio di colore o modalita' grafica effettuata sulla stessa linea di raster e' un rastersplit.
Con una routine del genere correttamente temporizzata si possono ottenere risultati strabilianti come <a href='http://noname.c64.org/csdb/release/?id=2879' target='_blank'>questo</a>, anche se questo demo e' una sorta di non plus ultra fuori dalla portata di chiunque, a parte pochi eletti gurus del VIC-II.
Iniziamo a vedere come si fa UN solo rastersplit:
; split raster
; versione 1
; singolo raster, schermo spento
; iAN CooG/HokutoForce
*=$0801
word eop
word 7102
byte $9e,[startprg]d,0
eop
word 0
startprg
sei
lda #$35
sta $01
lda #$7f
sta $dc0d
lda $dc0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
lda #<nmi
sta $fffa
lda #>nmi
sta $fffb
lda #$80 ; raster irq posizionata circa a meta' schermo
sta $d012
lda #$0b ; schermo spento, ci basta il colore del bordo
sta $d011 ; ed evitiamo le badlines
lda #01
sta $d01a
sta $d019
cli
jmp *
irq ; testato con vice, debug borders
inc $d019 ; 6 |-47 cicli prima che inizi la nuova riga
sta sa+1 ; 3 |
stx sx+1 ; 3 |
sty sy+1 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
bit $24 ; 3 |
nop ; 2 |
lda #$05 ; 2 |
ldx #$01 ; 2 |
ldy #$02 ; 2 |-0
sta $d020 ; 4 ok, partiamo da qua a contare i cicli
bit $24 ; 3 qua siamo ancora nell'estrema sinistra
bit $24 ; 3
bit $24 ; 3 < il normale bordo e' visibile da qua
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
stx $d020 ; 4
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
sty $d020 ; 3
bit $24 ; 3
bit $24 ; 3
bit $24 ; 3
lda #$00 ; 2
sta $d020 ; 3; 64
sa lda #00 ; 2; qua siamo GIA' sulla prossima riga
sx ldx #00 ; 2
sy ldy #00 ; 2
nmi rti ; 6
ok, una bandiera di 1 pixel in altezza e' un po' poco.
Abbiamo bisogno di ripetere la stessa sequenza su piu' righe, ma il tempo rimasto per ogni riga e' quasi 0, quindi non ci resta che duplicare il codice, senza usare iterazioni dex.. bne che ruberebbero troppi cicli macchina, ma facendo un loop unrolled, usando un paio di macro
; split raster
; versione 2
; molte righe, unrolled con macro, schermo spento
; iAN CooG/HokutoForce
*=$0801
word eop
word 7102
byte $9e,[startprg]d,0
eop
word 0
startprg
sei
lda #$35
sta $01
lda #$7f
sta $dc0d
lda $dc0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
lda #<nmi
sta $fffa
lda #>nmi
sta $fffb
lda #$0b
sta $d012
;lda #$0b
sta $d011
lda #01
sta $d01a
sta $d019
cli
jmp *
MAC SPLIT0
nop
REPEAT 11
bit $24
REPEND
endm
MAC SPLIT1
lda #$05
ldx #$01
ldy #$02
sta $d020
bit $24
bit $24
bit $24
bit $24
stx $d020
bit $24
bit $24
bit $24
bit $24
bit $24
sty $d020
bit $24
bit $24
bit $24
lda #$00
sta $d020
bit $24
ENDM
irq
inc $d019
sta sa+1
stx sx+1
sty sy+1
SPLIT0
REPEAT 280
SPLIT1
REPEND
sa lda #00
sx ldx #00
sy ldy #00
nmi rti
Il codice risultante e' ovviamente enorme, quasi 13k, ma con exomizer lo si riduce a 380bytes.
-
Davvero un ottimo lavoro! :metallica:
-
Ecco infine una rielaborazione usando un ciclo. E' limitata a 256 righe e necessariamente piu' "stretta" ma rende bene anche cosi'
; split raster
; versione 3
; molte righe, con ciclo, schermo spento
; iAN CooG/HokutoForce
*=$0801
word eop
word 7102
byte $9e,[startprg]d,0
eop
word 0
startprg
sei
lda #$35
sta $01
lda #$7f
sta $dc0d
lda $dc0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
lda #<nmi
sta $fffa
lda #>nmi
sta $fffb
lda #$18
sta $d012
lda #$0b
sta $d011
lda #01
sta $d01a
sta $d019
cli
jmp *
irq
inc $d019
sta sa+1
stx sx+1
sty sy+1
nop
bit $24
bit $24
bit $24
bit $24
bit $24
bit $24
bit $24
bit $24
bit $24
bit $24
bit $24
lda #$00
sta $ff
startpiece
lda #$05
ldx #$01
ldy #$02
sta $d020
bit $24
bit $24
bit $24
stx $d020
bit $24
bit $24
bit $24
bit $24
sty $d020
bit $24
bit $24
nop
lda #$00
sta $d020
nop
endpiece
dec $ff
bne startpiece
nop
sa lda #00
sx ldx #00
sy ldy #00
nmi rti
-
Non ho resistito, dovevo farne una versione da 128bytes :metallica:
; split raster
; versione 4
; molte righe, con ciclo, schermo spento + illegals, autostart
; 128 bytes esatti
; iAN CooG/HokutoForce
*=$0326
word newintro
word $F6ED
newintro
sei
lda #$35
sta $01
lda #$7f
sta $dc0d
lda $dc0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
lda #<nmi
sta $fffa
lda #>nmi
sta $fffb
lda #$18
sta $d012
lda #$0b
sta $d011
lda #01
sta $d01a
sta $d019
cli
jmp *
irq
inc $d019
sta sa+1
stx sx+1
sty sy+1
DCP ($c3,X); 2x8
DCP ($c3,X); 2x8
DCP ($c3,X); 2x8
DCP ($c3,X); 2x8
bit $24 ; 2x3
lda #$00
sta $ff
startpiece
lda #$05
ldx #$01
ldy #$02
sta $d020
CMP ($c1,X); 2x6
bit $24 ; 2x3
stx $d020
CMP ($c1,X); 2x6
CMP ($c1,X); 2x6
sty $d020
DCP ($c3,X); 2x8
lda #$00
sta $d020
nop ; 1x2
endpiece
dec $ff
bne startpiece
nop ; 1x2
sa lda #00
sx ldx #00
sy ldy #00
nmi rti
-
Davvero carino e interessante!
:c64:
-
Davvero carino e interessante!
:c64:
Sempre piu' difficile: versione "internazionale" con doppio irq. Premendo Spazio cambiano i colori della bandiera, fino a 8 combinazioni. E' stato un casino stabilizzare il tutto, ho dovuto gestire il "debounce" del tasto controllando lo stato di $dc01 e memorizzandolo in una locazione in zp, e ad ogni pressione sfarfallava e cambiava la posizione orrizontale - cosa che comunque fa ogni volta che si preme Restore - ma a colpi di nop l'ho fatto andare. Tutto rigorosamente entro i 256 bytes.
; split raster
; versione 5, 255 bytes
; molte righe, con ciclo, schermo spento + illegals, autostart
; doppio irq per sentire lo spazio, cambia i colori ad ogni pressione
; iAN CooG/HokutoForce
_Black = 0
_White = 1
_Red = 2
_Cyan = 3
_Purple = 4
_Green = 5
_Blue = 6
_Yellow = 7
_Orange = 8
_Brown = 9
_LightRed = 10
_DarkGrey = 11
_Grey = 12
_LightGreen = 13
_LightBlue = 14
_LightGrey = 15
startline = $18
*=$0326
word newintro
word $F6ED
newintro
sei
lda #$35
sta $01
lda #$7f
sta $dc0d
lda $dc0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
lda #<nmi
sta $fffa
lda #>nmi
sta $fffb
lda #startline
sta $d012
lda #$0b
sta $d011
ldx #01
stx $d01a
stx $d019
dex
;stx $fd; assumo siano a 0 alla partenza
;stx $fe
cli
jmp *
;-------------------------
irq
inc $d019
sta sa+1
stx sx+1
sty sy+1
DCP ($c3,X); 2x8
DCP ($c3,X); 2x8
DCP ($c3,X); 2x8
DCP ($c3,X); 2x8
bit $24 ; 2x3
lda #$00
sta $ff
startpiece
lda #_Green
ldx #_White
ldy #_Red
sta $d020
CMP ($c1,X); 2x6
bit $24 ; 2x3
stx $d020
CMP ($c1,X); 2x6
CMP ($c1,X); 2x6
sty $d020
DCP ($c3,X); 2x8
lda #_DarkGrey
sta $d020
nop ; 1x2
endpiece
dec $ff
bne startpiece
nop ; 1x2
lda #<irq2
sta $fffe
ldy #startline+1
sty $d012
ldy #$9b
sty $d011
sa lda #00
sx ldx #00
sy ldy #00
nmi rti
;-------------------------
irq2
inc $d019
sta za+1
stx zx+1
sty zy+1
;dec $d020
lda $fd
beq notpressed
lda $dc01
and #$10
bne exiz; esci perche' ancora premuto
lda #$0
sta $fd
notpressed
nop
lda $dc01
and #$10
sta $fd
beq exiz
ldx $fe
inx
txa
and #$07
tax
tax; questo e' solo per timing
okflag
stx $fe
lda dataflags1,x
sta startpiece+1
lda dataflags2,x
sta startpiece+1+2
lda dataflags3,x
sta startpiece+1+4
exiz
lda #<irq
sta $fffe
lda #startline
ldy #$0b
sty $d011
sta $d012
;inc $d020
za lda #00
zx ldx #00
zy ldy #00
rti
dataflags1
byte _Blue ; 1
byte _Green ; 2
byte _LightGreen ; 3
byte _Blue ; 4
byte _Red ; 5
byte _LightBlue ; 6
byte _Black ; 7
byte _Red ; 8
dataflags2 ;
byte _White ; 1
byte _White ; 2
byte _White ; 3
byte _Yellow ; 4
byte _White ; 5
byte _Yellow ; 6
byte _Yellow ; 7
byte _Blue ; 8
dataflags3 ;
byte _Red ; 1
byte _Red ; 2
byte _Orange ; 3
byte _Blue ; 4
byte _Red ; 5
byte _White ; 6
byte _Red ; 7
byte _Yellow ; 8