Evo SDCC/SDK kit is made to facilitate the development of non-complex graphic games for the baseconf of ZX Evolution (14 ÌÃö CPU, 4 Megabytes RAM, 320x200 in 16 colours out of 64, AY). ATM Turbo 2 (7 MHz CPU, 1 Megabyte RAM) compatibility is kept too. The kit works on a regular PC with MS Windows.

The kit contains SDCC (C cross compiler), a set of utilities to automate the resource conversion and linking, plus a low level library that provides graphics and other operations.

A developer must prepare his resources in standard formats and a C program, then the project can be compiled and linked with one button. The resulting TR-DOS disk image can be run in the ZX Evo emulator included or on a real machine.



Possibilities

About 55 kilobytes of C code. Resources and some library code reside in higher memory and switch automatically.

All the data is loaded from a disk and depacked in RAM with a loader before the run. There was not data loading initially as the disk size is less than RAM size. (But now a TR-DOS wrapper _DOS_3D13 is added to make your own disk operations, see the example.)

The library is capable of background drawing in 8x8 tiles, as well as individual 8x8 tiles. Coordinates or the tiles are multiples of 8. Individual tiles can be drawn with a given 'transparent' colour to print text over a picture.

Palette setting capability - one of 256 palettes imported from BMP, or you can set your palette in program. Virtual brightness of a palette can be changed in 7 steps from completely black to completely bright.

The library draws a list of 64 16x16 sprites with automatic background restoring. Maximum total number of sprite images is 5376 but in fact limited with RAM size. Output Y coordinate is pixel precise, X is 2 pixels precise. Output speed depends of the number of sprites in the list, opaque pixels in them, and your main program time. In a simple test you can draw about 20 ball sprites in one frame, and all the sprites can be drawn in 3 to 4 frames.

Playing three channel music in PT3 format and sound effects in AFX format. If Turbo Sound is present then the music and sound effects are played on different chips, otherwise they overlap (effects over the music).

Playing sampled sound effects with Covox (8 bit DAC). The program is stopped while the playing.

Reading joysticks and cursors on keyboard - arrows and fire. Reading 40-key keyboard.

Note: C standard libraries are not included. Evo SDK has simplified versions of memset() and memcpy(), and a 16 bit rand(). The memory must be allocated statically.



Resource formats

Graphics must be prepared in BMP format without compression, 16 or 256 colours (the first 16 are used). Any regular graphics editors can be used for this. (There are incompatibilities in newer versions of Photoshop and GIMP.)

Background images must have their sizes to be multiples of 8 pixels. Theoretical maximum is 2 Megabytes per image, 2048x2048 pixels for example. In practice, images (if used as images, not as their individual tiles) are screen size or less. There can be up to 256 background images in a project, the total size of the graphics is limited with RAM size.

Sprites are 16x16 pixels and must be prepared as one or many 256-color images with sizes that are multiple of 16 pixels. The first 16 colours can be used in graphics, the rest are transparent. This makes possible to use all the 16 colours in one sprite, plus transparent colour.

Palettes are imported from any 16 or 256 colour BMPs, separately from graphics, to make possible to use one palette with different images. Palettes can be set and changed in a program.

Music is in PT3 format. Pro Tracker 3 or Vortex Tracker II can be used for this. One AY chip is used, Turbo Sound is not supported in music. (You can use 6-channel FM music for Turbo Sound FM format, in compiled TFM Music Maker format, if you recompile the libraries - see below.)

Sound effects must be prepared in AFX format with AYFX Editor.

Sampled sound effects must be prepared as mono 8 or 16 bit uncompressed WAV files, with sampling frequency of 8000, 11025, 16000, 22050, 32000, or 44100 Hz.



Adding resources to a project

All the resources, such as images, sprites, music, sound effects, are added to a project via a batch file (compile.bat in the project directory). File names are converted into identifiers in resources.h header file.



Library functions

All the functions and their parameters are described in evo.h header file that must be included in a project. It resides in /evosdk/.



About SDCC

Evo SDK uses an older version of SDCC normally, for some reasons. Newer version compiles even the small projects for far too long, from tens seconds to sereval minutes. With --oldralloc switch it compiles as fast as the older version, with more compact code that runs slightly slower.

There is a limitation to local variables memory. If you use too much local memory, the program just fails to run, without any warnings from the compiler. Better declare them as static, at least for arrays.

You can't change SDCC version just with changing files, because of changes in assembler name, keywords for inlined assembly and library format. You must edit your sources and linker scripts. (Version of Evo SDK with SDCC 3.4.0 is now provided.)



Emulator notes

The emulator doesn't support change of CPU speed, 14 MHz is selected. As the real machine speed varies in this mode, Evo SDK uses 3.5 MHz to play samples, so they sound a lot higher than on actual machine. (You can press F1 in emulator, select ULA and load ATM1_2_3.5MHz preset to test.)



ATM Turbo 2 compatibility

To switch between ZX Evo (ATM3) and ATM Turbo 2 (or ATM Turbo 2 + TurboSound FM) recompile the libraries with one of the batch files in /evosdk/. (The default is ATM Turbo 2. ZX Evo compilation is reserved for projects that require over 1 Megabyte of RAM, because ZX Evo runs ATM Turbo 2 compilations well, without any loss in speed or anything.)



(Joystick usage notes

Please use vsync() before calling joystick() or else the music will play wrong. This is because accessing Kempston joystick requires switching off DOS signal, but interrupt handler needs it, so it's blocked.)



(Games made with Evo SDK include XNX, Innsmouth, Project R.O.B.O., 2048, Space Mercenary series, and Billiard.)


evo.h:

#pragma disable_warning 85

//declaring the types

typedef unsigned char u8;
typedef   signed char i8;
typedef unsigned  int u16;
typedef   signed  int i16;
typedef unsigned long u32;
typedef   signed long i32;

#define TRUE	1
#define FALSE	0

//masks for Kempston joystick (or cursor keys+Space) directions and buttons

#define JOY_RIGHT	0x01
#define JOY_LEFT	0x02
#define JOY_DOWN	0x04
#define JOY_UP		0x08
#define JOY_FIRE	0x10

//displacements in keyboard array, to read the keyboard

#define KEY_SPACE	0x23
#define KEY_ENTER	0x1e
#define KEY_SYMBOL	0x24
#define KEY_CAPS	0x00

#define KEY_0		0x14
#define KEY_1		0x0f
#define KEY_2		0x10
#define KEY_3		0x11
#define KEY_4		0x12
#define KEY_5		0x13
#define KEY_6		0x18
#define KEY_7		0x17
#define KEY_8		0x16
#define KEY_9		0x15

#define KEY_A		0x05
#define KEY_B		0x27
#define KEY_C		0x03
#define KEY_D		0x07
#define KEY_E		0x0c
#define KEY_F		0x08
#define KEY_G		0x09
#define KEY_H		0x22
#define KEY_I		0x1b
#define KEY_J		0x21
#define KEY_K		0x20
#define KEY_L		0x1f
#define KEY_M		0x25
#define KEY_N		0x26
#define KEY_O		0x1a
#define KEY_P		0x19
#define KEY_Q		0x0a
#define KEY_R		0x0d
#define KEY_S		0x06
#define KEY_T		0x0e
#define KEY_U		0x1c
#define KEY_V		0x04
#define KEY_W		0x0b
#define KEY_X		0x02
#define KEY_Y		0x1d
#define KEY_Z		0x01

//key flag masks

#define KEY_DOWN	0x01	//the key is held
#define KEY_PRESS	0x02	//the key was pressed, this flag is reset after you call keyboard()

//mouse button masks

#define MOUSE_LBTN	0x01
#define MOUSE_RBTN	0x02
#define MOUSE_MBTN	0x04

//a macro to get a colour code from RGB 2-bit values

#define RGB222(r,g,b)	(((b)&3)|(((g)&3)<<2)|(((r)&3)<<4))

//bright levels: lowest, highest, and medium (as specified in palette)

#define BRIGHT_MIN	0
#define BRIGHT_MID	3
#define BRIGHT_MAX	6

//this sprite image number marks the end of sprite list

#define SPRITE_END	0xff00



//fill memory with a value

void memset(void* m,u8 b,u16 len) _naked;

//copy memory, the areas can't collide

void memcpy(void* d,void* s,u16 len) _naked;

//generate a 16-bit pseudo-random number

u16 rand16(void) _naked;

//set border colour, 0..15

void border(u8 n) _naked;

//wait for the next TV frame

void vsync(void) _naked;

//read Kempston joystick and cursor keys+Space
//use vsync() before calling joystick() or else the music will play wrong
//see JOY_ constants above to mask the directions and buttons

u8 joystick(void) _naked;

//read the keyboard, returns 40-byte array of key states
//see KEY_ constants above to mask the states of the keys

void keyboard(u8* keys) _naked;

//read the current mouse position. X resolution is low (2 pixels as in sprites)
//mouse moves in a given clipping zone, see below

u8 mouse_pos(u8* x,u8* y) _naked;

//set the current position for mouse

void mouse_set(u8 x,u8 y) _naked;

//set the clipping zone for mouse, 0..160, 0..200 by default

void mouse_clip(u8 xmin,u8 ymin,u8 xmax,u8 ymax) _naked;

//get mouse move deltas, without lowering X resolution

u8 mouse_delta(i8* x,i8* y) _naked;

//play a given sound effect with given relative volume -8..8

void sfx_play(u8 sfx,i8 vol) _naked;

//stop all the sound effects that are playing

void sfx_stop(void) _naked;

//play a given music track (or resume after stopping)

void music_play(u8 mus) _naked;

//stop the music

void music_stop(void) _naked;

//play sample via Covox
//while playing, the program is stopped and interrupts are off

void sample_play(u8 sample) _naked;

//set all the values in the palette to 0 (black)

void pal_clear(void) _naked;

//set screen brightness BRIGHT_MIN..BRIGHT_MID..BRIGHT_MAX (0..3..6)
//from completely black, to specified in the palette, to completely white

void pal_bright(u8 bright) _naked;

//select a predefined palette

void pal_select(u8 id) _naked;

//copy a predefined palette into an array (16 bytes)

void pal_copy(u8 id,u8* pal) _naked;

//set a colour in the palette, id 0..15, col in R2G2B2 format

void pal_col(u8 id,u8 col) _naked;

//set all the 16 colours in the palette with R2G2B2 values from an array

void pal_custom(u8* pal) _naked;

//select an image for draw_tile()

void select_image(u8 id) _naked;

//select a transparent colour 0..15 for draw_tile_key()

void color_key(u8 col) _naked;

//draw tile from the current image
//one image can hold up to 65536 tiles (in reality, less, see above)

void draw_tile(u8 x,u8 y,u16 tile) _naked;

//draw tile with a mask (transparent colour)

void draw_tile_key(u8 x,u8 y,u16 tile) _naked;

//draw full image

void draw_image(u8 x,u8 y,u8 id) _naked;

//clear shadow (currently invisible) screen with colour 0..15

void clear_screen(u8 color) _naked;

//swap screens, the shadow screen becomes visible
//automatically waits for the next TV frame, doesn't need vsync() before the call
//this functions renews the sprites on screen, if they are on

void swap_screen(void) _naked;

//start the sprite drawing system
//visible screen must contain image where the sprites will be drawn
//this function is slow because of copying a lot of data
//when the sprites are on, they will be drawn automatically with swap_screen()

void sprites_start(void) _naked;

//stop the sprite drawing system

void sprites_stop(void) _naked;

//set sprite position
//id is a number in sprite list (0..63)
//x is X coordinate 0..152 (2 pixels precision)
//y is Y coordinate 0..184
//spr is sprite image number, or SPRITE_END to mark the end of list
//warning: there is no clipping, so sprite can't cross screen border

void set_sprite(u8 id,u8 x,u8 y,u16 spr) _naked;

//returns time passed since the start of the program

u32 time(void) _naked;

//wait a nomber of frames (one frame is 1/50 second)

void delay(u16 time) _naked;



(Translated and commented by Alone Coder. This translation and its descendants are not for use outside of this Evo SDK package unless I permit this. That's because of a certain immoral person who uses a patched Evo SDK and others' games to advertize his FPGA hardware. Ask any questions at dmitry (dot) alonecoder (at) gmail (dot) com.)