Date: Fri, 23 Dec 1994 20:23:27 -0500 (EST) From: john miller To: mail djgpp Cc: john hoeschele Subject: A kludge for using 16 bit libraries with djgpp 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 #include #include #include #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 #include #include #include #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); }