Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: iAN CooG - 06 Giugno 2004, 02:16:16
-
Lungi da me l'idea di essere considerato un demo-coder, ma basta poco davvero per mettere insieme un qualcosa che assomigli a un piccolo intro... il tutto fatto seguendo un tutorial e il solito PRG in formato testo a portata di mano.
;Little HF intro -=[iAN CooG/HokutoForce]=-
timer = $0700
*=$0801
.byte $0b
.byte $08
.byte $be
.byte $1b
.byte $9e
.byte $32
.byte $30
.byte $35
.byte $39
.byte $0
lda #0 ; clear screen using black
jsr $e536
sei
; build timer table @ $0700
; 23 byte of code instead of 40 byte fixed table
ldx #$00
ldy #$00
tlp1 lda #$08 ; 08 08 08 08 08 08 01
inx ; x 5 times
cpx #$08
bne tok1
lda #01
sta $02
ldx #0
tok1 sta timer,y
iny
cpy #$28
bne tlp1
ldx #$04 ; reset to 04xx to allow re-run of
jsr patchstars ; the intro; can be omitted
jsr starpattern
;now automodify the routine
;so next time only colours at $d800 are modified
ldx #$d8
jsr patchstars
;new irq
lda #<irq
sta $0314
lda #>irq
sta $0315
;ldx #$3b ; default values
;stx $d012
;stx irq+3
lda $d011
and #$7f
sta $d011
ldy #$27
prt lda title,y
sta $05e0,y
dey
bpl prt
cli
spc lda $dc01
and #$10; space?
bne spc
;rts
sei
jsr $fd15; reset vectors
jsr $e536; cls in white (FD15 ret w/A=$31)
dex
stx $c6 ; leave no key in buffer
cli
rts ; return to basic
;.................................
irq
ldx #$00
lda #$83
start
cmp $d012
bne start
nop ; wait some cycles
nop ; to make rasters more stable
nop
nop
nop
nop
loop
ldy timer,x
lda color,x
sta $d020
sta $d021
delay
dey
bne delay
inx
cpx #(endcolor-color)
bne loop
;rotating raster : up-down
lda endcolor-2
sta $fe
ldx #(endcolor-color-2)
rotr lda color-1,x
sta color ,x
dex
bne rotr
lda $fe
sta color
;rotating raster : down-up
; lda color
; sta $02
; ldx #00
; rotr lda color+1,x
; sta color ,x
; inx
; cpx #(endcolor-color-1)
; bne rotr
; lda $02
; sta endcolor-2
;---w8 some time
lda $dc05
cmp #$30
bmi xirq
ldx $02
cpx #(endstar-starcolor)
bne conts
ldx #0
conts lda starcolor,x
jsr stars
inx
stx $02
xirq jmp $ea31
;................................
starpattern
;connection lines
ldx #$0f; grey
lda #$21
sta $0502
stx $d902
lda #$27
sta $04B4
stx $d8B4
lda #$2C
sta $0466
stx $d866
lda #$2D
sta $0412
sta $0413
sta $0414
sta $0415
stx $d812
stx $d813
stx $d814
stx $d815
lda #$2E
sta $04B3
sta $043E
stx $d8B3
stx $d83E
; the 7 stars
lda #$2A
stars
sta $0411
sta $0416
sta $048D
sta $04DA
stars2
sta $052A
sta $0553
sta $057C
rts
patchstars
stx stars+2
stx stars+2+3
stx stars+2+6
stx stars+2+9
inx
stx stars2+2
stx stars2+2+3
stx stars2+2+6
rts
color ; italian style r00lz;)
.byte $02,$02,$02,$0a,$00,$02,$0a,$0f,$00
.byte $02,$0a,$0f,$01,$00,$02,$0a,$0f,$01
.byte $01,$01,$0f,$0d,$05,$00,$01,$0f,$0d
.byte $05,$00,$0f,$0d,$05,$00,$0d,$05,$05,$05,$0
endcolor
starcolor
.byte $06,$0e,$03,$01,$01,$07,$08,$09,$0b
endstar
;1234567890123456789012345678901234567890
title .scru "* HOKUTOFORCE: ITALY'S BRIGHTEST STARS *"
title_n
Usare sempre C64asm, soprattutto per la direttiva .SCRU che non trovo in nessun altro xasm
-
cosa fa la direttiva .SCRU ?
-
se non sbaglio,la .SCRU prende i caratteri di una stringa e ne poka in memoria i codici schermo.
-
se non sbaglio,la .SCRU prende i caratteri di una stringa e ne poka in memoria i codici schermo.
Esatto, fa la conversione in screencodes facendo prima l'uppercase della stringa ascii, usando .SCRL invece rispetta il lower/uppercase immesso.
-
Esatto, fa la conversione in screencodes facendo prima l'uppercase della stringa ascii, usando .SCRL invece rispetta il lower/uppercase immesso.
Aiuto! Non ho capito (forse sarà l'ora)... :overkiller:
Buonanotte a tutti! :sonno:
-
Pronto .... parlo col signor Richard Bayliss ? Un certo Ian Coog ti vuole rubare il tuo ruolo in HF :D
-
QUOTE
Esatto, fa la conversione in screencodes facendo prima l'uppercase della stringa ascii, usando .SCRL invece rispetta il lower/uppercase immesso.
Aiuto! Non ho capito (forse sarà l'ora)...
Significa che se le passi una stringa,la .SCRU (=SCREEN UPPER ) ne prende i corrispondenti maiuscoli e ne ricava i codici schermo;la .SCRL (SCREEN LOWER),invece,ricava i codici schermo dei caratteri maiuscoli,se la stringa è scritta in maiuscolo,minuscoli se la stringa è scritta in minuscolo. ;)
-
Significa che se le passi una stringa,la .SCRU (=SCREEN UPPER ) ne prende i corrispondenti maiuscoli e ne ricava i codici schermo;la .SCRL (SCREEN LOWER),invece,ricava i codici schermo dei caratteri maiuscoli,se la stringa è scritta in maiuscolo,minuscoli se la stringa è scritta in minuscolo.
Ahhhhhhhhhh ;)
-
Per motivi di tempo ho provato l'intro solo oggi, e devo dire che mi è piaciuta molto quella stable raster routine! Grande iAN, più passa il tempo più aumenta l'ammirazione che ho nei tuoi confronti, veramente ;) Bravo! :hail:
Ciao a tutti!
And remember... :c64: roolez!
-
Troppo buono Marc=ello, in fin dei conti sono partito modificando un sorgente di un tutorial ;)
La stable raster routine era originariamente nel tutorial molto piu' "grezza" nel senso che c'era la tabella precaricata di 256 bytes
08 08 08 08 08 08 08 01
...
x 64 volte. Uno spreco di bytes immane, ovviamente messa li' giusto per scopo didattico, ma visto che non veniva utilizzata tutta ci ho provato e dopo averla ridotta a solo 40 bytes ho pensato che generandola e buttandola in una zona del video che non si vedesse avrei risparmiato molti byte... non tanti in verita', in questo caso :)
Ad ogni modo fare dei raster stabili e' veramente peggio che spararsi nelle palle. Ancora non ho capito, tabella degli opcode e cicli macchina/istruzione alla mano, perche' sia necessario fare quei 6 NOP (2 cicli l'uno x 6=12) . I cicli macchina impiegati dal raster per passare completamente alla riga successiva sono 63 su un c64 PAL. Ma a me i conti non tornano...
-
Ci sono riuscito... l'ho compilato :metallica: EVVAI!
Davvero bello IAN, complimenti... :ciauz:
-
I cicli macchina impiegati dal raster per passare completamente alla riga successiva sono 63 su un c64 PAL. Ma a me i conti non tornano...
Ho provato a fare il conto del ciclo e mi risulta
loop
ldy timer,x
lda color,x
sta $d020
sta $d021
delay
dey
bne delay
inx
cpx #(endcolor-color)
bne loop
dey + bne delay -> (2+3 cicli macchina) x 7 volte e siamo a 35 cicli totali
dey + bne delay -> (2+2 cicli macchina) x 1 volta ( quando y è 0 non fa più il salto, quindi la bne porta via 2 cicli ) e siamo a 39 cicli totali
inx + cpx + bne loop -> 2+2+3 cicli e siamo a 46 cicli totali
ldy timer,x + lda color,x + sta $d020 + sta $d021 -> 4+4+4+4 cicli e siamo a 62 cicli totali
manca un ciclo,che verrebbe aggiunto all'ultima bne o a una delle ultime 4 istruzioni,nel caso in cui una di queste fosse a cavallo tra una pagina di memoria e l'altra
probabilmente,il ritardo iniziale di 12 cicli serve a far sì che il raster modifichi il colore di una parte della riga di schermo (ma non ne sono sicuro,mò provo a controllare :huh: :D )
Comunque ottimo lavoro! ( ci vuole testa anche per modificare un programma,non soltanto per crearlo ;) ) :ciauz:
-
Ho provato a fare il conto del ciclo e mi risulta
hmm allora sono io che non capisco. :confused:
ldy timer,x + lda color,x + sta $d020 + sta $d021 -> 4+4+4+4 cicli e siamo a 62 cicli totali
Ma questi avvengono dopo, o meglio durante il loop per settare il colore... perche' proprio 12 cicli prima di inziare il loop? E' quello che non capisco.
probabilmente,il ritardo iniziale di 12 cicli serve a far sì che il raster modifichi il colore di una parte della riga di schermo (ma non ne sono sicuro,mò provo a controllare )
Sicuramente, qualsiasi altro ritardo provoca lo spettinamento dei rasters... io voglio capire il perche'. Per ora lo prendo come assioma ma una spiegazione ci deve pur essere.
Comunque ottimo lavoro! ( ci vuole testa anche per modificare un programma,non soltanto per crearlo )
Nella mia vita commodorense non ho fatto altro che modificare i lavori altrui, per imparare si intende :P
Ed e' un ottima pratica per imparare, non mi stanchero' mai di ripeterlo.
Disassemblate, gente, disassemblate. :mechico:
-
Mi hai messo la pulce nell'orecchio.Vediamo un pò... :huh: :fagiano:
-
irq ; line 59
; irq (event) ; 9 [11-20] 14 [11-25] >7 + at least 2 c. of last ins.
; pha ; 3 [21-23] [26-28]
; txa ; 2 [24-25] [29-30]
; pha ; 3 [26-28] [31-33]
; tya ; 2 [29-30] [34-35]
; pha ; 3 [31-33] [36-38]
; tsx ; 2 [34-35] [39-40]
; lda $0104,x ; 4 [36-39] [41-44]
; and #xx ; 2 [40-41] [45-46]
; beq ; 3 [42-44] [47-49]
; jmp ($314) ; 5 [45-49] [50-54]
; go for line 60
ldx #$00 ; 2 [50-51] [55-56]
lda #$83 ; 2 [52-53] [57-58]
start
cmp $d012 ; 4 [54-57] [59-62]
bne start ; 3 [58-60] [63-2]
; .......
; line 161 (bad line)
nop ; 2 [3-4] [9-10]
nop ; 2 [5-6] [55-56]
nop ; 2 [7-8] [57-58]
nop ; 2 [9-10] [59-60]
nop ; 2 [11-55] [61-62]
nop ; 2 [56-57] [63-1]
loop
ldy timer,x ; 4 [58-61] [2-5]
lda color,x ; 4 [62-3] [6-9]
sta $d020 ; 4 [4-7] [10-13]
sta $d021 ; 4 [8-11] [14-17]
Qui la routine rivista con i timing.
Quando avviene un IRQ per raster, esso avviene sempre al ciclo 0 (tranne che per la linea 0, ma non è questo il caso).
Il processore deve però finire l'istruzione che sta eseguendo prima di passare il controllo alla routine di IRQ. Questo implica che l'IRQ inizia con un ritardo di al massimo 7 cicli. Nei commenti, il primo [] indica i cicli eseguiti nel caso più fortunato (l'IRQ eseguito subito). Il sucessivo [] mostra il timing nel caso peggiore.
Tra i due ci sono tutti gli altri casi, ma a noi interessa vedere che tutto funziona nel caso migliore e peggiore.
Dalla mia analisi, questa routine non mi risulta raster (ovvero sincronizzata al singolo cycle), ma syncronizzata quello che basta per avere l'effetto voluto (le barre colorate giuste).
Notate che il ciclo start, serve solo per aspettare la linea 161 che è in bad-line, quindi i cicli da 11 a 54 non sono disponibili per il processore.
I nop servono per dare il ritardo, in modo che quando si cambiano i colori del bordo/schermo, nel caso peggiore ciò avviene il ciclo prima che il raster utilizzi il colore (ciclo 14 e 18)
Nel caso migliore, arriviamo con cicli di vantaggio, ma lo cambiamo quando non è ancora visibile, perciò è ok.
I casi intermedi vanno di conseguenza.
Spero che questo vi abbia illustato il timing, anche se per rendere il raster stabile al ciclo, bisogna annullare i 7 cicli possibili di ritardo e ridurli a 0 e questo è un compito arduo e bisogna utilizzare tecniche particolari (come doppio interrupt e utilizzo di sprite).
bye
S.T.
-
:o :o
-
Ottima spiegazione Stefano. Quindi sia i nop fissi dopo start che il ciclo variabile tramite la tabella timer servono per gestire le badlines, giusto?
-
La parte col ciclo variabile non l'ho ancora analizzata, ma ogni 8 linee c'è la bad line e i cicli macchina si riducono e bisogna tenerne conto (come con i nop iniziali)
bye
S.T.
-
Grazie Ice00 per la spiegazione (ne ho ancora da imparare sulla gestione del raster :overkiller: :D)
Mi piacerebbe visitare la pagina che contiene il sorgente originale,magari lì c'e' la spiegazione dettagliata di alcune scelte programmative :)
Bye
-
Mi piacerebbe visitare la pagina che contiene il sorgente originale,magari lì c'e' la spiegazione dettagliata di alcune scelte programmative :)
Il sorgente fa parte di una grossa compilations di dox+tutorials che fu segnalata tempo fa anche su Lemon64, sono 18Mb zippati, forse si puo' trovare googlando un po' con C64 ML tutorial e simili.