Programación de juegos con z88dk

By eldeljar

Supporter (9)

eldeljar's picture

29-12-2016, 20:13

Hola, estoy empezando a desarrollar un juego de MSX con las librerías de z88dk y me gustaría saber si alguien ha desarrollado algún juego con ella.

El problema es que apenas tengo unos cuantos sprites de 16x16 y tiles y una única pantalla y ya tengo ocupados 12KB aproximadamente. Tampoco tengo muchas funciones en C como para que me ocupe tanto el código, además que todavía no he metido música ni efectos sonoros.

En ensamblador se que se usa pletter (por ejemplo) para comprimir las imagenes, pero no encuentro nada similar en C.

Si alguien ha desarrollado una ROM con z88dk me gustaría que me aconsejara sobre cómo puedo reducir/optimizar código, si hay alguna librería en C para comprimir y descomprimir las imagenes, opciones del compilador para optimizar el código generado, etc.

Muchas gracias.

Login or register to post comments

By samsaga2

Resident (52)

samsaga2's picture

30-12-2016, 09:51

Ni idea de z88dk pero tiene toda la pinta de que estas creando una rom de 16kb con lo que solo te quedarian 4kb para codigo. O comprimes o miras de crear una megarom con z88dk.

Megaroms con ese compilador no he visto pero si con el sdcc.

By eldeljar

Supporter (9)

eldeljar's picture

30-12-2016, 20:26

Gracias por la respuesta. En realidad intento hacer una rom de 32K y estoy intentando hacer optimizaciones en el código, pero aún así creo que me faltará espacio. Con las últimas optimizaciones he reducido el fichero binario a 9KB, pero teniendo en cuenta que sólo tengo una pantalla y todavía me falta implementar muchas funciones, me sigue pareciendo excesivo.

Ahora me voy a poner a revisar de nuevo el código a ver si puedo optimizar algo más, pero me sigue preocupando cómo puedo optimizar el espacio que ocupan las pantallas o si hay alguna forma de cargarlas en tiempo de ejecución.

Cualquier sugerencia será bienvenida.

By Alcoholics_Anonymous

Resident (39)

Alcoholics_Anonymous's picture

31-12-2016, 20:25

Sorry for the English Sad but I think it's unlikely you'll get good answers to your question from the msx scene since z88dk is not in common use by the msx community.

What does your compile line look like? z88dk has two C libraries (called classic and new) and two C compilers in it currently (called sccz80, derived from small C, and zsdcc, an improved version of sdcc) so the available optimizations and library functions depends on what you are using to build the binary.

In terms of data compression, the new C library contains zx7 and aplib. The classic library does not yet have these functions built-in but it's fairly easy to copy these functions out of the new library to use in your own project if necessary.

I am guessing you are using the classic library and sccz80 as C compiler so that your compile line looks something like "zcc +msx ...". Make sure you are targeting a ROM cartridge by using subtype=rom as in "zcc +msx -subtype=rom ..." (some details here). If you add "-create-app" to the compile line, a rom image will automatically be built. When using sccz80, the max optimization is -O3. You can also use zsdcc to compile your code by adding something like "-compiler=sdcc -SO3 --max-allocs-per-node200000 --opt-code-size --fsigned-char" to the compile line. Compilation using zsdcc is not thoroughly tested in conjunction with the classic library but it should be alright. The "--opt-code-size" is optional and "--fsigned-char" makes chars signed by default which is what is expected by most programs (zsdcc makes chars unsigned by default which produces better code). z88dk adds several things that improve on sdcc's output and "SO3" is one of them -- it enables some aggressive peephole optimizations.

A few a functions in the classic library are not ROMable but most will work. The new library, OTOH, was re-written from scratch to be ROMable and work well with any C compiler. Unfortunately there is no dedicated msx target for it yet but you can get it to automatically generate msx cartridges if you use the generic z80 target called embedded. You'll have access to the entire C library but nothing msx specific and no file io including terminal io. If you'd like to try compiling this way for the msx, let me know. It's possible to compile everything (multiple C, asm files) directly to an msx cartridge in one line.

Be sure to use the latest version of z88dk which is downloadable from z88dk's nightly build page. Correct installation instructions are available here. z88dk is an active project and it has been improved quite a bit since the last Sourceforge release.

By eldeljar

Supporter (9)

eldeljar's picture

01-01-2017, 16:35

Thank you very much for the information. I'm actually compiling with "zcc + msx -create-app -subtype = rom ..." and using the classic sccz80 library. I will further analyze the options you indicate.

On the other hand, I am also analyzing the zx7 tool to compress and decompress the data of the screens and sprites.

By Alcoholics_Anonymous

Resident (39)

Alcoholics_Anonymous's picture

01-01-2017, 21:41

eldeljar wrote:

Thank you very much for the information. I'm actually compiling with "zcc + msx -create-app -subtype = rom ..." and using the classic sccz80 library. I will further analyze the options you indicate.

(this one is the original z88dk library that has a specific msx target and has msx-specific functions in it)

compile with sccz80 (this is the one you are doing):
zcc +msx -vn -subtype=rom -create-app -O3 test.c -o test -m
;; -create-app generates a 32k msx rom
;; -m creates a map file so you know where things are in memory

compile with zsdcc:
zcc +msx -vn -subtype=rom -create-app -compiler=sdcc -SO3 --max-allocs-per-node200000 test.c -o test -m
;; -SO3 turns on aggressive peephole rules
;; --max-allocs-per-node200000 is high optimization level that will slow down compiles but produce better code
;; you can add --opt-code-size which will shrink code sometimes at the expense of speed

As mentioned, sdcc compiles are a little new with the classic lib but it should function alright.
Some classic library functions are not ROMable (and will not work as part of a rom) but most will be.

As for your program size it's hard to say what is making it that big without seeing it. Are you using any stdio functions? That will pull in a chunk of the library because the printf/scanf functions support a lot of % converters by default. You can be more selective about which ones get included in the binary with a suitable pragma and this will reduce the sizes of printf/scanf considerably.


On the other hand, I am also analyzing the zx7 tool to compress and decompress the data of the screens and sprites.

The zx7 binary is included in z88dk so you can compress with, eg, "zx7 -f file.bin" on the compile line. The "-f" just tells zx7 to overwrite any pre-existing output file ("file.bin.zx7" in this case). zx7 documentation.

The zx7 decompressor is easy to copy out of the new c lib to your project if you wind up compiling with the classic library. At some point down the road, the two libraries will be synchronized so that there is similar functionality in both.

There is no msx-specific target so you have to compile with the generic embedded target. You have to override the compile-time defaults to suit the msx and its memory map and that's done by supplying a few configuration files in your project. This zip contains an example project. The readme contains compile instructions. This demo was originally written by Timmy; link is in the readme.

I'll just describe the parts:

src/ contains all the source files. You can see there how asm and c are mixed. There are no examples of using special fastcall or callee linkage for functions written in asm and called from C because none of the functions take any parameters. If you do have functions taking parameters using those linkages instead of standard will save a lot of memory. The program makes use of the BIOS to do many things as you can see. The new library does not provide anything msx specific.

dmo.lst lists all the source files in the project. This single file will be given to the compiler and the compiler will grab all those files to compile into the binary. modifies the compile-time configuration to suit the msx. The configuration is commented. Two things which grab my attention: the stack pointer is not modified by the crt but is set by "crt_preamble.asm" to "ld sp, ($FC4A)". Hopefully that is ok. The second thing is that interrupts are enabled by the crt. Maybe they should be disabled at startup? These crt configuration variables are described here. One more thing: the clib=sdcc_iy compile is allowing the compiler to use IX and IY; on some targets this is a problem but I don't know if this is a problem for the msx.

crt_preamble.asm contains the msx cartridge preamble. This will appear at the beginning of the output cartridge rom. (Its presence is indicated in

An example compile using zsdcc (compile line described in readme):

zcc +embedded -vn -clib=sdcc_iy -SO3 --max-allocs-per-node200000 @demo.lst -o demo -create-app -Cz"--rombase=0x4000 --romsize=0x8000"

The output files generated:

demo.rom This is the 32k msx cartridge

demo_CODE.bin, demo_DATA.bin, demo_BSS.bin These are the raw binaries corresponding to the code, data and bss sections. Total ram use is the size of DATA plus BSS. Total space used in rom cartridge will be CODE plus a little more for a stored DATA section.

demo This file catches code and data not assigned to a section, meaning that stuff did not make it into the output rom. If this file is non-zero size, this is an error! It means you have forgotten to assign some asm stuff to a section someplace.

zcc_opt.def, zcc_proj.lst are files zcc generates to indicate active options and input source files used.

During the above compile, some messages:

The warnings are all accurate. Some have to do with assigning a negative number to an unsigned storage location, some with creating a loop that never ends, some with code after the forever loop never being reached.

The default compile is a compressed ROM model. This means what goes into the cartridge is the CODE section plus a compressed copy of the DATA section (a copy of the data section is necessary so that ram can be initialized at startup with non-zero values). The compressed DATA section is compressed using zx7; in this case the message "File converted from 50 to 41 bytes" is produced which means the data section was compressed from 50 to 41 bytes. The gain has to be at least ~80 bytes to be productive because the zx7 decompressor code is ~70 bytes long. So in this case the binary produced with compression is a little bit larger than one produced without. You can change to a non-compressed ROM compile by adding "-startup=1" to the compile line.

OK, that should be quite a bit to chew on :)

By eldeljar

Supporter (9)

eldeljar's picture

02-01-2017, 21:43

Thank you very much again.

The source code is not very optimized right now (I'm newbie) and so the binary file is 9KB. So far I'm just using the msx / gfx.h library.

However, I have executed "zx7 -f" on the binary file and compressed the binary file to 3KB.

Until I have more experience I will stay with the classic library, as it has very useful functions, but sooner or later I will use the new library.

The information will be very useful to me. Thank you very much.

My MSX profile