Autore Topic: Loader E Dintorni  (Letto 2805 volte)

Alberto

  • Utente
  • **
  • Post: 589
  • Gioco Preferito: Grand Prix Circuit
Loader E Dintorni
« il: 03 Febbraio 2005, 22:45:18 »
 Questo è il codice macchina di un tape-loader (mi pare il BurnerLoad),ossia
un programma scritto in codice macchina che riceve impulsi dal registratore
e li decodifica,convertendoli in bit.
Normalmente,il loader viene salvato su nastro come un qualsiasi altro
programma;una volta terminato di caricarlo,il C64 passa ad eseguirne il
codice.  

Ne spiego in breve il funzionamento,step by step :)
Codice: [Seleziona]
0351   SEI        ; disabilita tutti gli interrupt
0352   LDA #$FC    
0354   STA $0328    
0357   LDA #$02    
0359   STA $0329    
035c   LDA $D011    
035f   AND #$EF    
0361   STA $D011  ; blanka lo schermo
0364   LDA #$00    
0366   STA $C6      
0368   STA $9D      
036a   LDA #$80    
036c   STA $DD04    
036f   LDA #$01    
0371   STA $DD05  ; carica il timer A di CIA2 a 384 cicli di clock
0374   LDA #$19    
0376   STA $DD0E  ; avvia il timer
0379   LDA $01      
037b   AND #$1F    
037d   STA $01      ;avvia il registratore
037f   LDY #$00    
0381   JSR $03BC    
La prima parte del loader carica blanka il video per evitare disturbi durante
L'I/O col registratore,dopodichè inizializza il valore iniziale del timer A di CIA2 in modo che il conto alla rovescia duri 384 microsecondi.Poi spiegherò la funzione del timer.
Codice: [Seleziona]
03bc   JSR $03E3    

03e3   LDA #$10    
03e5   BIT $DC0D    
03e8   BEQ $03E5  ; attende di ricevere un impulso dal registratore
03ea   LDA $DD0D    
03ed   LSR A      ; se C=0 il bit associato all'impulso vale 0,
03ee   LDA #$19    ; altrimenti vale 1
03f0   STA $DD0E  ; ricarica e riavvia il timer A
03f3   RTS          
  
03bf   ROR $BD    ; shifta $BD verso destra per far posto al bit
                        ; ricevuto
03c1   LDA $BD      
03c3   CMP #$E3    ; il byte ricevuto vale 227?
03c5   BNE $03BC  ; no,continua a ricevere bit
03c7   JSR $03D3    
A questo punto,il loader si mette in attesa di ricevere un impulso dal registratore;
non appena lo riceve,verifica se il timer A di CIA2 ha già terminato il suo conto alla rovescia.Se sì,memorizza un bit 1 in $BD;altrimenti memorizza un bit 0 e fa ripartire il countdown (in altre parole,se trascorrono più di 384 microsecondi tra la ricezione di un impulso e del successivo viene memorizzato un bit 1,altrimenti un bit 0).
Infine controlla il byte ricevuto;se non vale 227 ($e3 esadecimale) riceve il prossimo impulso;se vale 237 ($ed esadecimale) passa alla seconda fase.
Codice: [Seleziona]
03d3   LDX #$08    ; si prepara a ricevere un byte alla volta
03d5   JSR $03E3    

03d8   ROR $BD      
03da   INC $D020  ; flasha il bordo
03dd   DEX        ; byte completato?
03de   BNE $03D5  ; no,riceve il prossimo bit
03e0   LDA $BD    ;
03e2   RTS          

03ca   CMP #$E3    ; sì,il byte ricevuto vale ancora 227?
03cc   BEQ $03C7  ; sì,ricevi un altro byte
03ce   CMP #$ED    ; no,vale 237?
03d0   BNE $03BC  ; no,torna a ricevere singoli bit
03d2   RTS          
Nella seconda fase,ogni otto impulsi consecutivi (quindi ogni 8 bit memorizzati) il loader controlla il byte attuale;se vale 227 riceve il prossimo byte,se vale 237 passa alla fase successiva.
Codice: [Seleziona]
0384   JSR $03D3  ; riceve il byte basso dell'indirizzo iniziale
0387   STA $C1    ; ...e lo salva
0389   JSR $03D3  ; riceve il byte alto dell'indirizzo iniziale
038c   STA $C2    ; ...e lo salva
038e   JSR $03D3  ; riceve il byte basso dell'indirizzo finale
0391   STA $C3    ; ...e lo salva
0393   JSR $03D3  ; riceve il byte alto dell'indirizzo finale
0396   STA $C4    ; ...e lo salva
0398   JSR $03D3    
039b   STA ($C1),Y; salva in memoria i byte di dati
039d   INC $C1      
039f   BNE $03A3    
03a1   INC $C2      
03a3   LDA $C1      
03a5   CMP $C3      
03a7   LDA $C2      
03a9   SBC $C4    ; blocco dati completato?
03ab   BCC $0398  ; no,riceve il prossimo byte di dati
03ad   DEC $03BB  ; sì,era l'ultimo blocco dati?
03b0   BNE $0381  ; no,riceve il prossimo blocco dati
In questa fase il loader riceve i byte d'indirizzo,che specificano in quale settore
della memoria vanno salvati i byte di dati.Una volta terminato di ricevere un blocco
di byte,verifica che ce ne siano altri:in caso affermativo,ripete il processo dall'inizio,altrimenti significa che sono stati ricevuti tutti i byte di dati.
Codice: [Seleziona]
03b2   LDA #$8E    
03b4   PHA          
03b5   LDA #$69    
03b7   PHA        ; setta l'inizio del codice macchina del
03b8   JMP $02E0  ; programma($8e6a = 36458)

02e0   NOOP #$EE    
02e2   LDY #$C0    
02e4   SLO $033C,Y  
02e7   DEY          
02e8   BNE $02E4; ripulisce il tape-buffer 
02ea   NOOP $2E,X  
02ec   JMP $FC93  ; ferma il registratore,ripristina l'IRQ normale
                  ; e le badline,ed esegue il programma
L'ultima parte del codice ferma il registratore,ripristina lo schermo e manda in esecuzione il programma. ;)

Spero che questo possa servire a qualcuno come introduzione verso il bellissimo mondo dei loader. :mattsid: