I'm using Turbo C and Turbo Assembler 2.01 to write a C wrapper around the XMS interface so I can use XMS memory in real mode, large model. I've started by writing the following:
#include <dos.h>
void (*xms_driver_interface)();
/*
Query whether there is an XMS driver available.
Returns 1 if XMS memory is available.
*/
int xms_available()
{
union REGS inregs, outregs;
inregs.x.ax = 0x4300u;
int86(0x2Fu, &inregs, &outregs);
return !!(outregs.h.al & 0x80u);
}
/*
Query whether there is an XMS driver available,
and populate xms_driver_interface if so.
Returns 1 if XMS memory is available and ready.
*/
int xms_init()
{
union REGS inregs, outregs;
struct SREGS sregs;
int success;
inregs.x.ax = 0x4310u;
int86x(0x2Fu, &inregs, &outregs, &sregs);
success = outregs.h.al;
if (!success) return 0;
xms_driver_interface = (void (*)())((((unsigned long int)sregs.es) << 4) + ((unsigned long int)outregs.x.bx));
return 1;
}
unsigned int xms_get_version_number()
{
_AX = 0x0000;
asm call [xms_driver_interface]
return _AX;
}
When Turbo C reaches the line asm call [xms_driver_interface], it backs up and says it's Restarting compile using assembly, and switches to a two stage process where TCC compiles xms.c and TASM assembles it. TASM aborts with the error xms.ASM(111) Forward reference needs override, which seems like the output of the Turbo tools aren't mutually compatible because the generated xms.ASM is referring to _xms_driver_interface before declaring it, requiring two passes.
Is there a way I can tell Turbo Assembler through Turbo C to use multiple passes on assembling?
I know I can pass /m2 to TASM directly, but when I split up my compilation process into separate phases it doesn't link correctly and it turns into a big mess.
Or is there some other method I should use to invoke my calculated pointer?
#pragma inlineis equivalent to thetcc -Boption if you happen to be compiling on the command line or via a MAKEFILE. – smitelli Sep 22 '20 at 16:14