80287 vs. Interactive 386ix

dkelly dkelly at npiatl.UUCP
Wed Oct 11 13:47:25 AEST 1989

I am posting this for lef at dogwood.atl.ga.us

I had what sounds like same problem with a couple of our 386 systems
(With 287).  We also had several systems from the same vendor all
configured alike which worked fine.  I eventually tracked the problem
down to a bit in CMOS.  Byte 0x14 of cmos should be a 0x43 for a 80387
and a 0x41 for 80287.  Nobody sets these bits so it is just random
chance if any 287 will work correctly or not.  The following program
will check with the operating system to determine the co-processor
type.  If you have this problem then it will say you have a 387
instead of a 287.  The reason for the bad clock hands is that a 387
has hardware Cosine and Sine and the library routines try to use the
instructions if it thinks you have one.  All Sines and Cosines will
return the input value without an error if this is your problem.  
The second program will attempt to patch the cmos to the correct
co-processor type (if you run it as super-user).  You will need to
bring you system down and re-run you manufacture setup program to
re-calculate the checksum after using the cramfix because I don't feel
like looking up the checksum algorithm for a one-time patch.  When you
reboot unix everything should work correctly.
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysi86.h>
#include <sys/fp.h>

	int i;

	sysi86(SI86FPHW, &i);
	switch (i) {
	case FP_NO:
		printf("No floating point supported at all\n");
	case FP_SW:
		printf("Floating point emulation in software\n");
	case FP_287:
		printf("Floating point done by 80287\n");
	case FP_387:
		printf("Floating point done by 80387\n");
		printf("ERROR!  Floating point value none of thoses listed\n");
 * cramfix.c : patch cmos memory on a 386/AT clone under Interactive 386/ix
 *           : This program patches byte 0x14 to 0x41 to indicate that
 *           : the math co-processor is an 80287.  
 *           : For an 80387 the value should be 0x43.

#include <stdio.h>
#include <sys/cram.h>
#include <fcntl.h>
#include <errno.h>

  struct {
    unsigned char adrs;
    unsigned char value;
    } cram_arg;
  register int cmosfile;

  cmosfile = open("/dev/cram", O_RDWR);
  if (cmosfile < 0) {
    fprintf(stderr, "Can't open /dev/cram driver, errno = %d\n", errno);
  cram_arg.adrs = 0x14;
  cram_arg.value = 0x41;
  ioctl(cmosfile, CMOSWRITE, &cram_arg);

	Lawrence Freil	       		    Usenet/DDN:lef at dogwood.atl.ga.us
        National Science Center Foundation  Phone:(404)-828-8459
	P.O. Box 1648
	Augusta, Ga 30903

More information about the Comp.unix.i386 mailing list