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

Return to the regular view of this page.

Commodore C64 Kernal

Notes about the C64 operating system & memory

CC BY-SA

Peter Mount, Area51.dev & Contributors

Commodore C64 Kernal

Notes about the C64 operating system & memory

TitleCommodore C64 Kernal
SubtitleNotes about the C64 operating system & memory
AuthorPeter Mount, Area51.dev & Contributors
CopyrightCC BY-SA

CC BY-SA version 4.0 license

You are free to:

  1. Share — copy and redistribute the material in any medium or format
  2. Adapt — remix, transform, and build upon the material or any purpose, even commercially.

This license is acceptable for Free Cultural Works.

The licensor cannot revoke these freedoms as long as you follow the license terms.

Under the following terms:

  1. Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
  2. ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
  3. No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.

Notices:

You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.

No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.

You can read the full license here: https://creativecommons.org/licenses/by-sa/4.0/

Table of Contents

1 - Commodore 64 Memory Map

Commodore 64 Memory Map

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.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.

1.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

1.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

1.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.

1.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

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

1.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

1.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

2 - Kernal Calls

Official OS calls

The entries below are the official1 Kernal entry points for the Commodore 64.

1 - Except for CLRLN & CLSR which are from the ROM disassembly but are useful.

Files

CLALL Close all open files
CLOSE Close a logical file
LOAD Load memory from a device
OPEN Open a logical file
SAVE Save memory to a device
SETLFS Setup a logical file
SETNAM Set file name

Channels

CHKIN Open channel for input
CHKOUT Open channel for output
CHRIN Get a character from the input channel
CHROUT Output a character
CLRCHN Clear I/O channels
READST Read status word

IEEE Serial Bus

ACPTR Get data from the serial bus
CIOUT Transmit a byte over the serial bus
LISTEN Command a device on serial bus to LISTEN
SECOND Send secondary address for LISTEN
SETTMO Set IEEE bus card timeout
TALK Command a device on serial bus to TALK
TKSA Send secondary address to a device commanded to TALK
UNLSN Send an UNLISTEN command
UNTLK Send an UNTALK command

Keyboard

GETIN Get a character
SCNKEY Scan the keyboard
STOP Check if key/stop key is pressed

Memory

IOBASE Define I/O memory page
MEMBOT Set bottom of memory
MEMTOP Set top of memory
RAMTAS Perform RAM test

Screen

CLRLN Clear the line X
CLSR Clear the screen
PLOT Set cursor location
SCREEN Return screen format
SETMSG Control system message output

System

CINT Initialise screen editor
IOINIT Initialise I/O Devices
RESTOR Restore default system & interrup vectors
VECTOR Manage RAM Vectors

Time

RDTIM Read system clock
SETTIM Set system clock
UDTIM Update system clock

2.1 - ACPTR

Get data from the serial bus
Function AddressDescription
ACPTR FFA5Get data from the serial bus

This routine gets a byte of data off the serial bus using full handshaking. The data is returned in the accumulator.

To prepare for this routine the TALK routine must be called first to command the device on the serial bus to send data through the bus. If the input device needs a secondary command, it must be sent by using the TKSA routine before calling this routine.

Errors are returned in the status word. The READST routine is used to read the status word.

Example:
JSRACPTRGet a byte from the bus
STAdata

2.2 - CHKIN

Open channel for input
Function AddressVectorDescription
CHKIN FFC6031EOpen channel for input

Any logical file number that has been created by the OPEN routine can be defined as an input channel. Of course, the device you intend opening a channel to must be an input device. Otherwise, an error will occur, and the routine will be aborted.

If you are getting data from anywhere other than the keyboard, this routine must be called before using either the CHRIN or the GETIN routines for data input. If you want to use the input from the keyboard, and no other input channels are opened, then the calls to this routine, and to the OPEN routine are not needed.

Example:
LDX#2Define logical file 2 as an input channel
JSRCHKIN

2.3 - CHKOUT

Open channel for output
Function AddressVectorDescription
CHKOUT FFC90320Open channel for output

Any logical file number that has been created by the OPEN routine can be defined as an output channel. Of course, the device you intend opening a channel to must be an output device. Otherwise, an error will occur, and the routine will be aborted.

This routine must be called before any data is sent to any output device unless you want to use the screen as your output device. If screen output is desired, and there are no other output channels already defined, then calls to this routine, and to the OPEN routine are not needed.

Example:
LDX#3Define logical file 3 as an output channel
JSRCHKOUT

2.4 - CHRIN

Get a character from the input channel
Function AddressDescription
CHRIN FFCFGet a character from the input channel

This routine gets a byte of data from a channel already set up as the input channel by the CHKIN routine. If CHKIN has NOT been used to define another input channel, then all your data is expected from the keyboard.

The data byte is returned in the accumulator. The Y index register is unchanged and is usually used in a loop to store received characters.

The channel remains open after the call.

Reading from the Keyboard

Input from the keyboard is handled in a special way. First, the cursor is turned on, and blinks until a carriage return is typed on the keyboard. All characters on the line can be retrieved one at a time by calling this routine once for each character. When the carriage return is retrieved, the entire line has been processed. The next time this routine is called, the whole process begins again, i.e., by flashing the cursor.

Example:

.readLine   LDY #0              ; Prepare Y register to store data
.readLoop   JSR CHRIN           ; Get next character
            STA BUF,Y           ; Store in BUF (0x200 89 byte basic input buffer)
            INY
            CMP #0x0D           ; Carriage Return
            BNE readLoop        ; Loop back for next character
            RTS
Example:
readLineLDY#0Prepare Y register to store data
readLoopJSRCHRINGet next character
STABUF,YStore in BUF (0x200 89 byte basic input buffer)
INY
CMP#0x0DCheck for Carriage Return
BNEreadLoopLoop back to the next character
RTS

This example does no bounds checking so if more than 89 characters are read it will overwrite the Kernal workspace in page 2.

Reading from other devices

Here you need to call OPEN and CHKIN first before calling CHRIN.

2.5 - CHROUT

Output a character
Function AddressVectorDescription
CHROUT FFD20326Output a character

This routine outputs a character to an already opened channel. Use the OPEN and CHKOUT routines to set up the output channel before calling this routine. If this call is omitted, data is sent to the default output device (number 3, the screen).

The data byte to be output is loaded into the accumulator, and this routine is called. The data is then sent to the specified output device. The channel is left open after the call.

Care must be taken when using this routine to send data to a specific serial device since data will be sent to all open output channels on the bus.

Unless this is desired, all open output channels on the serial bus other than the intended destination channel must be closed by a call to the CLRCHN routine.

Example:
LDX#4Logical file 4
JSRCHKOUTOpen channel 4 for output
LDA#'A'
JSRCHROUTSend character
JMPCLRCHNClear all I/O channels so future output goes to screen

2.6 - CINT

Initialise screen editor
Function AddressDescription
CINT FF81Initialise screen editor

This routine sets up the VIC-II chip, clear the screen, set the cursor pointer and the screen editor.

Normally, this routine is called as part of the initialization process of a Commodore 64 program cartridge.

2.7 - CIOUT

Transmit a byte over the serial bus
Function AddressDescription
CIOUT FFA8Transmit a byte over the serial bus

This routine is used to send information to devices on the serial bus. A call to this routine will put a data byte onto the serial bus using full serial handshaking.

Before this routine is called, the LISTEN routine must be used to command a device on the serial bus to get ready to receive data. If a device needs a secondary address, it must also be sent by using the SECOND routine.

The accumulator is loaded with a byte to handshake as data on the serial bus. A device must be listening or the status word will return a timeout.

This routine always buffers one character. (The routine holds the previous character to be sent back.) So when a call to the UNLSN routine is made to end the data transmission, the buffered character is sent with an End Or Identify (EOI) set. Then the UNLSN command is sent to the device.

Example:
LDA#'X'Send 'X' to the serial bus
JSRCIOUT

2.8 - CLALL

Close all open files
Function AddressVectorDescription
CLALL FFE7032CClose all open files

This routine closes all open files. When this routine is called, the pointers into the open file table are reset, closing all files.

Also, the CLRCHN routine is automatically called to reset the I/O channels.

2.9 - CLOSE

Close a logical file
Function AddressVectorDescription
CLOSE FFC3031CClose a logical file

This routine is used to close a logical file after all I/O operations have been completed on that file. This routine is called after the accumulator is loaded with the logical file number to be closed - the same number used when the file was opened using the OPEN routine.

Example:
LDA#15Close logical file 15
JSRCLOSE

2.10 - CLRCHN

Clear I/O channels
Function AddressVectorDescription
CLRCHN FFCC0322Clear I/O channels

This routine is called to clear all open channels and restore the I/O channels to their original default values.

It is usually called after opening other I/O channels like a tape or disk drive and using them for input/output operations. The default input device is 0 (keyboard). The default output device is 3 (screen).

This routine is automatically called when the CLALL routine is executed.

2.11 - CLRLN

Clear the line X
Function AddressDescription
CLRLN E9FFClear the line X

This routine clears the line pointed to by X.

This is not an official documented Kernal entry point but is listed in the C64 ROM disassembly.

2.12 - CLSR

Clear the screen
Function AddressDescription
CLSR E544Clear the screen

This routine sets up the screen line link table (0x00D9…0x00F2). It then clears the screen line by line using the CLRLN routine. Once that's completed, it then homes the cursor to the top left.

This is not an official documented Kernal entry point but is listed in the C64 ROM disassembly.

2.13 - GETIN

Get a character
Function AddressVectorDescription
GETIN FFE4032AGet a character

If the input channel is the keyboard, this subroutine removes one character from the keyboard queue and returns it as an ASCII value in the accumulator. If the queue is empty, the value returned in the accumulator will be zero.

Characters are put into the queue automatically by an interrupt driven keyboard scan routine which calls the SCNKEY routine. The keyboard buffer can hold up to ten characters. After the buffer is filled, additional characters are ignored until at least one character has been removed from the queue.

If the channel is RS-232, then only the A register is used and a single character is returned. See READST to check validity.

If the channel is serial, cassette, or screen, call BASIN routine.

See also

CHKIN, OPEN, READST

2.14 - IOBASE

Define I/O memory page
Function AddressDescription
IOBASE FFF3Define I/O memory page

This routine sets the X and Y registers to the address of the memory section where the memory mapped 110 devices are located. This address can then be used with an offset to access the memory mapped I/O devices in the Commodore 64. The offset is the number of locations from the beginning of the page on which the I/O register you want is located. The X register contains the low order address byte, while the Y register contains the high order address byte.

This routine exists to provide compatibility between the Commodore 64, VIC-20, and potential future models of the Commodore 64. If the I/O locations for a machine language program are set by a call to this routine, they should still remain compatible with future versions of the Commodore 64, the KERNAL and BASIC.

Example:
JSRIOBASESet the Data Direction Register (DDR) of user port
STXFREKZPStore base address
STYFREKZP+1
LDA#0New value of User Port DDR
LDY#2Offset to DDR of User Port
STA(FREKZP),YSet the register
RTS

Note: FREKZP (0x00FB) in this example is a 4 byte block of zeropage memory unused by Basic or Kernal and is available for user code.

For the C64 the value returned is 0xDC00 - address of CLA #1

For the C128 the value returned is 0xD000 - address of the VIC chip

2.15 - IOINIT

Initialise I/O Devices
Function AddressDescription
IOINIT FF84Initialise I/O Devices

This routine initializes all input/output devices and routines.

It is normally called as part of the initialization procedure of a Commodore 64 program cartridge.

2.16 - LISTEN

Command a device on serial bus to LISTEN
Function AddressDescription
LISTEN FFB1Command a device on serial bus to LISTEN

This routine will command a device on the serial bus to receive data. The accumulator must first be loaded with a device number between 0 and 31. When called, this routine then ORs bit by bit to convert this device number to a talk address. The specified device will then go into listen mode, and be ready to accept information.

Example:
LDA#8Command device #8 to listen
JSRLISTEN

2.17 - LOAD

Load memory from a device
Function AddressVectorDescription
LOAD FFD50330Load memory from a device

This routine LOADs data bytes from any input device directly into the memory. It can also be used for a verify operation, comparing data from a device with the data already in memory, while leaving the data stored in RAM unchanged.

To use, you first need to call SETLFS to set the device to save to. Then SETNAM must be called to set the filename.

The accumulator must be set to 0 for a load or 1 for a verify operation.

If the input device is opened with a secondary address of 0, the header information from the device is ignored. In this case the X & Y registers must contain the starting address for the load.

With a secondary address of 1 the data is loaded into memory starting at the location specified by the header.

This routine returns the highest address of the data loaded on exit.

You cannot load from devices 0 (keyboard), 2 (RS-232) or 3 (Screen).
Example:
fileNameEQUS"TESTCARD"Filename to load
fileNameEnd
loadFileLDA#8Logical File Number
LDX#8Device 8 = Disk
LDY#1Secondary address 1 = Use address stored in the file
LDA#fileNameEnd-fileNamelength of fileName
LDX#<fileNameAddress if fileName
LDY#>fileName
LDA#00=Load operation
JSRLOAD
STXendAddressOptional, save address after the loaded data
STYendAddress+1
RTS
endAddressEQUW0Address after our loaded data

2.18 - MEMBOT

Set bottom of memory
Function AddressDescription
MEMBOT FF9CSet bottom of memory

This routine reads or writes the bottom of memory.

When the Carry flag is set then the bottom memory address is read into the X, Y index registers.

When the Carry flag is clear then the bottom memory address is set to the address in the X, Y index registers.

The value is stored in the MEMSTR variable at 0x281.

Default values

Machine Value
C64 0x0800
V20 unexpanded 0x1000
V20 with 3K expansion 0x0400
V20 with 8K or more 0x1200
Example:
Move bottom of memory up 1 page
SECRead memory bottom
JSRMEMBOT
INY
CLCWrite memory bottom
JSRMEMBOT

2.19 - MEMTOP

Set top of memory
Function AddressDescription
MEMTOP FF99Set top of memory

This routine reads or writes the top of memory.

When the Carry flag is set then the top memory address is read into the X, Y index registers.

When the Carry flag is clear then the top memory address is set to the address in the X, Y index registers.

The value is stored in the MEMSIZ variable at 0x283.

2.20 - OPEN

Open a logical file
Function AddressVectorDescription
OPEN FFC0031AOpen a logical file

This routine is used to OPEN a logical file. Once the logical file is set up, it can be used for input/output operations.

Most of the I/O routines call on this routine to create the logical files to operate on. No arguments need to be set up to use this routine, but both the SETLFS and SETNAM routines must be called before using this routine.

Example:
openFileEquivalent of Basic: OPEN 15,8,15,"I/O"
LDA#filenameEnd-filenameLength of filename
LDX#<filenameAddress of filename
LDY#>filename
JSRSETNAMSet filename
LDA#15Logical file number
LDX#8Device number, 8 = disk
LDY#15Secondary address
JSRSETLFSSetup logical file
JMPOPENOpen the logical file
filenameEQUS"I/O"Filename
filenameEnd

2.21 - PLOT

Set cursor location
Function AddressDescription
PLOT FFF0Set cursor location

This routine either reads or sets the text cursor's location.

Reading cursor location

A call to this routine with the accumulator carry flag set loads the current position of the cursor on the screen (in X,Y coordinates) into the Y and X registers. Y is the column number of the cursor location (0-39), and X is the row number of the location of the cursor (0-24).

Example:
getCurPosGet current cursor position
SECSet Carry to read the text position
JSRPLOT
STXFREKZPStore the Row (0..24)
STYFREKZP+1Store the Column (0..39)
RTS

Note: FREKZP (0x00FB) in this example is a 4 byte block of zeropage memory unused by Basic or Kernal and is available for user code.

Setting cursor location

A call with the carry bit clear moves the cursor to X,Y as determined by the Y and X registers.

Example:

Example:
setCurPosSet the cursor position to Row 10 Column 5
CLCClear Carry to set the text position
LDX#10We want Row 10
LDY#5Column 5
JMPPLOT

2.22 - RAMTAS

Perform RAM test
Function AddressDescription
RAMTAS FF87Perform RAM test

This routine is used to test RAM and set the top and bottom of memory pointers accordingly.

It clears locations &00 to &0101 and &0200 to &03FF. It then allocates the cassette buffer, and sets the screen base to $0400.

Normally, this routine is called as part of the initialization process of a Commodore 64 program cartridge.

2.23 - RDTIM

Read system clock
Function AddressDescription
RDTIM FFDERead system clock

This routine is used to read the system clock. The clock's resolution is a 60th of a second. Three bytes are returned by the routine. The accumulator contains the most significant byte, the X index register contains the next most significant byte, and the Y index register contains the least significant byte.

Example:
readClockRead the system clock and store in zero page
JSRRDTIM
STYFREKZPLeast significant byte
STXFREKZP+1
STAFREKZP+2Most significant byte
RTS

Note: FREKZP (0x00FB) in this example is a 4 byte block of zeropage memory unused by Basic or Kernal and is available for user code.

2.24 - READST

Read status word
Function AddressDescription
READST FFB7Read status word

This routine returns the current status of the I/O devices in the accumulator. The routine is usually called after new communication to an I/O device. The routine gives you information about device status, or errors that have occurred during the I/O operation.

The bits returned in the accumulator contain the following information:

Bit Cassette Read Serial Bus R/W Tape Verify/Load
0 write timeout
1 read timeout
2 short block short block
3 long block long block
4 unrecoverable read error any mismatch
5 checksum error checksum error
6 end of file EOI line
7 end of tape device not present end of tape
Example:
JSRREADSTCheck for end of file during read
AND#&40Check bit 6
BNEeofDetectedBranch on EOF

2.25 - RESTOR

Restore default system & interrup vectors
Function AddressDescription
RESTOR FF8ARestore default system & interrup vectors

This routine restores the default values of all system vectors used in KERNAL and BASIC routines and interrupts.

See the Memory Map for the default vector contents.

The VECTOR routine is used to read and alter individual system vectors.

2.26 - SAVE

Save memory to a device
Function AddressVectorDescription
SAVE FFD80332Save memory to a device

This routine saves a section of memory to a device.

To use, you first need to call SETLFS to set the device to save to. Then SETNAM must be called to set the filename.

Finally you store the start address in 2 bytes of zero page memory, set X & Y to point to the address immediately after the data to save, and A to the offset within zeropage where the start address was stored.

Any errors are reported via the READST routine.

You cannot save to devices 0 (keyboard), 2 (RS-232) or 3 (Screen).
Example:
saveFileLDA#1Select device 1 = Cassette
LDA#0Set no file name, valid for cassette only
LDA#<startAddressStart address low byte
STAFREEKZPStore in Zero Page.
LDA#>startAddressStart address high byte
STAFREEKZP+1
LDX#<endAddressEnd address low byte
LDY#>endAddressEnd address high byte
LDA#<FREEKZPZero page offset to FREEKZP
JMPSAVESave the file

Note: FREKZP (0x00FB) in this example is a 4 byte block of zeropage memory unused by Basic or Kernal and is available for user code.

2.27 - SCNKEY

Scan the keyboard
Function AddressDescription
SCNKEY FF9FScan the keyboard

This routine scans the Commodore 64 keyboard and checks for pressed keys. It is the same routine called by the interrupt handler. If a key is down, its ASCII value is placed in the keyboard queue. This routine is called only if the normal IRQ interrupt is bypassed.

Example:
getKeyJSRSCNKEYScan keyboard
JSRGETINGet character
CMP#0Have we got a character?
BEQgetKeyNo then loop back
JMPCHROUTPrint it to the screen

2.28 - SCREEN

Return screen format
Function AddressDescription
SCREEN FFEDReturn screen format

This routine returns the format of the screen, e.g., 40 columns in X and 25 lines in Y. The routine can be used to determine what machine a program is running on. This function has been implemented on the Commodore 64 to help upward compatibility of your programs.

Example:
JSRSCREEN
STXMAXCOL
STYMAXROW

2.29 - SECOND

Send secondary address for LISTEN
Function AddressDescription
SECOND FF93Send secondary address for LISTEN

This routine transmits a secondary address on the serial bus for a LISTEN device. The routine sends this number as a secondary address command over the serial bus. This routine can only be called after a call to the LISTEN routine. It will not work after a TALK.

Example:
LDA#8Command device #8 to listen with command #15
LDA#15
JSRSECOND

2.30 - SETLFS

Setup a logical file
Function AddressDescription
SETLFS FFBASetup a logical file

This routine sets the logical file number, device address, and secondary address (command number) for other KERNAL routines.

The logical file number is used by the system as a key to the file table created by the OPEN file routine. Device addresses can range from 0 to 31. The following codes are used by the Commodore 64 to stand for the CBM devices listed below:

Address Device
0 Keyboard
1 Cassette / Datassette
2 RS232
3 Screen
4 Printer
8 Disk drive
9 Disk drive

Device numbers 4 or greater automatically refer to devices on the serial bus.

A command to the device is sent as a secondary address on the serial bus after the device number is sent during the serial attention handshaking sequence. If no secondary address is to be sent, the Y index register should be set to 255.

Example:
LDA#15Logical file number
LDX#8Device number, 8 = disk
LDY#15Secondary address
JSRSETLFSSetup logical file

2.31 - SETMSG

Control system message output
Function AddressDescription
SETMSG FF90Control system message output

This routine controls the printing of error and control messages by the KERNAL. Either print error messages or print control messages can be selected by setting the accumulator when the routine is called. FILE NOT FOUND is an example of an error message. PRESS PLAY ON CASSETTE is an example of a control message.

Bits 6 and 7 of this value determine where the message will come from.

If bit 7 is 1, one of the error messages from the KERNAL is printed.

If bit 6 is set, control messages are printed.

If this is set to 0 then all kernal messages are disabled.

2.32 - SETNAM

Set file name
Function AddressDescription
SETNAM FFBDSet file name

This routine is used to set up the file name for the OPEN, SAVE, or LOAD routines.

The accumulator must be loaded with the length of the file name. The X and Y registers must be loaded with the address of the file name, in standard 6502 low-byte/high-byte format.

The address can be any valid memory address in the system where a string of characters for the file name is stored.

If no file name is desired, the accumulator must be set to 0, representing a zero file length. The X and Y registers can be set to any memory address in that case.

Example:
LDA#filenameEnd-filenameLength of filename
LDX#<filenameAddress of filename
LDY#>filename
JSRSETNAMSet filename
filenameEQUS"I/O"Filename
filenameEnd

2.33 - SETTIM

Set system clock
Function AddressDescription
SETTIM FFDBSet system clock

A system clock is maintained by an interrupt routine that updates the clock every 1/60th of a second (one "jiffy"). The clock is three bytes long, which gives it the capability to count up to 5,184,000 jiffies (24 hours). At that point the clock resets to zero.

Before calling this routine to set the clock, the accumulator must contain the most significant byte, the X index register the next most significant byte, and the Y index register the least significant byte of the initial time setting (in jiffies).

Example:
setClockSet clock to 10 minutes = 600 seconds = 3600 jiffies
LDA#0Most significant byte
LDX#>3600
LDY#<3600Least significant byte
JMPSETTIM

2.34 - SETTMO

Set IEEE bus card timeout
Function AddressDescription
SETTMO FFA2Set IEEE bus card timeout

This routine sets the timeout flag for the IEEE bus. When the timeout flag is set, the Commodore 64 will wait for a device on the IEEE port for 64 milliseconds. If the device does not respond to the Commodore 64's Data Address Valid (DAV) signal within that time the Commodore 64 will recognize an error condition and leave the handshake sequence. When this routine is called when the accumulator contains a 0 in bit 7, timeouts are enabled. A 1 in bit 7 will disable the timeouts.

Example:
LDA#0Disable IEEE Timeout
JSRSETTMO

2.35 - STOP

Check if key/stop key is pressed
Function AddressVectorDescription
STOP FFE10328Check if key/stop key is pressed

This routine checks for either the RUN/STOP key or certain other keys are pressed.

Check for RUN/STOP key pressed

If the key was pressed during a UDTIM call, this call returns the z flag set. In addition, the channels will be reset to default values.

Example:
Check for STOP key pressed
JSRUDTIMUpdate timer which also scans for STOP
JSRSTOP
BNEstopNotDown
JMPstopDownJump to code to handle STOP
stopNotDownContinue further processing

In the above example if the STOP key is pressed we jump to the method stopDown. This method could reset your application, cancelling some lengthy operation.

Check for other keys

If the stop key is not pressed then the z flag will be clear and the accumulator will be set to one of the following keys located on the same keyboard column as the stop key:

C64 key Accumulator Vic-20 key Accumulator
1 0xFE Cursor Down 0x7F
Left arrow 0xFD / 0xBF
CTRL 0xFB , 0xDF
2 0xF7 N 0xEF
Space 0xEF V 0xF7
Commodore 0xDF X 0xFB
Q 0xBF Left Shift 0xFD

If no key is down in the STOP column, the routine returns 0xFF on both machines.

2.36 - TALK

Command a device on serial bus to TALK
Function AddressDescription
TALK FFB4Command a device on serial bus to TALK

To use this routine the accumulator must first be loaded with a device number between 0 and 31.

When called, this routine then ORs bit by bit to convert this device number to a talk address. Then this data is transmitted as a command on the serial bus.

If a secondary address is required then the TKSA routine must be called immediately after this one.

Example:
LDA#4Command device #4 to talk
JSRTALK

2.37 - TKSA

Send secondary address to a device commanded to TALK
Function AddressDescription
TKSA FF96Send secondary address to a device commanded to TALK

This routine transmits a secondary address on the serial bus for a TALK device. This routine must be called with a number between 0 and 31 in the accumulator. The routine sends this number as a secondary address command over the serial bus. This routine can only be called after a call to the TALK routine. It will not work after a LISTEN.

Example:
LDA#4Command device #4 to talk with command #7
JSRTALK
LDA#7
JSRTKSA

2.38 - UDTIM

Update system clock
Function AddressDescription
UDTIM FFEAUpdate system clock

This routine updates the system clock. Normally this routine is called by the normal KERNAL interrupt routine every 1/60th of a second. If the user program processes its own interrupts this routine must be called to update the time. In addition, the <STOP> key routine must be called, if the <STOP> key is to remain functional.

2.39 - UNLSN

Send an UNLISTEN command
Function AddressDescription
UNLISTEN FFAESend an UNLISTEN command

This routine commands all devices on the serial bus to stop receiving data. Calling this routine results in an UNLISTEN command being transmitted on the serial bus. Only devices previously commanded to listen are affected. This routine is normally used after the Commodore 64 has finished sending data to external devices. Sending the UNLISTEN commands the listening devices to get off the serial bus, so it can be used for other purposes.

Example:
JSRUNLSN

2.40 - UNTLK

Send an UNTALK command
Function AddressDescription
UNTLK FFABSend an UNTALK command

This routine commands all devices on the serial bus to stop sending data. Calling this routine results in an UNTALK command being transmitted on the serial bus. Only devices previously commanded to talk are affected.

Example:
JSRUNTLK

2.41 - VECTOR

Manage RAM Vectors
Function AddressDescription
VECTOR FF8DManage RAM Vectors

This routine manages all system vector jump addresses stored in RAM.

Calling this routine with the the accumulator carry bit set stores the current contents of the RAM vectors in a list pointed to by the X and Y registers.

When this routine is called with the carry clear, the user list pointed to by the X and Y registers is transferred to the system RAM vectors.

The RAM vectors are listed in the memory map.

This routine requires caution in its use. The best way to use it is to first read the entire vector contents into the user area, alter the desired vectors, and then copy the contents back to the system vectors.

3 - reference

3.1 - API by Address

API by Address
Function AddressVectorDescription
CLSR E544Clear the screen
CLRLN E9FFClear the line X
CINT FF81Initialise screen editor
IOINIT FF84Initialise I/O Devices
RAMTAS FF87Perform RAM test
RESTOR FF8ARestore default system & interrup vectors
VECTOR FF8DManage RAM Vectors
SETMSG FF90Control system message output
SECOND FF93Send secondary address for LISTEN
TKSA FF96Send secondary address to a device commanded to TALK
MEMTOP FF99Set top of memory
MEMBOT FF9CSet bottom of memory
SCNKEY FF9FScan the keyboard
SETTMO FFA2Set IEEE bus card timeout
ACPTR FFA5Get data from the serial bus
CIOUT FFA8Transmit a byte over the serial bus
UNTLK FFABSend an UNTALK command
UNLISTEN FFAESend an UNLISTEN command
LISTEN FFB1Command a device on serial bus to LISTEN
TALK FFB4Command a device on serial bus to TALK
READST FFB7Read status word
SETLFS FFBASetup a logical file
SETNAM FFBDSet file name
OPEN FFC0031AOpen a logical file
CLOSE FFC3031CClose a logical file
CHKIN FFC6031EOpen channel for input
CHKOUT FFC90320Open channel for output
CLRCHN FFCC0322Clear I/O channels
CHRIN FFCFGet a character from the input channel
CHROUT FFD20326Output a character
LOAD FFD50330Load memory from a device
SAVE FFD80332Save memory to a device
SETTIM FFDBSet system clock
RDTIM FFDERead system clock
STOP FFE10328Check if key/stop key is pressed
GETIN FFE4032AGet a character
CLALL FFE7032CClose all open files
UDTIM FFEAUpdate system clock
SCREEN FFEDReturn screen format
PLOT FFF0Set cursor location
IOBASE FFF3Define I/O memory page

3.2 - API by Name

API by Name
Function AddressVectorDescription
ACPTR FFA5Get data from the serial bus
CHKIN FFC6031EOpen channel for input
CHKOUT FFC90320Open channel for output
CHRIN FFCFGet a character from the input channel
CHROUT FFD20326Output a character
CINT FF81Initialise screen editor
CIOUT FFA8Transmit a byte over the serial bus
CLALL FFE7032CClose all open files
CLOSE FFC3031CClose a logical file
CLRCHN FFCC0322Clear I/O channels
CLRLN E9FFClear the line X
CLSR E544Clear the screen
GETIN FFE4032AGet a character
IOBASE FFF3Define I/O memory page
IOINIT FF84Initialise I/O Devices
LISTEN FFB1Command a device on serial bus to LISTEN
LOAD FFD50330Load memory from a device
MEMBOT FF9CSet bottom of memory
MEMTOP FF99Set top of memory
OPEN FFC0031AOpen a logical file
PLOT FFF0Set cursor location
RAMTAS FF87Perform RAM test
RDTIM FFDERead system clock
READST FFB7Read status word
RESTOR FF8ARestore default system & interrup vectors
SAVE FFD80332Save memory to a device
SCNKEY FF9FScan the keyboard
SCREEN FFEDReturn screen format
SECOND FF93Send secondary address for LISTEN
SETLFS FFBASetup a logical file
SETMSG FF90Control system message output
SETNAM FFBDSet file name
SETTIM FFDBSet system clock
SETTMO FFA2Set IEEE bus card timeout
STOP FFE10328Check if key/stop key is pressed
TALK FFB4Command a device on serial bus to TALK
TKSA FF96Send secondary address to a device commanded to TALK
UDTIM FFEAUpdate system clock
UNLISTEN FFAESend an UNLISTEN command
UNTLK FFABSend an UNTALK command
VECTOR FF8DManage RAM Vectors

3.3 - include

3.3.1 - BeebASM

Files for the BeebASM assembler

3.3.1.1 - api

Generated file for beebasm
; *************************************************************************** ; API for Commodore C64 Kernal ; Notes about the C64 operating system & memory ; Author: Peter Mount, Area51.dev & Contributors ; ; URL: https://area51.dev/c64/kernal/ ; ; Modified: Sun, 23 Jan 2022 17:05:58 UTC ; ; Current version: https://area51.dev/c64/kernal/reference/include/beebasm/api.asm ; *************************************************************************** ACPTR = &FFA5 ; Get data from the serial bus CHKIN = &FFC6 ; Open channel for input CHKOUT = &FFC9 ; Open channel for output CHRIN = &FFCF ; Get a character from the input channel CHROUT = &FFD2 ; Output a character CINT = &FF81 ; Initialise screen editor CIOUT = &FFA8 ; Transmit a byte over the serial bus CLALL = &FFE7 ; Close all open files CLOSE = &FFC3 ; Close a logical file CLRCHN = &FFCC ; Clear I/O channels CLRLN = &E9FF ; Clear the line X CLSR = &E544 ; Clear the screen GETIN = &FFE4 ; Get a character IOBASE = &FFF3 ; Define I/O memory page IOINIT = &FF84 ; Initialise I/O Devices LISTEN = &FFB1 ; Command a device on serial bus to LISTEN LOAD = &FFD5 ; Load memory from a device MEMBOT = &FF9C ; Set bottom of memory MEMTOP = &FF99 ; Set top of memory OPEN = &FFC0 ; Open a logical file PLOT = &FFF0 ; Set cursor location RAMTAS = &FF87 ; Perform RAM test RDTIM = &FFDE ; Read system clock READST = &FFB7 ; Read status word RESTOR = &FF8A ; Restore default system & interrup vectors SAVE = &FFD8 ; Save memory to a device SCNKEY = &FF9F ; Scan the keyboard SCREEN = &FFED ; Return screen format SECOND = &FF93 ; Send secondary address for LISTEN SETLFS = &FFBA ; Setup a logical file SETMSG = &FF90 ; Control system message output SETNAM = &FFBD ; Set file name SETTIM = &FFDB ; Set system clock SETTMO = &FFA2 ; Set IEEE bus card timeout STOP = &FFE1 ; Check if key/stop key is pressed TALK = &FFB4 ; Command a device on serial bus to TALK TKSA = &FF96 ; Send secondary address to a device commanded to TALK UDTIM = &FFEA ; Update system clock UNLISTEN = &FFAE ; Send an UNLISTEN command UNTLK = &FFAB ; Send an UNTALK command VECTOR = &FF8D ; Manage RAM Vectors

3.3.1.2 - headers

Generated file for beebasm
; *************************************************************************** ; Headers for Commodore C64 Kernal ; Notes about the C64 operating system & memory ; Author: Peter Mount, Area51.dev & Contributors ; ; URL: https://area51.dev/c64/kernal/ ; ; Modified: Sun, 23 Jan 2022 17:05:58 UTC ; ; Current version: https://area51.dev/c64/kernal/reference/include/beebasm/headers.asm ; *************************************************************************** ; C64 Zero Page D6510 = &0 ; 6510 On-Chip I/O DATA Direction Register R6510 = &1 ; 6510 On-Chip I/O Port ADRAY1 = &3 ; Vector to routine to convert Number from Floating Point to Signed Integer ADRAY2 = &5 ; Vector to routine to convert Number from Integer to Floating Point VERCK = &A ; Flag: LOAD or VERIFY TXTTAB = &2B ; Pointer to start of BASIC program text VARTAB = &2D ; Pointer to start of BASIC Variable storage area ARYTAB = &2F ; Pointer to start of array variable area STREND = &31 ; End of Basic array storage (+1), Start of free ram FRETOP = &33 ; Pointer to bottom of string text area FRESPC = &35 ; Temp pointer for strings BASMEMSIZ = &37 ; Highest address used by basic BLNSW = &CC ; Cursor Blink Enable RIBUF = &F7 ; RS232 Input Buffer Pointer ROBUF = &F9 ; RS232 Output Buffer Pointer FREKZP = &FB ; 4 free bytes of Zero Page for User Programs BASZPT = &FF ; BASIC temp data area for floating point to ASCII conversion ; C64 Page 2 BUF = &200 ; BASIC Line Editor Input Buffer LAT = &259 ; Active logical file number table FAT = &263 ; Device number for each logical file SAT = &26D ; Secondary address for each logical file KEYD = &277 ; Keyboard buffer MEMSTR = &281 ; Start of Memory pointer MEMSIZ = &283 ; End of Memory pointer COLOR = &286 ; Current Foreground text colour GDCOL = &287 ; Colour of character under Cursor HIBASE = &288 ; Page of Screen Memory XMAX = &289 ; Max length of keyboard buffer RPTFLG = &28A ; Which keys will repeat SHFLAG = &28D ; Shift/Ctrl/Commodore key pressed LSTSHF = &28E ; Last value of Shift/Ctrl/Commodore key pressed MODE = &291 ; Shift/Commodore switch AUTODN = &292 ; Screen scrolling enabled M51CTR = &293 ; Mock 6551 RS-232 Control Register M51CDR = &294 ; Mock 6551 RS-232 Command Register M51AJB = &295 ; Mock 6551 RS-232 Nonstandard Bit Timing M51STAT = &297 ; Mock 6551 RS-232 Status Register RIDBE = &29B ; RS-232 Index to end of receive buffer RIDBS = &29C ; RS-232 Index to start of receive buffer RODBE = &29D ; RS-232 Index to end of transmit buffer RODBS = &29E ; RS-232 Index to start of transmit buffer ENABL = &2A1 ; RS-232 Interrupts Enabled ; C64 Page 3 Vectors & Cassette Buffer USRPOK = &310 ; Jump instruction for BASIC USR() function USRADD = &311 ; Address of USR() function CINV = &314 ; IRQ Interrupt Routine Vector CBNV = &316 ; BRK Interrupt Routine Vector NMINV = &318 ; NMI Interrupt Routine Vector IOPEN = &31A ; Kernal OPEN Vector ICLOSE = &31C ; Kernal close Vector ICHKIN = &31E ; Kernal CHKIN Vector ICKOUT = &320 ; Kernal CKOUT Vector ICLRCH = &322 ; Kernal CLRCHN Vector IBASIN = &324 ; Kernal CHRIN Vector IBSOUT = &326 ; Kernal CHROUT Vector ISTOP = &328 ; Kernal STOP Vector IGETIN = &32A ; Kernal GETIN Vector ICLALL = &32C ; Kernal CLALL Vector USRCMD = &32E ; User-Defined Command Vector ILOAD = &330 ; Kernal LOAD Vector ISAVE = &332 ; Kernal SAVE Vector TBUFFR = &33C ; Cassette I/O Buffer ; VIC-II Registers VIC2M0X = &D000 ; X Coordinate Sprite 0 VIC2M0Y = &D001 ; Y Coordinate Sprite 0 VIC2M1X = &D002 ; X Coordinate Sprite 1 VIC2M1Y = &D003 ; Y Coordinate Sprite 1 VIC2M2X = &D004 ; X Coordinate Sprite 2 VIC2M2Y = &D005 ; Y Coordinate Sprite 2 VIC2M3X = &D006 ; X Coordinate Sprite 3 VIC2M3Y = &D007 ; Y Coordinate Sprite 3 VIC2M4X = &D008 ; X Coordinate Sprite 4 VIC2M4Y = &D009 ; Y Coordinate Sprite 4 VIC2M5X = &D00A ; X Coordinate Sprite 5 VIC2M5Y = &D05B ; Y Coordinate Sprite 5 VIC2M6X = &D00C ; X Coordinate Sprite 6 VIC2M6Y = &D00D ; Y Coordinate Sprite 6 VIC2M7X = &D00E ; X Coordinate Sprite 7 VIC2M7Y = &D00F ; Y Coordinate Sprite 7 VIC2MNX = &D010 ; Bit 8 of X coordinates VIC2CR1 = &D011 ; Control register 1 VIC2RASTER = &D012 ; Raster counter VIC2LPX = &D013 ; Light pen X VIC2LPY = &D014 ; Light pen Y VIC2SPE = &D015 ; Sprite Enabled VIC2CR2 = &D016 ; Control register 2 VIC2SPYE = &D017 ; Sprite Y expansion VIC2MPTR = &D018 ; Memory pointers VIC2INTR = &D019 ; Interrupt Register VIC2INTE = &D01A ; Interrupt Enabled VIC2SPDP = &D01B ; Sprite data priority VIC2SPMC = &D01C ; Sprite multicolour VIC2SPXE = &D01D ; Sprite X expansion VIC2SPSPCOL = &D01E ; Sprite-Sprite collision VIC2SPDCOL = &D01F ; Sprite data collision VIC2BORDER = &D020 ; Border colour VIC2B0C = &D021 ; Background colour 0 VIC2B1C = &D022 ; Background colour 1 VIC2B2C = &D023 ; Background colour 2 VIC2B3C = &D024 ; Background colour 3 VIC2SPMM0 = &D025 ; Sprite multicolour 0 VIC2SPMM1 = &D026 ; Sprite multicolour 1 VIC2SPCOL0 = &D027 ; Sprite 0 colour VIC2SPCOL1 = &D028 ; Sprite 1 colour VIC2SPCOL2 = &D029 ; Sprite 2 colour VIC2SPCOL3 = &D02A ; Sprite 3 colour VIC2SPCOL4 = &D02B ; Sprite 4 colour VIC2SPCOL5 = &D02C ; Sprite 5 colour VIC2SPCOL6 = &D02D ; Sprite 6 colour VIC2SPCOL7 = &D02E ; Sprite 7 colour ; SID Registers SID1FRELOW = &D400 ; Frequency voice 1 low byte SID1FREHIGH = &D401 ; Frequency voice 1 high byte SID1PWDCLOW = &D402 ; Pulse wave duty cycle voice 1 low byte SID1PWDCHIGH = &D403 ; Pulse wave duty cycle voice 1 high byte SID1CR = &D404 ; Control Register voice 1 ; Colour memory COLMEM = &D800 ; Colour Memory ; CIA 1 CIA1PRA = &DC00 ; Data Port A CIA1PRB = &DC01 ; Data Port B CIA1DDRA = &DC02 ; Data Direction Port A CIA1DDRB = &DC03 ; Data Direction Port B CIA1TIMAL = &DC04 ; Timer A Low byte CIA1TIMAH = &DC05 ; Timer A High byte CIA1TIMBL = &DC06 ; Timer B Low byte CIA1TIMBH = &DC07 ; Timer B High byte CIA1RTCT = &DC08 ; Real time clock 1/10s CIA1RTCS = &DC09 ; Real time clock seconds CIA1RTCM = &DC0A ; Real time clock minutes CIA1RTCH = &DC0B ; Real time clock hours CIA1SR = &DC0C ; Shift register CIA1ICS = &DC0D ; Interrupt Control & Status CIA1CTA = &DC0E ; Control Timer A CIA1CTB = &DC0F ; Control Timer B ; CIA 2 CIA2PRA = &DD00 ; Data Port A CIA2PRB = &DD01 ; User Port PB0-7 CIA2DDRA = &DD02 ; Data Direction Port A CIA2DDRB = &DD03 ; Data Direction Port B CIA2TIMAL = &DD04 ; Timer A Low byte CIA2TIMAH = &DD05 ; Timer A High byte CIA2TIMBL = &DD06 ; Timer B Low byte CIA2TIMBH = &DD07 ; Timer B High byte CIA2RTCT = &DD08 ; Real time clock 1/10s CIA2RTCS = &DD09 ; Real time clock seconds CIA2RTCM = &DD0A ; Real time clock minutes CIA2RTCH = &DD0B ; Real time clock hours CIA2SR = &DD0C ; Shift register CIA2ICS = &DD0D ; Interrupt Control & Status CIA2CTA = &DD0E ; Control Timer A CIA2CTB = &DD0F ; Control Timer B

3.3.2 - ZAsm

Files for the ZAsm assembler

3.3.2.1 - api

Generated file for zasm
; *************************************************************************** ; API for Commodore C64 Kernal ; Notes about the C64 operating system & memory ; Author: Peter Mount, Area51.dev & Contributors ; ; URL: https://area51.dev/c64/kernal/ ; ; Modified: Sun, 23 Jan 2022 17:05:58 UTC ; ; Current version: https://area51.dev/c64/kernal/reference/include/zasm/api.z80 ; *************************************************************************** ACPTR equ &FFA5 ; Get data from the serial bus CHKIN equ &FFC6 ; Open channel for input CHKOUT equ &FFC9 ; Open channel for output CHRIN equ &FFCF ; Get a character from the input channel CHROUT equ &FFD2 ; Output a character CINT equ &FF81 ; Initialise screen editor CIOUT equ &FFA8 ; Transmit a byte over the serial bus CLALL equ &FFE7 ; Close all open files CLOSE equ &FFC3 ; Close a logical file CLRCHN equ &FFCC ; Clear I/O channels CLRLN equ &E9FF ; Clear the line X CLSR equ &E544 ; Clear the screen GETIN equ &FFE4 ; Get a character IOBASE equ &FFF3 ; Define I/O memory page IOINIT equ &FF84 ; Initialise I/O Devices LISTEN equ &FFB1 ; Command a device on serial bus to LISTEN LOAD equ &FFD5 ; Load memory from a device MEMBOT equ &FF9C ; Set bottom of memory MEMTOP equ &FF99 ; Set top of memory OPEN equ &FFC0 ; Open a logical file PLOT equ &FFF0 ; Set cursor location RAMTAS equ &FF87 ; Perform RAM test RDTIM equ &FFDE ; Read system clock READST equ &FFB7 ; Read status word RESTOR equ &FF8A ; Restore default system & interrup vectors SAVE equ &FFD8 ; Save memory to a device SCNKEY equ &FF9F ; Scan the keyboard SCREEN equ &FFED ; Return screen format SECOND equ &FF93 ; Send secondary address for LISTEN SETLFS equ &FFBA ; Setup a logical file SETMSG equ &FF90 ; Control system message output SETNAM equ &FFBD ; Set file name SETTIM equ &FFDB ; Set system clock SETTMO equ &FFA2 ; Set IEEE bus card timeout STOP equ &FFE1 ; Check if key/stop key is pressed TALK equ &FFB4 ; Command a device on serial bus to TALK TKSA equ &FF96 ; Send secondary address to a device commanded to TALK UDTIM equ &FFEA ; Update system clock UNLISTEN equ &FFAE ; Send an UNLISTEN command UNTLK equ &FFAB ; Send an UNTALK command VECTOR equ &FF8D ; Manage RAM Vectors

3.3.2.2 - headers

Generated file for zasm
; *************************************************************************** ; Headers for Commodore C64 Kernal ; Notes about the C64 operating system & memory ; Author: Peter Mount, Area51.dev & Contributors ; ; URL: https://area51.dev/c64/kernal/ ; ; Modified: Sun, 23 Jan 2022 17:05:58 UTC ; ; Current version: https://area51.dev/c64/kernal/reference/include/zasm/headers.z80 ; *************************************************************************** ; C64 Zero Page D6510 equ &0 ; 6510 On-Chip I/O DATA Direction Register R6510 equ &1 ; 6510 On-Chip I/O Port ADRAY1 equ &3 ; Vector to routine to convert Number from Floating Point to Signed Integer ADRAY2 equ &5 ; Vector to routine to convert Number from Integer to Floating Point VERCK equ &A ; Flag: LOAD or VERIFY TXTTAB equ &2B ; Pointer to start of BASIC program text VARTAB equ &2D ; Pointer to start of BASIC Variable storage area ARYTAB equ &2F ; Pointer to start of array variable area STREND equ &31 ; End of Basic array storage (+1), Start of free ram FRETOP equ &33 ; Pointer to bottom of string text area FRESPC equ &35 ; Temp pointer for strings BASMEMSIZ equ &37 ; Highest address used by basic BLNSW equ &CC ; Cursor Blink Enable RIBUF equ &F7 ; RS232 Input Buffer Pointer ROBUF equ &F9 ; RS232 Output Buffer Pointer FREKZP equ &FB ; 4 free bytes of Zero Page for User Programs BASZPT equ &FF ; BASIC temp data area for floating point to ASCII conversion ; C64 Page 2 BUF equ &200 ; BASIC Line Editor Input Buffer LAT equ &259 ; Active logical file number table FAT equ &263 ; Device number for each logical file SAT equ &26D ; Secondary address for each logical file KEYD equ &277 ; Keyboard buffer MEMSTR equ &281 ; Start of Memory pointer MEMSIZ equ &283 ; End of Memory pointer COLOR equ &286 ; Current Foreground text colour GDCOL equ &287 ; Colour of character under Cursor HIBASE equ &288 ; Page of Screen Memory XMAX equ &289 ; Max length of keyboard buffer RPTFLG equ &28A ; Which keys will repeat SHFLAG equ &28D ; Shift/Ctrl/Commodore key pressed LSTSHF equ &28E ; Last value of Shift/Ctrl/Commodore key pressed MODE equ &291 ; Shift/Commodore switch AUTODN equ &292 ; Screen scrolling enabled M51CTR equ &293 ; Mock 6551 RS-232 Control Register M51CDR equ &294 ; Mock 6551 RS-232 Command Register M51AJB equ &295 ; Mock 6551 RS-232 Nonstandard Bit Timing M51STAT equ &297 ; Mock 6551 RS-232 Status Register RIDBE equ &29B ; RS-232 Index to end of receive buffer RIDBS equ &29C ; RS-232 Index to start of receive buffer RODBE equ &29D ; RS-232 Index to end of transmit buffer RODBS equ &29E ; RS-232 Index to start of transmit buffer ENABL equ &2A1 ; RS-232 Interrupts Enabled ; C64 Page 3 Vectors & Cassette Buffer USRPOK equ &310 ; Jump instruction for BASIC USR() function USRADD equ &311 ; Address of USR() function CINV equ &314 ; IRQ Interrupt Routine Vector CBNV equ &316 ; BRK Interrupt Routine Vector NMINV equ &318 ; NMI Interrupt Routine Vector IOPEN equ &31A ; Kernal OPEN Vector ICLOSE equ &31C ; Kernal close Vector ICHKIN equ &31E ; Kernal CHKIN Vector ICKOUT equ &320 ; Kernal CKOUT Vector ICLRCH equ &322 ; Kernal CLRCHN Vector IBASIN equ &324 ; Kernal CHRIN Vector IBSOUT equ &326 ; Kernal CHROUT Vector ISTOP equ &328 ; Kernal STOP Vector IGETIN equ &32A ; Kernal GETIN Vector ICLALL equ &32C ; Kernal CLALL Vector USRCMD equ &32E ; User-Defined Command Vector ILOAD equ &330 ; Kernal LOAD Vector ISAVE equ &332 ; Kernal SAVE Vector TBUFFR equ &33C ; Cassette I/O Buffer ; VIC-II Registers VIC2M0X equ &D000 ; X Coordinate Sprite 0 VIC2M0Y equ &D001 ; Y Coordinate Sprite 0 VIC2M1X equ &D002 ; X Coordinate Sprite 1 VIC2M1Y equ &D003 ; Y Coordinate Sprite 1 VIC2M2X equ &D004 ; X Coordinate Sprite 2 VIC2M2Y equ &D005 ; Y Coordinate Sprite 2 VIC2M3X equ &D006 ; X Coordinate Sprite 3 VIC2M3Y equ &D007 ; Y Coordinate Sprite 3 VIC2M4X equ &D008 ; X Coordinate Sprite 4 VIC2M4Y equ &D009 ; Y Coordinate Sprite 4 VIC2M5X equ &D00A ; X Coordinate Sprite 5 VIC2M5Y equ &D05B ; Y Coordinate Sprite 5 VIC2M6X equ &D00C ; X Coordinate Sprite 6 VIC2M6Y equ &D00D ; Y Coordinate Sprite 6 VIC2M7X equ &D00E ; X Coordinate Sprite 7 VIC2M7Y equ &D00F ; Y Coordinate Sprite 7 VIC2MNX equ &D010 ; Bit 8 of X coordinates VIC2CR1 equ &D011 ; Control register 1 VIC2RASTER equ &D012 ; Raster counter VIC2LPX equ &D013 ; Light pen X VIC2LPY equ &D014 ; Light pen Y VIC2SPE equ &D015 ; Sprite Enabled VIC2CR2 equ &D016 ; Control register 2 VIC2SPYE equ &D017 ; Sprite Y expansion VIC2MPTR equ &D018 ; Memory pointers VIC2INTR equ &D019 ; Interrupt Register VIC2INTE equ &D01A ; Interrupt Enabled VIC2SPDP equ &D01B ; Sprite data priority VIC2SPMC equ &D01C ; Sprite multicolour VIC2SPXE equ &D01D ; Sprite X expansion VIC2SPSPCOL equ &D01E ; Sprite-Sprite collision VIC2SPDCOL equ &D01F ; Sprite data collision VIC2BORDER equ &D020 ; Border colour VIC2B0C equ &D021 ; Background colour 0 VIC2B1C equ &D022 ; Background colour 1 VIC2B2C equ &D023 ; Background colour 2 VIC2B3C equ &D024 ; Background colour 3 VIC2SPMM0 equ &D025 ; Sprite multicolour 0 VIC2SPMM1 equ &D026 ; Sprite multicolour 1 VIC2SPCOL0 equ &D027 ; Sprite 0 colour VIC2SPCOL1 equ &D028 ; Sprite 1 colour VIC2SPCOL2 equ &D029 ; Sprite 2 colour VIC2SPCOL3 equ &D02A ; Sprite 3 colour VIC2SPCOL4 equ &D02B ; Sprite 4 colour VIC2SPCOL5 equ &D02C ; Sprite 5 colour VIC2SPCOL6 equ &D02D ; Sprite 6 colour VIC2SPCOL7 equ &D02E ; Sprite 7 colour ; SID Registers SID1FRELOW equ &D400 ; Frequency voice 1 low byte SID1FREHIGH equ &D401 ; Frequency voice 1 high byte SID1PWDCLOW equ &D402 ; Pulse wave duty cycle voice 1 low byte SID1PWDCHIGH equ &D403 ; Pulse wave duty cycle voice 1 high byte SID1CR equ &D404 ; Control Register voice 1 ; Colour memory COLMEM equ &D800 ; Colour Memory ; CIA 1 CIA1PRA equ &DC00 ; Data Port A CIA1PRB equ &DC01 ; Data Port B CIA1DDRA equ &DC02 ; Data Direction Port A CIA1DDRB equ &DC03 ; Data Direction Port B CIA1TIMAL equ &DC04 ; Timer A Low byte CIA1TIMAH equ &DC05 ; Timer A High byte CIA1TIMBL equ &DC06 ; Timer B Low byte CIA1TIMBH equ &DC07 ; Timer B High byte CIA1RTCT equ &DC08 ; Real time clock 1/10s CIA1RTCS equ &DC09 ; Real time clock seconds CIA1RTCM equ &DC0A ; Real time clock minutes CIA1RTCH equ &DC0B ; Real time clock hours CIA1SR equ &DC0C ; Shift register CIA1ICS equ &DC0D ; Interrupt Control & Status CIA1CTA equ &DC0E ; Control Timer A CIA1CTB equ &DC0F ; Control Timer B ; CIA 2 CIA2PRA equ &DD00 ; Data Port A CIA2PRB equ &DD01 ; User Port PB0-7 CIA2DDRA equ &DD02 ; Data Direction Port A CIA2DDRB equ &DD03 ; Data Direction Port B CIA2TIMAL equ &DD04 ; Timer A Low byte CIA2TIMAH equ &DD05 ; Timer A High byte CIA2TIMBL equ &DD06 ; Timer B Low byte CIA2TIMBH equ &DD07 ; Timer B High byte CIA2RTCT equ &DD08 ; Real time clock 1/10s CIA2RTCS equ &DD09 ; Real time clock seconds CIA2RTCM equ &DD0A ; Real time clock minutes CIA2RTCH equ &DD0B ; Real time clock hours CIA2SR equ &DD0C ; Shift register CIA2ICS equ &DD0D ; Interrupt Control & Status CIA2CTA equ &DD0E ; Control Timer A CIA2CTB equ &DD0F ; Control Timer B