Autore Topic: Dubbi su demo  (Letto 2808 volte)

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Dubbi su demo
« il: 28 Settembre 2013, 03:15:20 »
MODERAZIONE:
Non riesumare thread vecchi, è meglio aprire un nuovo thread e inserire un link all'originale.
Thread diviso da: http://ready64.org/smf/index.php?topic=3668
-eregil


Ciao a tutti.
Scusate se riporto in vita questo vecchio topic ma credo ne valga la pena visto che non é stato molto discusso il programma.
Cercavo da niubbone alcuni esempi per capire meglio come creare un charset personalizzato e altrove ho trovato risposte abbastanza soddisfacenti ( anche se mi piacerebbe scrivere un programma in assembly il più breve e chiaro possibile che permetta direttamente di scrivere dal Basic con un charset diverso da quello originale Commodore).

Ordunque cercando di studiarmi questo lavoro per motivi didattici mi sono reso conto pure io nella mia grande niubbità che é un insieme pasticciatissimo di istruzioni che spesso sono messe lì e che non servono a niente. I miei complimenti comunque a Elder (sinceri!) perché nnostante ciò in qualche modo il suo demo funziona(anche se secondo me qualcosa non va proprio come dovrebbe).

Dopo aver fatto partire l'eseguibile ho provato ad assemblare il listato originale a CBM prg Studio ma purtroppo non mi digerisce alcune istruzioni, che io non capisco appieno, tipo:

*=*+1

Cosa significa? L'indirizzo di partenza viene spostato di 1? Come altro posso scriverlo?


*= $5000-26

Scritto così sembra che da un numero esadecimale venga sottratto un numero decimale. Sono (ovviamente) due numeri entrambi esadecimali?


Passiamo al listato:

                        lda #$18    ; screen at $0400 chars a $2000
                        sta $d016       ;multicolor!

Ovviamente qua c'é un pasticcio. $18 andava assegnato ad $d018, come infatti succede qualche riga sotto. A $d016 Elder voleva assegnare qualcos'altro.
Questo 'ambo' di righe viene ripetuto ancora nel corso del listato, un copincolla davvero malfatto.

                        lda #$1b
                        ldx #$08
                        ldy #$18
                        sta $d011    ; text mode
                        sty $d018    ; screen a $0400, charset a $2000

Che senso ha quel ldx #$08 se non viene assegnato a niente?
Oppure non ci ho capito io qualcosa di quello che ho studiato, ma qualche riga sotto un bel ldx#$ff toglie pochi dubbi al pasticcio.

Se qualcuno si prende la briga mi spiega se ha un senso, o non molto del perché la prima istruzione 'sei' viene data a riga 11 e la rispettiva 'cli' a riga 132? E' normale? O bastava mettere la 'sei' all'inizio delle istruzioni di interrupt?



Dalla riga 145 ritroviamo queste:

                        lda #$1b
                        ldx #$08
                        ldy #$18
                        sta $d011   ; Clear high bit di $d012: text mode
                        sty $d018   
               
                        lda #$18        ; screen at $0400 chars a $2000
                        sta $d016       ; multicolor!
                       
A che serve ripetere? Ritroviamo anche ldx #$08 e company.

                        stx counter
                        lda $212e,x  ; byte xesimo dai caratteri
                        eor $ff          ; inverti
                        sta $212e,x  ; store al suo posto
                        inx
                       
                        lda #<int2   
                        ldx #>int2   
                        sta $0314   
                        stx $0315
                        ldy #$92
                        sty $d012

                        asl $d019
                        pla
                        tay
                        pla
                        tax
                        pla
                        rti     


Qua c'é una chiamata ad un interrupt. E' normale che non sia preceduto e seguito da sei e cli ?
Funziona, ma a proprio rischio e pericolo?
Mi fermo qui, il listato é lungo, nel frattempo spero che qualcuno abbia voglia di togliermi dubbi e dare conferme alle mie certezze!
« Ultima modifica: 30 Gennaio 2015, 19:06:37 da eregil »

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Dubbi Su "mini Demo"
« Risposta #1 il: 28 Settembre 2013, 14:48:41 »
 Tante istruzioni pla, nessun pha.
Suppongo che fra riga 175 e 179, e fra 219 e 223 le 'pla' siano da sostituire con 'pha'.

Riga 364-369:
                        ldy #$0
                        sty $d012
                       
                        ;rimetto apposto anche il registro $d012
                        lda #$34
                        sta $d012

Viene impostato $d012 due volte? Ha un senso?

 

eregil

  • Administrator
  • Utente
  • *****
  • Post: 714
  • Gioco Preferito: Impossible Mission
Dubbi Su "mini Demo"
« Risposta #2 il: 28 Settembre 2013, 18:33:44 »
 Se ti poni domande perché stai cercando di imparare va tutto bene, ma prima di "proporre modifiche" hai bisogno di rivederti un po' di basi, cerca prima di capire cosa fa il codice e possibilmente inizia da esempi più semplici.

In generale, le istruzioni SEI e CLI si utilizzano dove modifichi i puntatori alla routine di interrupt, non nella routine di interrupt stessa.

L'istruzione PHA non è l'unico modo in cui si mette qualcosa nello stack, perciò non deve necessariamente esserci un "equilibrio" tra numero di istruzioni PHA e numero di istruzioni PLA.

Scrivendo sul registro $d012, si modifica il numero di rasterline al quale viene chiamata la routine di interrupt relativa al raster. Senza entrare in maggiori dettagli, diciamo pure semplicemente che il comportamento di questo registro è "particolare" per cui in certi casi ha perfettamente senso impostarlo più volte in una routine come in questo demo.

Separo perché il thread di origine non deve essere "dirottato" su domande sulle basi.
 
Non rispondo a richieste private, di qualunque genere esse siano.
Per domande tecniche leggete le FAQ e usate l'apposito forum.
Per questioni amministrative contattate lo staff tramite il form Contatti sul sito.

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Dubbi Su "mini Demo"
« Risposta #3 il: 14 Ottobre 2013, 23:49:16 »
 Ciao Eregil e grazie per le risposte! (mi sono accorto solo adesso del topic credevo che avessi cancellato tutto).

Grazie per la spiegazione su pha e pla e il resto!

Non vorrei annoiarti ma vorrei cercare di capire come funziona così come é impostata la serie di interrupts del programma.
L'interrupt installato punta a 'int', all'interno del quale un interrupt punta a 'int2', all'interno del quale un interrupt punta a 'intsprites', all'interno del quale un interrupt punta a 'int3' che scrive così:
int3
  lda #  sta $0314  
  sta $d019
  inc $d012      
  cli

eccetera..

1) Perché int3 punta solo al 'low address' dell'interrupt int4?
2) Perché solo la dichiarazione dell'interrupt 'int' é all'interno di un sei..cli? Forse perché le altre chiamate ad interrupts sono nidificate all'interno, e quindi eseguite nel tempo di interrupt di 'int' e quindi non ci sono rischi?
3) perché la chiamata di int4 all'interno di int3 é chiusa da un'istruzione 'cli' senza che fosse stata data un'struzione 'sei'?

Ringrazio eregil o altri che volessero chiarirmi le idee!

eregil

  • Administrator
  • Utente
  • *****
  • Post: 714
  • Gioco Preferito: Impossible Mission
Dubbi Su "mini Demo"
« Risposta #4 il: 16 Ottobre 2013, 22:07:31 »
 Guarda, sul demo specifico eventualmente Elder interverrà se è ancora attivo e ha il tempo di farlo. Dato che personalmente conosco l'uso del raster proprio un minimo sindacale, e dovrei analizzare il codice meglio di quanto la mia disponibilità di tempo permette, mi limito a qualche indicazione che può avere carattere generale.

Quando si opera col raster è una tecnica abbastanza comune modificare il puntatore alla routine di interrupt di volta in volta, per lanciare routine diverse in base alla posizione del raster.

Inoltre, quando si utilizza il raster per produrre certi effetti visivi, càpita di dover scrivere il codice assembly contando il numero di cicli macchina che saranno impiegati ad eseguirlo, perché si ha la necessità di completare una determinata operazione esattamente in un momento particolare in cui il raster raggiunge la linea che ci interessa. Vi è un certo grado di incertezza su quando inizia l'esecuzione della routine di interrupt, ciò è dovuto al fatto che il 6510 entra nella routine di interrupt sempre dopo aver completato l'operazione corrente, la quale può richiedere ancora un numero variabile di cicli macchina. Perciò è necessario fare in modo che questo grado di incertezza sia eliminato in qualche modo.

Quindi in risposta alle tue domande:

1) è possibile che nel punto del codice in cui viene modificato solo il byte basso del puntatore, avvenga così perché è noto al programmatore che il byte alto è già impostato correttamente; è una piccola ottimizzazione, se vogliamo

2,3) questo ha a che fare con la tecnica del "double interrupt", che io non padroneggio e quindi che evito di descrivere dettagliatamente, onde non dire cose fuorvianti :) mi limito a dire che il principio è che per eliminare l'incertezza di cui sopra vogliamo che un interrupt avvenga mentre è ancora in corso l'esecuzione di una sequenza di NOP nella nostra routine di interrupt corrente, e questo richiede che eseguiamo una CLI al momento giusto, mentre una SEI in questo contesto non è necessaria.
 
Non rispondo a richieste private, di qualunque genere esse siano.
Per domande tecniche leggete le FAQ e usate l'apposito forum.
Per questioni amministrative contattate lo staff tramite il form Contatti sul sito.

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Dubbi Su "mini Demo"
« Risposta #5 il: 17 Ottobre 2013, 23:19:16 »
 Mi permetto di aggiungere qualche nota a quanto ha già detto Eregil.
Innanzitutto una premessa che ritengo doverosa: la minidemo in oggetto è uno dei primi lavori di Elder, è ancora "grezza" e non da la misura di quello che sa fare ora.

Il pezzo di codice accennato serve in effetti ad ottenere la stabilizzazione a doppio raster. Ti spiego sinteticamente come funziona:
- la routine int3, in risposta ad un raster interrupt, viene eseguita con un'incertezza di 0/6 (7 con gli illegal codes) cicli rispetto al preciso momento di trigger (in base all'ultima istruzione incontrata prima dell'irq).
- All'interno di int3 si imposta un nuovo raster irq nella riga successiva ma si fa in modo che questo secondo irq capiti durante istruzioni brevi in modo da ridurre l'incertezza a 0/1 cicli. Le nop - eseguite in 2 cicli - servono a questo: l'irq può capitare prima di una nop (2 cicli di ritardo) o in mezzo (3 cicli di ritardo).
- All'interno di int4, infine, basterà fare un opportuno controllo (quello di questo programma in effetti è sbagliato) del valore raster a cavallo tra la riga di chiamata e la successiva per assorbire l'ultima incertezza ed avere una routine perfettamente sincronizzata al video.

Ora, int3 è un po' criptico perchè c'è poco tempo a disposizione.
Alcune cose le ha già dette Eregil, le ripeto solo per elencarle tutte:
- Perchè c'è poco tempo? Perchè in risposta ad un irq il 64 esegue la routine puntata in $fffe/$ffff che quando, come in questo, caso il kernal è attivo, punta a $ff48. In $ff48 c'è un pezzo di codice che "costa" 29 cicli che sommati ai 7 della irq e ai 2 minimi di ritardo nel servire un irq fanno un totale di 38. D'altra parte l'incertezza dell'irq è di 0-6, quindi nel peggiore dei casi abbiamo solo 63-38-6=19 cicli a disposizione: pochi!!
- int3 e int4 sono volutamente nella stessa pagina (negli stessi 256 byte) perciò è sufficiente impostare il low byte dell'irq handler (lda+sta, 6 cicli risparmiati)
- int4 è dispari (align 2  *=*+1): con align 2 mi assicuro di avere un indirizzo pari, con *=*+1 passo al byte successivo. Mi serve dispari perchè così con una sta $d019 effettuo l'acknowledge del raster irq (il bit 0 è a 1). (lda, 2 cicli risparmiati)
- la inc $d012 serve a triggerare un nuovo raster nella linea successiva a quella corrente
- la cli è necessaria perchè, quando viene servito un irq, il 6510 imposta automaticamente la maschera (bit I dello SR attivo). In pratica dopo aver salvato lo SR e l'IP nello stack è come se venisse eseguita un'implicita "sei". Perchè? Il 6510 esegue "l'istruzione" irq quando il piedino irq è negato; d'altra parte se la periferica che ha abbassato il livello del piedino irq non viene "avvisata" (sta $d019 in questo caso) che è stata servita, il livello verrà mantenuto. In sostanza se il 6510 non attivasse la maschera si entrerebbe in un loop infinito di irq perchè la condizione che lo genera sarebbe sempre valida.

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Dubbi Su "mini Demo"
« Risposta #6 il: 18 Ottobre 2013, 01:39:26 »
 Beh ragazzi mi inchino commmosso alla vostra disponibilità e alle vostre conoscenze. Mi ci vorrà un pò di tempo per digerire il malloppo generosamente fornito da Freshness, tanta roba! Spero di avere ancora così tanta disponibilità per le tante domande che vorrei fare ( soprattutto spiegazioni sui listati forniti da Freshness e da Ian Coog perché sinceramente su tutte le decine di testi online che ho consultato non si arriva a decifrare che una parte di quanto scritto e sinceramente nemmeno cercando in profondità su Internet: forse dovrei studiarmi a fondo i contenuti di codebase64? Se avete altri siti o indirizzi da propormi per capire di più ve ne sarei grato!)
Ciao!

Elder0010

  • Utente
  • **
  • Post: 75
    • http://csdb.dk/scener/?id=22731
  • Gioco Preferito: Rampage
Dubbi Su "mini Demo"
« Risposta #7 il: 20 Ottobre 2013, 18:25:46 »
 Yep, sono sempre attivo :)  Freshness ha già risposto chiaramente a tutti i quesiti tecnici riguardanti il timing.

Per quanto riguarda il resto, era una delle mie primissime prove e ci sono diversi errori di distrazione, e "pasticci". Nel C64 world, le cose da tenere a mente sono veramente tante, e all'inizio può capitare di scrivere un pò di codice senza sapere al 100% l'effetto di ogni istruzione, e quindi può capitare di pasticciare.

Il post non era inteso come tutorial (avevo iniziato da un mese forse). La mia intenzione era far vedere il mio codice da niubbo ai più esperti, in modo da avere dritte e consigli.

In ogni caso, riguardo il charset, le cose da sapere sono queste:

1) il charset deve essere allineato a $800, per cui puoi importarlo a indirizzi come
$2000
$2800
$3000
ecc ecc. Per intenderci $2100 non va bene.

2) una volta importato il charset in una locazione di memoria consona (ad es $2000), devi ricordare che il VIC indicizza solo 16kb di memoria "per volta".
I 16 kb visibili dal VIC sono gestiti da $DD00 (bit 0 e 1), per cui si ha:

Codice: [Seleziona]
$DD00 = %xxxxxx11 -> bank0: $0000-$3fff
$DD00 = %xxxxxx10 -> bank1: $4000-$7fff
$DD00 = %xxxxxx01 -> bank2: $8000-$bfff
$DD00 = %xxxxxx00 -> bank3: $c000-$ffff
fonte Codebase64

Quindi, se il tuo charset è a $2000 e lo schermo è a $0400, il VIC deve "puntare" al bank 0. Quindi:

Codice: [Seleziona]
lda $dd00
and #%11111100
ora #%00000011;BANK 0
sta $DD00

Dopodichè si tratta di calcolare il valore giusto di $d018.
Sempre consultando le tabelle nel link di prima, si ha:

%0001xxxx schermo a $0400
%xxxx100x charset a $2000

combinando i due nybble, si ottiene
%00011000 che in hex è $18.

Quindi il codice diventa

Codice: [Seleziona]
lda $dd00
and #%11111100
ora #%00000011;BANK 0
sta $DD00

lda #$18
sta $d018

Tieni a mente che il charset e lo schermo devono essere nello stesso banco, altrimenti il giochino non funziona.

Alterare il charset in tempo reale, o selezionare charset diversi a seconda della rasterline sono dei tricks molto comuni nei demo, per cui è bene imparare almeno le basi prima di addentrarsi in queste cose.
lda #0 sta $d020 sta $d021

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Dubbi Su "mini Demo"
« Risposta #8 il: 22 Ottobre 2013, 10:28:47 »
 Ciao Elder!
Se quello era un tuo prodotto dopo solo un mese di smanettamento ti faccio i miei complimenti.
Abbiamo approcci piuttosto diversi nell'apprendere l'assembly, mi sembra che tu ti avventuravi in cose complesse che erano oltre le tue possibilità di allora, infatti come scrivi tu stesso alle volte facevi cose senza sapere bene i risultati. io uso invece solo quello che so, e mi rendo conto di fare progressi molto lenti, ciò che mi consentono i neuroni sani rimastimi.
Ci sono altri tuoi lavori più recenti al di fuori di questo Forum che si possono andare a spiare?Grazie e a presto!


P.s. avevi fatto giusto il listato, ma sbagliato la riga del commento, questa:

lda #$18 ; screen at $0400 chars a $2000
sta $d016 ;multicolor!

Ovviamente era più sotto

ldy #$18 ; screen at $0400 chars a $2000
sty $d018

Ciao!

Elder0010

  • Utente
  • **
  • Post: 75
    • http://csdb.dk/scener/?id=22731
  • Gioco Preferito: Rampage
Dubbi Su "mini Demo"
« Risposta #9 il: 23 Ottobre 2013, 14:54:16 »
 Tra qualche tempo uscirà un demo molto lungo che sto realizzando con Freshness, a seguito dell'uscita pubblicheremo tutto il source su un repository git! a presto
lda #0 sta $d020 sta $d021

COMMODORO

  • Utente
  • **
  • Post: 160
  • Gioco Preferito: Bomberman C64
Dubbi Su "mini Demo"
« Risposta #10 il: 24 Ottobre 2013, 02:05:45 »
Citazione da: "Elder0010"
Tra qualche tempo uscirà un demo molto lungo che sto realizzando con Freshness, a seguito dell'uscita pubblicheremo tutto il source su un repository git! a presto
Ottimo! Aspettiamo il vostro lavoro! Ciao!