This the multi-page printable view of this section.Click here to print.

Return to the regular view of this page.

Commodore 64 Memory Map

Commodore 64 Memory Map

Table of Contents

The following table shows the memory map for the Commodore 64.

Docs Address Normal Use Alternate Use All RAM mode ROM Cartridge
Page 00 0000 6510 IO DDR
0001 6510 IO Port
0002 Free for application use
0003 Kernal & BASIC Zero Page
00FB User Zero Page
00FF BASIC Temp Area
0100 Processor Stack
Page 02 0200 BASIC editor input buffer
0259 Kernal file tables
0277 Kernal Workspace
02A7 Free for application use
Page 03 0300 BASIC workspace
0314 Kernal Vector table
0334 Application Vector table
033C Cassette I/O Buffer
03FC Free for application use
0400 Default screen 1K Free if screen is mapped elsewhere
0800 38K Application memory 30K Application memory
8000 Cart ROM Low
A000 BASIC ROM 8K RAM Cart ROM High
C000 4K RAM
Page D0 D000 VIC-II Registers Character ROM 4K RAM As other columns
D400 SID Registers
Page D8 D800 Color RAM
Page DC DC00 CIA 1
Page DD DD00 CIA 2
DE00 Expansion I/O
DF00
Kernal E000 KERNAL ROM 8K RAM Cart ROM High
F000

Notes

  • The alternate use for a section of the memory map is selected by bits 0…2 of the 6510 I/O port.
    Note bits 0 & 1 must have at least 1 bit set. Both clear triggers All RAM mode.
  • All RAM Mode is selected with bits 0&1 of the 6510 I/O port set to 0.
    This mode exposes ram in the I/O area. It's not as useful due to it hiding the device I/O area.
  • Memory in pages 00…7F is always RAM
  • A cartridge can provide rom in 3 8K locations, although only 2 8K banks can be made visible to the processor at any time.
  • The default location of the screen & sprites is in pages 04…07. This can be reused if the screen is remapped in the VIC-II chip to an alternate location in memory.
  • Writing to memory when a ROM is paged in will still write to the RAM. Only reading will get data from the ROM.

    This is useful with BitMap screen mode as you can map the screen beneath the KERNAL rom as the VIC-II chip always sees RAM.

1 - Page 00

C64 Zero Page
AddressLenNameDescriptionDefault
00001D65106510 On-Chip I/O DATA Direction Register
Bit 0 Direction of Bit 0 on I/O Port. Default = 1 Output
Bit 1 Direction of Bit 1 on I/O Port. Default = 1 Output
Bit 2 Direction of Bit 2 on I/O Port. Default = 1 Output
Bit 3 Direction of Bit 3 on I/O Port. Default = 1 Output
Bit 4 Direction of Bit 4 on I/O Port. Default = 0 Input
Bit 5 Direction of Bit 5 on I/O Port. Default = 1 Output
Bit 6 Direction of Bit 6 on I/O Port. Not used
Bit 7 Direction of Bit 7 on I/O Port. Not used
0xEF
00011R65106510 On-Chip I/O Port
Bit 0 LORAM. Selects ROM/RAM at 0xA000. 1=Basic, 0=RAM
Bit 1 HIRAM. Selects ROM/RAM at 0xE000, 1=Kernal, 0=RAM
Bit 2 CHAREN. Selects Character ROM or I/O devices. 1=I/O, 0=ROM
Bit 3 Cassette Data Output line
Bit 4 Cassette switch sense. Reads 0=button pressed, 1=not pressed
Bit 5 Cassette Motor Control. 1=Motor on, 0=Motor off
Bit 6 Not used, not connected on 6510
Bit 7 Not used, not connected on 6510
0x37
00021Unused
00032ADRAY1Vector to routine to convert Number from Floating Point to Signed Integer0xB1AA
00052ADRAY2Vector to routine to convert Number from Integer to Floating Point0xB391
0007Used by BASIC and/or Kernal
000A1VERCKFlag: LOAD or VERIFY
00 LOAD
01-FF VERIFY
000BUsed by BASIC and/or Kernal
002B2TXTTABPointer to start of BASIC program text0x0801
002D2VARTABPointer to start of BASIC Variable storage areaEnd of program +1
002F2ARYTABPointer to start of array variable area
00312STRENDEnd of Basic array storage (+1), Start of free ram
00332FRETOPPointer to bottom of string text area
Grows downwards from end of BASIC area
00352FRESPCTemp pointer for strings
00372BASMEMSIZHighest address used by basic
RS232 device can reduce this by 512 bytes for it's buffers
0x9FFF
0039Used by BASIC
0090Used by Kernal
00CC1BLNSWCursor Blink Enable
00 Cursor is on
01-FF Cursor is off
00CDUsed by Kernal
00F72RIBUFRS232 Input Buffer Pointer
00xx for no buffer, allocate on input, any other value buffer exists
00F92ROBUFRS232 Output Buffer Pointer
00xx for no buffer, allocate on output, any other value buffer exists
00FB4FREKZP4 free bytes of Zero Page for User Programs
Guaranteed BASIC will not use these 4 bytes
00FF12BASZPTBASIC temp data area for floating point to ASCII conversion
Runs into start of page 1, free for use if conversions not needed

The C64 uses the 6510 Microprocessor, a variant of the 6502. The main difference is that this Microprocessor contains a built-in 8-bit I/O port, with 6 pins exposed on the 6510. This port is mapped into memory at addresses 0000 & 0001.

2 - Page 02

C64 Page 2
AddressLenNameDescriptionDefault
020089BUFBASIC Line Editor Input Buffer
0259Kernal File Tables
025910LATActive logical file number table
026310FATDevice number for each logical file
026D10SATSecondary address for each logical file
027710KEYDKeyboard buffer
02812MEMSTRStart of Memory pointer0x0800
02832MEMSIZEnd of Memory pointer
Usually this is the first byte of the BASIC ROM
0xA000
0286Screen workspace
02861COLORCurrent Foreground text colour
02871GDCOLColour of character under Cursor
02881HIBASEPage of Screen Memory0x04
0289Keyboard workspace
02891XMAXMax length of keyboard buffer
0x00 No buffer
0x01-0x0F Buffer size
028A1RPTFLGWhich keys will repeat
0x00 Only cursor, insert, delete or space repeat
0x40 No keys repeat
0x80 All keys repeat
028D1SHFLAGShift/Ctrl/Commodore key pressed
Bit 0 1=Left or Right shift is pressed or Shift Lock is active
Bit 1 1=Commodore key pressed
Bit 2 1=Control pressed
028E1LSTSHFLast value of Shift/Ctrl/Commodore key pressed
Used with SHFLAG to debounce those keys. Values match those for SHFLAG
02911MODEShift/Commodore switch
Enables/Disables character switching when Shift & Commodore keys are pressed
0x00 Commodore-Shift is disabled
0x80 Commodore-Shift will toggle between uppercase/graphics & lowercase/uppercase character set
02921AUTODNScreen scrolling enabled
0 enables scrolling, any other value disables scrolling
0293Mock 6551 RS-232
02931M51CTRMock 6551 RS-232 Control Register
%0xxxxxxx 1 stop bit
%1xxxxxxx 2 stop bits
%x00xxxxx 8 data bits
%x01xxxxx 7 data bits
%x10xxxxx 6 data bits
%x11xxxxx 5 data bits
%xxxx0110 300 bps
%xxxx1000 1200 bps
%xxxx1010 2400 bps
02941M51CDRMock 6551 RS-232 Command Register
%001xxxxx Odd Parity
%011xxxxx Even Parity
%101xxxxx Mark Parity
%111xxxxx Space Parity
%xx0xxxxx No parity
%xxx0xxxx Full Duplex
%xxx1xxxx Half Duplex
%xxxxxxx0 3 Line
%xxxxxxx1 X Line
02952M51AJBMock 6551 RS-232 Nonstandard Bit Timing
Not actually used by Kernal but present for 6551 UART emulation
02971M51STATMock 6551 RS-232 Status Register
Bit 0 1=Parity Error
Bit 1 1=Framing Error
Bit 2 1=Receive Buffer Overrun
Bit 3 1=Receive Buffer Empty
Bit 4 1=CTS (Clear To Send) Signal Missing
Bit 5 Unused
Bit 6 1=DTR (Data Set Ready) Signal Missing
Bit 7 1=Break Detected
02983Used by Kernal for RS-232
029BRS-232 Buffers
029B1RIDBERS-232 Index to end of receive buffer
029C1RIDBSRS-232 Index to start of receive buffer
029D1RODBERS-232 Index to end of transmit buffer
029E1RODBSRS-232 Index to start of transmit buffer
02A11ENABLRS-232 Interrupts Enabled
Bit 0 System is transmitting data
Bit 1 System is receiving data
Bit 4 System is waiting for receiver edge
02A2Used by Kernal
02A789Unused, available for application use

3 - Page 03

C64 Page 3 Vectors & Cassette Buffer
AddressLenNameDescriptionDefault
030012BASIC Indirect vector table
030C4Storage for registers with BASIC SYS call
1 byte each for A, X, Y & Status in that order
03103USRPOKJump instruction for BASIC USR() function
Actual JMP instruction so first byte MUST be 0x4C
0x4c
03112USRADDAddress of USR() function
This is the address used by USR() when it calls USRPOK
03131Unused
03142CINVIRQ Interrupt Routine Vector0xEA31
03162CBNVBRK Interrupt Routine Vector0xFE66
03182NMINVNMI Interrupt Routine Vector0xFE47
031AKernal Indirect Vectors
031A2IOPENKernal OPEN Vector0xFE4A
031C2ICLOSEKernal close Vector0xF291
031e2ICHKINKernal CHKIN Vector0xF20E
03202ICKOUTKernal CKOUT Vector0xF250
03222ICLRCHKernal CLRCHN Vector0xF333
03242IBASINKernal CHRIN Vector0xF157
03262IBSOUTKernal CHROUT Vector0xF1CA
03282ISTOPKernal STOP Vector0xF6ED
032A2IGETINKernal GETIN Vector0xF13E
032C2ICLALLKernal CLALL Vector0xF32F
032E2USRCMDUser-Defined Command Vector
Unused on C64, holdover from the PET.
0xFE66
03302ILOADKernal LOAD Vector0xF49E
03322ISAVEKernal SAVE Vector0xF5DD
03348Unused, space for 4 user vectors
033C192TBUFFRCassette I/O Buffer
03FC4Unused

4 - Page D0

VIC-II Registers
AddressNameBit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Description
D000VIC2M0XM0XX Coordinate Sprite 0
D001VIC2M0YM0YY Coordinate Sprite 0
D002VIC2M1XM1XX Coordinate Sprite 1
D003VIC2M1YM1YY Coordinate Sprite 1
D004VIC2M2XM2XX Coordinate Sprite 2
D005VIC2M2YM2YY Coordinate Sprite 2
D006VIC2M3XM3XX Coordinate Sprite 3
D007VIC2M3YM3YY Coordinate Sprite 3
D008VIC2M4XM4XX Coordinate Sprite 4
D009VIC2M4YM4YY Coordinate Sprite 4
D00AVIC2M5XM5XX Coordinate Sprite 5
D05BVIC2M5YM5YY Coordinate Sprite 5
D00CVIC2M6XM6XX Coordinate Sprite 6
D00DVIC2M6YM6YY Coordinate Sprite 6
D00EVIC2M7XM7XX Coordinate Sprite 7
D00FVIC2M7YM7YY Coordinate Sprite 7
D010VIC2MNXM7X8M6X8M5X8M4X8M3X8M2X8M1X8M0X8Bit 8 of X coordinates
D011VIC2CR1RST8[1]ECMBMMDENRSELYSCROLLControl register 1
D012VIC2RASTERRASTER[1]Raster counter
D013VIC2LPXLPXLight pen X
D014VIC2LPYLPYLight pen Y
D015VIC2SPEM7EM6EM5EM4EM3EM2EM1EM0ESprite Enabled
D016VIC2CR2RES[3]MCMCSELXSCROLLControl register 2
D017VIC2SPYEM7YEM6YEM5YEM4YEM3YEM2YEM1YEM0YESprite Y expansion
D018VIC2MPTRVM13VM12VM11VM10CB13CB12CB11Memory pointers
D019VIC2INTRIRQILPIMMCIMBCIRSTInterrupt Register
D01AVIC2INTEIRQELPEMMCEMBCERSTInterrupt Enabled
D01BVIC2SPDPM7DPM6DPM5DPM4DPM3DPM2DPM1DPM0DPSprite data priority
D01CVIC2SPMCM7MCM6MCM5MCM4MCM3MCM2MCM1MCM0MCSprite multicolour
D01DVIC2SPXEM7XEM6XEM5XEM4XEM3XEM2XEM1XEM0XESprite X expansion
D01EVIC2SPSPCOLM7MM6MM5MM4MM3MM2MM1MM0MSprite-Sprite collision[2]
D01FVIC2SPDCOLM7DM6DM5DM4DM3DM2DM1DM0DSprite data collision[2]
D020VIC2BORDERECBorder colour
D021VIC2B0CB0CBackground colour 0
D022VIC2B1CB1CBackground colour 1
D023VIC2B2CB2CBackground colour 2
D024VIC2B3CB3CBackground colour 3
D025VIC2SPMM0MM0Sprite multicolour 0
D026VIC2SPMM1MM1Sprite multicolour 1
D027VIC2SPCOL0M0CSprite 0 colour
D028VIC2SPCOL1M1CSprite 1 colour
D029VIC2SPCOL2M2CSprite 2 colour
D02AVIC2SPCOL3M3CSprite 3 colour
D02BVIC2SPCOL4M4CSprite 4 colour
D02CVIC2SPCOL5M5CSprite 5 colour
D02DVIC2SPCOL6M6CSprite 6 colour
D02EVIC2SPCOL7M7CSprite 7 colour
D02E0xFF on read, write ignoredUnused
D02F0xFF on read, write ignoredUnused
D0300xFF on read, write ignoredUnused
D0310xFF on read, write ignoredUnused
D0320xFF on read, write ignoredUnused
D0330xFF on read, write ignoredUnused
D0340xFF on read, write ignoredUnused
D0350xFF on read, write ignoredUnused
D0360xFF on read, write ignoredUnused
D0370xFF on read, write ignoredUnused
D0380xFF on read, write ignoredUnused
D0390xFF on read, write ignoredUnused
D03A0xFF on read, write ignoredUnused
D03B0xFF on read, write ignoredUnused
D03C0xFF on read, write ignoredUnused
D03D0xFF on read, write ignoredUnused
D03E0xFF on read, write ignoredUnused
D03F0xFF on read, write ignoredUnused

Multiple address ranges

The VIC-II chip has 64 addressable registers. In the C64 memory map it is mapped to the range 0xD000…0xD3FF with it's registers repeated every 64 bytes.

This means that the following address ranges match those of the first 64 bytes at 0xD000…0xD03F:

Address Range Equivalent
0xD0400xD07FSame as 0xD000…0xD03F
0xD0800xD0BFSame as 0xD000…0xD03F
0xD0C00xD0FFSame as 0xD000…0xD03F
0xD1000xD13FSame as 0xD000…0xD03F
0xD1400xD17FSame as 0xD000…0xD03F
0xD1800xD1BFSame as 0xD000…0xD03F
0xD1C00xD1FFSame as 0xD000…0xD03F
0xD2000xD23FSame as 0xD000…0xD03F
0xD2400xD27FSame as 0xD000…0xD03F
0xD2800xD2BFSame as 0xD000…0xD03F
0xD2C00xD2FFSame as 0xD000…0xD03F
0xD3000xD33FSame as 0xD000…0xD03F
0xD3400xD37FSame as 0xD000…0xD03F
0xD3800xD3BFSame as 0xD000…0xD03F
0xD3C00xD3FFSame as 0xD000…0xD03F

Notes:

  1. RST8 in 0xD011 is bit 8 of the RASTER register in 0xD012.
  2. Registers 0xD01E & 0xD01F cannot be written and are cleared on reading
  3. RES in 0xD016 stops the VIC on the 6566. It has no function on the 6567 or 6569
  4. Bit's with no label are not connected and return 1 on a read.

5 - Page D4

SID Registers
AddressNameBit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Description
D400SID1FRELOWFRE1LOWFrequency voice 1 low byte
D401SID1FREHIGHFRE1HIGHFrequency voice 1 high byte
D402SID1PWDCLOWPWDC1LOWPulse wave duty cycle voice 1 low byte
D403SID1PWDCHIGHPWDC1HIGHPulse wave duty cycle voice 1 high byte
D404SID1CRnoisepulsesawtoothtriangletestringmod V3synth V3gateControl Register voice 1

6 - Page D8

Colour memory
AddressLenNameBit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Description
D8001000COLMEMNot ConnectedColourColour Memory
D8E824Not ConnectedUnusedUnused

Memory format

For each character in every row (40 chars per row; 0-39) and column (25 columns; 0-24) one of 16 colors can be assigned. The color values 0-15 are only used in the lower nibbles. The upper nibbles are undefined and are purely random values.

The colour memory is provided by an MM2114N-3 4Kb (1024x4) static RAM chip.

As this chip only provides 4 bits, the upper nibble is random as it's not connected to anything. It is separate from the onboard 64K RAM

7 - Page DC

CIA 1
AddressNameBit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Description
DC00CIA1PRAKM7
PAD
KM6
PAD
KM5KM4
J2FB
LPEN
KM3
J2Dn
KM2
J2Up
KM1
J2Rt
KM0
J2Lt
Data Port A[1,2,3]
DC01CIA1PRBKM7
TIMB
KM6
TIMA
KM5KM4
J1FB
LPEN
KM3
J1Dn
KM2
J1Up
KM1
J1Rt
KM0
J1Lt
Data Port B[1,4]
DC02CIA1DDRADDA7DDA6DDA5DDA4DDA3DDA2DDA1DDA0Data Direction Port A
DC03CIA1DDRBDDB7DDB6DDB5DDB4DDB3DDB2DDB1DDB0Data Direction Port B
DC04CIA1TIMALTIMALTimer A Low byte
DC05CIA1TIMAHTIMAHTimer A High byte
DC06CIA1TIMBLTIMBLTimer B Low byte
DC07CIA1TIMBHTIMBHTimer B High byte
DC08CIA1RTCTRTCTReal time clock 1/10s
DC09CIA1RTCSRTCSReal time clock seconds
DC0ACIA1RTCMRTCMReal time clock minutes
DC0BCIA1RTCHRTCHReal time clock hours
DC0CCIA1SRSRShift register
DC0DCIA1ICSIRQ
Source
Always 0
Unused
IRQ Flag
IntRel
SDR
IntRel
Alarm
IntRel
UTB
IntRel
UTA
IntRel
Interrupt Control & Status
Read top, Write bottom
DC0ECIA1CTARTC[5]SRC[6]TSRC[7]Load[8]RES[9]OVFL[10]UNFL1[11]STARTControl Timer A
DC0FCIA1CTBTCOUNT[13]Load[8]RES[9]OVFL[10]UNFL2[12]STARTControl Timer B

Multiple address ranges

CIA1 is mapped to addresses 0xDCxx but only occupies 16 bytes. Referencing any address from 0xDC1x…0xDCFx will mirror those at 0xDC0x.

Notes:

  1. Keyboard matrix pins are R/W. PRA for columns, PRB for rows
  2. Joystick pins 0=activated. Port 1 in PRA and Port 2 on PRB
  3. Bits 6 & 7 of CIA1PRA selects paddle, %01=Paddle A, %10=Paddle B
  4. Bits 6 & 7 of CIA1PRB handler timer toggle/impule output.<br/>Bit 2 of register 14 or timer A & 15 for B
  5. RTC 0=60Hz 1=50Hz
  6. Shift register direction SP pin 0=read, 1=write
  7. TSRC 0=count system cycles, 1=positive slope at CNT pin
  8. 1 = Load latic into the timer once
  9. 0 = Timer restart after underflow (latch reloaded), 1 = timer stops after underflow
  10. 0 = Timer overflow, port B bit 6 high 1 cycle, 1 = underflow, port B bit 6 inverted
  11. 1 = Indicates timer underflow at port B bit 6
  12. 1 = Indicates timer underflow at port B bit 7
  13. Timer counts: %00 System cycle, %01 +ve slope CNT-pin, %10 Timer A underflow, %11 Timer A underflow if CNT-pin high

8 - Page DD

CIA 2
AddressNameBit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Description
DD00CIA2PRASBDISBCISBDOSBCOSBAOTXD/PA2VICMEM[]Data Port A[1,2,3]
DD01CIA2PRBPB7
DSR
PB6
CTS
PB5
UPJ
PB4
DCD
PB3
RI
PB2
DTR
PB1
RTS
PB0
RXD
User Port PB0-7[4]
DD02CIA2DDRADDA7DDA6DDA5DDA4DDA3DDA2DDA1DDA0Data Direction Port A
DD03CIA2DDRBDDB7DDB6DDB5DDB4DDB3DDB2DDB1DDB0Data Direction Port B
DD04CIA2TIMALTIMALTimer A Low byte
DD05CIA2TIMAHTIMAHTimer A High byte
DD06CIA2TIMBLTIMBLTimer B Low byte
DD07CIA2TIMBHTIMBHTimer B High byte
DD08CIA2RTCTRTCTReal time clock 1/10s
DD09CIA2RTCSRTCSReal time clock seconds
DD0ACIA2RTCMRTCMReal time clock minutes
DD0BCIA2RTCHRTCHReal time clock hours
DD0CCIA2SRSRShift register
DD0DCIA2ICSNMI[14]
Source
Always 0
Unused
NMI Flag[15]
IntRel
SDR
IntRel
Alarm
IntRel
UTB
IntRel
UTA
IntRel
Interrupt Control & Status
Read top, Write bottom
DD0ECIA2CTARTC[5]SRC[6]TSRC[7]Load[8]RES[9]OVFL[10]UNFL1[11]STARTControl Timer A
DD0FCIA2CTBTCOUNT[13]Load[8]RES[9]OVFL[10]UNFL2[12]STARTControl Timer B

Multiple address ranges

CIA2 is mapped to addresses 0xDDxx but only occupies 16 bytes. Referencing any address from 0xDD1x…0xDDFx will mirror those at 0xDD0x.

Notes:

  1. SBxx Serial Bus, D=Data, C=Clock, A=Attention, I=In, O=Out
  2. Bit 2 is RS232 TXD output or the userport PA2 (Pin M)
  3. Bits 0 & 1 VIC-II memory base, %00 = Bank 3 0xC000-0xFFFF, %01 = Bank 2 0x8000-0xBFFF, %10 = Bank 1 0x4000-0x7FFF, %11 = Bank 0 0x0000-0x3FFF
  4. Port B is the user port data, either 8 I/O pins or RS232
  5. RTC 0=60Hz 1=50Hz
  6. Shift register direction SP pin 0=read, 1=write
  7. TSRC 0=count system cycles, 1=positive slope at CNT pin
  8. 1 = Load latic into the timer once
  9. 0 = Timer restart after underflow (latch reloaded), 1 = timer stops after underflow
  10. 0 = Timer overflow, port B bit 6 high 1 cycle, 1 = underflow, port B bit 6 inverted
  11. 1 = Indicates timer underflow at port B bit 6
  12. 1 = Indicates timer underflow at port B bit 7
  13. Timer counts: %00 System cycle, %01 +ve slope CNT-pin, %10 Timer A underflow, %11 Timer A underflow if CNT-pin high
  14. CIA-2 is connected to the NMI line
  15. NMI Signal occured at FLAG-pin RS232 data received