La mappa di memoria del C/64

Oggi parleremo della mappa di memoria del C/64. Dovete sapere che programmare il C/64 era complicato per diverse ragioni:

  1. Il Basic V2 era troppo lento per scrivere giochi effettivi
  2. La maggior parte delle feature richiedevano di scrivere direttamente su celle di memoria mappate sui chip audio e video, spesso cambiando singoli bit.
  3. La mappa di memoria del C/64 era abbastanza complessa, soprattutto se confrontata con molti altri computer del medesimo periodo.


La Mappa di memoria dal C64Wiki

.

Premessa: il MOS 6502 non ha istruzioni di I/O dedicate.

Commodore penso' di  mappare i registri I/O dei chip del C/64 direttamente sulla RAM. Questo semplificava anche la scrittura del software, solo che... gli altri microcomputer (es Vic20 o C/16) non avevano cosi' tanta memoria... e quindi non era un problema mappare questi registri nello spazio di indirizzamento da 64Kb, ne' mappare le ROM. Per prendere anche una architettura diversa,  lo ZX Spectrum  aveva "solo" 48Kb RAM e teneva la ROM in quello che restava (16Kb)

Il C/64 veniva fornito con un quantitativo di RAM enorme, che riempiva tutto lo spazio di indirizzamento del 6502,: si trattava di una scommessa fatta (e vinta) da Commodore che confidava sulla riduzione dei costi dei chip di memoria RAM statica.

Per cui la ROM era "mappata" sullo spazio di indirizzamento del 6502, e quindi la ROM del BASIC e de Kernal poteva essere "rimpiazzata" dalla RAM sottostante (Bank Switching).

Tutto questo era gestito attraverso la locazione $01, che pilotava un chip chiamato Programmable Logic Array  (PLA, peraltro uno dei chip custom del C/64).

In particolare ecco la semantica della locazione $01 bit per bit:

1	Bit 0 - LORAM: Configures RAM or ROM at $A000-$BFFF
2	Bit 1 - HIRAM: Configures RAM or ROM at $E000-$FFFF
3	Bit 2 - CHAREN: Configures I/O or ROM at $D000-$DFFF
4	Bit 3 - Cassette Data Output Line (Datasette)
5	Bit 4 - Cassette Switch Sense; 1 = Switch Closed
6	Bit 5 - Cassette Motor Control; 0 = On, 1 = Off
7	Bit 6 - Undefined
8	Bit 7 - Undefined

I 4Kb in $D000-DFFF hanno un triplo bank switching: in questi 4KB trovate sia la maggior parte dei registri di I/O,  la ROM dei caratteri e ALTRI 4 Kb di VERA RAM.

Peccato che per accedere alla RAM in $D000 si deve per forza disattivare anche il Kernal in $E000-$FFFF e quindi il suo utilizzo non risulta agevolissimo (questo schema mostra tutte le configurazioni). Rinunciare al Kernal non è agevole perché gli interrupt (mascherabili (IRQ) e non (NMI)) hanno bisogno delle routine di gestione, e queste stanno proprio nel Kernal: se lo si disativa bisogna reimplementarsele a mano.

La CHAR ROM è "posizionata" in $D000 solo ad uso e consumo del 6502: il VIC-II usa un modo completamente diverso per indirizzare la memoria perchè puó indirizzare solo 16k di RAM alla volta.  Siccome 16x4 fa 64, ci sono solo 4 "banchi" in cui è segmentata la memoria per il VIC-II e bastano due bit per dirgli che banco "guardare".

Difatti si dice che inizialmente il C/64 era stato pensato per avere solo 16Kb di RAM, da cui si capisce perché il VIC-II avesse solo un bus a 14 bit.

In due di queste quattro modalitá la CHAR ROM è visibile al VICII, e non c'è bisogno di mapparla nello spazio di indirizzamento del C/64. La CHAR ROM è accessibile in $D000 nel caso serva ai programmi applicativi, per es per "copiarla" in memoria e fare solo piccole modifiche ad una parte del charset.

Un bel caos giusto?

Le cartucce

Le cartucce (CART ROM) possono mappare fino a tre aree per un totale di 3x8=24Kb, ma devono di norma coprire l'area da $8000 perché al BOOT il kernal cerca lí la signature che scatena il lancio per consentire alla cartuccia di partire. In particolare in $8004–$8008 deve esserci la stringa "CBM80" che fa sí che il Kernal faccia un salto indiretto all'indirizzo posto in $8000-8001.

Ciliegina sulla torta, non trovate proprio tutti gli I/O in $D000-DFFF, perche' alcuni sono sulle locazioni $00- $01 e altri si trovano sul registro SID (!) per es i potenziometri per alcuni dispositivi come i paddle gioco.