Platform Amstrad CPC - z88dk/z88dk GitHub Wiki

Classic library support (+cpc)

  • Native console output
  • Native console input
  • ANSI vt100 engine
  • Generic console
    • Redefinable font
    • UDG support
    • Paper colour
    • Ink colour
    • Inverse attribute
    • Bold attribute
    • Underline attribute
  • Lores graphics
  • Hires graphics
  • PSG sound
    • ETracker (SAA tracker)
    • PSG Lib (SN76489)
    • Arkos2 Player (AY)
    • WYZ Player (AY)
    • Vortex tracker (AY)
  • One bit sound
  • Inkey driver
  • Hardware joystick
  • File I/O
  • Interrupts
  • RS232

Warning: When running with the firmware enabled, the CPC reserves 40% of the register set for its own usage. z88dk installs handlers to allow compiled code to utilise all registers. This is essential when writing code that intends to be performant when using long, long long and floating point datatypes. Additionally, some sccz80 generated code will use the alternate register set.

Quick start

To create a disk image:

zcc +cpc -lcpcfs -lm -subtype=dsk -create-app -o program program.c

To create a tape file:

zcc +cpc -lndos -lm -subtype=wav -create-app -o program program.c

Adding -subtype=fastwav can shorten the loading time by producing a non standard audio format.

A CP/M target is also available for the CPC. To create a CP/M disk image:

zcc +cpm -subtype=cpc -create-app -lm -o program program.c

Loading programs

The code is compiled by default to address $1200, to load a tape file and run your application:


| tape
memory &11ff
load "",&1200
call &1200

To load from disc:

memory &11ff
load "program.cpc",&1200
call &1200

If you produce code under $1200 and needs to get loaded then run from BASIC, the "memory" command is required; in example, to compile and run a program located at $400:

zcc +cpc -lcpcfs -lmz -pragma-define:CRT_ORG_CODE=1024 -create-app -o program adv_a.c
openout"d"
memory &3ff
closeout
load"mybin",&400
call &400

Library support

Library support for CPC is fairly complete, the firmware interposer functionality allows usage of all z80 registers and z88dk's assembler written optimised standard library.

Generic console

The generic console supports all 3 official graphics modes. Switching using console_ioctl() will also change the pixel plotting mode. The modes are as follows:

  • Mode 0: 160×200 pixels with 16 colors (4 bpp)
  • Mode 1: 320×200 pixels with 4 colors (2 bpp)
  • Mode 2: 640×200 pixels with 2 colors (1 bpp)

CPC custom library

z88dk incorporates cpcrslib which provides a large amount of functionality out of the box.

Floating point

In addition to supporting the classic maths libraries, the CPC target supports a native maths library which is selected my using the command line option -lmz when compiling.

The library that is linked in by default supports 3 models of CPC - CPC464, CPC664 and CPC6128.

Should memory be in short supply and you wish to compile for a specific CPC then you can do the following:

zcc +cpc [...] -lmz -l6128_math

or -l464_math or -l664_math which will save about 600 bytes of memory.

The additional functions introduced with the development of the native CPC library, are now available in all the implementations; these are:

void deg();

Switch the FP engine into degrees mode

void rad();

Switch the FP engine into radians mode

double pi();

Return the value of pi.

File IO

Support for file IO on the CPC has been added. This uses the CAS_ interface and as such as the limitation that only 2 files may be open at a time - one for reading and one for writing. In addition due to the firmware implementation of these routines, a 2k buffer is required for both input and output. This buffer is statically built into the program.

The following routines are not supported by the CPC fcntl library:

ftell()
fgetpos()
fsetpos()
rewind()
fseek()
creat()
lseek()
mkdir()
getcwd()
rmdir()
getwd()

Moreover, open() only supports the O_RDONLY and O_WRONLY flags.

To link in the library supply the -lcpcfs flag to the compiler. If you do not require file IO in your program then supply the -lndos flag which links in a dummy stub library that simply returns errors.

Calling the firmware

As a result of the CPC firmware hogging registers, all calls to the firmware should be made through the interposer:

EXTERN firmware
; Load registers
call firmware
defw call_address

Failure to do so will result in crashes and other multicolour screen effects.

Interrupt handling

There are two options for installing an interrupt manager:

  1. (default) The firmware interrupt manager is invoked
  2. The firmware interrupt manager isn't invoked (-pragma-define:CRT_DISABLE_FIRMWARE_ISR=1)

The firmware interrupt manager amongst other things scans the keyboard, so if it is not enabled the zcc option --hardware-keyboard should be provided which reads the keyboard hardware directly.

Note, when calling the firmware, interrupts will be missed regardless of which manager is used.

z88dk offers two available ISR frequencies: cpc_add_vsync_isr() (aliased to add_raster_int()) which is called at 50Hz and cpc_add_fast_isr() which is called at 300Hz.

128k program generation

The +cpc supports using the 128k banks for either code or data. When placing code, there is an assumed split of the memory space. If we take the default configuration where z88dk compiles to address $1200:

0000 - 3fff = common page - contains library support routines
4000 - 7fff = banks are paged in here

To place functions into banks, you should use the #pragma bank NN directive, where NN is a decimal number between 0 and 7.

Take care when placing data/code into banks - some of the banks are already used in the regular address space.

z88dk supports generating banked applications in both cas and dsk formats.

Due to technical reasons, the loader is always present within the crt0 (even when it is inert), to remove this code if you are tight for space add the option: -pragma-define:CRT_DISABLELOADER=1

Tricks using the WinAPE emulator

When using the WinAPE Amstrad CPC emulator, if the opcode 0xED, 0xFF is executed, then it activates a Breakpoint and show the debugger.

'norecess' suggests the following:

#define crASSERT( expression ) \
    if ( !( expression ) ) \
    { \
        asm( "defb $ed, $ff" ); \
    }

#define crBREAK( ) \
    asm( "defb $ed, $ff" );

Links

No cart

Z88DK as described in CPCWIKI

Short tutorial about using the z88dk on Linux (RPI) to create Amstrad applications

"entwickeln-mit-z88dk", tutorial in German

Blue Angel 69 - CPC game written with z88dk

Magical Drop CPC - game written with z88dk

Grimware - CPC insights

CPC Sprite Library (Amstrad CPC) cpcrslib is a C library containing routines and functions that allows the handling of sprites and tile-mapping on the Amstrad CPC. The library is written to be used with the z88dk compiler. cpcrslib also incorporates keyboard routines to redefine and to detect keys, as well as general routines to change to the screen mode or the colours.

Crocolib (Amstrad CPC/CPC+) Crocolib is a complete framework targeting Amstrad CPC computers, written in C using the z88dk C cross compiler. It allows the creation of rich programs featuring very low-level hardware support. Tools are also included to convert data to the target machine.