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
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.
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.
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.
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.
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.