(Ma con che diavolo di interlinea hai scritto?)
Discorso molto lungo. Non so nemmeno quale sia la tua preparazione in merito,
ma faccio finta di parlare con uno che sa cosa sia l'assembler.
Io non ho mai usato linkers, mi linkavo a mano i files caricandoli in memoria
gia' rilocati. Ai tempi avevo il memory editor interno dello speeddos e la
cartuccia O.M.A., che nella sua semplicita' aveva quel che bastava: un monitor
LM residente. Non serve altro.
Un intro e' un programma che dopo aver presentato qualcosa a video, fa partire
un altro programma. Quest'altro programma ovviamente non puo' risiedere nello
stesso spazio occupato dall'intro ma va accodato. Prima di eseguirlo va
ovviamente mosso, dalla posizione provvisoria alla vera posizione.
Per fare questo bisogna conoscere l'occupazione dell'intro, del programma da
linkare, e soprattutto sapere che l'intro non vada ad usare MAI indirizzi
occupati dal programma rilocato.
Es: intro da $0800 a $2FFF, spazio per il programma rilocato: da $3000 a $FFFF,
ma l'intro non dovra' mai scrivere in quella zona di RAM (ovviamente puo' farlo
nei registri SID/VIC/CIA, perche' la ram deve essere attivata forzatamente per
scrivere da $D000 a $DFFF)
Quando non si hanno i parametri, va disassemblato e *capito* cosa fa l'intro.
L'intro che hai tu nel disco e' compresso e cosi' com'e' non e' utilizzabile ma
va decompresso a mano prima dell'uso. Lo capisci anche solo dalla sys, un intro
decompresso non ha mai sys, ma questo lo puoi capire a colpo d'occhio solo
con un po' di anni di esperienza, a furia di disassemblaggi.
Per decomprimere il prg devi disassemblarlo, o se preferisci, debuggare passo
per passo con un monitor, vice e' ottimo perche' permette anche i breakpoint.
Seguendo il flusso vedrai che inizia rilocando un pezzo a $0100 e lo esegue.
A $0100 ora c'e' il vero e proprio codice di decompressione.
Seguendolo fino alla fine troverai:
0199 A9 37 LDA #$37
019B 85 01 STA $01
019D 58 CLI
019E 20 00 38 JSR $3800
01A1 4C AE A7 JMP $A7AE
e questa e' la jmp di inizio del nostro intro, $3800.
Possiamo salvare la memoria PRIMA che venga eseguita questa istruzione.
E' bene che gli intro non vadano mai salvati durante l'esecuzione, spesso
non reinizializzano i loro vari puntatori una volta partiti, assumendo che
sia tutto settato "in fabbrica".
Per fare questo puoi, se usi un c64 vero con una cart dotata di monitor (AR):
.> 08E5 CE 20 D0 DEC $D020
.> 08E7 D0 FB BNE $08E5
ed uscire dal monitor. Ricordati o annotati cosa c'era nella jmp.
Lancialo, lascia che finisca di decomprimersi e vedrai il bordo flashare.
rientra nel monitor e poi salva, anche tutta la memoria da $0800 fino a $FFFF,
vedremo dopo dove finisce veramente l'intro.
S "intro3800",08,0800,ffff
Con vice e' piu' semplice. dopo aver caricato l'intro, ALT-M, e dai
break 3800
x
(Ovviamente 3800 lo sai perche' hai gia' disassemblato. ALtrimenti segui passo
a passo con "z" finche' non trovi la locazione.)
poi dai RUN, riappare il monitor e dai:
> 01 38
s "intro3800.prg" 0 0800 ffff
> 01 37
x
Ora dobbiamo capire i parametri dell'intro, cioe' da dove finisce, dov'e' la
routine di rilocazione e che comando dare per avviare il programma linkato
una volta che lo si e' rilocato.
Se ho un intro che va da $0800 a $2FFF quasi sicuramente richiede di avere
il programma linkato a $3000. Il codice dell'intro prevede sicuramente un tasto
di uscita, solitamente spazio. Per sentire la pressione di un tasto ci sono
diversi modi, leggendo $C5 e/o $C6, facendo JSR $FFE4, o leggendo direttamente
la keymatrix dalla porta $DC01. I primi metodi implicano l'uso del basic e
del kernal attivi. Quasi sempre pero' si preferisce evitarli perche' rubano
preziosi cicli macchina e in un intro pieno di irq temporizzate al millisecondo
non si puo' specare nulla, quindi si opta al 99% l'uso di $DC01.
Questo per dire che va cercato nel disassemblato 01 DC per trovare ad esempio
38F4 AD 01 DC LDA $DC01
38F7 C9 EF CMP #$EF
38F9 D0 F9 BNE $38F4
che e' il loop infinito di attesa del tasto spazio. Appena lo si preme:
38FB 78 SEI
38FC A9 0B LDA #$0B
38FE 8D 11 D0 STA $D011
3901 20 18 E5 JSR $E518
3904 A9 00 LDA #$00
3906 8D 20 D0 STA $D020
3909 8D 21 D0 STA $D021
390C A9 1B LDA #$1B
390E 8D 11 D0 STA $D011
3911 A0 40 LDY #$40
3913 B9 5F 0D LDA $0D5F,Y
3916 99 FF 03 STA $03FF,Y
3919 88 DEY
391A D0 F7 BNE $3913
391C A9 EA LDA #$EA
391E 8D 15 03 STA $0315
3921 A9 31 LDA #$31
3923 8D 14 03 STA $0314
3926 A9 00 LDA #$00
3928 8D 18 D4 STA $D418
392B 58 CLI
392C 4C 00 04 JMP $0400
viene rilocato un pezzo di codice da $0d60 a $0400, ripristinati vic e irq
alla normalita' e si va a $0400 che ORA contiene del codice, vediamolo
0D60 78 SEI
0D61 A9 34 LDA #$34
0D63 85 01 STA $01
0D65 A2 C8 LDX #$C8
0D67 A0 00 LDY #$00
0D69 B9 01 3F LDA $3F01,Y
0D6C 99 01 08 STA $0801,Y
0D6F 88 DEY
0D70 D0 F7 BNE $0D69
0D72 EE 0B 04 INC $040B
0D75 EE 0E 04 INC $040E
0D78 CA DEX
0D79 D0 EE BNE $0D69
0D7B A9 37 LDA #$37
0D7D 85 01 STA $01
0D7F 58 CLI
0D80 4C E2 FC JMP $FCE2
qua viene rilocato il programma linkato, da $3F01 a $0801, poi c'e' la jmp.
In QUESTO caso particolare c'e' JMP $FCE2, che e' il reset. Derivo da cio' che
quest'intro l'hai preso da intros.c64.org, dove abbiamo come prassi modificare
gli intro perche' si resettino all'uscita, prima di ripaccarli e upparli la'.
Questa jmp va modificata con l'indirizzo di partenza del tuo programma linkato
che ha una sys 2066, quindi metteremo:
.>0D80 4C 12 08 JMP $0812
Il $3F01 e' anche indicativo della lungezza dell'intro: finisce a $3F00.
O almeno dovrebbe. In questo caso e' sicuro, ma spesso capita di avere
intro da una parte, programma linkato in mezzo, e in fondo alla memoria la
musica usata dall'intro. Questo lo si evince anche solo risalvando l'intro
da $0800 a $3F00, cancellando la memoria (da AR un bel configure memory)
ricaricandolo e vedendo se va tutto.
Ora va caricato il prg secondario a $3F01 anziche' $0801
L "POPEYE",08,3F01
annotati l'indirizzo finale (in questo caso $76F0) e salva il tutto
S "TUTTO3800",08,0800,76F0
ora non ti resta che char-paccare e crunchare il tutto.
Quando avrai imparato le basi, usando un C64, potrai passare alla vita
comoda con i cross tools.
Per linkare 2 prg puoi usare exomizer, cbmcombine o anche un piccolo sorgente
Dasm:
*=$0800
incprg intro3800.prg
*=$3f01
incprg popeye.prg
*=$0d80
jmp $0812
semplicemente assemblandolo otterrai un prg con i 2 prg linkati e con la
jmp gia' al suo posto.