diff -Nru base0133/src/emu/inptport.c w0133/src/emu/inptport.c
--- base0133/src/emu/inptport.c	2009-05-27 20:15:29.000000000 +1200
+++ w0133/src/emu/inptport.c	2009-07-20 22:24:43.000000000 +1200
@@ -107,6 +107,10 @@
 #include "uimess.h"
 #endif /* MESS */
 
+/* recorded speed read from an INP file */
+double rec_speed;
+int sprintframetime(char *timearray, const running_machine *machine);
+
 
 /* temporary: set this to 1 to enable the originally defined behavior that
    a field specified via PORT_MODIFY which intersects a previously-defined
@@ -1944,8 +1948,10 @@
 profiler_mark(PROFILER_INPUT);
 
 	/* record/playback information about the current frame */
-	playback_frame(machine, curtime);
-	record_frame(machine, curtime);
+	if(machine->input_port_data->playback_file)  // avoid re-recording - coz that's cheating. ;)
+		playback_frame(machine, curtime);
+	else
+		record_frame(machine, curtime);
 
 	/* track the duration of the previous frame */
 	portdata->last_delta_nsec = attotime_to_attoseconds(attotime_sub(curtime, portdata->last_frame_time)) / ATTOSECONDS_PER_NANOSECOND;
@@ -3909,6 +3915,9 @@
 static void playback_end(running_machine *machine, const char *message)
 {
 	input_port_private *portdata = machine->input_port_data;
+	char timearray[]="100d 00:00:00.00:";
+	double avg_speed = ((double)portdata->playback_accumulated_speed/10000) / portdata->playback_accumulated_frames;
+	sprintframetime(timearray, machine);
 
 	/* only applies if we have a live file */
 	if (portdata->playback_file != NULL)
@@ -3919,12 +3928,16 @@
 
 		/* pop a message */
 		if (message != NULL)
-			popmessage("Playback Ended\nReason: %s", message);
+			popmessage("Playback Ended - %u Frames (%s) - Speed %6.2f%%\nReason: %s",
+				(UINT32)portdata->playback_accumulated_frames, timearray, avg_speed, message);
 
 		/* display speed stats */
-		portdata->playback_accumulated_speed /= portdata->playback_accumulated_frames;
-		mame_printf_info("Total playback frames: %d\n", (UINT32)portdata->playback_accumulated_frames);
-		mame_printf_info("Average recorded speed: %d%%\n", (UINT32)((portdata->playback_accumulated_speed * 200 + 1) >> 21));
+		if (portdata->playback_accumulated_frames)
+			portdata->playback_accumulated_speed /= portdata->playback_accumulated_frames;
+		else
+			portdata->playback_accumulated_speed = 0;
+		mame_printf_info("Total playback frames: %d (%s)\n", (UINT32)portdata->playback_accumulated_frames,timearray);
+		mame_printf_info("Average recorded speed: %d%%\n", (UINT32)(avg_speed));
 	}
 }
 
@@ -3950,7 +3963,7 @@
 			playback_end(machine, "Out of sync");
 
 		/* then the speed */
-		portdata->playback_accumulated_speed += playback_read_uint32(machine);
+		portdata->playback_accumulated_speed += (rec_speed=playback_read_uint32(machine)/(double)(1 << 20))*1000000;
 		portdata->playback_accumulated_frames++;
 	}
 }
@@ -4069,6 +4082,13 @@
 	if (filename[0] == 0)
 		return;
 
+	/* if in debug mode, don't start recording */
+	if(machine->debug_flags & DEBUG_FLAG_ENABLED)
+		return;
+
+	/* disable cheats */
+	options_set_bool(mame_options(),OPTION_CHEAT,0,OPTION_PRIORITY_MAXIMUM);
+
 	/* open the record file  */
 	filerr = mame_fopen(SEARCHPATH_INPUTLOG, filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &portdata->record_file);
 	assert_always(filerr == FILERR_NONE, "Failed to open file for recording");
@@ -4174,3 +4194,55 @@
 		}
 	}
 }
+
+/* INP file handle helper functions */
+mame_file* get_record_file(running_machine* machine)
+{
+	input_port_private *portdata = machine->input_port_data;
+	return portdata->record_file;
+}
+
+mame_file* get_playback_file(running_machine* machine)
+{
+	input_port_private *portdata = machine->input_port_data;
+	return portdata->playback_file;
+}
+
+int sprintframetime(char *timearray, const running_machine *machine)
+{
+	static int fps = 0;
+	char *tptr=timearray;
+	int seconds;
+	int minutes;
+	if (!fps) // assign the fps that we'll be calculating (must be same mess version)
+		fps=ATTOSECONDS_TO_HZ(((const screen_config *)video_screen_first(machine->config)->inline_config)->refresh);
+	seconds = (fps) ? machine->input_port_data->playback_accumulated_frames/fps : 0;
+	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*(machine->input_port_data->playback_accumulated_frames%fps)/fps;
+	*tptr++ = '.';
+	*tptr++ = '0'+seconds/10;
+	*tptr++ = '0'+seconds%10;
+	*tptr=0;
+	return tptr-timearray;
+}
diff -Nru base0133/src/emu/inptport.h w0133/src/emu/inptport.h
--- base0133/src/emu/inptport.h	2009-05-27 20:15:29.000000000 +1200
+++ w0133/src/emu/inptport.h	2009-07-20 22:24:43.000000000 +1200
@@ -1036,5 +1036,8 @@
 /* convert an input_port_token to a default string */
 const char *input_port_string_from_token(const input_port_token token);
 
+/* helper function to access INP file handles.  **shakes fist at MAMEdev** */
+mame_file* get_record_file(running_machine* machine);
+mame_file* get_playback_file(running_machine* machine);
 
 #endif	/* __INPTPORT_H__ */
diff -Nru base0133/src/emu/ui.c w0133/src/emu/ui.c
--- base0133/src/emu/ui.c	2009-04-27 21:18:17.000000000 +1200
+++ w0133/src/emu/ui.c	2009-07-20 22:24:43.000000000 +1200
@@ -21,6 +21,7 @@
 #include "uiinput.h"
 #include "uimenu.h"
 #include "uigfx.h"
+#include "inptport.h"
 
 #ifdef MESS
 #include "mess.h"
@@ -248,7 +249,7 @@
 
 	/* disable everything if we are using -str for 300 or fewer seconds, or if we're the empty driver,
        or if we are debugging */
-	if (!first_time || (str > 0 && str < 60*5) || machine->gamedrv == &driver_empty || (machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
+	if (!first_time || (str > 0 && str < 60*5) || machine->gamedrv == &driver_empty || (machine->debug_flags & DEBUG_FLAG_ENABLED) != 0  || get_record_file(machine))
 		show_gameinfo = show_warnings = show_disclaimer = FALSE;
 
 	/* initialize the on-screen display system */
@@ -1198,7 +1199,7 @@
 		mame_schedule_soft_reset(machine);
 
 	/* handle a request to display graphics/palette */
-	if (ui_input_pressed(machine, IPT_UI_SHOW_GFX))
+	if (ui_input_pressed(machine, IPT_UI_SHOW_GFX) && !get_record_file(machine))
 	{
 		if (!is_paused)
 			mame_pause(machine, TRUE);
@@ -1206,14 +1207,14 @@
 	}
 
 	/* handle a save state request */
-	if (ui_input_pressed(machine, IPT_UI_SAVE_STATE))
+	if (ui_input_pressed(machine, IPT_UI_SAVE_STATE) && !get_record_file(machine))
 	{
 		mame_pause(machine, TRUE);
 		return ui_set_handler(handler_load_save, LOADSAVE_SAVE);
 	}
 
 	/* handle a load state request */
-	if (ui_input_pressed(machine, IPT_UI_LOAD_STATE))
+	if (ui_input_pressed(machine, IPT_UI_LOAD_STATE) && !get_record_file(machine))
 	{
 		mame_pause(machine, TRUE);
 		return ui_set_handler(handler_load_save, LOADSAVE_LOAD);
@@ -1224,7 +1225,7 @@
 		video_save_active_screen_snapshots(machine);
 
 	/* toggle pause */
-	if (ui_input_pressed(machine, IPT_UI_PAUSE))
+	if (ui_input_pressed(machine, IPT_UI_PAUSE) && !get_record_file(machine))
 	{
 		/* with a shift key, it is single step */
 		if (is_paused && (input_code_pressed(KEYCODE_LSHIFT) || input_code_pressed(KEYCODE_RSHIFT)))
@@ -1286,11 +1287,11 @@
 	}
 
 	/* toggle throttle? */
-	if (ui_input_pressed(machine, IPT_UI_THROTTLE))
+	if (ui_input_pressed(machine, IPT_UI_THROTTLE) && !get_record_file(machine))
 		video_set_throttle(!video_get_throttle());
 
 	/* check for fast forward */
-	if (input_type_pressed(machine, IPT_UI_FAST_FORWARD, 0))
+	if (input_type_pressed(machine, IPT_UI_FAST_FORWARD, 0) && !get_record_file(machine))
 	{
 		video_set_fastforward(TRUE);
 		ui_show_fps_temp(0.5);
diff -Nru base0133/src/emu/uimenu.c w0133/src/emu/uimenu.c
--- base0133/src/emu/uimenu.c	2009-07-14 19:06:24.000000000 +1200
+++ w0133/src/emu/uimenu.c	2009-07-20 22:24:43.000000000 +1200
@@ -16,6 +16,7 @@
 #include "uimenu.h"
 #include "audit.h"
 #include "eminline.h"
+#include "inptport.h"
 
 #ifdef MESS
 #include "uimess.h"
@@ -1225,7 +1226,7 @@
 	}
 
 	/* pause enables/disables pause */
-	if (!ignorepause && exclusive_input_pressed(menu, IPT_UI_PAUSE, 0))
+	if (!ignorepause && exclusive_input_pressed(menu, IPT_UI_PAUSE, 0) && !get_record_file(menu->machine))
 		mame_pause(menu->machine, !mame_is_paused(menu->machine));
 
 	/* see if any other UI keys are pressed */
diff -Nru base0133/src/emu/video.c w0133/src/emu/video.c
--- base0133/src/emu/video.c	2009-07-16 19:37:54.000000000 +1200
+++ w0133/src/emu/video.c	2009-07-20 22:24:43.000000000 +1200
@@ -165,7 +165,7 @@
 	{ 0,1,1,1,1,1,1,1,1,1,1,1 }
 };
 
-
+extern double rec_speed;
 
 /***************************************************************************
     FUNCTION PROTOTYPES
@@ -1609,10 +1609,14 @@
 	int paused = mame_is_paused(machine);
 	static char buffer[1024];
 	char *dest = buffer;
+	screen_state* state = get_safe_token(machine->primary_screen);
 
 	/* validate */
 	assert(machine != NULL);
 
+	/* show frame counter */
+	dest += sprintf(dest, "[%i] : ",(UINT32)state->frame_number);
+
 	/* if we're paused, just display Paused */
 	if (paused)
 		dest += sprintf(dest, "paused");
@@ -1637,6 +1641,10 @@
 	if (global.partial_updates_this_frame > 1)
 		dest += sprintf(dest, "\n%d partial updates", global.partial_updates_this_frame);
 
+	if(get_playback_file(machine))
+	{
+		dest += sprintf(dest,"\nRecorded speed: %5.2f%%",rec_speed*100);
+	}
 	/* return a pointer to the static buffer */
 	return buffer;
 }
diff -Nru base0133/src/version.c w0133/src/version.c
--- base0133/src/version.c	2009-07-20 19:20:41.000000000 +1200
+++ w0133/src/version.c	2009-07-20 22:26:10.000000000 +1200
@@ -10,4 +10,4 @@
 ***************************************************************************/
 
 extern const char build_version[];
-const char build_version[] = "0.133 ("__DATE__")";
+const char build_version[] = "0.133[W] ("__DATE__")";
diff -Nru --strip-trailing-cr mames/src/emu/info.c.orig mames/src/emu/info.c
--- mames/src/emu/info.c.orig	2008-05-24 16:46:32.000000000 -0700
+++ mames/src/emu/info.c	2008-05-24 17:21:06.000000000 -0700
@@ -40,21 +39,30 @@
 {
 	const input_port_config *port;
 	const input_field_config *field;
+	int portnum = -1;
 
 	/* iterate looking for DIP switches */
 	for (port = portlist; port != NULL; port = port->next)
 		for (field = port->fieldlist; field != NULL; field = field->next)
+		{
+			if (port->tag != NULL)
+				portnum++;
 			if (field->type == IPT_DIPSWITCH)
 			{
 				const input_setting_config *setting;
 
 				/* output the switch name information */
 				fprintf(out, "\t\t<dipswitch name=\"%s\">\n", xml_normalize_string(input_field_name(field)));
+				fprintf(out, "\t\t<dipswitch");
+				fprintf(out, " mask=\"%i\"", field->mask);
+				fprintf(out, " port=\"%i\"", portnum);
+				fprintf(out, " name=\"%s\">\n", xml_normalize_string(input_field_name(field)));
 
 				/* loop over settings */
 				for (setting = field->settinglist; setting != NULL; setting = setting->next)
 				{
 					fprintf(out, "\t\t\t<dipvalue name=\"%s\"", xml_normalize_string(setting->name));
+					fprintf(out, " value=\"%i\"", setting->value);
 					if (setting->value == field->defvalue)
 						fprintf(out, " default=\"yes\"");
 					fprintf(out, "/>\n");
@@ -63,6 +72,7 @@
 				/* terminate the switch entry */
 				fprintf(out, "\t\t</dipswitch>\n");
 			}
+		}
 }
 
 
diff -Nru base0133/src/emu/emu.mak w0133/src/emu/emu.mak
--- base0133/src/emu/emu.mak	2009-07-11 01:26:54.000000000 +1200
+++ w0133/src/emu/emu.mak	2009-07-20 22:45:40.000000000 +1200
@@ -86,7 +86,8 @@
 	$(EMUOBJ)/debug/debughlp.o \
 	$(EMUOBJ)/debug/debugvw.o \
 	$(EMUOBJ)/debug/express.o \
-	$(EMUOBJ)/debug/textbuf.o
+	$(EMUOBJ)/debug/textbuf.o \
+	$(EMUOBJ)/inpview.o
 
 ifdef PROFILER
 EMUOBJS += \
diff -Nru base0133/src/emu/emuopts.c w0133/src/emu/emuopts.c
--- base0133/src/emu/emuopts.c	2009-07-14 10:34:43.000000000 +1200
+++ w0133/src/emu/emuopts.c	2009-07-20 22:45:40.000000000 +1200
@@ -156,6 +156,8 @@
 	{ "bios",                        NULL,        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 base0133/src/emu/inptport.c w0133/src/emu/inptport.c
--- base0133/src/emu/inptport.c	2009-05-27 20:15:29.000000000 +1200
+++ w0133/src/emu/inptport.c	2009-07-20 22:45:40.000000000 +1200
@@ -107,6 +107,7 @@
 #include "uimess.h"
 #endif /* MESS */
 
+#include "inpview.h"
 
 /* temporary: set this to 1 to enable the originally defined behavior that
    a field specified via PORT_MODIFY which intersects a previously-defined
@@ -659,6 +660,9 @@
 	/* register callbacks for when we load configurations */
 	config_register(machine, "input", load_config_callback, save_config_callback);
 
+	/* 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 */
 	basetime = playback_init(machine);
 	record_init(machine);
@@ -3993,6 +3997,36 @@
     INPUT RECORDING
 ***************************************************************************/
 
+int input_port_used(running_machine* machine, int type,int player)
+{
+	const input_port_config* port;
+	const input_field_config* bit;
+
+	/* loop over all input ports */
+	for (port = machine->portconfig; port != NULL; port = port->next)
+	{
+		UINT32 portvalue;
+
+		/* loop over all bitfields for this port */
+		for (bit = port->fieldlist; bit != NULL; bit = bit->next)
+		{
+			if((port->state->defvalue & bit->mask) != 0)  // default value for the bit should be 0 if active high.
+				portvalue = ~port->state->digital;
+			else
+				portvalue = port->state->digital;
+
+			if(bit->type == type && bit->player == player)
+			{
+				if((bit->type == type) && (portvalue & bit->mask) != (bit->defvalue & bit->mask))
+					return 1;
+				else
+					return 0;
+			}
+		}
+	}
+	return 0;
+}
+
 /*-------------------------------------------------
     record_write_uint8 - write an 8-bit value
     to the record file
diff -Nru base0133/src/emu/inptport.h w0133/src/emu/inptport.h
--- base0133/src/emu/inptport.h	2009-05-27 20:15:29.000000000 +1200
+++ w0133/src/emu/inptport.h	2009-07-20 22:45:40.000000000 +1200
@@ -1037,4 +1037,6 @@
 const char *input_port_string_from_token(const input_port_token token);
 
 
+int input_port_used(running_machine*, int, int);
+
 #endif	/* __INPTPORT_H__ */
diff -Nru base0133/src/emu/inpview.c w0133/src/emu/inpview.c
--- base0133/src/emu/inpview.c	1970-01-01 13:00:00.000000000 +1300
+++ w0133/src/emu/inpview.c	2009-07-20 22:45:40.000000000 +1200
@@ -0,0 +1,257 @@
+// Input viewer module for MAME
+// Complete re-write started Aug 23, 2006
+
+#include <stdio.h>
+#include "ui.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(running_machine* machine)
+{
+	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(machine,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(machine,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 base0133/src/emu/inpview.h w0133/src/emu/inpview.h
--- base0133/src/emu/inpview.h	1970-01-01 13:00:00.000000000 +1300
+++ w0133/src/emu/inpview.h	2009-07-20 22:45:40.000000000 +1200
@@ -0,0 +1,26 @@
+// Input viewer header
+
+#include "mame.h"
+
+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(running_machine*);
+void inpview_set_data(int,const char*);
+int inpview_get_player(void);
+unsigned int convert_txt(char*);
diff -Nru base0133/src/emu/ui.c w0133/src/emu/ui.c
--- base0133/src/emu/ui.c	2009-04-27 21:18:17.000000000 +1200
+++ w0133/src/emu/ui.c	2009-07-20 22:45:40.000000000 +1200
@@ -30,7 +30,7 @@
 
 #include <ctype.h>
 
-
+#include "inpview.h"
 
 /***************************************************************************
     CONSTANTS
@@ -372,6 +372,11 @@
 	/* cancel takes us back to the ingame handler */
 	if (ui_handler_param == UI_HANDLER_CANCEL)
 		ui_set_handler(handler_ingame, 0);
+
+ 	// Input viewer
+ 	if(inpview_get_player() != 0)
+ 		render_input(machine);
+ 
 }
 
 
diff -Nru mess_cvs/src/emu/video/tms9928a.c mess/src/emu/video/tms9928a.c
--- mess_cvs/src/emu/video/tms9928a.c	2008-05-24 12:51:55.000000000 -0300
+++ mess/src/emu/video/tms9928a.c	2008-05-24 20:53:49.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
@@ -234,6 +234,10 @@
 	return &tms.visarea;
 }
 
+/* hide borders */
+void TMS9928A_hide_borders (running_machine *machine, int hide_borders) {
+	video_screen_set_visarea (machine->primary_screen, 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 (running_machine *machine) {
 	int i;
diff -Nru mess_cvs/src/emu/video/tms9928a.h mess/src/emu/video/tms9928a.h
--- mess_cvs/src/emu/video/tms9928a.h	2008-05-24 12:51:55.000000000 -0300
+++ mess/src/emu/video/tms9928a.h	2008-05-24 20:58:48.000000000 -0300
@@ -86,3 +86,6 @@
 ** MachineDriver video declarations for the TMS9928A chip
 */
 MACHINE_DRIVER_EXTERN( tms9928a );
+
+/* hide borders */
+void TMS9928A_hide_borders (running_machine *, int);
diff -Nru mess_cvs/src/emu/video/v9938.c mess/src/emu/video/v9938.c
--- mess_cvs/src/emu/video/v9938.c	2008-05-24 12:51:55.000000000 -0300
+++ mess/src/emu/video/v9938.c	2008-05-24 20:49:09.000000000 -0300
@@ -48,6 +48,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 */
@@ -633,6 +635,15 @@
 		}
 	}
 
+void v9938_hide_borders (int i)
+	{
+	vdp->hide_borders = i;
+	if (vdp->size == RENDER_HIGH)
+		video_screen_set_visarea (vdp->screen, 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 (vdp->screen, 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
@@ -1453,9 +1464,9 @@
 	if (vdp->size != vdp->size_old)
 		{
 		if (vdp->size == RENDER_HIGH)
-			video_screen_set_visarea (vdp->screen, 0, 512 + 32 - 1, 0, 424 + 56 - 1);
+			video_screen_set_visarea (vdp->screen, 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 (vdp->screen, 0, 256 + 16 - 1, 0, 212 + 28 - 1);
+			video_screen_set_visarea (vdp->screen, 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_cvs/src/emu/video/v9938.h mess/src/emu/video/v9938.h
--- mess_cvs/src/emu/video/v9938.h	2008-05-24 12:51:55.000000000 -0300
+++ mess/src/emu/video/v9938.h	2008-05-24 20:48:20.000000000 -0300
@@ -20,6 +20,7 @@
 void v9938_set_sprite_limit (int which, int);
 void v9938_set_resolution (int which, int);
 int v9938_get_transpen(int which);
+void v9938_hide_borders (int);
 
 extern PALETTE_INIT( v9938 );
 extern PALETTE_INIT( v9958 );
diff -Nru --strip-trailing-cr mames/src/mess/drivers/msx.c.orig mames/src/mess/drivers/msx.c
--- mames/src/mess/drivers/msx.c.orig	2008-08-29 23:21:06.000000000 -0700
+++ mames/src/mess/drivers/msx.c	2008-08-29 23:22:52.000000000 -0700
@@ -137,6 +137,11 @@
 	PORT_DIPSETTING( 1, DEF_STR( Low ))
 	PORT_DIPSETTING( 2, "Auto" )
 
+	PORT_START("OPTIONS")
+	PORT_CONFNAME(0x01, 0x00, "Hide borders")
+	PORT_CONFSETTING( 0x00, DEF_STR( No ))
+	PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
+
 	PORT_START("MOUSE0")
 	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_cvs/src/mess/machine/msx.c mess/src/mess/machine/msx.c
--- mess_cvs/src/mess/machine/msx.c	2008-05-24 12:54:48.000000000 -0300
+++ mess/src/mess/machine/msx.c	2008-05-24 20:58:44.000000000 -0300
@@ -405,6 +405,7 @@
 {
 	v9938_set_sprite_limit(0, input_port_read(device->machine, "DSW") & 0x20);
 	v9938_set_resolution(0, input_port_read(device->machine, "DSW") & 0x03);
+	v9938_hide_borders(input_port_read(device->machine, "OPTIONS") & 0x01);
 	v9938_interrupt(device->machine, 0);
 }
 
@@ -421,6 +422,7 @@
 	}
 
 	TMS9928A_set_spriteslimit (input_port_read(device->machine, "DSW") & 0x20);
+	TMS9928A_hide_borders(device->machine, input_port_read(device->machine, "OPTIONS") & 0x01);
 	TMS9928A_interrupt(device->machine);
 }
 
diff -Nru mess_cvs/src/mess/includes/spectrum.h mess/src/mess/includes/spectrum.h
--- mess_cvs/src/mess/includes/spectrum.h	2008-05-24 12:53:33.000000000 -0300
+++ mess/src/mess/includes/spectrum.h	2008-05-24 20:34:36.000000000 -0300
@@ -23,6 +23,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 */
@@ -46,6 +51,11 @@
 #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
+
 typedef enum
 {
 	TIMEX_CART_NONE,
diff -Nru mames/src/mess/video/spectrum.c.orig mames/src/mess/video/spectrum.c
--- mames/src/mess/video/spectrum.c.orig	2009-03-11 19:37:54.000000000 -0700
+++ mames/src/mess/video/spectrum.c	2009-03-11 19:39:52.000000000 -0700
@@ -122,7 +122,12 @@
         int x, y, b, scrx, scry;
         unsigned short ink, pap;
         unsigned char *attr, *scr;
-		int full_refresh = 1;
+	int full_refresh = 1;
+	int hide_borders;
+	
+	hide_borders = input_port_read(screen->machine, "OPTIONS") & 0x01;
+
+	video_screen_set_visarea (screen->machine->primary_screen, 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_screen_location;
 
diff -Nru mess_cvs/src/mess/drivers/spectrum.c mess/src/mess/drivers/spectrum.c
--- mess_cvs/src/mess/drivers/spectrum.c	2008-05-24 12:55:29.000000000 -0300
+++ mess/src/mess/drivers/spectrum.c	2008-05-24 20:34:36.000000000 -0300
@@ -438,6 +438,11 @@
 	PORT_DIPSETTING(	0x00, "Enabled" )
 	PORT_DIPSETTING(	0x20, "Disabled" )
 	PORT_BIT(0x1f, IP_ACTIVE_LOW, IPT_UNUSED)
+
+	PORT_START("OPTIONS") /* [17] */
+	PORT_CONFNAME(0x01, 0x00, "Hide borders")
+	PORT_CONFSETTING( 0x00, DEF_STR( No ))
+	PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
 
 	PORT_INCLUDE( spec_joys )
 INPUT_PORTS_ENDdiff -Nru mess_cvs/src/mess/video/timex.c mess/src/mess/video/timex.c
--- mess_cvs/src/mess/video/timex.c	2008-05-24 12:53:54.000000000 -0300
+++ mess/src/mess/video/timex.c	2008-05-24 20:38:21.000000000 -0300
@@ -201,6 +201,10 @@
 	/* for now TS2068 will do a full-refresh */
 	int count;
 	int full_refresh = 1;
+	int hide_borders;
+	hide_borders = input_port_read(screen->machine, "OPTIONS") & 0x01;
+
+	video_screen_set_visarea (screen->machine->primary_screen, 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)
         {
@@ -241,6 +245,10 @@
 	/* for now TS2068 will do a full-refresh */
 	int count;
 	int full_refresh = 1;
+	int hide_borders;
+	hide_borders = input_port_read(screen->machine, "OPTIONS") & 0x01;
+
+	video_screen_set_visarea (screen->machine->primary_screen, 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
@@ -1069,6 +1069,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)
 				{
@@ -2436,7 +2445,7 @@
 	datamap_set_trackbar_range(properties_datamap, IDC_PRESCALE,    1, 10, 1);
 	datamap_set_trackbar_range(properties_datamap, IDC_JDZ,         0.00, 1.00,  (float)0.05);
 	datamap_set_trackbar_range(properties_datamap, IDC_JSAT,        0.00, 1.00,  (float)0.05);
-	datamap_set_trackbar_range(properties_datamap, IDC_SPEED,       0.00, 3.00,  (float)0.01);
+	datamap_set_trackbar_range(properties_datamap, IDC_SPEED,       0.00,55.00,  (float)0.25);
 	datamap_set_trackbar_range(properties_datamap, IDC_BEAM,        (float)0.10, 10.00, (float)0.10);
 	datamap_set_trackbar_range(properties_datamap, IDC_VOLUME,      -32,  0, 1);
 	datamap_set_trackbar_range(properties_datamap, IDC_SECONDSTORUN, 0,  60, 1);
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",                   "0",    OPTION_BOOLEAN,		"use the new MESS UI" },
+	{ "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,119,134,86,10,0
     CONTROL         "Use New UI",IDC_USE_NEW_UI,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,119,146,86,10,0
+    GROUPBOX        "Tournament",IDC_STATIC,113,154,102,28
+    EDITTEXT        IDC_TOURNAMENT,119,164,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
@@ -91,6 +91,7 @@
 {
 	/* allocate memory for our data structure */
 	machine->ui_mess_data = auto_alloc_clear(machine, ui_mess_private);
+	machine->ui_mess_data->active = 1; /* start mess in partial emulation mode */
 
 	/* retrieve options */
 	machine->ui_mess_data->use_natural_keyboard = options_get_bool(mame_options(), OPTION_NATURAL_KEYBOARD);
@@ -325,7 +326,7 @@
 int ui_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/mslegacy.c mames/src/mess/mslegacy.c
--- mames.111/src/mess/mslegacy.c	2006-07-30 09:07:44.000000000 -0700
+++ mames/src/mess/mslegacy.c	2007-01-14 18:45:22.000000000 -0800
@@ -11,7 +11,7 @@
 #include "mslegacy.h"
 
 
-static const char *const mess_default_text[] =
+const char *const mess_default_text[] =
 {
 	"OK",
 	"Off",
@@ -70,7 +70,8 @@
 	"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 machine_config *config, const device_config *dev)
 {
 	image_device_info info = image_device_getinfo(config, dev);
@@ -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 machine_config *config, const device_config *device, const char *software);
 const char *GetSelectedSoftware(int driver_index, const machine_config *config, const device_config *device);
 
+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" },
 	{ "aviwrite",                    NULL,        0,                 "optional filename to write an AVI 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/src/emu/video.c.orig mames/src/emu/video.c
--- mames/src/emu/video.c.orig	2008-05-10 14:54:18.000000000 -0700
+++ mames/src/emu/video.c	2008-05-10 16:12:52.000000000 -0700
@@ -100,6 +100,7 @@
 	osd_ticks_t 			speed_last_realtime;	/* real time at the last speed calculation */
 	attotime 				speed_last_emutime;		/* emulated time at the last speed calculation */
 	double 					speed_percent;			/* most recent speed percentage */
+	double 					rec_percent;			/* most recent playing back speed percentage */
 	UINT32 					partial_updates_this_frame;/* partial update counter this frame */
 
 	/* overall speed computation */
@@ -1597,14 +1598,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);
-
-	if(get_playback_file(machine))
-	{
-		dest += sprintf(dest,"\nRecorded speed: %5.2f%%",rec_speed*100);
-	}
+  	/* display playback info when playing back - don't leave Recorded speed line in */
+	{
+		extern int sprintf_playback_info(char *dest, const running_machine *machine); 
+		dest += sprintf_playback_info(dest, machine);
+	}
 	/* return a pointer to the static buffer */
 	return buffer;
 }
@@ -1844,6 +1848,10 @@
 	osd_ticks_t target_ticks;
 	osd_ticks_t diff_ticks;
 
+	/* always throttle when recording and don't throttle if not throttling */
+	//if (machine->input_port_data->record_file) global.throttle = 100;
+	if (!global.throttle) return;
+		
 	/* apply speed factor to emu time */
 	if (global.speed != 0 && global.speed != 100)
 	{
diff -Nru --strip-trailing-cr mames/src/emu/inptport.c.orig mames/src/emu/inptport.c
--- mames/src/emu/inptport.c.orig	2009-06-17 10:55:58.000000000 -0700
+++ mames/src/emu/inptport.c	2009-06-17 11:24:04.000000000 -0700
@@ -102,6 +102,9 @@
 #include <ctype.h>
 #include <time.h>
 #include <stdarg.h>
+#include "options.h"
+static int val2;
+/*#define MAX_INPUT_PORTS			32*/
 
 #ifdef MESS
 #include "uimess.h"
@@ -284,6 +288,32 @@
 #define RECIP_SCALE(s)				(((INT64)1 << 48) / (s))
 #define APPLY_SCALE(x,s)			(((INT64)(x) * (s)) >> 24)
 
+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 && swapped_image_cache_port[i++])
+		swapped_image_cache_port[i-1]=swapped_image_cache_port[i];
+	return q;
+}
+
+const mame_file *mame_recording(const running_machine *machine)
+{
+	return machine->input_port_data->record_file;
+}
 
 
 /***************************************************************************
@@ -489,13 +519,11 @@
 
 /* input playback */
 static time_t playback_init(running_machine *machine);
-static void playback_end(running_machine *machine, const char *message);
 static void playback_frame(running_machine *machine, attotime curtime);
 static void playback_port(const input_port_config *port);
 
 /* input recording */
 static void record_init(running_machine *machine);
-static void record_end(running_machine *machine, const char *message);
 static void record_frame(running_machine *machine, attotime curtime);
 static void record_port(const input_port_config *port);
 
@@ -3879,7 +3910,15 @@
 
 	/* open the playback file */
 	filerr = mame_fopen(SEARCHPATH_INPUTLOG, filename, OPEN_FLAG_READ, &portdata->playback_file);
-	assert_always(filerr == FILERR_NONE, "Failed to open file for playback");
+	//portdata->playback_accumulated_frames = 0; // reset the playback counter (for the mess gui repeating playbacks)
+	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 (portdata->playback_file)
+			mame_fclose(portdata->playback_file);
+		portdata->playback_file=NULL;
+		return 0;
+	}
 
 	/* read the header and verify that it is a modern version; if not, print an error */
 	if (mame_fread(portdata->playback_file, header, sizeof(header)) != sizeof(header))
@@ -3899,7 +3938,14 @@
 
 	/* verify the header against the current game */
 	if (memcmp(machine->gamedrv->name, header + 0x14, strlen(machine->gamedrv->name) + 1) != 0)
-		fatalerror("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", header + 0x14, machine->gamedrv->name);
+	{
+		mame_printf_info("Input file is for " GAMENOUN " '%s', not for current " GAMENOUN " '%s'\n", 
+			header + 0x14, machine->gamedrv->name);
+		if (portdata->playback_file)
+			mame_fclose(portdata->playback_file);
+		portdata->playback_file=NULL;
+		return 0;
+	}
 
 	/* enable compression */
 	mame_fcompress(portdata->playback_file, FCOMPRESS_MEDIUM);
@@ -3912,7 +3958,7 @@
     playback_end - end INP playback
 -------------------------------------------------*/
 
-static void playback_end(running_machine *machine, const char *message)
+void playback_end(running_machine *machine, const char *message)
 {
 	input_port_private *portdata = machine->input_port_data;
 	char timearray[]="100d 00:00:00.00:";
@@ -3947,7 +3993,7 @@
     playback
 -------------------------------------------------*/
 
-static void playback_frame(running_machine *machine, attotime curtime)
+void playback_frame(running_machine *machine, attotime curtime)
 {
 	input_port_private *portdata = machine->input_port_data;
 
@@ -3957,7 +4003,20 @@
 		attotime readtime;
 
 		/* first the absolute time */
+		UINT32 dummy;
 		readtime.seconds = playback_read_uint32(machine);
+		/* take off the msb of the time for image caching */
+		if ( (dummy=(readtime.seconds>>24)) )
+		{
+			/* images were swapped must change images */
+			const device_config *img=image_from_absolute_index(machine, (dummy>>4)&0xf);
+			
+			if (image_cache_option_value((dummy&0xf)-1) && *image_cache_option_value((dummy&0xf)-1) && image_load(img,image_cache_option_value((dummy&0xf)-1))==INIT_FAIL) /* if image cache is empty skip this error */
+			{
+				popmessage("Playback image load failed: This recording expects valid imagecache%d option.",(int)(dummy&0xf));
+			}
+		}
+		readtime.seconds &= 0x00ffffff;
 		readtime.attoseconds = playback_read_uint64(machine);
 		if (attotime_compare(readtime, curtime) != 0)
 			playback_end(machine, "Out of sync");
@@ -4066,6 +4155,26 @@
 }
 
 
+int sprintf_playback_info(char *dest, const running_machine *machine)
+{
+	if (machine->input_port_data->playback_file)
+	{
+		int ret=sprintf(dest,"\n %5.1f%% ", 100*rec_speed);
+		ret += sprintframetime(dest+ret, machine);
+		return ret;
+	}
+	return	0; 
+}
+
+int image_cache_file_not_loaded_for_record(running_machine *machine, const char *filename)
+{
+	return machine->input_port_data->record_file
+		&& image_cache_option_value(0)
+		&& *image_cache_option_value(0)
+		&& !image_cache(filename)
+		;
+}
+
 /*-------------------------------------------------
     record_init - initialize INP recording
 -------------------------------------------------*/
@@ -4111,6 +4220,9 @@
 	header[0x11] = INP_HEADER_MINVERSION;
 	strcpy((char *)header + 0x14, machine->gamedrv->name);
 	sprintf((char *)header + 0x20, APPNAME " %s", build_version);
+	header[51+4] = 0; /* terminate the name for reserved wolfmess space */
+	val2 = (UINT32)systime.time;
+	tournament = options_get_int(mame_options(), "tournament");
 
 	/* write it */
 	mame_fwrite(portdata->record_file, header, sizeof(header));
@@ -4124,7 +4236,7 @@
     record_end - end INP recording
 -------------------------------------------------*/
 
-static void record_end(running_machine *machine, const char *message)
+void record_end(running_machine *machine, const char *message)
 {
 	input_port_private *portdata = machine->input_port_data;
 
@@ -4132,6 +4244,19 @@
 	if (portdata->record_file != NULL)
 	{
 		/* close the file */
+ 		UINT32 val=(UINT32)time(NULL),val3=options_get_int(mame_options(), mess_default_text[53-4]),a,b,c,d; char r=0;
+ 		if (!_mame_fseek(portdata->record_file,51+4,SEEK_SET,1))
+		{ mame_fwrite(portdata->record_file,&r,sizeof(char));
+		mame_fwrite(portdata->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(portdata->record_file,&val,sizeof(UINT32)); }
 		mame_fclose(portdata->record_file);
 		portdata->record_file = NULL;
 
@@ -4154,12 +4279,41 @@
 	/* if recording, record information about the current frame */
 	if (portdata->record_file != NULL)
 	{
+		const char *end_recording_message=NULL;
 		/* first the absolute time */
-		record_write_uint32(machine, curtime.seconds);
+		if (curtime.seconds & 0xff000000)
+		{
+			// end recording because we can't have it conflict with image caching
+			record_end(machine, end_recording_message="Can't overwite Image Cache Reserved Byte");
+		}
+		// if we have image cache swapping then note it in the msb of the seconds recorded
+		record_write_uint32(machine, curtime.seconds|(deque_swapped_image_cache()<<24));
 		record_write_uint64(machine, curtime.attoseconds);
 
 		/* then the current speed */
-		record_write_uint32(machine, video_get_speed_percent(machine) * (double)(1 << 20));
+		rec_speed=video_get_speed_percent(machine);
+		// round the speed so the precision is less and making the inp more compressable, nah dont do it it's fine
+		//rec_speed = ( (int)((rec_speed+(1./512))*256.) )/256.;
+ 		record_write_uint32(machine, rec_speed * (double)(1 << 20));
+
+		if (tournament)
+		{
+			// wait a few seconds of frames before checking speed
+			if (portdata->playback_accumulated_frames > 120 && rec_speed < .10)
+			{
+				end_recording_message=
+				"***********************************\n"
+				"******** Machine Emulation ********\n"
+				"****** Performance Degraded: ******\n"
+				"*********** Terminating ***********\n"
+				"************ Recording ************\n"
+				"***********************************\n";
+			}
+		}
+		if (end_recording_message)
+		{
+			record_end(machine, end_recording_message);
+		}
 	}
 }
 
diff -Nru --strip-trailing-cr mames/src/emu/inptport.h.orig mames/src/emu/inptport.h
--- mames/src/emu/inptport.h.orig	2009-06-17 10:56:00.000000000 -0700
+++ mames/src/emu/inptport.h	2009-06-17 10:56:00.000000000 -0700
@@ -518,6 +518,8 @@
 typedef struct _input_field_config input_field_config;
 
 
+void playback_end(running_machine* machine, const char *message);
+void record_end(running_machine* machine, const char *message);
 /* custom input port callback function */
 typedef UINT32 (*input_field_custom_func)(const input_field_config *field, void *param);
 
@@ -668,6 +670,8 @@
 	char						gamename[12];	/* +14: game name string, NULL-terminated */
 	char						version[32];	/* +20: system version string, NULL-terminated */
 };
+extern const char *const mess_default_text[];
+extern const mame_file *mame_recording(const running_machine *machine);
 
 
 
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
@@ -513,6 +513,62 @@
  * have been more appropriate for an Apple IIgs.  So we've substituted in the
  * Robert Munafo palette instead, which is more accurate on 8-bit Apples
  */
+/* 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, but my friend says the mess colors are more acurate less bright */
+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 rgb_t apple2_palette[] =
 {
 	RGB_BLACK,
@@ -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_palette, ARRAY_LENGTH(apple2_palette)); // apple2_pretty_palette
 }
 
 static const struct AY8910interface ay8910_interface =
@@ -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_palette)) // apple2_pretty_palette
 	MDRV_PALETTE_INIT(apple2)
 
 	MDRV_VIDEO_START(apple2)
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
@@ -921,6 +921,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_opts, drivers[nGameIndex]);
 #endif // MESS
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
@@ -865,6 +865,15 @@
 	// display the dialog
 	result = win_file_dialog(device->machine, wnd, is_save ? WIN_FILE_DIALOG_SAVE : WIN_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 (image_cache_file_not_loaded_for_record(device->machine,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)
 	{
 		// mount the image
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->config, machine->gamedrv, extract_device_options_for_device);
+			mess_enumerate_devices(mame_options(), machine->config, 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/src/mess/osd/winui/messui.c.orig mames/src/mess/osd/winui/messui.c
--- mames/src/mess/osd/winui/messui.c.orig	2008-05-05 08:46:54.000000000 -0700
+++ mames/src/mess/osd/winui/messui.c	2008-05-14 16:42:08.000000000 -0700
@@ -142,8 +142,8 @@
 
 static BOOL DevView_GetOpenFileName(HWND hwndDevView, const machine_config *config, const device_config *dev, LPTSTR pszFilename, UINT nFilenameLength);
 static BOOL DevView_GetCreateFileName(HWND hwndDevView, const machine_config *config, const device_config *dev, LPTSTR pszFilename, UINT nFilenameLength);
-static void DevView_SetSelectedSoftware(HWND hwndDevView, int nDriverIndex, const machine_config *config, const device_config *dev, LPCTSTR pszFilename);
-static LPCTSTR DevView_GetSelectedSoftware(HWND hwndDevView, int nDriverIndex, const machine_config *config, const device_config *dev, LPTSTR pszBuffer, UINT nBufferLength);
+static void DevView_SetSelectedSoftware(HWND hwndDevView, int nDriverIndex, const machine_config *config, const device_config *dev, int image_cache_index, LPCTSTR pszFilename);
+static LPCTSTR DevView_GetSelectedSoftware(HWND hwndDevView, int nDriverIndex, const machine_config *config, const device_config *dev, int image_cache_index, LPTSTR pszBuffer, UINT nBufferLength);
 
 #ifdef MAME_DEBUG
 static void MessTestsBegin(void);
@@ -842,6 +842,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);*/
+	}
+}
+
 
 static BOOL DevView_GetOpenFileName(HWND hwndDevView, const machine_config *config, const device_config *dev, LPTSTR pszFilename, UINT nFilenameLength)
 {
@@ -853,7 +867,10 @@
 	hwndList = GetDlgItem(GetMainWindow(), IDC_LIST);
 	gamenum = Picker_GetSelectedItem(hwndList);
 
-	SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev);
+	if (dev)
+		SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev);
+	else // if dev is unknown just specify all types
+		imagetypes[0].ext=NULL;
 	bResult = CommonFileImageDialog(last_directory, GetOpenFileName, pszFilename, config, imagetypes);
 
 	return bResult;
@@ -871,7 +888,10 @@
 	hwndList = GetDlgItem(GetMainWindow(), IDC_LIST);
 	gamenum = Picker_GetSelectedItem(hwndList);
 
-	SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev);
+	if (dev)
+		SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev);
+	else // if dev is unknown just specify all types
+		imagetypes[0].ext=NULL;
 	bResult = CommonFileImageDialog(last_directory, GetSaveFileName, pszFilename, config, imagetypes);
 
 	return bResult;
@@ -880,12 +900,15 @@
 
 
 static void DevView_SetSelectedSoftware(HWND hwndDevView, int drvindex,
-	const machine_config *config, const device_config *dev, LPCTSTR pszFilename)
+	const machine_config *config, const device_config *dev, int image_cache_index, LPCTSTR pszFilename) // not passing index
 {
 	char* utf8_filename = utf8_from_tstring(pszFilename);
 	if( !utf8_filename )
 		return;
-	MessSpecifyImage(drvindex, dev, utf8_filename);
+	if (image_cache_index>=0)
+		InternalSetSelectedImageCache(drvindex, image_cache_index, utf8_filename);
+	else
+		MessSpecifyImage(drvindex, dev, utf8_filename);
 	MessRefreshPicker();
 	free(utf8_filename);
 }
@@ -893,11 +916,13 @@
 
 
 static LPCTSTR DevView_GetSelectedSoftware(HWND hwndDevView, int nDriverIndex,
-	const machine_config *config, const device_config *dev, LPTSTR pszBuffer, UINT nBufferLength)
+ 	const machine_config *config, const device_config *dev, int image_cache_index, LPTSTR pszBuffer, UINT nBufferLength)
 {
 	LPCTSTR t_buffer = NULL;
 	TCHAR* t_s;
-	LPCSTR s = GetSelectedSoftware(nDriverIndex, config, dev);
+	LPCSTR s = (image_cache_index>=0
+		? GetSelectedImageCache(nDriverIndex, image_cache_index)
+		: GetSelectedSoftware(nDriverIndex, config, dev));
 
 	t_s = tstring_from_utf8(s);
 	if( !t_s )
diff -Nru --strip-trailing-cr mames/src/mess/osd/winui/devview.h.orig mames/src/mess/osd/winui/devview.h
--- mames/src/mess/osd/winui/devview.h.orig	2008-05-14 16:11:40.000000000 -0700
+++ mames/src/mess/osd/winui/devview.h	2008-05-14 16:12:32.000000000 -0700
@@ -8,8 +8,8 @@
 {
 	BOOL (*pfnGetOpenFileName)(HWND hwndDevView, const machine_config *config, const device_config *dev, LPTSTR pszFilename, UINT nFilenameLength);
 	BOOL (*pfnGetCreateFileName)(HWND hwndDevView, const machine_config *config, const device_config *dev, LPTSTR pszFilename, UINT nFilenameLength);
-	void (*pfnSetSelectedSoftware)(HWND hwndDevView, int nGame, const machine_config *config, const device_config *dev, LPCTSTR pszFilename);
-	LPCTSTR (*pfnGetSelectedSoftware)(HWND hwndDevView, int nGame, const machine_config *config, const device_config *dev, LPTSTR pszBuffer, UINT nBufferLength);
+	void (*pfnSetSelectedSoftware)(HWND hwndDevView, int nGame, const machine_config *config, const device_config *dev, int image_cache_index, LPCTSTR pszFilename);
+	LPCTSTR (*pfnGetSelectedSoftware)(HWND hwndDevView, int nGame, const machine_config *config, const device_config *dev, int image_cache_index, LPTSTR pszBuffer, UINT nBufferLength);
 };
 
 void DevView_SetCallbacks(HWND hwndDevView, const struct DevViewCallbacks *pCallbacks);
diff -Nru --strip-trailing-cr mames/src/mess/osd/winui/devview.c.orig mames/src/mess/osd/winui/devview.c
--- mames/src/mess/osd/winui/devview.c.orig	2008-05-14 15:39:44.000000000 -0700
+++ mames/src/mess/osd/winui/devview.c	2008-05-14 16:23:12.000000000 -0700
@@ -38,6 +38,8 @@
 struct DevViewEntry
 {
 	const device_config *dev;
+	int active;
+	int image_cache_index;
 	HWND hwndStatic;
 	HWND hwndEdit;
 	HWND hwndBrowseButton;
@@ -64,7 +66,7 @@
 
 	if (pDevViewInfo->pEntries != NULL)
 	{
-		for (i = 0; pDevViewInfo->pEntries[i].dev; i++)
+		for (i = 0; pDevViewInfo->pEntries[i].active; i++)
 		{
 			DestroyWindow(pDevViewInfo->pEntries[i].hwndStatic);
 			DestroyWindow(pDevViewInfo->pEntries[i].hwndEdit);
@@ -114,13 +116,14 @@
 
 	if (pDevViewInfo->pEntries)
 	{
-		for (i = 0; pDevViewInfo->pEntries[i].dev; i++)
+		for (i = 0; pDevViewInfo->pEntries[i].active; i++)
 		{
 			pszSelection = pDevViewInfo->pCallbacks->pfnGetSelectedSoftware(
 				hwndDevView,
 				pDevViewInfo->config->driver_index,
 				pDevViewInfo->config->mconfig,
 				pDevViewInfo->pEntries[i].dev,
+				pDevViewInfo->pEntries[i].image_cache_index,
 				szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
 
 			if (!pszSelection)
@@ -146,6 +149,7 @@
 			pDevViewInfo->config->driver_index,
 			pDevViewInfo->config->mconfig,
 			pDevViewInfo->pEntries[nChangedEntry].dev,
+			pDevViewInfo->pEntries[nChangedEntry].image_cache_index,
 			pszFilename);
 	}
 }
@@ -205,6 +209,9 @@
 
 	if (nDevCount > 0)
 	{
+		int id;
+		nDevCount += MAX_ICACHE;
+	
 		// get the names of all of the devices
 		ppszDevices = (LPTSTR *) alloca(nDevCount * sizeof(*ppszDevices));
 		i = 0;
@@ -219,20 +226,24 @@
 			free(s);
 			i++;
 		}
+		for (id = 0; id < MAX_ICACHE; id++)
+		{
+			s = (LPTSTR)image_cache_option_name(id);
+			ppszDevices[i] = alloca(strlen(s) + 1); //(_tcslen(s) + 1)* sizeof(TCHAR)
+			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)
@@ -249,6 +260,7 @@
 		{
 			image_device_info info = image_device_getinfo(pDevViewInfo->config->mconfig, dev);
 
+			pEnt->active = 1;
 			pEnt->dev = dev;
 
 			pEnt->hwndStatic = win_create_window_ex_utf8(0, "STATIC", info.name,
@@ -281,6 +293,46 @@
 			}
 
 			y += nHeight;
+			pEnt->image_cache_index = -1;
+			pEnt++;
+		}
+		y += nHeight/2;
+		for (id = 0; id < MAX_ICACHE; id++)
+		{
+			pEnt->active = 1;
+			pEnt->dev = NULL;
+			pEnt->image_cache_index = id;
+
+			pEnt->hwndStatic = win_create_window_ex_utf8(0, "STATIC", image_cache_option_name(id),
+				WS_VISIBLE | WS_CHILD, nStaticPos, y, nStaticWidth, nHeight,
+				hwndDevView, NULL, NULL, NULL);
+
+			pEnt->hwndEdit = win_create_window_ex_utf8(0, "EDIT", "",
+				WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, nEditPos, y, nEditWidth, nHeight,
+				hwndDevView, NULL, NULL, NULL);
+
+			pEnt->hwndBrowseButton = win_create_window_ex_utf8(0, "BUTTON", "...",
+				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++;
 		}
 	}
@@ -307,8 +359,8 @@
 	if (pDevViewInfo->pCallbacks->pfnGetOpenFileName)
 		AppendMenu(hMenu, MF_STRING, 1, TEXT("Mount..."));
 
-	info = image_device_getinfo(pDevViewInfo->config->mconfig, pEnt->dev);
-	if (info.creatable)
+	/* only have a create option if there is a device pointer and it's createble */
+	if (pEnt->dev && (info=image_device_getinfo(pDevViewInfo->config->mconfig, pEnt->dev)).creatable)
 	{
 		if (pDevViewInfo->pCallbacks->pfnGetCreateFileName)
 			AppendMenu(hMenu, MF_STRING, 2, TEXT("Create..."));
@@ -433,7 +486,7 @@
 			{
 				DevView_GetColumns(hwndDevView, &nStaticPos, &nStaticWidth,
 					&nEditPos, &nEditWidth, &nButtonPos, &nButtonWidth);
-				while(pEnt->dev)
+				while(pEnt->active)
 				{
 					GetClientRect(pEnt->hwndStatic, &r);
 					MapWindowPoints(pEnt->hwndStatic, hwndDevView, ((POINT *) &r), 2);
diff -Nru --strip-trailing-cr mames/src/mess/image.c.orig mames/src/mess/image.c
--- mames/src/mess/image.c.orig	2009-06-17 10:56:00.000000000 -0700
+++ mames/src/mess/image.c	2009-06-18 06:58:06.000000000 -0700
@@ -23,6 +23,21 @@
 #include "messopts.h"
 #include "ui.h"
 #include "zippath.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
+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},
+};
 
 
 
@@ -55,6 +70,7 @@
     /* variables that are only non-zero when an image is mounted */
     core_file *file;
     astring *name;
+	char *full_path;
     char *dir;
     char *hash;
     char *basename_noext;
@@ -261,6 +277,8 @@
 
     if (machine->images_data != NULL)
     {
+		int id;
+
         /* extract the options */
         mess_options_extract(machine);
 
@@ -284,6 +302,20 @@
         }
 
         machine->images_data = NULL;
+
+		/* 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(astring_c(swappable_image_cache[id].cached_name));
+				astring_free(swappable_image_cache[id].cached_name);
+				swappable_image_cache[id].cached = 0;
+				swappable_image_cache[id].cached_name = NULL;
+			}
+		}
     }
 }
 
@@ -780,7 +812,7 @@
     image_load_internal - core image loading
 -------------------------------------------------*/
 
-static int image_load_internal(const device_config *image, const char *path,
+static int image_load_internal(int level, const device_config *image, const char *orig_path,
     int is_create, int create_format, option_resolution *create_args)
 {
     running_machine *machine = image->machine;
@@ -789,10 +821,91 @@
     UINT32 open_plan[4];
     int i;
     image_slot_data *slot = find_image_slot(image);
+	const char *path;
+	swapped_image *cached=image_cache(orig_path);
 
     /* sanity checks */
     assert_always(image != NULL, "image_load(): image is NULL");
-    assert_always(path != NULL, "image_load(): path is NULL");
+	assert_always(orig_path != NULL, "image_load(): path is NULL");
+
+ 	if (level==0 && cached && (orig_path && *orig_path))
+ 	{
+ 		extern void queue_swapped_image_cache(char);
+		/* we are now loading */
+		slot->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], *tstr;
+			int pid = getpid(),digit=10000,hasDigit=0;
+ 			mame_file *outfile;
+			core_file *infile;
+			file_error filerr = FILERR_NONE;
+			 			
+ 			for (tstr=pidstr; digit; digit /= 10)
+ 			{
+ 				if (pid/digit)
+ 				{
+ 					hasDigit=1;
+ 				}
+ 				if (hasDigit)
+ 				{
+ 					*tstr++ = '0' + (pid/digit)%10;
+ 					pid -= (pid/digit)*digit;
+ 				}
+ 			}
+ 			*tstr++ = 0;
+
+			/* open the original image */
+			slot->err  = zippath_fopen(orig_path, OPEN_FLAG_READ, &infile, slot->name);
+
+			if (slot->err !=  FILERR_NONE)
+				goto done; // if we can't read the oringinal image path we're done
+
+			/* build pathname for image cache in current working directory.
+			 * must be a full or relative path or image loading or unlinking the file wont work.
+			 */
+			if (cached->cached_name)
+ 				astring_free(cached->cached_name);
+			cached->cached_name = astring_assemble_5(astring_alloc(), "./", pidstr, image_cache_option_briefname(cached->index),
+				".", osd_basename((char*)astring_c(slot->name)));
+
+			/* open the new image cache file to copy into */
+			filerr = mame_fopen(SEARCHPATH_IMAGE, astring_c(cached->cached_name), OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, &outfile);
+ 			if (filerr != FILERR_NONE || !outfile)
+ 			{
+				popmessage("%s: Could Not write image cache to filesystem, choose another current working dir.", astring_c(cached->cached_name));
+ 				if (outfile)
+	 				mame_fclose(outfile);
+				if (infile)
+					core_fclose(infile);
+				//image_unload(image);
+ 				slot->err = IMAGE_ERROR_FILENOTFOUND;
+ 				goto done;
+ 			}
+ 			while ( (bytes_read=core_fread(infile, tmpbuffer, sizeof(tmpbuffer))) )
+ 			{
+ 				mame_fwrite(outfile, tmpbuffer, bytes_read);
+ 			}
+			core_fclose(infile);
+ 			mame_fclose(outfile);
+			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 = astring_c(cached->cached_name);
+ 	}
+ 	else
+ 	{
+		/* we are now loading */
+		slot->is_loading = 1;
+
+ 		path = orig_path;
+ 	}
 
     /* first unload the image */
     image_unload(image);
@@ -878,7 +991,7 @@
 
 int image_load(const device_config *image, const char *path)
 {
-    return image_load_internal(image, path, FALSE, 0, NULL);
+	return image_load_internal(0, image, path, FALSE, 0, NULL);
 }
 
 
@@ -932,7 +1045,7 @@
 int image_create(const device_config *image, const char *path, const image_device_format *create_format, option_resolution *create_args)
 {
     int format_index = (create_format != NULL) ? create_format->index : 0;
-    return image_load_internal(image, path, TRUE, format_index, create_args);
+	return image_load_internal(0, image, path, TRUE, format_index, create_args);
 }
 
 
@@ -1891,3 +2004,51 @@
 {
     return machine->images_data->slots[absolute_index].dev;
 }
+/* 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/src/mess/image.h.orig mames/src/mess/image.h
--- mames/src/mess/image.h.orig	2009-06-17 10:56:00.000000000 -0700
+++ mames/src/mess/image.h	2009-06-17 11:18:02.000000000 -0700
@@ -320,7 +320,21 @@
 const device_config *image_from_absolute_index(running_machine *machine, int absolute_index);
 
 
-
+/* 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;
+	astring *cached_name;
+} swapped_image;
+swapped_image *image_cache(const char *filename);
+int image_cache_file_not_loaded_for_record(running_machine *machine, 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/filemngr.c.orig mames/src/mess/filemngr.c
--- mames/src/mess/filemngr.c.orig	2008-08-29 21:27:48.000000000 -0700
+++ mames/src/mess/filemngr.c	2008-08-29 23:16:26.000000000 -0700
@@ -826,7 +826,15 @@
 
 				case SELECTOR_ENTRY_TYPE_FILE:
 					/* file */
-					image_load(menustate->manager_menustate->selected_device, entry->fullpath);
+					if (entry->fullpath[0] && image_cache_file_not_loaded_for_record(machine,entry->fullpath))
+					{
+						popmessage("Image Load Failed: Image selected must be in an imagecache when recording");
+					}
+					else
+					{
+						image_load(menustate->manager_menustate->selected_device, entry->fullpath);
+					}
+					
 					ui_menu_stack_pop(machine);
 					break;
 			}
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;
--- sdlmess0129/src/lib/util/corefile.c.orig	2009-01-10 08:33:02.000000000 -0800
+++ sdlmess0129/src/lib/util/corefile.c	2009-01-10 09:09:44.000000000 -0800
@@ -328,6 +328,35 @@
     core_fseek - seek within a file
 -------------------------------------------------*/
 
+int _core_fseek(core_file *file, INT64 offset, int whence, int header)
+{
+	int err = 0;
+
+	/* error if compressing and not seeking in header */
+	if (!header && file->zdata != NULL)
+		return 1;
+
+	/* flush any buffered char */
+	file->back_char_head = 0;
+	file->back_char_tail = 0;
+
+	/* switch off the relative location */
+	switch (whence)
+	{
+		case SEEK_SET:
+			file->offset = offset;
+			break;
+
+		case SEEK_CUR:
+			file->offset += offset;
+			break;
+
+		case SEEK_END:
+			file->offset = file->length + offset;
+			break;
+	}
+	return err;
+}
 int core_fseek(core_file *file, INT64 offset, int whence)
 {
 	int err = 0;
@@ -359,6 +388,8 @@
 }
 
 
+
+
 /*-------------------------------------------------
     core_ftell - return the current file position
 -------------------------------------------------*/
--- sdlmess0129/src/lib/util/corefile.h.orig	2009-01-10 08:57:53.000000000 -0800
+++ sdlmess0129/src/lib/util/corefile.h	2009-01-10 09:08:13.000000000 -0800
@@ -69,6 +69,7 @@
 
 /* adjust the file pointer within the file */
 int core_fseek(core_file *file, INT64 offset, int whence);
+int _core_fseek(core_file *file, INT64 offset, int whence, int header);
 
 /* return the current file pointer */
 UINT64 core_ftell(core_file *file);
--- sdlmess0129/src/emu/fileio.c.orig	2009-01-10 08:37:52.000000000 -0800
+++ sdlmess0129/src/emu/fileio.c	2009-01-10 09:07:22.000000000 -0800
@@ -405,6 +405,18 @@
     mame_fseek - seek within a file
 -------------------------------------------------*/
 
+int _mame_fseek(mame_file *file, INT64 offset, int whence, int header)
+{
+	/* load the ZIP file now if we haven't yet */
+	if (file->zipfile != NULL)
+		load_zipped_file(file);
+
+	/* seek if we can */
+	if (file->file != NULL)
+		return _core_fseek(file->file, offset, whence, header);
+
+	return 1;
+}
 int mame_fseek(mame_file *file, INT64 offset, int whence)
 {
 	/* load the ZIP file now if we haven't yet */
@@ -419,6 +431,7 @@
 }
 
 
+
 /*-------------------------------------------------
     mame_ftell - return the current file position
 -------------------------------------------------*/
--- sdlmess0129/src/emu/fileio.h.orig	2009-01-10 08:38:00.000000000 -0800
+++ sdlmess0129/src/emu/fileio.h	2009-01-10 09:06:42.000000000 -0800
@@ -106,6 +106,7 @@
 /* ----- file positioning ----- */
 
 /* adjust the file pointer within the file */
+int _mame_fseek(mame_file *file, INT64 offset, int whence, int header);
 int mame_fseek(mame_file *file, INT64 offset, int whence);
 
 /* return the current file pointer */
diff -Nru --strip-trailing-cr mames.131/src/emu/ui.c mames/src/emu/ui.c
--- mames.131/src/emu/ui.c	2009-06-01 14:49:20.000000000 -0700
+++ mames/src/emu/ui.c	2009-06-01 14:58:31.000000000 -0700
@@ -1206,9 +1206,29 @@
 
 	/* handle a reset request */
 	if (ui_input_pressed(machine, IPT_UI_RESET_MACHINE))
-		mame_schedule_hard_reset(machine);
+	{
+		if (get_playback_file(machine) || get_record_file(machine))
+		{
+			if (get_playback_file(machine))
+				playback_end(machine, "USER TERMINATED PLAYBACK");
+			if (get_record_file(machine))
+				record_end(machine, "USER TERMINATED RECORD");
+		}
+		else
+			mame_schedule_hard_reset(machine);
+	}
 	if (ui_input_pressed(machine, IPT_UI_SOFT_RESET))
-		mame_schedule_soft_reset(machine);
+	{
+		if (get_playback_file(machine) || get_record_file(machine))
+		{
+			if (get_playback_file(machine))
+				playback_end(machine, "USER TERMINATED PLAYBACK");
+			if (get_record_file(machine))
+				record_end(machine, "USER TERMINATED RECORD");
+		}
+		else
+			mame_schedule_soft_reset(machine);
+	}
 
 	/* handle a request to display graphics/palette */
 	if (ui_input_pressed(machine, IPT_UI_SHOW_GFX) && !get_record_file(machine))
diff -Nru --strip-trailing-cr mames/src/emu/uimenu.c.orig mames/src/emu/uimenu.c
--- mames/src/emu/uimenu.c.orig	2009-02-14 09:10:12.000000000 -0800
+++ mames/src/emu/uimenu.c	2009-02-14 09:44:06.000000000 -0800
@@ -83,6 +83,7 @@
 enum
 {
 	VIDEO_ITEM_ROTATE = 0x80000000,
+	VIDEO_ITEM_THROTTLE,
 	VIDEO_ITEM_VIEW
 };
 
@@ -2926,6 +2927,14 @@
 	{
 		switch ((FPTR)event->itemref)
 		{
+			case VIDEO_ITEM_THROTTLE:
+				if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT)
+				{
+					video_set_throttle(!video_get_throttle());
+					changed = TRUE;
+				}
+				break;
+
 			/* rotate adds rotation depending on the direction */
 			case VIDEO_ITEM_ROTATE:
 				if (event->iptkey == IPT_UI_LEFT || event->iptkey == IPT_UI_RIGHT)
@@ -3026,6 +3035,10 @@
 	enabled = layermask & LAYER_CONFIG_ZOOM_TO_SCREEN;
 	ui_menu_item_append(menu, "View", enabled ? "Cropped" : "Full", enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)LAYER_CONFIG_ZOOM_TO_SCREEN);
 
+	/* throttling */
+	enabled = video_get_throttle();
+	ui_menu_item_append(menu, "Throttle", enabled ? "Normal" : "Fast", enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)VIDEO_ITEM_THROTTLE);
+
 	astring_free(tempstring);
 }
 

--- 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
--- 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 \
@@ -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/nec.h
 
 
@@ -1249,7 +1248,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 \
@@ -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 \
--- sdlmess0129/src/osd/sdl/sdl.mak.orig	2009-01-10 08:43:40.000000000 -0800
+++ sdlmess0129/src/osd/sdl/sdl.mak	2009-01-10 08:45:20.000000000 -0800
@@ -181,6 +181,12 @@
 
 OBJDIRS += $(SDLOBJ)
 
+ifdef PTR64
+SDL_LIBS = `sdl-config --libs`
+else
+SDL_LIBS = `sdl-config --libs|sed s/64//`
+endif
+
 SDLMAIN =
 
 #-------------------------------------------------
@@ -250,7 +256,7 @@
 
 ifndef SDL_INSTALL_ROOT
 CFLAGS += `sdl-config --cflags`
-LIBS += -lm `sdl-config --libs` $(LIBGL)
+LIBS += -lm $(SDL_LIBS) $(LIBGL)
 else
 CFLAGS += -I$(SDL_INSTALL_ROOT)/include
 #LIBS += -L/opt/intel/cce/9.1.051/lib  -limf -L$(SDL_INSTALL_ROOT)/lib -Wl,-rpath,$(SDL_INSTALL_ROOT)/lib -lSDL $(LIBGL)
@@ -322,7 +328,7 @@
 # causes a significant problem)
 CFLAGS += `sdl-config --cflags | sed 's:/SDL::'` -DNO_SDL_GLEXT
 # Remove libSDLmain, as its symbols conflict with SDLMain_tmpl.m
-LIBS += `sdl-config --libs | sed 's/-lSDLmain//'` -lpthread
+LIBS += `echo $(SDL_LIBS) | sed 's/-lSDLmain//'` -lpthread
 endif
 
 SDLMAIN = $(SDLOBJ)/SDLMain_tmpl.o
@@ -337,7 +343,7 @@
 OSDCOREOBJS += $(SDLOBJ)/debugwin.o
 
 CFLAGS += `sdl-config --cflags`
-LIBS += `sdl-config --libs`
+LIBS += $(SDL_LIBS)
 
 # to avoid name clash of '_brk'
 $(OBJ)/emu/cpu/h6280/6280dasm.o : CDEFS += -D__STRICT_ANSI__

