Skip to content

Get function API #137

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

Closed
stevesims opened this issue Mar 24, 2025 · 4 comments
Closed

Get function API #137

stevesims opened this issue Mar 24, 2025 · 4 comments
Milestone

Comments

@stevesims
Copy link
Contributor

stevesims commented Mar 24, 2025

#136 discusses ideas about allowing the line editor to be customised, and providing access to the underlying functions that are used to implement auto-complete.

To facilitate this we would need an API that can provide access to those functions. The API would, essentially, return pointers to the C functions, and follow the ZDS C function calling conventions.

With such a mechanism in place we could then look to expose other functions inside MOS.

Additionally as returning a 24-bit pointer is not really friendly to Z80 code, providing an alternate API to call a C function would be a sensible companion API. I believe that this should be callable from Z80 code.

@stevesims stevesims added this to the MOS 3.x milestone Mar 24, 2025
@stevesims stevesims changed the title Get function API Get/Call function API Apr 13, 2025
@stevesims
Copy link
Contributor Author

One thing I hadn't understood/appreciated about how the eZ80 works in ADL mode vs plain Z80 mode is that the processor has two different stack registers, SPL and SPS. In ADL mode code SPL (Stack Pointer Long) is used, and this is the "SP" register that MOS's code sees. Z80 mode code however will be seeing SPS (Stack Pointer Short) for its "SP" register, which the eZ80 combines with MB to work out the actual memory address of the stack to use.

This means that the idea of using the stack to pass arguments to functions, or APIs, aren't really compatible with Z80 mode code - at least not directly.

In order to allow APIs to fetch arguments from the stack to be usable from Z80 mode code we will need to provide a mechanism to allow such arguments to be pushed to the correct stack. I suspect this means having a few APIs to "push argument". These would likely be "push 8-bit arg", "push 16-bit arg", "push 24-bit arg", "push 32-bit arg", and "push pointer arg". (The push 24 and push 32 would be splitting input values across two registers in a manner that is Z80 mode friendly.). These may need companion "pop argument" APIs.

So Z80-mode code wishing to use a "Call C Function" API would need to use these "push argument" APIs to push arguments to the stack first.

A friendly API would not necessarily need to have "pop argument" APIs. In principle, the API call that is using stack-based arguments could potentially automatically pop them. This may require a "start arguments" API call to help the system understand where the arguments begin, as an API call such as f_fprintf (#154) supports a variable number of arguments. A "pop all arguments" API could restore the SP back to where it was when the "start arguments" API was called. This will need a more thought - at this time I'm unsure how "safe" these ideas are. For instance, what happens if multiple calls to "start arguments" are made without a corresponding "pop all" occurring? Can calls be nested, and if so what does that mean?

This whole general idea of using the stack for arguments will need quite a bit more thought, analysis, and discussion.

@stevesims
Copy link
Contributor Author

the idea of a "call C function" API, together with having "push argument" APIs to provide access to C functions in a Z80-friendly way actually can't work by just pushing arguments to the ADL stack (SPL)

the problem is that calling an API using RST.LIL 8 pushes a return address, and a processor mode indicator byte, to the SPL stack. the RET.L to return from that API is expecting to find those things on the stack to resume execution to the caller, so we can't just add extra stuff to the stack - that would break the return

in principle, APIs could still be created that allow C function calls to be made from Z80 mode code, but a different mechanism would need to be used to gather arguments and set up the stack for the function call

short-term it's probably simpler to not do this, and only have a "get C function" API, usable only by ADL mode code

longer term whilst a "call C function" API might be possible, it's probably not worth it. calling C functions is an advanced feature, and restricting that to code running in ADL mode seems reasonable.

@stevesims stevesims changed the title Get/Call function API Get function API Apr 14, 2025
@stevesims
Copy link
Contributor Author

#169 implements a mos_getfunction API. it currently returns the underlying C functions for raw SD card access (#162), the f_printf function that we can't easily wrap into a MOS-style API, and several other functions whose API calls use the IX register and thus are awkward to use from C code

@stevesims
Copy link
Contributor Author

Released in MOS 3.0

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

No branches or pull requests

1 participant