Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Amstrad CPC 464/6128 Programming Resources

Amstrad CPC 464/6128 Programming Resources

A collection of information gathered from various resources into a single document to be able to program for Amstrad CPC 464/6128 machines.

Hardware

CPC has the following components on the mainboard:

schematic

Firmware

I/O Port mapping

The CPC IN/OUT design differs from the norm in that port numbers are defined using 16 bits, as opposed to the traditional 8 bits.

IN r,(C)/OUT (C),r instructions: Bits b15-b8 come from the B register, bits b7-b0 come from r IN A,(n)/OUT (n),A instructions: Bits b15-b8 come from the A register, bits b7-b0 come from n Listed below are the internal hardware devices and the bit fields to which they respond. In the table:

- means this bit is ignored, 0 means the bit must be set to 0 for the hardware device to respond, 1 means the bit must be set to 1 for the hardware device to respond. r1 and r0 mean a bit used to define a register

Hardware device Address Read/Write b15 b14 b13 b12 b11 b10 b9 b8
Gate-Array &7f Write Only 0 1 - - - - - -
RAM Configuration &7f Write Only 0 - - - - - - -
CRTC &BC-&BF Read/Write - 0 - - - - r1 r0
ROM select &DF Write only - - 0 - - - - -
Printer port &EF Write only - - - 0 - - - -
8255 PPI &F4-&F7 Read/Write - - - - 0 - r1 r0
Expansion Peripherals &F8-&FB Read/Write - - - - - 0 - -

Z80

CRTC

It is HD6845S.

I/O port address Function Read/Write
&BCxx 6845 CRTC Index Write only
&BDxx 6845 CRTC Data Out Write only
&BExx 6845 CRTC Status Read only
&BFxx 6845 CRTC Data In Read only

Registers

Register Index Register Name
0 Horizontal Total
1 Horizontal Displayed
2 Horizontal Sync Position
3 Horizontal and Vertical Sync Widths
4 Vertical Total
5 Vertical Total Adjust
6 Vertical Displayed
7 Vertical Sync position
8 Interlace and Skew
9 Maximum Raster Address
10 Cursor Start Raster
11 Cursor End Raster
12 Display Start Address (High)
13 Display Start Address (Low)
14 Cursor Address (High)
15 Cursor Address (High)
16 Light Pen Address (High)
17 Light Pen Address (High)
.------- REG 12 --------.   .------- REG 13 --------.
 |                       |   |                       |
  15 14 13 12 11 10 09 08     07 06 05 04 03 02 01 00
 .--.--.--.--.--.--.--.--.   .--.--.--.--.--.--.--.--.
 |X |X |  |  |  |  |  |  |   |  |  |  |  |  |  |  |  |
 '--'--'--'--'--'--'--'--'   '--'--'--'--'--'--'--'--'
       '--.--'--.--'---------------.-----------------'
          |     |                  |
          |     |                  '------> Offset for setting
          |     |                           videoram 
          |     |                           (1024 positions)
          |     |                           Bits 0..9
          |     |
          |     '-------------------------> Video Buffer : note (1)
          |
          '-------------------------------> Video Page : note (2)
 note (1)                 note (2)
 .--.--.--------------.  .--.--.---------------.
 |11|10| Video Buffer |  |13|12|   Video Page  |
 |--|--|--------------|  |--|--|---------------|
 | 0| 0|     16Ko     |  | 0| 0|  0000 - 3FFF  |
 |--|--|--------------|  |--|--|---------------|
 | 0| 1|     16Ko     |  | 0| 1|  4000 - 7FFF  |
 |--|--|--------------|  |--|--|---------------|
 | 1| 0|     16Ko     |  | 1| 0|  8000 - BFFF  |
 |--|--|--------------|  |--|--|---------------|
 | 1| 1|     32Ko     |  | 1| 1|  C000 - FFFF  |
 '--'--'--------------'  '--'--'---------------'

Example

ld bc, &bc06 ;; Select Register 6 Vertical Displayed
out (c), c

ld bc, &bd80 ;; Set value &80
out (c), c
ld bc, &bc00+13   ;; Select Display Low Address
out (c), c

ld bc, &bd00+&01  ;; Set &c001 as the display address
out (c), c

Gate Array

An ASIC responsible for various display related tasks.

Every scanline is 64 microseconds.

What is the total number of scanlines per frame?

What is the duration of Vertical Blanking?

What is the duration of Horizontal Blanking?

I/O port address Function Read/Write
&7Fxx Write
Bit 7 Bit 6 Register Function
0 0 PENR Select pen
0 1 INKR Select colour for selected pen
1 0 RMR Select screen mode, rom configuration and interrupt control
1 1 MMR Ram Memory Management

PENR

This register can be used to select one of the 17 color-registers (pen 0 to 15 or the border). It will remain selected until another PENR command is executed.

Bit Value Function
7 0 Gate Array function "Pen Selection"
6 0
5 x not used
4 1 Select border
3 x ignored
2 x ignored
1 x ignored
0 x ignored

INKR

This register takes a 5bits parameter which is a color-code. This color-code range from 0 to 31 but there's only 27 differents colors (because the Gate Array use a 3-states logic on the R,G and B signals, thus 3x3x3=27).

Bit Value Function
7 0 Gate Array function "Colour Selection"
6 1
5 x not used
4 x Colour number
3 x
2 x
1 x
0 x

Palette

Hardware Number Colour Name R % G % B % Hexadecimal RGB values
54h Black 0 0 0 #000000 0/0/0
44h (or 50h) Blue 0 0 50 #000080 0/0/128
55h Bright Blue 0 0 100 #0000FF 0/0/255
5Ch Red 50 0 0 #800000 128/0/0
58h Magenta 50 0 50 #800080 128/0/128
5Dh Mauve 50 0 100 #8000FF 128/0/255
4Ch Bright Red 100 0 0 #FF0000 255/0/0
45h (or 48h) Purple 100 0 50 #ff0080 255/0/128
4Dh Bright Magenta 100 0 100 #FF00FF 255/0/255
56h Green 0 50 0 #008000 0/128/0
46h Cyan 0 50 50 #008080 0/128/128
57h Sky Blue 0 50 100 #0080FF 0/128/255
5Eh Yellow 50 50 0 #808000 128/128/0
40h (or 41h) White 50 50 50 #808080 128/128/128
5Fh Pastel Blue 50 50 100 #8080FF 128/128/255
4Eh Orange 100 50 0 #FF8000 255/128/0
47h Pink 100 50 50 #FF8080 255/128/128
4Fh Pastel Magenta 100 50 100 #FF80FF 255/128/255
52h Bright Green 0 100 0 #00FF00 0/255/0
42h (or 51h) Sea Green 0 100 50 #00FF80 0/255/128
53h Bright Cyan 0 100 100 #00FFFF 0/255/255
5Ah Lime 50 100 0 #80FF00 128/255/0
59h Pastel Green 50 100 50 #80FF80 128/255/128
5Bh Pastel Cyan 50 100 100 #80FFFF 128/255/255
4Ah Bright Yellow 100 100 0 #FFFF00 255/255/0
43h (or 49h) Pastel Yellow 100 100 50 #FFFF80 255/255/128
4Bh Bright White 100 100 100 #FFFFFF 255/255/255

RMR

Bit Value Function
7 1
6 0
5 0
4 x Reset interrupt counter
3 x Upper ROM (0 enable, 1 disable)
2 x Lower ROM (0 enabled, 1 disable)
1 x Select Video Mode 0, 1, 2, 3
0 x

Video Mode

Bit 1 Bit 0 Screen mode
0 0 Mode 0, 160x200 resolution, 16 colours
0 1 Mode 1, 320x200 resolution, 4 colours
1 0 Mode 2, 640x200 resolution, 2 colours
1 1 Mode 3, 160x200 resolution, 4 colours

Relevant excerpt from Firmware manual about video memory mapping

in MODE 2 (where there are two colours only, each pixel needs only one
           bit - either on or off)

    bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
     p0   p1   p2   p3   p4   p5   p6   p7

(the pixels are arranged with p0 being the leftmost one, etc)

in MODE 1 (where four colours are available and so two bits are needed
           for each pixel - 1 byte represents 4 pixels)
    bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
    p0(1) p1(1) p2(1) p3(1) p0(0) p1(0) p2(0) p3(0)

(each pixel is twice as wide as in MODE 2)

in MODE 0 (where sixteen colours are possible and four bits are needed
           for each pixel - 1 byte represents 2 pixels)

    bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
    p0(0) p1(0) p0(2) p1(2) p0(1) p1(1) p0(3) p1(3)

(each pixel is four times as wide as in MODE 2)

NB: the numbers in brackets show  which  bit of the pixel's pen number
the screen byte bit refers  to.   For  example  in  MODE 1, the 4 most
significant bits of the byte hold bit  1  of the pixel's pen value and
the 41east signifcant bits hold bit 0 of the pen value.


     6128  � 464   � Size � Comments on the memory locations

     &C000   &C000   &4000  normal (upper) screen area.  The
                              alternative (lower) screen area is from
                              &4000 to &7FFF.  The addresses of the
                              starts of lines and rows in the normal
                              screen area after a MODE instruction
                              are:

    LINE    R0W0   R0W1   R0W2   R0W3   R0W4   R0W5   R0W6   R0W7
    1       C000   C800   D000   D800   E000   E800   F000   F800
    2       C050   C850   D050   D850   E050   E850   F050   F850
    3       C0A0   C8A0   D0A0   D8A0   E0A0   E8A0   F0A0   F8A0
    4       C0F0   C8F0   D0F0   D8F0   E0F0   E8F0   F0F0   F8F0
    5       C140   C940   D140   D940   E140   E940   F140   F940
    6       C190   C990   D190   D990   E190   E990   F190   F990
    7       C1E0   C9E0   D1E0   D9E0   E1E0   E9E0   F1E0   F9E0
    8       C230   CA30   D230   DA30   E230   EA30   F230   FA30
    9       C280   CA80   D280   DA80   E280   EA80   F280   FA80
    10      C2D0   CAD0   D2D0   DAD0   E2D0   EAD0   F2D0   FAD0
    11      C320   CB20   D320   DB20   E320   EB20   F320   FB20
    12      C370   CB70   D370   DB70   E370   EB70   F370   FB70
    13      C3C0   CBC0   D3C0   DBC0   E3C0   EBC0   F3C0   FBC0
    14      C410   CC10   D410   DC10   E410   EC10   F410   FC10
    15      C460   CC60   D460   DC60   E460   EC60   F460   FC60
    16      C4B0   CCB0   D4B0   DCB0   E4B0   ECB0   F4B0   FCB0
    17      C500   CD00   D500   DD00   E500   ED00   F500   FD00
    18      C550   CD50   D550   DD50   E550   ED50   F550   FD50
    19      C5A0   CDA0   D5A0   DDA0   E5A0   EDA0   F5A0   FDA0
    20      C5F0   CDF0   D5F0   DDF0   E5F0   ED50   F550   FD50
    21      C640   CE40   D640   DE40   E640   EE40   F640   FE40
    22      C690   CE90   D690   DE90   E690   EE90   F690   FE90
    23      C6E0   CEE0   D6E0   DEE0   E6E0   EEE0   F6E0   FEE0
    24      C730   CF30   D730   DF30   E730   EF30   F730   FF30
    25      C780   CF80   D780   DF80   E780   EF80   F780   FF80

spare start C7D0   CFD0   D7D0   DFD0   E7D0   EFD0   F7D0   FFD0
 spare end  C7FF   CFFF   D7FF   DFFF   E7FF   EFFF   F7FF   FFFF

    Once the whole screen  has  been  scrolled  in any direction, the
above table will  become  incorrect.   On  scrolling,  all  the above
addresses will have an offset (MOD &800) added, derived as follows:

+&02 per scroll to the left (=2, 1 or « character in MODE 2, MODE 1
     or MODE 0 respectively)
-&02 per scroll to the right (=2, 1 or « character in MODE 2, MODE 1
     or MODE 0 respectively)
+&50 per scroll up one line
-&50 per scroll down one line

Upper ROM

When set to 0, &c000-&ffff reads Upper ROM

Lower ROM

When set to 0, &0000-&3ffff reads Firmware ROM

Example

ld bc, &7f01 ;; Select PEN 1
out (c), c

ld bc, &7f54 ;; Write INKR color-code &54 (%01011000)
out (c), c

PPI 8255

Programmable universal I/O interface device

Datasheet: http://cpctech.cpc-live.com/docs/datasheet/msm82c55a.pdf

Bit 9 Bit 8 PPI Function Read/Write status
0 0 Port A data Read/Write
0 1 Port B data Read/Write
1 0 Port C data Read/Write
1 1 Control Write Only
I/O address PPI Function
&F4xx Port A data
&F5xx Port B data
&F6xx Port C data
&F7xx Control

Port A

PSG Data (Programmable Sound Generator)

Entire bitmap is data bus

Port B

Bit Description Usage
7 Cassette read data
6 Parallel/Printer port ready signal "1" = not ready, "0" = Ready
5 /EXP
4 (note 5)
3 (note 1)
2 (note 2)
1 (note 3)
0 6845 VSYNC State of VSYNC from 6845. "1" = VSYNC active, "0" = VSYNC inactive

Example

ld b, &f5
.vsync_sync
in a, (c)
rra
jr nc, vsync_sync

Port C

PSG Control (Programmable Sound Generator)

Bit Description Usage
7 PSG BDIR PSG function selection
6 PSG BC1
----- ------------------------ ---------------------------------------------------
5 Cassette Write data
4 Cassette Motor Control set bit to "1" for motor on, or "0" for motor off
----- ------------------------ ---------------------------------------------------
3 Keyboard line Select keyboard line to be scanned (0-15)
2
1
0

PSG function selection:

Bit 7 Bit 6 Function
0 0 Inactive
0 1 Read from selected PSG register
1 0 Write to selected PSG register
1 1 Select PSG register
@JimmyDansbo

This comment has been minimized.

Copy link

@JimmyDansbo JimmyDansbo commented Jan 5, 2021

Could you provide information on which compiler/assembler to use (you use)?
Thanks for a great article.

@neuro-sys

This comment has been minimized.

Copy link
Owner Author

@neuro-sys neuro-sys commented Jan 5, 2021

Could you provide information on which compiler/assembler to use (you use)?
Thanks for a great article.

@JimmyDansbo

Hello, I used different assemblers: rasm, Protest/Maxam or WinAPE.

I also wrote more comprehensive notes here: https://neuro-sys.github.io/2019/10/01/amstrad-cpc-crtc.html

@JimmyDansbo

This comment has been minimized.

Copy link

@JimmyDansbo JimmyDansbo commented Jan 5, 2021

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment