Autore Topic: Sprite Msb  (Letto 6602 volte)

Fabbroz75

  • Utente
  • **
  • Post: 65
  • Gioco Preferito: Aufwiedersehen Monty
Sprite Msb
« il: 16 Ottobre 2012, 12:08:52 »
Ciao a tutti!
Quanto tempo... ma la passione per il nostro per C64 non è mai svanita anzi! Ho recentemente acquistato la 64SDInfinity 2.0 e la EasyFlash per giocare e programmare comodamente, e adesso, rischio anche il divorzio  :gerico:  :lol:

Mi sono rimesso a studiiare l'asm del c64... per rilassarmi dopo sessioni di lavoro in quell'obrobrio di Objective-c :D

Ad ogni modo... ho provato a fare una demo e mi sono imbattuto nel problema dello scrolling degli sprite oltre $ff. Ho letto che per ovviare il problema si utilizza $D010 per espanderli.

Potete aiutarmi a risolvere il problema?
Ho trovato una porzione di codice che ho inserito nel mio.. ma non ho capito come gestirla (vuoi anche per la mia poca esperienza con l'asm c64).

Vi allego tutto il codice + il prg.
in mezzo al codice c'è la subroutine MSB chiamata exp richiamata con un jsr exp prima di irq1

Perdonate i sicuri strafalcioni di coding ma sto imparando :)
Grazie a tutti :)


 
« Ultima modifica: 22 Gennaio 2015, 00:27:36 da eregil »
C64/C64c/C128/C16/Vic20 | 64SD Infinity 2.0 |

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Sprite Msb
« Risposta #1 il: 16 Ottobre 2012, 15:36:06 »
 Ciao Fabbroz,
 mi sono permesso di riscrivere un pezzettino del tuo codice perchè secondo me è più semplice da capire della (giustissima) funzione che hai inserito.
Ecco il pezzo:

Codice: [Seleziona]
;muovo gli sprites
lda #$00
inc $d000
bne skspr1
ora #$01
skspr1
inc $d002
bne skspr2
ora #$02
skspr2.
inc $d004
bne skspr3
ora #$04
skspr3
inc $d006
bne skspr4
ora #$08
skspr4
inc $d008
bne skspr5
ora #$10
skspr5
eor $d010
sta $d010

Questo va a sostituire il corrispondente tratto nel tuo codice (fino a "; scrolling $d016" per intenderci.
Come hai evidenziato tu gli sprite hanno 9 bit di movimento orizzontale: gli 8 bit meno significativi son salvati in altrettanti registri $d000+2*x, il 9° bit di ciascuno di essi è "impacchettato" in unico byte in $d010.
E' chiaro che, in termini di complessità di codice, questa cosa rende piuttosto rognoso muovere ogni sprite oltre il primo byte (>255).
Quella che ti ho proposto sopra è una soluzione, ovviamente ce ne sono molte altre, alcune probabilmente più efficienti.

Ti spiego il primo miniblocco (da "lda #$00" a skspr1), gli altri seguono la medesima logica.

- Parto con accumulatore a 0 (vedremo poi perchè)

1) Incremento gli 8 bit meno significativi del primo sprite (l'istruzione "inc" NON modifica l'accumulatore!!)
2) L'incremento ha dato come risultato 0? Se si, significa che abbiamo oltrepassato il valore 255 (overflow), in questo caso proseguo all'istruzione successiva perchè $d010 dev'essere modificato; in caso contrario la skippo.
3*) La "ora #$01" serve a settare il bit 0 dell'accumulatore (che, siccome verrà poi usato in $d010, rappresenta di fatto il MSb dello sprite 0).

Stessa procedura per gli altri 4 sprite, cambia chiaramente il bit da impostare, rispettivamente:
sprite 0: bit 0 => ora #$01
sprite 1: bit 1 => ora #$02
sprite 2: bit 2 => ora #$04
sprite 3: bit 3 => ora #$08
sprite 4: bit 4 => ora #$10

Le ultime due istruzioni fanno le seguenti cose:
- eor $d010 serve per invertire lo stato del MSb degli sprite che hanno appena sorpassato 255. Chiaramente vengono invertiti i soli sprite per i quali è stato attivato il corrispondente bit nelle istruzioni precedenti.
- sta $d010 ovviamente salva il nuovo valore di $d010

Spero di essere stato esauriente, se qualcosa non è chiaro chiedi pure.
Buon coding!
 

Fabbroz75

  • Utente
  • **
  • Post: 65
  • Gioco Preferito: Aufwiedersehen Monty
Sprite Msb
« Risposta #2 il: 16 Ottobre 2012, 16:56:11 »
Citazione da: "Freshness79"
Ciao Fabbroz,
 mi sono permesso di riscrivere un pezzettino del tuo codice perchè secondo me è più semplice da capire della (giustissima) funzione che hai inserito.
Ecco il pezzo:

Codice: [Seleziona]
;muovo gli sprites
lda #$00
inc $d000
bne skspr1
ora #$01
skspr1
inc $d002
bne skspr2
ora #$02
skspr2.
inc $d004
bne skspr3
ora #$04
skspr3
inc $d006
bne skspr4
ora #$08
skspr4
inc $d008
bne skspr5
ora #$10
skspr5
eor $d010
sta $d010

Questo va a sostituire il corrispondente tratto nel tuo codice (fino a "; scrolling $d016" per intenderci.
Come hai evidenziato tu gli sprite hanno 9 bit di movimento orizzontale: gli 8 bit meno significativi son salvati in altrettanti registri $d000+2*x, il 9° bit di ciascuno di essi è "impacchettato" in unico byte in $d010.
E' chiaro che, in termini di complessità di codice, questa cosa rende piuttosto rognoso muovere ogni sprite oltre il primo byte (>255).
Quella che ti ho proposto sopra è una soluzione, ovviamente ce ne sono molte altre, alcune probabilmente più efficienti.

Ti spiego il primo miniblocco (da "lda #$00" a skspr1), gli altri seguono la medesima logica.

- Parto con accumulatore a 0 (vedremo poi perchè)

1) Incremento gli 8 bit meno significativi del primo sprite (l'istruzione "inc" NON modifica l'accumulatore!!)
2) L'incremento ha dato come risultato 0? Se si, significa che abbiamo oltrepassato il valore 255 (overflow), in questo caso proseguo all'istruzione successiva perchè $d010 dev'essere modificato; in caso contrario la skippo.
3*) La "ora #$01" serve a settare il bit 0 dell'accumulatore (che, siccome verrà poi usato in $d010, rappresenta di fatto il MSb dello sprite 0).

Stessa procedura per gli altri 4 sprite, cambia chiaramente il bit da impostare, rispettivamente:
sprite 0: bit 0 => ora #$01
sprite 1: bit 1 => ora #$02
sprite 2: bit 2 => ora #$04
sprite 3: bit 3 => ora #$08
sprite 4: bit 4 => ora #$10

Le ultime due istruzioni fanno le seguenti cose:
- eor $d010 serve per invertire lo stato del MSb degli sprite che hanno appena sorpassato 255. Chiaramente vengono invertiti i soli sprite per i quali è stato attivato il corrispondente bit nelle istruzioni precedenti.
- sta $d010 ovviamente salva il nuovo valore di $d010

Spero di essere stato esauriente, se qualcosa non è chiaro chiedi pure.
Buon coding!
Grazie, sei stato chiarissimo e dettagliato nella spiegazione.
Ho provato il tuo codice ed ovviamente funziona.

Provo ad analizzarlo bene.
Vedo anche di riscriverlo diversamente (solo per capire ogni singolo passaggio)

Grazie ancora, gentilissimo.
Fab

 
C64/C64c/C128/C16/Vic20 | 64SD Infinity 2.0 |

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Sprite Msb
« Risposta #3 il: 17 Ottobre 2012, 10:07:01 »
 Ogni volta che leggo un post del genere mi torna la voglia di programmare!!!

ps. Freshness79 sei un mito!

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Sprite Msb
« Risposta #4 il: 30 Giugno 2013, 05:11:47 »
 Spero non sia troppo tardi per riesumare questo topic..

Mi potete spiegare il significato di

        bne *-3

che viene scritto la prima volta alla riga 166?
So a cosa serve l'istruzione bne ovviamente ma non capisco l'abbreviazione successiva e soprattutto non riesco a farlo digerire a CBM Program Studio e vorrei tradurlo in qualcosa più comprensibile per entrambi..  ;)
Grazie!
 

tsm_carmine

  • Redazione
  • Utente
  • ****
  • Post: 489
  • Gioco Preferito: Krakout
Sprite Msb
« Risposta #5 il: 30 Giugno 2013, 11:09:27 »
Citazione da: "COMMODORO"
Mi potete spiegare il significato di

        bne *-3
Salto condizionato a 3 byte prima dell'indirizzo corrente.
Riusciremo a costruire un mondo dove più nessuno osi pronunciare le parole... "lettore floppy"?

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Sprite Msb
« Risposta #6 il: 30 Giugno 2013, 17:16:08 »
Citazione da: "tsm_carmine"
Citazione da: "COMMODORO"
Mi potete spiegare il significato di

        bne *-3
Salto condizionato a 3 byte prima dell'indirizzo corrente.
Molte grazie Carmine!
 :)  :)  

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Sprite Msb
« Risposta #7 il: 05 Luglio 2013, 02:57:52 »
 Per favore, chi mi può spiegare perché alla fine del file 01demo.asm vengono usate espressioni come $1000-$7e e $2000-2 al posto del risultato stesso dell'operazione? ( dato che il programma che uso io per esempio non esegue da sé il calcolo durante l' assemblaggio del programma). Motivi di maggior semplicità di lettura? Il risultato non cambia?

Fabbroz75

  • Utente
  • **
  • Post: 65
  • Gioco Preferito: Aufwiedersehen Monty
Re:Sprite Msb
« Risposta #8 il: 13 Maggio 2015, 20:57:22 »
lol, dopo due anni rispondo (scusa) in modo da chiudere correttamente il topic
si è per maggior leggibilità. il risultato non cambia :)

Ringrazio ancora chi mi ha aiutato ;)
C64/C64c/C128/C16/Vic20 | 64SD Infinity 2.0 |