Hi there! I am Drew DeVault, the primary maintainer of KnightOS:

https://github.com/KnightOS/kernel

It's a z80 operating system that runs on TI calculators. Currently, both
the kernel and userspace are written entirely in assembly. We would like
to provide support for C in userspace for the upcoming release of kernel
0.7.0, and we would like to use SDCC for this purpose. However, we have
some difficulty.

KnightOS relocates programs at runtime as they are executing, by means
of these macros:

        kcall(addr)             ; RST 0x08 \ CALL addr
        kjp(addr)               ; RST 0x08 \ JP addr
        kld(register, addr)     ; RST 0x08 \ LD register, addr

The restart at 0x08 relocates these by modifying the code to read as such:

        NOP \ CALL absolute_address
        NOP \ JP absolute_address
        NOP \ LD register, absolute_address

Also supported is kjp(cc, addr) and kcall(cc, addr). Of course, this
only affects references that live inside the running executable.

The ideal solution to this problem would be for SDCC to be aware of this
paradigm and to directly emit compliant assembly. Since SDCC cannot
currently do that (or at least we don't think it can), we are
considering some alternative options. The one we currently have in mind
is processing the assembly source before the assembler gets to it, but
this has the potential issue of screwing up relative jumps (which can
only jump a maximum of 127 bytes in either direction). Manipulating
assembly source like this is also just a crappy solution in general, so
we'd like to find something else.

Do you folks know of a good way we can solve this problem? Is this
something SDCC could be extended to support, or are we better off
figuring out an external solution?

On another note, we also have an ABI that is primarily designed for
assembly users. This means that it assumes the caller is responsible for
managing registers how they please and expects the caller to load
arguments into specific registers that vary depending on the syscall
being made. See the reference documentation for details:

http://www.knightos.org/documentation/reference/system.html

We can work around this problem by writing verbose C shims around our
syscalls, like so:

inline void fast_copy(SCREEN *screen) __naked {
        __asm
        PUSH IY
        INC SP
        INC SP
        POP IY
        PUSH IY
        CALL FASTCOPY ; Expects IY to be pointer to display memory
        DEC SP
        DEC SP
        POP IY
        __endasm;
        screen; /* Squelch warning */
}

Is there a more appropriate mechanism for doing this? Ideally we could
mention to the __asm directive which registers we plan on clobbering and
SDCC would figure out the ideal way to work this into the surrounding
code. Please note that we may not be able to use the new __asm(...)
format, because we need to preprocess it to resolve FASTCOPY.

One last question: with compilers like gcc, the target can be specified
at configure time, which will set up good defaults for target
architecture and a crt0 and ABI considerations and such. Can we do
something similar with SDCC to avoid asking users to write long
incantations into their makefiles?

Thanks for reading my long email, I appreciate it!

--
Drew DeVault

------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to