Introduction
VIC-II Colour codes
Image-Application formats
Hardware Keyboard Matrix and
Digital Joystick Scanning
GCR - Group Coded Recording
Comments to nonC64 assembler programmers
This section is intended for programmers of the C64 (Mainly Assembler coders), or other programmers who need information about the programming of the C64. It contains some practical information and it is not the intention to give you an course in assembler programming here.
VIC-II Colour codes and Luminance intensity
Dec
Hex
Colour
Brightness
Vice Palette
R,G,BCCSC64 palette
R,G,B0
0
Black
0/0
00, 00, 00
10, 10, 10
1
1
White
4/8
FF, FF, FF
FF, FF, FF
2
2
Red
1/2
68, 37, 2B
E0, 40, 40
3
3
Cyan
3/6
70, A4, B2
60, FF, FF
4
4
Purple
2/3
6F, 3D, 86
E0, 60, E0
5
5
Green
2/5
58, 8D, 43
40, E0, 40
6
6
Blue
1/1
35, 28, 79
40, 40, E0
7
7
Yellow
3/7
B8, C7, 6F
FF, FF, 40
8
8
Orange
2/3
6F, 4F, 25
E0, A0, 40
9
9
Brown
1/1
43, 39, 00
9C, 74, 48
10
A
Light Red
2/5
9A, 67, 59
FF, A0, A0
11
B
Dark Gray (1)
1/2
44, 44, 44
54, 54, 54
12
C
Medium Gray (2)
2/4
6C, 6C, 6C
88, 88, 88
13
D
Light Green
3/7
9A, D2, 84
A0, FF, A0
14
E
Light Blue
2/4
6C, 5E, B5
A0, A0, FF
15
F
Light Gray (3)
3/6
95, 95, 95
C0, C0, C0
Note: Brightness is on a 0-4 scale on the original C64, and a 0-8 scale on C64C & C128(D)
Formats for application image types:
Start addr.
Start address/Load address (first two bytes of the file)
Length
File length in bytes (including load address bytes)
Bitmap
Bitmap offset (8000 bytes)
Colour
Colour data offset (1000 bytes). In Multicolour mode, Copy (25*40) 1000 bytes to the area $D800 and upward.
Background
Background colour (1 byte), stored in lower nybble of $D021
Common file formats for Hires raw-images on the C64 |
||||||
Name (Hires) |
Start Addr. |
Length |
Bitmap |
Screen |
Colour Nybbles |
Background |
Art Studio |
$2000 |
9009 |
0 |
8000 |
|
|
Doodle |
$5C00 |
9218 |
1024 |
0 |
||
Image System (Hi) |
$4000 |
9194 |
0 |
8192 |
The upper 4 bits of screen memory becomes the colour of any bits that is set (to 1) in the 8*8 pixels attribute controlled by the screen memory. The lower 4 bits is the colour of any pixels cleared (0).
Common file formats for multicolour bitmap raw-images on the C64 |
||||||
Name (Multicolour) |
Start Addr. |
Length |
Bitmap |
Screen |
Colour Nybbles |
Background |
Artist 64 |
$4000 |
10242 |
0 |
8192 |
9216 |
10239 |
Adv. Art Studio |
$2000 |
10018 |
0 |
8000 |
9016 |
9001 |
Amica Paint (*) |
$4000 |
10257 |
0 |
8000 |
9000 |
10000 |
Blazing Paddles |
$A000 |
10242 |
0 |
8192 |
9216 |
8064 |
Koala Painter |
$6000 |
10003 |
0 |
8000 |
9000 |
10000 |
Image System (MC) |
$3C00 |
10218 |
1024 |
9216 |
0 |
9215 |
Vidcom 64 |
$5800 |
10050 |
2048 |
1024 |
0 |
2024 |
CDU Paint |
$7EEF |
10277 |
273 |
8273 |
9273 |
10273 |
(*) Amica Paint can save in packed format, using control-codes ($C2) for loops etc. For depacking : $C2 00 marks end of picture, $C2 xx yy means copy byte yy xx-times. Other bytes combinations must just be stored as they are. Furthermore, Amica Paint has an extra feature included in the file; The colour-Rotation-Table at offset Addr. 10000 with a total of 256 bytes.
Common formats for FLI raw-images on the C64 |
||||||
Application |
Background |
Colour |
Colour Screens |
Bitmap |
Notes |
|
Saga FLI * |
$3B01-$3BC8 |
$3C00-$3FFF |
$4000-$5FFF |
$6000-$7F3F |
$3B00? |
|
Interpaint (*) |
$3B00-$3BFF |
$3C00-$3FE7 |
$4000-$5FFF |
$6000-$7FFF |
*Options |
* Rasterbars is an EXTENSION to the FLI concept.
The keyboard is read as a matix of 8 rows by 8 columns. The row is selected by clearing (set to 0) the corresponding bit in the CIA1 port A ($DC00). The column data bits are then read from the CIA1 port B ($DC01), and a cleared bit indicates that the key is pressed at the time of scanning.
Row |
Key |
|||||||
0 |
CRSR U/D |
F5 |
F3 |
F1 |
F7 |
CRSR L/R |
RETURN |
INST/DEL |
1 |
L-SHIFT |
E |
S |
Z |
4 |
A |
W |
3 |
2 |
X |
T |
F |
C |
6 |
D |
R |
5 |
3 |
V |
U |
H |
B |
8 |
G |
Y |
7 |
4 |
N |
O |
K |
M |
0 |
J |
I |
8 |
5 |
,< |
@ |
: |
.> |
- |
L |
P |
+ |
6 |
/? |
UP-ARROW |
= |
R-SHIFT |
CLR/HOME |
; |
* |
£ |
7 |
RUN/STOP |
Q |
C= |
SPACE |
2 |
CTRL |
LEFT-ARROW |
1 |
Column |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Notice: A keypress is of course not buffered in hardware. If a key is pressed, the bits are cleared at that moment, not before or after. You can scan for more than one key at a time if you want, withing the limits of course. For a buffering input stream, you should write your own routines or use kernal calls.
For scanning Joystisk 0 and 1 (Port A and B) you use the same registers, only this time you read from Port A also if you want to scan Joystick 0 in Port A.
X |
X |
X |
FIRE |
RIGHT |
LEFT |
DOWN |
UP |
|
Joystick 0 ($DC00) bits |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Joystick 1 ($DC01) bits |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
X = Not important in connection with Joystisk
To give a simple example how keyboard scanning works, here is an example of how to wait for a press on the SPACE key.
|
You can make versions which clean up the registers before and after use, or you can make quick and dirty versions for shorter code. It depends on what you need in your final code. This is just to give you an example.
This is the disk encoding scheme of the Commodore 1541 (and similar) diskdrives , and does not take advantage of the index hole present on the disks (Some systems are Index-hole oriented) but is a SYNC-oriented format. It does however take advantage of the possibility of larger tracks towards the edge of the disk (Some systems don´t).
Each 1 bit on the magnetic media (disk) is represented by a fluxation in the magnetic field, either from North to South, or the other way. Each 0-bit is represented by a -nonchanged- magnetic field. A flux in the field generates a small current in the wires of the coil, this current is amplified and, in turn, interpreted as a High level (1) by the digital logic.
The disk is divided into tracks. Each track is divided into a number sectors. Each sector consists of a block-header and a datablock. In order to mark the beginning of a blockheader or datablock, a SYNC of ATLEAST 9 magnetic fluxations, e.g. (N)SNSNSNSNS (= 111111111) are written to disk. All this is in order to keep knowledge of where a sectors starts (without it, you would not be able to tell (in a simple way) which bits are what).
Loop data ($55 = %01010101) are part of Block-headers (10 * $55) and Data-blocks (X * $55, if needed).
The basics rules for recordings which are not Sync signals:
1. Not more eight 1-bits in sequence, recorded on the magnetic media.
2. Not more than two 0-bits in sequence, recorded on the magnetic media.
In order to achieve this, the each nybble is recorded as 5 bits-GCR code.
GCR conversion table
Dec
Hex
Binary
GCR value
Dec
Hex
Binary
GCR value
0
0
0000
01010
8
8
1000
01001
1
1
0001
01011
9
9
1001
11001
2
2
0010
10010
10
A
1010
11010
3
3
0011
10011
11
B
1011
11011
4
4
0100
01110
12
C
1100
01101
5
5
0101
01111
13
D
1101
11101
6
6
0110
10110
14
E
1110
11110
7
7
0111
10111
15
F
1111
10101
Example of GCR encoding
Four bytes plain data (in this case $12, $34, $AB and $CD) are converted into 5 bytes GCR format:
Bytes: $12 $34 $AB $CD
Binary: 00010010 00110100 10101011 11001101
Nibbles: 0001 0010 0011 0100 1010 1011 1100 1101
GCR codes: 01010 01011 10011 01110 11010 11011 01101 11101
Nibbles: 0101 0010 1110 0110 1110 1101 0110 1101 1011 1101
GCR bytes: 01010010 11100110 11101101 01101101 10111101
Converted: $52 $E6 $ED $6D $BD
As already mentioned, the scheme takes advantage of different track length. It simply adds more sectors to each track.
Sectors/Track on 1541 drives
Track
Sectors
1-17
21
18-24
19
25-30
18
31-35
17
Tracks 35-40 must be supported by an extra system (e.g trackloader or systems like Dolphin Dos.)
Examples of alternative disk encoding schemes, used on other systems:
MFM - Scheme used on many diskdrives for PC etc, also used on some drives of the C64/C128.
As I have coded in assembler on a wide range of microprocessors; the 6502, 8051, Motorola 68K, 56K (DSP), Intel 80X86, Pentium and ARM (Advanced Risc Machines) based processors, I know there is variation in the syntax of how to represent something in the assembler code, I feel the need for having a small section explaining the special signs and symbols used when it comes to coding the C64 in assembler.
A guide for common signs, symbols and terms used by C64 coders in the assembler syntax.
$ |
Hexadecimal number; Eg. $C000 (49152 decimal) same way as 0xC000 in C and some other systems. Used alone in an assembler instruction, it normally is a memory address (e.g. STA $D020 - Store the value from the accumulator to the memory location $D020 (In this case the VIC-II chip - Border colour). |
% |
Binary number. Is used similar to $ (Hexadecimal) |
# |
Numerical value. E.g. LDA #0 - Load accumulator with the value 0 (Not the value stored at address 0). Can be combined with the $ sign to represent a hexadecimal value, e.g. LDA #$0F will Load the accumulator with the numerical value 15 (Decimal). Similar syntax is common on many other platforms. |
< |
LSB, Least Significant Byte. E.g. LDA #<$ABCD will load #$CD into the accumulator. The final instruction will be LDA #$CD. Usefull with constants or to make the source easy to read. |
> |
MSB, Most Significant Byte. E.g. LDA #>$ABCD will load #$AB into the accumulator. See < |
Nybble |
4 bits (1 bytes = 2 nybbles. A nybble is either the uppermost or lower 4 bits) |
General readings
Commodore 64 Programmers Reference Guide
- Published by Commodore Business Machines, Inc. and Howard W. Sams & Co., Inc.Programming the 6502
- Rodnay Zaks, Sybex. (ISBN : 0-89588-046-6)
Advanced readings
The MOS 6567/6569 video controller (VIC-II) and its application in the Commodore 64
- Christian Baur