Mail Archives: djgpp/1994/12/23/20:50:54
The approach described in the following two programs is an attempt to
allow 32 bit programs compiled with DJ's gcc dos port to work with 16 bit
libraries. This may only be of interest for users who wish to acquire
image data using frame grabbers or linear camera interfaces although
others may also find the following technique useful.
The basic technique here is to create a 16 bit program that will link with
libraries provided for some given hardware and pass parameters to a 32 bit
program using a system command. In effect, the 16 bit program becomes a
pseudo TSR but without the problems that are frequently encountered with
TSRs. The 32 bit program calls the required 16 bit function using the
appropriate dpmi function (_go32_dpmi_simulate_fcall_iret) and memory is
read using the dosmemget function. In a similar fashion, data could be
written using dosmemput.
By any standard this approach is kludgy but it is relatively simple and
foolproof and uses a minimun of specialized coding. Anyone wishing to make
improvements to the following code is encouraged to do so with a request to
share the improvements with the list. Special thanks are due to DJ and
Charles Sandmann for their expert help and suggestions.
/* The following program may be compiled with Turbo C or Microsoft C and will */
/* call a 32 bit (gcc) program and pass addresses for a buffer and function. */
/* Addresses are passed using command line arguments */
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#define SIZE 1728
long counter = 0;
unsigned char far *buffer;
void interrupt far function(void)
{
int i;
printf("16 bit function call count# %6d\n", counter);
counter++;
for (i = 0; i < SIZE; i++)
buffer[i] = (unsigned char) ((i + counter) & 0xFF);
return;
}
void main(void)
{
int ret;
unsigned long bufaddr = (unsigned long) buffer;
void (interrupt far *func_point) (void) = function;
char command_line[120], temp[40];
buffer = (unsigned char far *) malloc(SIZE);
bufaddr = (16L * (long) FP_SEG(buffer)) + (long) FP_OFF(buffer);
strcpy(command_line, "gccprog ");
ultoa(bufaddr, temp, 10);
sprintf(temp, "%lu", bufaddr);
strcat(command_line, " ");
strcat(command_line, temp);
itoa((int) FP_SEG(func_point), temp, 10);
strcat(command_line, " ");
strcat(command_line, temp);
itoa((int) FP_OFF(func_point), temp, 10);
strcat(command_line, " ");
strcat(command_line, temp);
printf("%s\n", command_line);
ret = system(command_line);
printf("ret = %d\n", ret);
exit(ret);
}
/***************************** End of 16 bit Program *************************/
/* This is a 32 bit program and must have the name gccprog.exe after stubbing */
/* It is called by a 16 bit C program and in turn calls a 16 bit function in */
/* the original 16 bit program. Command line arguments to the 32 bit program */
/* are used to pass the addresses of a buffer and the 16 bit function. */
#include <stdio.h>
#include <stdlib.h>
#include <dpmi.h>
#include <go32.h>
#define MAXSIZE 1728
void main(int argc, char *argv[])
{
int dbaddr, i, j;
unsigned short seg, off;
_go32_dpmi_registers regs;
unsigned char buffer[MAXSIZE];
if (argc != 4)
{
fprintf(stderr, "Fatal Error: Wrong number of command line args!\n");
exit(1);
}
dbaddr = atoi(argv[1]);
memset(®s, 0, sizeof(regs)); /* Initialize regs */
seg = regs.x.cs = (u_short) atoi(argv[2]);
off = regs.x.ip = (u_short) atoi(argv[3]);
for (j = 0; j < 10; j++) /* Call 16 bit function 10 times */
{
fprintf(stderr, "DOS Call Executing: ");
_go32_dpmi_simulate_fcall_iret(®s);
dosmemget(dbaddr, MAXSIZE, buffer);
for (i = 0; i < 15; i++)
printf("gcc: %d\n", (int) buffer[i]);
}
exit(0);
}
- Raw text -