Autore Topic: Una Bandiera Di Rastersplit  (Letto 1760 volte)

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Una Bandiera Di Rastersplit
« il: 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:
Codice: [Seleziona]
; 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

Codice: [Seleziona]
; 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.
« Ultima modifica: 21 Gennaio 2015, 23:09:07 da eregil »
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -

MarC=ello

  • Utente
  • **
  • Post: 337
  • Gioco Preferito: CBM BASIC 2.0
Una Bandiera Di Rastersplit
« Risposta #1 il: 02 Giugno 2008, 15:44:40 »
 Davvero un ottimo lavoro!  :metallica:  
-=MarC=ellO=-

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Una Bandiera Di Rastersplit
« Risposta #2 il: 02 Giugno 2008, 16:03:06 »
Ecco infine una rielaborazione usando un ciclo. E' limitata a 256 righe e necessariamente piu' "stretta" ma rende bene anche cosi'
Codice: [Seleziona]
; 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
« Ultima modifica: 21 Gennaio 2015, 23:09:33 da eregil »
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Una Bandiera Di Rastersplit
« Risposta #3 il: 02 Giugno 2008, 18:18:41 »
Non ho resistito, dovevo farne una versione da 128bytes :metallica:

Codice: [Seleziona]
; 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

« Ultima modifica: 21 Gennaio 2015, 23:09:56 da eregil »
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -

CobraComm

  • Neo-iscritto
  • *
  • Post: 43
  • Gioco Preferito: Ghosts'N'Goblins,Commando,Ye Ar Kung Fu,MMC 64
Una Bandiera Di Rastersplit
« Risposta #4 il: 02 Giugno 2008, 21:36:09 »
 Davvero carino e interessante!

 :c64:  

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Una Bandiera Di Rastersplit
« Risposta #5 il: 05 Giugno 2008, 22:36:15 »
Citazione da: CobraComm
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.
Codice: [Seleziona]
; 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
« Ultima modifica: 21 Gennaio 2015, 23:10:19 da eregil »
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -