Molti hanno sicuramente conosciuto e magari avuto il piacere di giocare con una delle console che ha dato lustro alla storia dei videogiochi. Il SuperNintendo (o SNES) di Nintendo, infatti, conserva ancora un posto d’onore nel cuore degli appassionati, perché ha saputo regalare capolavori, ma soprattutto tantissime ore liete e di grande divertimento. In una parola: emozioni.
Di questa console all’epoca non si sapeva molto, tranne che avesse una grafica “pazzesca”, un audio di pari livello, e giochi come Street Fighter II e The Magical Quest erano lì a testimoniarlo.
Della CPU si conosceva ancor meno, a parte che fosse a 16 bit e avesse una sigla strana, ma con un’aria familiare; era una certa 65816 della Western Design Center (WDC), e quel 65 davanti portava anch’esso a ricordi altrettanto piacevoli…
In effetti non era la prima volta che ne sentivo parlare. Un trafiletto di una nota rivista del settore (MC MicroComputer o Commodore Gazette) della seconda metà degli anni ’80 esaltava le miracolose caratteristiche di una cartuccia in grado di regalare una velocità stratosferica di 7Mhz al Commodore 64, capacità di indirizzare ben 16MB di memoria e di eseguire in scioltezza calcoli a 16 bit.
Abituati come eravamo al Mhz di clock, ai 64KB di RAM e ai miseri 8 bit del 6510, potete immaginare la faccia di un fanatico commodoriano che si trova davanti a cotanta manna. No, non ci vuole molto a immaginarlo.
Naturalmente le innovazioni apportate nei confronti del 6502 (col quale rimane totalmente compatibile sia a livello hardware che software, grazie all’apposita modalità “emulazione”; fatta eccezione per le istruzioni non documentate) non si fermano alle caratteristiche appena citate:
- tutti i registri sono a 16 bit (compreso lo stack);
- le modalità d’indirizzamento della memoria sono 24 (erano 13 nel 6502);
- codice e dati si possono rilocare molto facilmente (anche relativamente allo stack);
- codice e dati hanno segmenti (chiamati banchi nel gergo 65816) diversi;
- è possibile rilocare la pagina zero (cioé le prime 256 locazioni di memoria, a cui si accede con apposite e veloci modalità d’indirizzamento) in qualunque indirizzo di memoria (multiplo di 256);
- sono state aggiunte diverse nuove istruzioni (che permettono di settare e resettare singoli bit, azzerare locazioni di memoria, spostare blocchi di memoria, conservare sullo stack i registri indice, dati e il program counter, ecc.);
- è supportato un coprocessore (per accelerare i calcoli in virgola mobile).
Considerata la semplicità architetturale del 6502, i cambiamenti sono notevoli, pur mantenendo la stessa “filosofia”; nel bene e nel male. Rimangono le pesanti limitazioni del predecessore, che era dotato di pochi registri e il cui numero rimane purtroppo invariato (soltanto 3). Inoltre, anche se è stato esteso a 16 bit, lo stack può risiedere soltanto nei primi 64KB di memoria, e lo stesso limite permane per i vettori di interrupt.
Per fare qualcosa di più sarebbe stato necessario stravolgere e complicare il design del microprocessore, introducendo escamotage come l’uso di particolari opcode come prefissi per estenderne il numero, similmente a quanto fatto da Intel con l’8086 e Zilog con lo Z80.
Questo perché, nonostante il 6502 avesse lasciato diversi “buchi” nella tabella degli opcode (soltanto 150 circa erano utilizzati, sui 256 disponibili), aggiungere tutte quelle nuove modalità d’indirizzamento e le nuove istruzioni ha portato a coprirli tutti, lasciandone disponibile uno soltanto (che verrà impiegato dopo per il successore a 32 bit, il 65832).
Si è preferito, quindi, puntare sul potenziamento della CPU, sfruttando i punti di forza di quella dalla quale deriva. In particolare è l’accesso alla memoria (veloce e con numerose modalità d’indirizzamento) che ha fatto felici i programmatori del 6502, e che col 65816 non possono che gioire grazie alle ben 24 che adesso sono a disposizione.
Modalità che permettono di accedere ai dati in maniera relativa rispetto al PC (program counter) o allo stack, mancanza di cui si sentiva e che tutti i microprocessori più moderni mettono bene o male a disposizione.
Una grossa pecca che trovo, però, è quella della gestione della dimensione dei registri e dei dati. Il processore, infatti, è in grado di manipolare quantità a 8 o 16 bit in maniera molto “rigida”, previa apposita impostazione (esistono due istruzioni allo scopo). Per essere precisi, è possibile decidere programmaticamente se l’accumulatore e l’accesso alla memoria debbano essere a 8 o 16 bit; lo stesso si può fare per i registri indice (X e Y).
Da ciò si evince che non è possibile miscelare arbitrariamente istruzioni che trattano quantità a 8 e 16 bit, come avviene invece con la maggior parte delle altre CPU. Se, ad esempio, devo lavorare con un dato a 8 bit e subito dopo con uno a 16 bit, sarà necessario impostare prima la modalità a 8 bit (con l’istruzione REP), e poi quella a 16 bit (con la SEP).
Chi ha esperienza nel campo della programmazione di basso livello (con assembly e/o linguaggio macchina) starà sicuramente storcendo il naso, e personalmente non posso che condividere questo malumore: è un meccanismo decisamente ostico con cui lavorare, che porta a perdere tempo (dovendo utilizzare diverse volte le istruzioni REP e SEP) e risulta anche suscettibile a errori (basta sbagliare la maschera di bit da impostare per andare incontro a disastri che possono essere difficili da scoprire).
Anche qui si tratta di scelte di design volte a mantenere la semplicità architetturale di cui parlavo prima, che con l’utilizzo dei prefissi l’avrebbe sicuramente complicata, ma anche reso la vita molto più facile ai programmatori.
In ogni caso e per quanto discutibili possano essere queste decisioni, è stato fatto un buon lavoro per ridare linfa alla “serie 65”. Soprattutto se pensiamo che dietro al design dell’intero progetto c’era praticamente un solo uomo: il CEO della stessa società da lui fondata!