diff -Naur xmame-0.60.1/makefile.unix xmame-0.60.1-ps2/makefile.unix
--- xmame-0.60.1/makefile.unix	2002-05-02 22:53:55.000000000 -0400
+++ xmame-0.60.1-ps2/makefile.unix	2002-05-22 04:27:00.150444000 -0400
@@ -115,6 +115,10 @@
 # CFLAGS = -fullwarn -n32 -mips4 -Ofast -OPT:Olimit=0 -IPA
 ### for IRIX with R4K Mips chips (older Indys, Indigo2s, etc).
 # CFLAGS = -fullwarn -n32 -mips3 -Ofast -OPT:Olimit=0 -IPA
+### for PlayStation2 linux use following opts
+# CFLAGS    = -O -mcpu=r5900 -Wall -Wno-unused -fsingle-precision-constant \
+#  -fstrength-reduce -fomit-frame-pointer -ffast-math -fsigned-char -pipe \
+#  -malign-loops=2 -malign-jumps=2 -funroll-loops
 ### used by me, for full ansi testing and debugging (with gcc).
 # CFLAGS    = -ggdb -ansi -pedantic -D_XOPEN_SOURCE -D_BSD_SOURCE -Wall \
 #  -Wno-long-long -Wno-trigraphs -Wp,-Wno-paste \
@@ -231,7 +235,7 @@
 # MY_CPU = m68k
 ### generic risc (powerpc, sparc, hppa, ibm)
 # MY_CPU = risc
-### generic risc, lsb-first (RISC (ultrix machines))
+### generic risc, lsb-first (RISC (ultrix machines) & PlayStation2)
 # MY_CPU = risc_lsb
 ### mips (generic risc + SGI compiler bug workarounds)
 # MY_CPU = mips
@@ -285,7 +289,8 @@
 # JOY_PAD = 1
 # NetBSD/FreeBSD USB joystick support.
 # JOY_USB = 1
-
+# PlayStation2-linux native pad support.
+# JOY_PS2 = 1
 
 ##############################################################################
 # *** Sound Devices
diff -Naur xmame-0.60.1/src/inptport.c xmame-0.60.1-ps2/src/inptport.c
--- xmame-0.60.1/src/inptport.c	2002-05-04 05:06:06.000000000 -0400
+++ xmame-0.60.1-ps2/src/inptport.c	2002-05-20 19:58:42.000000000 -0400
@@ -449,6 +449,10 @@
 	{ "JOYCODE_1_BUTTON4",	  	IKT_STD,		JOYCODE_1_BUTTON4 },
 	{ "JOYCODE_1_BUTTON5",	  	IKT_STD,		JOYCODE_1_BUTTON5 },
 	{ "JOYCODE_1_BUTTON6",	  	IKT_STD,		JOYCODE_1_BUTTON6 },
+	{ "JOYCODE_1_BUTTON7",	  	IKT_STD,		JOYCODE_1_BUTTON7 },
+	{ "JOYCODE_1_BUTTON8",	  	IKT_STD,		JOYCODE_1_BUTTON8 },
+	{ "JOYCODE_1_BUTTON9",	  	IKT_STD,		JOYCODE_1_BUTTON9 },
+	{ "JOYCODE_1_BUTTON10",	  	IKT_STD,		JOYCODE_1_BUTTON10 },
 	{ "JOYCODE_1_START",	  	IKT_STD,		JOYCODE_1_START },
 	{ "JOYCODE_1_SELECT",	  	IKT_STD,		JOYCODE_1_SELECT },
 	{ "JOYCODE_2_LEFT",		  	IKT_STD,		JOYCODE_2_LEFT },
@@ -461,6 +465,10 @@
 	{ "JOYCODE_2_BUTTON4",	  	IKT_STD,		JOYCODE_2_BUTTON4 },
 	{ "JOYCODE_2_BUTTON5",	  	IKT_STD,		JOYCODE_2_BUTTON5 },
 	{ "JOYCODE_2_BUTTON6",	  	IKT_STD,		JOYCODE_2_BUTTON6 },
+	{ "JOYCODE_2_BUTTON7",	  	IKT_STD,		JOYCODE_2_BUTTON7 },
+	{ "JOYCODE_2_BUTTON8",	  	IKT_STD,		JOYCODE_2_BUTTON8 },
+	{ "JOYCODE_2_BUTTON9",	  	IKT_STD,		JOYCODE_2_BUTTON9 },
+	{ "JOYCODE_2_BUTTON10",	  	IKT_STD,		JOYCODE_2_BUTTON10 },
 	{ "JOYCODE_2_START",	  	IKT_STD,		JOYCODE_2_START },
 	{ "JOYCODE_2_SELECT",	  	IKT_STD,		JOYCODE_2_SELECT },
 	{ "JOYCODE_3_LEFT",		  	IKT_STD,		JOYCODE_3_LEFT },
@@ -473,6 +481,10 @@
 	{ "JOYCODE_3_BUTTON4",	  	IKT_STD,		JOYCODE_3_BUTTON4 },
 	{ "JOYCODE_3_BUTTON5",	  	IKT_STD,		JOYCODE_3_BUTTON5 },
 	{ "JOYCODE_3_BUTTON6",	  	IKT_STD,		JOYCODE_3_BUTTON6 },
+	{ "JOYCODE_3_BUTTON7",	  	IKT_STD,		JOYCODE_3_BUTTON6 },
+	{ "JOYCODE_3_BUTTON8",	  	IKT_STD,		JOYCODE_3_BUTTON6 },
+	{ "JOYCODE_3_BUTTON9",	  	IKT_STD,		JOYCODE_3_BUTTON6 },
+	{ "JOYCODE_3_BUTTON10",	  	IKT_STD,		JOYCODE_3_BUTTON6 },
 	{ "JOYCODE_3_START",	  	IKT_STD,		JOYCODE_3_START },
 	{ "JOYCODE_3_SELECT",	  	IKT_STD,		JOYCODE_3_SELECT },
 	{ "JOYCODE_4_LEFT",		  	IKT_STD,		JOYCODE_4_LEFT },
@@ -485,6 +497,10 @@
 	{ "JOYCODE_4_BUTTON4",	  	IKT_STD,		JOYCODE_4_BUTTON4 },
 	{ "JOYCODE_4_BUTTON5",	  	IKT_STD,		JOYCODE_4_BUTTON5 },
 	{ "JOYCODE_4_BUTTON6",	  	IKT_STD,		JOYCODE_4_BUTTON6 },
+	{ "JOYCODE_4_BUTTON7",	  	IKT_STD,		JOYCODE_4_BUTTON7 },
+	{ "JOYCODE_4_BUTTON8",	  	IKT_STD,		JOYCODE_4_BUTTON8 },
+	{ "JOYCODE_4_BUTTON9",	  	IKT_STD,		JOYCODE_4_BUTTON9 },
+	{ "JOYCODE_4_BUTTON10",	  	IKT_STD,		JOYCODE_4_BUTTON10 },
 	{ "JOYCODE_4_START",	  	IKT_STD,		JOYCODE_4_START },
 	{ "JOYCODE_4_SELECT",	  	IKT_STD,		JOYCODE_4_SELECT },
 
diff -Naur xmame-0.60.1/src/input.h xmame-0.60.1-ps2/src/input.h
--- xmame-0.60.1/src/input.h	2002-05-02 22:53:50.000000000 -0400
+++ xmame-0.60.1-ps2/src/input.h	2002-05-20 19:58:42.000000000 -0400
@@ -49,19 +49,23 @@
 	JOYCODE_1_LEFT,JOYCODE_1_RIGHT,JOYCODE_1_UP,JOYCODE_1_DOWN,
 	JOYCODE_1_BUTTON1,JOYCODE_1_BUTTON2,JOYCODE_1_BUTTON3,
 	JOYCODE_1_BUTTON4,JOYCODE_1_BUTTON5,JOYCODE_1_BUTTON6,
-	JOYCODE_1_START, JOYCODE_1_SELECT,
+	JOYCODE_1_BUTTON7,JOYCODE_1_BUTTON8,JOYCODE_1_BUTTON9,
+	JOYCODE_1_BUTTON10, JOYCODE_1_START, JOYCODE_1_SELECT,
 	JOYCODE_2_LEFT,JOYCODE_2_RIGHT,JOYCODE_2_UP,JOYCODE_2_DOWN,
 	JOYCODE_2_BUTTON1,JOYCODE_2_BUTTON2,JOYCODE_2_BUTTON3,
 	JOYCODE_2_BUTTON4,JOYCODE_2_BUTTON5,JOYCODE_2_BUTTON6,
-	JOYCODE_2_START, JOYCODE_2_SELECT,
+	JOYCODE_2_BUTTON7,JOYCODE_2_BUTTON8,JOYCODE_2_BUTTON9,
+	JOYCODE_2_BUTTON10, JOYCODE_2_START, JOYCODE_2_SELECT,
 	JOYCODE_3_LEFT,JOYCODE_3_RIGHT,JOYCODE_3_UP,JOYCODE_3_DOWN,
 	JOYCODE_3_BUTTON1,JOYCODE_3_BUTTON2,JOYCODE_3_BUTTON3,
 	JOYCODE_3_BUTTON4,JOYCODE_3_BUTTON5,JOYCODE_3_BUTTON6,
-	JOYCODE_3_START, JOYCODE_3_SELECT,
+	JOYCODE_3_BUTTON7,JOYCODE_3_BUTTON8,JOYCODE_3_BUTTON9,
+	JOYCODE_3_BUTTON10, JOYCODE_3_START, JOYCODE_3_SELECT,
 	JOYCODE_4_LEFT,JOYCODE_4_RIGHT,JOYCODE_4_UP,JOYCODE_4_DOWN,
 	JOYCODE_4_BUTTON1,JOYCODE_4_BUTTON2,JOYCODE_4_BUTTON3,
 	JOYCODE_4_BUTTON4,JOYCODE_4_BUTTON5,JOYCODE_4_BUTTON6,
-	JOYCODE_4_START, JOYCODE_4_SELECT,
+	JOYCODE_4_BUTTON7,JOYCODE_4_BUTTON8,JOYCODE_4_BUTTON9,
+	JOYCODE_4_BUTTON10, JOYCODE_4_START, JOYCODE_4_SELECT,
 	JOYCODE_MOUSE_1_BUTTON1,JOYCODE_MOUSE_1_BUTTON2,JOYCODE_MOUSE_1_BUTTON3,
 #define __code_joy_first JOYCODE_1_LEFT
 #define __code_joy_last JOYCODE_MOUSE_1_BUTTON3
diff -Naur xmame-0.60.1/src/unix/Makefile xmame-0.60.1-ps2/src/unix/Makefile
--- xmame-0.60.1/src/unix/Makefile	2002-05-02 22:53:53.000000000 -0400
+++ xmame-0.60.1-ps2/src/unix/Makefile	2002-05-19 11:06:35.000000000 -0400
@@ -63,7 +63,7 @@
 # joystick objs
 JOY_DIR  = $(OBJDIR)/joystick-drivers
 JOY_OBJS = $(JOY_DIR)/joy_i386.o $(JOY_DIR)/joy_pad.o $(JOY_DIR)/joy_x11.o \
-    $(JOY_DIR)/joy_usb.o $(JOY_DIR)/XInputDevices.o
+    $(JOY_DIR)/joy_usb.o $(JOY_DIR)/joy_ps2.o $(JOY_DIR)/XInputDevices.o
 
 # framskip objs
 FRAMESKIP_DIR  = $(OBJDIR)/frameskip-drivers
diff -Naur xmame-0.60.1/src/unix/devices.c xmame-0.60.1-ps2/src/unix/devices.c
--- xmame-0.60.1/src/unix/devices.c	2002-05-05 19:07:59.000000000 -0400
+++ xmame-0.60.1-ps2/src/unix/devices.c	2002-05-21 14:16:39.000000000 -0400
@@ -29,8 +29,8 @@
       NULL,		0,			0,		NULL,
       NULL },
    { "joytype",		"jt",			rc_int,		&joytype,
-      "0",      	0,			5,		NULL,
-      "Select type of joystick support to use:\n0 No joystick\n1 i386 style joystick driver (if compiled in)\n2 Fm Town Pad support (if compiled in)\n3 X11 input extension joystick (if compiled in)\n4 new i386 linux 1.x.x joystick driver(if compiled in)\n5 NetBSD USB joystick driver (if compiled in)" },
+      "0",      	0,			6,		NULL,
+      "Select type of joystick support to use:\n0 No joystick\n1 i386 style joystick driver (if compiled in)\n2 Fm Town Pad support (if compiled in)\n3 X11 input extension joystick (if compiled in)\n4 new i386 linux 1.x.x joystick driver(if compiled in)\n5 NetBSD USB joystick driver (if compiled in)\n6 PS2-Linux native pad (if compiled in)" },
    { "analogstick",	"as",			rc_bool,	&analogstick,
      "0",		0,			0,		NULL,
      "Use Joystick as analog for analog controls" },
@@ -46,6 +46,9 @@
    { NULL,		NULL,			rc_link,	joy_usb_opts,
      NULL,		0,			0,		NULL,
      NULL },
+   { NULL,		NULL,			rc_link,	joy_ps2_opts,
+     NULL,		0,			0,		NULL,
+     NULL },
 #ifdef USE_XINPUT_DEVICES
    { NULL,		NULL,			rc_link,        XInputDevices_opts,
      NULL,		0,			0,		NULL,
@@ -84,6 +87,10 @@
 	{ JOY_BUTTON_CODE(0,3), JOYCODE_1_BUTTON4 },
 	{ JOY_BUTTON_CODE(0,4), JOYCODE_1_BUTTON5 },
 	{ JOY_BUTTON_CODE(0,5), JOYCODE_1_BUTTON6 },
+	{ JOY_BUTTON_CODE(0,6), JOYCODE_1_BUTTON7 },
+	{ JOY_BUTTON_CODE(0,7), JOYCODE_1_BUTTON8 },
+	{ JOY_BUTTON_CODE(0,8), JOYCODE_1_BUTTON9 },
+	{ JOY_BUTTON_CODE(0,9), JOYCODE_1_BUTTON10 },
 	{ JOY_AXIS_CODE(1,0,0), JOYCODE_2_LEFT },
 	{ JOY_AXIS_CODE(1,0,1), JOYCODE_2_RIGHT },
 	{ JOY_AXIS_CODE(1,1,0), JOYCODE_2_UP },
@@ -94,6 +101,10 @@
 	{ JOY_BUTTON_CODE(1,3), JOYCODE_2_BUTTON4 },
 	{ JOY_BUTTON_CODE(1,4), JOYCODE_2_BUTTON5 },
 	{ JOY_BUTTON_CODE(1,5), JOYCODE_2_BUTTON6 },
+	{ JOY_BUTTON_CODE(1,6), JOYCODE_2_BUTTON7 },
+	{ JOY_BUTTON_CODE(1,7), JOYCODE_2_BUTTON8 },
+	{ JOY_BUTTON_CODE(1,8), JOYCODE_2_BUTTON9 },
+	{ JOY_BUTTON_CODE(1,9), JOYCODE_2_BUTTON10 },
 	{ JOY_AXIS_CODE(2,0,0), JOYCODE_3_LEFT },
 	{ JOY_AXIS_CODE(2,0,1), JOYCODE_3_RIGHT },
 	{ JOY_AXIS_CODE(2,1,0), JOYCODE_3_UP },
@@ -104,6 +115,10 @@
 	{ JOY_BUTTON_CODE(2,3), JOYCODE_3_BUTTON4 },
 	{ JOY_BUTTON_CODE(2,4), JOYCODE_3_BUTTON5 },
 	{ JOY_BUTTON_CODE(2,5), JOYCODE_3_BUTTON6 },
+	{ JOY_BUTTON_CODE(2,6), JOYCODE_3_BUTTON7 },
+	{ JOY_BUTTON_CODE(2,7), JOYCODE_3_BUTTON8 },
+	{ JOY_BUTTON_CODE(2,8), JOYCODE_3_BUTTON9 },
+	{ JOY_BUTTON_CODE(2,9), JOYCODE_3_BUTTON10 },
 	{ JOY_AXIS_CODE(3,0,0), JOYCODE_4_LEFT },
 	{ JOY_AXIS_CODE(3,0,1), JOYCODE_4_RIGHT },
 	{ JOY_AXIS_CODE(3,1,0), JOYCODE_4_UP },
@@ -114,6 +129,10 @@
 	{ JOY_BUTTON_CODE(3,3), JOYCODE_4_BUTTON4 },
 	{ JOY_BUTTON_CODE(3,4), JOYCODE_4_BUTTON5 },
 	{ JOY_BUTTON_CODE(3,5), JOYCODE_4_BUTTON6 },
+	{ JOY_BUTTON_CODE(3,6), JOYCODE_4_BUTTON7 },
+	{ JOY_BUTTON_CODE(3,7), JOYCODE_4_BUTTON8 },
+	{ JOY_BUTTON_CODE(3,8), JOYCODE_4_BUTTON9 },
+	{ JOY_BUTTON_CODE(3,9), JOYCODE_4_BUTTON10 },
 	{ 0,0 }
 };
 
@@ -255,6 +274,32 @@
    if (use_mouse)
       fprintf (stderr_file, "Mouse/Trakball selected.\n");
    
+#ifdef JOY_PS2
+   /* Special mapping for PlayStation2 -- to be removed when 0.60 patch done */
+   /* Add mappings for P1 SELECT, START, P2 SELECT, START */
+   joy_list[JOY_BUTTON_CODE(0,6)] = JOYCODE_1_SELECT;
+   joy_list[JOY_BUTTON_CODE(0,7)] = JOYCODE_1_START;
+   joy_list[JOY_BUTTON_CODE(1,6)] = JOYCODE_2_SELECT;
+   joy_list[JOY_BUTTON_CODE(1,7)] = JOYCODE_2_START;
+   /* For now, L2 is equivalent of TAB, and R2 is equivalent of ESC */
+   joy_list[JOY_BUTTON_CODE(0,8)] = KEYCODE_TAB;
+   joy_list[JOY_BUTTON_CODE(0,9)] = KEYCODE_ESC;
+   /* Remap L3 and R3 to BUTTON7 and BUTTON8 */
+   joy_list[JOY_BUTTON_CODE(0,10)] = JOYCODE_1_BUTTON7;
+   joy_list[JOY_BUTTON_CODE(0,11)] = JOYCODE_1_BUTTON8;
+   joy_list[JOY_BUTTON_CODE(1,10)] = JOYCODE_2_BUTTON7;
+   joy_list[JOY_BUTTON_CODE(1,11)] = JOYCODE_2_BUTTON8;
+   /* Map the 4 directional buttons to the four axes. */
+   joy_list[JOY_BUTTON_CODE(0,12)] = JOYCODE_1_LEFT;
+   joy_list[JOY_BUTTON_CODE(0,13)] = JOYCODE_1_RIGHT;
+   joy_list[JOY_BUTTON_CODE(0,14)] = JOYCODE_1_UP;
+   joy_list[JOY_BUTTON_CODE(0,15)] = JOYCODE_1_DOWN;
+   joy_list[JOY_BUTTON_CODE(1,12)] = JOYCODE_2_LEFT;
+   joy_list[JOY_BUTTON_CODE(1,13)] = JOYCODE_2_RIGHT;
+   joy_list[JOY_BUTTON_CODE(1,14)] = JOYCODE_2_UP;
+   joy_list[JOY_BUTTON_CODE(1,15)] = JOYCODE_2_DOWN;
+#endif
+
    return OSD_OK;
 }
 
@@ -292,6 +337,11 @@
          joy_usb_init();
          break;
 #endif
+#ifdef PS2_JOYSTICK
+      case JOY_PS2:
+	 joy_ps2_init();
+	 break;
+#endif
       default:
          fprintf (stderr_file, "OSD: Warning: unknown joytype: %d, or joytype not compiled in.\n"
             "   Disabling joystick support.\n", joytype);
@@ -333,6 +383,17 @@
    
    xmame_keyboard_exit();
    
+   switch(joytype)
+   {
+#ifdef PS2_JOYSTICK
+      case JOY_PS2:
+	 joy_ps2_exit();
+	 break;
+#endif
+      default:
+	 break;
+   }
+
    for(i=0;i<JOY;i++)
       if(joy_data[i].fd >= 0)
          close(joy_data[i].fd);
@@ -558,7 +619,7 @@
 
 void joy_evaluate_moves (void)
 {
-   int i, j, treshold;
+   int i, j, threshold;
 
    if( is_usb_ps_gamepad )
     {
@@ -584,11 +645,11 @@
 	     else if (joy_data[i].axis[j].val < joy_data[i].axis[j].min)
 	       joy_data[i].axis[j].min = joy_data[i].axis[j].val;
 	     
-	     treshold = (joy_data[i].axis[j].max - joy_data[i].axis[j].center) >> 1;
+	     threshold = (joy_data[i].axis[j].max - joy_data[i].axis[j].center) >> 1;
 	     
-	     if (joy_data[i].axis[j].val < (joy_data[i].axis[j].center - treshold))
+	     if (joy_data[i].axis[j].val < (joy_data[i].axis[j].center - threshold))
 	       joy_data[i].axis[j].dirs[0] = TRUE;
-	     else if (joy_data[i].axis[j].val > (joy_data[i].axis[j].center + treshold))
+	     else if (joy_data[i].axis[j].val > (joy_data[i].axis[j].center + threshold))
 	       joy_data[i].axis[j].dirs[1] = TRUE;
 	   }
        }
diff -Naur xmame-0.60.1/src/unix/devices.h xmame-0.60.1-ps2/src/unix/devices.h
--- xmame-0.60.1/src/unix/devices.h	2002-05-05 19:07:59.000000000 -0400
+++ xmame-0.60.1-ps2/src/unix/devices.h	2002-05-21 06:45:29.000000000 -0400
@@ -78,7 +78,7 @@
 #define MOUSE_GET_BUTTON(code) \
  ((code - JOY_LIST_LEN) % MOUSE_LIST_TOTAL_ENTRIES)
 
-enum { JOY_NONE, JOY_I386, JOY_PAD, JOY_X11, JOY_I386NEW, JOY_USB };
+enum { JOY_NONE, JOY_I386, JOY_PAD, JOY_X11, JOY_I386NEW, JOY_USB, JOY_PS2 };
 
 /*** variables ***/
 
@@ -132,6 +132,7 @@
 extern struct rc_option joy_pad_opts[];
 extern struct rc_option joy_x11_opts[];
 extern struct rc_option joy_usb_opts[];
+extern struct rc_option joy_ps2_opts[];
 
 #include "joystick-drivers/XInputDevices.h"
 
@@ -141,5 +142,7 @@
 void joy_pad_init(void);
 void joy_x11_init(void);
 void joy_usb_init(void);
+void joy_ps2_init(void);
+void joy_ps2_exit(void);
 #undef EXTERN
 #endif
diff -Naur xmame-0.60.1/src/unix/joystick-drivers/joy_ps2.c xmame-0.60.1-ps2/src/unix/joystick-drivers/joy_ps2.c
--- xmame-0.60.1/src/unix/joystick-drivers/joy_ps2.c	1969-12-31 19:00:00.000000000 -0500
+++ xmame-0.60.1-ps2/src/unix/joystick-drivers/joy_ps2.c	2002-05-21 14:41:35.000000000 -0400
@@ -0,0 +1,430 @@
+/*
+ * XMame PlayStation2 controller support.  Supports standard PlayStation
+ * controllers on a PlayStation2-Linux machine with /dev/ps2padxx drivers
+ *
+ * Written by Joan Touzet <joant@ieee.org> May 2002.
+ * Release 1.0 -- "Cling Peaches"
+ * 
+ * TODO: * Consider allowing user to change controller mode during runtime
+ *         (problematic for games expecting analog input)
+ *       * Select optimal controller mode on a per-game basis
+ *         (wait for 0.60 per-game mapping module to be in place)
+ *       * Store the controller's pre-xmame state and restore on exit
+ *       * Integrate Analog+ patches for better analog support.
+ *       * Test with pure digital, analog controllers (if avail.)
+ */
+
+/* Format of data read from the PS2 Pad:
+ * 32 character-sized bytes
+ * Byte #	Data
+ * ========================================
+ *  0		0x0 = valid data, other = invalid data
+ *  		  (in fact, ps2pad_read will return -EIO if data[0] != 0)
+ *  		  
+ *  1		Packed status data
+ *                Upper byte: pad type, use PS2PAD_TYPE() to shift
+ *  		  Known types:
+ *  		    NEJICON   -- 0x2
+ *  		    DIGITAL   -- 0x4
+ *  		    ANALOG    -- 0x5
+ *  		    DUALSHOCK -- 0x7
+ *  		  (Lower byte * 2 + 2) = upper bound of data[] index
+ *  		    For DIGITAL controllers (and DUALSHOCK controllers in
+ *  		      digital mode) = 0 (only data[2] and data[3] filled)
+ *		    For DUALSHOCK controllers in analog mode = 3
+ *		      (data[4] through data[7] filled)
+ *		      
+ *  2		First half of digital button bits:
+ *  		  76543210
+ *  		  --------
+ *  		  |||||||\__ SELECT
+ *  		  ||||||\___ L3
+ *  		  |||||\____ R3
+ *  		  ||||\_____ START
+ *  		  |||\______ UP
+ *  		  ||\_______ DOWN
+ *  		  |\________ LEFT
+ *  		  \_________ RIGHT
+ *
+ *  3		Second half of digital button bits:
+ *  		  76543210
+ *  		  --------
+ *  		  |||||||\__ L2
+ *  		  ||||||\___ R2
+ *  		  |||||\____ L1
+ *  		  ||||\_____ R1
+ *  		  |||\______ TRIANGLE
+ *  		  ||\_______ CIRCLE
+ *  		  |\________ CROSS
+ *  		  \_________ SQUARE
+ *
+ * 4		(DualShock Analog Mode) Analog Right X Axis
+ * 		  8 unsigned bits ( -127 for signed data)
+ *
+ * 5		(DualShock Analog Mode) Analog Right Y Axis
+ * 		  8 unsigned bits ( -127 for signed data)
+ *
+ * 6		(DualShock Analog Mode) Analog Left X Axis
+ * 		  8 unsigned bits ( -127 for signed data)
+ *
+ * 7		(DualShock Analog Mode) Analog Left Y Axis
+ * 		  8 unsigned bits ( -127 for signed data)
+ */
+
+#include "xmame.h"
+#include "devices.h"
+#include <sys/ioctl.h>
+#include <linux/ps2/pad.h>
+
+/* define the following for PS2 driver debugging */
+#undef JDEBUG
+#define BUFSIZE 128
+/* name of ps2pad device prefix */
+#define PS2PADDEV "/dev/ps2pad"
+/* name of ps2pad status device */
+#define PS2PADSTAT "/dev/ps2padstat"
+
+/* Global definitions to make code more readable.  Taken from the actual
+ * PS2 pad kernel driver source code.
+ */
+char *pad_type_names[16] = {
+	"type 0",
+	"type 1",
+	"NEJICON",	/* PS2PAD_TYPE_NEJICON	*/
+	"type 3",
+	"DIGITAL",	/* PS2PAD_TYPE_DIGITAL	*/
+	"ANALOG",	/* PS2PAD_TYPE_ANALOG	*/
+	"type 6",
+	"DUALSHOCK",	/* PS2PAD_TYPE_DUALSHOCK*/
+	"type 8",
+	"type 9",
+	"type A",
+	"type B",
+	"type C",
+	"type D",
+	"type E",
+	"type F",
+};
+
+char *pad_stat_names[4] = {
+	"Not connected",
+	"Ready",
+	"Busy",
+	"Error",
+};
+
+char *pad_rstat_names[4] = {
+	"Complete",
+	"Failed",
+	"Busy",
+	"UNKNOWN",
+};
+
+struct rc_option joy_ps2_opts[] = {
+   /* name, shortname, type, dest, deflt, min, max, func, help */
+   { NULL,		NULL,			rc_end,		NULL,
+     NULL,		0,			0,		NULL,
+     NULL }
+};
+
+static u_char pad_data[PS2PAD_DATASIZE];
+static int numpads = 0;
+
+/* Forward declarations */
+void joy_ps2_poll(void);
+
+
+/* Lock/unlock the PS2 pad's mode. */
+static void ps2pad_lockset (
+	int fd,				/* fd pointing to pad device */
+	char padtype,			/* Controller mode/type */
+	int lock)			/* 0 = unlock, 1 = lock */
+{
+    struct ps2pad_mode padmode;
+    struct ps2pad_modeinfo modeinfo;
+    int rc, i, max;
+
+    /* First, search the controller's table of possible modes for
+     * a match with the requested mode.  If no match is found,
+     * use the current mode.
+     */
+    modeinfo.term = PS2PAD_MODETABLE;
+    modeinfo.offs = -1;
+    rc = ioctl (fd, PS2PAD_IOCMODEINFO, &modeinfo);
+    if (rc != 0)
+    {
+	fprintf(stderr_file, "Unexpected rc=%d from ps2 IOCMODEINFO ioctl!\n", rc);
+	return;
+    }
+    max = modeinfo.result;
+    for (i=0; i<max; i++)
+    {
+	modeinfo.offs = i;
+	rc = ioctl (fd, PS2PAD_IOCMODEINFO, &modeinfo);
+	if (rc != 0)
+	{
+	    fprintf(stderr_file, "Unexpected rc=%d from ps2 IOCMODEINFO ioctl!\n", rc);
+	    return;
+	}
+	if (modeinfo.result == padtype) 
+	    break;
+    }
+
+    if (i == max) {
+	/* Couldn't find our mode.  Use current mode. */
+	modeinfo.term = PS2PAD_MODECUROFFS;
+	rc = ioctl (fd, PS2PAD_IOCMODEINFO, &modeinfo);
+	i = modeinfo.result;
+	if (rc != 0)
+	{
+	    fprintf(stderr_file, "Unexpected rc=%d from ps2 IOCMODEINFO ioctl!\n", rc);
+	    return;
+	}
+    }
+	
+    /* Now lock or unlock our controller. */
+    padmode.offs = i;
+    /* Magic numbers used:  0, 1: maintain present lock status
+     *                         2: unlock switch
+     *                         3: lock switch
+     */
+    padmode.lock = ((lock == 1) ? 3 : 2);
+    rc = ioctl (fd, PS2PAD_IOCSETMODE, &padmode);
+    if (rc != 0) 
+    {
+	fprintf (stderr_file, "PS2 Pad could not be %slocked! rc=%d \n",
+			(lock == 0) ? "un" : "", rc);
+	exit(-1);
+    }
+    return;
+}
+
+
+/* Initialization routine. */
+void joy_ps2_init (void)
+{
+    int i, j, res, tempfd;
+    char devname[BUFSIZE];
+
+    fprintf (stderr_file, "PlayStation2 pad interface initialization...\n");
+
+
+    /* Check how many possible pads can be connected. */
+    /* The following code has been commented out because it seems to
+     * cause the PS2 to crash intermittently.  Until the bug is
+     * worked out, we'll assume a maximum of 2 devices (since no
+     * more are supported by the kernel anyway.
+     */
+    numpads = 2;
+#if 0
+    sprintf (devname, "%s", PS2PADSTAT);
+    tempfd = open(devname, O_RDONLY|O_NONBLOCK);
+    if (tempfd < 0) {
+	fprintf (stderr_file, "PlayStation2 padstat failed to open!\n");
+	fflush(stderr);
+	return;
+    }
+    res = ioctl(tempfd, PS2PAD_IOCGETNPADS, &numpads);
+    if (res < 0) {
+	fprintf (stderr_file, "PlayStation2 padstat ioctl failed!\n");
+	fflush(stderr);
+	return;
+    }
+    close(tempfd);
+#endif
+
+    /* Now loop through each controller. */
+    for (i = 0; i < numpads; i++)
+    {
+	sprintf (devname, "%s%1d0", PS2PADDEV, i);
+
+	if ((joy_data[i].fd = open (devname, O_RDONLY)) >= 0)
+	{
+	    int ires = PS2PAD_STAT_BUSY;
+
+	    /* We might have just woken up the pad.  Wait for READY */
+	    while (ires == PS2PAD_STAT_READY)
+	    {
+		res = ioctl(joy_data[i].fd, PS2PAD_IOCGETSTAT, &ires);
+		if (res != 0)
+		{
+		    fprintf(stderr_file,
+			"Unexpected rc=%d from ps2 IOCGETSTAT ioctl!\n", res);
+		}
+	    }
+	    if ((ires == PS2PAD_STAT_NOTCON) ||
+			(ires == PS2PAD_STAT_ERROR))
+	    {
+		if (ires == PS2PAD_STAT_ERROR)
+		    fprintf(stderr_file,
+			"PS2 Pad #%d had PS2PAD_STAT_ERROR!\n", i);
+		fprintf(stderr_file,
+			"Pad data corrupt, closing fd %d\n", joy_data[i].fd);
+		close(joy_data[i].fd);
+		joy_data[i].fd = -1;
+		continue;
+	    }
+
+	    /* Lock down the controller's mode. */
+	    ps2pad_lockset(joy_data[i].fd, PS2PAD_TYPE_DUALSHOCK, 1);
+
+	    /* Read pad data and fill in default values */
+	    res = read(joy_data[i].fd, &pad_data, PS2PAD_DATASIZE);
+	    if ((res == 0) || (pad_data[0] != 0))
+ 	    {
+	 	fprintf(stderr_file,
+			"Pad data corrupt, closing fd %d\n", joy_data[i].fd);
+		close(joy_data[i].fd);
+		joy_data[i].fd = -1;
+		continue;
+	    }
+	    
+	    switch(PS2PAD_TYPE(pad_data[1]))
+	    {
+		case PS2PAD_TYPE_DUALSHOCK:
+			/* 4 axes, 16 buttons. */
+			joy_data[i].num_axis = 4;
+			joy_data[i].num_buttons = 16;
+			break;
+		case PS2PAD_TYPE_DIGITAL:
+		default:
+			/* 0 axes, 16 buttons. */
+			joy_data[i].num_axis = 0;
+			joy_data[i].num_buttons = 16;
+	    }
+	    /* Sanity check. */
+	    if (joy_data[i].num_buttons > JOY_BUTTONS)
+		joy_data[i].num_buttons = JOY_BUTTONS;
+	    if (joy_data[i].num_axis > JOY_AXIS)
+		joy_data[i].num_axis = JOY_AXIS;
+
+	    if (PS2PAD_TYPE(pad_data[1]) == PS2PAD_TYPE_DUALSHOCK)
+	    {
+		joy_data[i].axis[0].center = (int)pad_data[6];
+		joy_data[i].axis[1].center = (int)pad_data[7];
+		joy_data[i].axis[2].center = (int)pad_data[4];
+		joy_data[i].axis[3].center = (int)pad_data[5];
+
+		/* Set min/max values to +1/-1 and let autocalibrate
+		 * take care of the rest.
+                 */
+		for (j=0; j<joy_data[i].num_axis; j++)
+		{
+		    if (joy_data[i].axis[j].center == 0)
+			joy_data[i].axis[j].center = 0x7f;
+		    joy_data[i].axis[j].min = joy_data[i].axis[j].center - 1;
+		    joy_data[i].axis[j].max = joy_data[i].axis[j].center + 1;
+		}
+	    }
+
+	    fprintf (stderr_file, "PS2 pad %s is %s\n",
+			    devname,
+			    pad_type_names[PS2PAD_TYPE(pad_data[1])]);
+	    joy_poll_func = joy_ps2_poll;
+	}
+
+    } /* for (numpads) */
+}
+
+
+void joy_ps2_poll (void)
+{
+    int i, res, ires;
+    int buttons;
+
+    for (i=0; i<numpads; i++)
+    {
+	/* Gracefully fail */
+	if (joy_data[i].fd < 0)
+	    continue;
+
+	/* We might have just woken up the pad.  Wait for READY */
+	res = ioctl(joy_data[i].fd, PS2PAD_IOCGETSTAT, &ires);
+	if (res != 0)
+	{
+	    fprintf(stderr_file,
+		"Unexpected rc=%d from ps2 IOCGETSTAT ioctl!\n", res);
+	    fflush(stderr);
+	    return;
+	}
+	if ((ires == PS2PAD_STAT_NOTCON) ||
+		(ires == PS2PAD_STAT_ERROR))
+	{
+	    if (ires == PS2PAD_STAT_ERROR)
+		fprintf(stderr_file,
+			"PS2 Pad #%d had PS2PAD_STAT_ERROR!\n", i);
+	    fprintf(stderr_file,
+		"Pad data corrupt, closing fd %d\n", joy_data[i].fd);
+	    close(joy_data[i].fd);
+	    joy_data[i].fd = -1;
+	    continue;
+	}
+
+	if (ires != PS2PAD_STAT_READY)
+	    continue;
+
+	res = read(joy_data[i].fd, &pad_data, PS2PAD_DATASIZE);
+	if ((res == 0) || (pad_data[0] != 0))
+	{
+	    fprintf(stderr_file,
+		"Pad data corrupt, closing fd %d\n", joy_data[i].fd);
+	    close(joy_data[i].fd);
+	    joy_data[i].fd = -1;
+	    continue;
+	}
+     
+	buttons = ((int)pad_data[2] << 8) | pad_data[3];
+
+#ifdef JDEBUG
+	fprintf(stderr_file, "pad: %x %02x %02x %02x %02x\n",
+			buttons,
+			pad_data[4], pad_data[5], pad_data[6],
+			pad_data[7]);
+#endif
+
+	/* get button values */
+	joy_data[i].buttons[0]  = (buttons & PS2PAD_BUTTON_SQUARE  ) ? 0 : 1;
+	joy_data[i].buttons[1]  = (buttons & PS2PAD_BUTTON_TRIANGLE) ? 0 : 1;
+	joy_data[i].buttons[2]  = (buttons & PS2PAD_BUTTON_CROSS   ) ? 0 : 1;
+	joy_data[i].buttons[3]  = (buttons & PS2PAD_BUTTON_CIRCLE  ) ? 0 : 1;
+	joy_data[i].buttons[4]  = (buttons & PS2PAD_BUTTON_L1      ) ? 0 : 1;
+	joy_data[i].buttons[5]  = (buttons & PS2PAD_BUTTON_R1      ) ? 0 : 1;
+	joy_data[i].buttons[6]  = (buttons & PS2PAD_BUTTON_SELECT  ) ? 0 : 1;
+	joy_data[i].buttons[7]  = (buttons & PS2PAD_BUTTON_START   ) ? 0 : 1;
+	joy_data[i].buttons[8]  = (buttons & PS2PAD_BUTTON_L2      ) ? 0 : 1;
+	joy_data[i].buttons[9]  = (buttons & PS2PAD_BUTTON_R2      ) ? 0 : 1;
+	joy_data[i].buttons[10]  = (buttons & PS2PAD_BUTTON_L3      ) ? 0 : 1;
+	joy_data[i].buttons[11]  = (buttons & PS2PAD_BUTTON_R3      ) ? 0 : 1;
+	joy_data[i].buttons[12]  = (buttons & PS2PAD_BUTTON_LEFT    ) ? 0 : 1;
+	joy_data[i].buttons[13]  = (buttons & PS2PAD_BUTTON_RIGHT   ) ? 0 : 1;
+	joy_data[i].buttons[14]  = (buttons & PS2PAD_BUTTON_UP      ) ? 0 : 1;
+	joy_data[i].buttons[15]  = (buttons & PS2PAD_BUTTON_DOWN    ) ? 0 : 1;
+
+	/* Only read analog data if the pad is in DualShock mode */
+	if (PS2PAD_TYPE(pad_data[1]) == PS2PAD_TYPE_DUALSHOCK)
+	{
+	    joy_data[i].axis[0].val = (int) pad_data[6];
+	    joy_data[i].axis[1].val = (int) pad_data[7];
+	    joy_data[i].axis[2].val = (int) pad_data[4];
+	    joy_data[i].axis[3].val = (int) pad_data[5];
+	}
+
+    }
+
+    /* evaluate joystick movements */
+   joy_evaluate_moves ();
+}
+
+
+void joy_ps2_exit()
+{
+
+   int i;
+   for (i=0; i<numpads; i++)
+   {
+      /* A -1 as the joytype will leave the pad in its current state,
+       * since it will never match a real joypad type
+       */
+      ps2pad_lockset(joy_data[i].fd, -1, 0);
+   }
+}
diff -Naur xmame-0.60.1/src/unix/unix.mak xmame-0.60.1-ps2/src/unix/unix.mak
--- xmame-0.60.1/src/unix/unix.mak	2002-05-02 22:53:53.000000000 -0400
+++ xmame-0.60.1-ps2/src/unix/unix.mak	2002-05-19 11:29:20.000000000 -0400
@@ -225,6 +225,9 @@
 ifdef JOY_PAD
 CONFIG += -DLIN_FM_TOWNS
 endif
+ifdef JOY_PS2
+CONFIG += -DPS2_JOYSTICK
+endif
 ifdef JOY_USB
 CONFIG += -DUSB_JOYSTICK
 ifeq ($(ARCH), netbsd)
diff -Naur xmame-0.60.1/src/unix/video-drivers/SDL.c xmame-0.60.1-ps2/src/unix/video-drivers/SDL.c
--- xmame-0.60.1/src/unix/video-drivers/SDL.c	2002-05-02 22:53:54.000000000 -0400
+++ xmame-0.60.1-ps2/src/unix/video-drivers/SDL.c	2002-05-19 10:05:22.000000000 -0400
@@ -26,6 +26,7 @@
        Test mouse buttons (which games use them?)
 
 ***************************************************************************/
+#define PARANOIC
 #define __SDL_C
 
 #undef SDL_DEBUG
@@ -578,7 +579,7 @@
       H_Palette_modified = 0;
    }
    
-#ifdef PANANOIC 
+#ifdef PARANOIC 
       memset(Offscreen_surface->pixels,'\0' ,Vid_height * Vid_width);
 #endif 
 
