Autore Topic: Barra Multicolore  (Letto 1275 volte)

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Barra Multicolore
« il: 08 Agosto 2004, 07:15:58 »
 Analizzando un vecchio demo ho trovato una routinetta per un bell'effetto.
la routine era
Codice: [Seleziona]
C000  EE 20 D0  INC $D020
C003  EE 20 D0  INC $D020
....
....
C2FD  EE 20 D0  INC $D020
C300  EC 12 D0  CPX $D012
C303  D0 FB     BNE $C300
C305  CA        DEX
C306  4C 00 C0  JMP $C000

Cioe' 256 incrementi del colore del bordo piu' un controllo della posizione
del raster prima del loop.

Per comodita' l'ho convertita in asm (uso DASM)
Codice: [Seleziona]
   org $c000

    SEI      ; queste non c'erano ma sono necessarie
    LDA #0  ; vedremo dopo il perche'
    STA $d011;
lC000
    REPEAT 256
    INC $D020
    REPEND
lC300
    CPX $D012
    BNE lC300
    DEX
    JMP lC000

mi sono detto: ecco un'altra routine da generare. Ma guardando bene in memoria
il generatore della routine c'era gia' :) Ogni tanto qualcuno ci pensava.

Codice: [Seleziona]
1000  4C 0C 10  JMP $100C
1003  EC 12 D0  CPX $D012
1006  D0 FB     BNE $1003
1008  CA        DEX
1009  4C FF FF  JMP $FFFF
100C  78        SEI
100D  A9 00     LDA #$00
100F  85 FB     STA $FB
1011  A9 C0     LDA #$C0
1013  85 FC     STA $FC
1015  A0 00     LDY #$00
1017  A9 EE     LDA #$EE
1019  91 FB     STA ($FB),Y
101B  C8        INY
101C  A9 20     LDA #$20
101E  91 FB     STA ($FB),Y
1020  C8        INY
1021  A9 D0     LDA #$D0
1023  91 FB     STA ($FB),Y
1025  18        CLC
1026  A5 FB     LDA $FB
1028  69 03     ADC #$03
102A  85 FB     STA $FB
102C  A5 FC     LDA $FC
102E  69 00     ADC #$00
1030  85 FC     STA $FC
1032  C9 C3     CMP #$C3
1034  D0 DF     BNE $1015
1036  A5 FB     LDA $FB
1038  C9 00     CMP #$00
103A  D0 D9     BNE $1015
103C  AD 03 10  LDA $1003
103F  A0 00     LDY #$00
1041  91 FB     STA ($FB),Y
1043  C8        INY
1044  B9 03 10  LDA $1003,Y
1047  91 FB     STA ($FB),Y
1049  C8        INY
104A  B9 03 10  LDA $1003,Y
104D  91 FB     STA ($FB),Y
104F  C8        INY
1050  B9 03 10  LDA $1003,Y
1053  91 FB     STA ($FB),Y
1055  C8        INY
1056  B9 03 10  LDA $1003,Y
1059  91 FB     STA ($FB),Y
105B  C8        INY
105C  B9 03 10  LDA $1003,Y
105F  91 FB     STA ($FB),Y
1061  C8        INY
1062  B9 03 10  LDA $1003,Y
1065  91 FB     STA ($FB),Y
1067  C8        INY
1068  A9 00     LDA #$00
106A  91 FB     STA ($FB),Y
106C  C8        INY
106D  A9 C0     LDA #$C0
106F  91 FB     STA ($FB),Y
1071  A9 00     LDA #$00
1073  8D 11 D0  STA $D011
1076  78        SEI
1077  4C 00 C0  JMP $C000
mhhh... gia' c'e' qualcosa che non mi piace, vedo troppe ripetizioni.
L'ho riassemblato cosi'
Codice: [Seleziona]
; prima analisi e commenti
            org $1000

DestAddr = $C000

            JMP realstart  ; cos'e', in stile .COM dei x86?
                          ; non abbiamo bisogno di avere
code2transf                ; un segmento dati dentro il codice
            CPX $D012
            BNE *-3
            DEX
            JMP $FFFF      ; perche' non direttamente $C000?

realstart
            SEI
            LDA #<DestAddr
            STA $FB
            LDA #>DestAddr
            STA $FC
loop
            LDY #$00
            LDA #$EE      ; INC
            STA ($FB),Y
            INY
            LDA #$20      ; <$D020
            STA ($FB),Y
            INY
            LDA #$D0      ; >$D020
            STA ($FB),Y
            CLC
            LDA $FB        ; aggiunge 3 al lowbyte ptr $FB
            ADC #$03
            STA $FB
            LDA $FC        ; questo significa:
            ADC #$00      ; se la prec. addizione setta il
            STA $FC        ; riporto, incrementa $FC...

            CMP #>DestAddr+3; se $300 bytes sono stati scritti
            BNE loop      ; (3 istruzioni x $100 volte...)
            LDA $FB
            CMP #$00      ; CMP #$00 e' sempre evitabile
            BNE loop
            LDA code2transf
            LDY #$00

            STA ($FB),Y    ; quanto codice ripetuto qua ...
            INY
            LDA code2transf,Y
            STA ($FB),Y    ; una per byte in code2transf?
            INY
            LDA code2transf,Y
            STA ($FB),Y    ; che spreco!
            INY
            LDA code2transf,Y
            STA ($FB),Y
            INY
            LDA code2transf,Y
            STA ($FB),Y
            INY
            LDA code2transf,Y
            STA ($FB),Y
            INY
            LDA code2transf,Y
            STA ($FB),Y
            INY
            LDA #<DestAddr; e qui mette l'indirizzo
            STA ($FB),Y    ; della JMP $C000 finale
            INY
            LDA #>DestAddr; se l'avesse precaricato
                          ; si riparmiava anche questo
            STA ($FB),Y
            LDA #$00      ; spegne lo schermo e disabilita
            STA $D011      ; le IRQ, per evitare i soliti
            SEI            ; sfarfallamenti
            JMP DestAddr

Ok, lo possiamo ricostruire :D

Codice: [Seleziona]
;---------------------------------------------
; Nice colourbar generator
; Trovato in "Radio City" by DDG
; Ridotto da 122 a 63 bytes
; iAN CooG/HokutoForce 08/08/04
;---------------------------------------------
            org $0801
DestAddr = $C000

            word eop
            word 7102
            byte $9e
            byte "2059"
            byte 0
eop
;---------------------------------------------
            LDX #$00
            SEI
            LDA #<DestAddr
            STA $FB
            LDA #>DestAddr
            STA $FC
;---------------------------------------------
          ; uso X come contatore
          ; metti EE 20 D0 x 256 volte

            LDY #$00
loop
            LDA #$EE  ; INC
            JSR storebyte
            LDA #$20  ; <$D020
            JSR storebyte
            LDA #$D0  ; >$D020
            JSR storebyte
            DEX
            BNE loop
;---------------------------------------------

            LDY #codeend-code2transf
lastpiece
            LDA code2transf,Y
            STA ($FB),Y
            DEY
            BPL lastpiece
            INY
            STY $D011

code2transf            ; incorporato qui tanto
            CPX $D012  ; non da' fastidio
            BNE *-3    ; aspetta il retrace e
            DEX        ; poi parte :)
            JMP DestAddr
codeend
;---------------------------------------------
storebyte
            STA ($FB),Y; Y sempre 0
            INC $FB
            BNE noinc
            INC $FC    ; solo se $FB e' 0
noinc
            RTS

E' stato sufficiente raggruppare la scrittura dei byte in una subroutine che pensa anche ad incrementare i puntatori ogni volta, e senza bisogno di LDA/ADC/STA.
Poi un ciclo per trasferire i bytes finali di code2transf, che guardacaso potevano benissimo stare proprio dopo il ciclo, perche' conengono gia' anche la JMP per iniziare la routine generata.
La riduzione e' notevole no?
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -

MarC=ello

  • Utente
  • **
  • Post: 337
  • Gioco Preferito: CBM BASIC 2.0
Barra Multicolore
« Risposta #1 il: 09 Agosto 2004, 23:37:16 »
 Ciao iAN!

Stasera sono a pezzi e non ho potuto dare la dovuta attenzione né alla routine di generazione originale né al tuo recoding, comunque sì, ho notato le ripetizioni nella routine di generazione del codice poi da te ben risistemata. Molto interessante.

Ho provato l'effetto della routine, ed è molto interessante. Non avrei mai pensato di poter ottenere un effetto "vite" che si avvolge e trasla con così poche istruzioni... bisogna avere fantasia, sono troppo razionale ancora! Presto spero di diventare più creativo..  :)

Ciao!


 
-=MarC=ellO=-

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Barra Multicolore
« Risposta #2 il: 10 Agosto 2004, 01:04:01 »
 
Citazione da: "MarC=ello"
Ho provato l'effetto della routine, ed è molto interessante. Non avrei mai pensato di poter ottenere un effetto "vite" che si avvolge e trasla con così poche istruzioni... bisogna avere fantasia, sono troppo razionale ancora! Presto spero di diventare più creativo..  :)
Lo speriamo tutti. Intanto ti posso dare la routine di stable raster piu' piccola al mondo (credo)
Codice: [Seleziona]
   sei
loop
    lda #0
    sta $d021
    lda $d012
    sta $d020
    sta $d020
    jmp loop
queste poche istruzioni sono sufficienti a creare la temporizzazione necessaria per far si' che ogni riga abbia il proprio colore e perfettamente stabile. :o

E tanto per fare un indovinello... perche' questo mini programmino funziona
Codice: [Seleziona]
loop
    dec $d021
    bne loop

mentre questo no?

Codice: [Seleziona]
loop
    inc $d021
    bne loop

Sia INC che DEC settano il flag Z quando la locazione diventa 0, no? allora perche' il primo esempio gira all'infinito anche se non dovrebbe? Misteri dei registri del VIC-II :)





 
(hint: i nibble alti di molte locazioni del VIC, come quelli della memoria colore a $D800, non sono collegati, quindi contengono quasi sempre $Fx o addirittura random)
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -