Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zcc: further process global defs file generated by z80asm -g #73

Closed
aralbrec opened this issue Feb 17, 2017 · 3 comments
Closed

zcc: further process global defs file generated by z80asm -g #73

aralbrec opened this issue Feb 17, 2017 · 3 comments

Comments

@aralbrec
Copy link
Member

aralbrec commented Feb 17, 2017

Related to #42 (although a global def file is also being used to build the bifrost*2 engine in the new c lib zx library where the engine is produced as a pre-assembled binary with entry points communicated via the global defs).

The problem being considered is how to communicate public entry points to already assembled binaries easily. The application is the manual distribution of a binary across several memory banks where calls across banks must be done via trampoline to the publicly exported interface in another bank.

The global defs file produced by z80asm -g is exactly what is needed. However it currently produces a file with every publicly exported symbol defined as a "defc foo = $xxx ; modulename" in the defs file. There is nothing wrong with this information - what is needed is a way to use that more easily.

Some things that would help:

  • Addition of "PUBLIC foo" for each define so that the user doesn't have to manually add PUBLIC to symbols needed in other compiles (other compiles will add the global defs file to gain knowledge of entry points).

  • A means to filter out unneeded symbols. In the new library especially, a lot of extra public constants may appear in the global defs file that is irrelevant to a bankswitching task and may interfere with the same constants defined during compiles of other portions of the project.

The suggestion is to have zcc process the global defs file to the required form by introducing new flags to accompany -g: -g, -gp, -gf filename, -gF filename, -gpf filename, -gpF filename

The 'p' corresponds to adding the "PUBLIC foo" exports into the defs file. The "f" indicates that a following file will contain symbols that will be accepted from the defs file. The "F" indicates that a following file will contain symbols that will be rejected from the defs file.

With this arrangement I think the user has a good way to get out of the global defs file what is needed.

Does it sound reasonable?

@aralbrec
Copy link
Member Author

A few more thoughts on this before an implementation is attempted:

  • The command line switch only needs to be -gpf with the leading "g" required and then "p","f" each optionally present in any order. If "p" is present symbols will also have a "PUBLIC foo" line added to the defs file. If "f" is present then the following specified file will be used to read in rules that determine which defines are included or excluded from the defs file. This way the user can specify exactly what defines are present in the output.

  • The idea for the rules file is to have one regular expression per line with a leading "-" or "+" indicating whether the rule causes rejection or acceptance respectively. These rules will be processed in the order they appear in the file individually for each "defc foo = $nnn ; comment" line that z80asm produces in the .def files. Each individual rule is applied to "foo" only to determine if it will be included in the final defs file.

I'm looking at copt and its regular expression engine to see if it can be reused in zcc to do this regular expression thing.

@aralbrec
Copy link
Member Author

aralbrec commented Feb 28, 2017

The changes have been made to zcc. The regular expression engine used by copt is reused in zcc to filter the global defc file.

The options with description below:

-g
Same behaviour as before with all publicly declared symbols from a compile written to a .def file in assembler friendly form.

-gp
All publicly declared symbols from a compile are written to a .def file with accompanying "PUBLIC" in assembler friendly form.

-gf filename
All publicly declared symbols from a compile are filtered by regular expression rules stored in file "filename" and surviving symbols are written to a .def file in assembly friendly form.

-gpf filename
All publicly declared symbols from a compile are filtered by regular expression rules stored in file "filename" and surviving symbols are written to a .def file with accompanying "PUBLIC" in assembly friendly form.

In "filename" there is one rule per line. The line can be optionally preceded by ";", "+", "-" which mean comment, accept, reject respectively (if not present, accept is implied). Each public symbol is matched against the rules in order found in "filename". The first match determines whether the symbol will be accepted or rejected.

An example:

__IOCTL_READBUFSIZE
-__[.]*
+[.]*

The first rule will accept the specific symbol __IOCTL_READBUFSIZE. The second rule will reject any symbols beginning with __. The last rule will accept anything else. "." is a posix-defined special char that matches any character except \n.

The purpose of this change is to make it easier to manually create bankswitched programs or export an interface to a compiled binary.

@aralbrec
Copy link
Member Author

aralbrec commented Apr 7, 2018

I thought I'd share this perverse application of using the global def file generated by zcc -g.

The problem is how to communicate a #define value and a sizeof value to an asm file that creates space based on these values. In the asm file, space declared with, eg, defs N must have N known at assemble time. Ie it can't be an extern symbol and must be a declared constant. So the only way to communicate the value from an external source is through an include file.

In C, the name of an array is an alias for a constant address. So this twisted bit of code uses this to communicate the size of a structure to an asm file via the address of an array.

  1. Make a dummy .c program that places arrays at an address equal to the sizeof the struct wanted with the symbol name wanted.
  2. Compile to binary using -gf foo.rxp option which will create the global def file (-g) and prune symbols based on regular expressions in file "foo.rxp".

Here's an example communicating the size of "struct data".

dummy.c

struct data
{
   char a;
   int b;
   long c;
};

#ifdef __SDCC

__at (sizeof(struct data)) unsigned char _data[];

#endif

#ifdef __SCCZ80

unsigned char _data[] @ (sizeof(struct data));

#endif

void main(void)
{
}

And the regular expression file "dummy.rxp"

+data
-[.]*

After a compile:
zcc +zx -vn -gf dummy.rxp -clib=sdcc_iy dummy.c -o dummy

The file "dummy.def" is created with one defc:

defc __data = $0007

which can be directly included into the asm file.

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

No branches or pull requests

1 participant