News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_cpcitor

cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC.

Started by cpcitor, 20:01, 08 October 13

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

cpcitor

Quote from: cpcitor on 22:40, 29 December 14
Hello,

Summary: cpc-dev-tool-chain updated

Updated again. Mostly some new C function to call firmware.  :)
It looks like the ASM wrappers to call firmware function from C can be generated from a decorated C-level prototype.  I might later make some wrapper generator.  The benefit would be to cover all firmware calls, that would be a problem solved once and for all.

Anyway, quick changelog:

cfwi.lib wasn't remade as needed. Quick fix. I should rework all this.
Added more firmware calls: fw_scr_set_border fw_scr_set_ink
Added more firmware calls: fw_gra_set_paper fw_gra_get_paper fw_gra_wr_char fw_gra_win_width fw_gra_win_height
Add more keyboard handling routines: fw_km_read_char, fw_km_read_key, fw_km_wait_char, fw_km_wait_key
Add access to firmware routine KL TIME PLEASE.


Github repository: cpcitor/cpc-dev-tool-chain · GitHub

As an example, here's a slightly simplified source of the function cf_platform_init(), first function called by main(). As you can see, I favor source readability/maintainability and make sure other aspects (fast code, short code, etc) are good enough, and they are so far.

#include "platform.h"
#include "stdlib.h"

#include <cfwi/cfwi.h>

enum { ink_count = 16 };
const uint8_t const inks[ink_count] = { 0, 26, 6, 24, 18, 20, 2, 8, 15, 13, 3, 12, 9, 10, 1, 4 };

void cf_platform_init()
{
        fw_scr_initialise();
        fw_scr_set_mode( 0 );

        {
                uint8_t i;

                for ( i = 0; i < ink_count; i++ )
                {
                        uint8_t color = inks[i];
                        fw_scr_set_ink( i, color, color );
                }

                fw_scr_set_border( 0, 0 );
        }

        {
                long unsigned int cpctime = fw_kl_time_please();
                srand( cpctime );
        }

}

Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Quote from: cpcitor on 12:43, 08 January 15
Updated again. Mostly some new C function to call firmware.  :)

TL;DR: cpc-dev-tool-chain is updated again, covering each time more of the CPC firmware, offering a  :) lean, clean, readable, C-based API to program for the CPC, while leaving you free for all asm-level hacks and whatever you want.  ;)

Thanks

Thanks to Kevin Thacker for the scanned+OCRed firmware book!

What's this?

cpc-dev-tool-chain is a development environment targeting the Amstrad CPC platform. The pitch: it works on a modern machine and automates all the step to build for the CPC: fetching compilers and other tools, building your projects, right to the DSK or CDT file.

If you know CPC BASIC and modern C, you'll feel right at home!

cpc-dev-tool-chain was key inspiration in the creation of the nice cpctelera which has put lots of efforts on optimized routines for 2D games, especially platform games.

Update

Most updates were driven by the development of color-flood-for-amstrad-cpc game.  The focus was to exercise a rich part of C. In that context, the simplest way to have something fun enough was to call firmware for IO.  I confirm SDCC is a solid C compiler.

Summarising a number of updates since then:

* Slightly better Cygwin compatibility (but not tested recently, might be broken now?)
* Updated third-party tools: cpcrslib, 2cdt, SDCC, z88dk
* More firmware calls available from C!
* Install documentation
* Improved SDCC compile parameters
* Sort module names (which match C source file names) to allow developer to choose symbol order. In practice, if the C source file containing main() is called e.g. 00_main.c, then main() will in most cases be the first symbol in the binary, and thus the entry point (but if you use initialised global variables, you have to use a crt0, which will be selected as entry point and put first).
* Updated test/variable_storage_class_test which is also about when you need a crt0.
* Rework project configuration: no more need to store machine-dependent absolute path names in version-controlled files!
* Rework project configuration: use cdtc-project-setup, it will also update existing project to match new behaviour.
* Generated Makefile are better documented and explain how you can customise build parameters.
* Setup time: don't compile useless parts of SDCC
* Fix buggy wrapper to TXT SET CURSOR.
* Refined types, use meaningful types, e.g. unsigned char when it is really a character, vs uint8_t when it's really an integer.
* Verbose download of SDCC (since it's a bit long).
* Ability to resume SDCC download if interrupted (since it's a bit long).
* Various fixes and improvements of user-project Makefile logic.
* Add make au to generate audio files in .au format.
* Possibility to edit text files locally without regards to line feed, and have them converted to CPC-compliant ASCII files.

Next

* Cover more firmware calls.
* Better project management (e.g. some way to express which source files contribute to which generated file, which go to DSK, to tape in which order etc)?
* Just ask what you think?

Stats

Here's a count of firmware calls, grouped by pack/prefix, that are new or were adjusted somehow:


      2 fw_byte
      5 fw_gra
     20 fw_km
     10 fw_txt


which bring the total count of all firmware calls, grouped by pack/prefix, listed in cfwi:


      4 fw_cas
     19 fw_gra
      1 fw_jre
      4 fw_kl
     40 fw_km
      7 fw_lkjb
      2 fw_mc
      7 fw_scr
      2 fw_sound
     47 fw_txt



Here's a list of firmware calls that are new or were adjusted somehow:


fw_gra_line_relative(int x, int y);
fw_gra_move_relative(int x, int y);
fw_gra_plot_relative(int x, int y);
fw_gra_test_absolute(int x, int y);
fw_gra_test_relative(int x, int y);
fw_km_char_return (unsigned char c) __z88dk_fastcall;
fw_km_exp_buffer(unsigned char *buffer, uint16_t buffer_bytecount);
fw_km_get_control(uint8_t key_number) __z88dk_fastcall;
fw_km_get_delay();
fw_km_get_expand(uint8_t token, uint8_t char_number);
fw_km_get_joystick(void);
fw_km_get_shift(uint8_t key_number) __z88dk_fastcall;
fw_km_get_state(void);
fw_km_get_translate(uint8_t key_number) __z88dk_fastcall;
fw_km_read_char (void);
fw_km_read_key (void);
fw_km_set_control(uint8_t key_number, uint8_t new_translation) __z88dk_fastcall;
fw_km_set_delay(uint8_t startup_delay, uint8_t repeat_speed);
fw_km_set_expand(uint8_t token, uint8_t string_length, unsigned char* string);
fw_km_set_repeat(uint8_t key_number, enum fw_byte_all_or_nothing repeat_allowed) __z88dk_fastcall;
fw_km_set_shift(uint8_t key_number, uint8_t new_translation) __z88dk_fastcall;
fw_km_set_translate(uint8_t key_number, uint8_t new_translation) __z88dk_fastcall;
fw_km_test_key(uint8_t key_number) __z88dk_fastcall;
fw_km_wait_char (void);
fw_km_wait_key (void);
fw_txt_clear_window();
fw_txt_output(unsigned char c);
fw_txt_set_column(int8_t column);
fw_txt_set_cursor(int8_t row, int8_t column);
fw_txt_set_m_table(void *buffer, bool disable, uint8_t lowest_affected_character);
fw_txt_set_paper(uint8_t p);
fw_txt_set_pen(uint8_t p);
fw_txt_set_row(int8_t row);
fw_txt_win_enable(unsigned char left, unsigned char right, unsigned char top, unsigned char bottom);
fw_txt_wr_char(unsigned char c);

Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

Takis Kalatzis

Regarding Cygwin, I have tried doing a clean install today and unfortunately all 3 make commands described in the documentation fail.


hello_world_using_zk88d : says that Modern::Perl is a prerequisite


hello_world_using_sdcc, cpcrslib : WARNING: `makeinfo' is missing on your system.  You should only need it if
         you modified a `.texi' or `.texinfo' file, or any other file
         indirectly affecting the aspect of the manual.  The spurious
         call might also be the consequence of using a buggy `make' (AIX,
         DU, IRIX).  You might want to install the `Texinfo' package or
         the `GNU make' package.  Grab either from any GNU archive site.


Any advice?

cpcitor

Thank you Takis for trying and reporting.

What's your operating system? What version of cygwin?

Thanks.
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Quote from: Takis Kalatzis on 15:43, 08 December 17
Regarding Cygwin, I have tried doing a clean install today and unfortunately all 3 make commands described in the documentation fail.


hello_world_using_zk88d : says that Modern::Perl is a prerequisite


hello_world_using_sdcc, cpcrslib : WARNING: `makeinfo' is missing on your system.  You should only need it if
         you modified a `.texi' or `.texinfo' file, or any other file
         indirectly affecting the aspect of the manual.  The spurious
         call might also be the consequence of using a buggy `make' (AIX,
         DU, IRIX).  You might want to install the `Texinfo' package or
         the `GNU make' package.  Grab either from any GNU archive site.


Any advice?

Reproduced both problems.

Regarding z88dk

It looks like cygwin's perl is just plain too old. That may be tough to fix.

Furthermore, z88dk is not a priority target at the moment.

Z88DK is mostly a target in itself, to provide a common ground for portable code between hardware platforms. With z88dk one typically doesn't target CPC with all its benefits, one writes for z88dk with the common features. That's the spirit of z88dk.

Besides, z88dk now uses SDCC internally, actually a SDCC version which is tuned for the Z80 and uses both register sets. The expected benefit: is shorter and/or faster code in some conditions. The trouble is: this is incompatible with CPC firmware unless you disable firmware and run without it. They are also working on a "firmware interposer" which saves alternate register set on each firmware call, on interrupts, by patching the jump block in first bytes of RAM. But even that is difficult. All in all, meeting cygwin's old perl and z88dk in a state of flux doesn't fit well.

Regarding makeinfo

Looks like makeinfo isn't needed to run the software, only to rebuild documentation in some cases. Actually only the documentation of the bfd tools which isn't currently used.

Try to add -k to your make commands. It should at least build the rest of what it cans.

Looking for a fix.
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Quote from: Takis Kalatzis on 15:43, 08 December 17
hello_world_using_zk88dk

Quote from: Takis Kalatzis on 15:43, 08 December 17
hello_world_using_sdcc, cpcrslib

Any advice?

Yes, we have a fix!

The fix is in cygwin to add package texinfo.

For maximum reproducibility, you may want to start over with a fresh clone of the git repository.

If the download and/or build steps are too long, you can fix with your current copy, but you have to remove the file tool/sdcc/sdcc_srctree.ref to trigger a full recompile of SDCC. It will reused the cached tar.bz2 archive and thus won't need to redownload the whole thing.

I have updated the documentation. Now it tells:

Quotemake hello_world_using_sdcc-all builds hello_world_using_sdcc/hellosdc.dsk

make cpcrslib-all builds a number of DSK files in cpclib/cpcrslib/cpcrslib-master/examples/*/*.dsk

See https://github.com/cpcitor/cpc-dev-tool-chain/blob/master/documentation/how_to_install.md

Please tell me the option you choose (starting from scratch or only rebuilding sdcc) and if it works well. It worked here.

Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

I forgot to add:

* Wrappers will now use Z88DK fastcall convention when applicable (new ones do already, not reviewed all existing wrappers yet). This makes shorter and faster wrapper code (though the difference in speed will be small since firmware call imply context switching logic which is longer than the wrapper anyway).
* Fixed cygwin compatibility (thanks Takis for reporting).

Pushed new version with somehow improved messages. Consider:

git rebase

and perhaps

git reset --hard

if you have some unwanted local changes, to clear them.
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Hello.

Just pushed another update.  Now covering about half the firmware calls.  Nearly all KM (keyboard, including key repeat, redefine, shortcuts like Ctrl-Return) and TXT (write text, text windows, copy, cursor) now available to C programs!

Some are not tested, yet the most important ones are successfully used in https://github.com/cpcitor/color-flood-for-amstrad-cpc .

Now some statistics:

[attachimg=1]

Added those calls:

uint16_t fw_km_read_char (void);
enum fw_byte_all_or_nothing fw_km_exp_buffer(unsigned char *buffer, uint16_t buffer_bytecount);
enum fw_byte_all_or_nothing fw_km_get_repeat(uint8_t key_number) __z88dk_fastcall;
uint16_t fw_km_get_delay(void);
void fw_txt_output(unsigned char c) __z88dk_fastcall;
void fw_txt_wr_char(unsigned char c) __z88dk_fastcall;
uint16_t fw_txt_rd_char(void);
void fw_txt_set_graphic(bool enable) __z88dk_fastcall;
void fw_txt_win_enable(uint8_t left, uint8_t right, uint8_t top, uint8_t bottom);
uint32_t fw_txt_get_window(void);
void fw_txt_clear_window(void);
void fw_txt_set_column(int8_t column) __z88dk_fastcall;
void fw_txt_set_row(int8_t row) __z88dk_fastcall;
void fw_txt_set_cursor(int8_t row, int8_t column);
void fw_txt_set_cursor__fastcall(int16_t colum8h_row8l) __z88dk_fastcall;
uint32_t fw_txt_get_cursor();
uint32_t fw_txt_validate(void);
void fw_txt_set_pen(uint8_t p) __z88dk_fastcall;
uint8_t fw_txt_get_pen(void);
void fw_txt_set_paper(uint8_t p) __z88dk_fastcall;
uint8_t fw_txt_get_paper(void);
void fw_txt_inverse(void);
void fw_txt_set_back(uint8_t is_transparent) __z88dk_fastcall;
uint8_t fw_txt_get_back(void);
typedef uint8_t fw_txt_character_matrix_t[8];
enum fw_byte_all_or_nothing fw_txt_set_matrix(uint8_t character, fw_txt_character_matrix_t *matrix);
uint32_t fw_txt_set_m_table(fw_txt_character_matrix_t *buffer, bool disable, uint8_t lowest_affected_character);
uint32_t fw_txt_get_m_table();
typedef struct fw_txt_control_code_entry_t fw_txt_control_code_table_t[fw_txt_control_code_count];
uint8_t fw_txt_str_select();
void fw_txt_swap_streams(uint8_t stream1, uint8_t stream2);

Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

Takis Kalatzis

Hi, tried again with Cygwin for Windows 7. Cygwin version is the latest. Added texinfo package, performed a git rebase and deleted [size=0px]tool/sdcc/sdcc_srctree.ref[/size]


Both targets now fail on cpcxfs compilation :



make[4]: Entering directory '/home/Takis/cpc-dev-tool-chain/tool/cpcxfs/cpcxfs/src'
gcc -Wall -O3 -DLINUX=1 -DDOS=0 match.o tools.o fs.o ui.o cpcfs.o readdef.o unix.o -o cpcxfs  -lncurses
match.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make[4]: *** [makefile.lnx:59: cpcxfs] Error 1
make[4]: Leaving directory '/home/Takis/cpc-dev-tool-chain/tool/cpcxfs/cpcxfs/src'




cpcitor

Quote from: Takis Kalatzis on 15:35, 14 December 17
Hi, tried again with Cygwin for Windows 7. Cygwin version is the latest. Added texinfo package, performed a git rebase and deleted [size=0px]tool/sdcc/sdcc_srctree.ref[/size]


Both targets now fail on cpcxfs compilation :



make[4]: Entering directory '/home/Takis/cpc-dev-tool-chain/tool/cpcxfs/cpcxfs/src'
gcc -Wall -O3 -DLINUX=1 -DDOS=0 match.o tools.o fs.o ui.o cpcfs.o readdef.o unix.o -o cpcxfs  -lncurses
match.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make[4]: *** [makefile.lnx:59: cpcxfs] Error 1
make[4]: Leaving directory '/home/Takis/cpc-dev-tool-chain/tool/cpcxfs/cpcxfs/src'

I had a strange experience with cpcxfs while testing on Win10 recently.
At first, cpcfxs did not compile. Then it compiled fine.
But the message was different.

Code includes provision to use iDSK instead of cpcxfs.
Can you try this?

cd hello_world_using_sdcc ; make PREFER_IDSK_OVER_CPCXFS=1 dsk


Cool, You wrote at 16:35 and I reply to you at 16:30.
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

Takis Kalatzis

The last command you suggested failed with :



+ iDSK hellosdc.dsk.tmp -n -i hellosdc.bin -e 4000 -c 4000 -t 1
[size=78%]/bin/bash: line 13: /home/Takis/cpc-dev-tool-chain/tool/idsk/iDSK.0.13/iDSK/src/iDSK: cannot execute binary file: Exec format error[/size]make: *** [..//sdcc-project.Makefile:209: hellosdc.dsk] Error 126

cpcitor

This is strange.  Both your last error messages imply corrupted files.
Is the underlying system clean?

I have to query for a few informations.

* Version of the Operating System. 32 or 64bits?
* Version of cygwin? 32 or 64bits?
* Can you PM the corrupted files in a ZIP to me, like below?


cd /home/Takis/cpc-dev-tool-chain/
tar zcvf corruptedfiles.tar.gz tool/idsk/iDSK.0.13/iDSK/src/iDSK tool/cpcxfs/cpcxfs/src/match.o
explorer . &


... then send corruptedfiles.tar.gz?

I'll try to see what's wrong with them.

Then, what happens if you delete the files then run make again?


cd /home/Takis/cpc-dev-tool-chain/
rm -v tool/idsk/iDSK.0.13/iDSK/src/iDSK tool/cpcxfs/cpcxfs/src/match.o
make hello_world_using_sdcc-all


Thanks!
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Another update. Now fully covering GRA firmware pack jump block!

* A number of functions were changed to __z88dk_fastcall (and wrapper adjusted).
* A number of wrappers were shortened/simplified.

For coverage statistics and details have a look at: https://rawgit.com/cpcitor/cpc-dev-tool-chain/master/cpclib/cfwi/coverage.html

Here's a list of affected functions (generated from git log output):

void fw_gra_move_absolute(int16_t x, int16_t y);
void fw_gra_move_absolute__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_move_relative(int16_t x, int16_t y);
void fw_gra_move_relative__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
uint32_t fw_gra_ask_cursor(void);
void fw_gra_set_origin(int16_t x, int16_t y);
void fw_gra_set_origin__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
uint32_t fw_gra_get_origin(void);
void fw_gra_win_width(int16_t x1, int16_t x2);
void fw_gra_win_width__fastcall(int32_t fw_gra_x_x_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_win_height(int16_t y1, int16_t y2);
void fw_gra_win_height__fastcall(int32_t fw_gra_y_y_coordinates_t_asint) __z88dk_fastcall;
uint32_t fw_gra_get_w_width();
uint32_t fw_gra_get_w_height();
void fw_gra_set_pen(uint8_t pencolor) __z88dk_fastcall;
uint8_t fw_gra_get_pen(void);
void fw_gra_set_paper(uint8_t papercolor) __z88dk_fastcall;
uint8_t fw_gra_get_paper(void);
void fw_gra_plot_absolute(int16_t x, int16_t y);
void fw_gra_plot_absolute__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_plot_relative(int16_t x, int16_t y);
void fw_gra_plot_relative__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_test_absolute(int16_t x, int16_t y);
void fw_gra_test_absolute__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_test_relative(int16_t x, int16_t y);
void fw_gra_test_relative__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_line_absolute(int16_t x, int16_t y);
void fw_gra_line_absolute__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_line_relative(int16_t x, int16_t y);
void fw_gra_line_relative__fastcall(uint32_t fw_gra_x_y_coordinates_t_asint) __z88dk_fastcall;
void fw_gra_wr_char(char character) __z88dk_fastcall;
void fw_gra_default(void);
long int fw_kl_time_please(void);
unsigned char fw_km_wait_char(void);
uint16_t fw_km_read_char(void);
void fw_km_char_return(unsigned char c) __z88dk_fastcall;
unsigned char fw_km_wait_key(void);
uint16_t fw_km_read_key(void);

Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Quote from: Takis Kalatzis on 10:58, 15 December 17
The last command you suggested failed with :
cannot execute binary file: Exec format error

Cf my previous answer, is that reproducible, can you send me files so that I check if they are indeed corrupted?

CPCTelera mentions in its troubleshooting section specific things that happens with Windows, and workarounds:
Quote
    Antivirus and scanning software.  This kind of software is causing random issues that cause Cygwin and CPCtelera not to operate properly.  Common problems include failing to compile and/or execute programs, privilege problems on executing programs and random crashes of Cygwin.  If you experience this problems, try disabling your antivirus or scanning software.  Once being sure that this is the reason for your problems, you may want to configure your software not to interfere with Cygwin.
    Windows 8/10 privilege problems.  Under some unclarified circumstances, some users have privilege problems executing Cygwin sofware, and that affects CPCtelera.  In this cases, the most common workaround is launching Cygwin terminal with administrator privileges.
    Windows 8/10 executable conflicts.  Some users experience compilation or execution problems due to other Windows being using other software installed outside cygwin.  This usually happens with MinWG (gcc, g++), SDCC and git, but may happen with other software aswell.  On some installations, Windows PATH variable gives priority to previously installed software.  So, when compiling with gcc, sdcc or using git, problems happen due to Windows version of the software being executed.  In this cases, please check Windows PATH variable and adjust it accordingly.

CPCtelera Reference Manual - Troubleshooting

It works here, so I can't guess what's wrong.
I'm willing to help but your feedback is needed. Thanks!
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Quote from: cpcitor on 22:00, 20 December 17
Another update. Now fully covering GRA firmware pack jump block!

Another update with double focus:

1. Steps towards making it easier to make and publish projects using cpc-dev-tool-chain.
    * Simplified bootstrap of 3rd party projects. For example, color-flood-for-amstrad-cpc can be compiled with just git clone ; configure ; make
    * More planned on https://github.com/cpcitor/cpc-dev-tool-chain/blob/master/documentation-for-maintainers/third_party_projects_usig_cdtc.md

2. For the record, the benefit of the firmware interface is to easily get firmware benefits with comfort of C, type safety, short C source code, short generated ASM code.
* cfwi now cover MC pack.
    * MC SCREEN OFFSET for firmware-assisted hardware scrolling.
    * MC CLEAR INKS Set all inks to background like BASIC does during e.g. MODE.
    * MC SET INKS Set all inks from a table. Both shorter C and ASM code!
    * MC SEND PRINTER Can be very useful for CPC code in emulator to send detailed debug log to host OS (or for real CPC to send to real printer, if that still exists ;-). I'm considering using this for unit tests.

3. (Yes, 3 for the price of 2 ;-). C header files include official documentation from Amstrad books.  When C-level wrapper needs any explanation, these are given with C-level example code.

List of affected C-level functions:

void fw_mc_boot_program(void *loader) __z88dk_fastcall;
void fw_mc_start_program(uint8_t rom_selection, void *entry);
void fw_mc_set_mode(uint8_t mode) __z88dk_fastcall;
void fw_mc_screen_offset(uint8_t screen_base, uint16_t screen_offset);
void fw_mc_clear_inks16(ink_vector16 *ink_vector) __z88dk_fastcall;
void fw_mc_clear_inks4(ink_vector4 *ink_vector) __z88dk_fastcall;
void fw_mc_clear_inks2(ink_vector2 *ink_vector) __z88dk_fastcall;
void fw_mc_clear_inks1(ink_vector1 *ink_vector) __z88dk_fastcall;
void fw_mc_set_inks(ink_vector16 *ink_vector) __z88dk_fastcall;
void fw_mc_print_char(unsigned char char_to_send_7bits) __z88dk_fastcall;
uint8_t fw_mc_busy_printer(void);
void fw_mc_send_printer(unsigned char char_to_send_7bits) __z88dk_fastcall;
void fw_mc_sound_register(uint8_t register_number, uint8_t data);
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

cpc-dev-tool-chain updated again.

* To allow SDCC to better optimize register allocation and avoid unnecessary register PUSH/POP, I've started to add __preserves_regs type annotation on C prototypes in cpc-dev-tool-chain/cpclib/cfwi/include/cfwi at master · cpcitor/cpc-dev-tool-chain.
* Improved generation of HTML documentation. Now generated both from official documentation (OCR'ed by @Arnoldemu) and .h files and ASM source. Reports all firmware calls from Soft968 section 15, shows which are implemented or not, the variants. Nice HTML tables with a bit of CSS styling.
* The script that generated documentation also performs more detailed sanity checks, which spotted some inconsistencies.
* Fixed some inconsistencies detected by the documentation script.
* Some actual documentation fixes.

Coverage up to 57% !  8)
Nice coverage report: Firmware coverage in cpc-dev-tool-chain's CFWI (C-firmware interface)

Regarding __preserves_regs:

I did only a quick test (without a high max-alloc-per-node).
Not a big deal but it did reduce code size somehow, while things still work.  Peeking at ASM code, I saw indeed at least an instance where useless PUSH/POP pair disappeared.
When several firmware calls are chained, the optimization can be defeated by one specific firmware call that needs the PUSH/POP pair again, which shows that SDCC still does its job.
It also looks like it causes no-overall-effect changes in where SDCC stores some registers via IX.
All in all, only good points.
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

cpcitor

Heya all!

TL;DR: work-in-progress on improvements in cpcitor/cpc-dev-tool-chain to reduce code repetition, program CRTC easily from C, initial support for 2D sprites etc.

I'm working on yet another production for the CPC.

cpcitor/cpc-dev-tool-chain did support cpcrslib before cpctelera was forked from it, but 2D sprites was not my focus.

Another production is on its way. This one uses non-standard CPC definition (256x256 like Arkanoid) and features 2D sprites with a routine compatible with this mode.

Some work in progress include:

* generic facility to export ASM-defined values to C (#define for integer values, and when value represents data in memory, a macro to use C pointers with proper C type to get the compiler help you). Allows to apply the DRY principle: don't repeat information in many places. Make code shorter, cleaner, more resilient to changes, reduces development complexity and time.
* Short generic routines to set CRTC to any definition (width<=504 pixels, height<=280). Callable from C or ASM. Compile-time sanity check: abort compilation if values are incompatible with 16k screen. It use the feature above, so C or ASM code can use variables representing CRTC registers. More DRY principle!
* a program to convert PNG images to sprite data of any dimensions (width has to be integral number of bytes, rectangular shape, no transparency so far). Supports mode 0, 1, 2. Many convenient command-line options. For example, reads the palette from file or command line, sensible defaults, sanity checks to ensure generated data makes sense and helps you get the job done even if the program that generates the PNGs is sloppy about the palette (unused entries, duplicates, etc) or even if you know the palette but the PNG is encoded without one. Also command-line option to flip generated data vertically (my routine draws sprites from the bottom, for a reason). The output is generated assembly with generated ASM-level constants (global symbols available to C, too, DRY principle again) representing the sprite dimensions, palette count and all palette values. You can thus set palette from one the sprites without repetition at all. (This is what I do.)
* Integration of the program with the tool chain. Edit your PNG, save it, do make run and the generated DSK,CDT,VOC/WAV and all have the new image updated inside. No need to keep any generated file. DRY, lean and clean.
* Macros to access all known undocumented Z80 instructions. Based on z80 Instruction Set and turned into a source ASM with macros by a bash script.
* Now patches the sdasz80 assembler that have it report Z80 timings on the CPC, instead of generic timings! Based on https://borilla.co.uk/z80.html which is based in turn on data measured by Arnoldemu and the Executioner. In the example below, numbers between brackets are CPC timings. Based on same data as above.

I know about RASM, it does undocumented instructions and probably timing reports. Not sure yet if it does everything I need. I'm pretty obsessed with having a build in only one manual step: "trigger the build, get the finished file ready to run". Even the graphics! Perhaps I will give RASM a try some day.

Below is example assembler output showing timings. This is a number of snippets extracted from real code:


---------------------->VV<- Z80 CPC Timings
   4006 21 A1 5E      [ 3]   27         ld hl, #sprite_jg9_tile_06_png_data ;3
   4009 01 00 70      [ 3]   28         ld bc, #0x7000
   400C CD 69 40      [ 5]   29         call drawsprite

   407D 4F            [ 1]   46         ld c,a                                            ;1 - store dest LSB
   407E 14            [ 1]   47         inc d                                             ;1 - H table
   407F 1A            [ 2]   48         ld a,(de)                                         ;2 - a=line start MSB
   4080 57            [ 1]   49         ld d,a                                            ;1 - HL=dest
   4081 59            [ 1]   50         ld e,c                                            ;1

   4082 ED A0         [ 5]   72         LDI                     ;5

   43B7 3E 01         [ 2]   71 ld a, #0x01
   43B9 F5            [ 4]   72 push af
   43BA 33            [ 2]   73 inc sp
   43BB CD D4 45      [ 5]   74 call _fw_scr_set_mode
   43BE 33            [ 2]   75 inc sp

   43C2 21 AF 43      [ 3]   79 ld hl, #_game_palette
   43C5 CD DD 45      [ 5]   80 call _fw_mc_set_inks__4

   40A1                      38 _screen_address_processing__configure_crtc::
   40A1 01 01 BC      [ 3]   39         ld bc, #0xbc01
   40A4 ED 49         [ 4]   40         out (c), c
   40A6 01 20 BD      [ 3]   41         ld bc, #0xbd00 + _crtc_r1_disp_width_chars
   40A9 ED 49         [ 4]   42         out (c), c
                             43
                             44         ;; horizontal centering
   40AB 01 02 BC      [ 3]   45         ld bc, #0xbc02
   40AE ED 49         [ 4]   46         out (c), c
   40B0 01 2A BD      [ 3]   47         ld bc, #0xbd00 + 46 + ((_crtc_r1_disp_width_chars-40)/2)
   40B3 ED 49         [ 4]   48         out (c), c
                             49
   40B5 01 06 BC      [ 3]   50         ld bc, #0xbc06
   40B8 ED 49         [ 4]   51         out (c), c
   40BA 01 20 BD      [ 3]   52         ld bc, #0xbd00 + _crtc_r6_disp_height_chars
   40BD ED 49         [ 4]   53         out (c), c
                             54
                             55         ;; vertical centering
   40BF 01 07 BC      [ 3]   56         ld bc, #0xbc07
   40C2 ED 49         [ 4]   57         out (c), c
   40C4 01 22 BD      [ 3]   58         ld bc, #0xbd00 + 30 + ((_crtc_r6_disp_height_chars-24)/2)
   40C7 ED 49         [ 4]   59         out (c), c

   40FA 3E 08         [ 2]  111 ld a, #8
   40FC 84            [ 1]  112 add a, h
   40FD 67            [ 1]  113 ld h, a
   40FE 10 EE         [ 4]  114         djnz next_scan_line_in_char
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

zhulien

i found a lot of sprites libraries and sprite functions are very difficult to use, i guess there needs to be a balance on the CPC given the lower horsepower between ease of use and performance - but I wonder if my JS sprite library would be fast enough on CPC if re-written in C?


http://8bitology.net/poc/framework/js/  look at jsprites.js for the sprite library, and game-spritedemo.js for an example how to use them.


Briefly, they work by having an array of images and an array of sprites (basically metadata that can use the images).  the images can be used in multiple sprites and may contain multiple frames of multiple sprites - kind of like tiles - or sprites sheets that you can easily find on Google.


You setup the metadata with a couple of properties, such as animation sequences, as many as you like and you can control from which animation point to start at from the sprite library.  You can automatically loop, or with logic change to different sequences such as death, jump, walk right, walk left etc... whatever suits the situation. 


The sprite library allows you to create easily, custom arrays from the main sprites array - for example, you might have all sprites in the main array, but want to build a custom level1 sprite array for level 1 of a game, so this can be done easily to optimise the array that will be iterated through for updating animation sequences, movements etc.


With JS, like C you can have a function in place of some properties - pointers in C, but in-line functions in JS.  This means updating a coordinate for example doesn't have to be so simple as adding 1, but can be for example a function that looks up the next position within a circle circumference if you want gyrus style movement.


In the provided example, there are a couple of asynchronous callbacks, onRenderCanvas which paints the canvas (or screen if you like), and onIterationGameLoop which does the game processing.  In CPC World think of the game loop being an interrupt and the render  function being a separate interrupt - this allows for different speed systems to play a game at the same speed but with different automatic frame-skips.  On CPC they can be 1 interrupt I guess.   Within onRenderCanvas there is the paintSprites function that automatically paints the sprites on the screen at whatever coordinate they should be painted at and whatever frame should be painted.  In the game loop, we can call the animateSprites which changes them to the next animation sequence, moveSprites which changes their position to their next position and showSprites which decides which ones to show (we can have hidden ones too).


Anyway, the code is very very simple to follow too even though it is in JS and you are coding in C - so... I hope you might find it useful?

roudoudou

Quote from: cpcitor on 23:16, 12 February 20
I know about RASM, it does undocumented instructions and probably timing reports. Not sure yet if it does everything I need. I'm pretty obsessed with having a build in only one manual step: "trigger the build, get the finished file ready to run". Even the graphics! Perhaps I will give RASM a try some day.
RASM does internal timing in order to produce synchronized code but if you want timing report, people have done Visual Studio plugin: https://marketplace.visualstudio.com/items?itemName=mborik.z80-macroasm
My pronouns are RASM and ACE

reidrac

Quote from: roudoudou on 07:14, 13 February 20
RASM does internal timing in order to produce synchronized code but if you want timing report, people have done Visual Studio plugin: https://marketplace.visualstudio.com/items?itemName=mborik.z80-macroasm

In case this helps: https://github.com/reidrac/z80count

It counts Z80 cycles; not CPC specific. It adds (and updates) comments to the code.
Released The Return of Traxtor, Golden Tail, Magica, The Dawn of Kernel, Kitsune`s Curse, Brick Rick and Hyperdrive for the CPC.

If you like my games and want to show some appreciation, you can always buy me a coffee.

roudoudou

Quote from: reidrac on 08:01, 13 February 20
It counts Z80 cycles; not CPC specific.
Nops are useless to spectrum/MSX users as regular ticks are useless for CPC users   ;D
Rasm will do both in the future  8)
My pronouns are RASM and ACE

roudoudou

oups, someone told me i put the wrong plugin :D
z80-asm-meter-vscode, is the cycle measurement plugin
My pronouns are RASM and ACE

norecess464

I use both plugins as referenced by @roudoudou above and I have to say it's awesome!
ps. it's for VSCode, not VisualStudio
My personal website: https://norecess.cpcscene.net
My current project is Sonic GX, a remake of Sonic the Hedgehog for the awesome Amstrad GX-4000 game console!

roudoudou

Quote from: norecess on 14:15, 13 February 20
I use both plugins as referenced by @roudoudou above and I have to say it's awesome!
ps. it's for VSCode, not VisualStudio
Visual Studio Code indeed...
My pronouns are RASM and ACE

cpcitor

Quote from: norecess on 14:15, 13 February 20
I use both plugins as referenced by @roudoudou above and I have to say it's awesome!
ps. it's for VSCode, not VisualStudio

Ah, so it exists outside of Windows. That's good news.

Just tried https://marketplace.visualstudio.com/items?itemName=mborik.z80-macroasm but did not figure at once how to tell it where to look for definitions.

I found https://github.com/theNestruo/z80-asm-meter-vscode but just seeing numbers in status bar is not whet I expected.

Quote from: roudoudou on 08:06, 13 February 20
Nops are useless to spectrum/MSX users as regular ticks are useless for CPC users   ;D
Rasm will do both in the future  8)

But it is open-source, so it can be adjusted to CPC timings. (So is RASM.)

Hey, Reidrac, your games seem impressive! Not played them, but the graphics are great and the video of "The dawn of kernel" from https://www.usebox.net/jjm/ suggests a very nice experience.
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

Powered by SMFPacks Menu Editor Mod