Autore Topic: Scrolling Orizzontale  (Letto 5668 volte)

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Scrolling Orizzontale
« Risposta #15 il: 12 Maggio 2010, 21:34:32 »
 Scrivendo align $100 si indica al compilatore che il codice a seguire deve avere un indirizzo multiplo di $100 (ad es $0800,$0c00,$1200 etc).
Se, per caso fortuito, in quel punto l'indirizzo é già allineato a $100 il compilatore non farà assolutamente nulla. Nel caso più frequente nel quale l'ultimo indirizzo non sia invece allineato il compilatore inserirà un certo numero di 0 finché non raggiungerà l'allineamento richiesto.
Ad esempio supponi di avere questo programma

org $1000
lda #$00
sta $d020
rts

align $08

lda #$01
sta $d020
rts

il compilatore genererà il seguente codice:

$1000 $A9 $00
$1002 $8d $20 $d0
$1005 $60
$1006 $00 -> Aggiunto dal compilatore per allineare
$1007 $00 -> Aggiunto dal compilatore per allineare

$1008 $A9 $01 -> Codice allineato a 8 ($1008)
$100a $8d $20 $d0
$100d $60
 

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Scrolling Orizzontale
« Risposta #16 il: 13 Maggio 2010, 00:53:58 »
Ecco una versione con una semplice mappa costituita da 256 colonne da 32 byte ciascuna (dei quali solo 25 usati).
Non so se esistano tool che permettano di lavorare su una mappa di questo genere... solo ho trovato fosse la più semplice da implementare nello scroller.
Il codice in più parti non é probabilmente ottimizzato ma fa comunque il suo mestiere senza skippare alcun frame.
Andrebbe aggiunto l'aggiornamento della mappa colore (eventualmente usando in qualche modo i 7 byte rimanenti in ciascun blocco della mappa) e bisognerebbe inizializzare correttamente i due framebuffer: per il momento per poter visualizzare la mappa bisogna iniziare a muoversi.
« Ultima modifica: 22 Gennaio 2015, 00:16:20 da eregil »

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #17 il: 13 Maggio 2010, 09:34:08 »
 Grazie della preziosa spiegazione!

Sono veramente colpito dalla soluzione adottata per calcolare dinamicamente (codice self-mod) l'indirizzo di origine e destinazione nella split-copy del frame buffer!
Spero di riuscire ad arrivare anch'io questi livelli qualitativi!

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Scrolling Orizzontale
« Risposta #18 il: 14 Maggio 2010, 02:48:49 »
Per la spiegazione nessun problema, sei anzi altri dubbi sulla parte di codice che ho modificato, chiedi pure.
Per quanto riguarda certe routine...mah... non credo ci voglia poi molto ad avere un po' di dimestichezza con le istruzioni ed i metodi di indirizzamento del 6510 e, comunque, una volta acquisita vedrai che é più semplice di quanto tu possa pensare trovare nuove vie per risolvere i problemi. Alla fine é proprio questo il divertimento.
Detto questo... beh... compila lo zip, dovresti riconoscere la mappa che ho caricato ;).
« Ultima modifica: 22 Gennaio 2015, 00:16:49 da eregil »

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #19 il: 14 Maggio 2010, 11:54:22 »
 Fantastico!
Tu non ci crederai ma era proprio il risultato a cui volevo arrivare....
A dir la verità un po mi dispiace avere già sotto mano il risultato finale (ci sarei voluto arrivare con le mie forze) ma sicuramente sarà un ottimo materiale di studio!

Concordo con te che il bello di questo tipo di programmazione è proprio riuscire a trovare dei modi sempre più efficienti per risolvere dei problemi

Attualmente ancora non ho capito bene la logica che sta dietro a
Codice: [Seleziona]
tya   ; uso il valore in Y precedentemente salvato per
lsr   ; calcolare l'high-byte di sorgente e destinazione
ora ixbuf01,x; con una OR ottengo la sorgente
sta dxfrom+2 ;
and #$03 ; rimaschero il valore per annullare la precedente OR
ora ixbuf10,x; con questa OR ottengo la destinazione
sta dxto+2  ;
lda #$00 ; uso il carry generato dalla precedente LSR per avere il valore $00 o $80
ror   ; in questo modo ho la totale distribuzione del carico
sta dxto+1  ; negli 8 spostamenti: $000,$080,$100,$180,$200,$280,$300 e $380
adc #$01  ; la sorgente (FROM) e' un carattere piu' a destra rispetto alla destinazione per avere l'effettivo
sta dxfrom+1; spostamento.
Pensavo che fosse necessario moltiplicare il valore di finescroll presente in Y per $80 per avere l'indirizzo del framebuffer da aggiornare ma non mi pare che funzioni cosi......

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Scrolling Orizzontale
« Risposta #20 il: 14 Maggio 2010, 13:48:05 »
 hmmm..  cercherò di rovinarti meno il gioco nei miei prossimi interventi, magari dandoti suggerimenti piuttosto che postare codice.
Scusami ma spesso mi é più congeniale rispondere con del codice piuttosto che a parole. ;)
Comunque c'é ancora un sacco di roba implementabile e migliorabile, hai ancora tantissimo spazio d'azione!
Detto questo, il codice.
Dunque siamo daccordo che il risultato che cerchiamo é dato dalla formula:

Indirizzo = finetune * $80

In questo modo a seconda del valore di finetune indirizzo punterà a $0000,$0080,$0100... ...$0380.
Ora sarai daccordo che possiamo riformulare l'operazione in questo modo:

Indirizzo = (finetune * $100) /2

Perché scriverla in questo modo? Perché finetune*$100 non é un'operazione, é solamente considerare finetune come hibyte del risultato invece di lowbyte. Con una sola LSR, quindi, otteniamo l'hibyte del risultato e nel carry finisce quello che rappresenta il bit più significativo del lobyte del risultato.
Concretamente:
1 - TYA
mette nell'accumulatore finetune
2 - LSR
divide per 2 l'accumulatore e mette nel carry il bit che servirà al lobyte
A questo punto abbiamo già l'hibyte del risultato giusto
Quindi:
3 - ORA ixbuf01,x
serve ad aggiungere l'hibyte appena calcolato a quello di base del buffer prescelto (x vale 0 oppure 1 a seconda del framebuffer selezionato e ixbuf01 punta ad una coppia di valori che rappresentano il primo l'hibyte base del framebuffer 0 ed il secondo l'hibyte base del framebuffer 1).
4 - STA dxfrom+2
a questo punto ho il primo hibyte completamente calcolato e lo posso salvare nell'indirizzo puntato dall'istruzione dxfrom. Le istruzioni che usano indirizzamento assoluto (o assoluto indicizzato) si compongono di opcode, lobyte e hibyte dell'indirizzo puntato, esattamente in quest'ordine.
Salvando quindi il valore calcolato all'indirizzo dxfrom+2, di fatto imposto l'hibyte dell'indirizzo puntato dall'istruzione in dxfrom.
5 - AND #$03
serve per riottenere il vecchio risultato privo dell'ultima OR che ho fatto. In pratica nell'accumulatore ora ho lo stesso valore che avevo prima del punto 3
6 - ORA ixbuf10,x
con questa OR, in modo simile al punto 3, ottengo l'hibyte della destinazione. ixbuf10 punta a due valori che sono gli stessi di ixbuf01, solo invertiti
7 - STA dxto+2
salvo il risultato nell'hibyte dell'indirizzo puntato dall'istruzione alla locazione dxto
8 - LDA #$00
A questo punto ho completamente sistemato l'hibyte delle due istruzioni di copia, mi interessa mettere a posto il lobyte. Annullo l'accumulatore. Ricorda che c'é un informazione che mi porto dietro dal punto 2, il valore del Carry che rappresenta il bit meno significativo di finetune
9 - ROR
con questa semplice rotazione a destra faccio entrare il valore del carry nel bit più significativo dell'accumulatore: siccome l'accumulatore é nullo a causa dell'istruzione 8 con questa ROR potrà acquisire valore $00 oppure $80, a seconda del carry.
10 - STA dxto+1
lo salvo nel lobyte dell'indirizzo puntato dall'istruzione in dxto (in pratica aggiorno il lobyte della destinazione)
11 - ADC #$01  
aggiungo 1 per la sorgente perché sto spostando lo schermo verso sinistra, non devo preoccuparmi del carry perché dopo la ROR dell'istruzione 9 é sicuramente 0
12 - STA dxfrom+1
salvo quest'ultimo valore come lobyte dell'indirizzo puntato dall'istruzione in dxfrom (aggiorno il lobyte della sorgente)

Ok, spero di essere stato comprensibile ed esauriente!
...A quando un paio di righe in alto sullo schermo con l'indicazione di vite, punti ecc? ;) E di sprite non ne mettiamo?

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #21 il: 14 Maggio 2010, 15:29:59 »
 Innanzi tutto grazie!!!!

Non preoccuparmi per il mio divertimento, sicuramente il codice che posti vale più di mille spiegazione!

Per quanto riguarda la delucidazione sul codice devo dire che ora mi è tutto chiaro anche se rimango ancora molto impressionato dalla genialità ed allo stesso tempo dalla semplicità della soluzione adottata...

Prima di aggiungere sprite et simila voglio studiarmelo ancora un po!

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #22 il: 28 Settembre 2010, 16:44:12 »
 Ho implementato il popolamento iniziale dei due framebuffer (manca ancora la color map) ma c'è un problemino che non riesco a risolvere:
Se all'avvio del programma faccio scorrere verso sinistra ho uno scatto di un carattere....

Codice: [Seleziona]
; Ciclo di inizializzazione della colormap e dei due framebuffer
ldy #$0
ldx #$0
lpCmpC
lda mappointer,x;carico valore
lpSMC
sta screen0  ;Aggiorna schermo
sta screen1  ;Aggiorna schermo

;lda #$01   ;carico valore
;lpSMCcolor
;sta color+990  ;aggiorna color map
      
clc    ;Questo mi cambia dinamicamente il valore di screen0 e screen1 modificando il codice al volo
lda lpSMC+1  ;SCREEN0 h
adc #$28
sta lpSMC+1
clc
lda lpSMC+4  ;SCREEN1 h
adc #$28
sta lpSMC+4
bcc lpSMC1  ;Se non è modificato il carry continua il ciclo
inc lpSMC+2  ;SCREEN0 l
inc lpSMC+5  ;SCREEN1 l

lpSMC1
inx
cpx #$19  ;Sei arrivato al carattere 25
bne lpCmpC  ;no allora ricomincia
     ;si allora mi sposto alla colonna successiva
ldx #$0   ;azzero X
iny    ;incrementa Y

sty lpSMC+1  ;Ricarico il valore screen0 incrementandolo di 1
lda #$B8  ;B8 è la prima parte di $3800 + $8000
sta lpSMC+2
sty lpSMC+4  ;Ricarico il valore screen1 incrementandolo di 1
lda #$BC  ;BC è la prima parte di $3C00 + $8000
sta lpSMC+5

clc    ;Sposto anche mappointer in avanti di 32
lda lpCmpC+1
adc #$20
sta lpCmpC+1
bcc lpSMC2  ;Se non è modificato il carry continua il ciclo
inc lpCmpC+2    
lpSMC2
cpy #$28
bne lpCmpC

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Scrolling Orizzontale
« Risposta #23 il: 30 Settembre 2010, 13:15:30 »
 Ciao Antonio,
 mi fa piacere vedere che ancora ci lavori, la costanza va premiata.
Ho dato un'occhiata al tuo codice e l'ho trovato sostanzialmente corretto; l'ho sistemato un attimo solo per rendere più agibile la fase di test.
Non mi sembra comunque che possa generare dei "buchi".
Potresti mettere essere più preciso sul tipo di problema che hai avuto? Potresti anche postare il codice completo dello scroller, comprensivo del filler che hai realizzato?

Codice: [Seleziona]
; ***********************************************
; Inizializzazione variabili solo a scopo di test
;
*=$1000

screen0 equ $04
screen1 equ $bc
ptr0h equ ptr0+2
ptr0l equ ptr0+1
ptr1h equ ptr1+2
ptr1l equ ptr1+1
mappointer equ $8000
;
; ***********************************************

; Ciclo di inizializzazione della colormap e dei due framebuffer


ldy #$00
ldx #$00
stx ptr0l
stx ptr1l
lda #screen0
sta ptr0h
lda #screen1
sta ptr1h

lpCmpC
lda mappointer,x;carico valore
ptr0
sta $ffff   ;Aggiorna schermo
ptr1
sta $ffff   ;Aggiorna schermo

;lda #$01;carico valore
;lpSMCcolor
;sta color+990;aggiorna color map

clc    ;Questo mi cambia dinamicamente il valore di screen0 e screen1 modificando il codice al volo
lda ptr0l   ;SCREEN0 h
adc #$28
sta ptr0l
sta ptr1l
bcc lpSMC1   ;Se non è modificato il carry continua il ciclo
inc ptr0h   ;SCREEN0 l
inc ptr1h   ;SCREEN1 l

lpSMC1
inx
cpx #$19   ;Sei arrivato al carattere 25
bne lpCmpC   ;no allora ricomincia      
ldx #$00  ;si allora mi sposto alla colonna successiva azzero X
iny    ;incrementa Y

sty ptr0l   ;Ricarico il valore screen0 incrementandolo di 1
lda #screen0 ;B8 è la prima parte di $3800 + $8000
sta ptr0h
sty ptr1l   ;Ricarico il valore screen1 incrementandolo di 1
lda #screen1 ;BC è la prima parte di $3C00 + $8000
sta ptr1h

clc    ;Sposto anche mappointer in avanti di 32
lda lpCmpC+1
adc #$20
sta lpCmpC+1
bcc lpSMC2   ;Se non è modificato il carry continua il ciclo
inc lpCmpC+2
lpSMC2
cpy #$28
bne lpCmpC
rts

Raffox

  • Administrator
  • Utente
  • *****
  • Post: 714
    • http://www.raffox.com
  • Gioco Preferito: Moonshadow (Idea)
Scrolling Orizzontale
« Risposta #24 il: 30 Settembre 2010, 14:49:41 »
 Una domanda...
Perché sta $ffff è ripetuto due volte all'inizio del sorgente?

tsm_carmine

  • Redazione
  • Utente
  • ****
  • Post: 513
  • Gioco Preferito: Krakout
Scrolling Orizzontale
« Risposta #25 il: 30 Settembre 2010, 15:07:15 »
Citazione da: "Raffox"
Una domanda...
Perché sta $ffff è ripetuto due volte all'inizio del sorgente?
Perché quel codice viene modificato in un altro punto del programma, credo.
Riusciremo a costruire un mondo dove più nessuno osi pronunciare le parole... "lettore floppy"?

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Scrolling Orizzontale
« Risposta #26 il: 30 Settembre 2010, 18:23:29 »
 E' corretta la deduzione di Carmine. In linea di massima metto $ffff quando c'é del codice self-modifying, mi scuso per non averlo indicato.
 

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #27 il: 01 Ottobre 2010, 12:26:45 »
 Confermo che le 2 sta vengono alterate nelle istruzioni successive allo scopo di copiare i valori della mappa (memorizzati in maniera orizzontale) sulla memoria video come colonne verticali.

Ecco il codice completo dello scroller (in effetti avevo postato solo la routine di popolamento iniziale).
Per i files contenenti la grafica puoi scaricare l'archivio postato (da te) tempo fa.
Il problema è evidente se provi a scorrere verso sinistra subito dopo l'avvio del programma....lo sfondo scatta subito di un carattere verso destra.

Codice: [Seleziona]
processor 6502

; Costanti
rastline = $30+((25*8)/2)-8; La rasterline iniziale é grosso modo a centro schermo
finescrline = $FA  ; quella finale é nel bordo inferiore
screen0 = $3800+$8000; Framebuffer 0
screen1 = $3C00+$8000;; Framebuffer 1
color = $d800  ; Memoria colore
mappointer = $4000  ; Mappa   (256 "colonne" da 32 byte di cui 25 usati)
mapcolor = $4000+$2000; Mappa  colore (256 "colonne" da 32 byte di cui 25 usati)


; Variabili zero page

; Attenzione! Questo blocco porta via 200 valori di zero page, precisamente
; da $20 a $E7; salvo variare il range non si possono usare queste locazioni
; di memoria per altri scopi
sxupc0 = $20    ; 50 valori che puntano alla colonna 0 del FB 0
sxupc1 = sxupc0+$32  ; 50 valori che puntano alla colonna 0 del FB 1
dxupc0 = sxupc1+$32  ; 50 valori che puntano alla colonna 39 del FB 0
dxupc1 = dxupc0+$32  ; 50 valori che puntano alla colonna 39 del FB 1
posx = $F9  ; Posizione nella mappa
pmap = $FA  ; puntatore usato in più contesti
page = $FC  ; pagina da assegnare a $D018
finescroll = $FD; scrolling fine da assegnare a $D016
cscr = $FE  ; Framebuffer (avrà valore 0/1)


; Codice
 
org $0801
; *********
; Sys Basic
; *********

word eop
word 7102
byte $9e,"2061",0
eop word 0

org $080D; Inizio del programma


; ********************
; Impostazioni di base
; ********************

main
sei

; Ciclo di inizializzazione della colormap e dei due framebuffer
ldy #$0
ldx #$0
lpCmpC
lda mappointer,x;carico valore
lpSMC
sta screen0  ;Aggiorna schermo
sta screen1  ;Aggiorna schermo

;lda #$01  ;carico valore
;lpSMCcolor
;sta color+990  ;aggiorna color map
      
clc    ;Questo mi cambia dinamicamente il valore di screen0 e screen1 modificando il codice al volo
lda lpSMC+1  ;SCREEN0 h
adc #$28
sta lpSMC+1
clc
lda lpSMC+4  ;SCREEN1 h
adc #$28
sta lpSMC+4
bcc lpSMC1  ;Se non è modificato il carry continua il ciclo
inc lpSMC+2  ;SCREEN0 l
inc lpSMC+5  ;SCREEN1 l

lpSMC1
inx
cpx #$19  ;Sei arrivato al carattere 25
bne lpCmpC  ;no allora ricomincia
    ;si allora mi sposto alla colonna successiva
ldx #$0  ;azzero X
iny    ;incrementa Y

sty lpSMC+1  ;Ricarico il valore screen0 incrementandolo di 1
lda #$B8  ;B8 è la prima parte di $3800 + $8000
sta lpSMC+2
sty lpSMC+4  ;Ricarico il valore screen1 incrementandolo di 1
lda #$BC  ;BC è la prima parte di $3C00 + $8000
sta lpSMC+5

clc    ;Sposto anche mappointer in avanti di 32
lda lpCmpC+1
adc #$20
sta lpCmpC+1
bcc lpSMC2  ;Se non è modificato il carry continua il ciclo
inc lpCmpC+2    
lpSMC2
cpy #$28
bne lpCmpC

; Ciclo di inizializzazione dei pointer precalcolati per l'aggiornamento della prima ed ultima colonna
ldx #$31
copyupcpointers
lda sxupdatecol0,x
sta sxupc0,x
lda sxupdatecol1,x
sta sxupc1,x
lda dxupdatecol0,x
sta dxupc0,x
lda dxupdatecol1,x
sta dxupc1,x  
dex
bpl copyupcpointers


lda #$36;Libero A000-BFFF dalla BASIC ROM RAM (Freshness79)
sta $01
lda #$15;Seleziono banco 2 ($8000-$BFFF 00010101)
sta $dd00
lda #$D7;Posizione di scrolling iniziale e scrolling HW nel punto piu' a destra
sta $D016
sta finescroll
lda #$E0;Attivo schermo 0 (11100000 E0)
sta $d018
sta page
lda #$00;Indicatore dello schermo corrente
sta cscr
lda #$00
sta $d020
sta $d021
lda #$0c
sta $d022
lda #$0b
sta $d023
jsr initIRQ
cli
jmp *;Loop infinito

initIRQ
lda #<routineIRQ; Indirizzo codice (parte alta)
sta $0314
lda #>routineIRQ; Indirizzo codice (parte bassa)
sta $0315
lda #rastline; Raster line di attivazione IRQ raster
sta $d012
lda #$1b; Azzera il bit 7 che sarebbe il Raster Compare: (Bit 8) di $d012
sta $D011
lda #$7f; 01111111 BIT 7 a 0
sta $dc0d; Azzera il bit 7 di CIA Interrupt Control Register (Read IRQs/Write Mask) per disattivarlo
sta $dd0d; Azzera il bit 7 di CIA Interrupt Control Register (Read NMls/Write Mask) per disattivarlo
lda $dc0d; Acknowledge di un eventuale IRQ generato dal CIA1 - assicuro che l'unica fonte di interruzione
lda $dd0d; Acknowledge di un eventuale NMI generato dal CIA2 - sia il VIC
lda #$01; Abilita IRQ raster
sta $d019; VIC Interrupt Flag Register (Bit = 1: IRQ Occurred)
sta $d01a; IRQ Mask Register: 1 = Interrupt Enabled
rts

routineIRQ
inc $d019; Dico al vic che la routine è stata eseguita
inc $d020; Colora una raster line per capire quanto raster consumo per scrollare
lda #<secondirq; Imposto il prossimo raster IRQ
sta $0314
lda #>secondirq
sta $0315
lda #finescrline
sta $d012

ldx $d016  ; leggo il finetune corrente
txa  ; lo salvo in X
and #$07  ; quindi lo maschero per recuperare i 3 bit utili
tay  ; e lo salvo in Y, questa e' la posizione corrente.
lda $DC00  ; Leggo il valore del joystick
eor #%00001100; si lavora meglio in logica positiva.
and #%00001100; Seleziono le sole direzioni sx e dx
cmp #%00000100; spostamento a sinistra?
beq jsx  ; si, sposta a sinistra
cmp #%00001000; spostamento a destra?
beq dx  ; si, sposta a destra
jmp lpExit  ; nessun spostamento
jsx
jmp sx
dx  
dex  ; Aggiorno X per ottenere il nuovo valore
txa  ; di scrolling fine
and #$07  ; dopo averlo opportunamente mascherato
ora #$D0  ; e "or-ato" lo salvo
sta finescroll; nella variabile che verra' poi usata nel secondo interrupt
ldx cscr  ; Carico il frame (0 o 1)
tya  ; uso il valore in Y precedentemente salvato per
lsr  ; calcolare l'high-byte di sorgente e destinazione
ora ixbuf01,x; con una OR ottengo la sorgente
sta dxfrom+2;
and #$03; rimaschero il valore per annullare la precedente OR
ora ixbuf10,x; con questa OR ottengo la destinazione
sta dxto+2  ;
lda #$00; uso il carry generato dalla precedente LSR per avere il valore $00 o $80
ror  ; in questo modo ho la totale distribuzione del carico
sta dxto+1  ; negli 8 spostamenti: $000,$080,$100,$180,$200,$280,$300 e $380
adc #$01  ; la sorgente (FROM) e' un carattere piu' a destra rispetto alla destinazione per avere l'effettivo
sta dxfrom+1; spostamento.
ldx #$7f  ; copio i dati con un ciclo (qua si potrebbe srotolare tutto ed ottimizzare)
dxfrom
lda $ffff,x; Indirizzo calcolato nei passaggi precedenti
dxto
sta $ffff,x; IDEM
dex
bpl dxfrom
cpy #$00  ; Abbiamo saltato un intero carattere?
bne dxExit  ; No, possiamo uscire
lda cscr  ; Cambio frame
eor #$01
sta cscr
tax  ; Lo metto in X per usarlo successivamente
lda page  ; Cambio pagina video
eor #$10
sta page
inc posx; incremento la posizione nella mappa
lda #$00; calcolo l'indirizzo base nella mappa
sta pmap;
clc  ;
lda posx;
adc #$27; Aggiungo 39 alla posizione orizzontale perché stiamo aggiornando l'ultima colonna
lsr  ; La rudimentale mappa che ho implementato si compone di blocchi
ror pmap; di 32 byte che vanno da $4000 ad $8fff (256 blocchi). Ciascun
lsr  ; blocco corrisponde ad una colonna verticale nello schermo perciò
ror pmap; dei 32 byte disponibili ne uso solamente 25 (i 7 rimanenti potrebbero
lsr  ; essere usati ad esempio per aggiornare la mappa colore con 1 colore
ror pmap; ogni 4 caratteri - 7x4=28)
ora #(mappointer/$100)
sta pmap+1
lda dxupdbuf,x; Carico l'indirizzo della tabella di valori precalcolati usata
tax  ; per salvare i dati nello schermo
ldy #$00
dxcpcolumn  ;
lda (pmap),y; y scorre lungo i 25 byte del blocco selezionato
sta ($00),x; x scorre nella tabella di 50 valori (25 indirizzi lo/hi)
inx  ; corrispondente alle posizioni dello schermo
inx  ; X=X+2 perché ogni indirizzo porta via due byte
iny  ; Y=Y+1
cpy #$19; abbiamo copiate tutte le 25 righe?
bne dxcpcolumn    
jsr scrollCdx; Aggiornamento della mappa colore (verso destra)
lda cscr
bne dxfix1
jsr fixcoldx0
jmp lpExit
dxfix1
jsr fixcoldx1
dxExit
jmp lpExit

; Gestione movimento a sinistra
; Sono indicate solamente le modifiche
; rispetto alla routine di destra
; il resto e' identico

sx
inx  ; *Incremento
txa
and #$07
ora #$D0
sta finescroll
ldx cscr
tya
lsr  
ora ixbuf01,x
sta sxfrom+2
and #$03
ora ixbuf10,x
sta sxto+2
lda #$00
ror
sta sxfrom+1; sorgente e
adc #$01
sta sxto+1; destinatario invertiti
ldx #$7f
sxfrom
lda $ffff,x
sxto
sta $ffff,x
dex
bpl sxfrom
cpy #$07; Valore limite diverso (7)
bne lpExit
lda cscr
eor #$01
sta cscr
tax
lda page
eor #$10
sta page
dec posx; Decremento della posizione
lda #$00  
sta pmap
lda posx; non serve addizionare $27
lsr
ror pmap
lsr
ror pmap
lsr
ror pmap
ora #(mappointer/$100)
sta pmap+1
lda sxupdbuf,x; uso il buffer per la direzione sinistra
tax
ldy #$00
sxcpcolumn
lda (pmap),y
sta ($00),x
inx
inx
iny
cpy #$19
bne sxcpcolumn    
jsr scrollCsx; spostamento verso sinistra della mappa colore
lda cscr
bne fixsx1
jsr fixcolsx0
jmp lpExit
fixsx1
jsr fixcolsx1
lpExit
dec $d020  ; Fine barra consumo CPU

iret
pla;Pull Accumulator from Stack
tay;transfer A to Y
pla;Pull Accumulator from Stack
tax;transfer A to X
pla;Pull Accumulator from Stack
rti; return from interrupt

secondirq
lsr $d019  ; IRQ Acknowledge
lda #<routineIRQ; Setto la routine principale
sta $0314  ; come prossimo handler del raster interrupt
lda #>routineIRQ
sta $0315
lda #rastline; Fisso la linea alla quale avverrà l'interruzione
sta $d012
lda finescroll; Imposto il finescroll fuori dalla zona video
sta $d016
lda page  ; switch della pagina video (pure questo fuori dalla zona video)
sta $d018
bne iret  ; sempre diverso da 0 qua, equivalente a jmp iret



; *****************************************
; Routine srotolate per l'update del colore
; *****************************************

scrollCdx
C01 SET 0
ldx color
REPEAT 1023
lda color+C01+1
sta color+C01
C01 SET C01 + 1
REPEND
stx color+$3ff
rts

scrollCsx
ldx color+$200
ldy color+$3ff
C01 SET 511
REPEAT 512
lda color+C01
sta color+C01+1
C01 SET C01 -1
REPEND
C01 SET 510
REPEAT 511
lda color+$200+C01
sta color+$200+C01+1
C01 SET C01 -1
REPEND  
sty color
stx color+$201
rts  

fixcolsx0
ROW SET 0
REPEAT 25
ldx screen0+ROW
lda $6000,x
sta color+ROW
ROW SET ROW +40
REPEND
rts

fixcolsx1
ROW SET 0
REPEAT 25
ldx screen1+ROW
lda $6000,x
sta color+ROW
ROW SET ROW +40
REPEND
rts

fixcoldx0
ROW SET 0
REPEAT 25
ldx screen0+39+ROW
lda $6000,x
sta color+39+ROW
ROW SET ROW +40
REPEND
rts

fixcoldx1
ROW SET 0
REPEAT 25
ldx screen1+39+ROW
lda $6000,x
sta color+39+ROW
ROW SET ROW +40  
REPEND
rts

; *******************************************
; Puntatori e tabelle con valori precalcolati
; *******************************************

align 16

ixbuf01
.BYTE screen0/$100,screen1/$100
ixbuf10
.BYTE screen1/$100,screen0/$100
sxupdbuf
.BYTE sxupc0,sxupc1
dxupdbuf
.BYTE dxupc0,dxupc1

dxupdatecol0
.BYTE $27,$00+screen0/$100,$4F,$00+screen0/$100,$77,$00+screen0/$100
.BYTE $9F,$00+screen0/$100,$C7,$00+screen0/$100,$EF,$00+screen0/$100
.BYTE $17,$01+screen0/$100,$3F,$01+screen0/$100,$67,$01+screen0/$100
.BYTE $8F,$01+screen0/$100,$B7,$01+screen0/$100,$DF,$01+screen0/$100
.BYTE $07,$02+screen0/$100,$2F,$02+screen0/$100,$57,$02+screen0/$100
.BYTE $7F,$02+screen0/$100,$A7,$02+screen0/$100,$CF,$02+screen0/$100
.BYTE $F7,$02+screen0/$100,$1F,$03+screen0/$100,$47,$03+screen0/$100
.BYTE $6F,$03+screen0/$100,$97,$03+screen0/$100,$BF,$03+screen0/$100
.BYTE $E7,$03+screen0/$100
dxupdatecol1
.BYTE $27,$00+screen1/$100,$4F,$00+screen1/$100,$77,$00+screen1/$100
.BYTE $9F,$00+screen1/$100,$C7,$00+screen1/$100,$EF,$00+screen1/$100
.BYTE $17,$01+screen1/$100,$3F,$01+screen1/$100,$67,$01+screen1/$100
.BYTE $8F,$01+screen1/$100,$B7,$01+screen1/$100,$DF,$01+screen1/$100
.BYTE $07,$02+screen1/$100,$2F,$02+screen1/$100,$57,$02+screen1/$100
.BYTE $7F,$02+screen1/$100,$A7,$02+screen1/$100,$CF,$02+screen1/$100
.BYTE $F7,$02+screen1/$100,$1F,$03+screen1/$100,$47,$03+screen1/$100
.BYTE $6F,$03+screen1/$100,$97,$03+screen1/$100,$BF,$03+screen1/$100
.BYTE $E7,$03+screen1/$100
sxupdatecol0
.BYTE $00,$00+screen0/$100,$28,$00+screen0/$100,$50,$00+screen0/$100
.BYTE $78,$00+screen0/$100,$A0,$00+screen0/$100,$C8,$00+screen0/$100
.BYTE $F0,$00+screen0/$100,$18,$01+screen0/$100,$40,$01+screen0/$100
.BYTE $68,$01+screen0/$100,$90,$01+screen0/$100,$B8,$01+screen0/$100
.BYTE $E0,$01+screen0/$100,$08,$02+screen0/$100,$30,$02+screen0/$100
.BYTE $58,$02+screen0/$100,$80,$02+screen0/$100,$A8,$02+screen0/$100
.BYTE $D0,$02+screen0/$100,$F8,$02+screen0/$100,$20,$03+screen0/$100
.BYTE $48,$03+screen0/$100,$70,$03+screen0/$100,$98,$03+screen0/$100
.BYTE $C0,$03+screen0/$100
sxupdatecol1
.BYTE $00,$00+screen1/$100,$28,$00+screen1/$100,$50,$00+screen1/$100
.BYTE $78,$00+screen1/$100,$A0,$00+screen1/$100,$C8,$00+screen1/$100
.BYTE $F0,$00+screen1/$100,$18,$01+screen1/$100,$40,$01+screen1/$100
.BYTE $68,$01+screen1/$100,$90,$01+screen1/$100,$B8,$01+screen1/$100
.BYTE $E0,$01+screen1/$100,$08,$02+screen1/$100,$30,$02+screen1/$100
.BYTE $58,$02+screen1/$100,$80,$02+screen1/$100,$A8,$02+screen1/$100
.BYTE $D0,$02+screen1/$100,$F8,$02+screen1/$100,$20,$03+screen1/$100
.BYTE $48,$03+screen1/$100,$70,$03+screen1/$100,$98,$03+screen1/$100
.BYTE $C0,$03+screen1/$100

*=$4000
incbin "map.bin"
incbin "colors.bin"
*=$8000
incbin "chars.bin"

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #28 il: 05 Ottobre 2010, 15:06:10 »
 Risolto!
In effetti è bastato inizializzare il secondo framebuffer con lo schermo già scrollato di un carattere (come è ovvio che sia)
Adesso mi manca solo l'init della colormap!

Codice: [Seleziona]
processor 6502

; Costanti
rastline = $30+((25*8)/2)-8; La rasterline iniziale é grosso modo a centro schermo
finescrline = $FA  ; quella finale é nel bordo inferiore
screen0 = $3800+$8000 ; Framebuffer 0
screen1 = $3C00+$8000; ; Framebuffer 1
color = $d800   ; Memoria colore
mappointer = $4000  ; Mappa   (256 "colonne" da 32 byte di cui 25 usati)
mapcolor = $4000+$2000 ; Mappa  colore (256 "colonne" da 32 byte di cui 25 usati)


; Variabili zero page

; Attenzione! Questo blocco porta via 200 valori di zero page, precisamente
; da $20 a $E7; salvo variare il range non si possono usare queste locazioni
; di memoria per altri scopi
sxupc0 = $20    ; 50 valori che puntano alla colonna 0 del FB 0
sxupc1 = sxupc0+$32  ; 50 valori che puntano alla colonna 0 del FB 1
dxupc0 = sxupc1+$32  ; 50 valori che puntano alla colonna 39 del FB 0
dxupc1 = dxupc0+$32  ; 50 valori che puntano alla colonna 39 del FB 1
posx = $F9   ; Posizione nella mappa
pmap = $FA   ; puntatore usato in più contesti
page = $FC   ; pagina da assegnare a $D018
finescroll = $FD ; scrolling fine da assegnare a $D016
cscr = $FE   ; Framebuffer (avrà valore 0/1)


; Codice
 
org $0801
; *********
; Sys Basic
; *********

word eop
word 7102
byte $9e,"2061",0
eop word 0

org $080D; Inizio del programma


; ********************
; Impostazioni di base
; ********************

main
sei

; Ciclo di inizializzazione della colormap e dei due framebuffer
ldy #$0
ldx #$0
lpCmpC
lda mappointer,x;carico valore
lpSMC
sta screen0  ;Aggiorna schermo

;lda #$01   ;carico valore
;lpSMCcolor
;sta color+990  ;aggiorna color map
      
clc    ;Questo mi cambia dinamicamente il valore di screen0 e screen1 modificando il codice al volo
lda lpSMC+1  ;SCREEN0 h
adc #$28
sta lpSMC+1
bcc lpSMC1  ;Se non è modificato il carry continua il ciclo
inc lpSMC+2  ;SCREEN0 l

lpSMC1
inx
cpx #$19  ;Sei arrivato al carattere 25
bne lpCmpC  ;no allora ricomincia
     ;si allora mi sposto alla colonna successiva
ldx #$0   ;azzero X
iny    ;incrementa Y

sty lpSMC+1  ;Ricarico il valore screen0 incrementandolo di 1
lda #$B8  ;B8 è la prima parte di $3800 + $8000
sta lpSMC+2

clc    ;Sposto anche mappointer in avanti di 32
lda lpCmpC+1
adc #$20
sta lpCmpC+1
bcc lpSMC2  ;Se non è modificato il carry continua il ciclo
inc lpCmpC+2    
lpSMC2
cpy #$28
bne lpCmpC

; Ciclo di inizializzazione dei pointer precalcolati per l'aggiornamento della prima ed ultima colonna
ldx #$31
copyupcpointers
lda sxupdatecol0,x
sta sxupc0,x
lda sxupdatecol1,x
sta sxupc1,x
lda dxupdatecol0,x
sta dxupc0,x
lda dxupdatecol1,x
sta dxupc1,x  
dex
bpl copyupcpointers


lda #$36;Libero A000-BFFF dalla BASIC ROM RAM (Freshness79)
sta $01
lda #$15;Seleziono banco 2 ($8000-$BFFF 00010101)
sta $dd00
lda #$D7;Posizione di scrolling iniziale e scrolling HW nel punto piu' a destra
sta $D016
sta finescroll
lda #$E0;Attivo schermo 0 (11100000 E0)
sta $d018
sta page
lda #$00;Indicatore dello schermo corrente
sta cscr

;Copia lo schermo già scrollato a SX su SCREEN 0
ldx #$00
lpInitScreen1
lda screen0,x
sta screen1+1,x
lda screen0+256,x
sta screen1+1+256,x
lda screen0+512,x
sta screen1+1+512,x
lda screen0+768,x
sta screen1+1+768,x
inx
bne lpInitScreen1
      
lda #$00 ;Continuia inizializzazione
sta $d020
sta $d021
lda #$0c
sta $d022
lda #$0b
sta $d023
jsr initIRQ
cli
jmp * ;Loop infinito

initIRQ
lda #<routineIRQ; Indirizzo codice (parte alta)
sta $0314
lda #>routineIRQ; Indirizzo codice (parte bassa)
sta $0315
lda #rastline; Raster line di attivazione IRQ raster
sta $d012
lda #$1b ; Azzera il bit 7 che sarebbe il Raster Compare: (Bit 8) di $d012
sta $D011
lda #$7f ; 01111111 BIT 7 a 0
sta $dc0d ; Azzera il bit 7 di CIA Interrupt Control Register (Read IRQs/Write Mask) per disattivarlo
sta $dd0d ; Azzera il bit 7 di CIA Interrupt Control Register (Read NMls/Write Mask) per disattivarlo
lda $dc0d ; Acknowledge di un eventuale IRQ generato dal CIA1 - assicuro che l'unica fonte di interruzione
lda $dd0d ; Acknowledge di un eventuale NMI generato dal CIA2 - sia il VIC
lda #$01 ; Abilita IRQ raster
sta $d019 ; VIC Interrupt Flag Register (Bit = 1: IRQ Occurred)
sta $d01a ; IRQ Mask Register: 1 = Interrupt Enabled
rts

routineIRQ
inc $d019 ; Dico al vic che la routine è stata eseguita
inc $d020 ; Colora una raster line per capire quanto raster consumo per scrollare
lda #<secondirq; Imposto il prossimo raster IRQ
sta $0314
lda #>secondirq
sta $0315
lda #finescrline
sta $d012

ldx $d016  ; leggo il finetune corrente
txa   ; lo salvo in X
and #$07  ; quindi lo maschero per recuperare i 3 bit utili
tay   ; e lo salvo in Y, questa e' la posizione corrente.
lda $DC00  ; Leggo il valore del joystick
eor #%00001100; si lavora meglio in logica positiva.
and #%00001100; Seleziono le sole direzioni sx e dx
cmp #%00000100; spostamento a sinistra?
beq jsx  ; si, sposta a sinistra
cmp #%00001000; spostamento a destra?
beq dx   ; si, sposta a destra
jmp lpExit  ; nessun spostamento
jsx
jmp sx
dx  
dex   ; Aggiorno X per ottenere il nuovo valore
txa   ; di scrolling fine
and #$07  ; dopo averlo opportunamente mascherato
ora #$D0  ; e "or-ato" lo salvo
sta finescroll; nella variabile che verra' poi usata nel secondo interrupt
ldx cscr  ; Carico il frame (0 o 1)
tya   ; uso il valore in Y precedentemente salvato per
lsr   ; calcolare l'high-byte di sorgente e destinazione
ora ixbuf01,x; con una OR ottengo la sorgente
sta dxfrom+2 ;
and #$03 ; rimaschero il valore per annullare la precedente OR
ora ixbuf10,x; con questa OR ottengo la destinazione
sta dxto+2  ;
lda #$00 ; uso il carry generato dalla precedente LSR per avere il valore $00 o $80
ror   ; in questo modo ho la totale distribuzione del carico
sta dxto+1  ; negli 8 spostamenti: $000,$080,$100,$180,$200,$280,$300 e $380
adc #$01  ; la sorgente (FROM) e' un carattere piu' a destra rispetto alla destinazione per avere l'effettivo
sta dxfrom+1; spostamento.
ldx #$7f  ; copio i dati con un ciclo (qua si potrebbe srotolare tutto ed ottimizzare)
dxfrom
lda $ffff,x ; Indirizzo calcolato nei passaggi precedenti
dxto
sta $ffff,x ; IDEM
dex
bpl dxfrom
cpy #$00  ; Abbiamo saltato un intero carattere?
bne dxExit  ; No, possiamo uscire
lda cscr  ; Cambio frame
eor #$01
sta cscr
tax   ; Lo metto in X per usarlo successivamente
lda page  ; Cambio pagina video
eor #$10
sta page
inc posx ; incremento la posizione nella mappa
lda #$00 ; calcolo l'indirizzo base nella mappa
sta pmap ;
clc   ;
lda posx ;
adc #$27 ; Aggiungo 39 alla posizione orizzontale perché stiamo aggiornando l'ultima colonna
lsr   ; La rudimentale mappa che ho implementato si compone di blocchi
ror pmap ; di 32 byte che vanno da $4000 ad $8fff (256 blocchi). Ciascun
lsr   ; blocco corrisponde ad una colonna verticale nello schermo perciò
ror pmap ; dei 32 byte disponibili ne uso solamente 25 (i 7 rimanenti potrebbero
lsr   ; essere usati ad esempio per aggiornare la mappa colore con 1 colore
ror pmap ; ogni 4 caratteri - 7x4=28)
ora #(mappointer/$100)
sta pmap+1
lda dxupdbuf,x; Carico l'indirizzo della tabella di valori precalcolati usata
tax   ; per salvare i dati nello schermo
ldy #$00
dxcpcolumn  ;
lda (pmap),y; y scorre lungo i 25 byte del blocco selezionato
sta ($00),x ; x scorre nella tabella di 50 valori (25 indirizzi lo/hi)
inx   ; corrispondente alle posizioni dello schermo
inx   ; X=X+2 perché ogni indirizzo porta via due byte
iny   ; Y=Y+1
cpy #$19 ; abbiamo copiate tutte le 25 righe?
bne dxcpcolumn    
jsr scrollCdx; Aggiornamento della mappa colore (verso destra)
lda cscr
bne dxfix1
jsr fixcoldx0
jmp lpExit
dxfix1
jsr fixcoldx1
dxExit
jmp lpExit

; Gestione movimento a sinistra
; Sono indicate solamente le modifiche
; rispetto alla routine di destra
; il resto e' identico

sx
inx   ; *Incremento
txa
and #$07
ora #$D0
sta finescroll
ldx cscr
tya
lsr  
ora ixbuf01,x
sta sxfrom+2
and #$03
ora ixbuf10,x
sta sxto+2
lda #$00
ror
sta sxfrom+1; sorgente e
adc #$01
sta sxto+1 ; destinatario invertiti
ldx #$7f
sxfrom
lda $ffff,x
sxto
sta $ffff,x
dex
bpl sxfrom
cpy #$07 ; Valore limite diverso (7)
bne lpExit
lda cscr
eor #$01
sta cscr
tax
lda page
eor #$10
sta page
dec posx ; Decremento della posizione
lda #$00  
sta pmap
lda posx ; non serve addizionare $27
lsr
ror pmap
lsr
ror pmap
lsr
ror pmap
ora #(mappointer/$100)
sta pmap+1
lda sxupdbuf,x; uso il buffer per la direzione sinistra
tax
ldy #$00
sxcpcolumn
lda (pmap),y
sta ($00),x
inx
inx
iny
cpy #$19
bne sxcpcolumn    
jsr scrollCsx; spostamento verso sinistra della mappa colore
lda cscr
bne fixsx1
jsr fixcolsx0
jmp lpExit
fixsx1
jsr fixcolsx1
lpExit
dec $d020  ; Fine barra consumo CPU

iret
pla ;Pull Accumulator from Stack
tay ;transfer A to Y
pla ;Pull Accumulator from Stack
tax ;transfer A to X
pla ;Pull Accumulator from Stack
rti ; return from interrupt

secondirq
lsr $d019  ; IRQ Acknowledge
lda #<routineIRQ; Setto la routine principale
sta $0314  ; come prossimo handler del raster interrupt
lda #>routineIRQ
sta $0315
lda #rastline ; Fisso la linea alla quale avverrà l'interruzione
sta $d012
lda finescroll ; Imposto il finescroll fuori dalla zona video
sta $d016
lda page  ; switch della pagina video (pure questo fuori dalla zona video)
sta $d018
bne iret  ; sempre diverso da 0 qua, equivalente a jmp iret



; *****************************************
; Routine srotolate per l'update del colore
; *****************************************

scrollCdx
C01 SET 0
ldx color
REPEAT 1023
lda color+C01+1
sta color+C01
C01 SET C01 + 1
REPEND
stx color+$3ff
rts

scrollCsx
ldx color+$200
ldy color+$3ff
C01 SET 511
REPEAT 512
lda color+C01
sta color+C01+1
C01 SET C01 -1
REPEND
C01 SET 510
REPEAT 511
lda color+$200+C01
sta color+$200+C01+1
C01 SET C01 -1
REPEND  
sty color
stx color+$201
rts  

fixcolsx0
ROW SET 0
REPEAT 25
ldx screen0+ROW
lda $6000,x
sta color+ROW
ROW SET ROW +40
REPEND
rts

fixcolsx1
ROW SET 0
REPEAT 25
ldx screen1+ROW
lda $6000,x
sta color+ROW
ROW SET ROW +40
REPEND
rts

fixcoldx0
ROW SET 0
REPEAT 25
ldx screen0+39+ROW
lda $6000,x
sta color+39+ROW
ROW SET ROW +40
REPEND
rts

fixcoldx1
ROW SET 0
REPEAT 25
ldx screen1+39+ROW
lda $6000,x
sta color+39+ROW
ROW SET ROW +40  
REPEND
rts

; *******************************************
; Puntatori e tabelle con valori precalcolati
; *******************************************

align 16

ixbuf01
.BYTE screen0/$100,screen1/$100
ixbuf10
.BYTE screen1/$100,screen0/$100
sxupdbuf
.BYTE sxupc0,sxupc1
dxupdbuf
.BYTE dxupc0,dxupc1

dxupdatecol0
.BYTE $27,$00+screen0/$100,$4F,$00+screen0/$100,$77,$00+screen0/$100
.BYTE $9F,$00+screen0/$100,$C7,$00+screen0/$100,$EF,$00+screen0/$100
.BYTE $17,$01+screen0/$100,$3F,$01+screen0/$100,$67,$01+screen0/$100
.BYTE $8F,$01+screen0/$100,$B7,$01+screen0/$100,$DF,$01+screen0/$100
.BYTE $07,$02+screen0/$100,$2F,$02+screen0/$100,$57,$02+screen0/$100
.BYTE $7F,$02+screen0/$100,$A7,$02+screen0/$100,$CF,$02+screen0/$100
.BYTE $F7,$02+screen0/$100,$1F,$03+screen0/$100,$47,$03+screen0/$100
.BYTE $6F,$03+screen0/$100,$97,$03+screen0/$100,$BF,$03+screen0/$100
.BYTE $E7,$03+screen0/$100
dxupdatecol1
.BYTE $27,$00+screen1/$100,$4F,$00+screen1/$100,$77,$00+screen1/$100
.BYTE $9F,$00+screen1/$100,$C7,$00+screen1/$100,$EF,$00+screen1/$100
.BYTE $17,$01+screen1/$100,$3F,$01+screen1/$100,$67,$01+screen1/$100
.BYTE $8F,$01+screen1/$100,$B7,$01+screen1/$100,$DF,$01+screen1/$100
.BYTE $07,$02+screen1/$100,$2F,$02+screen1/$100,$57,$02+screen1/$100
.BYTE $7F,$02+screen1/$100,$A7,$02+screen1/$100,$CF,$02+screen1/$100
.BYTE $F7,$02+screen1/$100,$1F,$03+screen1/$100,$47,$03+screen1/$100
.BYTE $6F,$03+screen1/$100,$97,$03+screen1/$100,$BF,$03+screen1/$100
.BYTE $E7,$03+screen1/$100
sxupdatecol0
.BYTE $00,$00+screen0/$100,$28,$00+screen0/$100,$50,$00+screen0/$100
.BYTE $78,$00+screen0/$100,$A0,$00+screen0/$100,$C8,$00+screen0/$100
.BYTE $F0,$00+screen0/$100,$18,$01+screen0/$100,$40,$01+screen0/$100
.BYTE $68,$01+screen0/$100,$90,$01+screen0/$100,$B8,$01+screen0/$100
.BYTE $E0,$01+screen0/$100,$08,$02+screen0/$100,$30,$02+screen0/$100
.BYTE $58,$02+screen0/$100,$80,$02+screen0/$100,$A8,$02+screen0/$100
.BYTE $D0,$02+screen0/$100,$F8,$02+screen0/$100,$20,$03+screen0/$100
.BYTE $48,$03+screen0/$100,$70,$03+screen0/$100,$98,$03+screen0/$100
.BYTE $C0,$03+screen0/$100
sxupdatecol1
.BYTE $00,$00+screen1/$100,$28,$00+screen1/$100,$50,$00+screen1/$100
.BYTE $78,$00+screen1/$100,$A0,$00+screen1/$100,$C8,$00+screen1/$100
.BYTE $F0,$00+screen1/$100,$18,$01+screen1/$100,$40,$01+screen1/$100
.BYTE $68,$01+screen1/$100,$90,$01+screen1/$100,$B8,$01+screen1/$100
.BYTE $E0,$01+screen1/$100,$08,$02+screen1/$100,$30,$02+screen1/$100
.BYTE $58,$02+screen1/$100,$80,$02+screen1/$100,$A8,$02+screen1/$100
.BYTE $D0,$02+screen1/$100,$F8,$02+screen1/$100,$20,$03+screen1/$100
.BYTE $48,$03+screen1/$100,$70,$03+screen1/$100,$98,$03+screen1/$100
.BYTE $C0,$03+screen1/$100

*=$4000
incbin "map.bin"
incbin "colors.bin"
*=$8000
incbin "chars.bin"

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Scrolling Orizzontale
« Risposta #29 il: 07 Ottobre 2010, 17:34:05 »
Ecco il codice completo anche dell' inizializzazione della color memory
« Ultima modifica: 22 Gennaio 2015, 00:17:06 da eregil »