z80 Development Kit
You are not logged in.
Hi all,
So I've started looking at what it takes to make a library, and while I
made the library equivalent of 'hello world' and it did indeed work, it's
brought up a lot of questions. My test program just used a __FASTCALL__
function so none of the other issues have presented themselves.
Firstly:
In the wiki, there is an example:
5 XLIB sp1_IterateSprChar_callee
6 XDEF ASMDISP_SP1_ITERATESPRCHAR_CALLEE
7
8 LIB l_jpix
The XDEF - is the format for the string always ASMDISP_functionname_CALLEE
for callee linkage functions: for example, would
extern int __LIB__ __CALLEE__ foo(int a, char *b);
look like this in the corresponding asm file:
XLIB foo
XDEF ASMDISP_FOO_CALLEE
LIB foobarlib
.foo
...some code...
Secondly:
Is there an accepted practise of unmunging the stack when returning from a
__CALLEE__ function? Is it just a case of unwinding the stack with a few
POP instructions, then restoring the return address, or are there other
considerations with __CALLEE__ linkage I might be missing?
Are there any instances (other than __FASTCALL__) where you would *not*
use __CALLEE__ linkage for a library function?
Thirdly:
Any registers that need to be preserved? I'm thinking the main set (AF,
HL, DE, BC) are all fair game since any caller will be moving things in
and out of its own local variables on the stack, rather than keeping stuff
in registers. However, I'm also thinking that IX and IY should be
preserved (since the caller might be referencing things on the stack with
IX+d and IY+d instructions)
Almost lastly: including symbols from elsewhere in files consumed by
z80asm. I've been using sjasmplus for my asm projects (the current one is
this ethernet board for the Spectrum). I'd like to export some symbols to
include in the ROM call wrapper which will form the C socket library -
what's the best way to do this when using z80asm? (With sjasmplus, I tend
to just use its 'include' directive).
And lastly...and probably a big one. The ROM socket library returns a
socket handle - what should I be doing to associate this with something
to be usable as a file descriptor for the Z88dk, such that the low level
I/O functions can work with a socket equally well as they do a file - i.e.
such that read()/write()/close() etc. work? Any good pointers for things
to look at such that it'll integrate with the low level I/O?
Thanks.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673 … om/javaone
Secondly:
Is there an accepted practise of unmunging the stack when returning from a
__CALLEE__ function? Is it just a case of unwinding the stack with a few
POP instructions, then restoring the return address, or are there other
considerations with __CALLEE__ linkage I might be missing?
Unwinding whilst preserving the return value is all you need to do.
Any registers that need to be preserved? I'm thinking the main set (AF,
HL, DE, BC) are all fair game since any caller will be moving things in
and out of its own local variables on the stack, rather than keeping stuff
in registers. However, I'm also thinking that IX and IY should be
preserved (since the caller might be referencing things on the stack with
IX+d and IY+d instructions)
Everything is fair game, though that depends on what registers are reserved
for use by the platform.
Almost lastly: including symbols from elsewhere in files consumed by
z80asm. I've been using sjasmplus for my asm projects (the current one is
this ethernet board for the Spectrum). I'd like to export some symbols to
include in the ROM call wrapper which will form the C socket library -
what's the best way to do this when using z80asm? (With sjasmplus, I tend
to just use its 'include' directive).
Turn the symbol files into the format defc XXX = fff, then you can just use INCLUDE "file"
And lastly...and probably a big one. The ROM socket library returns a
socket handle - what should I be doing to associate this with something
to be usable as a file descriptor for the Z88dk, such that the low level
I/O functions can work with a socket equally well as they do a file - i.e.
such that read()/write()/close() etc. work? Any good pointers for things
to look at such that it'll integrate with the low level I/O?
You could look at the ZSock integration I did about 8 years ago that did precisely this -
there's a :TCP/host/port device and a :UDP/host/port device hooked into stdio. Hooking in at the fcntl
is probably too low-level to switch on the file handle type.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673 … om/javaone
Offline
Firstly:
In the wiki, there is an example:
5 XLIB sp1_IterateSprChar_callee
6 XDEF ASMDISP_SP1_ITERATESPRCHAR_CALLEE
7
8 LIB l_jpix
The XDEF - is the format for the string always ASMDISP_functionname_CALLEE
for callee linkage functions: for example, would
extern int __LIB__ __CALLEE__ foo(int a, char *b);
look like this in the corresponding asm file:
XLIB foo
XDEF ASMDISP_FOO_CALLEE
LIB foobarlib
.foo
...some code...
There is no fixed format for the XDEF string -- what you see is what I thought made sense at the time. An XDEF'd name is merely a local name made global so it could be anything. The particular XDEF above (ASMDISP_SP1_ITERATESPRCHAR_CALLEE) is a displacement from the C entry point of the function (sp1_IterateSprChar_callee) to the asm entry point (asmentry IIRC). I thought it made sense to: (1) make the name long so that it wouldn't collide with any global names in a user C/asm program and (2) connect the XDEF name to the function name since its purpose was to indicate an alternate entry point to the function. This way users could likely guess at the name rather than having to look it up.
I've used this naming "convention" in library functions rewritten from C into asm (sp1, stdlib, strings), simply because I view z88dk not just as a C complier but as a vehicle for general z80 code reuse. So adding an asm entry point to functions is an extra in support of this. But yes, if you want to follow this "convention" then you have the right idea above.
Are there any instances (other than __FASTCALL__) where you would *not*
use __CALLEE__ linkage for a library function?
No I don't think so. As mentioned in the wiki, z88dk does require an alternate CALLER entry point for calls through a function pointer. If that's done, then CALLEE is always preferable.
C language library functions must be CALLER linkage because the C compiler cannot generate code for a CALLEE linked function.
Thirdly:
Any registers that need to be preserved? I'm thinking the main set (AF,
HL, DE, BC) are all fair game since any caller will be moving things in
and out of its own local variables on the stack, rather than keeping stuff
in registers. However, I'm also thinking that IX and IY should be
preserved (since the caller might be referencing things on the stack with
IX+d and IY+d instructions)
As dom mentioned, anything goes. z88dk doesn't reserve any registers for itself.
On the spectrum in particular, the value of the IY register is important to the Basic ISR and IY/HL' is important to some ROM routines. However in any code I've written for the spectrum I preferentially use other registers first but if the best implementation requires use of those registers, I use them. I then leave it up to the programmer to disable interrupts or install an IM2 handler. This makes most sense (to me) for non-core add-ons (ie for the SP1 sprite library it makes sense but for memcpy it probably doesn't). Although now with talk in another thread about what to do about the misbehaving (from our point of view) CPC firmware, it could turn out that all targets may eventually have optional code inserted so that all registers can be used without side effects.
From the point of view of a C/asm program, the use of IY affects the basic interrupt only. The use of the EXX set (HL' in particular) only affects some ROM calls. z88dk does use a few (tape i/o among one or two more) however these are not affected by using HL'. It is only when returning to basic or using Stef's jump to Basic line # stuff that side effects might be seen.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673 … om/javaone
Offline