Di recente mi ha sorpreso il commento di uno sviluppatore Amiga abbastanza noto riguardo una questione che, devo ammettere, mi tocca direttamente, avendo utilizzato estensivamente l’accorgimento di cui si lamenta “jotd” (rinomatissimo per aver sistemato e/o migliorato una caterva di giochi per il nostro amato computer, sviluppando sui strumenti specifici allo scopo, oppure sfruttando il notissimo WHDLoad).
Ne riporto integralmente il contenuto, in quanto costituito esclusivamente da un paio di righe:
020 + chip ram wasn’t that slow. The problem arose only when connecting a Phase5 060 board with games using chipmem. But that wasn’t really the fault of the 1200, rather lazy devs that would assemble games at absolute location $400.
Quella a cui si riferisce, la Chip Mem, era l’unica, preziosissima, memoria a cui potevano accedere i chip custom della macchina e a cui la CPU poteva anch’essa accedere, ma con minor priorità (o addirittura non potendovi accedere del tutto se tutti gli accessi a questa memoria fossero stati utilizzati da tali chip).
Questa memoria è, dunque, particolarmente importante, anche alla luce del fatto che sia l’unica memoria che un qualunque Amiga era sicuro dovesse esser dotato: tutti gli altri tipi di memoria RAM sono, infatti, opzionali!
Inoltre è anche l’unica di cui si conosce l’indirizzo di partenza: 0
(in esadecimale, a 32 bit: $00000000
) e che dovrebbe essere presente per almeno 256kB (ma tutti gli Amiga a partire dal 500 e 2000 ne hanno almeno 512kB. Gli Amiga 1000, che erano equipaggiati soltanto di 256kB, potevano arrivare a 512kB tramite un’espansione di memoria di cui praticamente tutti si sono dotati).
Per tutti questi motivi la Chip Mem
ha rappresentato da sempre IL punto di riferimento per gli sviluppatori, che potevano sicuramente contare sulla presenza di 512kB di memoria a partire dall’indirizzo 0
, per l’appunto. In particolare, era naturale scrivere codice tenendo conto di riferimenti assoluti alla memoria, entro quest’intervallo di indirizzi (da $00000000
a $0007FFF
), quando un gioco prendeva totale controllo del sistema (il che era sostanzialmente la norma, per poter sfruttare al meglio le poche risorse a disposizione).
Ed era, quindi, altrettanto naturale utilizzare proprio l’indirizzo $400
(risparmio l’aggiunta di zeri addizionali per semplificare la scrittura degli indirizzi), citato da jotd, da dove far partire il codice. Si tratta, alla fine, di un indirizzo come un altro, da questo punto di vista. Non vedo, pertanto, perché lagnarsi o voler discriminare l’uso di indirizzi come questi anziché altri all’interno di questo tipo di memoria: non c’è alcuna differenza!
Comunque l’uso di indirizzi “corti” come questi è dovuto anche al fatto che siano accessibili dal processore 68000 utilizzando un’apposita modalità d’indirizzamento della memoria, chiamata per l’appunto “assoluta corta” (absolute short), che richiede soltanto due byte (16-bit) anziché i canonici 4 (32-bit) richiesti da quella “assoluta lunga” (absolute long), con un notevole risparmio di spazio, ma con la limitazione di poter accedere soltanto a 64kB di memoria (da $FFFF8000
a $FFFFFFFF
se il valore a 16 bit è negativo e da $00000000
a $00007FFF
se è positivo).
Al posto di questa si sarebbe potuta utilizzare anche la modalità d’indirizzamento relativa al contatore di programma (PC
), che prevede l’utilizzo di un offset a 16-bit, e che, quindi, avrebbe contribuito allo stesso modo, se non fosse per il fatto che non è possibile scrivere in memoria utilizzandola (si può soltanto leggere, oppure eseguire codice), mentre con l’assoluta corta ciò non crea problemi.
Poiché, in genere, i programmi avevano codice e dati (variabili e piccoli buffer, in particolare) vicini o addirittura mischiati, piazzando il codice a $0400
(che, per inciso, era la prima locazione di memoria libera utilizzabile: il primo kB di memoria, infatti, era stato riservato da Motorola per memorizzare la tabella dei vettori per le interruzioni) si aveva tutto a portata di mano, insomma.
In ogni caso tutto rimane perfettamente lecito / legittimo: non c’è assolutamente nulla di male nell’utilizzare quest’area di memoria, visto che presenta tutti questi vantaggi.
Il rovescio della medaglia (molto probabilmente le rimostranze di jotd saranno dovute proprio a questo) è che il codice del gioco sarà costretto a girare sulla lenta (per la CPU) memoria Chip e idem per l’accesso ai dati. In questo modo si preclude l’utilizzo della ben più veloce memoria Fast (a cui il processore può accedere in maniera completamente indipendente) per i sistemi che ne siano dotati, con evidenti benefici a livello prestazionale.
Se ciò può essere sicuramente vero per i giochi 3D (o di strategia, scacchi, ecc.) che richiedono parecchio tempo a carico della CPU, non lo è certamente per quelli 2D, che usualmente risultano già “tarati” per girare a 60/50 (NTSC/PAL) o 30/25 (sempre NTSC o PAL) FPS.
Supponendo di rientrare nella prima tipologia, avrebbe quindi senso spostare il codice in Fast Mem, operazione (chiamata rilocazione, in gergo tecnico) che usualmente viene effettuata da jotd, se necessaria per un particolare gioco.
Il punto è che non sarebbe certo complicato farlo, convertendo tutti gli indirizzamenti assoluti corti in quelli relativi al PC, visto che occupano esattamente lo stesso spazio in memoria, con l’unica eccezione rappresentata dalle operazioni di scrittura in memoria (con indirizzamento assoluto corto, ovviamente): in questo caso si potrebbe convertire l’indirizzo assoluto corto nell’equivalente lungo, per poi provvedere a sistemare opportunamente tale l’indirizzo prima dell’esecuzione (perché non si sa in quale indirizzo di memoria Fast potrebbero finire le locazioni di memoria da scrivere).
E’ senz’altro una rogna, ma da qui ad etichettare come “pigri” i programmatori soltanto per aver fatto il loro dovere (ossia ottimizzare il più possibile il codice causa risorse limitate), mi sembra a dir poco eccessivo.
Veniamo adesso a quello che dovrebbe essere il reale problema che abbia portato a quelle affermazioni di jotd, cioè il comportamento della scheda acceleratrice per Amiga 1200 basata su processore 68060 e realizzata dalla Phase 5, la quale sembrerebbe avere difficoltà nell’accesso alla memoria Chip.
Innanzitutto c’è da dire che, nel panorama Amiga, l’adozione di schede acceleratrici abbiano comportato tante volte problemi di diverso tipo, molto spesso riconducibili a codice scritto male per i giochi, demo, e persino applicazioni, quale risultato di non aver perfettamente seguito le linee guida di mamma Commodore (mi riferisco, in particolare, ai famosi manuali per gli sviluppatori della linea Amiga ROM Kernel Manuals, e in particolare al manuale dell’Hardware).
Questo, però, non implica che tutti i problemi di compatibilità con le schede acceleratrici siano dovuti esclusivamente alla cattiva programmazione. Assumere ciò sarebbe, infatti, una fallacia logica (quella della generalizzazione affrettata o del campione non rappresentativo).
Difatti jotd si lamenta dei giochi che utilizzino memoria Chip. Cosa, invero, alquanto comune (a motivo di quanto scritto e chiarificato prima) e… impossibile da non realizzare, poiché i giochi devono usare tale memoria quanto meno per i dati, ma riguardo l’Amiga 1200 (base) serve anche per contenerne il codice. Difatti utilizzare memoria Chip è… perfettamente lecito, linee guida Commodore alla mano!
Anche quella che sembra una successiva precisazione, cioè l’invettiva contro i programmatori che utilizzino indirizzi assoluti come $0400
, lascia il tempo che trova per quanto detto: tali locazioni di memoria non contrastano con alcuna direttiva che si trovi nei suddetti manuali.
Probabilmente jotd avrebbe desiderato che i giochi utilizzassero memoria Fast, in modo da non avere problemi con la scheda acceleratrice della Phase 5, ma ciò funzionerebbe soltanto se tale scheda acceleratrice ne fosse dotata. Infatti non sta scritto da nessuna parte che tale scheda debba necessariamente montare tale memoria. Anche se sarebbe stupido non farlo (e non ho mai sentito di casi del genere, infatti), sulla carta uno scenario del genere sarebbe possibile e, dunque, le problematiche di cui lamenta rimarrebbero ugualmente, qualunque fosse l’indirizzo di memoria in cui il codice girerebbe nella memoria Chip.
Infine, è bene precisare un paio di cose. Il primo è che non cita altre schede acceleratrici, ma soltanto quella di Phase 5. Dunque se fosse soltanto questa ad avere problemi, direi che alla fine non sarebbe colpa degli sviluppatori “pigri”, quanto degli ingegneri che avrebbero realizzato una scheda acceleratrice malfunzionante. Per cui le rimostranze dovrebbero essere rivolte a loro e non ai programmatori.
Secondo, e non meno importante, tanti giochi per Amiga 1200 sono stati sviluppati quando del futuro processore 68060 di casa Motorola non si sapeva praticamente nulla né tanto meno abbiano avuto modo di metter le mani su una delle sue possibili schede acceleratrici che l’avrebbe montato (in particolare proprio questa, che sembra esser l’unica a esser affetta da problemi). Quindi, e non essendo dotati di sfere di cristallo, gli sviluppatori non avrebbero certo potuto tenerne conto, anche volendo!
In conclusione, posso certamente capire le frustrazioni di chi per passione si occupi di eliminare bug o migliorare il codice dei vecchi giochi per Amiga, ma da programmatore ritengo che le accuse di jotd siano assolutamente infondate: non eravamo pigri facendo scelte come quelle di cui si lamenta, ma stavamo “semplicemente” facendo il nostro dovere. Ossia spremere la macchina meglio che potevamo!