[comp.unix.sysv386] X386 patches for SCO Unix

jimke@microsoft.UUCP (Jim KELLY) (12/18/90)

At the end of this post is a patch to Thomas Roell's X386 server that will
let you build and run X386 on SCO Unix System V/386 3.2. Sorry for the
large post but I have no publically available node to put this on.

To install this you need the X11R4 sources up to fix-18 PLUS Thomas Roell's
November 8th X386 sources/patches. Follow all the instructions given to
setup the ix386 version. Apply the patch below. I have only built this
using gcc. Check the README.SCO file for problems I had with other
compilers.

The SCO version has some minor flaws at present. But then again the OS
and development system do too.

-- I have only tested this with a Microsoft serial mouse. The serial port
   usually resides at /dev/tty1a so update the Xconfig file before you
   start the server. Remember to set up your display/card paramters too.

-- The screen may go blank after stopping the server. Hit enter a couple
   times or run 'clear'.

-- If you have an ET3000 you will need an OS with version 3.2.1 or greater.
   ET4000 should be OK with 3.2.0 but I haven't tested it.

-- The mouse buttons are flip-flopped. Use xmodmap to fix this.

-- You cannot switch to a different virtual terminal using <Alt><F?> or
   any other key combination.

-- No shared library support unless you have the newest DevSys, 3.2.2.

-- The CAPS and NUM lock work but don't light up.

-- The hot key combination <Ctrl><Alt><Bksp> will kill the server with no
   questions asked.

-- Check mit/README.SCO for more details.

Jim Kelly
uunet!microsoft!jimke

-------- Cut Me --------
*** mit/README.SCO-	Sun Dec 16 22:06:40 1990
--- mit/README.SCO	Mon Dec 17 00:10:32 1990
***************
*** 0 ****
--- 1,198 ----
+ 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. roell did most of the work. roell uses the terminology
+ STREAMS pipes for local IPC, but the server still uses the STREAMS
+ psuedo-ttys (ptm/pts) rather than the pipe driver (sp).
+ 
+ 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.
+ 
+ I added an SCO specific file
+     ./server/ddx/at386/sco.h
+ 
+ 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).
+ 
+ First of all we must access the system console so that we can map
+ screen memory into our virtual space, ring the bell and play with the
+ lights on the keyboard. We must also map I/O ports because they are
+ just as protected. To open the system console you open your tty.
+ Typically you open "/dev/tty" which gives you a handle to your
+ controlling tty. The server has a problem with this becuase before
+ execing the server, xinit calls setpgrp() which loses the controlling
+ tty. Opening "/dev/tty" fails. Now in the server I get my real tty
+ name via ttyname() call setpgrp() then open the tty.
+ ./clients/xinit/xinit.c
+ ./server/ddx/at386/screen.c
+ 
+ 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. But if your VGA driver needs to address
+ 		> 64K (et3000), then you must have 3.2.1 or greater.
+ ./server/ddx/at386/vga/vga.c
+ 
+ KDMKTONE is not supported. You need KIOCSOUND to ring the bell. It
+ takes an explicit call to both start and stop the bell. Because we
+ need < second precision and to avoid nap(), I used select() and
+ specified zero file descriptors.
+ ./server/ddx/at386/keyboard.c
+ 
+ I tried adding a VGA driver for my SuperVGA card, Video7 VRAM. There is a
+ limitation with this card that won't allow it to work with the Nov 8
+ version of the server. You cannot have separate read and write pages.
+ The bitblt code sets the read page, then the write page and then
+ does the blite. With the VRAM you would have to reset the page before each
+ set of read/writes. Since this would take minor surgury on the server I
+ just went out and bought an ET4000 card.
+ 
+ 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.
+ 
+ Had a problem with large amounts of data thrugh the IPC for the
+ STREAMSCONN server. This was a bug in _XWriteV in ./lib/X/XlibInt.c.
+ The routine was not simulating writev quite correctly. The function
+ has two nested loops. If the "write" inside the inner loop failed, it
+ only broke out of the inner loop. It should return immediately. I
+ guess it is possbile for one "write" to fail and later "write" to
+ succeed within the same function.  Data gets written twice or not at
+ all. I submitted a bug report to expo for this.
+ 
+ Next change was to the all important xterm. I used /dev/ttyp?  for
+ psuedo-termianls rather than the STREAMS tty, /dev/ptmx. Here in lies
+ the second major snafu of SCO I've found. xterm opens "/dev/tty" to
+ read the tty settings.  Under certain conditions this open causes the
+ kernel to panic. I use twm as my window manager and like to use its
+ menus to start new xterms. The controlling tty for twm is /dev/ptmx
+ because xinit loses the the controlling tty and twm picks up /dev/ptmx
+ to use it for IPC with the server. When twm starts an xterm, xterm
+ inherits this controlling tty. When xterm goes to open "/dev/tty"
+ (remember opening /dev/tty returns a handle to your controlling tty),
+ the kernel panics.  Could it be that the /dev/tty driver does not
+ specify a clone open when it redirects the open to /dev/ptmx
+ (/dev/ptmx is a clone driver).  I don't know, but leaving out the open
+ fixes the problem and you end up with a working xterm. Roell has left
+ this code out as well for some reason.
+ ./clients/xterm/main.c
+ 
+ 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.
+ 
+ cc did find a cosmetic bug in ./server/ddx/mi/mispritest.h
+ 95c95
+ < #define LINE_SORT(x1,y1,x2,y2) \
+ ---
+ > #define LINE_SORT(x1,y2,x2,y2) \
+ 
+ None of the cc fixes are included in the patches.
+ 
+ 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
*** mit/clients/xinit/xinit.c-	Sun Dec 16 21:46:54 1990
--- mit/clients/xinit/xinit.c	Sat Dec 15 12:26:51 1990
***************
*** 405,415 ****
--- 405,422 ----
  		 * at xinit when ready to accept connections
  		 */
  		(void) signal(SIGUSR1, SIG_IGN);
+ #ifndef SCO
  		/*
+ 		 * The SCO server needs to know our controlling tty. Delay
+ 		 * the setpgrp() until we are in the server.
+ 		 */
+ 
+ 		/*
  		 * prevent server from getting sighup from vhangup()
  		 * if client is xterm -L
  		 */
  		setpgrp(0,getpid());
+ #endif /* SCO */
  
  		Execute (server);
  		Error ("no server \"%s\" in PATH\n", server[0]);
*** mit/clients/xterm/main.c-	Sun Dec 16 21:46:51 1990
--- mit/clients/xterm/main.c	Sat Dec 15 12:26:52 1990
***************
*** 50,56 ****
  #include <ctype.h>
  
  #if defined(att) || defined(SYSV386)
! #ifndef TCPCONN
  #define USE_USG_PTYS
  #endif
  #define USE_SYSV_UTMP
--- 50,56 ----
  #include <ctype.h>
  
  #if defined(att) || defined(SYSV386)
! #if !defined(TCPCONN) && !defined(SCO)
  #define USE_USG_PTYS
  #endif
  #define USE_SYSV_UTMP
***************
*** 149,154 ****
--- 149,157 ----
  #include "menu.h"
  #include <X11/StringDefs.h>
  #include <X11/Shell.h>
+ #ifdef SCO
+ #undef SIGTSTP
+ #endif
  #ifdef SIGTSTP
  #include <sys/wait.h>
  #ifdef hpux
***************
*** 1194,1199 ****
--- 1197,1206 ----
   		 * defaults.
   		 */
  #ifdef SYSV386
+ 		/*
+ 		 * SCO will panic the kernel if you open("/dev/tty",) and your
+ 		 * controlling tty is /dev/ptmx.
+ 		 */
  		tty = -1;
  		errno = ENXIO;
  #else
*** mit/config/at386.cf-	Thu Nov  8 12:24:10 1990
--- mit/config/at386.cf	Thu Dec 13 23:31:10 1990
***************
*** 23,30 ****
  
  #ifdef SCO
  #define OSName			SCO UNIX System V Release 3.2
! #define OSMajorVersion		1
! #define OSMinorVersion		0
  #define OPERATING_SYSTEM	SYSV386
  #define OSDefines		-DSCO 
  #endif
--- 23,30 ----
  
  #ifdef SCO
  #define OSName			SCO UNIX System V Release 3.2
! #define OSMajorVersion		3
! #define OSMinorVersion		2
  #define OPERATING_SYSTEM	SYSV386
  #define OSDefines		-DSCO 
  #endif
***************
*** 46,52 ****
--- 46,56 ----
  #define HasInputExtension		NO   /* only with -DXINPUT */
  #define BuildExamples			NO             /* saves some space */
  #define InstallXdmConfig 		YES
+ #ifdef SCO
+ #define HasShadow 			NO
+ #else
  #define HasShadow 			YES
+ #endif
  #define ExecableScripts			NO
  #define StripInstalledPrograms 		YES
  #define CompatibilityFlags 		-DXAW_BC
***************
*** 81,87 ****
  /*
   * you should use GNU dbm for compiling the server. So define here HasNdbm
   */
! #define HasNdbm YES
  
  /*
   * You are absolutely urged to use GNU CC!!!! GCC produces about 30% faster
--- 85,91 ----
  /*
   * you should use GNU dbm for compiling the server. So define here HasNdbm
   */
! #define HasNdbm NO
  
  /*
   * You are absolutely urged to use GNU CC!!!! GCC produces about 30% faster
***************
*** 95,105 ****
   */
  
  #define HasGcc YES
! #define CcCmd gcc -DNOSTDHDRS -fstrength-reduce -fpcc-struct-return -fwritable-strings
! #define LibraryCcCmd gcc -DNOSTDHDRS -fstrength-reduce -fpcc-struct-return
  #define ShlibDefines -D__GNUC__ -DGNULIB=/usr/local/lib/gcc-gnulib
  
- 
  /*
   * adjust this paths according to your local site's MINIMUM requirements
   */
--- 99,108 ----
   */
  
  #define HasGcc YES
! #define CcCmd gcc -DNOSTDHDRS -DNO_PROTOTYPE -fstrength-reduce -fpcc-struct-return -fwritable-strings
! #define LibraryCcCmd gcc -DNOSTDHDRS -DNO_PROTOTYPE -fstrength-reduce -fpcc-struct-return
  #define ShlibDefines -D__GNUC__ -DGNULIB=/usr/local/lib/gcc-gnulib
  
  /*
   * adjust this paths according to your local site's MINIMUM requirements
   */
***************
*** 119,131 ****
  /*
   * these shared libs are only tested for ISC & GNU CC !!!!!!
   * they will shurely be inuseably for other systems
   */
! #define HasSVR3SharedLibraries YES
! #define SharedLibX             YES
! #define SharedLibXt            YES
! #define SharedLibXaw           YES
! #define SharedLibXmu           YES
! #define SharedLibXext          YES
  
  /*****************************************************************************
   *			  Server-specfic parameters                          *
--- 122,137 ----
  /*
   * these shared libs are only tested for ISC & GNU CC !!!!!!
   * they will shurely be inuseably for other systems
+  *
+  * The SCO DevSys 3.2 mkshlib is broken. You'll need the 3.2v2.0 version to
+  * build shared libs, otherwise just say NO.
   */
! #define HasSVR3SharedLibraries NO
! #define SharedLibX             NO
! #define SharedLibXt            NO
! #define SharedLibXaw           NO
! #define SharedLibXmu           NO
! #define SharedLibXext          NO
  
  /*****************************************************************************
   *			  Server-specfic parameters                          *
*** mit/config/imakemdep.h-	Sun Dec 16 21:47:12 1990
--- mit/config/imakemdep.h	Sat Dec 15 12:26:54 1990
***************
*** 135,141 ****
  #ifdef ISC              /* System V/386 folks */
          "-DISC",
  #endif
! #ifdef ISCO
          "-DSCO",
  #endif
  #ifdef ESIX
--- 135,141 ----
  #ifdef ISC              /* System V/386 folks */
          "-DISC",
  #endif
! #ifdef SCO
          "-DSCO",
  #endif
  #ifdef ESIX
*** mit/include/Xos.h-	Sun Dec 16 21:47:12 1990
--- mit/include/Xos.h	Sat Dec 15 12:26:54 1990
***************
*** 165,170 ****
--- 165,174 ----
        char            sa_data[14];
  };
  
+ #ifndef SCO
+ /*
+  * These are already defined in sys/select.h for SCO.
+  */
  typedef	unsigned char	u_char;
  typedef	unsigned short	u_short;
  typedef	unsigned int	u_int;
***************
*** 189,194 ****
--- 193,199 ----
  #define	FD_CLR(n, p)	((p)->fds_bits[0] &= ~(1 << (n)))
  #define	FD_ISSET(n, p)	((p)->fds_bits[0] & (1 << (n)))
  #define	FD_ZERO(p)	bzero((char *)(p), sizeof(*(p)))
+ #endif /* SCO */
  
  #endif
  #endif
*** mit/lib/X/XlibInt.c-	Sun Dec 16 21:46:27 1990
--- mit/lib/X/XlibInt.c	Sun Dec 16 17:02:25 1990
***************
*** 1775,1787 ****
  	for (p = v[i].iov_base, len = v[i].iov_len; len > 0; ) {
  	    int rc = ((*_XsStream[_XsTypeOfStream[fd]].WriteToStream)
  		      (fd, p, len));
! 	    if (rc > 0) {
! 		p += rc;
! 		len -= rc;
! 		size += rc;
! 	    } else if (rc < 0) {
! 		break;
! 	    }
  	}
      }
  
--- 1775,1787 ----
  	for (p = v[i].iov_base, len = v[i].iov_len; len > 0; ) {
  	    int rc = ((*_XsStream[_XsTypeOfStream[fd]].WriteToStream)
  		      (fd, p, len));
! 	    if (rc < 0 && size == 0)
! 		return -1;
! 	    if (rc <= 0)
! 		return size;
! 	    p += rc;
! 	    len -= rc;
! 	    size += rc;
  	}
      }
  
***************
*** 1875,1877 ****
--- 1875,1904 ----
  }
  
  #endif /* STREAMSCONN */
+ 
+ #if defined(SCO) && defined(__GNUC__)
+ 
+ /*
+  * This will fix the broken _ftol if you have the gcc libraries. If you are
+  * lucky to have the newest DevSys you can get rid of this altogether.
+  */
+ 
+ long _ftol(f)
+ double f;
+ {
+     __asm__ ("subl	$12,%esp");
+     __asm__ ("fstcw	-8(%ebp)");
+     __asm__ ("movw	-8(%ebp),%ax");
+     __asm__ ("orw	$0x0c00,%ax");
+     __asm__ ("movw	%ax,-4(%ebp)");
+     __asm__ ("fldcw	-4(%ebp)");
+     __asm__ ("fistpl	-12(%ebp)");
+     __asm__ ("fldcw	-8(%ebp)");
+     __asm__ ("movl	-12(%ebp),%eax");
+ }
+ 
+ int dummy()
+ {
+ }
+ 
+ #endif
*** mit/lib/Xt/Create.c-	Sun Dec 16 17:26:01 1990
--- mit/lib/Xt/Create.c	Sun Dec 16 10:42:11 1990
***************
*** 29,35 ****
--- 29,37 ----
  #include "StringDefs.h"
  #include "Shell.h"
  #include "ShellP.h"
+ #ifndef SCO
  #include <stdio.h>
+ #endif
  
  static String XtNxtCreateWidget = "xtCreateWidget";
  static String XtNxtCreatePopupShell = "xtCreatePopupShell";
*** mit/lib/Xt/Resources.c-	Sun Dec 16 17:25:59 1990
--- mit/lib/Xt/Resources.c	Sun Dec 16 10:43:28 1990
***************
*** 26,32 ****
--- 26,34 ----
  
  ******************************************************************/
  
+ #ifndef SCO
  #include <stdio.h>
+ #endif
  #include "IntrinsicI.h"
  #include "VarargsI.h"
  #include "Shell.h"
*** mit/rgb/rgb.c-	Sun Dec 16 17:40:05 1990
--- mit/rgb/rgb.c	Sat Dec 15 12:26:56 1990
***************
*** 14,20 ****
--- 14,24 ----
  #include <dbm.h>
  #define dbm_open(name,flags,mode) (!dbminit(name))
  #define dbm_store(db,key,content,flags) (store(key,content))
+ #ifdef SCO
+ #define dbm_close(db)
+ #else
  #define dbm_close(db) dbmclose()
+ #endif
  #endif
  
  #undef NULL
*** mit/rgb/showrgb.c-	Sun Dec 16 21:47:04 1990
--- mit/rgb/showrgb.c	Sat Dec 15 12:26:56 1990
***************
*** 30,36 ****
--- 30,40 ----
  #define dbm_open(name,flags,mode) (!dbminit(name))
  #define dbm_firstkey(db) (firstkey())
  #define dbm_fetch(db,key) (fetch(key))
+ #ifdef SCO
+ #define dbm_close(db)
+ #else
  #define dbm_close(db) dbmclose()
+ #endif
  #endif
  
  #undef NULL
*** mit/server/ddx/at386/X386.h-	Thu Nov  8 09:49:56 1990
--- mit/server/ddx/at386/X386.h	Sat Dec 15 12:26:57 1990
***************
*** 32,37 ****
--- 32,41 ----
  #include "ix386.h"
  #endif
  
+ #ifdef SCO
+ #include "sco.h"
+ #endif
+ 
  #include "compiler.h"
  
  /*
*** mit/server/ddx/at386/keyboard.c-	Thu Nov  8 09:50:30 1990
--- mit/server/ddx/at386/keyboard.c	Mon Dec 17 00:16:07 1990
***************
*** 63,69 ****
      /* 0x0b */  XK_0,           	XK_parenright,
      /* 0x0c */  XK_minus,       	XK_underscore,
      /* 0x0d */  XK_equal,       	XK_plus,
!     /* 0x0e */  XK_Delete,              XK_BackSpace,
      /* 0x0f */  XK_Tab,         	NoSymbol,
      /* 0x10 */  XK_q,           	XK_Q,
      /* 0x11 */  XK_w,           	XK_W,
--- 63,69 ----
      /* 0x0b */  XK_0,           	XK_parenright,
      /* 0x0c */  XK_minus,       	XK_underscore,
      /* 0x0d */  XK_equal,       	XK_plus,
!     /* 0x0e */  XK_BackSpace,           XK_BackSpace,
      /* 0x0f */  XK_Tab,         	NoSymbol,
      /* 0x10 */  XK_q,           	XK_Q,
      /* 0x11 */  XK_w,           	XK_W,
***************
*** 323,333 ****
--- 323,351 ----
      DevicePtr     pKeyboard;        /* Keyboard to ring */
  {
    X386KeyboardPtr pPriv = (X386KeyboardPtr)pKeyboard->devicePrivate;
+ #ifdef SCO
+ #include <sys/select.h>
+   struct timeval timeout;
+ #endif
  
    TRACE( ("ATKbdBell(loudness=%d, pKeyboard=0x%x)\n", loudness, pKeyboard) );
  
+ #ifdef SCO
+   /*
+    * KDMKTONE is not supported on SCO. To make sound we use KIOCSOUND. The
+    * sound must be explicitly turned on and off. The timeout needs to have
+    * millisecond precision. I use the typical select() hack to do this
+    * instead of nap() so I won't have to link with -lx.
+    */
+   timeout.tv_sec = pPriv->ctrl.bell_duration / 1000;
+   timeout.tv_usec = ( pPriv->ctrl.bell_duration % 1000 ) * 1000;
+   ioctl(((X386DevicePtr)pPriv)->Fd, KIOCSOUND, pPriv->ctrl.bell_pitch << 2);
+   select(0, NULL, NULL, NULL, &timeout);
+   ioctl(((X386DevicePtr)pPriv)->Fd, KIOCSOUND, 0);
+ #else
    ioctl(((X386DevicePtr)pPriv)->Fd, KDMKTONE, 
  	(pPriv->ctrl.bell_duration << 16) | pPriv->ctrl.bell_pitch);
+ #endif
  }
  
  
*** mit/server/ddx/at386/screen.c-	Thu Nov  8 09:50:39 1990
--- mit/server/ddx/at386/screen.c	Sun Dec 16 15:31:48 1990
***************
*** 280,285 ****
--- 280,291 ----
    
    if (consoleFd == -1) {
      tty = (char *) ttyname(0);
+ #ifdef SCO
+     /*
+      * Now that we have our tty name from ttyname() we can setpgrp().
+      */
+     setpgrp();
+ #else
      if (!tty || (strcmp(tty,"/dev/console") == 0))
        {
  	/*
***************
*** 300,305 ****
--- 306,312 ----
  	sprintf(vtname,"/dev/vt0%1d",ttyno);
  	tty = vtname;
        }
+ #endif /* SCO */
  
      /*
       * now close them to avoid hanging clients
***************
*** 366,371 ****
--- 373,443 ----
    
    if (ioctl(consoleFd, VT_SETMODE, &vgaVT) < 0)
      FatalError ("failed to set the state of the virtual terminal\n");
+ 
+ #define THE_GREAT_SCO_ORCHID_PRO_DESIGNER_2_HACK
+ #ifdef THE_GREAT_SCO_ORCHID_PRO_DESIGNER_2_HACK
+   {
+ #include <sys/console.h>
+       register int i, j;
+ 
+       static unsigned char seq[]={
+ 	  0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0xac,
+       };
+       static unsigned char crtc[]={
+ 	  0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+ 	  0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x12,
+ 	  0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+ 	  0xff,
+       };
+       static unsigned char grc[]={
+ 	  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+ 	  0xff,
+       };
+       static unsigned char pal[]={
+ 	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 	  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 	  0x0C, 0x00, 0x0f, 0x08, 0x00,
+       };
+ 
+       TRACE( ("THE_GREAT_SCO_ORCHID_PRO_DESIGNER_2_HACK\n") );
+       inb(0x3da);
+       outb(0x3c0, 0);			/* disable attributes */
+       for (i=0; i<8; i++)		/* sequencer */
+ 	  outw(0x3c4, (seq[i]<<8) | i);
+       outb(0x3c2, 0x67);		/* misc out reg */
+       outw(0x3c4, 0x0300);		/* enable sequencer */
+ 
+       outw(0x3d4, 0x2011);		/* unprotect crtc regs 0-7 */
+       for (i=0; i<25; i++)		/* CRTC */
+ 	  outw(0x3d4, (crtc[i]<<8) | i);
+       outw(0x3d4, 0x0033);		/* ET4000 CRTC */
+       outw(0x3d4, 0x0834);
+       outw(0x3d4, 0x0035);
+       for (i=0; i<9; i++)		/* graphics controller */
+ 	  outw(0x3ce, (grc[i]<<8) | i);
+       inb(0x3da);			/* reset attribute f/f */
+       for (i=0; i<21; i++) {		/* attributes */
+ 	  outb(0x3c0, i);
+ 	  outb(0x3c0, pal[i]);
+       }
+       outb(0x3c8, 0);			/* DAC */
+       for (i=0; i<64; i++) {
+ 	  j=i;
+ 	  outb(0x3c9, ((j&1)*0x2a) | ((j>>3) & 1)*0x15);
+ 	  j>>=1;
+ 	  outb(0x3c9, ((j&1)*0x2a) | ((j>>3) & 1)*0x15);
+ 	  j>>=1;
+ 	  outb(0x3c9, ((j&1)*0x2a) | ((j>>3) & 1)*0x15);
+       }
+       for (; i<256; i++) {
+ 	  outb(0x3c9, 0);
+ 	  outb(0x3c9, 0);
+ 	  outb(0x3c9, 0);
+       }
+       inb(0x3da);
+       outb(0x3c0, 0x20);		/* enable attributes */
+   }
+ #endif
  }
  
  /*-
*** mit/server/ddx/at386/sco.h-	Sun Dec 16 22:06:48 1990
--- mit/server/ddx/at386/sco.h	Mon Dec 17 00:19:04 1990
***************
*** 0 ****
--- 1,49 ----
+ /*
+  * Copyright 1990 by Thomas Roell, Dinkelscherben, Germany.
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+  * the above copyright notice appear in all copies and that both that
+  * copyright notice and this permission notice appear in supporting
+  * documentation, and that the name of Thomas Roell not be used in
+  * advertising or publicity pertaining to distribution of the software without
+  * specific, written prior permission.  Thomas Roell makes no representations
+  * about the suitability of this software for any purpose.  It is provided
+  * "as is" without express or implied warranty.
+  *
+  * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+  * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+  * PERFORMANCE OF THIS SOFTWARE.
+  *
+  * Author:  Thomas Roell, roell@lan.informatik.tu-muenchen.de
+  *
+  * $Header: /proj/X11/mit/server/ddx/at386/RCS/sco.h,v 1.4 90/11/08 17:48:41 root Exp $
+  */
+ 
+ 
+ /*
+  * SYS V/386 dependent includes (SCO's version)
+  */
+ #include    <stdio.h>
+ #include    <ctype.h>
+ #include    <sys/ioctl.h>
+ #include    <sys/param.h>
+ #include    <sys/types.h>
+ #include    <time.h>
+ #include    <sys/file.h>
+ #include    <sys/fcntl.h>
+ #include    <sys/signal.h>
+ #include    <sys/vtkd.h>
+ #include    <sys/console.h>
+ #include    <termio.h>
+ #include    <errno.h>
+ extern int errno;
+ #undef VGA
+ 
+ #define LED_CAP  0x01
+ #define LED_NUM  0x02
+ #define LED_SCR  0x04
*** mit/server/ddx/at386/vga/vga.c-	Thu Nov  8 10:08:22 1990
--- mit/server/ddx/at386/vga/vga.c	Sun Dec 16 15:13:03 1990
***************
*** 182,188 ****
--- 182,219 ----
      X386Screen.FrameY0 + vgaVideoModes[vgaCurrentVideoMode].VDisplay -1;
  
    if (vgaBase == NULL) {
+ #ifdef SCO
      /*
+      * This is an ioctl to the vid driver that I found in the 3.2v2.0
+      * release notes. The driver searches the table compiled in from
+      * /etc/conf/pack.d/cn/class.h for physical sizes and addresses
+      * for video hardware. It will enable I/O ports and map the adapter
+      * memory and return its virtual address. This will only work on
+      * 3.2.1 (ODT 1.0) or higher. If it fails I assume you are running
+      * 3.2.0 in which case we try something else.
+      */
+     if ( (vgaBase = ioctl(consoleFd, MAP_CLASS, "SVGA")) == -1 ) {
+ 	/*
+ 	 * The MAP_CLASS ioctl failed, must be running 3.2.0. Next we try
+ 	 * the MAPCONS ioctl. First the screen must be in graphics mode,
+ 	 * hence the SW_VGA12 above. Next we must be running as root or
+ 	 * else MAPCONS will fail. Usually this will be accomplished by
+ 	 * having the server be a setuid program.
+ 	 */
+ 	if ( (vgaBase = ioctl(consoleFd, MAPCONS, 0)) == -1 )
+ 	    FatalError("failed to map the video memory\n");
+     }
+ 
+     /*
+      * In either case we will make another ioctl to map some more I/O
+      * ports. Even though MAP_CLASS does part of the job, it did not
+      * map all the I/O ports for my Super VGA. You must be running as
+      * root to execute this ioctl only if you are running 3.2.0. For
+      * newer revs of the OS anybody can invoke this.
+      */
+     ioctl(consoleFd, KDENABIO, 0);
+ #else
+     /*
       * Map the VGA's memory into the servers address-space. We have here to
       * keep up with the fact that the VGA memory may only be mapped at an
       * (386-) page boundary. So allocate more memory, and then adjust the
***************
*** 196,201 ****
--- 227,233 ----
      if ((unsigned int)vgaBase & 0xFFF) {
        vgaBase += 0x1000 - ((unsigned int)vgaBase & 0xFFF);
      }
+ #endif /* SCO */
  
      vgaReadBottom += (unsigned int)vgaBase; 
      vgaReadTop += (unsigned int)vgaBase; 
***************
*** 257,267 ****
     */
    if (vgaOrigVideoState)
      (vgaRestoreFunc)(vgaOrigVideoState);
!   
    /*
     * This ioctl call may fail on abnormal server abort ...
     */
    ioctl(consoleFd, KDUNMAPDISP);
  
    saveInitFunc = vgaInitFunc;
    saveSaveFunc = vgaSaveFunc;
--- 289,301 ----
     */
    if (vgaOrigVideoState)
      (vgaRestoreFunc)(vgaOrigVideoState);
! 
! #ifndef SCO  
    /*
     * This ioctl call may fail on abnormal server abort ...
     */
    ioctl(consoleFd, KDUNMAPDISP);
+ #endif
  
    saveInitFunc = vgaInitFunc;
    saveSaveFunc = vgaSaveFunc;
***************
*** 316,321 ****
--- 350,356 ----
        saveFuncs = FALSE;
      }
  
+ #ifndef SCO
    vgaDSC.vaddr    = (char *)vgaBase;
    vgaDSC.physaddr = (char *)0xA0000;
    vgaDSC.length   = vgaMapSize;
***************
*** 323,328 ****
--- 358,364 ----
    if (ioctl(consoleFd, KDMAPDISP, &vgaDSC) < 0) {
      FatalError ("failed to remap the videomemory\n");
    }
+ #endif
    
    vgaOrigVideoState = (pointer)(vgaSaveFunc)(vgaOrigVideoState);
    (vgaRestoreFunc)(vgaNewVideoState);
*** mit/server/ddx/at386/vga/vga.h-	Thu Nov  8 10:08:45 1990
--- mit/server/ddx/at386/vga/vga.h	Fri Dec 14 17:48:22 1990
***************
*** 150,156 ****
  
  typedef struct {
    unsigned char MiscOutReg;     /* */
!   unsigned char CRTC[24];       /* Crtc Controller */
    unsigned char Sequencer[5];   /* Video Sequencer */
    unsigned char Graphics[9];    /* Video Graphics */
    unsigned char Attribute[21];  /* Video Atribute */
--- 150,156 ----
  
  typedef struct {
    unsigned char MiscOutReg;     /* */
!   unsigned char CRTC[25];       /* Crtc Controller */
    unsigned char Sequencer[5];   /* Video Sequencer */
    unsigned char Graphics[9];    /* Video Graphics */
    unsigned char Attribute[21];  /* Video Atribute */
*** mit/server/ddx/mi/mispritest.h-	Sun Dec 16 17:28:21 1990
--- mit/server/ddx/mi/mispritest.h	Sat Dec 15 12:27:06 1990
***************
*** 92,98 ****
   */
  #define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
  
! #define LINE_SORT(x1,y2,x2,y2) \
  { int _t; \
    if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
    if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
--- 92,98 ----
   */
  #define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
  
! #define LINE_SORT(x1,y1,x2,y2) \
  { int _t; \
    if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
    if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }