***  1.0  ********************************************************************
The following is an extensive explanation of changes to the X11R4
sources in order to run in on SCO UNIX System V/386 3.2.

The starting point was patchlevel 18 plus changes done for ix386 by
roell@lan.informatik.tu-muenchen.de. It was not too difficut to modify
for SCO. Tom did most of the work.
 
The compiler I used was gcc. The SCO development system contains two
compilers, cc which is an ANSIish Microsoft C 5.1 port and rcc which
is the AT&T pcc-based compiler. I'll discuss the other compiler
attempts below.

There has been quite a lot of press about binary compatibility among
the System V/386 3.2 Unixes. Let's set the record straight that this
piece of software compiled for SCO will only run on SCO Unix. (Not to
mention software that uses some of the Xenix or security system
calls).
 
We have a handle to the console. To move into graphics mode an
KDSETMODE ioctl is sent to the console. How is screen memory mapped.
There are three ioctl's documented in the System Administrators
Reference and release notes that claim to do this.
    KDMAPDISP - always causes the kernel to panic.
    MAPCONS   - maps the screen memory, the size of which is defined by
                the mode we are in. Must switch to a graphics mode before
                or else we won't map all the memory.
    MAP_CLASS - maps the screen memory and IO port based on the kernel
                configuration in /etc/conf/pack.d/cn/class.h. The argument
                to the ioctl is a string describing the type of device. I
                used "SVGA" because the screen must map into 128K of CPU
              addressable memory and MAPCONS only maps 64K. MAP_CLASS
              only works on 3.2.1 and above. If this ioctl fails I
              revert to MAPCONS.
./server/ddx/at386/vga/vga.c

I had to modify /boot to even get the machine to boot. It seems the
VRAM's have some ROM pointed to by int 6d. The old /boot does not move
the 6d vector segment from E000 to C000 like it does the other video
vectors (10, 1f, 43).  There is OLIVETTI code for this so I assume the
cards would work on those architectures. I have a Compaq.

Had other problems with my ET4000 card which is an Orchid Pro Designer
II w/1M. Whenever the server switched modes the VGA registers would
get hosed. There must be some compatibility problem with the vga
driver and these cards. Don't know if it effects all ET4000 cards or
not. Since one of the server's last duties is to switch to text mode,
I had to hand reset the VGA registers in ./server/ddx/at386/screen.c.

sin() and cos() seemed to screw up the stack. This seems to be a known
bug with _ftol() that is fixed in the next rev of the DevSys.  In
./lib/X/XlibInt.c I have redefined _ftol() and it either fixes the
problem or moves it somewhere else.

I have been unsuccessful at creating shared libraries. This is a known
problem with the SCO DevSys 3.2, one which is fixed in the SCO DevSys
3.2v2.0 -- The Sequel.

The build was done using 'make BOOTSTRAPCFLAGS=-DSCO -DSYSV386 -DSYSV" World'.

Compiler problems --
cc is picky about function prototypes and declarations matching. To avoid
these problems I would specify -DNeedFunctionPrototypes=0 everywhere.

cc has resource limitations. I had to simplify one compilicated
expression in ./lib/X/XPutImage.c. It also had a problem with a huge
macro in ./server/ddx/at386/vga/vgaGlyph.c. Splitting the #define up
fixed that.  Identifiers are truncated to 32 characters. This caused
problems with the two macros sz_xMbufGetMultiBufferAttributesRequest
and sz_xMbufGetMultiBufferAttributesReply defined in
./extensions/include/multibufst.h as well as some interdependent
identifiers elsewhere in ./extensions/include/multibuf.h,
./extensions/lib/XMultibuf.c and ./extensions/server/multibuf.c. This
also caused the compiler to generate the message
      UNKNOWN ERROR: Contact Microsoft Technical Support

In the file ./lib/Xt/Selection.c, cc gave me the error
      static function 'HandleSelectionReplies' not found
This function is first declared static within the scope of another
function and then defined, as static, later in the same file. So I
rearranged some functions so that it is defined before it is invoked.
Then I ran into another problem with another function that was defined
as static, but later it generated an external reference, one which
could never be resolved. By playing musical functions I was able to
find a function ordering that produced a usable object file.

The GNU assembly routines for I/O ports did not hang well with cc. SCO
has built-in functions inp, outp and outpw which I used to simulate
inb, outb and outw in place of the GNU inline assembly in
./server/ddx/at386/compiler.h. These functions are declared intrinsic
using #pragma so the compiler will generate inline in's and out's,
i.e. no function calls.
 
I have not tried rcc on this code and I don't think I will. It does not
produce very good code.

That leaves us with gcc, which is capable of compiling all the
sources. Be careful to specify the -fpcc-struct-return switch or
else you'll produce incompatible code with SCO's libdbm.a.

I've seen one instances where the three compilers produce mutually
incompatible code.

./server/ddx/mfb/mfb.h defines the struct mfbPrivGC which contains 3
unsigned char followed by two unsigned bitfields, each one bit,
followed by a pointer and other stuff.

      struct bad_news {
          unsigned char a;
          unsigned char b;
          unsigned char c;
          unsigned      x:1;
          unsigned      y:1;
          char *        p;
      };

offsets generated          cc  rcc gcc
        unsigned char a    0   0   0
        unsigned char b    1   1   1
        unsigned char c    2   2   2
        unsigned      x:1  4   3   3
        unsigned      y:1  4   3   3
        char *        p    8   4   4
 
Not a good situation when you compile different files with different
compilers.

December 17, 1990
----------------

Jim Kelly
Microsoft Corporation
uunet!microsoft!jimke

***  1.1a  *******************************************************************
  
Downloaded X386 1.1. Many of the SCO patches are now included with this
version. But the new capabilities of 1.1 have also introduced new
incompatiblities.

1.1 has additional TCP/IP support for System V/386 Unixes. Each vendor
has decided to support the Berkeley socket interface each in their own
twisted ways. Differences not only crop up with the kernel interface
but also which include files contain the appropriate definitions.

The SCO kernel interface is the non-STREAMS driver /dev/socksys. There
is a convenient library libsocket.a with all the Berkeley networking
and utility functions. Problem is it is not a STREAMS driver and
it cannot handle the I_NREAD ioctl. This driver will accept FIONREAD.
In ./mit/lib/X/Xlibos.h, BytesReadable is defined in terms of one of
these two ioctls. Which one should SCO use? The answer is both. When
you want BytesReadable from a LOCALCONN you need to use I_NREAD. From
a TCPCONN you use FIONREAD. So the #define BytesReadable is replaced
by a function in ./mit/lib/X/XlibInt.c, which will try I_NREAD and
then FIONREAD if that fails.
 
The differences in #include locations and contents played havoc with
source files. For the SCO networking dev sys, the major include files
are located at <sys/types.h>, <sys/socket.h>, <netinet/in.h> and
<netdb.h>. There is also a lack of a <sys/uio.h> or <sys/bsdtypes.h>.
 
I've gotten my hands on the next rev of SCO's development system, 3.2.2.
They have fixed the broken _ftol() so I don't need mine anymore. It
is included, #ifdef'ed out.
 
With the new TCP/IP support I have found yet another problem, this
time with the TCP/IP dev sys. I have an early version 1.0.0. The
function inet_addr() seems to be corrupting some of the non-disposable
registers.  However I couldn't reproduce this behavior in a standalone
program.  For this I went ahead and replaced inet_addr() in libsocket.a
using 'ar' with my own simple-minded function.
 
unsigned long inet_addr(name)
char *name;
{
    unsigned d0, d1, d2, d3;

    if (sscanf(name, "%d.%d.%d.%d", &d3, &d2, &d1, &d0) != 4)
	return 0xffffffff;

    return (d0<<24)|(d1<<16)|(d2<<8)|(d3);
}
 
More incompatibilties. Thomas has beefed up his select() via poll()
emulation routine, ./mit/server/ddx/at386/bsdemul/select.c. POLLPRI is
added to the events mask of all the fd's. For whatever reason this
causes /dev/tty and /dev/tty[12]a (serial port) to induce poll to fail
with EINVAL. The STREAMS connection /dev/ptmx and the TCP connection
/dev/socksys don't mind as much.
 
The ioctl to read the keyboard type, KDGKBTYPE, is constantly returning
0 which is not valid. For SCO the kbdtype will be set as if you had
a KB_101 type keyboard.
 
Additonal functionallity in ./mit/server/ddx/at386/keyboard.c forces
the addition of two additional includes to ./mit/server/ddx/at386/sco.h,
<sys/emap.h> and <sys/keyboard.h>.

Chicken and egg problem. mkfontdir is compiled with the shared Xmu
library, and cannot be used until the library is installed. Yet
mkfontdir is used in the build and fails to execute. The Imakefile was
modified to use the static version of Xmu to make mkfontdir.
 
Modifications were made to ./mit/clients/xterm/main.c to support SCO's
job control facilities.

Xdm is removed from the build. To compile and use this you will need to
translate getpwent() type calls into SCO's getprpwent() calls. These
access the Trusted Computing Base (TCB) instead of /etc/passwd or
/etc/shadow. This client also requires crypt() which does not come
in the regular dev sys box.
 
For the configuaration file at386.cf, gcc should contain anther command
line defined -DNO_PROTOTYPE. This prevents some prototype clashes.
Another prototype clash is avoided by defining _SVID before including
<string.h> in ./mit/include/Xos.h.
 
February 24, 1991
-----------------
 
Jim Kelly
Microsoft Corporation
uunet!microsoft!jimke
