1 hour ago, pzembrod said:
In general, a function_id parameter goes against one of my design principles, which is not to needlessly join code execution paths, only to divide them apart again based on a parameter that comes from a constant
Don't forget the C16 has 32 bytes of memory for passing parameters, starting at address 02. The first 12 bytes are intended for passing volatile parameters, the next 12 are "safe" parameters (ie, not altered by the caller). The full description of the recommended mechanism for passing parameters is in the Programmer's Reference, "New API for the Commander X16"
I do tend to think of the C000 startup address as a "cold start" routine, though. That should be the one that you use the first time you boot the program and to set up the initial memory map and configure the software. I actually do agree that, generally speaking, it should be immune to the values in the registers or the ABI.
For specific applications, such as "open with a file" or "open and print", I would expect those to live in a jump table at the
end of the function ROM. Putting the jump table at the end allows you to expand the jump table by growing downward, toward the program code, and (of course) the program code can grow upward, toward the jump table.
Just remember that the last half-page or so should be copies of the KERNAL jump table and should trampoline over to the KERNAL routines, so code living in User land can consistently call KERNAL routines, no matter which bank is active. So you'd probably want to
end your function ROM jump table at $FEFF and grow it downward.
So...
C000: jump to the startup routine
C003: program signature: text with program name and version
C010 (approx): start of the program
FE00: empty space, followed by jump table
FEFF: End of Function ROM jump table
FF00: Start of KERNAL jump table and CPU vectors