Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: darkj - 13 Dicembre 2005, 13:07:16
-
Premetto che sono alle prime armi con l'assembly del 6510, quindi perdonatemi eventuali incorrettezze.
Sto cercando di scrivere una routine per lo scrolling fluido dello schermo dall'alto verso il basso per fare questo imposto il registro di scrolling vericale con i valori da 0 a 7 (ultimi tre bit) quindi bisognerebbe fare uno shift dello schermo di una riga verso il basso e ricominciare la procedura.
Il massimo che sono riuscito ad ottenere è la seguente routine che a parte un bug sul primo carattere che ancora devo risolvere non è comunque soddisfacente perchè presenta uno scatto vistoso quando lo schermo dopo lo shift verso il basso viene riportato su dall'impostazione a 0 del registo di scrolling. Probabilmente non mi sono spiegato bene ma se eseguite il codice forse sarà più chiaro.
Qualcuno ha qualche suggerimento da darmi? Grazie!
* = $c000
lda $d011 ;entra in modalità 24 righe
and #$f7
sta $d011
;;;;;;;;;;;;;;;
; SCROLLING ;
;;;;;;;;;;;;;;;
inizio ldx #$00
scroll stx $2ffe
lda $d011
and #$f8
clc
adc $2ffe
tay
waitras2 lda $d011 ;attende che il raster sia fuori dallo schermo visibile
and #$80
beq waitras2
tya
sta $d011
inx
txa
ldy #$05 ;ciclo di ritardo
wait3
ldx #$ff ;ciclo di ritardo
wait2 dex
bne wait2
dey
bne wait3
tax
cpx #$08
bcc scroll
;;;;;;;;;;;;;;;;;;;;;;;;
; Copia dello schermo ;
;;;;;;;;;;;;;;;;;;;;;;;;
lda #$c1
sta $02
lda #$07
sta $03
schermo ldy #$00
lda ($02),y
ldy #$28
sta ($02),y
dec $02
bne schermo
ldy #$00
lda ($02),y
ldy #$28
sta ($02),y
lda $03
cmp #$05
bcc fine
dec $03
lda #$ff
sta $02
jmp schermo
fine ldy #$28
lda #$20
riga sta ($02),y
dey
bne riga
sta ($02),y
jmp inizio
-
Tempo fa avevo postato questo:
http://ready64.altervista.org/forum/index....topic=548&st=15 (http://ready64.org/smf/index.php?topic=548.15)
Per ottenere un coarse scrolling verticale che non impiegasse una madonnata di cicli per spostare lo schermo su di una riga, compresi gli attributi colore, avevo risolto con del codice unrolled autogenerato.
-
Grazie mille Ian!!!
Ammazza però ... che lungo! :) Ed io che ero convinto che ci fosse una soluzione molto più breve!!!
A proposito in quel post dici di usare DASM, io ho sempre usato c64asm ma dando un'occhiata superficiale vedo dei comandi a me ignoti quindi dubito di poterlo compilare con c64asm.
Dici che mi conviene passare a DASM? Che caratteristiche differenti ha?
Grazie ancora per la risposta!
-
Ho provato ad assemblare il codice ma vedo che lo scrolling è dal basso verso l'alto mentre a me serviva l'effetto contrario, cioè con i caratteri che scrollano dall'alto verso il basso, pensi che il codice sia facilmente modificabile o non ci provo neanche? Grazie!
-
Dasm e' public domain, e i sorgenti liberi mi hanno permesso di farne modifiche a mio piacimento, tra queste l'implementazione di comandi presenti in C64asm che mi hanno permesso di disfarmi di quest'ultimo che per colpa dei bachi di mala-implementazione mi stava diventando stretto. Sul mio sito trovi la mia versione, comprensiva di dox ampliati con le aggiunte da me apportate.
Per quanto riguarda lo scrolling, puoi evitare di creare un generatore di codice ma farlo in modo semplice tramite l'uso di macro:
N SET 24
REPEAT 24
M SET 39
REPEAT 40
lda $0400 + [40 * [N-1]]+M
sta $0400 + [40 * N] +M
lda $d800 + [40 * [N-1]]+M
sta $d800 + [40 * N] +M
M SET M - 1
REPEND
N SET N - 1
REPEND
a discapito pero' dell'occupazione del codice risultante (11kb solo per il coarse scrolling che quindi sfora oltre $cfff se fai partire il codice da $c000)
Purtroppo occorre temporizzare bene il momento in cui si effettua il coarse: riportando lo smooth scrolling a 0 lo schermo "torna su" di quasi una riga, lo spostamento delle righe da 0-24 a 1-25 deve avvenire il piu' velocemente possibile e anche facendo attenzione che il raster sia oltre il bordo inferiore puo' non bastare.
Su C= Hacking #7 c'e' un articolo che parla di FLD (Flexible line distance) che puo' essere sfruttato se lo scopo e' solo quello di far sparire verso il basso lo schermo (o farlo apparire dal basso verso l'alto) con questo trucco che fa si' che non sia necessario il coarse.
Se pero' lo scopo e' quello di fare che so, un SEU vericale, cioe' quando si muove giu' di una riga , una nuova riga deva apparire alla riga 0, beh non resta che la via del codice unrolled per il coarse e una bella routine cycle exact che usi una o piu' raster interrupt. Buon divertimento :P
-
Dasm e' public domain, e i sorgenti liberi mi hanno permesso di farne modifiche a mio piacimento, tra queste l'implementazione di comandi presenti in C64asm che mi hanno permesso di disfarmi di quest'ultimo che per colpa dei bachi di mala-implementazione mi stava diventando stretto. Sul mio sito trovi la mia versione, comprensiva di dox ampliati con le aggiunte da me apportate.
Ok lo scaricherò e lo proverò, in particolar modo la possibilità di utilizzare delle macro mi sembra molto interessante!
Se pero' lo scopo e' quello di fare che so, un SEU vericale, cioe' quando si muove giu' di una riga , una nuova riga deva apparire alla riga 0, beh non resta che la via del codice unrolled per il coarse e una bella routine cycle exact che usi una o piu' raster interrupt. Buon divertimento :P
Esatto lo scopo finale dovrebbe essere quello!!! ;)
Ho un dubbio, mi dici di utilizzare un codice unrolled per questione di velocità di esecuzione? In modo che lo shift dello schermo risulti "invisibile"? Un codice unrolled non da benefici in termini di velocità di esecuzione solo in cpu di tipo pipelined e quindi più "moderne" del 6510?
-
Un codice unrolled non da benefici in termini di velocità di esecuzione solo in cpu di tipo pipelined e quindi più "moderne" del 6510?
Da' sempre benefici, perche' si impiegano meno cicli macchina (non ci sono controlli ne salti), senza considerare che un lda ($ff),y impiega 5 clicli contro i 4 di una lda $ffff; una sta ($ff),y ne impiega 6 contro i 4 di una sta $ffff; aggiungiamo i dec con 5 cicli, i bne con 2 etc...
Ti faccio una conta veloce dei cicli:
lda #$c1 ; 2
sta $02 ; 3
;
lda #$07 ; 2
sta $03 ; 3
;
schermo ;
ldy #$00 ; 2|22 * 256 = 5632
lda ($02),y ; 5|
ldy #$28 ; 2|
sta ($02),y ; 6|
dec $02 ; 5|
bne schermo ; 2|
ldy #$00 ; 2|
lda ($02),y ; 5|
ldy #$28 ; 2|
sta ($02),y ; 6|
lda $03 ; 3|
cmp #$05 ; 2|
bcc fine ; 2|
dec $03 ; 5|
lda #$ff ; 2|
sta $02 ; 3|
jmp schermo ; 3|(35 +5632)*3 = 17001
;
fine ;
ldy #$28 ; 2
lda #$20 ; 2
riga ;
sta ($02),y ; 6|10*40=400
dey ; 2|
bne riga ; 2|
sta ($02),y ; 6
jmp inizio ; 3
;
totale 17414 (/63= 276 righe di raster!)
Invece una cosa come
lda $0400
sta $0428
lda $d800
sta $d828
(e via per altre 999 ripetizioni) sono tutte da 4 cicli, quindi
16 *1000=16000 cicli
/63= 253 righe di raster! sempre tantissime