[Z88dk-users] User made libraries

Bridge to the z88dk-users mailing list
Post Reply
jburrell7
New member
Posts: 3
Joined: Wed Dec 16, 2015 7:16 pm

[Z88dk-users] User made libraries

Post by jburrell7 »

I have been attempting to make a user defined library for an FPGA based TS2068 that has additional bells and whistles. It seems that the documentation for the assembler is out of date since the XLIB pseudo op has been removed in favour of PUBLIC. I found this by searching through the documentation file and it was in release notes The remaining instructions for compiling libraries also don't seem to match what the assembler/linker is expecting.

First:
I want to have one file that handles printing to an ANSI style terminal that includes seven functions. The file is pretty small so I don't see the sense in separating out the various functions.
I have included PUBLIC declarations for each of the functions such as: PUBLIC term_selTerm


I am assembling with this command line: z80asm -d -xTsTxtAnsi @TsTxtAnsi.lst and am getting an obj file as expected. I copy the obj file and rename it as a .lib file in the libs/clibs directory.

When I attempt to use the function *term_selTerm*, the linker says that the .lib file is not a library file. I am not sure where to go from here.



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I have been attempting to make a user defined library for an FPGA based TS2068 that has additional bells and whistles. It seems that the documentation for the assembler is out of date since the XLIB pseudo op has been removed in favour of PUBLIC. I found this by searching through the documentation file and it was in release notes The remaining instructions for compiling libraries also don't seem to match what the assembler/linker is expecting.
The old directives XLIB, LIB, XDEF, XREF are deprecated (/gone now?) and are replaced with PUBLIC, EXTERN (and GLOBAL).

PUBLIC means this label should be made visible outside the file (replacing XLIB and XDEF).

EXTERN means this label is defined outside the file someplace else (replacing LIB and XREF).

GLOBAL should not normally be used - it means if this label is defined in this file make it PUBLIC otherwise make it EXTERN. We needed this for sdcc which uses it extensively but its use can lead to silent linking errors. Stick to PUBLIC and EXTERN wherever possible.

In addition to these, SECTIONs were introduced (see a few paragraphs into https://www.z88dk.org/wiki/doku.php?id= ... y_language ). You can continue to use z80asm as a plain assembler without sections but be aware that the c libraries are all sectioned now so if your code should be usable from the c compile line or with z88dk's crts, it should also be assigned to appropriate sections so that it gets included into the output binary. Sections are named containers into which assembled bytes are poured and at binary generation phase, the linker will sequence sections in memory according to a supplied memory map. Sections allow z88dk to generate ROMable code; an unnamed section or a section not known to the memory map may not be included in the output binary or may be appended to the binary rather than placed appropriately (eg in ram rather than rom).

If you're not sure which sections to place code and data into, safe sections are "code_user" (read only code), "rodata_user" (read only data), "smc_user" (self modifying code), "data_user" (non-zero data) and "bss_user" (initially zero data). There's also a "code_crt_init" section if you want to wedge in initialization code before main() is called (assign code there without a RET) or "code_crt_exit" for code executed after main returns but before files are closed (again no RET). In an all asm project, _main can be an assembly label indicating the asm program's start point.
First:
I want to have one file that handles printing to an ANSI style terminal that includes seven functions. The file is pretty small so I don't see the sense in separating out the various functions.
I have included PUBLIC declarations for each of the functions such as: PUBLIC term_selTerm
Ok, something like:

Code: Select all

SECTION code_user

PUBLIC _term_selTerm

_term_selTerm:
....

PUBLIC _foo

_foo:
.....

SECTION bss_user

someText:  defm "hello world"
defb 0
The routines are small or interdependent so you want to link the whole file if any PUBLIC symbol is referenced.

I put a leading underscore on the names so that they can be made visible to the c compilers. With sccz80 you can give C items a special __LIB__ attribute which allows it to see names without leading underscores (this was used to make a kind of scope for system functions separate from user functions of the same name) but sdcc is unable to do this so we now do everything without __LIB__ and all names visible to C must have a leading underscore.
I am assembling with this command line: z80asm -d -xTsTxtAnsi @TsTxtAnsi.lst and am getting an obj file as expected. I copy the obj file and rename it as a .lib file in the libs/clibs directory.

When I attempt to use the function *term_selTerm*, the linker says that the .lib file is not a library file. I am not sure where to go from here.
z80asm may be assembling all the files listed in the .lst file to .o object files first and then generating the actual lib file TsTxtAnsi.lib out of the .o files. Have a look to see if the .lib file is also there.

.o and .lib are not the same thing - an object file is partially assembled, only waiting to have physical addresses patched when it becomes part of a binary. A library file is an indexed set of linking units, out of which the linker will pull individual units as needed by the current compile. So renaming is out.

If you get the .lib file you can use z80nm to have a look at what's inside. You can do the same for .o files

If you're not getting the .lib as output what comes to mind is when you performed your last update (See https://github.com/z88dk/z88dk#installation to get a current nightly build or git clone). If it was recent and the problem still occurs are you able to share some source code so we can test directly?

I will mention that you can also build libraries using zcc with the advantage that zcc is able to swallow any sort of input like .c, .asm, .asm.m4, etc.



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
jburrell7
New member
Posts: 3
Joined: Wed Dec 16, 2015 7:16 pm

Post by jburrell7 »

Alvin,

Thanks for the speedy response. I have/had the 1.99 release, so that was not the issue. I followed your suggestions and now the library and compiler are happy with one another. I won't get to do much more than that today due to other commitments, but any other problems are likely mine. Bugs, bugs, bugs, how I can write bugs. :D

As a matter of overall C style - is it better to define C callable function names in assembler with underscores or use the __LIB__ prefix in the function prototypes?

I am very happy to see sections now included in the assembler. The ability to write rommable coded is especially welcome. Is there an update to the assembler manual? The manuals distributed with V1.99 still reference the deprecated pseudo ops.

If not, do you want someone to write the manual?



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

Bugs, bugs, bugs, how I can write bugs. :D
As a matter of overall C style - is it better to define C callable function names in assembler with underscores or use the __LIB__ prefix in the function prototypes?
lol.

It's best to do with underscores now so that it will work with both c compilers.

For a function defined in assembler (let's assume no parameters or fastcall linkage so that the one parameter is in registers and we don't have to worry about stack frame), in C you make the compiler aware that the function exists in a header file:

extern void some_function(void);

and in assembler you would implement like this:

SECTION code_user
PUBLIC _some_function

_some_function:
...
ret

(For all functions any return value is in a subset of dehl unless it's longlong or float).

And there are various details to worry about when you pass parameters that are better explained elsewhere (or ask if you need to know).

I am very happy to see sections now included in the assembler. The ability to write rommable coded is especially welcome. Is there an update to the assembler manual? The manuals distributed with V1.99 still reference the deprecated pseudo ops.
Yes sections were a great relief. You can also use them to write bankswitched code but we can't do that automatically yet - it requires manual work.
If not, do you want someone to write the manual?
Paulo is maintaining the assembler so wait to see if he says something when he's not busy. I don't know if he has a wip doc going or not.



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

If not, do you want someone to write the manual?
>Paulo is maintaining the assembler so wait to see if he says something when he's not busy. I don't know if he has a wip doc going or not.


Let's remember that in this phase we're evolving a lot to match the sdcc requirements. Paulo mostly reacted to this evolution needs. It seems to me he is now trying to clean some redundancies still used for retrocompatibility. Docs are surely necessary but will be temporary too for some more time



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

>Let's remember that in this phase we're evolving a lot to match the sdcc requirements. Paulo mostly reacted to this evolution needs. It seems to me he is now trying to clean some redundancies still used for retrocompatibility. Docs are surely necessary but will be temporary too for some more time

Well I'd say it's beyond what sdcc needs :)

Paulo is re-implementing from scratch so that it's easier to add the new features that will be coming up, primarily to do with macros (built into z80asm as opposed to the m4 type), link-time optimizations and automatic linking for bankswitched memory. These are things that aren't easy to add to the current codebase. That will take a while though and what z80asm is now is pretty stable.

It's a shame, IMO, that a current easy to get started doc is unavailable for z80asm because, in combination with m4 for macros, it is probably one of the best if not the best z80 cross assembler available right now. A brief doc containing topics like: this is how you build a binary/object/library, this is how you use macros, the concept of sections, public/extern, how they are used in the c libraries, banked memory, and so on would be very helpful.

My preference (most of the time) is to use z80asm through zcc since zcc is able to chew on more file types and will automatically do what needs to be done. zcc also opens up macros for z80asm which is something that people have missed in z80asm in earlier versions of z88dk. I'm willing to bet there is only a handful of us that knows how to do these things.



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Post Reply