Autore Topic: Cynthcart: Da Prg A Rom  (Letto 3620 volte)

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Cynthcart: Da Prg A Rom
« il: 30 Novembre 2007, 23:27:03 »
 Convertire un piccolo programma che occupi meno di 8kb in una rom, che sia una
cartuccia o una rom del basic, non e' troppo difficile, una volta studiato
un po' il disassemblato della rom a partire dalla routine di reset a $FCE2.
Tutto sta nel trasferire il programma che abbiamo "Infilato" nella ROM,
programma che normalmente sarebbe caricabile e lanciabile con un RUN, dalla ROM
alla memoria normale a $0801.
Da una richiesta avvenuta di recente, ma che avevo affrontato gia' tempo fa,
provo a spiegare come trasformare il programma CynthCart in una ROM.
Iniziamo disassemblando il programma in questione:

Codice: [Seleziona]
Filename: cynthcart.prg
Loading address: $0801

0801  0B 08     anc #$08  ; mettere qua l'header per le cart
0803  0A        ASL      ;
0804  00        BRK      ;
0805  9E 32 30  shx $3032,Y;
0808  36 31     ROL $31,X;
080A  00        BRK      ; qua mettere una jmp
080B  00        BRK      ; ad una routine di init necessaria in tutte le cart
080C  00        BRK      ; che metteremo in fondo al file

080D  A2 18     LDX #$18  ; la routine di trasferimento ci torna utile:
080F  A9 32     LDA #$32   : patch: #$31
0811  85 22     STA $22
0813  A9 08     LDA #$08  ; patch: #$80, cosi' copia da $8031
0815  85 23     STA $23  ; trasferisce da $0832 ...
0817  A9 00     LDA #$00
0819  85 24     STA $24
081B  A9 30     LDA #$30
081D  85 25     STA $25  ; ... a $3000
081F  A0 00     LDY #$00
0821  B1 22     LDA ($22),Y
0823  91 24     STA ($24),Y
0825  88        DEY
0826  D0 F9     BNE $0821

0828  E6 23     INC $23
082A  E6 25     INC $25
082C  CA        DEX      ; per $18 volte (quindi fino a $2031)
082D  D0 F0     BNE $081F; eccessivo, dato che a $1c00 il prg e' finito

082F  4C 00 30  JMP $3000; e qua parte il programma vero e proprio
[il resto del disassemblato e' irrilevante]

Come possiamo vedere anche dai commenti che ho aggiunto, lo stesso programma
fa gia' una rilocazione da $0832 a $3000 e poi esegue il programma cosi'
trasferito. Lo spazio occupato dalla linea basic con la SYS2061 e' sufficiente
per infilarci l'header necessaria perche' sia interpretabile dal kernal come
una cartuccia, header con i 2 vettori di reset e warm start e la famigerata
signature "CBM80", che indica appunto che quel che si trova a $8000 e' una
cartuccia. Possiamo notare che e' sufficiente cambiare il puntatore in zp a
$22/$23 contenente l'indirizzo sorgente della routine di trasferimento,
facendoli puntare al nuovo indirizzo, calcolabile con:
($8000-$0801)+$0832=$8031
e giusto per correggere un esagerazione, limitare la copia a soli $14 blocchi
da $100 bytes, essendo il prg lungo $1302 bytes, per risparmiare qualche
millisecondo e non certo perche copiare piu' bytes sia un grave errore.

Codice: [Seleziona]
; iAN CooG/HokutoForce
; conversione del programma cynthcart.prg in un .bin da 8kb
; per farne una cartuccia (eprom da 8 kb, senza ulteriore hw)
; rimuovere i primi 2 byte (00 80) dal .prg risultante prima di usarlo
; per programmare la eprom.

        *=$8000,$ff
        incprg _orig\cynthcart.prg
      ; qua siamo dopo la fine del prg caricato a $8000
      ; ci mettiamo la routine di init necessaria durante il reset

patch   jsr $fda3; stesse chiamate di inizializzazione che troviamo
        jsr $fd50; a $FCE2: Initialise I/O, Initialise System Constants,
        jsr $fd15; Restore Kernal Vectors,Initialize screen editor
        jsr $ff5b;

        cli
        ldx #$00  ; schermo nero, dopo l'init sarebbe blu/azzurro
        stx $d020
        stx $d021
        dex
        txs      ; azzera lo stack
        lda #$1b
        sta $d011; modo testo
        lda #$c8
        sta $d016; modo singlecolor
        lda #$15
        sta $d018; schermo a $0400, chars a $1000

        jmp back  ; ok, continuiamo il normale svolgimento del programma

        *=$8000,$ff
        word start
        word start
        byte $c3,$c2,$cd,$38,$30;CBM80 signature

start
        jmp patch; e non jsr perche' dobbiamo anche resettare lo stack
back
        *=$800d
        byte #$14
        *=$800f
        byte <$8031; facciamo partire la rilocazione dal punto corretto
        *=$8013
        byte >$8031

        *=$9ff0,$ff
        byte "iAN CooG/HF 2007"

le 4 JSR nella routine patch sono necessarie perche' quando il kernal vede
che deve eseguire il codice puntato dal primo vettore ($8000) non le esegue,
cosa che avviene quando invece deve partire normalmente lanciando l'interprete
Basic. Noi abbiamo proprio bisogno di simulare la partenza da basic, il
caricamento del programma a $0801 e conseguente RUN, da qui la necessita' di
effettuare tutte le inizializzazioni del caso.
La sola compilazione di questo programma che crea una versione patchata e
rilocata del prg non basta, dobbiamo operare in 2 modi
1) creare un .CRT, file emulabile da Vice/CCS
2) creare un .BIN, file da dare in pasto ad un eprom burner, programmando
cosi' la nostra eprom.

Nel primo caso, se non si vuole creare manualmente l'header del .CRT seguendo
la struttura spiegata nei dox (CRT.TXT, fornito con formats.zip in 64copy),
abbiamo bisogno di mcart di Markus Brenner, o di Cartconv, fornito con Vice.
usarli e' facile, basta seguire le istruzioni stampate a schermo semplicemente
lanciandoli senza parametri. Nell'archivio fornito c'e' anche un comodo batch
che fa tutto al vostro posto, pigroni!1

Nel secondo caso invece, abbiamo bisogno che il file sia di esattamente 8192
bytes, mentre il prg e' di 8194; questo perche' il prg ha nei primi 2 bytes
l'indirizzo di partenza $8000. Basta levarli con un hexeditor, con dd (comando
gnu/unix, googlando troverete che e' disponibile anche in dos/windows) o quel
che vi pare.
A quel punto dovete arrangiarvi perche' non ho mai visto un eprom burner in vita
mia e non saprei proprio come consigliare lo svolgimento dell'operazione.

Non e' finita qua. Oltre che creare una Cartuccia, si puo' in taluni casi
convertire un prg da meno di 8kb in una ROM sostitutiva del Basic, ammesso che
questo programma non faccia in alcun modo uso delle routine appunto contenute
nel Basic, fosse anche solo la stampa tramite jsr $ab1e.
Appurato questo, la conversione e' ancora piu' semplice del primo caso: le
routine di init le esegue il kernal, serve solo un vettore a $a000 che punta
alla nostra routine di reloc, e il gioco e' fatto.

Codice: [Seleziona]
; iAN CooG/HokutoForce
; conversione del programma cynthcart.prg in un .bin da 8kb
; per sostituire la ROM del BASIC.
; rimuovere i primi 2 byte (00 A0) dal .prg risultante prima di usarlo
; per programmare la eprom.

        *=$a000,$ff
        incprg _orig\cynthcart.prg
      ; qua siamo dopo la fine del prg caricato a $a000
      ; ci mettiamo la routine di init necessaria durante il reset

patch
        ldx #$00  ; schermo nero, dopo l'init sarebbe blu/azzurro
        stx $d020
        stx $d021
        lda #$1b
        sta $d011; modo testo
        lda #$c8
        sta $d016; modo singlecolor
        lda #$15
        sta $d018; schermo a $0400, chars a $1000

        rts; ok, continuiamo il normale svolgimento del programma

        *=$a000,$ff
        word start; la routine a $fce2, se non c'e' la signature delle cart,
                  ; esegue una jmp ($a000) quindi qua ci mettiamo l'indirizzo

start
        jsr patch
        nop      ; riempitivo per arrivare alla routine rilocante
        nop
        nop
        nop
        nop
        nop
        nop
back
        *=$a00d
        byte #$14
        *=$a00f
        byte <$a031; facciamo partire la rilocazione dal punto corretto
        *=$a013
        byte >$a031

        *=$bff0,$ff
        byte "iAN CooG/HF 2007"
in questo caso l'unica opzione e' solo quella dello strip dello startaddres.
Il binario risultante, sempre di 8192 bytes puo' essere usato sia come
basic.rom da Vice/CCS, che programmato su eprom.

Quale vantaggio puo' avere usare una ROM Basic piuttosto di una cart?
Un programma su cart occupa la zona $8000-9FFF rendendola inacessibile come RAM. Se il programma una volta trasferito ed eseguito dovesse usare questa zona per scriverci, salterebbe per aria. Con una rom invece, come gia' detto, l'unica limitazione e' dovuta all'impossibilita' di usare le routine del basic.
Per fare in modo che questa zona torni ad essere utilizzabile quando si usa una cart, la stessa dovrebbe essere dotata di circuiteria speciale per gestire il bankswitching, che permetterebbe di selezionare cosa far vedere al C64 in quella zona, rom o ram. Cartucce di questo tipo sono ad esempio la Magic desk/HESware, le Ocean, le comuni cart di Freeze come Action Replay, e altre spiegate sempre in CRT.TXT. Queste cartucce consentono tra l'altro di avere piu' banchi da 8kb, quindi ampliando la capacita' a programmi ben piu' estesi di 8kb.

Per ogni delucidazione :rtfm:, grazie per l'attenzione, buonasera.

iancoog.altervista.org/hid/cynthcart_prg2rom.7z
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -