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?