Date: Mon, 10 Feb 92 21:15 +1100 From: Bill Metzenthen Subject: Bug fix for bdos() To: djgpp AT sun DOT soe DOT clarkson DOT edu, dj AT ctron DOT com Status: O Thanks to DJ Delorie for DJGPP. I have downloaded version 1.05 and have it working on my machine. I have a few concrete suggestions of ways to make this great program a little better... Here is the first one: There is a bug in the bdos() function of the DJGPP library. This function returns -1 if the carry flag is set on return from DOS, but not all DOS functions correctly set the carry flag. I came upon this bug when attempting to compile BEAV, which uses bdos(7,0,0) to fetch a character from the keyboard. The problem is that under MS-DOS 5.0, DOS function 0x07 appears to ALWAYS return with the carry flag set! As near as I can determine, no DOS function below 0x38 can be relied upon to correctly set the carry flag. Therefore there is no point in checking the carry flag of such functions. Extensions to DOS may have exceptions to this rule, an example is the Phar Lap DOS extender which is accessed via function 0x25. Similar comments apply to bdosptr(), which is coded identically to to bdos() in the current djgpp distribution (it works!). The following diffs are my suggested modifications to the distributed files: changes to the libsrc/c/dos directory: ---------------------------- snip snip --------------------------- diff -c old/bdos.c ./bdos.c *** old/bdos.c Thu Mar 7 12:04:42 1991 --- ./bdos.c Tue Feb 11 07:38:44 1992 *************** *** 1,6 **** --- 1,16 ---- #include #include + /* + Modified 10th Feb 1992 by W. Metzenthen. + + bdos() should be useable for the following functions: + 0x00..0x08 0x0b 0x0d 0x0e 0x18 0x19 0x1d 0x1e 0x20 0x26 0x2e + 0x30 0x31 0x33 0x4c 0x4d 0x4f 0x54 0x58 0x5f 0x61 + Of these, only functions 0x4f 0x58 and 0x5f use the carry flag. + + Note that bdos() is almost identical to bdosptr(). + */ bdos(int func, unsigned dx, unsigned al) { union REGS r; *************** *** 8,14 **** r.h.ah = func; r.h.al = al; int86(0x21, &r, &r); ! if (r.x.cflag) { errno = r.x.ax; return -1; --- 18,25 ---- r.h.ah = func; r.h.al = al; int86(0x21, &r, &r); ! if ( (r.x.cflag) && ! !((func < 0x38) || (func == 0x4d) || (func == 0x54) || (func == 0x61)) ) { errno = r.x.ax; return -1; diff -c old/bdosptr.c ./bdosptr.c *** old/bdosptr.c Thu Mar 7 12:04:42 1991 --- ./bdosptr.c Tue Feb 11 07:38:58 1992 *************** *** 1,6 **** --- 1,16 ---- #include #include + /* + Modified 10th Feb 1992 by W. Metzenthen. + + bdosptr() should be useable for the following functions: + 0x09 0x0a 0x0c(some) 0x0f..0x17 0x1a 0x21..0x25 + 0x39 0x3a 0x3b 0x3d 0x41 0x43 0x5d 0x5e + Of these, only functions above 0x37 use the carry flag. + + Note that bdos() is almost identical to bdosptr(). + */ bdosptr(int func, void *dx, unsigned al) { union REGS r; *************** *** 8,14 **** r.h.ah = func; r.h.al = al; int86(0x21, &r, &r); ! if (r.x.cflag) { errno = r.x.ax; return -1; --- 18,24 ---- r.h.ah = func; r.h.al = al; int86(0x21, &r, &r); ! if ( (r.x.cflag) && (func >= 0x38) ) { errno = r.x.ax; return -1; ---------------------------- snip snip --------------------------- changes to the docs directory: ---------------------------- snip snip --------------------------- diff -c old/funcs.doc ./funcs.doc *** old/funcs.doc Mon Jul 22 02:12:46 1991 --- ./funcs.doc Tue Feb 11 07:31:16 1992 *************** *** 629,644 **** unsigned char dl, dh; unsigned short upper_dx; } h; }; struct SREGS {unsigned short cs, ds, es, fs, gs, ss; }; /* system calls */ union REGS r,s; /* declare r etc for interrupts to read the PC registers from and/or put them back into */ int f; unsigned i,j; void* p; struct SREGS t; ! bdos(f,i,j) /* {int}: registers: DS = i, AL = j; call DOS function f */ ! bdos(f,p,j) /* ditto but registers DS & AL = pointer p */ ! int86(f,&r,&s) /* {int}: registers = r; call 80x86 interrupt f; s = regs */ ! int86x(f,&r,&s,&t) /* {int} ditto, but t = results */ ! intdos(&r,&s) /* {int}: registers = r; call 80x86 interrupt 21hex; s = regs */ ! intdosx(&r,&s,&t) /* {int} ditto, but t = results */ ======================================== ERLANG.H [A SORT OF RANDOM NUMBER] --- 629,651 ---- unsigned char dl, dh; unsigned short upper_dx; } h; }; struct SREGS {unsigned short cs, ds, es, fs, gs, ss; }; + go32 make intelligent translations of pointers. e.g. if a DOS function + requires a pointer in ds:dx then go32 looks in edx for a pointer, therefore + to use DOS function 9 (display string) one might use bdosptr(9,"string$",0) + or int86(0x21,&r,&s) with r.x.dx = "string$"; + /* system calls */ union REGS r,s; /* declare r etc for interrupts to read the PC registers from and/or put them back into */ int f; unsigned i,j; void* p; struct SREGS t; ! bdos(f,i,j) /* {int}: registers: DX = i, AL = j; call DOS function f */ ! bdosptr(f,&p,j) /* ditto but registers DS:DX = pointer p */ ! int86(f,&r,&s) /* {int}: registers = r; call 80x86 interrupt f; ! s = return regs */ ! int86x(f,&r,&s,&t) /* {int} ditto, but seg registers = t ignored */ ! intdos(&r,&s) /* {int}: registers = r; call 80x86 interrupt 21hex; ! s = return regs */ ! intdosx(&r,&s,&t) /* {int} ditto, but t = seg registers ignored */ ======================================== ERLANG.H [A SORT OF RANDOM NUMBER] diff -c old/internal.doc ./internal.doc *** old/internal.doc Sat Mar 16 14:01:00 1991 --- ./internal.doc Tue Feb 11 03:27:56 1992 *************** *** 270,276 **** 2: open 3: fstat 4: gettimeofday ! 5: settimeofdat 6: stat 7: system --- 270,276 ---- 2: open 3: fstat 4: gettimeofday ! 5: settimeofday 6: stat 7: system ---------------------------- snip snip --------------------------- Bill Metzenthen