diff -Nru base0122/src/emu/inptport.c w0122/src/emu/inptport.c
--- base0122/src/emu/inptport.c	2007-12-18 05:41:39.000000000 +1300
+++ w0122/src/emu/inptport.c	2007-12-19 10:55:18.000000000 +1300
@@ -90,6 +90,7 @@
     except that the accumulated deltas are not bounded, but rather wrap.
 
 ***************************************************************************/
+#define _USE_32BIT_TIME_T  // VC2005 uses a 64-bit time_t structure by default
 
 #include "osdepend.h"
 #include "driver.h"
@@ -231,7 +232,7 @@
 	char header[7];  // must be "XINP" followed by NULLs
 	char shortname[9];  // game shortname
 	char version[32];  // MAME version string
-	long starttime;  // approximate INP start time
+	UINT32 starttime;  // approximate INP start time
 	char dummy[32];  // for possible future expansion
 };
 
@@ -270,10 +271,10 @@
 static input_port_entry *input_ports_default;
 
 /* recorded speed read from an INP file */
-static double rec_speed;
+double rec_speed;
 
 /* set to 1 if INP file being played is a standard MAME INP file */
-static int no_extended_inp;
+int no_extended_inp;
 
 /* for average speed calculations */
 static int framecount;
@@ -322,8 +323,6 @@
 	input_port_28_dword_r,	input_port_29_dword_r,	input_port_30_dword_r,	input_port_31_dword_r
 };
 
-
-
 /***************************************************************************
     COMMON SHARED STRINGS
 ***************************************************************************/
@@ -445,7 +444,6 @@
 };
 
 
-
 /***************************************************************************
     DEFAULT INPUT PORTS
 ***************************************************************************/
@@ -1225,8 +1223,9 @@
 static void setup_record(running_machine *machine)
 {
 	const char *filename = options_get_string(mame_options(), OPTION_RECORD);
-	inp_header inpheader;
+	//inp_header inpheader;
 	file_error filerr;
+	struct ext_header xheader;
 
 	/* if no file, nothing to do */
 	if (filename[0] == 0)
@@ -1236,10 +1235,16 @@
 	filerr = mame_fopen(SEARCHPATH_INPUTLOG, filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &machine->record_file);
 	assert_always(filerr == FILERR_NONE, "Failed to open file for recording");
 
+	/* disable cheats */
+	options_set_bool(mame_options(),OPTION_CHEAT,0,OPTION_PRIORITY_MAXIMUM);
+
 	/* create a header */
-	memset(&inpheader, 0, sizeof(inpheader));
-	strcpy(inpheader.name, machine->gamedrv->name);
-	mame_fwrite(machine->record_file, &inpheader, sizeof(inpheader));
+	memset(&xheader, '\0', sizeof(struct ext_header));
+	strcpy(xheader.header, "XINP\0\0\0");
+	strcpy(xheader.shortname, machine->gamedrv->name);
+	strcpy(xheader.version, build_version);
+	xheader.starttime = (UINT32)time(NULL);
+	mame_fwrite(Machine->record_file, &xheader, sizeof(struct ext_header));
 }
 
 
@@ -1255,8 +1260,13 @@
 	/* close any playback or recording files */
 	if (machine->playback_file != NULL)
 		mame_fclose(machine->playback_file);
-	if (machine->record_file != NULL)
-		mame_fclose(machine->record_file);
+  	if (machine->record_file != NULL)
+	{
+		UINT32 val = (UINT32)time(NULL);
+		mame_fseek(machine->record_file,52,SEEK_SET);
+		mame_fwrite(machine->record_file,&val,sizeof(UINT32));
+  		mame_fclose(machine->record_file);
+	}
 }
 
 
@@ -2798,7 +2808,7 @@
 			}
 		}
 	}
-
+	else  // because re-recording is cheating
 	/* handle recording */
 	if (Machine->record_file != NULL)
 	{
@@ -2971,7 +2981,7 @@
 				/* note that analog ports are handled instantaneously at port read time */
 			}
 	}
-
+	
 #ifdef MESS
 	/* less MESS to MESSy things */
 	inputx_update();
@@ -3006,12 +3016,21 @@
 			update_playback_record(portnum, readinputport(portnum));
 	}
 
+	/* record speed */
+	if(Machine->record_file != NULL)
+	{
+		double speed = video_get_speed_percent();
+		UINT32 marker = 0x00ABCDEF;  // end of frame marker
+		mame_fwrite(Machine->record_file,&speed,sizeof(double));
+		mame_fwrite(Machine->record_file,&marker,sizeof(UINT32));
+	}
+
 	/* store speed read from INP file, if extended INP */
 	if (Machine->playback_file != NULL && !no_extended_inp)
 	{
-		long dummy;
+		UINT32 dummy;
 		mame_fread(Machine->playback_file,&rec_speed,sizeof(double));
-		mame_fread(Machine->playback_file,&dummy,sizeof(long));
+		mame_fread(Machine->playback_file,&dummy,sizeof(UINT32));
 		framecount++;
 		rec_speed *= 100;
 		totalspeed += rec_speed;
diff -Nru base0122/src/emu/ui.c w0122/src/emu/ui.c
--- base0122/src/emu/ui.c	2007-12-18 05:41:39.000000000 +1300
+++ w0122/src/emu/ui.c	2007-12-19 10:43:51.000000000 +1300
@@ -321,7 +321,7 @@
 	int state;
 
 	/* disable everything if we are using -str */
-	if (!first_time || (str > 0 && str < 60*5) || Machine->gamedrv == &driver_empty)
+	if (!first_time || (str > 0 && str < 60*5) || Machine->gamedrv == &driver_empty  || Machine->record_file)
 		show_gameinfo = show_warnings = show_disclaimer = FALSE;
 
 	/* initialize the on-screen display system */
@@ -1286,7 +1286,7 @@
 		mame_schedule_soft_reset(Machine);
 
 	/* handle a request to display graphics/palette */
-	if (input_ui_pressed(IPT_UI_SHOW_GFX))
+	if (input_ui_pressed(IPT_UI_SHOW_GFX) && !Machine->record_file)
 	{
 		if (!is_paused)
 			mame_pause(Machine, TRUE);
@@ -1294,14 +1294,14 @@
 	}
 
 	/* handle a save state request */
-	if (input_ui_pressed(IPT_UI_SAVE_STATE))
+	if (input_ui_pressed(IPT_UI_SAVE_STATE) && !Machine->record_file)
 	{
 		mame_pause(Machine, TRUE);
 		return ui_set_handler(handler_load_save, LOADSAVE_SAVE);
 	}
 
 	/* handle a load state request */
-	if (input_ui_pressed(IPT_UI_LOAD_STATE))
+	if (input_ui_pressed(IPT_UI_LOAD_STATE) && !Machine->record_file)
 	{
 		mame_pause(Machine, TRUE);
 		return ui_set_handler(handler_load_save, LOADSAVE_LOAD);
@@ -1312,7 +1312,7 @@
 		video_save_active_screen_snapshots(Machine);
 
 	/* toggle pause */
-	if (input_ui_pressed(IPT_UI_PAUSE))
+	if (input_ui_pressed(IPT_UI_PAUSE) && !Machine->record_file)
 	{
 		/* with a shift key, it is single step */
 		if (is_paused && (input_code_pressed(KEYCODE_LSHIFT) || input_code_pressed(KEYCODE_RSHIFT)))
@@ -1378,11 +1378,11 @@
 	}
 
 	/* toggle throttle? */
-	if (input_ui_pressed(IPT_UI_THROTTLE))
+	if (input_ui_pressed(IPT_UI_THROTTLE) && !Machine->record_file)
 		video_set_throttle(!video_get_throttle());
 
 	/* check for fast forward */
-	if (input_port_type_pressed(IPT_UI_FAST_FORWARD, 0))
+	if (input_port_type_pressed(IPT_UI_FAST_FORWARD, 0) && !Machine->record_file)
 	{
 		video_set_fastforward(TRUE);
 		ui_show_fps_temp(0.5);
diff -Nru base0122/src/emu/uimenu.c w0122/src/emu/uimenu.c
--- base0122/src/emu/uimenu.c	2007-12-18 05:41:39.000000000 +1300
+++ w0122/src/emu/uimenu.c	2007-12-19 10:43:51.000000000 +1300
@@ -634,7 +634,7 @@
 		*selected = num_items - 1;
 
 	/* pause enables/disables pause */
-	if (input_ui_pressed(IPT_UI_PAUSE))
+	if (input_ui_pressed(IPT_UI_PAUSE) && !Machine->record_file)
 		mame_pause(Machine, !mame_is_paused(Machine));
 
 	return 0;
diff -Nru base0122/src/emu/video.c w0122/src/emu/video.c
--- base0122/src/emu/video.c	2007-12-18 05:41:39.000000000 +1300
+++ w0122/src/emu/video.c	2007-12-19 10:43:51.000000000 +1300
@@ -158,7 +158,9 @@
 	{ 0,1,1,1,1,1,1,1,1,1,1,1 }
 };
 
-
+// speed recorded in INP file
+extern double rec_speed;
+extern int no_extended_inp;
 
 /***************************************************************************
     FUNCTION PROTOTYPES
@@ -1216,6 +1218,10 @@
 	if (global.partial_updates_this_frame > 1)
 		dest += sprintf(dest, "\n%d partial updates", global.partial_updates_this_frame);
 
+	/* display recorded speed on playback */
+	if(Machine->playback_file != NULL && !no_extended_inp)
+		dest += sprintf(dest,"\n Recorded speed %f%%", rec_speed);
+
 	/* return a pointer to the static buffer */
 	return buffer;
 }
@@ -2196,6 +2202,10 @@
 	}
 }
 
+double video_get_speed_percent(void)
+{
+	return global.speed_percent;
+}
 
 
 /***************************************************************************
diff -Nru base0122/src/emu/video.h w0122/src/emu/video.h
--- base0122/src/emu/video.h	2007-12-18 05:37:57.000000000 +1300
+++ w0122/src/emu/video.h	2007-12-19 10:43:51.000000000 +1300
@@ -166,4 +166,6 @@
 
 void video_crosshair_toggle(void);
 
+double video_get_speed_percent(void);
+
 #endif	/* __VIDEO_H__ */
diff -Nru base0113s/src/emu/info.c w0113/src/emu/info.c
--- base0113s/src/emu/info.c	2007-02-12 16:43:00.000000000 +1300
+++ w0113/src/emu/info.c	2007-03-06 10:40:09.000000000 +1300
@@ -36,6 +36,7 @@
 static void print_game_switch(FILE* out, const game_driver* game)
 {
 	const input_port_entry* input;
+	int port = -1;
 
 	begin_resource_tracking();
 
@@ -43,6 +44,9 @@
 
 	while (input->type != IPT_END)
 	{
+		if(input->start.tag != NULL)
+			port++;
+
 		if (input->type==IPT_DIPSWITCH_NAME)
 		{
 			int def = input->default_value;
@@ -50,6 +54,8 @@
 			fprintf(out, "\t\t<dipswitch");
 
 			fprintf(out, " name=\"%s\"", xml_normalize_string(input->name));
+			fprintf(out, " mask=\"%i\"", input->mask);
+			fprintf(out, " port=\"%i\"", port);
 			++input;
 
 			fprintf(out, ">\n");
@@ -58,6 +64,7 @@
 			{
 				fprintf(out, "\t\t\t<dipvalue");
 				fprintf(out, " name=\"%s\"", xml_normalize_string(input->name));
+				fprintf(out, " value=\"%i\"", input->default_value);
 				if (def == input->default_value)
 					fprintf(out, " default=\"yes\"");
 
diff -Nru base0120/src/emu/emu.mak w0120/src/emu/emu.mak
--- base0120/src/emu/emu.mak	2007-10-15 19:58:53.000000000 +1300
+++ w0120/src/emu/emu.mak	2007-10-16 01:00:34.000000000 +1300
@@ -75,6 +75,7 @@
 	$(EMUOBJ)/uitext.o \
 	$(EMUOBJ)/validity.o \
 	$(EMUOBJ)/video.o \
+	$(EMUOBJ)/inpview.o \
 
 ifdef PROFILER
 EMUOBJS += \
diff -Nru base0120/src/emu/emuopts.c w0120/src/emu/emuopts.c
--- base0120/src/emu/emuopts.c	2007-09-11 18:16:58.000000000 +1200
+++ w0120/src/emu/emuopts.c	2007-10-16 00:58:01.000000000 +1300
@@ -156,6 +156,8 @@
 	{ "bios",                        "default",   0,                 "select the system BIOS to use" },
 	{ "cheat;c",                     "0",         OPTION_BOOLEAN,    "enable cheat subsystem" },
 	{ "skip_gameinfo",               "0",         OPTION_BOOLEAN,    "skip displaying the information screen at startup" },
+	{ "inpview;iv",		             "0",         0,                 "enable input viewer" },
+	{ "inplayout;il",                "standard",  0,                 "set input viewer layout type" },
 
 	{ NULL }
 };
diff -Nru base0120/src/emu/inptport.c w0120/src/emu/inptport.c
--- base0120/src/emu/inptport.c	2007-09-29 15:57:09.000000000 +1200
+++ w0120/src/emu/inptport.c	2007-10-16 00:58:01.000000000 +1300
@@ -106,6 +106,7 @@
 #include "inputx.h"
 #endif
 
+#include "inpview.h"
 
 /***************************************************************************
     CONSTANTS
@@ -1140,6 +1141,9 @@
 	/* register callbacks for when we load configurations */
 	config_register("input", input_port_load, input_port_save);
 
+	/* INPVIEW: initialise -inpview and -inplayout options */
+	inpview_set_data(options_get_int(mame_options(),"inpview"),options_get_string(mame_options(),"inplayout"));
+
 	/* open playback and record files if specified */
 	setup_playback(machine);
 	setup_record(machine);
@@ -3599,3 +3603,30 @@
 				break;
 			}
 }
+
+int input_port_used(int type,int player)
+{
+	int portnum, bitnum;
+
+	/* loop over all input ports */
+	for (portnum = 0; portnum < MAX_INPUT_PORTS; portnum++)
+	{
+		input_port_info *portinfo = &port_info[portnum];
+		input_bit_info *info;
+		unsigned long portvalue;
+
+		for (bitnum = 0, info = &portinfo->bit[0]; bitnum < MAX_BITS_PER_PORT && info->port; bitnum++, info++)
+		{
+			portvalue = portinfo->playback;
+
+			if(info->port->type == type && info->port->player == player)
+			{
+				if((info->port->type == type) && (portvalue & info->port->mask) != (info->port->default_value & info->port->mask))
+					return 1;
+				else
+					return 0;
+			}
+		}
+	}
+	return 0;
+}
diff -Nru base0120/src/emu/inptport.h w0120/src/emu/inptport.h
--- base0120/src/emu/inptport.h	2007-09-29 15:57:09.000000000 +1200
+++ w0120/src/emu/inptport.h	2007-10-16 00:58:01.000000000 +1300
@@ -899,4 +899,6 @@
 UINT32 readinputportbytag(const char *tag);
 UINT32 readinputportbytag_safe(const char *tag, UINT32 defvalue);
 
+int input_port_used(int, int);
+
 #endif	/* __INPTPORT_H__ */
diff -Nru base0120/src/emu/inpview.c w0120/src/emu/inpview.c
--- base0120/src/emu/inpview.c	1970-01-01 13:00:00.000000000 +1300
+++ w0120/src/emu/inpview.c	2007-10-16 00:58:01.000000000 +1300
@@ -0,0 +1,258 @@
+// Input viewer module for MAME
+// Complete re-write started Aug 23, 2006
+
+#include <stdio.h>
+#include "ui.h"
+#include "uitext.h"
+#include "inptport.h"
+#include "render.h"
+#include "inpview.h"
+
+#define CHAR_WIDTH  (1.0f / 80.0f)
+#define INPUT_TYPES 5
+
+#define COL_RED     MAKE_ARGB(0xff, 0xff, 0x00, 0x00)
+#define COL_BLUE    MAKE_ARGB(0xff, 0x00, 0x00, 0xff)
+#define COL_GREEN   MAKE_ARGB(0xff, 0x00, 0xff, 0x00)
+#define COL_YELLOW  MAKE_ARGB(0xff, 0xff, 0xff, 0x00)
+#define COL_ORANGE  MAKE_ARGB(0xff, 0xff, 0x80, 0x00)
+#define COL_BLACK   MAKE_ARGB(0xff, 0x00, 0x00, 0x00)
+#define COL_GRAY    MAKE_ARGB(0xff, 0x80, 0x80, 0x80)
+#define COL_WHITE   MAKE_ARGB(0xff, 0xff, 0xff, 0xff)
+
+#define BGCOL       MAKE_ARGB(0x80, 0x80, 0x00, 0x00)
+
+// uncomment if you plan to use MAME's built-in font
+//#define OLD_UI_FONT 1
+
+#ifndef OLD_UI_FONT
+#define DIR_LEFT   0x2190
+#define DIR_UP     0x2191
+#define DIR_RIGHT  0x2192
+#define DIR_DOWN   0x2193
+#else
+#define DIR_LEFT   'L'
+#define DIR_UP     'U'
+#define DIR_RIGHT  'R'
+#define DIR_DOWN   'D'
+#endif
+
+struct input_type_definition inptype[INPUT_TYPES] = 
+{
+	{
+		"standard",
+		1,
+		{
+			{"1P", IPT_START1, 1, 50, 0, 0, COL_WHITE},
+			{"2P", IPT_START2, 1, 53, 0, 0, COL_WHITE},
+			{"3P", IPT_START3, 1, 56, 0, 0, COL_WHITE},
+			{"4P", IPT_START4, 1, 59, 0, 0, COL_WHITE},
+			{"5P", IPT_START5, 1, 62, 0, 0, COL_WHITE},
+			{"6P", IPT_START6, 1, 65, 0, 0, COL_WHITE},
+			{"7P", IPT_START7, 1, 68, 0, 0, COL_WHITE},
+			{"8P", IPT_START8, 1, 71, 0, 0, COL_WHITE},
+			{"1",  IPT_BUTTON1, 1, 20, 0, 1, COL_WHITE},
+			{"2",  IPT_BUTTON2, 1, 22, 0, 1, COL_WHITE},
+			{"3",  IPT_BUTTON3, 1, 24, 0, 1, COL_WHITE},
+			{"4",  IPT_BUTTON4, 1, 26, 0, 1, COL_WHITE},
+			{"5",  IPT_BUTTON5, 1, 28, 0, 1, COL_WHITE},
+			{"6",  IPT_BUTTON6, 1, 30, 0, 1, COL_WHITE},
+			{"7",  IPT_BUTTON7, 1, 32, 0, 1, COL_WHITE},
+			{"8",  IPT_BUTTON8, 1, 34, 0, 1, COL_WHITE},
+			{"9",  IPT_BUTTON9, 1, 36, 0, 1, COL_WHITE},
+			{"0",  IPT_BUTTON10, 1, 38, 0, 1, COL_WHITE},
+			{"_L",  IPT_JOYSTICK_LEFT, 1, 10, 0, 1, COL_WHITE},
+			{"_R",  IPT_JOYSTICK_RIGHT, 1, 12, 0, 1, COL_WHITE},
+			{"_U",  IPT_JOYSTICK_UP, 1, 14, 0, 1, COL_WHITE},
+			{"_D",  IPT_JOYSTICK_DOWN, 1, 16, 0, 1, COL_WHITE},
+			{"NULL", -1, 0,0,0,0,0}
+		}
+	},
+	{
+		"mahjong",
+		2,
+		{
+			{"1P", IPT_START1, 1, 50, 0, 0, COL_WHITE},
+			{"2P", IPT_START2, 1, 53, 0, 0, COL_WHITE},
+			{"3P", IPT_START3, 1, 56, 0, 0, COL_WHITE},
+			{"4P", IPT_START4, 1, 59, 0, 0, COL_WHITE},
+			{"5P", IPT_START5, 1, 62, 0, 0, COL_WHITE},
+			{"6P", IPT_START6, 1, 65, 0, 0, COL_WHITE},
+			{"7P", IPT_START7, 1, 68, 0, 0, COL_WHITE},
+			{"8P", IPT_START8, 1, 71, 0, 0, COL_WHITE},
+			{"A",  IPT_MAHJONG_A, 1, 10, 0, 1, COL_WHITE},
+			{"B",  IPT_MAHJONG_B, 1, 12, 0, 1, COL_WHITE},
+			{"C",  IPT_MAHJONG_C, 1, 14, 0, 1, COL_WHITE},
+			{"D",  IPT_MAHJONG_D, 1, 16, 0, 1, COL_WHITE},
+			{"E",  IPT_MAHJONG_E, 1, 18, 0, 1, COL_WHITE},
+			{"F",  IPT_MAHJONG_F, 1, 20, 0, 1, COL_WHITE},
+			{"G",  IPT_MAHJONG_G, 1, 22, 0, 1, COL_WHITE},
+			{"H",  IPT_MAHJONG_H, 1, 24, 0, 1, COL_WHITE},
+			{"I",  IPT_MAHJONG_I, 1, 26, 0, 1, COL_WHITE},
+			{"J",  IPT_MAHJONG_J, 1, 28, 0, 1, COL_WHITE},
+			{"K",  IPT_MAHJONG_K, 1, 30, 0, 1, COL_WHITE},
+			{"L",  IPT_MAHJONG_L, 1, 32, 0, 1, COL_WHITE},
+			{"M",  IPT_MAHJONG_M, 1, 34, 0, 1, COL_WHITE},
+			{"N",  IPT_MAHJONG_N, 1, 36, 0, 1, COL_WHITE},
+			{"O",  IPT_MAHJONG_O, 1, 38, 0, 1, COL_WHITE},
+			{"P",  IPT_MAHJONG_P, 1, 40, 0, 1, COL_WHITE},
+			{"Q",  IPT_MAHJONG_Q, 1, 42, 0, 1, COL_WHITE},
+			{"REACH",  IPT_MAHJONG_REACH, 2, 14, 0, 1, COL_WHITE},
+			{"CHI",  IPT_MAHJONG_CHI, 2, 26, 0, 1, COL_WHITE},
+			{"PON",  IPT_MAHJONG_PON, 2, 34, 0, 1, COL_WHITE},
+			{"KAN",  IPT_MAHJONG_KAN, 2, 42, 0, 1, COL_WHITE},
+			{"RON",  IPT_MAHJONG_RON, 2, 50, 0, 1, COL_WHITE},
+			{"BET",  IPT_MAHJONG_BET, 2, 58, 0, 1, COL_WHITE},
+			{"NULL", -1, 0,0,0,0,0}
+		}
+	},
+	{
+		"dualstick",
+		1,
+		{
+			{"1P", IPT_START1, 1, 50, 0, 0, COL_WHITE},
+			{"2P", IPT_START2, 1, 53, 0, 0, COL_WHITE},
+			{"3P", IPT_START3, 1, 56, 0, 0, COL_WHITE},
+			{"4P", IPT_START4, 1, 59, 0, 0, COL_WHITE},
+			{"5P", IPT_START5, 1, 62, 0, 0, COL_WHITE},
+			{"6P", IPT_START6, 1, 65, 0, 0, COL_WHITE},
+			{"7P", IPT_START7, 1, 68, 0, 0, COL_WHITE},
+			{"8P", IPT_START8, 1, 71, 0, 0, COL_WHITE},
+			{"1",  IPT_BUTTON1, 1, 30, 0, 1, COL_WHITE},
+			{"2",  IPT_BUTTON2, 1, 32, 0, 1, COL_WHITE},
+			{"3",  IPT_BUTTON3, 1, 34, 0, 1, COL_WHITE},
+			{"4",  IPT_BUTTON4, 1, 36, 0, 1, COL_WHITE},
+			{"5",  IPT_BUTTON5, 1, 38, 0, 1, COL_WHITE},
+			{"6",  IPT_BUTTON6, 1, 40, 0, 1, COL_WHITE},
+			{"7",  IPT_BUTTON7, 1, 42, 0, 1, COL_WHITE},
+			{"8",  IPT_BUTTON8, 1, 44, 0, 1, COL_WHITE},
+			{"9",  IPT_BUTTON9, 1, 46, 0, 1, COL_WHITE},
+			{"0",  IPT_BUTTON10, 1, 48, 0, 1, COL_WHITE},
+			{"_L",  IPT_JOYSTICKLEFT_LEFT,   1, 6, 0, 1, COL_WHITE},
+			{"_R",  IPT_JOYSTICKLEFT_RIGHT,  1, 8, 0, 1, COL_WHITE},
+			{"_U",  IPT_JOYSTICKLEFT_UP,     1, 10, 0, 1, COL_WHITE},
+			{"_D",  IPT_JOYSTICKLEFT_DOWN,   1, 12, 0, 1, COL_WHITE},
+			{"_L",  IPT_JOYSTICKRIGHT_LEFT,  1, 18, 0, 1, COL_WHITE},
+			{"_R",  IPT_JOYSTICKRIGHT_RIGHT, 1, 20, 0, 1, COL_WHITE},
+			{"_U",  IPT_JOYSTICKRIGHT_UP,    1, 22, 0, 1, COL_WHITE},
+			{"_D",  IPT_JOYSTICKRIGHT_DOWN,  1, 24, 0, 1, COL_WHITE},
+			{"NULL", -1, 0,0,0,0,0}
+		}
+	},
+	{
+		"neogeo",
+		2,
+		{
+			{"1P", IPT_START1, 2, 53, 0, 0, COL_YELLOW},
+			{"2P", IPT_START2, 1, 53, 0, 0, COL_YELLOW},
+			{"A",  IPT_BUTTON1, 1, 26, 0, 1, COL_RED},
+			{"B",  IPT_BUTTON2, 2, 29, 0, 1, COL_YELLOW},
+			{"C",  IPT_BUTTON3, 2, 32, 0, 1, COL_GREEN},
+			{"D",  IPT_BUTTON4, 1, 35, 0, 1, COL_BLUE},
+			{"_L",  IPT_JOYSTICK_LEFT, 1, 15, 0, 1, COL_WHITE},
+			{"_R",  IPT_JOYSTICK_RIGHT, 1, 19, 0, 1, COL_WHITE},
+			{"_U",  IPT_JOYSTICK_UP, 2, 17, 0, 1, COL_WHITE},
+			{"_D",  IPT_JOYSTICK_DOWN, 1, 17, 0, 1, COL_WHITE},
+			{"NULL", -1, 0,0,0,0,0}
+		}
+	},
+	{
+		"6button",
+		2,
+		{
+			{"1P", IPT_START1, 2, 53, 0, 0, COL_YELLOW},
+			{"2P", IPT_START2, 1, 53, 0, 0, COL_YELLOW},
+			{"1",  IPT_BUTTON1, 2, 30, 0, 1, COL_WHITE},
+			{"2",  IPT_BUTTON2, 2, 33, 0, 1, COL_WHITE},
+			{"3",  IPT_BUTTON3, 2, 36, 0, 1, COL_WHITE},
+			{"4",  IPT_BUTTON4, 1, 30, 0, 1, COL_WHITE},
+			{"5",  IPT_BUTTON5, 1, 33, 0, 1, COL_WHITE},
+			{"6",  IPT_BUTTON6, 1, 36, 0, 1, COL_WHITE},
+			{"_L",  IPT_JOYSTICK_LEFT, 1, 15, 0, 1, COL_WHITE},
+			{"_R",  IPT_JOYSTICK_RIGHT, 1, 19, 0, 1, COL_WHITE},
+			{"_U",  IPT_JOYSTICK_UP, 2, 17, 0, 1, COL_WHITE},
+			{"_D",  IPT_JOYSTICK_DOWN, 1, 17, 0, 1, COL_WHITE},
+			{"NULL", -1, 0,0,0,0,0}
+		}
+	}
+};
+
+int player;
+int layout;
+
+void render_input()
+{
+	int port = 0;
+	char txt[6];
+	float height = ui_get_line_height();
+
+	if(player < 1 || player > 8)
+		return;  // invalid player
+
+	render_ui_add_rect(0.0f,1.0f-(float)(inptype[layout].lines*height),1.0f,1.0f,BGCOL,PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+	while(inptype[layout].inp[port].port != -1)
+	{
+		strcpy(txt,inptype[layout].inp[port].text);
+
+		if(inptype[layout].inp[port].playerspecific == 0)
+		{
+			if(input_port_used(inptype[layout].inp[port].port,0) != 0)
+			{
+				int ch = convert_txt(txt);
+				int col = inptype[layout].inp[port].colour;
+				if(ch == 0)
+					ui_draw_text_full(txt,(float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),1.0f,JUSTIFY_LEFT,WRAP_NEVER,DRAW_OPAQUE,col,0,NULL,NULL);
+				else
+					render_ui_add_char((float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),height,render_get_ui_aspect(),col,ui_get_font(),ch);
+			}
+		}
+		else
+		{
+			if(input_port_used(inptype[layout].inp[port].port,player-1) != 0)
+			{
+				int ch = convert_txt(txt);
+				int col = inptype[layout].inp[port].colour;
+				if(ch == 0)
+					ui_draw_text_full(txt,(float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),1.0f,JUSTIFY_LEFT,WRAP_NEVER,DRAW_OPAQUE,col,0,NULL,NULL);
+				else
+					render_ui_add_char((float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),height,render_get_ui_aspect(),col,ui_get_font(),ch);
+			}
+		}
+		port++;
+	}
+}
+
+void inpview_set_data(int ply, const char* lay)
+{
+	player = ply;
+	layout = 0;
+	while(layout < INPUT_TYPES)
+	{
+		if(strcmp(inptype[layout].name,lay) == 0)
+		{
+			printf("INPVIEW: using layout type '%s'\n",lay);
+			return;
+		}
+		layout++;
+	}
+	printf("INPVIEW: invalid type specified, standard layout in use\n");
+	layout = 0;
+}
+
+int inpview_get_player()
+{
+	return player;
+}
+
+unsigned int convert_txt(char* txt)
+{
+		if(strcmp(txt,"_L") == 0)
+			return DIR_LEFT;
+		if(strcmp(txt,"_R") == 0)
+			return DIR_RIGHT;
+		if(strcmp(txt,"_U") == 0)
+			return DIR_UP;
+		if(strcmp(txt,"_D") == 0)
+			return DIR_DOWN;
+	return 0;
+}
diff -Nru base0120/src/emu/inpview.h w0120/src/emu/inpview.h
--- base0120/src/emu/inpview.h	1970-01-01 13:00:00.000000000 +1300
+++ w0120/src/emu/inpview.h	2007-10-16 00:58:01.000000000 +1300
@@ -0,0 +1,24 @@
+// Input viewer header
+
+struct inputs
+{
+	char text[6];  // character(s) to display
+	int port;  // port to check
+	int line;  // line to display on
+	int x;  // location on line to display at
+	char isanalogue;  // non-zero if the input is analogue
+	char playerspecific;  // is a player specific port (if 0, then player should be 0 too)
+	unsigned long colour;
+};
+
+struct input_type_definition
+{
+	char name[13];  // NULL-terminated string to identify different type using a possible -inplayout option
+	int lines;  // number of lines to use for this type
+	struct inputs inp[64];  // list of displayed buttons, and the inputs they correspond to (64 max)
+};
+
+void render_input(void);
+void inpview_set_data(int,const char*);
+int inpview_get_player(void);
+unsigned int convert_txt(char*);
diff -Nru base0120/src/emu/ui.c w0120/src/emu/ui.c
--- base0120/src/emu/ui.c	2007-09-07 04:42:07.000000000 +1200
+++ w0120/src/emu/ui.c	2007-10-16 00:58:01.000000000 +1300
@@ -31,7 +31,7 @@
 #include <stdarg.h>
 #include <math.h>
 
-
+#include "inpview.h"
 
 /***************************************************************************
     CONSTANTS
@@ -452,6 +452,10 @@
 	/* let MESS display its stuff */
 	mess_ui_update();
 #endif
+
+	// Input viewer
+	if(Machine->playback_file && inpview_get_player() != 0)
+		render_input();
 }
 
 
diff -Nru mess/src/emu/video/tms9928a.c mess_modified/src/emu/video/tms9928a.c
--- mess/src/emu/video/tms9928a.c	2007-10-15 03:58:53.000000000 -0300
+++ mess_modified/src/emu/video/tms9928a.c	2007-10-23 00:42:22.000000000 -0300
@@ -120,7 +120,7 @@
 #define LEFT_BORDER			15		/* a bit less for 9918a??? */
 #define RIGHT_BORDER		15		/* 13 for 9929a */
 #define TOP_BORDER_60HZ		27
-#define BOTTOM_BORDER_60HZ	24
+#define BOTTOM_BORDER_60HZ	27
 #define TOP_BORDER_50HZ		51		/* unknown (102 for top+bottom?) */
 #define BOTTOM_BORDER_50HZ	51		/* unknown (102 for top+bottom?) */
 #define TOP_BORDER			tms.top_border
@@ -233,6 +233,10 @@
 	return &tms.visarea;
 }
 
+/* hide borders */
+void TMS9928A_hide_borders (int hide_borders) {
+	video_screen_set_visarea (0, LEFT_BORDER - (hide_borders ? 0 : 8), LEFT_BORDER + 256 + (hide_borders ? 0 : 8) - 1, TOP_BORDER - (hide_borders ? 0 : 24), TOP_BORDER + 192 + (hide_borders ? 0 : 24) - 1);
+}
 
 void TMS9928A_post_load (void) {
 	int i;
diff -Nru mess/src/emu/video/tms9928a.h mess_modified/src/emu/video/tms9928a.h
--- mess/src/emu/video/tms9928a.h	2007-10-15 03:58:53.000000000 -0300
+++ mess_modified/src/emu/video/tms9928a.h	2007-10-23 00:42:22.000000000 -0300
@@ -86,3 +86,6 @@
 ** MachineDriver video declarations for the TMS9928A chip
 */
 MACHINE_DRIVER_EXTERN( tms9928a );
+
+/* hide borders */
+void TMS9928A_hide_borders (int i);
diff -Nru mess/src/emu/video/v9938.c mess_modified/src/emu/video/v9938.c
--- mess/src/emu/video/v9938.c	2007-10-15 03:58:53.000000000 -0300
+++ mess_modified/src/emu/video/v9938.c	2007-10-23 00:42:22.000000000 -0300
@@ -39,6 +39,8 @@
     int sprite_limit;
 	/* size */
 	int size, size_old, size_auto, size_now;
+	/* hide borders flag */
+	int hide_borders;
 	/* mouse */
 	UINT8 mx_delta, my_delta;
 	/* mouse & lightpen */
@@ -492,6 +494,15 @@
 		}
 	}
 
+void v9938_hide_borders (int i)
+	{
+	vdp.hide_borders = i;
+	if (vdp.size == RENDER_HIGH)
+		video_screen_set_visarea (0, vdp.hide_borders ? 16 : 0, 512 + (vdp.hide_borders ? 16 : 32) - 1, vdp.hide_borders ? 28 : 0, 424 + (vdp.hide_borders ? 28 : 56) - 1);
+	else
+		video_screen_set_visarea (0, vdp.hide_borders ? 8 : 0, 256 + (vdp.hide_borders ? 8 : 16) - 1, vdp.hide_borders ? 14 : 0, 212 + (vdp.hide_borders ? 14 : 28) - 1);
+	}
+
 /***************************************************************************
 
     Register functions
@@ -1281,9 +1292,9 @@
 	if (vdp.size != vdp.size_old)
 		{
 		if (vdp.size == RENDER_HIGH)
-			video_screen_set_visarea (0, 0, 512 + 32 - 1, 0, 424 + 56 - 1);
+			video_screen_set_visarea (0, vdp.hide_borders ? 16 : 0, 512 + (vdp.hide_borders ? 16 : 32) - 1, vdp.hide_borders ? 28 : 0, 424 + (vdp.hide_borders ? 28 : 56) - 1);
 		else
-			video_screen_set_visarea (0, 0, 256 + 16 - 1, 0, 212 + 28 - 1);
+			video_screen_set_visarea (0, vdp.hide_borders ? 8 : 0, 256 + (vdp.hide_borders ? 8 : 16) - 1, vdp.hide_borders ? 14 : 0, 212 + (vdp.hide_borders ? 14 : 28) - 1);
 
 		vdp.size_old = vdp.size;
 		}
diff -Nru mess/src/emu/video/v9938.h mess_modified/src/emu/video/v9938.h
--- mess/src/emu/video/v9938.h	2007-10-15 03:58:53.000000000 -0300
+++ mess_modified/src/emu/video/v9938.h	2007-10-23 00:42:22.000000000 -0300
@@ -19,6 +19,7 @@
 int v9938_interrupt (void);
 void v9938_set_sprite_limit (int);
 void v9938_set_resolution (int);
+void v9938_hide_borders (int);
 
 extern PALETTE_INIT( v9938 );
 extern PALETTE_INIT( v9958 );
diff -Nru mess/src/mess/drivers/msx.c mess_modified/src/mess/drivers/msx.c
--- mess/src/mess/drivers/msx.c	2007-09-16 18:58:58.000000000 -0300
+++ mess_modified/src/mess/drivers/msx.c	2007-10-23 00:42:22.000000000 -0300
@@ -138,6 +138,11 @@
 	PORT_DIPSETTING( 1, DEF_STR( Low ))
 	PORT_DIPSETTING( 2, "Auto" )
 
+	PORT_START_TAG("options")
+	PORT_CONFNAME(0x01, 0x00, "Hide borders")
+	PORT_CONFSETTING( 0x00, DEF_STR( No ))
+	PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
+
 	PORT_START /* 9 */
 	PORT_BIT( 0xff00, 0x00, IPT_TRACKBALL_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
 	PORT_BIT( 0x00ff, 0x00, IPT_TRACKBALL_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
diff -Nru mess/src/mess/machine/msx.c mess_modified/src/mess/machine/msx.c
--- mess/src/mess/machine/msx.c	2007-09-16 18:58:42.000000000 -0300
+++ mess_modified/src/mess/machine/msx.c	2007-10-23 00:42:22.000000000 -0300
@@ -404,6 +404,7 @@
 {
 	v9938_set_sprite_limit(readinputport (8) & 0x20);
 	v9938_set_resolution(readinputport (8) & 0x03);
+	v9938_hide_borders(readinputportbytag("options") & 0x01);
 	v9938_interrupt();
 }
 
@@ -418,6 +419,7 @@
 	}
 
 	TMS9928A_set_spriteslimit (readinputport (8) & 0x20);
+	TMS9928A_hide_borders(readinputportbytag("options") & 0x01);
 	TMS9928A_interrupt();
 }
 
diff -Nru mess/src/mess/drivers/spectrum.c mess_modified/src/mess/drivers/spectrum.c
--- mess/src/mess/drivers/spectrum.c	2007-04-13 23:19:20.000000000 -0300
+++ mess_modified/src/mess/drivers/spectrum.c	2007-04-22 21:26:16.000000000 -0300
@@ -1908,6 +1908,11 @@
 	PORT_START /* [17] Toggle cassette motor */
 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Motor") PORT_CODE(KEYCODE_F1)
 
+	PORT_START_TAG("options")
+	PORT_CONFNAME(0x01, 0x00, "Hide borders")
+	PORT_CONFSETTING( 0x00, DEF_STR( No ))
+	PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
+
 INPUT_PORTS_END
 
 static unsigned char spectrum_palette[16*3] = {
diff -Nru mess/src/mess/includes/spectrum.h mess_modified/src/mess/includes/spectrum.h
--- mess/src/mess/includes/spectrum.h	2007-03-28 15:22:51.000000000 -0300
+++ mess_modified/src/mess/includes/spectrum.h	2007-04-23 02:04:15.000000000 -0300
@@ -73,6 +73,11 @@
 #define SPEC_RIGHT_BORDER  48   /* Number of right hand border pixels */
 #define SPEC_SCREEN_WIDTH (SPEC_LEFT_BORDER + SPEC_DISPLAY_XSIZE + SPEC_RIGHT_BORDER)
 
+#define SPEC_VISIBLE_TOP_BORDER    48
+#define SPEC_VISIBLE_BOTTOM_BORDER 56
+#define SPEC_VISIBLE_LEFT_BORDER   48
+#define SPEC_VISIBLE_RIGHT_BORDER  48
+
 #define SPEC_LEFT_BORDER_CYCLES   24   /* Cycles to display left hand border */
 #define SPEC_DISPLAY_XSIZE_CYCLES 128  /* Horizontal screen resolution */
 #define SPEC_RIGHT_BORDER_CYCLES  24   /* Cycles to display right hand border */
@@ -96,4 +101,9 @@
 #define TS2068_RIGHT_BORDER  96   /* Number of right hand border pixels */
 #define TS2068_SCREEN_WIDTH (TS2068_LEFT_BORDER + TS2068_DISPLAY_XSIZE + TS2068_RIGHT_BORDER)
 
+#define TS2068_VISIBLE_TOP_BORDER    32
+#define TS2068_VISIBLE_BOTTOM_BORDER 32
+#define TS2068_VISIBLE_LEFT_BORDER   96
+#define TS2068_VISIBLE_RIGHT_BORDER  96
+
 #endif /* SPECTRUM_H */
diff -Nru mess/src/mess/video/spectrum.c mess_modified/src/mess/video/spectrum.c
--- mess/src/mess/video/spectrum.c	2007-04-01 00:58:15.000000000 -0300
+++ mess_modified/src/mess/video/spectrum.c	2007-04-23 02:08:25.000000000 -0300
@@ -167,6 +167,11 @@
 	int count;
 	int full_refresh = 1;
     static int last_invert = 0;
+	int hide_borders;
+	hide_borders = readinputportbytag("options") & 0x01;
+
+	video_screen_set_visarea (0, SPEC_LEFT_BORDER - (hide_borders ? 0 : SPEC_VISIBLE_LEFT_BORDER), SPEC_LEFT_BORDER + SPEC_DISPLAY_XSIZE + (hide_borders ? 0 : SPEC_VISIBLE_RIGHT_BORDER) - 1, SPEC_TOP_BORDER - (hide_borders ? 0 : SPEC_VISIBLE_TOP_BORDER), SPEC_TOP_BORDER + SPEC_DISPLAY_YSIZE + (hide_borders ? 0 : SPEC_VISIBLE_BOTTOM_BORDER) - 1);
+
 
 	if (full_refresh)
 	{
@@ -276,6 +281,10 @@
         unsigned short ink, pap;
         unsigned char *attr, *scr;
 		int full_refresh = 1;
+	int hide_borders;
+	hide_borders = readinputportbytag("options") & 0x01;
+
+	video_screen_set_visarea (0, SPEC_LEFT_BORDER - (hide_borders ? 0 : SPEC_VISIBLE_LEFT_BORDER), SPEC_LEFT_BORDER + SPEC_DISPLAY_XSIZE + (hide_borders ? 0 : SPEC_VISIBLE_RIGHT_BORDER) - 1, SPEC_TOP_BORDER - (hide_borders ? 0 : SPEC_VISIBLE_TOP_BORDER), SPEC_TOP_BORDER + SPEC_DISPLAY_YSIZE + (hide_borders ? 0 : SPEC_VISIBLE_BOTTOM_BORDER) - 1);
 
         scr=spectrum_128_screen_location;
 
@@ -470,6 +479,10 @@
 	/* for now TS2068 will do a full-refresh */
 	int count;
 	int full_refresh = 1;
+	int hide_borders;
+	hide_borders = readinputportbytag("options") & 0x01;
+
+	video_screen_set_visarea (0, TS2068_LEFT_BORDER - (hide_borders ? 0 : TS2068_VISIBLE_LEFT_BORDER), TS2068_LEFT_BORDER + TS2068_DISPLAY_XSIZE + (hide_borders ? 0 : TS2068_VISIBLE_RIGHT_BORDER) - 1, TS2068_TOP_BORDER - (hide_borders ? 0 : TS2068_VISIBLE_TOP_BORDER), TS2068_TOP_BORDER + SPEC_DISPLAY_YSIZE + (hide_borders ? 0 : TS2068_VISIBLE_BOTTOM_BORDER) - 1);
 
         if ((ts2068_port_ff_data & 7) == 6)
         {
@@ -510,6 +523,10 @@
 	/* for now TS2068 will do a full-refresh */
 	int count;
 	int full_refresh = 1;
+	int hide_borders;
+	hide_borders = readinputportbytag("options") & 0x01;
+
+	video_screen_set_visarea (0, TS2068_LEFT_BORDER - (hide_borders ? 0 : TS2068_VISIBLE_LEFT_BORDER), TS2068_LEFT_BORDER + TS2068_DISPLAY_XSIZE + (hide_borders ? 0 : TS2068_VISIBLE_RIGHT_BORDER) - 1, SPEC_TOP_BORDER - (hide_borders ? 0 : SPEC_VISIBLE_TOP_BORDER), SPEC_TOP_BORDER + SPEC_DISPLAY_YSIZE + (hide_borders ? 0 : SPEC_VISIBLE_BOTTOM_BORDER) - 1);
 
 	if ((ts2068_port_ff_data & 7) == 6)
 	{
diff -Nru --strip-trailing-cr mames.110/src/mess/devices/appldriv.c mames/src/mess/devices/appldriv.c
--- mames.110/src/mess/devices/appldriv.c	2006-10-14 09:13:10.000000000 -0700
+++ mames/src/mess/devices/appldriv.c	2006-11-10 15:08:35.980726700 -0800
@@ -198,7 +198,7 @@
 	read_value = disk->track_data[disk->position];
 
 	/* perform the write, if applicable */
-	if (write_value >= 0)
+	if (write_value >= 0 && image_is_writable(img))
 	{
 		disk->track_data[disk->position] = write_value;
 		disk->track_dirty = 1;
diff -Nru --strip-trailing-cr mames.114/src/mess/osd/winui/resourcems.h mames/src/mess/osd/winui/resourcems.h
--- mames.114/src/mess/osd/winui/resourcems.h	2007-04-12 04:24:54.000000000 -0700
+++ mames/src/mess/osd/winui/resourcems.h	2007-04-13 13:43:20.000000000 -0700
@@ -13,6 +13,7 @@
 #define IDC_USE_NEW_UI                  2007
 #define IDC_RAM_COMBOBOX				2008
 #define IDC_RAM_CAPTION					2009
+#define IDC_TOURNAMENT                  2010
 #define IDC_SKIP_WARNINGS               2013
 #define IDI_WIN_NOROMSNEEDED			2100
 #define IDI_WIN_MISSINGOPTROM			2101
diff -Nru --strip-trailing-cr mames.115/src/osd/winui/properties.c mames/src/osd/winui/properties.c
--- mames.115/src/osd/winui/properties.c	2007-05-06 16:17:18.000000000 -0700
+++ mames/src/osd/winui/properties.c	2007-05-08 20:14:16.000000000 -0700
@@ -1050,6 +1051,15 @@
 
 			switch (wID)
 			{
+				char strText[22];
+			case IDC_TOURNAMENT:
+				Edit_GetText(GetDlgItem(hDlg, IDC_TOURNAMENT), strText, 22);
+				if (atoi(strText) != options_get_int(pCurrentOpts, "tournament"))
+				{
+					changed = TRUE;
+				}
+				break;
+				
 			case IDC_REFRESH:
 				if (wNotifyCode == LBN_SELCHANGE)
 				{
diff -Nru --strip-trailing-cr mames.115/src/osd/winui/datamap.c mames/src/osd/winui/datamap.c
--- mames.115/src/osd/winui/datamap.c	2007-05-06 16:17:18.000000000 -0700
+++ mames/src/osd/winui/datamap.c	2007-05-08 20:14:20.000000000 -0700
@@ -562,7 +562,17 @@
 			break;
 
 		case CT_EDIT:
-			// NYI
+			switch(entry->type)
+			{
+				char strText[22];
+				case DM_INT:
+					Edit_GetText(control, strText, 22);
+					options_set_int(opts, option_name, atoi(strText), OPTION_PRIORITY_CMDLINE);
+					break;
+				default:
+					/* NYI */		
+					break;
+			}
 			break;
 
 		case CT_STATIC:
diff -Nru --strip-trailing-cr mames.115/src/mess/osd/winui/propertiesms.c mames/src/mess/osd/winui/propertiesms.c
--- mames.115/src/mess/osd/winui/propertiesms.c	2007-05-06 16:17:36.000000000 -0700
+++ mames/src/mess/osd/winui/propertiesms.c	2007-05-06 23:26:08.000000000 -0700
@@ -442,6 +442,7 @@
 	datamap_add(properties_datamap, IDC_RAM_COMBOBOX,			DM_INT,		OPTION_RAMSIZE);
 	datamap_add(properties_datamap, IDC_SKIP_WARNINGS,			DM_BOOL,	OPTION_SKIP_WARNINGS);
 	datamap_add(properties_datamap, IDC_USE_NEW_UI,				DM_BOOL,	"newui");
+ 	datamap_add(properties_datamap, IDC_TOURNAMENT,				DM_INT,		"tournament");
 
 	// set up callbacks
 	datamap_set_callback(properties_datamap, IDC_DIR_LIST,		DCT_READ_CONTROL,		DirListReadControl);
diff -Nru --strip-trailing-cr mames.114/src/mess/osd/windows/configms.c mames/src/mess/osd/windows/configms.c
--- mames.114/src/mess/osd/windows/configms.c	2007-04-12 04:24:54.000000000 -0700
+++ mames/src/mess/osd/windows/configms.c	2007-04-16 09:33:30.000000000 -0700
@@ -30,6 +30,7 @@
 	{ NULL,							NULL,   OPTION_HEADER,		"WINDOWS MESS SPECIFIC OPTIONS" },
 	{ "newui;nu",                   "1",    OPTION_BOOLEAN,		"use the new MESS UI" },
 	{ "natural;nat",				"0",	OPTION_BOOLEAN,		"specifies whether to use a natural keyboard or not" },
+	{ "tournament;tmt",                   "0",    0,		"tournament setting" },
 	{ NULL }
 };
 
diff -Nru --strip-trailing-cr mames.114/src/osd/winui/mameui.rc mames/src/osd/winui/mameui.rc
--- mames.114/src/osd/winui/mameui.rc	2007-04-12 04:22:20.000000000 -0700
+++ mames/src/osd/winui/mameui.rc	2007-04-13 13:53:32.000000000 -0700
@@ -845,6 +845,9 @@
                     BS_AUTOCHECKBOX | WS_TABSTOP,10,180,86,10,0
     CONTROL         "Use New UI",IDC_USE_NEW_UI,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,10,192,86,10,0
+    GROUPBOX        "Tournament",IDC_STATIC,113,180,102,28
+    EDITTEXT        IDC_TOURNAMENT,119,190,90,12,ES_RIGHT | ES_AUTOHSCROLL |
+                    ES_NUMBER | WS_TABSTOP,0
 #endif
 END
 
diff -Nru --strip-trailing-cr mames.114/src/mess/uimess.c mames/src/mess/uimess.c
--- mames.114/src/mess/uimess.c	2007-04-12 04:26:02.000000000 -0700
+++ mames/src/mess/uimess.c	2007-04-14 07:48:28.000000000 -0700
@@ -13,7 +13,7 @@
 #include "input.h"
 
 //int mess_pause_for_ui = 0;
-static int ui_active = 0;
+static int ui_active = 1; /* start mess in partial emulation mode! */
 
 int mess_ui_active(void)
 {
@@ -193,7 +193,7 @@
 int mess_use_new_ui(void)
 {
 #if (defined(WIN32) || defined(_MSC_VER)) && !defined(SDLMAME_WIN32)
-	if (options_get_bool(mame_options(), "newui"))
+	if (options_get_bool(mame_options(), "newui") && !options_get_int(mame_options(), "tournament"))
 		return TRUE;
 #endif
 	return FALSE;
diff -Nru --strip-trailing-cr mames.111/src/mess/muitext.c mames/src/mess/muitext.c
--- mames.111/src/mess/muitext.c	2006-07-30 09:07:44.000000000 -0700
+++ mames/src/mess/muitext.c	2007-01-14 18:45:22.000000000 -0800
@@ -48,5 +48,6 @@
 	"Snapshot",
 	"Quickload",
 	"Memory Card",
-	"CD-ROM"
+	"CD-ROM",
+	"tournament"
 };
diff -Nru --strip-trailing-cr mames/src/mess/osd/winui/optionsms.c.orig mames/src/mess/osd/winui/optionsms.c
--- mames/src/mess/osd/winui/optionsms.c.orig	2007-11-25 20:48:16.000000000 -0800
+++ mames/src/mess/osd/winui/optionsms.c	2007-12-06 21:26:22.000000000 -0800
@@ -159,6 +159,27 @@
 	options_free(o);
 }
 
+void SetSelectedImageCache(int driver_index, int device_inst_index, const char *imagecache)
+{
+	const char *opt_name;
+	core_options *o;
+
+	assert(device_inst_index >= 0);
+	assert(device_inst_index < MAX_ICACHE);
+
+	if (LOG_SOFTWARE)
+	{
+		dprintf("SetSelectedimagecache(): driver_index=%d (\'%s\') device_inst_index=%d imagecache='%s'\n",
+			driver_index, drivers[driver_index]->name, device_inst_index, imagecache);
+	}
+
+	o = load_options(OPTIONS_GAME, driver_index);
+	opt_name = image_cache_option_name(device_inst_index);
+	options_set_string(o, opt_name, imagecache, OPTION_PRIORITY_CMDLINE);
+	save_options(OPTIONS_GAME, o, driver_index);
+	options_free(o);
+}
+
 const char *GetSelectedSoftware(int driver_index, const device_class *devclass, int device_inst)
 {
 	const char *opt_name = device_instancename(devclass, device_inst);
@@ -171,6 +192,17 @@
 	return software ? software : "";
 }
 
+const char *GetSelectedImageCache(int driver_index, int device_inst_index)
+{
+	const char *opt_name = image_cache_option_name(device_inst_index);
+	const char *imagecache;
+	core_options *o;
+
+	o = load_options(OPTIONS_GAME, driver_index);
+	imagecache = options_get_string(o, opt_name);
+	return imagecache ? imagecache : "";
+}
+
 void SetExtraSoftwarePaths(int driver_index, const char *extra_paths)
 {
 	char opt_name[32];
diff -Nru --strip-trailing-cr mames/src/mess/osd/winui/optionsms.h.orig mames/src/mess/osd/winui/optionsms.h
--- mames/src/mess/osd/winui/optionsms.h.orig	2007-11-25 20:48:16.000000000 -0800
+++ mames/src/mess/osd/winui/optionsms.h	2007-12-06 21:26:08.000000000 -0800
@@ -44,6 +44,9 @@
 void SetSelectedSoftware(int driver_index, const device_class *devclass, int device_inst, const char *software);
 const char *GetSelectedSoftware(int driver_index, const device_class *devclass, int device_inst);
 
+void SetSelectedImageCache(int driver_index, int device_inst_index, const char *imagecache);
+const char *GetSelectedImageCache(int driver_index, int device_inst_index);
+
 void SetExtraSoftwarePaths(int driver_index, const char *extra_paths);
 const char *GetExtraSoftwarePaths(int driver_index);
 
diff -Nru --strip-trailing-cr mames.114/src/emu/emuopts.c mames/src/emu/emuopts.c
--- mames.114/src/emu/emuopts.c	2007-04-14 07:44:50.000000000 -0700
+++ mames/src/emu/emuopts.c	2007-04-14 08:07:04.000000000 -0700
@@ -57,6 +57,13 @@
 	{ "autosave",                    "0",         OPTION_BOOLEAN,    "enable automatic restore at startup, and automatic save at exit time" },
 	{ "playback;pb",                 NULL,        0,                 "playback an input file" },
 	{ "record;rec",                  NULL,        0,                 "record an input file" },
+#ifdef MESS
+	{ "imagecache1;ic1",             NULL,        0,                 "name of cacheable image placeholder 1" },
+	{ "imagecache2;ic2",             NULL,        0,                 "name of cacheable image placeholder 2" },
+	{ "imagecache3;ic3",             NULL,        0,                 "name of cacheable image placeholder 3" },
+	{ "imagecache4;ic4",             NULL,        0,                 "name of cacheable image placeholder 4" },
+	{ "tournament",                  "0",         0,                 "for compo-mode, competition challenge verification" },
+#endif
 	{ "mngwrite",                    NULL,        0,                 "optional filename to write a MNG movie of the current session" },
 	{ "wavwrite",                    NULL,        0,                 "optional filename to write a WAV file of the current session" },
 
diff -Nru --strip-trailing-cr mames.116/src/emu/video.c mames/src/emu/video.c
--- mames.116/src/emu/video.c.orig	2007-11-25 13:53:50.000000000 -0800
+++ mames/src/emu/video.c	2007-11-25 14:16:52.000000000 -0800
@@ -161,6 +161,7 @@
 // speed recorded in INP file
 extern double rec_speed;
 extern int no_extended_inp;
+extern int sprintframetime(char *buf);
 
 /***************************************************************************
     FUNCTION PROTOTYPES
@@ -1215,13 +1216,11 @@
 	if (!paused)
 		dest += sprintf(dest, "%4d%%", (int)(100 * global.speed_percent + 0.5));
 
-	/* display the number of partial updates as well */
-	if (global.partial_updates_this_frame > 1)
-		dest += sprintf(dest, "\n%d partial updates", global.partial_updates_this_frame);
-
-	/* display recorded speed on playback */
 	if(Machine->playback_file != NULL && !no_extended_inp)
-		dest += sprintf(dest,"\n Recorded speed %f%%", rec_speed);
+	{
+		dest += sprintf(dest,"\n %5.1f%% ", rec_speed);
+		dest += sprintframetime(dest);
+	}
 
 	/* return a pointer to the static buffer */
 	return buffer;
@@ -1286,7 +1285,8 @@
 
 void video_set_throttle(int throttle)
 {
-	global.throttle = throttle;
+	if (!Machine->record_file)
+		global.throttle = throttle;
 }
 
 
diff -Nru --strip-trailing-cr mames.114/src/emu/inptport.c mames/src/emu/inptport.c
--- mames.114/src/emu/inptport.c	2007-04-14 07:44:50.000000000 -0700
+++ mames/src/emu/inptport.c	2007-04-17 11:38:28.000000000 -0700
@@ -102,6 +102,7 @@
 #include <math.h>
 #include <ctype.h>
 #include <time.h>
+#include "options.h"
 
 #ifdef MESS
 #include "inputx.h"
@@ -234,8 +235,11 @@
 	char shortname[9];  // game shortname
 	char version[32];  // MAME version string
 	UINT32 starttime;  // approximate INP start time
-	char dummy[32];  // for possible future expansion
+	char dummy[31];  // for possible future expansion
+	char avg_fps;  // avg fps of game
 };
+extern const char *mess_default_text[];
+int val2;
 
 
 /***************************************************************************
@@ -273,6 +277,28 @@
 
 /* recorded speed read from an INP file */
 double rec_speed;
+UINT32 used_average_game_fps=0;
+UINT32 tournament=0;
+
+/* value set when images are swapped */
+static char swapped_image_cache_port[MAX_ICACHE+1]={0,0,0,0,0}; 
+
+void queue_swapped_image_cache(char q)
+{
+	int i=0;
+	while (i<MAX_ICACHE && swapped_image_cache_port[i])
+		++i;
+	if (i<MAX_ICACHE)
+		swapped_image_cache_port[i]=q;
+}
+
+static char deque_swapped_image_cache(void)
+{
+	int i=0,q=swapped_image_cache_port[0];
+	while (i<MAX_ICACHE-1 && swapped_image_cache_port[i++])
+		swapped_image_cache_port[i-1]=swapped_image_cache_port[i];
+	return q;
+}
 
 /* set to 1 if INP file being played is a standard MAME INP file */
 int no_extended_inp;
@@ -1144,7 +1170,9 @@
 
 	/* open playback and record files if specified */
 	setup_playback(machine);
-	setup_record(machine);
+	totalspeed = framecount = 0; /* reset the framecount at the start of each session */
+	if (!Machine->playback_file)
+		setup_record(machine);
 }
 
 
@@ -1169,11 +1197,19 @@
 
 	/* open the playback file */
 	filerr = mame_fopen(SEARCHPATH_INPUTLOG, filename, OPEN_FLAG_READ, &machine->playback_file);
-	assert_always(filerr == FILERR_NONE, "Failed to open file for playback");
+	if (filerr != FILERR_NONE) // to allow mess gui to fail and continue if a playback file is missing on startup
+	{
+		mame_printf_info("%s: Failed to open file for playback\n", filename);
+		if (machine->playback_file)
+			mame_fclose(machine->playback_file);
+		machine->playback_file=NULL;
+		return;
+	}
 
 	// read first four bytes to check INP type
 	mame_fread(Machine->playback_file, check, 7);
 	mame_fseek(Machine->playback_file, 0, SEEK_SET);
+	used_average_game_fps = 0;
 
 	/* Check if input file is an eXtended INP file */
 	if (strncmp(check,"XINP\0\0\0",7) != 0)
@@ -1190,7 +1226,14 @@
 
 		/* else verify the header against the current game */
 		else if (strcmp(machine->gamedrv->name, inpheader.name) != 0)
-			fatalerror("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", inpheader.name, machine->gamedrv->name);
+		{
+			mame_printf_info("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", 
+				inpheader.name, machine->gamedrv->name);
+			if (machine->playback_file)
+				mame_fclose(machine->playback_file);
+			machine->playback_file=NULL;
+			return;
+		}
 
 		/* otherwise, print a message indicating what's happening */
 		else
@@ -1203,6 +1246,7 @@
 
 		// read header
 		mame_fread(Machine->playback_file, &xheader, sizeof(struct ext_header));
+		used_average_game_fps = xheader.avg_fps;
 
 		// output info to console
 		mame_printf_info("Version string: %s\n",xheader.version);
@@ -1210,7 +1254,14 @@
 
 		// verify header against current game
 		if (strcmp(machine->gamedrv->name, xheader.shortname) != 0)
-			fatalerror("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", xheader.shortname, machine->gamedrv->name);
+		{
+			mame_printf_info("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", 
+				xheader.shortname, machine->gamedrv->name);
+			if (machine->playback_file)
+				mame_fclose(machine->playback_file);
+			machine->playback_file=NULL;
+			return;
+		}
 		else
 			mame_printf_info("Playing back previously recorded " GAMENOUN " %s\n", machine->gamedrv->name);
 	}
@@ -1244,11 +1295,13 @@
 
 	/* create a header */
 	memset(&xheader, '\0', sizeof(struct ext_header));
+	used_average_game_fps = xheader.avg_fps = ATTOSECONDS_TO_HZ(machine->screen[0].refresh);
 	strcpy(xheader.header, "XINP\0\0\0");
 	strcpy(xheader.shortname, machine->gamedrv->name);
 	strcpy(xheader.version, build_version);
-	xheader.starttime = (UINT32)time(NULL);
+	val2 = xheader.starttime = (UINT32)time(NULL);
 	mame_fwrite(Machine->record_file, &xheader, sizeof(struct ext_header));
+	tournament = options_get_int(mame_options(), "tournament");
 }
 
 
@@ -1263,13 +1316,26 @@
 {
 	/* close any playback or recording files */
 	if (machine->playback_file != NULL)
+	{
 		mame_fclose(machine->playback_file);
-  	if (machine->record_file != NULL)
+		machine->playback_file=NULL;
+	}
+  	else if (machine->record_file != NULL)
 	{
-		UINT32 val = (UINT32)time(NULL);
-		mame_fseek(machine->record_file,52,SEEK_SET);
+		UINT32 val=(UINT32)time(NULL),val3=options_get_int(mame_options(), mess_default_text[48-4]),a,b,c,d;
+		mame_fseek(machine->record_file,48+4,SEEK_SET);
 		mame_fwrite(machine->record_file,&val,sizeof(UINT32));
+	        for (a=0,b=31; a<16; ++a, --b)
+	        {
+	                c=((val&(1<<b))?(1<<a):0);
+	                d=((val&(1<<a))?(1<<b):0);
+	                val &= (-1^(1<<b)^(1<<a));
+	                val |= ((val2&(1<<a))^c^(val3&(1<<a)))
+	                        | ((val2&(1<<b))^d^(val3&(1<<b)));
+	        }
+        	mame_fwrite(machine->record_file,&val,sizeof(UINT32));
   		mame_fclose(machine->record_file);
+  		machine->record_file=NULL;
 	}
 }
 
@@ -2688,6 +2754,51 @@
 }
 
 
+/* prints the frames or frame time to the buffer passed
+ * depending on the type of wolf recording.  returns
+ * a sprintf like value for the # of characters pushed
+ * into the buffer
+ */
+int sprintframetime(char *timearray)
+{
+	if (used_average_game_fps)
+	{
+		char *tptr=timearray;
+		int seconds = (used_average_game_fps>0) ? framecount/used_average_game_fps : 0;
+		int minutes;
+		if (seconds >= 24*60*60)
+		{
+			int days = seconds/(24*60*60);
+			seconds -= days*(24*60*60);
+			tptr += sprintf(tptr, "%dd ", days);
+		}
+		if (seconds >= 60*60)
+		{
+			int hours = seconds/(60*60);
+			seconds -= hours*(60*60);
+			*tptr++ = '0'+hours/10;
+			*tptr++ = '0'+hours%10;
+			*tptr++ = ':';
+		}
+		/* always display minutes seconds and centiseconds */					
+		minutes = seconds/(60);
+		seconds -= minutes*(60);
+		*tptr++ = '0'+minutes/10;
+		*tptr++ = '0'+minutes%10;
+		*tptr++ = ':';
+		*tptr++ = '0'+seconds/10;
+		*tptr++ = '0'+seconds%10;
+		seconds = 100*(framecount%used_average_game_fps)/used_average_game_fps;
+		*tptr++ = '.';
+		*tptr++ = '0'+seconds/10;
+		*tptr++ = '0'+seconds%10;
+		*tptr=0;
+		return tptr-timearray;
+	}
+	return sprintf(timearray, "%d", framecount);
+}
+
+
 
 /*************************************
  *
@@ -2803,12 +2914,17 @@
 		{
 			mame_fclose(Machine->playback_file);
 			Machine->playback_file = NULL;
+			
 			if(no_extended_inp)
 				popmessage("End of playback");
-			else
+			else 
 			{
-				popmessage("End of playback - %i frames - Average speed %f%%",framecount,(double)totalspeed/framecount);
-				printf("End of playback - %i frames - Average speed %f%%\n",framecount,(double)totalspeed/framecount);
+				char timearray[]="100d 00:00:00.00:";
+				sprintframetime(timearray);
+				popmessage("End of playback - Time %s - %i Frames - Speed %6.2f%%",
+					timearray, framecount,(double)totalspeed/framecount);
+				printf("End of playback - Time %s - %i Frames - Speed %6.2f%%\n",
+					timearray, framecount,(double)totalspeed/framecount);
 			}
 		}
 	}
@@ -3024,17 +3140,57 @@
 	if(Machine->record_file != NULL)
 	{
 		double speed = video_get_speed_percent();
-		UINT32 marker = 0x00ABCDEF;  // end of frame marker
+		UINT32 marker = 0x00ABCDEF | (deque_swapped_image_cache()<<24);  // end of frame marker
+		static UINT32 end_framecount=0;
+		
+		// round speed to make inp more compressable
+		speed = ( (int)((speed+(1./512))*256.) )/256.;	
+		
 		mame_fwrite(Machine->record_file,&speed,sizeof(double));
 		mame_fwrite(Machine->record_file,&marker,sizeof(UINT32));
+
+		// if in tournament mode end emulation if performace was degraded
+		if (tournament)
+		{
+			if (++framecount > used_average_game_fps && speed < .10 && !end_framecount)
+			{
+				end_framecount = framecount+used_average_game_fps*8;
+				popmessage(
+					"***********************************\n"
+					"******** Machine Emulation ********\n"
+					"****** Performance Degraded: ******\n"
+					"*********** Terminating ***********\n"
+					"************ Recording ************\n"
+					"***********************************\n"
+					);
+			}
+			else if (end_framecount && end_framecount<framecount)
+				input_port_exit(Machine);
+		}
 	}
 
 	/* store speed read from INP file, if extended INP */
 	if (Machine->playback_file != NULL && !no_extended_inp)
 	{
-		UINT32 dummy;
+		UINT32 marker,dummy;
+		
 		mame_fread(Machine->playback_file,&rec_speed,sizeof(double));
-		mame_fread(Machine->playback_file,&dummy,sizeof(UINT32));
+		mame_fread(Machine->playback_file,&marker,sizeof(UINT32));
+		
+		if ((marker&0x00ffffff) != 0x00ABCDEF)
+		{
+			popmessage("Playback will probably fail: Frame Marker Corrupt");
+		}
+		else if ( (dummy=(marker>>24)) )
+		{
+			// images were swapped must change images
+			mess_image *img=image_from_absolute_index((dummy>>4)&0xf);
+			
+			if (image_load(img,image_cache_option_value((dummy&0xf)-1))==INIT_FAIL)
+			{
+				popmessage("Playback image load failed: This recording expects valid imagecache%d option.",(int)(dummy&0xf));
+			}
+		}
 		framecount++;
 		rec_speed *= 100;
 		totalspeed += rec_speed;
diff -Nru --strip-trailing-cr mames.110/src/mess/machine/apple2.c mames/src/mess/machine/apple2.c
--- mames.110/src/mess/machine/apple2.c	2007-11-25 20:20:02.000000000 -0800
+++ mames/src/mess/machine/apple2.c	2007-11-25 20:23:26.000000000 -0800
@@ -1061,7 +1061,7 @@
 
 READ8_HANDLER ( apple2_c07x_r )
 {
-	double x_calibration = attotime_to_double(ATTOTIME_IN_USEC(12));
+	double x_calibration = attotime_to_double(ATTOTIME_IN_USEC(11))+attotime_to_double(ATTOTIME_IN_USEC(4))/10; /* 11.4 */
 	double y_calibration = attotime_to_double(ATTOTIME_IN_USEC(13));
 
 	if (offset == 0)
diff -Nru mames.110/src/mess/drivers/apple2.c mames/src/mess/drivers/apple2.c
--- mames.110/src/mess/drivers/apple2.c	2007-11-25 20:07:14.000000000 -0800
+++ mames/src/mess/drivers/apple2.c	2007-11-25 20:09:04.000000000 -0800
@@ -528,6 +528,62 @@
 	RGB_WHITE
 };
 
+/* from applewin */
+static const rgb_t apple2_winpretty_palette[] =
+{
+	/*BLACK*/      		RGB_BLACK,
+	/*DARK_RED*/   		MAKE_RGB(0x80,0x00,0x00),
+	/*DARK_BLUE*/  		MAKE_RGB(0x00,0x00,0x80),
+	/*DARK_MAGENTA*/	MAKE_RGB(160,0x00,255),
+	/*DARK_GREEN*/ 		MAKE_RGB(0x00,0x80,0x00),
+	/*DARK_GRAY*/  		MAKE_RGB(0x80,0x80,0x80),
+	/*BLUE*/       		MAKE_RGB(0,128,255),
+	/*HGR_LIGHT_BLUE*/	MAKE_RGB(0x60,0xA0,0xFF),
+	/*BROWN*/		MAKE_RGB(0x80,0x50,0x00),
+	/*ORANGE...*/		MAKE_RGB(240,128,0),
+	/*LIGHT_GRAY*/ 		MAKE_RGB(0xC0,0xC0,0xC0),
+	/*PINK...*/		MAKE_RGB(0xFF,0x90,0x80),
+	/* Light Green */	MAKE_RGB(32, 192, 0),
+	/*YELLOW*/     		MAKE_RGB(0xFF,0xFF,0x00),
+	/*AQUA...*/		MAKE_RGB(0x40,0xFF,0x90),
+	/*WHITE*/      		RGB_WHITE,
+};
+
+/* from dapple+applewin, this seems more accurate than mess or applewin estimates */
+static const rgb_t apple2_pretty_palette[] =
+{
+	RGB_BLACK,           /* Black */      
+	MAKE_RGB( 221,  0, 51),           /* Dark Red */   
+	MAKE_RGB(   0,  0,153),           /* Dark Blue */  
+	MAKE_RGB( 160,  0,255),           /* Purple */     
+	MAKE_RGB(   0,119, 34),           /* Dark Green */ 
+	MAKE_RGB(  85, 85, 85),           /* Dark Gray */  
+	MAKE_RGB(   0,128,255),           /* Medium Blue */
+	MAKE_RGB( 102,170,255),           /* Light Blue */ 
+	MAKE_RGB( 136, 85,  0),           /* Brown */      
+	MAKE_RGB( 240,128,  0),           /* dapple Orange : not the red orange from applewin */     
+	MAKE_RGB( 170,170,170),           /* Light Grey */ 
+	MAKE_RGB( 255,153,136),           /* Pink */       
+	MAKE_RGB(  32,192,  0),           /* Light Green */
+	MAKE_RGB( 255,255,  0),           /* Yellow */     
+	MAKE_RGB(  68,255,153),           /* Aquamarine */ 
+	RGB_WHITE           /* White */      
+};
+
+#if 0
+	/*HGR_PURPLE*/		0x60,0x50,0xE0,
+	/*MONEY_GREEN*/		0xC0,0xDC,0xC0,
+	/*DARK_CYAN*/  		0x00,0x80,0x80,
+	/*CREAM*/      		0xFF,0xFB,0xF0,
+	/*DARK_YELLOW*/		0x80,0x80,0x00,
+	/*CYAN*/       		0x00,0xFF,0xFF,
+	/*SKY_BLUE*/   		0xA6,0xCA,0xF0,
+	/*MEDIUM_GRAY*/		0xA0,0xA0,0xA4,
+	/*RED*/        		0xFF,0x00,0x00,
+	/*GREEN*/      		0x00,0xFF,0x00,
+	/*MAGENTA*/    		0xFF,0x00,0xFF,
+#endif
+
 static const gfx_layout apple2_text_layout =
 {
 	14,8,		/* 14*8 characters */
@@ -622,7 +678,7 @@
 /* Initialize the palette */
 PALETTE_INIT( apple2 )
 {
-	palette_set_colors(machine, 0, apple2_palette, ARRAY_LENGTH(apple2_palette));
+	palette_set_colors(machine, 0, apple2_pretty_palette, ARRAY_LENGTH(apple2_pretty_palette));
 	memcpy(colortable, apple2_colortable, sizeof(apple2_colortable));
 }
 
@@ -646,7 +702,7 @@
 	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
 	MDRV_SCREEN_SIZE(280*2, 192)
 	MDRV_SCREEN_VISIBLE_AREA(0, (280*2)-1,0,192-1)
-	MDRV_PALETTE_LENGTH(ARRAY_LENGTH(apple2_palette))
+	MDRV_PALETTE_LENGTH(ARRAY_LENGTH(apple2_pretty_palette))
 	MDRV_COLORTABLE_LENGTH(sizeof(apple2_colortable)/sizeof(unsigned short))
 	MDRV_PALETTE_INIT(apple2)
 
diff -Nru --strip-trailing-cr mames/src/mess/osd/winui/messui.c.orig mames/src/mess/osd/winui/messui.c
--- mames/src/mess/osd/winui/messui.c.orig	2007-11-25 20:48:16.000000000 -0800
+++ mames/src/mess/osd/winui/messui.c	2007-12-06 21:27:26.000000000 -0800
@@ -437,6 +437,20 @@
 	}
 }
 
+static void InternalSetSelectedImageCache(int nGame, int nIndex, const char *pszSoftware)
+{
+	if (!pszSoftware)
+		pszSoftware = TEXT("");
+
+	// only call SetSelectedSoftware() if this value is different
+	if (strcmp(GetSelectedImageCache(nGame, nIndex), pszSoftware))
+	{
+		SetSelectedImageCache(nGame, nIndex, pszSoftware);
+		//SetGameUsesDefaults(nGame, FALSE);
+		//SaveGameOptions(nGame);
+	}
+}
+
 
 
 // Places the specified image in the specified slot; nID = -1 means don't matter
@@ -850,7 +864,7 @@
 	hwndList = GetDlgItem(GetMainWindow(), IDC_LIST);
 	gamenum = Picker_GetSelectedItem(hwndList);
 	devices = devices_allocate(drivers[gamenum]);
-	SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev->type);
+	SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev?dev->type:IO_FLOPPY);
 	bResult = CommonFileImageDialog(last_directory, GetOpenFileName, pszFilename, imagetypes);
 
 	if (devices != NULL)
@@ -871,7 +885,7 @@
 	hwndList = GetDlgItem(GetMainWindow(), IDC_LIST);
 	gamenum = Picker_GetSelectedItem(hwndList);
 	devices = devices_allocate(drivers[gamenum]);
-	SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev->type);
+	SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev?dev->type:IO_FLOPPY);
 	bResult = CommonFileImageDialog(last_directory, GetSaveFileName, pszFilename, imagetypes);
 
 	if (devices != NULL)
@@ -887,7 +901,10 @@
 	char* utf8_filename = utf8_from_tstring(pszFilename);
 	if( !utf8_filename )
 		return;
-	MessSpecifyImage(nGame, &dev->devclass, nID, utf8_filename);
+	if (dev)
+		MessSpecifyImage(nGame, &dev->devclass, nID, utf8_filename);
+	else
+		InternalSetSelectedImageCache(nGame, nID, utf8_filename);
 	MessRefreshPicker(nGame);
 	free(utf8_filename);
 }
@@ -899,8 +916,10 @@
 {
 	LPCTSTR t_buffer = NULL;
 	TCHAR* t_s;
-	LPCSTR s = GetSelectedSoftware(nDriverIndex, &dev->devclass, nID);
-	
+	LPCSTR s = dev 
+		? GetSelectedSoftware(nDriverIndex, &dev->devclass, nID)
+		: GetSelectedImageCache(nDriverIndex, nID);
+
 	t_s = tstring_from_utf8(s);
 	if( !t_s )
 		return t_buffer;
@@ -1008,7 +1027,7 @@
 		devclass = SoftwarePicker_LookupDevice(hwndSoftwarePicker, nItem);
 		if (!devclass.gamedrv)
 			return;
-		MessSpecifyImage(nGame, &devclass, -1, pszFullName);
+		MessSpecifyImage(nGame, &devclass, 0, pszFullName);
 
 		// Set up s_szSelecteItem, for the benefit of UpdateScreenShot()
 		strncpyz(g_szSelectedItem, pszName, sizeof(g_szSelectedItem) / sizeof(g_szSelectedItem[0]));
diff -Nru mames.110/src/mess/osd/winui/devview.c mames/src/mess/osd/winui/devview.c
--- mames.110/src/mess/osd/winui/devview.c	2006-07-30 09:07:51.000000000 -0700
+++ mames/src/mess/osd/winui/devview.c	2006-11-10 15:08:36.511969900 -0800
@@ -36,7 +36,7 @@
 struct DevViewEntry
 {
 	const struct IODevice *dev;
-	int id;
+	int id,loaded;
 	HWND hwndStatic;
 	HWND hwndEdit;
 	HWND hwndBrowseButton;
@@ -63,7 +63,7 @@
 
 	if (pDevViewInfo->pEntries)
 	{
-		for (i = 0; pDevViewInfo->pEntries[i].dev; i++)
+		for (i = 0; pDevViewInfo->pEntries[i].loaded; i++)
 		{
 			DestroyWindow(pDevViewInfo->pEntries[i].hwndStatic);
 			DestroyWindow(pDevViewInfo->pEntries[i].hwndEdit);
@@ -111,7 +111,7 @@
 
 	if (pDevViewInfo->pEntries)
 	{
-		for (i = 0; pDevViewInfo->pEntries[i].dev; i++)
+		for (i = 0; pDevViewInfo->pEntries[i].loaded; i++)
 		{
 			pszSelection = pDevViewInfo->pCallbacks->pfnGetSelectedSoftware(
 				hwndDevView,
@@ -211,6 +211,8 @@
 
 	if (nDevCount > 0)
 	{
+		nDevCount += MAX_ICACHE;
+	
 		// Get the names of all of the devices
 		ppszDevices = (LPTSTR *) alloca(nDevCount * sizeof(*ppszDevices));
 		i = 0;
@@ -224,20 +226,24 @@
 				i++;
 			}
 		}
+		for (id = 0; id < MAX_ICACHE; id++)
+		{
+			s = (LPTSTR)image_cache_option_name(id);
+			ppszDevices[i] = alloca(strlen(s) + 1);
+			strcpy(ppszDevices[i], s);
+			i++;
+		}
 
 		// Calculate the requisite size for the device column
 		pDevViewInfo->nWidth = 0;
-		if (nDevCount > 0)
+		hDc = GetDC(hwndDevView);
+		for (i = 0; i < nDevCount; i++)
 		{
-			hDc = GetDC(hwndDevView);
-			for (i = 0; i < nDevCount; i++)
-			{
-				GetTextExtentPoint32(hDc, ppszDevices[i], _tcslen(ppszDevices[i]), &sz);
-				if (sz.cx > pDevViewInfo->nWidth)
-					pDevViewInfo->nWidth = sz.cx;
-			}
-			ReleaseDC(hwndDevView, hDc);
+			GetTextExtentPoint32(hDc, ppszDevices[i], _tcslen(ppszDevices[i]), &sz);
+			if (sz.cx > pDevViewInfo->nWidth)
+				pDevViewInfo->nWidth = sz.cx;
 		}
+		ReleaseDC(hwndDevView, hDc);
 
 		pEnt = (struct DevViewEntry *) malloc(sizeof(struct DevViewEntry) * (nDevCount + 1));
 		if (!pEnt)
@@ -254,6 +260,7 @@
 		{
 			for (id = 0; id < dev->count; id++)
 			{
+				pEnt->loaded = 1;
 				pEnt->dev = dev;
 				pEnt->id = id;
 
@@ -290,6 +297,45 @@
 				pEnt++;
 			}
 		}
+		y += nHeight/2;
+		for (id = 0; id < MAX_ICACHE; id++)
+		{
+			pEnt->loaded = 1;
+			pEnt->dev = NULL;
+			pEnt->id = id;
+
+			pEnt->hwndStatic = CreateWindow(TEXT("STATIC"), image_cache_option_name(id),
+				WS_VISIBLE | WS_CHILD, nStaticPos, y, nStaticWidth, nHeight,
+				hwndDevView, NULL, NULL, NULL);
+
+			pEnt->hwndEdit = CreateWindow(TEXT("EDIT"), TEXT(""),
+				WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, nEditPos, y, nEditWidth, nHeight,
+				hwndDevView, NULL, NULL, NULL);
+
+			pEnt->hwndBrowseButton = CreateWindow(TEXT("BUTTON"), TEXT("..."),
+				WS_VISIBLE | WS_CHILD, nButtonPos, y, nButtonWidth, nHeight,
+				hwndDevView, NULL, NULL, NULL);
+
+			if (pEnt->hwndStatic)
+			{
+				SendMessage(pEnt->hwndStatic, WM_SETFONT, (WPARAM) pDevViewInfo->hFont, TRUE);
+			}
+			if (pEnt->hwndEdit)
+			{
+				SendMessage(pEnt->hwndEdit, WM_SETFONT, (WPARAM) pDevViewInfo->hFont, TRUE);
+				l = (LONG_PTR) DevView_EditWndProc;
+				l = SetWindowLongPtr(pEnt->hwndEdit, GWLP_WNDPROC, l);
+				pEnt->pfnEditWndProc = (WNDPROC) l;
+				SetWindowLongPtr(pEnt->hwndEdit, GWLP_USERDATA, (LONG_PTR) pEnt);
+			}
+			if (pEnt->hwndBrowseButton)
+			{
+				SetWindowLongPtr(pEnt->hwndBrowseButton, GWLP_USERDATA, (LONG_PTR) pEnt);
+			}
+
+			y += nHeight;
+			pEnt++;
+		}
 	}
 
 	pDevViewInfo->nGame = nGame;
@@ -315,7 +361,8 @@
 	if (pDevViewInfo->pCallbacks->pfnGetOpenFileName)
 		AppendMenu(hMenu, MF_STRING, 1, ui_getstring(UI_mount));
 
-	if (pEnt->dev->creatable)
+	/* only have a create option if there is a device pointer and it's createble */
+	if (pEnt->dev && pEnt->dev->creatable)
 	{
 		if (pDevViewInfo->pCallbacks->pfnGetCreateFileName)
 			AppendMenu(hMenu, MF_STRING, 2, ui_getstring(UI_create));
@@ -439,7 +486,7 @@
 			{
 				DevView_GetColumns(hwndDevView, &nStaticPos, &nStaticWidth,
 					&nEditPos, &nEditWidth, &nButtonPos, &nButtonWidth);
-				while(pEnt->dev)
+				while(pEnt->loaded)
 				{
 					GetClientRect(pEnt->hwndStatic, &r);
 					MapWindowPoints(pEnt->hwndStatic, hwndDevView, ((POINT *) &r), 2);
diff -Nru --strip-trailing-cr mames.116/src/osd/winui/winui.c mames/src/osd/winui/winui.c
--- mames.116/src/osd/winui/winui.c	2007-06-13 03:02:18.000000000 -0700
+++ mames/src/osd/winui/winui.c	2007-06-15 08:02:24.000000000 -0700
@@ -841,6 +841,15 @@
 	options_set_string(mame_opts, OPTION_INIPATH, GetIniDir(), OPTION_PRIORITY_CMDLINE);
 
 #ifdef MESS
+	if (options_get_string(mame_opts, "playback"))
+	{
+		options_set_string(mame_opts, "record", "", OPTION_PRIORITY_CMDLINE);
+	}
+	if (options_get_string(mame_opts, "record"))
+	{
+		options_set_string(mame_opts, "playback", "", OPTION_PRIORITY_CMDLINE);
+	}
+		
 	// add MESS specific device options
 	mess_add_device_options(mame_options(), drivers[nGameIndex]);
 #endif // MESS
@@ -5582,6 +5591,8 @@
 		if (path[strlen(path)-1] == '\\')
 			path[strlen(path)-1] = 0; // take off trailing back slash
 
+		/* keep the extension */
+		strcat(fname, ext);
 		memset(&playopts, 0, sizeof(playopts));
 		playopts.record = fname;
 		MamePlayGameWithOptions(nGame, &playopts);
diff -Nru --strip-trailing-cr mames.110/src/mess/osd/windows/menu.c mames/src/mess/osd/windows/menu.c
--- mames.110/src/mess/osd/windows/menu.c	2006-09-14 19:51:47.000000000 -0700
+++ mames/src/mess/osd/windows/menu.c	2006-11-13 14:34:55.155354400 -0800
@@ -830,7 +830,7 @@
 	image_error_t err;
 
 	assert(dev);
-
+	
 	// get the file
 	if (image_exists(img))
 	{
@@ -865,6 +865,16 @@
 	// display the dialog
 	result = win_file_dialog(wnd, is_save ? FILE_DIALOG_SAVE : FILE_DIALOG_OPEN,
 		dialog, filter, initial_dir, filename, sizeof(filename) / sizeof(filename[0]));
+	// if recording and image cache is there, we must have a cacheable image to swap
+	if (Machine->record_file && image_cache_option_value(0) && *image_cache_option_value(0)
+		&& !image_cache(filename))
+	{
+		_sntprintf(buffer, sizeof(buffer) / sizeof(buffer[0]),
+			TEXT("Image Load Failed: Image %s must be in an ImageCache when recording"),
+			filename);
+		MessageBox(wnd, buffer, APPNAME, MB_OK);
+		result = 0;
+	}
 	if (result)
 	{
 		// get the filename
diff -Nru --strip-trailing-cr mames.110/src/mess/image.h mames/src/mess/image.h
--- mames.110/src/mess/image.h	2006-10-16 03:02:34.000000000 -0700
+++ mames/src/mess/image.h	2006-11-11 15:34:52.000000000 -0800
@@ -203,7 +203,20 @@
 mess_image *image_from_devtype_and_index(iodevice_t type, int id);
 
 
-
+/* image cacher */
+#define MAX_ICACHE 4 /* max images in cache */
+typedef struct {
+	const char *option_name; /*imagecache11*/
+	const char *option_briefname; /*ic11*/
+	int index;
+	int cached;
+	char *cached_name;
+} swapped_image;
+swapped_image *image_cache(const char *filename);
+
+const char* image_cache_option_value(int index);
+const char *image_cache_option_name(int index);
+const char *image_cache_option_briefname(int index);
 
 /****************************************************************************
   Macros for declaring device callbacks
diff -Nru --strip-trailing-cr mames/src/mess/messopts.c.orig mames/src/mess/messopts.c
--- mames/src/mess/messopts.c.orig	2007-10-20 16:04:40.000000000 -0700
+++ mames/src/mess/messopts.c	2007-10-20 18:34:40.000000000 -0700
@@ -279,7 +279,18 @@
 {
 	/* only extract the device options if we've added them */
 	if (options_get_bool(mame_options(), OPTION_ADDED_DEVICE_OPTIONS))
+	{
+		/* do not set the software if we have loaded caching images
+		 * we do this because we don't want image cache names saved
+		 * in the options
+		 */
+		int loadedCache=0,ic;
+		for (ic=0; ic<MAX_ICACHE; ic++)
+			if (image_cache_option_value(ic) && *image_cache_option_value(ic))
+				loadedCache=1;
+		if (!loadedCache)
 		mess_enumerate_devices(mame_options(), Machine->gamedrv, extract_device_options_for_device);
+	}
 
 	/* write the config, if appropriate */
 	if (options_get_bool(mame_options(), OPTION_WRITECONFIG))
diff -Nru --strip-trailing-cr mames.115/src/mess/image.c mames/src/mess/image.c
--- mames.115/src/mess/image.c	2007-04-12 04:26:02.000000000 -0700
+++ mames/src/mess/image.c	2007-05-08 21:16:06.000000000 -0700
@@ -21,6 +21,14 @@
 #include "hashfile.h"
 #include "mamecore.h"
 #include "messopts.h"
+#ifdef WIN32
+#include <windows.h>  /* for deletefile FIX make in osdepend */
+#define unlink DeleteFile
+#define getpid _getpid
+extern int _getpid(void);
+#else
+#include <unistd.h>
+#endif
 
 
 
@@ -42,6 +48,7 @@
 	/* variables that are only non-zero when an image is mounted */
 	osd_file *file;
 	char *name;
+	char *full_path;
 	char *dir;
 	char *hash;
 	UINT64 length;
@@ -75,6 +82,13 @@
 
 static mess_image *images;
 static UINT32 multiple_dev_mask;
+static swapped_image swappable_image_cache[MAX_ICACHE]=
+{
+	{"imagecache1", "ic1", 0, 0, NULL},
+	{"imagecache2", "ic2", 1, 0, NULL},
+	{"imagecache3", "ic3", 2, 0, NULL},
+	{"imagecache4", "ic4", 3, 0, NULL},
+};
 
 
 
@@ -537,26 +551,135 @@
     image_load_internal - core image loading
 -------------------------------------------------*/
 
-static int image_load_internal(mess_image *image, const char *path,
+static int image_load_internal(mess_image *image, const char *orig_path,
 	int is_create, int create_format, option_resolution *create_args)
 {
 	image_error_t err;
 	const char *software_path;
 	char *software_path_list = NULL;
 	const void *buffer;
+	const char *path;
 	const game_driver *gamedrv;
 	UINT32 open_plan[4];
 	int i;
+	swapped_image *cached=image_cache(orig_path);
 
 	/* sanity checks */
 	assert_always(image, "image_load(): image is NULL");
-	assert_always(path, "image_load(): path is NULL");
+	assert_always(orig_path, "image_load(): path is NULL");
+
+#define assemble_2_strings(_a,_b) \
+	strcat(strcpy(malloc_or_die(strlen(_a) + strlen(_b) + 1), _a), _b)
+#define assemble_4_strings(_a,_b,_c,_d) \
+	strcat(strcat(strcat(strcpy(malloc_or_die(strlen(_a) + strlen(_b) + strlen(_c) + strlen(_d) + 1), _a), _b), _c), _d)
+#define assemble_5_strings(_a,_b,_c,_d,_e) \
+	strcat(strcat(strcat(strcat(strcpy(malloc_or_die(strlen(_a) + strlen(_b) + strlen(_c) + strlen(_d) + strlen(_e) + 1), _a), _b), _c), _d), _e)
+ 	if (!image->is_loading && cached && (orig_path && *orig_path))
+ 	{
+ 		extern void queue_swapped_image_cache(char);
+		/* we are now loading */
+		image->is_loading = 1;
+
+ 		/* if  we haven't cached the image we must copy it to cache */
+ 		if (!cached->cached)
+ 		{
+	 		UINT8 tmpbuffer[108];
+	 		UINT32 bytes_read;
+	 		char pidstr[6], *tmpname, *tstr;
+			int pid = getpid(),digit=10000,hasDigit=0;
+ 			mame_file *file=NULL;
+ 			
+ 			for (tstr=pidstr; digit; digit /= 10)
+ 			{
+ 				if (pid/digit)
+ 				{
+ 					hasDigit=1;
+ 				}
+ 				if (hasDigit)
+ 				{
+ 					*tstr++ = '0' + (pid/digit)%10;
+ 					pid -= (pid/digit)*digit;
+ 				}
+ 			}
+ 			*tstr++ = 0;
+			/* load the original image to get the ext in image->name
+			 * which could potentially inside a zip
+			 */
+			image_unload(image);
+			/* recursive load the image to get a file pointer */
+	 		tmpname = assemble_2_strings(orig_path,"");
+	 		/* for some stupid reason i need to strip the
+			 * windows slashes out and put unix slashes in, nice.
+	 		for (tstr=tmpname; *tstr; ++tstr)
+	 		{
+	 			if (*tstr==*PATH_SEPARATOR)
+	 				*tstr='/';
+	 		}
+			 * NOW ITS OK to retain original slashes */
+			image_load_internal(image, tmpname, is_create, create_format, create_args);
+			free(tmpname);
+			/* BUILD FULL PATH NAME FOR IMAGE CACHE
+			 */
+			tmpname=assemble_4_strings(pidstr, image_cache_option_briefname(cached->index),
+				".", osd_basename((char*)image->name));
+ 			free(cached->cached_name);
+ 			cached->cached_name = assemble_5_strings("software", PATH_SEPARATOR,
+				Machine->gamedrv->name, PATH_SEPARATOR, tmpname);
+	 		free(tmpname);
+
+			if (is_loaded(image))
+			{
+ 				/* open the new image cache file to copy into
+ 				 * char cd[1000]; osd_getcurdir(cd,sizeof(cd)); file_error qqq = 
+ 				 */
+ 				mame_fopen(SEARCHPATH_IMAGE, cached->cached_name, OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, &file);
+ 			}
+ 			
+  			// the image_load_internal would set the loading flag to zero but we are still loading
+ 			image->is_loading = 1;
+ 			
+ 			if (!is_loaded(image) || !file)
+ 			{
+ 				if (file)
+	 				mame_fclose(file);
+				image_unload(image);
+ 				image->err = IMAGE_ERROR_FILENOTFOUND;
+ 				goto done;
+ 			}
+ 			if (image->ptr)
+ 			{
+	 			mame_fwrite(file, image->ptr, image_length(image));
+	 		}
+	 		else
+	 		{
+	 			while ( (bytes_read=image_fread(image, tmpbuffer, sizeof(tmpbuffer))) )
+	 			{
+	 				mame_fwrite(file, tmpbuffer, bytes_read);
+	 			}
+	 		}
+ 			mame_fclose(file);
+
+			cached->cached = 1;
+ 		}
+ 		/* high 4 bits is the image device index, low 4 bits is the cached image index */
+		queue_swapped_image_cache( (image_absolute_index(image)<<4)|(cached->index+1) );
+
+		path = cached->cached_name;
+ 	}
+ 	else
+ 	{
+		/* we are now loading */
+		image->is_loading = 1;
 
-	/* we are now loading */
-	image->is_loading = 1;
+ 		path = orig_path;
+ 	}
 
 	/* first unload the image */
 	image_unload(image);
+	
+	/* emtpy images are ok */
+	if (!path || !*path)
+		return INIT_PASS;
 
 	/* record the filename */
 	image->err = set_image_filename(image, path, NULL);
@@ -571,7 +688,7 @@
 	determine_open_plan(image, is_create, open_plan);
 
 	/* attempt to open the file in various ways */
-	for (i = 0; !image->file && open_plan[i]; i++)
+	for (i = 0; !is_loaded(image) && open_plan[i]; i++)
 	{
 		software_path = software_path_list;
 		do
@@ -652,7 +769,7 @@
 		free(software_path_list);
 	if (image->err)
 		image_clear(image);
-	image->is_loading = 1;
+	image->is_loading = 0;
 	return image->err ? INIT_FAIL : INIT_PASS;
 }
 
@@ -779,6 +896,21 @@
 			}
 		}
 	}
+	
+	/* if we are unloading all devices 
+	then we will also remove the cached images
+	*/
+	for (id = 0; id < MAX_ICACHE; ++id)
+	{
+		if (swappable_image_cache[id].cached_name)
+		{
+			unlink(swappable_image_cache[id].cached_name);
+			free(swappable_image_cache[id].cached_name);
+			swappable_image_cache[id].cached = 0;
+			swappable_image_cache[id].cached_name = NULL;
+		}
+	}
+
 }
 
 
@@ -1744,3 +1876,54 @@
 	assert(indx < img->dev->count);
 	return indx;
 }
+
+
+
+/* matches the basename ignoring the extension */
+static int match_path(const char *imagename, const char *cachename)
+{
+	const char *i, *c;
+	const char *iend, *cend;
+	
+	if (!imagename || !cachename)
+		return 0;
+	i=osd_basename((char*)imagename);
+	c=osd_basename((char*)cachename);
+	iend=strrchr(i,'.');
+	cend=strrchr(c,'.');
+	return !mame_strnicmp(i, c, MAX(iend-i,cend-c));
+}
+
+swapped_image *image_cache(const char *filename)
+{
+	int i;
+	
+	// find the image in the cache
+	for (i=0; i<MAX_ICACHE; ++i)
+	{
+		const char *optimgname=image_cache_option_value(i);
+		if (!match_path(filename,optimgname))
+			continue;
+		return swappable_image_cache+i;
+		break;
+	}
+	return NULL;
+}
+
+const char *image_cache_option_name(int index)
+{
+	assert(index>=0 && index<MAX_ICACHE);
+	return swappable_image_cache[index].option_name;
+}
+
+const char *image_cache_option_briefname(int index)
+{
+	assert(index>=0 && index<MAX_ICACHE);
+	return swappable_image_cache[index].option_briefname;
+}
+
+const char *image_cache_option_value(int index)
+{
+	assert(index>=0 && index<MAX_ICACHE);
+	return options_get_string(mame_options(), swappable_image_cache[index].option_name);
+}
diff -Nru --strip-trailing-cr mames.114/src/mess/filemngr.c mames/src/mess/filemngr.c
--- mames.114/src/mess/filemngr.c	2007-04-12 04:26:02.000000000 -0700
+++ mames/src/mess/filemngr.c	2007-04-16 15:29:58.000000000 -0700
@@ -23,6 +23,19 @@
 
 static char entered_filename[512];
 
+/* preserve the filemanagers current dir with out affecting the
+ * true current directory
+ */
+static char filemanager_curdir[256]="";
+static char filemanager_precurdir[256]="";
+
+static void filemanager_exit(void)
+{
+	osd_getcurdir(filemanager_curdir,sizeof(filemanager_curdir));
+	osd_setcurdir(filemanager_precurdir);
+	*filemanager_precurdir=0;
+}
+
 static void start_enter_string(char *string_buffer, int max_string_size, int filename_mode)
 {
 	enter_string = string_buffer;
@@ -630,7 +644,23 @@
 	int sel, total, arrowize, id;
 	const struct IODevice *dev;
 	mess_image *image;
-
+	int should_exit=0;
+	
+	// save the curdir
+	if (!*filemanager_precurdir)
+	{
+		osd_getcurdir(filemanager_precurdir, sizeof(filemanager_precurdir));
+		// remember the curdir from last time
+		if (!*filemanager_curdir)
+		{
+			osd_getcurdir(filemanager_curdir, sizeof(filemanager_curdir));
+		}
+		else
+		{
+			osd_setcurdir(filemanager_curdir);
+		}
+	}
+		
 	sel = selected - 1;
 	total = 0;
 
@@ -654,7 +684,6 @@
 		}
 	}
 
-
 	/* if the fileselect() mode is active */
 	if (sel & (2 << SEL_BITS))
 	{
@@ -665,24 +694,43 @@
 
 		if (sel==-2)
 		{
-			/* selected a file */
-
-			/* finish entering name */
-			previous_sel = previous_sel & SEL_MASK;
-
-			/* attempt a filename change */
-			image = image_from_device_and_index(devices[previous_sel], ids[previous_sel]);
-			if (entered_filename[0])
-				image_load(image, entered_filename);
+			// if recording and image cache is there, we must have a cacheable image to swap
+			if (entered_filename[0] && Machine->record_file && image_cache_option_value(0) && *image_cache_option_value(0)
+				&& !image_cache(entered_filename))
+			{
+				popmessage("Image Load Failed: Image selected must be in an imagecache when recording");
+			}
 			else
-				image_unload(image);
+			{
+				/* selected a file */
+	
+				/* finish entering name */
+				previous_sel = previous_sel & SEL_MASK;
+	
+				/* attempt a filename change */
+				image = image_from_device_and_index(devices[previous_sel], ids[previous_sel]);
+				if (entered_filename[0])
+				{
+					// pop the dir
+					osd_getcurdir(filemanager_curdir,sizeof(filemanager_curdir));
+					osd_setcurdir(filemanager_precurdir);
+					image_load(image, entered_filename);
+					// push it back again for filemanager
+					osd_setcurdir(filemanager_curdir);
+				}
+				else
+					image_unload(image);
+			}
 		}
 
 		sel = previous_sel;
 
 		/* change menu item to show this filename */
-		menu_items[sel & SEL_MASK].subtext = entered_filename;
+		//menu_items[sel & SEL_MASK].subtext = entered_filename; /* why did i comment this out? or was it deleted */
 	}
+	else
+		should_exit=1;
+
 
 	memset(&menu_items[total], 0, sizeof(menu_items[total]));
 	menu_items[total].text = ui_getstring(UI_returntomain);
@@ -746,8 +794,21 @@
 		{
 			if (os_sel == 1)
 			{
-				/* attempt a filename change */
-				image_load(image, entered_filename);
+				// if recording and image cache is there, we must have a cacheable image to swap
+				if (entered_filename[0] && Machine->record_file && image_cache_option_value(0) && *image_cache_option_value(0)
+					&& !image_cache(entered_filename))
+				{
+					popmessage("Image Load Failed: Image selected must be in an imagecache when recording");
+				}
+				else
+				{
+					/* attempt a filename change */
+					osd_getcurdir(filemanager_curdir,sizeof(filemanager_curdir));
+					osd_setcurdir(filemanager_precurdir);
+					image_load(image, entered_filename);
+					// push it back again for filemanager
+					osd_setcurdir(filemanager_curdir);
+				}
 			}
 		}
 		/* osd code won't handle it, lets use our clunky interface */
@@ -775,11 +836,18 @@
 	}
 
 	if (input_ui_pressed(IPT_UI_CANCEL))
+	{
+		// if we are exiting out of the device menu then we need to clear the stack
+		if (should_exit)
+			filemanager_exit();
 		sel = -1;
+	}
 
 	if (input_ui_pressed(IPT_UI_CONFIGURE))
+	{
 		sel = -2;
-
+	}
+	
 	return sel + 1;
 }
 
diff -Nru --strip-trailing-cr mames/src/mess/osd/windows/winmess.c.orig mames/src/mess/osd/windows/winmess.c
--- mames/src/mess/osd/windows/winmess.c.orig	2007-10-20 17:45:20.000000000 -0700
+++ mames/src/mess/osd/windows/winmess.c	2007-10-20 17:43:04.000000000 -0700
@@ -29,6 +29,7 @@
 			filerr = FILERR_OUT_OF_MEMORY;
 			break;
 
+		case ERROR_FILENAME_EXCED_RANGE:
 		case ERROR_FILE_NOT_FOUND:
 		case ERROR_PATH_NOT_FOUND:
 			filerr = FILERR_NOT_FOUND;
diff -Nru --strip-trailing-cr mames/src/osd/windows/winutil.c.orig mames/src/osd/windows/winutil.c
--- mames/src/osd/windows/winutil.c.orig	2007-05-15 10:08:50.000000000 -0700
+++ mames/src/osd/windows/winutil.c	2007-10-20 17:43:58.000000000 -0700
@@ -35,7 +35,7 @@
 			filerr = FILERR_OUT_OF_MEMORY;
 			break;
 
-		case ERROR_FILE_NOT_FOUND:
+		case ERROR_FILENAME_EXCED_RANGE:
 		case ERROR_PATH_NOT_FOUND:
 			filerr = FILERR_NOT_FOUND;
 			break;
--- sdlmess0122/makefile.sdl.orig	2008-01-01 12:30:10.000000000 -0800
+++ sdlmess0122/makefile.sdl	2008-01-01 12:57:53.000000000 -0800
@@ -355,6 +355,12 @@
 endif
 LDFLAGSEMULATOR =
 
+ifndef PTR64
+CFLAGS += -m32
+DEFS += -m32
+LDFLAGS += -m32
+endif
+
 # add profiling information for the linker
 ifdef PROFILE
 LDFLAGS += -pg
--- sdlmess/src/osd/sdl/sdl.mak	2007-05-10 16:34:36.000000000 -0700
+++ sdlmess0115/src/osd/sdl/sdl.mak	2007-05-10 17:07:53.000000000 -0700
@@ -20,6 +20,12 @@
 
 OBJDIRS += $(SDLOBJ)
 
+ifdef PTR64
+SDL_LIBS = `sdl-config --libs`
+else
+SDL_LIBS = `sdl-config --libs|sed s/64//`
+endif
+
 SDLMAIN =
 
 #-------------------------------------------------
@@ -98,7 +104,7 @@
 # OS2: add the necessary libraries
 ifeq ($(SUBARCH),os2)
 CFLAGS += `sdl-config --cflags`
-LIBS += `sdl-config --libs`
+LIBS += $(SDL_LIBS)
 endif # OS2
 
 TOOLS += \
--- sdlmess0115/src/emu/cpu/cpu.mak.orig	2007-05-25 23:12:32.000000000 -0700
+++ sdlmess0115/src/emu/cpu/cpu.mak	2007-05-25 23:16:43.000000000 -0700
@@ -870,7 +870,6 @@
 							$(CPUSRC)/m6502/t65c02.c \
 							$(CPUSRC)/m6502/t65sc02.c \
 							$(CPUSRC)/m6502/t6510.c \
-							$(CPUSRC)/m6502/tdeco16.c
 
 $(CPUOBJ)/m6502/m65ce02.o:	$(CPUSRC)/m6502/m65ce02.c \
 							$(CPUSRC)/m6502/m65ce02.h \
@@ -1066,8 +1065,6 @@
 							$(CPUSRC)/powerpc/ppc.h \
 							$(CPUSRC)/powerpc/ppc_ops.c \
 							$(CPUSRC)/powerpc/ppc_mem.c \
-							$(CPUSRC)/powerpc/ppc403.c \
-							$(CPUSRC)/powerpc/ppc602.c \
 							$(CPUSRC)/powerpc/ppc603.c
 
 $(CPUOBJ)/powerpc/ppcdrc.o:	$(CPUSRC)/powerpc/ppcdrc.c \
@@ -1109,7 +1106,6 @@
 						$(CPUSRC)/nec/nec.h \
 						$(CPUSRC)/nec/necintrf.h \
 						$(CPUSRC)/nec/necea.h \
-						$(CPUSRC)/nec/nechost.h \
 						$(CPUSRC)/nec/necinstr.h \
 						$(CPUSRC)/nec/necmodrm.h
 
@@ -1118,7 +1114,6 @@
 							$(CPUSRC)/v30mz/necmodrm.h \
 							$(CPUSRC)/v30mz/necinstr.h \
 							$(CPUSRC)/v30mz/necea.h \
-							$(CPUSRC)/v30mz/nechost.h \
 							$(CPUSRC)/v30mz/necintrf.h
 
 
@@ -1398,7 +1393,6 @@
 $(CPUOBJ)/tms9900/tms9900.o:	$(CPUSRC)/tms9900/tms9900.c \
 								$(CPUSRC)/tms9900/tms9900.h \
 								$(CPUSRC)/tms9900/99xxcore.h \
-								$(CPUSRC)/tms9900/99xxstat.h
 
 $(CPUOBJ)/tms9900/tms9980a.o:	$(CPUSRC)/tms9900/tms9980a.c \
 								$(CPUSRC)/tms9900/tms9900.h \
@@ -1644,7 +1638,6 @@
 
 $(CPUOBJ)/minx/minx.o:		$(CPUSRC)/minx/minx.c \
 							$(CPUSRC)/minx/minx.h \
-							$(CPUSRC)/minx/minxd.c \
 							$(CPUSRC)/minx/minxopce.h \
 							$(CPUSRC)/minx/minxopcf.h \
 							$(CPUSRC)/minx/minxops.h \

