ITALIA  
 
Commodore 64 vs. Sinclair Spectrum :: La Memoria
 
 
Chip 4164 8K DRAM
Mappa di memoria del C64 all'accensione
 
Come il C64 vede la memoria

Caratteristiche e gestione della memoria

La prima versione dello Spectrum nasceva con 16K di RAM espandibile a 48K mediante l'inserzione di chip di memoria e logica di controllo in zoccoli appositamente previsti. Quasi immediatamente fu però disponibile la ben più dotata versione con 48K di base. I primi 16K dello Spectrum erano composti da 8 integrati DRAM 4116 da 2K ciascuno e e costituivano la memoria base della macchina. I successivi 32K di memoria erano composti da 8 chip DRAM 4132 da 4K. E' significativo notare come i 4132 fossero in realtà dei 4164 con un banco malfunzionante, quindi utilizzabili solo per metà e rimarchiati 4132. All'atto dell'espansione era importante verificare che tutti gli 8 chip avessero il medesimo banco buono (quello superiore o quello inferiore) e non mischiare chip dei due tipi. Bisognava poi settare un jumper all'interno dello Spectrum in accordo al banco da utilizzare. La mappa della memoria dello Spectrum è abbastanza semplice e statica. La ROM è collegata direttamente alle 16K linee più basse e non può essere modificata o esclusa via software, ad esempio per aumentare la RAM senza meccanismi di paginazione. Seguono poi la memoria video (display file), le variabili di sistema e la memoria utente. L'area delle variabili di sistema non è propriamente statica e può spostarsi a seconda che i microdrive siano o meno presenti, poiché questi ultimi vanno ad occupare una piccola porzione di memoria.

Il Commodore 64 dispone di 64K di RAM costituiti da 8 chip DRAM 4164 da 8K ciascuno più un chip 2114 da 0.5K per la RAM colore. Alla locazioni 0 e 1 troviamo la porta I/O del processore 6510. Il resto dei primi 2K è occupato dale variabili di sistema e dalla memoria schermo, di circa 1 k, utilizzata per il modo testo. Vi sono poi 38K di memoria utente per il BASIC, il linguaggio BASIC in ROM seguito da un'area protetta di 4K nella quale memorizzare routine in linguaggio macchina, lo spazio di I/O per gestire ai vari coprocessori interni ed infine la ROM del Kernal. Come si nota, anche nel C64 una parte della memoria viene occupata per compiti interni e all'accensione sono disponibili per il BASIC 38K. Questo ha dato luogo nel tempo alla errata credenza che il 64 non abbia veramente 64K di memoria. In realtà la gestione della memoria nel C64 è complessa e versatile, ed è uno dei maggiori punti di forza della macchina. Nel C64 oltre ai 64K di RAM ci sono anche 20K di ROM. Come era possibile far vedere alla CPU, che disponeva di bus indirizzi a 16 bit, ben 84K locazioni senza utilizzare la paginazione e senza una costosa MMU? Con una soluzione semplice ma intelligente: il C64 vede le ROM sovrapposte alla RAM (cioè con gli stessi indirizzi di una porzione di RAM). Utilizzando la porta I/O della CPU è possibile switchare dinamicamente in e out le porzioni di ROM che in un dato momento non ci servono aumentando la RAM disponibile. Per farlo basta scrivere un byte alla locazione 0. Se ad esempio vogliamo lavorare in linguaggio macchina possiamo scaricare momentaneamente il BASIC, recuperando 8K ed ottenendo un unico blocco contiguo di 50K. Scaricando il Kernal si possono guadagnare altri 8K di RAM portando il totale al 58K.

Mappa di memoria
dello Spectrum

Ma non finisce qui. In condizioni standard il C64 non può usare la RAM in lettura ma può accedervi in scrittura. Poiché il processore video accede alla RAM in maniera indipendente, significa che è possibile usare come memoria video la porzione di RAM che sta "sotto" alle ROM e senza doverle scaricare. Inoltre la memoria video nel C64 è rilocabile e può essere piazzata dove torna più comodo, si possono preparare più pagine grafiche in memoria da intercambiare all'occorrenza e si possono generare effetti interessanti. Questo costituisce un indubbio vantaggio rispetto allo Spectrum dove il display file è statico e non è possibile recuperare più memoria. Anche se si possono memorizzare dati in quell'area bisogna in tal caso rinunciare a grafica e testo, e quindi l'utilità è fortemente limitata ad alcune applicazioni particolari (come i copiatori). Continuando ad analizzare la mappa di memoria del C64 si notano altri particolari. Lo spezzone di 4K posto sopra al BASIC ad esempio non si trova in tale posizione per un caso o per una implementazione frettolosa. Accorpare quei 4K ai sottostanti 38K non avrebbe modificato sostanzialmente le possibilità della macchina poiché 38K erano all'epoca più che sufficienti per qualsiasi programma BASIC. Basti pensare che negli elaboratori CP/M da ufficio, dotati di 64K e dal costo di svariati milioni di Lire, il BASIC Microsoft lasciava disponibili 31K. In quella posizione invece, il piccolo spezzone costituisce un area protetta dalla sovrascrittura dai programmi BASIC nella quale è possibile memorizzare piccole routine in linguaggio macchina da richiamare all'occorrenza, programmi TSR o nuovi comandi da aggiungere al BASIC stesso. Nello Spectrum invece è necessario provvedere alla protezione delle routine in linguaggio macchina, assicurandoci che i programmi in BASIC non vadano a sovrascriverle. Nel C64 il meccanismo di gestione della memoria permette anche di copiare in RAM le ROM, scaricarle e poi modificarle a nostro piacimento, oppure trattenere solo le porzioni che ci servono e liberare il resto. Il linguaggio di base ed il sistema operativo possono essere completamente rimpiazzati da altri e senza un'eccessiva penalizzazione in termini di memoria come invece avverrebbe sullo Spectrum. Le possibilità sono davvero tante e sono limitate solamente dalla fantasia del programmatore.

Un esempio di utilizzo della memoria nascosta

Questo è un semplice programma che illustra alcuni dei concetti sopra esposti. Utilizza per la grafica la memoria che si trova sotto all' interprete BASIC direttamente da linguaggio BASIC, senza doverlo disabilitare.

10 BNC=16384*2
20 POKE 56576,PEEK(56576)AND252)OR1 30 POKE 53272,PEEK(53272)OR8
40 BASE=BNC+8192
50 POKE 53265,PEEK(53265)OR32
60 FOR I=BASE TO BASE+7999:POKE I,0:NEXT I
70 FOR U=BNC+1024 TO BNC+2043:POKE U,1:NEXT U
80 FOR I=0 TO 39:POKE BASE+3200+I*8,255:NEXT I
90 FORB=BNC+1424 TO BNC+2024:POKEB,3:NEXTB
100 GET A$:IF A$="" THEN 100
100 POKE 53272,21:POKE56576,151:POKE53265,155
110 END

le linee da 10 a 30 settano il VIC-II per vedere il banco $8000-$BFFF e selezionano la pagina alta, quella agli indirizzi $A000-$BFFF situata proprio sotto l'interprete BASIC (cioè alle stesse locazioni). Successivamente viene attivata la modalità bitmap mentre la linea 60 azzera la memoria video e la linea 70 setta il colore bianco per tutte le locazioni nella memoria colore. Le linee 80 e 90 disegnano una riga in alta risoluzione che divide in due lo schermo e colorano la parte inferiore di celeste. Infine si attende la pressione di un tasto per riportare tutto alla normalità. Poiché la pagina disponibile è di 8192 bytes mentre il bitmap ne occupa 8000, possiamo utilizzare lo spazio rimasto per qualcosa di utile, ad esempio inserirvi dati relativi agli sprite, aggiungendo le seguenti linee:

95 GOSUB 1000
1000 X=255:POKE BNC+2040,X
1010 FORI=0 TO 26:POKE BNC+X*64+I,0:NEXTI
1020 FORJ=27 TO 62:READA:POKE BNC+X*64+J,A:NEXTJ
1030 POKE 53269,1 accende lo sprite #0 1040 POKE 53287,2
1050 POKE 53249,113:POKE53248,0
1060 FORI=0 TO 160 STEP.025:POKE53248,INT(I):NEXT
1070 RETURN 1100 DATA 0,24,0,0,24,0,0,24,0 1110 DATA 0,255,0,0,249,0,0,255,0 1120 DATA 255,255,255,127,255,254,63,255,252 1130 DATA 31,255,248,15,255,240,7,255,224

La linea 1000 setta il puntatore ai dati per lo sprite proprio nella spazio libero della nostra pagina. Le linee 1010-1040 si occupano di disegnare e colorare lo sprite, le 1050-1060 di posizionare e muovere lo sprite. Tutto è stato fatto con poche righe di BASIC utilizzando come memoria video la memoria nascosta e senza dover rinunciare ad alcuna parte delle ROM. Questo è solo un esempio, molte altre sono le possibilità di utilizzo e ribadicono l'intrinseca versatilità della macchina.