Closed afarlie closed 3 years ago
Hello @afarlie,
The pascal 'modifier' as far as I can understand changes the function prolog/epilog generation, because "pascal" functions clean up the stack in the called funciton, whereas ccdecl leave this to the caller.
Yes, the toolchain has already supported a stdcall
calling convention for some time. This is slightly different from a "Pascal" calling convention (in stdcall
, the parameters are pushed in reverse order, like in cdecl
), but is close enough for most purposes.
There is also a regparmcall
calling convention, where some function arguments are passed and accepted in registers.
By the way, if you wish, you can try installing the pre-compiled packages for the toolchain --- there are Ubuntu packages available, as well as packages for MS-DOS (or FreeDOS). The command
ia16-elf-gcc -v --help
will give a list of command line options --- including IA-16-specific options --- that the GCC driver supports. If you install the Ubuntu packages you should also be able to access the man page via
man ia16-elf-gcc
and the info documentation (which is more detailed --- it discusses syntax extensions, usages, etc.) via
info /usr/ia16-elf/info/gcc.info
Let me know if you have any problems installing the toolchain.
Thank you!
You are correct that stdcall is the reverse of pascal in terms of how it places parameters on the stack, and that a 16 bit stdcall would suffice at present (for code written directly with the compiler, or for which source is available for recompilation.)
My reason for suggesting "far pascal" support be included (.. when someone writes the patch :lol: ) was because, in 16 bit DOS /Windows 3.x era, a number of external libraries (including a fair proportion of the Win16 API/ABI) used "far pascal" quite extensively, and for code written in gcc-16 to be unable to make use of code in such libraries, and API would place it at a disadvanatge. Support for 'far pascal' would also eventually be needed if someone figured out generation of the New Executable binary format, given that as I recall, certain entry points for New Executables, assume 'pascal' over '_ccdecl' conventions. (Side note: It seems at present that gcc-16 is essentially targeting "real" mode. )
Limiting the complier to a 16bit 'stdcall' (or ccdecl), is understandable at this stage of development though, I appreciate this isn't a priority hence I agree with the closure of this issue.
Hello @afarlie,
a number of external libraries (including a fair proportion of the Win16 API/ABI) used "far pascal" quite extensively, and for code written in gcc-16 to be unable to make use of code in such libraries, and API would place it at a disadvanatge.
Well, the GCC IA-16 toolchain also happens to already have support for far functions. You can declare and define functions which are both far and use the stdcall
calling convention --- when using the "small" memory model (-mcmodel=small
) --- like so:
__attribute__ ((stdcall)) unsigned __far f (unsigned x);
__attribute__ ((stdcall)) unsigned __far
g (unsigned x)
{
return f (x) + 1;
}
(The main limitation of the far function facility is that, for now, the stack (%ss:%sp
) is assumed to be in the same segment as the program's global data space. This is another issue that I had been trying to work on.)
Thank you!
Hello @afarlie,
I would suggest again to install the GCC IA-16 toolchain and reading the documentation to see what features it currently has.
Thank you!
@tkchia Can I ask you something about this? I'm trying to build the example source code in the VBE/AI SDK. It has the far pascal
keywords sprinkled throughout the code, and I can't figure out how to rewrite it so that gcc-ia16 can compile it. I'm trying to compile PLAY.C
as a starting point. How should such far pointer declarations be rewritten? I couldn't get the examples that you posted further above to work.
A copy of the SDK can be downloaded here:
(I've scanned the ZIP file on Virustotal.com, and out of 62 virus scanners, one flagged the file as potentially malicious. It's therefore most likely a false positive.)
If you prefer I open a separate issue for this, let me know.
Thank you for your help! :slightly_smiling_face:
Hello @volkertb,
I couldn't get the examples that you posted further above to work.
You need to remember to pass the -mcmodel=small
switch.
With newer versions of gcc-ia16
(after Feb 2021), you can also say just __stdcall
instead of __attribute__ ((stdcall))
.
I'm trying to compile
PLAY.C
as a starting point. How should such far pointer declarations be rewritten?
Unfortunately, as I said, the pascal
calling convention is not yet directly supported. For now, if you want to use gcc-ia16
to declare pointers to far pascal
functions, you will probably need to use stdcall
and reverse the argument order. (Yes, admittedly, this is not very nice.) So instead of
void (pascal far *wsApplRSyncCB ) ( int, void far *, long, long ); //rec
you will need to say something like
void (__stdcall __far *wsApplRSyncCB ) (long, long, void __far *, int);
(I suspect that the the callback functions will also be called with %ds
and %ss
pointing outside your programs' data segment. So, by right, you may also need to add __attribute__ ((no_assume_ds_data, no_assume_ss_data))
too. Under Open Watcom this will probably be __loadds __declspec (farss)
.)
Anyway, I am trying to see if I can get gcc-ia16
to directly support pascal
functions. One wrinkle is that GCC's middle-end internals pretty much assume that arguments are always passed in the same order within a program. This makes it somewhat hard to have a pascal
, that co-exists with the other function calling conventions cdecl
, stdcall
, and regparmcall
.
Thank you!
By the way, if it makes things easier for you: I got permission from someone at VESA to publish the VBE/AI SDK sources to GitHub. They consider it public domain now. See https://github.com/volkertb/vbe-ai-sdk (I left out one non-crucial folder that contained some stuff copyrighted by a third party.)
I guess if it proves too much of a hassle to implement far pascal
support in gcc-ia16
, we can just modify (or fork) the SDK sources to use the keywords you mentioned instead. It would be preferable if we could maintain a single codebase that would work with all popular DOS C compilers, though.
Hello @volkertb,
Thanks! Perhaps, as a start, we can instead first try to get the SDK working with the Open Watcom compiler --- since OW already supports both __far
and __pascal
, and it is already open source (even if it is not considered Debian-free). One of my goals for gcc-ia16
is to get it to be compatible with OW as far as feasible.
I am not sure which particular compiler(s) the SDK was originally meant to work with. For the moment, it does not build cleanly under OW yet.
Thank you!
Apparently, it was Borland C++.
the far
and pascal
keywords are documented in the manual: http://www.bitsavers.org/pdf/borland/borland_C++/Borland_C++_Version_3.1_Programmers_Guide_1992.pdf
But you indeed have a point: it would have been nice if this had been clarified in the VBE/AI 1.0 Specification document. Or even better, if they had included example code for other popular DOS C/C++ compilers of the day (Watcom, Microsoft) as well.
Having multiple mutally incompatible assembler dialects was bad enough. Now mutually incompatible C/C++ extensions/macros as well? :confused:
But yeah, making the code compile with Open Watcom would indeed be a sensible first step. It would allow it to be built with one open source compiler, and soon two, once you've added this compatibility to gcc-ia16
. :slightly_smiling_face:
Do you need any help porting the code to Open Watcom? You are obviously a far more skilled C/C++ developer than I am, but at the very least, I can act as your rubber duck when you run into issues. It would be educational to me as well. :duck:
Anyway, I created an issue for this: https://github.com/volkertb/vbe-ai-sdk/issues/1
By the way, you might want to update your fork. I added the FM timbres that I left out of the SDK earlier, since I received clarification from The Fat Man on the new terms of use of his FM timbres. They're free to use now, as long as people give him credit in the software they include it in. :slightly_smiling_face: I also added a LICENSE.md file.
@tkchia Have you seen this reply in the FreeDOS Developers mailing list?
as the FreeDOS kernel uses "far pascal" as well, I looked it up.
probably
define far __far
is all you need to "port" the code to WatcomC
Tom
He didn't explicitly mention it, but I assume that a #define pascal __pascal
would be required too.
Perhaps you already tried adding such defines, but Open Watcom still refuses to compile the code for some other reason?
This would be a very simple solution if it worked, though. And we could then enclose them inside #ifndef
blocks to retain compatibility with Borland C++. :slightly_smiling_face:
Hello @volkertb,
You are obviously a far more skilled C/C++ developer than I am, but at the very least, I can act as your rubber duck when you run into issues. It would be educational to me as well. 🦆
Haha, thanks. 🙂🦆🧸 I will most probably need your help on the VBE audio interface standard itself, since I am not so familiar with it (or with VBE, for that matter).
I will continue the discussion at the new issue thread you created (https://github.com/volkertb/vbe-ai-sdk/issues/1).
By the way, you might want to update your fork.
Got it. Thanks!
Hello @volkertb (and @afarlie),
I have come up with an initial implementation of the pascal
calling convention for gcc-ia16
(the code is at the branch tkchia/pascal
).
It is currently usable, but should be considered experimental --- I need to do further tests on it to make sure that it works exactly as it should.
Thank you!
In some code (typically 16 bit Windows 3.x) code, I've seen references to 'pascal' modifiers.
The pascal 'modifier' as far as I can understand changes the function prolog/epilog generation, because "pascal" functions clean up the stack in the called funciton, whereas ccdecl leave this to the caller.
https://jdebp.eu/FGA/function-calling-conventions.html has some more on this.
See also a section in - https://www.nasm.us/doc/nasmdoc8.html about writing 16 bit code.
Apologies if this is something that's already supported.