diff -Nru sdlmame0136\src\emu\cpu\cpu.mak sdlmame0136.pong\src\emu\cpu\cpu.mak
--- sdlmame0136\src\emu\cpu\cpu.mak	Thu Dec 31 22:20:49 2009
+++ sdlmame0136.pong\src\emu\cpu\cpu.mak	Sun Jan 10 13:52:40 2010
@@ -24,6 +24,21 @@
 
 
 #-------------------------------------------------
+# GENSYNC
+#-------------------------------------------------
+
+ifneq ($(filter GENSYNC,$(CPUS)),)
+OBJDIRS += $(CPUOBJ)/gensync
+CPUOBJS += $(CPUOBJ)/gensync/gensync.o
+DASMOBJS += $(CPUOBJ)/gensync/gensyncd.o
+$(CPUOBJ)/gensync/gensync.o:	$(CPUSRC)/gensync/gensync.c \
+								$(CPUSRC)/gensync/gensyncd.c \
+								$(CPUSRC)/gensync/gensync.h
+endif
+
+
+
+#-------------------------------------------------
 # Dynamic recompiler objects
 #-------------------------------------------------
 
diff -Nru sdlmame0136\src\emu\cpu\gensync\gensync.c sdlmame0136.pong\src\emu\cpu\gensync\gensync.c
--- sdlmame0136\src\emu\cpu\gensync\gensync.c	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\emu\cpu\gensync\gensync.c	Sun Jan 10 13:52:40 2010
@@ -0,0 +1,314 @@
+/*****************************************************************************
+ * Generic Video Synchronization CPU replacement for non-CPU games
+ * It does nothing but count horizontal and vertical synchronization,
+ * so a driver can use cpu_getscanline() and the provided registers to
+ * access the bits of generic horizontal and vertical counters.
+ * A driver defines it's video layout by specifying ten parameters:
+ * h_max			horizontal modulo value (including blanking/sync)
+ * v_max			vertical modulo value (including blanking/sync)
+ * hblank_start	start of horizontal blanking
+ * hsync_start		start of horizontal sync
+ * hsync_end		end of horizontal sync
+ * hblank_end		end of horizontal blanking
+ * vblank_start	start of vertical blanking
+ * vsync_start		start of vertical sync
+ * vsync_end		end of vertical sync
+ * vblank_end		end of vertical blanking
+ *****************************************************************************/
+
+#include "state.h"
+#include "debugger.h"
+#include "gensync.h"
+
+typedef struct
+{
+	int pc;
+	int h_max, v_max, size;
+	int hblank_start, hsync_start, hsync_end, hblank_end;
+	int vblank_start, vsync_start, vsync_end, vblank_end;
+	int icount;
+} GENSYNC;
+
+static CPU_RESET( gensync )
+{
+	GENSYNC* cpustate = (GENSYNC*)device->token;
+
+	cpustate->pc = 0;
+}
+
+/*
+ * Call this function with an ponter to an array of ten ints:
+ * The horizontal and vertical maximum values, the horizontal
+ * blanking start, sync start, sync end and blanking end followed
+ * by the vertical blanking start, sync start, sync end counter values.
+ * In your machine driver add a pointer to an array like:
+ *		int video[] = {454,262, 0,32,64,80, 0,4,8,16 };
+ * for the reset_param to the CPU_GENSYNC entry.
+ */
+static CPU_INIT( gensync )
+{
+	GENSYNC* cpustate		= (GENSYNC*)device->token;
+	const int* video		= device->static_config;
+
+	cpustate->h_max			= video[0];
+	cpustate->v_max			= video[1];
+	cpustate->size			= cpustate->h_max * cpustate->v_max;
+	cpustate->hblank_start	= video[2];
+	cpustate->hsync_start	= video[3];
+	cpustate->hsync_end		= video[4];
+	cpustate->hblank_end	= video[5];
+	cpustate->vblank_start	= video[6];
+	cpustate->vsync_start	= video[7];
+	cpustate->vsync_end		= video[8];
+	cpustate->vblank_end	= video[9];
+
+	state_save_register_device_item(device, 0, cpustate->pc);
+	state_save_register_device_item(device, 0, cpustate->h_max);
+	state_save_register_device_item(device, 0, cpustate->v_max);
+	state_save_register_device_item(device, 0, cpustate->size);
+	state_save_register_device_item(device, 0, cpustate->hblank_start);
+	state_save_register_device_item(device, 0, cpustate->hsync_start);
+	state_save_register_device_item(device, 0, cpustate->hsync_end);
+	state_save_register_device_item(device, 0, cpustate->hblank_end);
+	state_save_register_device_item(device, 0, cpustate->vblank_start);
+	state_save_register_device_item(device, 0, cpustate->vsync_start);
+	state_save_register_device_item(device, 0, cpustate->vsync_end);
+	state_save_register_device_item(device, 0, cpustate->vblank_end);
+}
+
+static CPU_EXIT( gensync )
+{
+}
+
+static CPU_EXECUTE( gensync )
+{
+	GENSYNC* cpustate = (GENSYNC*)device->token;
+
+	cpustate->icount = cycles;
+
+	do
+	{
+		debugger_instruction_hook(device, cpustate->pc);
+		if (++cpustate->pc == cpustate->size)
+			cpustate->pc = 0;
+	} while (--cpustate->icount > 0);
+
+	return cycles - cpustate->icount;
+}
+
+/* SU 078u2 */
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static CPU_SET_INFO( gensync )
+{
+	GENSYNC* cpustate = (GENSYNC*)device->token;
+
+	int h = cpustate->pc % cpustate->h_max;
+	int v = (cpustate->pc / cpustate->h_max) % cpustate->v_max;
+
+	switch (state)
+	{
+		/* --- the following bits of info are set as 64-bit signed integers --- */
+		case CPUINFO_INT_REGISTER + GS_PC:				cpustate->pc			= info->i % cpustate->size;							break;
+		case CPUINFO_INT_REGISTER + GS_H:				h						= info->i % cpustate->h_max;						break;
+		case CPUINFO_INT_REGISTER + GS_V:				v						= info->i % cpustate->v_max;						break;
+		case CPUINFO_INT_REGISTER + GS_HBLANK_START:	cpustate->hblank_start	= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_HSYNC_START:		cpustate->hsync_start	= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_HSYNC_END:		cpustate->hsync_end		= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_HBLANK_END:		cpustate->hblank_end	= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_VBLANK_START:	cpustate->vblank_start	= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_VSYNC_START:		cpustate->vsync_start	= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_VSYNC_END:		cpustate->vsync_end		= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_VBLANK_END:		cpustate->vblank_end	= info->i;											break;
+		case CPUINFO_INT_REGISTER + GS_1H:				h						= (h & ~0x001) | ((info->i & 1) << 0);				break;
+		case CPUINFO_INT_REGISTER + GS_2H:				h						= (h & ~0x002) | ((info->i & 1) << 1);				break;
+		case CPUINFO_INT_REGISTER + GS_4H:				h						= (h & ~0x004) | ((info->i & 1) << 2);				break;
+		case CPUINFO_INT_REGISTER + GS_8H:				h						= (h & ~0x008) | ((info->i & 1) << 3);				break;
+		case CPUINFO_INT_REGISTER + GS_16H:				h						= (h & ~0x010) | ((info->i & 1) << 4);				break;
+		case CPUINFO_INT_REGISTER + GS_32H:				h						= (h & ~0x020) | ((info->i & 1) << 5);				break;
+		case CPUINFO_INT_REGISTER + GS_64H:				h						= (h & ~0x040) | ((info->i & 1) << 6);				break;
+		case CPUINFO_INT_REGISTER + GS_128H:			h						= (h & ~0x080) | ((info->i & 1) << 7);				break;
+		case CPUINFO_INT_REGISTER + GS_256H:			h						= (h & ~0x100) | ((info->i & 1) << 8);				break;
+		case CPUINFO_INT_REGISTER + GS_512H:			h						= (h & ~0x200) | ((info->i & 1) << 9);				break;
+		case CPUINFO_INT_REGISTER + GS_1V:				v						= (v & ~0x001) | ((info->i & 1) << 0);				break;
+		case CPUINFO_INT_REGISTER + GS_2V:				v						= (v & ~0x002) | ((info->i & 1) << 1);				break;
+		case CPUINFO_INT_REGISTER + GS_4V:				v						= (v & ~0x004) | ((info->i & 1) << 2);				break;
+		case CPUINFO_INT_REGISTER + GS_8V:				v						= (v & ~0x008) | ((info->i & 1) << 3);				break;
+		case CPUINFO_INT_REGISTER + GS_16V:				v						= (v & ~0x010) | ((info->i & 1) << 4);				break;
+		case CPUINFO_INT_REGISTER + GS_32V:				v						= (v & ~0x020) | ((info->i & 1) << 5);				break;
+		case CPUINFO_INT_REGISTER + GS_64V:				v						= (v & ~0x040) | ((info->i & 1) << 6);				break;
+		case CPUINFO_INT_REGISTER + GS_128V:			v						= (v & ~0x080) | ((info->i & 1) << 7);				break;
+		case CPUINFO_INT_REGISTER + GS_256V:			v						= (v & ~0x100) | ((info->i & 1) << 8);				break;
+		case CPUINFO_INT_REGISTER + GS_512V:			v						= (v & ~0x200) | ((info->i & 1) << 9);				break;
+
+		case CPUINFO_INT_PC:							cpustate->pc			= info->i % (cpustate->h_max * cpustate->v_max);	break;
+		case CPUINFO_INT_SP:							;																			break;
+
+		/* --- the following bits of info are set as pointers to data or functions --- */
+	}
+
+	cpustate->pc = v * cpustate->h_max + h;
+}
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+CPU_GET_INFO( gensync )
+{
+	GENSYNC* cpustate = (NULL != device) ? (GENSYNC*)device->token : NULL;
+	int h, v;
+
+	if (NULL == cpustate)
+	{
+		h = v = 0;
+	}
+	else if (cpustate->h_max > 0)
+	{
+		h = cpustate->pc % cpustate->h_max;
+		v = (cpustate->pc / cpustate->h_max) % cpustate->v_max;
+	}
+	else /* Machine has not been reset yet so we fill in hardcoded values */
+	{
+		h = cpustate->pc % 454;
+		v = (cpustate->pc / 454) % 261;
+	}
+
+	switch (state)
+	{
+		/* --- the following bits of info are returned as 64-bit signed integers --- */
+		case CPUINFO_INT_CONTEXT_SIZE:							info->i = sizeof(GENSYNC);													break;
+		case CPUINFO_INT_INPUT_LINES:							info->i = 0;																break;
+		case CPUINFO_INT_DEFAULT_IRQ_VECTOR:					info->i = 0;																break;
+		case DEVINFO_INT_ENDIANNESS:							info->i = ENDIANNESS_LITTLE;												break;
+		case CPUINFO_INT_CLOCK_MULTIPLIER:						info->i = 1;																break;
+		case CPUINFO_INT_CLOCK_DIVIDER:							info->i = 1;																break;
+		case CPUINFO_INT_MIN_INSTRUCTION_BYTES:					info->i = 1;																break;
+		case CPUINFO_INT_MAX_INSTRUCTION_BYTES:					info->i = 1;																break;
+		case CPUINFO_INT_MIN_CYCLES:							info->i = 1;																break;
+		case CPUINFO_INT_MAX_CYCLES:							info->i = 1;																break;
+
+		case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:	info->i = 16;																break;
+		case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM:	info->i = 16;																break;
+		case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM:	info->i = 0;																break;
+		case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA:	info->i = 0;																break;
+		case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA:	info->i = 0;																break;
+		case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA:	info->i = 0;																break;
+		case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO:		info->i = 0;																break;
+		case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO:		info->i = 0;																break;
+		case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO:		info->i = 0;																break;
+
+		case CPUINFO_INT_PREVIOUSPC:							info->i = 0; /* not implemented */											break;
+		case CPUINFO_INT_PC:									info->i = cpustate->pc;														break;
+		case CPUINFO_INT_SP:									info->i = 0;																break;
+
+		case CPUINFO_INT_REGISTER + GS_H:						info->i = h;																break;
+		case CPUINFO_INT_REGISTER + GS_V:						info->i = v;																break;
+		case CPUINFO_INT_REGISTER + GS_MAX_H:					info->i = cpustate->h_max;													break;
+		case CPUINFO_INT_REGISTER + GS_MAX_V:					info->i = cpustate->v_max;													break;
+		case CPUINFO_INT_REGISTER + GS_X:						info->i = cpustate->hblank_start < cpustate->hblank_end ?
+																			(( h >= cpustate->hblank_start && h < cpustate->hblank_end )?
+																			  -1 : h - cpustate->hblank_end):
+																			(( h >= cpustate->hblank_start || h < cpustate->hblank_end )?
+																			  -1 : h - cpustate->hblank_start);								break;
+		case CPUINFO_INT_REGISTER + GS_Y:						info->i = cpustate->vblank_start < cpustate->vblank_end ?
+																			(( v >= cpustate->vblank_start && v < cpustate->vblank_end )?
+																			  -1 : v - cpustate->vblank_end):
+																			(( v >= cpustate->vblank_start || v < cpustate->vblank_end )?
+																			  -1 : v - cpustate->hblank_start);								break;
+		case CPUINFO_INT_REGISTER + GS_HBLANK_START:			info->i = cpustate->hblank_start;											break;
+		case CPUINFO_INT_REGISTER + GS_HSYNC_START:				info->i = cpustate->hsync_start;											break;
+		case CPUINFO_INT_REGISTER + GS_HSYNC_END:				info->i = cpustate->hsync_end;												break;
+		case CPUINFO_INT_REGISTER + GS_HBLANK_END:				info->i = cpustate->hblank_end;												break;
+		case CPUINFO_INT_REGISTER + GS_VBLANK_START:			info->i = cpustate->vblank_start;											break;
+		case CPUINFO_INT_REGISTER + GS_VSYNC_START:				info->i = cpustate->vsync_start;											break;
+		case CPUINFO_INT_REGISTER + GS_VSYNC_END:				info->i = cpustate->vsync_end;												break;
+		case CPUINFO_INT_REGISTER + GS_VBLANK_END:				info->i = cpustate->vblank_end;												break;
+		case CPUINFO_INT_REGISTER + GS_HBLANK:					info->i = cpustate->hblank_start < cpustate->hblank_end ?
+																			  h >= cpustate->hblank_start && h < cpustate->hblank_end:
+																			  h >= cpustate->hblank_start || h < cpustate->hblank_end;		break;
+		case CPUINFO_INT_REGISTER + GS_HSYNC:					info->i = cpustate->hsync_start < cpustate->hsync_end ?
+																			  h >= cpustate->hsync_start && h < cpustate->hsync_end:
+																			  h >= cpustate->hsync_start || h < cpustate->hsync_end;		break;
+		case CPUINFO_INT_REGISTER + GS_VBLANK:					info->i = cpustate->vblank_start < cpustate->vblank_end ?
+																			  v >= cpustate->vblank_start && v < cpustate->vblank_end:
+																			  v >= cpustate->vblank_start || v < cpustate->vblank_end;		break;
+		case CPUINFO_INT_REGISTER + GS_VSYNC:					info->i = cpustate->vsync_start < cpustate->vsync_end ?
+																			  v >= cpustate->vsync_start && v < cpustate->vsync_end:
+																			  v >= cpustate->vsync_start || v < cpustate->vsync_end;		break;
+		case CPUINFO_INT_REGISTER + GS_1H:						info->i = (h >> 0) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_2H:						info->i = (h >> 1) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_4H:						info->i = (h >> 2) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_8H:						info->i = (h >> 3) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_16H:						info->i = (h >> 4) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_32H:						info->i = (h >> 5) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_64H:						info->i = (h >> 6) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_128H:					info->i = (h >> 7) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_256H:					info->i = (h >> 8) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_512H:					info->i = (h >> 9) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_1V:						info->i = (v >> 0) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_2V:						info->i = (v >> 1) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_4V:						info->i = (v >> 2) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_8V:						info->i = (v >> 3) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_16V:						info->i = (v >> 4) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_32V:						info->i = (v >> 5) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_64V:						info->i = (v >> 6) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_128V:					info->i = (v >> 7) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_256V:					info->i = (v >> 8) & 1;														break;
+		case CPUINFO_INT_REGISTER + GS_512V:					info->i = (v >> 9) & 1;														break;
+
+		/* --- the following bits of info are returned as pointers to data or functions --- */
+		case CPUINFO_FCT_SET_INFO:								info->setinfo = CPU_SET_INFO_NAME(gensync);									break;
+		case CPUINFO_FCT_INIT:									info->init = CPU_INIT_NAME(gensync);										break;
+		case CPUINFO_FCT_RESET:									info->reset = CPU_RESET_NAME(gensync);										break;
+		case CPUINFO_FCT_EXIT:									info->exit = CPU_EXIT_NAME(gensync);										break;
+		case CPUINFO_FCT_EXECUTE:								info->execute = CPU_EXECUTE_NAME(gensync);									break;
+		case CPUINFO_FCT_BURN:									info->burn = NULL;															break;
+		case CPUINFO_FCT_DISASSEMBLE:							info->disassemble = CPU_DISASSEMBLE_NAME(gensync);							break;
+		case CPUINFO_PTR_INSTRUCTION_COUNTER:					info->icount = &cpustate->icount;											break;
+
+		/* --- the following bits of info are returned as NULL-terminated strings --- */
+		case DEVINFO_STR_NAME:									strcpy(info->s, "GENSYNC");													break;
+		case DEVINFO_STR_FAMILY:								strcpy(info->s, "GENSYNC generic video synchronization");					break;
+		case DEVINFO_STR_VERSION:								strcpy(info->s, "0.2");														break;
+		case DEVINFO_STR_SOURCE_FILE:							strcpy(info->s, __FILE__);													break;
+		case DEVINFO_STR_CREDITS:								strcpy(info->s, "Copyright The MAMEDEV team.");								break;
+
+		case CPUINFO_STR_FLAGS:									sprintf(info->s, "%4d:%4d", v, h);											break;
+
+		case CPUINFO_STR_REGISTER + GS_PC:						sprintf(info->s, "PC:%03X:%03X", h, v);										break;
+		case CPUINFO_STR_REGISTER + GS_HBLANK_START:			sprintf(info->s, "HBS:%03X", cpustate->hblank_start);						break;
+		case CPUINFO_STR_REGISTER + GS_HSYNC_START:				sprintf(info->s, "HSS:%03X", cpustate->hsync_start);						break;
+		case CPUINFO_STR_REGISTER + GS_HSYNC_END:				sprintf(info->s, "HSE:%03X", cpustate->hsync_end);							break;
+		case CPUINFO_STR_REGISTER + GS_HBLANK_END:				sprintf(info->s, "HBE:%03X", cpustate->hblank_end);							break;
+		case CPUINFO_STR_REGISTER + GS_VBLANK_START:			sprintf(info->s, "VBS:%03X", cpustate->vblank_start);						break;
+		case CPUINFO_STR_REGISTER + GS_VSYNC_START:				sprintf(info->s, "VSS:%03X", cpustate->vsync_start);						break;
+		case CPUINFO_STR_REGISTER + GS_VSYNC_END:				sprintf(info->s, "VSE:%03X", cpustate->vsync_end);							break;
+		case CPUINFO_STR_REGISTER + GS_VBLANK_END:				sprintf(info->s, "VBE:%03X", cpustate->vblank_end);							break;
+		case CPUINFO_STR_REGISTER + GS_1H:						sprintf(info->s, "1H:%X", (h >> 0) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_2H:						sprintf(info->s, "2H:%X", (h >> 1) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_4H:						sprintf(info->s, "4H:%X", (h >> 2) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_8H:						sprintf(info->s, "8H:%X", (h >> 3) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_16H:						sprintf(info->s, "16H:%X", (h >> 4) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_32H:						sprintf(info->s, "32H:%X", (h >> 5) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_64H:						sprintf(info->s, "64H:%X", (h >> 6) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_128H:					sprintf(info->s, "128H:%X", (h >> 7) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_256H:					sprintf(info->s, "256H:%X", (h >> 8) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_512H:					sprintf(info->s, "512H:%X", (h >> 9) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_1V:						sprintf(info->s, "1V:%X", (v >> 0) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_2V:						sprintf(info->s, "2V:%X", (v >> 1) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_4V:						sprintf(info->s, "4V:%X", (v >> 2) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_8V:						sprintf(info->s, "8V:%X", (v >> 3) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_16V:						sprintf(info->s, "16V:%X", (v >> 4) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_32V:						sprintf(info->s, "32V:%X", (v >> 5) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_64V:						sprintf(info->s, "64V:%X", (v >> 6) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_128V:					sprintf(info->s, "128V:%X", (v >> 7) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_256V:					sprintf(info->s, "256V:%X", (v >> 8) & 1);									break;
+		case CPUINFO_STR_REGISTER + GS_512V:					sprintf(info->s,  "512V:%X", (v >> 9) & 1);									break;
+	}
+}
+/* SU 078u2 */
diff -Nru sdlmame0136\src\emu\cpu\gensync\gensync.h sdlmame0136.pong\src\emu\cpu\gensync\gensync.h
--- sdlmame0136\src\emu\cpu\gensync\gensync.h	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\emu\cpu\gensync\gensync.h	Sun Jan 10 13:52:40 2010
@@ -0,0 +1,26 @@
+#ifndef _GENSYNC_H
+#define _GENSYNC_H
+
+#include "cpuintrf.h"
+
+enum
+{
+	GS_PC, GS_H, GS_V, GS_MAX_H, GS_MAX_V, GS_X, GS_Y,
+	GS_HBLANK, GS_HSYNC, GS_VBLANK, GS_VSYNC,
+	GS_HBLANK_START, GS_HSYNC_START, GS_HSYNC_END, GS_HBLANK_END,
+	GS_VBLANK_START, GS_VSYNC_START, GS_VSYNC_END, GS_VBLANK_END,
+	GS_1H, GS_2H, GS_4H, GS_8H,
+	GS_16H, GS_32H, GS_64H, GS_128H,
+	GS_256H, GS_512H,
+	GS_1V, GS_2V, GS_4V, GS_8V,
+	GS_16V, GS_32V, GS_64V, GS_128V,
+	GS_256V, GS_512V
+};
+
+CPU_GET_INFO( gensync );
+#define CPU_GENSYNC CPU_GET_INFO_NAME( gensync )
+
+CPU_DISASSEMBLE( gensync );
+
+#endif	/* _GENSYNC_H */
+
diff -Nru sdlmame0136\src\emu\cpu\gensync\gensyncd.c sdlmame0136.pong\src\emu\cpu\gensync\gensyncd.c
--- sdlmame0136\src\emu\cpu\gensync\gensyncd.c	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\emu\cpu\gensync\gensyncd.c	Sun Jan 10 13:52:40 2010
@@ -0,0 +1,31 @@
+#include <string.h>
+#include "gensync.h"
+
+CPU_DISASSEMBLE( gensync )
+{
+	int hblank = cpu_get_reg(device, GS_HBLANK);
+	int hsync = cpu_get_reg(device, GS_HSYNC);
+	int vblank = cpu_get_reg(device, GS_VBLANK);
+	int vsync = cpu_get_reg(device, GS_VSYNC);
+
+	if (hblank)
+	{
+		buffer += sprintf(buffer, " HB");
+		if (hsync)
+			buffer += sprintf(buffer, " HS");
+	}
+	else
+		buffer += sprintf(buffer, " X:%03X", (UINT32)cpu_get_reg(device, GS_X));	/* SU 078u2 */
+
+	if (vblank)
+	{
+		buffer += sprintf(buffer, " VB");
+		if (vsync)
+			buffer += sprintf(buffer, " VS");
+	}
+	else
+		buffer += sprintf(buffer, " Y:%03X", (UINT32)cpu_get_reg(device, GS_Y));	/* SU 078u2 */
+
+	return 1 | DASMFLAG_SUPPORTED;
+}
+
diff -Nru sdlmame0136\src\emu\romload.c sdlmame0136.pong\src\emu\romload.c
--- sdlmame0136\src\emu\romload.c	Thu Dec 31 22:20:49 2009
+++ sdlmame0136.pong\src\emu\romload.c	Sun Jan 10 13:52:40 2010
@@ -343,27 +343,30 @@
 
 	romdata->system_bios = 0;
 
-	/* first determine the default BIOS name */
-	for (rom = romdata->machine->gamedrv->rom; !ROMENTRY_ISEND(rom); rom++)
-		if (ROMENTRY_ISDEFAULT_BIOS(rom))
-			defaultname = ROM_GETNAME(rom);
+	if (romdata->machine->gamedrv->rom != NULL)
+	{
+		/* first determine the default BIOS name */
+		for (rom = romdata->machine->gamedrv->rom; !ROMENTRY_ISEND(rom); rom++)
+			if (ROMENTRY_ISDEFAULT_BIOS(rom))
+				defaultname = ROM_GETNAME(rom);
 
-	/* look for a BIOS with a matching name */
-	for (rom = romdata->machine->gamedrv->rom; !ROMENTRY_ISEND(rom); rom++)
-		if (ROMENTRY_ISSYSTEM_BIOS(rom))
-		{
-			const char *biosname = ROM_GETNAME(rom);
-			int bios_flags = ROM_GETBIOSFLAGS(rom);
-			char bios_number[20];
+		/* look for a BIOS with a matching name */
+		for (rom = romdata->machine->gamedrv->rom; !ROMENTRY_ISEND(rom); rom++)
+			if (ROMENTRY_ISSYSTEM_BIOS(rom))
+			{
+				const char *biosname = ROM_GETNAME(rom);
+				int bios_flags = ROM_GETBIOSFLAGS(rom);
+				char bios_number[20];
 
-			/* Allow '-bios n' to still be used */
-			sprintf(bios_number, "%d", bios_flags - 1);
-			if (strcmp(bios_number, specbios) == 0 || strcmp(biosname, specbios) == 0)
-				romdata->system_bios = bios_flags;
-			if (defaultname != NULL && strcmp(biosname, defaultname) == 0)
-				default_no = bios_flags;
-			bios_count++;
-		}
+				/* Allow '-bios n' to still be used */
+				sprintf(bios_number, "%d", bios_flags - 1);
+				if (strcmp(bios_number, specbios) == 0 || strcmp(biosname, specbios) == 0)
+					romdata->system_bios = bios_flags;
+				if (defaultname != NULL && strcmp(biosname, defaultname) == 0)
+					default_no = bios_flags;
+				bios_count++;
+			}
+	}
 
 	/* if none found, use the default */
 	if (romdata->system_bios == 0 && bios_count > 0)
diff -Nru sdlmame0136\src\mame\audio\pong.c sdlmame0136.pong\src\mame\audio\pong.c
--- sdlmame0136\src\mame\audio\pong.c	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\mame\audio\pong.c	Sun Jan 10 18:54:09 2010
@@ -0,0 +1,59 @@
+/***************************************************************************
+	pong.c
+	Sound handler
+
+	J. Buchmueller, November '99
+****************************************************************************/
+
+#include "driver.h"
+#include "includes/pong.h"
+#include "sound/samples.h"
+
+/* HJB 99/11/22 corrected HIT_CLOCK and VBLANK_CLOCK */
+#define HIT_CLOCK		(PONG_MAX_V-PONG_VBLANK) * PONG_FPS / 16 / 2
+#define VBLANK_CLOCK	(PONG_MAX_V-PONG_VBLANK) * PONG_FPS / 16 / 4
+#define SCORE_CLOCK 	PONG_MAX_V * PONG_FPS / 32
+
+#define CHANNEL_HIT	0
+#define CHANNEL_VBLANK	1
+#define CHANNEL_SCORE	2
+
+static	INT16 waveform[4] = { -120, -120, 120, 120 };
+
+int pong_hit_sound = 0;
+int pong_vblank_sound = 0;
+int pong_score_sound = 0;
+
+/************************************/
+/* Sound handler start				*/
+/************************************/
+static TIMER_CALLBACK( pong_sh_update )
+{
+	const device_config *samples = devtag_get_device(machine, "samples");
+
+	sample_set_volume(samples, CHANNEL_HIT, pong_hit_sound ? 100.0 : 0.0);
+	sample_set_volume(samples, CHANNEL_VBLANK, pong_vblank_sound ? 100.0 : 0.0);
+	sample_set_volume(samples, CHANNEL_SCORE, pong_score_sound ? 100.0 : 0.0);
+}
+
+static SAMPLES_START( pong_sh_start )
+{
+	const device_config *samples = devtag_get_device(device->machine, "samples");
+
+	sample_start_raw(samples, CHANNEL_HIT, waveform, sizeof(waveform), sizeof(waveform)*HIT_CLOCK, 1);
+	sample_start_raw(samples, CHANNEL_VBLANK, waveform, sizeof(waveform), sizeof(waveform)*VBLANK_CLOCK, 1);
+	sample_start_raw(samples, CHANNEL_SCORE, waveform, sizeof(waveform), sizeof(waveform)*SCORE_CLOCK, 1);
+
+	sample_set_volume(samples, CHANNEL_HIT, 0.0);
+	sample_set_volume(samples, CHANNEL_VBLANK, 0.0);
+	sample_set_volume(samples, CHANNEL_SCORE, 0.0);
+
+	timer_pulse(device->machine, video_screen_get_frame_period(device->machine->primary_screen), NULL, 0, pong_sh_update);
+}
+
+samples_interface pong_samples_interface =
+{
+	3,
+	NULL,
+	pong_sh_start
+};
diff -Nru sdlmame0136\src\mame\drivers\pong.c sdlmame0136.pong\src\mame\drivers\pong.c
--- sdlmame0136\src\mame\drivers\pong.c	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\mame\drivers\pong.c	Sun Jan 10 18:54:22 2010
@@ -0,0 +1,103 @@
+/***************************************************************************
+	pong.c
+	Machine driver
+
+	J. Buchmueller, November '99
+***************************************************************************/
+
+#include "driver.h"
+#include "cpu/gensync/gensync.h"
+#include "sound/samples.h"
+#include "sndintrf.h"
+#include "includes/pong.h"
+#include "deprecat.h"
+
+extern struct SamplesSound_interface pong_samples_interface;
+
+static INPUT_PORTS_START( pong )
+	PORT_START("IN0") // buttons
+	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
+	PORT_DIPNAME( 0x02, 0x00, "Ending Score" )
+	PORT_DIPSETTING(    0x00, "11" )
+	PORT_DIPSETTING(    0x02, "15" )
+	PORT_BIT( 0xfc, IP_ACTIVE_LOW,	IPT_UNUSED )
+
+	PORT_START("IN1") // control 1
+	PORT_BIT( 0x1ff, (PONG_MAX_V-15)/2, IPT_AD_STICK_Y ) PORT_MINMAX(PONG_VBLANK - 12, 255) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_PLAYER(1)
+
+	PORT_START("IN2") // control 2
+	PORT_BIT( 0x1ff, (PONG_MAX_V-15)/2, IPT_AD_STICK_Y ) PORT_MINMAX(PONG_VBLANK - 12, 255) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_PLAYER(2)
+INPUT_PORTS_END
+
+
+static unsigned short colortable_source[] =
+{
+	0,1,
+	1,0,
+	2,0,
+};
+
+#define PONG_CLOCK	PONG_FPS * PONG_MAX_V * PONG_MAX_H + 49410   /* Pong uses a standard US TV crystal with 14,318,100 Hz */
+
+static int pong_video[] = {
+	PONG_MAX_H, PONG_MAX_V,
+	0, PONG_HSYNC0, PONG_HSYNC1, PONG_HBLANK,
+	0, PONG_VSYNC0, PONG_VSYNC1, PONG_VBLANK
+};
+
+static PALETTE_INIT( pong )
+{
+	int i;
+
+	for (i = 0; i < sizeof(colortable_source) / sizeof(colortable_source[0]); i++)
+	{
+		rgb_t color;
+
+		switch (colortable_source[i])
+		{
+		case 0:   color = RGB_BLACK; break;						/* black */
+		case 1:   color = RGB_WHITE; break;						/* white (1k resistor) */
+		default:  color = MAKE_RGB(0xd4, 0xd4, 0xd4); break;	/* slightly darker white (1.2k resistor) */
+		}
+
+		palette_set_color(machine, i, color);
+	}
+}
+
+static MACHINE_DRIVER_START( pong )
+
+	/* basic machine hardware */
+	MDRV_CPU_ADD("maincpu", GENSYNC, PONG_CLOCK)
+	MDRV_CPU_CONFIG(pong_video)
+	MDRV_CPU_VBLANK_INT_HACK(pong_vh_scanline, PONG_MAX_V)
+
+	/* video hardware */
+	MDRV_SCREEN_ADD("screen", RASTER)
+	MDRV_SCREEN_REFRESH_RATE(PONG_FPS)
+	MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))  /* frames per second, vblank duration */
+	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
+	MDRV_SCREEN_SIZE(PONG_MAX_H, PONG_MAX_V)
+	MDRV_SCREEN_VISIBLE_AREA(PONG_HBLANK, PONG_MAX_H-1, PONG_VBLANK, PONG_MAX_V-1)
+	MDRV_PALETTE_LENGTH(sizeof(colortable_source)/sizeof(colortable_source[0]))
+
+	MDRV_PALETTE_INIT(pong)
+	MDRV_VIDEO_START(pong)
+	MDRV_VIDEO_UPDATE(pong)
+
+	/* sound hardware */
+	MDRV_SPEAKER_STANDARD_MONO("mono")
+
+	MDRV_SOUND_ADD("samples", SAMPLES, 0)
+	MDRV_SOUND_CONFIG(pong_samples_interface)
+	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.20)
+MACHINE_DRIVER_END
+
+/***************************************************************************
+
+  Game driver(s)
+
+***************************************************************************/
+
+#define rom_pong 0	/* this game has no ROMs */
+
+GAME( 1972, pong, 0, pong, pong, 0, ROT0, "Atari", "Pong", 0 )
diff -Nru sdlmame0136\src\mame\includes\pong.h sdlmame0136.pong\src\mame\includes\pong.h
--- sdlmame0136\src\mame\includes\pong.h	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\mame\includes\pong.h	Sun Jan 10 13:52:40 2010
@@ -0,0 +1,17 @@
+/* The video synchronization layout, derived from the schematics */
+#define PONG_MAX_H	(256+128+64+4+2)
+#define PONG_MAX_V	(256+4+1)
+#define PONG_HBLANK (64+16)
+#define PONG_VBLANK 16
+#define PONG_HSYNC0 32
+#define PONG_HSYNC1 64
+#define PONG_VSYNC0 4
+#define PONG_VSYNC1 8
+#define PONG_FPS	60
+
+VIDEO_START( pong );
+VIDEO_UPDATE( pong );
+INTERRUPT_GEN( pong_vh_scanline );
+VIDEO_EOF( pong );
+
+
diff -Nru sdlmame0136\src\mame\mame.mak sdlmame0136.pong\src\mame\mame.mak
--- sdlmame0136\src\mame\mame.mak	Thu Dec 31 22:20:48 2009
+++ sdlmame0136.pong\src\mame\mame.mak	Sun Jan 10 13:52:40 2010
@@ -34,6 +34,7 @@
 # updated with any MAME core changes
 #-------------------------------------------------
 
+CPUS+=GENSYNC
 CPUS += Z80
 CPUS += Z180
 CPUS += I8085
@@ -1646,6 +1647,7 @@
 	$(DRIVERS)/vroulet.o \
 	$(DRIVERS)/wldarrow.o \
 	$(DRIVERS)/xyonix.o $(VIDEO)/xyonix.o \
+	$(DRIVERS)/pong.o $(VIDEO)/pong.o $(AUDIO)/pong.o \
 
 #-------------------------------------------------
 # layout dependencies
diff -Nru sdlmame0136\src\mame\mamedriv.c sdlmame0136.pong\src\mame\mamedriv.c
--- sdlmame0136\src\mame\mamedriv.c	Thu Dec 31 22:20:48 2009
+++ sdlmame0136.pong\src\mame\mamedriv.c	Sun Jan 10 13:52:40 2010
@@ -9952,4 +9952,6 @@
 	DRIVER( am_mg24 )	/* (c) Amatic 2000 */
 	DRIVER( am_mg3 )	/* (c) Amatic 2000 */
 
+	DRIVER( pong )		/* (c) 1972 Atari */
+
 #endif	/* DRIVER_RECURSIVE */
diff -Nru sdlmame0136\src\mame\video\pong.c sdlmame0136.pong\src\mame\video\pong.c
--- sdlmame0136\src\mame\video\pong.c	Wed Dec 31 16:00:00 1969
+++ sdlmame0136.pong\src\mame\video\pong.c	Sun Jan 10 18:54:35 2010
@@ -0,0 +1,892 @@
+/**************************************************************************
+	pong.c
+	Video handler
+
+	J. Buchmueller, November '99
+****************************************************************************/
+
+#include "driver.h"
+#include "cpu/gensync/gensync.h"
+#include "ui.h"
+#include "includes/pong.h"
+
+extern int pong_hit_sound;
+extern int pong_vblank_sound;
+extern int pong_score_sound;
+
+static int V;
+static int VRESET;
+
+static int ATRACT;
+static int STOP_G;
+
+static int vpad1_timer;			   /* NE555/B9 */
+static int vpad1_count;			   /* 7493/B8 */
+#define VPAD1 (vpad1_count < 15)
+static int score1;				   /* 7490/C7 + 74107/C8.1 */
+
+static int vpad2_timer;			   /* NE555/A9 */
+static int vpad2_count;			   /* 7493/A8 */
+#define VPAD2 (vpad2_count < 15)
+static int score2;				   /* 7490/D7 + 74107/C8.2 */
+
+static int speed;				   /* 7493/F1 */
+static int speed_q1;			   /* 74107/H2.2*/
+static int speed_q2;			   /* 74107/H2.1 */
+
+
+static int hpos_a;				   /* 9316/G7 */
+static int hpos_b;				   /* 9316/H7 */
+static int hpos_c;				   /* 74107/G6.2 */
+static int HVID;				   /* 7420/H6.2 */
+
+static int vpos_a;				   /* 9316/B3 */
+static int vpos_b;				   /* 9316/A3 */
+static int VVID;				   /* 7402/D2.4 */
+
+static int vvel_b;				   /* 7474/A5.2 */
+static int vvel_c;				   /* 7474/A5.1 */
+static int vvel_d;				   /* 7474/B5.1 */
+static int hit_vbl_q;			   /* 74107/A2.1 */
+static int hit_vbl_0;			   /* direction during last frame (previous state of 74107/A2.1) */
+
+static int v_velocity;			   /* 7483/B4 */
+
+static int score_q;				   /* 74107/H3.2 */
+#define L	(score_q == 1)
+#define R	(score_q == 0)
+
+static int hit_a;				   /* 7400/H4.3 */
+static int hit_b;				   /* 7400/H4.2 */
+
+static int hit_vblank;			   /* 74107/F3.1 */
+
+static int hit_sound;			   /* 7474/C2.1 */
+
+static int score_sound_timer;	   /* NE555/G4 */		/* SU 059 */
+static int serve_timer;			   /* NE555/F4 */		/* SU 059 */
+
+#ifdef MAME_DEBUG
+static int hpos;				   /* debug */
+static int vpos;				   /* debug */
+static int hpos_h;				   /* debug */
+static int vpos_h;				   /* debug */
+#endif
+
+INLINE void pong_hit_detector(running_machine *machine);
+INLINE void pong_vertical_velocity(running_machine *machine);
+INLINE void pong_7seg(running_machine *machine, int H0, int n);
+
+/* SU 059 */
+static TIMER_CALLBACK( score_timer_cb )
+{
+	score_sound_timer = 0;
+	/* disable score sound */
+	pong_score_sound = 0;
+}
+
+static TIMER_CALLBACK( serve_timer_cb )
+{
+	serve_timer = 0;
+	/* falling edge of serve timer (output of NE555/F4) */
+	hpos_a = 0;
+	hpos_b = 0;
+	hpos_c = 0;
+}
+/* SU 059 */
+
+VIDEO_START( pong )
+{
+	ATRACT = 0;
+	STOP_G = 1;
+
+	vpad1_timer = 0;
+	vpad1_count = 0;
+	score1 = 0;
+
+	vpad2_timer = 0;
+	vpad2_count = 0;
+	score2 = 0;
+
+	speed = 0;
+	speed_q1 = 0;
+	speed_q2 = 0;
+
+	score_q = 0;
+
+	hpos_a = 0;
+	hpos_b = 0;
+	hpos_c = 0;
+
+	vpos_a = 0;
+	vpos_b = 0;
+
+	vvel_b = 0;
+	vvel_c = 0;
+	vvel_d = 0;
+	hit_vbl_q = 0;
+
+	v_velocity = 0;
+
+	hit_a = 0;
+	hit_b = 1;
+
+	hit_sound = 0;
+
+	score_sound_timer = 0;	  /* SU 059 */
+	serve_timer = 0;		  /* SU 059 */
+
+	pong_hit_detector( machine );
+
+	video_start_generic_bitmapped( machine );
+}
+
+VIDEO_UPDATE( pong )
+{
+	const rectangle *clip = video_screen_get_visible_area(screen);
+
+#ifdef MAME_DEBUG
+	popmessage(
+		"vvel: %2d\n"
+		"hpos: %3d\n"
+		"vpos: %3d\n"
+		"Aa/Ba: %d/%d\n"
+		"hpos_h: %3d\n"
+		"vpos_h: %3d\n"
+		"speed: %2d %d/%d->%d\n"
+		"L/R: %d/%d\n" ,
+		v_velocity ,
+		hpos ,
+		vpos ,
+		hit_a , hit_b ,
+		hpos_h ,
+		vpos_h ,
+		speed , speed_q1 , speed_q2 , (speed_q1 && speed_q2) ? 0 : 1 ,
+		score_q , score_q ^ 1
+	);
+#endif
+
+	if ( input_port_read(screen->machine, "IN0") & 1 )
+	{
+		if ( STOP_G )
+		{
+			STOP_G = 0;
+			ATRACT = 1;
+			score1 = 0;
+			score2 = 0;
+			if ( !serve_timer )														 /* SU 059 */
+			{
+			/* monoflop (NE555/G4) with a 330 kOhms resistor and 4.7 æF capacitor */
+				timer_set(screen->machine, ATTOTIME_IN_USEC(12*330000*47/100), NULL, 0, serve_timer_cb);			/* SU 059 */
+				serve_timer = 1;														/* SU 059 */
+			}
+		}
+	}
+
+	copybitmap(bitmap,screen->machine->generic.tmpbitmap,0,0,0,0,clip);
+	bitmap_fill(screen->machine->generic.tmpbitmap, clip, screen->machine->pens[0]);
+
+	/* reset the VPAD timers */
+	vpad1_timer = 0;
+	vpad2_timer = 0;
+
+	/* save state of the vblank flip-flop 74107/A2 */
+	hit_vbl_0 = hit_vbl_q;
+
+	logerror("VIDEO_UPDATE at H:%d, V:%d\n", (int)cpu_get_reg(screen->machine->firstcpu, GS_H), (int)cpu_get_reg(screen->machine->firstcpu, GS_V));	/* SU 078u2 */
+
+	cpu_set_reg(screen->machine->firstcpu, GS_V, 0);
+	V = 0;
+	VRESET = 1;
+
+	return 0;
+}
+
+/******* HORIZONTAL SYNC *****************************************************
+ * Pong's horizontal counter is made up of two 7493 chips (4 bit
+ * binary counters F8 and F9) and a JK flip-flop (74107 F6) for
+ * the MSB, whic is bit 8 of the pixel column number.
+ * The HRESET signal is generated when counters reached 256+128+64+4+2,
+ * that is the pixel clock #454 of a scanline. The HRESET signal
+ * is decoded using the eight input NAND gate 7430/F7, three inputs are
+ * tied to Vcc and the remaining five are connected to the 256H, 128H,
+ * 64H, 4H and 2H outputs. This signal goes to a D-type flip-flop.
+ * The raising edge of the clock pulse latches the output of F7 in
+ * 7474/E7.2, it's output Q\ is called HRESET.
+ * The HRESET goes away at the next clock cycle's raising edge.
+ * At the time HRESET is active, there's another flip-flop made from two
+ * NAND gates (7400/H5.2 and 7400/H5.3) set to generate the HBLANK signal.
+ * This signal remains active until the counter reaches 64+16 (decoded by
+ * 7410/G5.2), so the first 80 pixel clocks are invisible/blanked.
+ * During the horizontal blanking time, there's the HSYNC signal
+ * drived from counter bit 6 (32H), so pixel clocks 0..31 are
+ * HBLANK alone, 32..63 HBLANK+HSYNC and 64..79 HBLANK alone again.
+ *****************************************************************************/
+#define H4		(H&4)
+#define H8		(H&8)
+#define H16 	(H&16)
+#define H32 	(H&32)
+#define H64 	(H&64)
+#define H128	(H&128)
+#define H256	(H&256)
+
+#define HBLANK	(H < PONG_HBLANK)
+
+/******* VERTICAL SYNC *******************************************************
+ * The vertical counter is also made up of two 7493 chips (4-bit
+ * binary counters E8 and E9) and a JK flip-flop (74107/D9.2) for
+ * the MSB, which is bit 8 of the scanline number.
+ * The VRESET signal is generated when counters reached 256+4+1,
+ * that is when scanline #261 is being displayed.
+ * (This shows that PONG was a horizontal game ;)
+ * Similiar to the HORIZONTAL COUNTER there are really two more
+ * VERTICAL SYNC counter values, because VRESET is delayed by the
+ * pixel clock: the VRESET signal is decoded using a three input
+ * NAND gate (7410/D8.3) and it's inputs are connected to the 256V,
+ * 4V and 1V outputs. The clock pulse (HRESET) in scanline 261
+ * latches the output of D8.3 in the D-type flip-flop (7474/E7.1).
+ * It's negative output Q\ is called VRESET, very similiar to the
+ * horizontal stuff. The VRESET goes away on the next raising edge
+ * of the cycle (HRESET going high).
+ * At the time VRESET goes active (high), there's another flip-flop
+ * made from two NOR gates (7400/F5.3 and 7400/F5.4) set to generate
+ * the VBLANK\ signal. This signal remains active until the counter
+ * reaches 16, so the first 16 scanlines are invisible/blanked.
+ * During the vertical blanking time, there's the VSYNC signal drived
+ * from the VERTICAL SYNC counter bits 2+3 (VBLANK and 4V and 8V\),
+ * so scanlines 0..3 are VBLANK alone, scanlines 4..7 VBLANK+VSYNC
+ * and scanlines 8..15 VBLANK alone again.
+ *
+ * If you multiply 261 by the 454 pixels per scanline, the pixel
+ * clock must have been 7,109,640 Hz for a 60 Hz frame rate.
+ * This would mean a crystal with 14,219,280 Hz, but probably it
+ * was a standard US TV crystal with 14,318,100 Hz
+ *****************************************************************************/
+#define V4	(V&4)
+#define V8	(V&8)
+#define V16 	(V&16)
+#define V32 	(V&32)
+#define V64 	(V&64)
+#define V128	(V&128)
+
+#define VBLANK	(V < PONG_VBLANK)
+
+
+/******* VERTICAL SYNC *******************************************************
+ * The VERTICAL SYNC counters are incremented once per scanline
+ * We emulate this by calling pong_vh_scanline() 262 times per frame
+ *****************************************************************************/
+INTERRUPT_GEN( pong_vh_scanline )
+{
+	int HRESET, H;
+	int pen1 = device->machine->pens[1];
+
+	if ( V >= PONG_MAX_V )
+		return;	/* SU 058 */
+
+/******* THE NET *************************************************************
+ * I'll try to start with the simpler things:
+ * The net is a vertical line of one pixel width,
+ * which occurs every four scanlines - it is 'dashed'.
+ * This is decoded using a JK flip-flop clocked
+ * with the pixel clock, J tied to 256H and K to -256H.
+ * So everytime when there's a change in 256H/-256H the
+ * JK flip-flop will be set for one pixel clock.
+ * The -Q output is sent into a three input NOR gate together
+ * with VBLANK and 4V, so the NET output of gate G2 is true
+ * for (H == 256) and ((V & 4) == 0) for every non-blanked
+ * scanline (scanlines 16...260).
+ *****************************************************************************/
+	if ( !V4 && !VBLANK )
+		*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256) = pen1;
+
+/******* THE SCORE ***********************************************************
+ * The score for both players is counted using a decade
+ * counter plus a JK flip-flop for the 10. There's C7/C8 1st
+ * for player 1 and D7/C8 2nd for player two.
+ * The two scores are de-multiplexed using two 74153 chips C6/D6.
+ * This are four one-of-four de-multiplexers and they select
+ * the signals by decoding 32H and 64H signals.
+ * So there are > 14 different stages during each scanline.
+ * They alternate according to the following table:
+ *  state   A       B       C       D
+ *  -------------------------------------------
+ *  0       +5v     P1.E    P1.E    P1.E
+ *  1       P1.A    P1.B    P1.C    P1.D
+ *  2       +5v     P2.E    P2.E    P2.E
+ *  3       P2.A    P2.B    p2.C    P2.D
+ *  4       - same ase 0 -
+ *  ...
+ * So we have four score 'digits' here, spread to 4 * 32 pixels.
+ * They are contained in the signals A,B,C and D.
+ * A BCD-to-7segment decoder 7448 is used to convert those
+ * four bits into the segment of a 7-segment LED, which has
+ * the following layout:
+ *         a
+ *       -----
+ *    f |  g  | b
+ *       -----
+ *    e |     | c
+ *       -----
+ *         d
+ * One tricky detail is hidden in the states 0, 2, 4 etc.:
+ * The 7448 decodes 15 into 'no segments active'. Since the
+ * A signal is tied to +5V and all other inputs are tied to -Q
+ * of the overflow JK flip-flop for the even states, this has
+ * the effect of suppressing the leading zero until the overflow
+ * from the JK flip-flop is set (and thus -Q is cleared to lo).
+ *
+ * Well, and Pong uses no LED displays, but decodes the
+ * horizontal and vertical positions into segments using
+ * a whole lotta gates. I don't want to describe it here ;)
+ * Look at the gates E2, E3, F2 for the horizontal decoding.
+ *****************************************************************************/
+
+	/* Decode the players scores into 7 segment displays
+	 * Gate F2.1 decodes 32V && !64V && !128V && 'hpos valid',
+	 * so we first check if the VERTICAL SYNC counter is in range:
+	 */
+	if ( V32 && !V64 && !V128 )
+	{
+		/* Instead of going through the whole line and
+		 * checking the expression for the E2/E3 gates,
+		 * we call a decoding function with appropriate X offsets.
+		 */
+		pong_7seg(device->machine, 128, score1 > 9 ? 1 : 15);
+		pong_7seg(device->machine, 128 + 32, score1 % 10);
+		pong_7seg(device->machine, 256 + 32, score2 > 9 ? 1 : 15);
+		pong_7seg(device->machine, 256 + 32 + 32, score2 % 10);
+	}
+
+
+/******* THE ATRACT MODE *****************************************************
+ * If the ATRACT signal is lo (while no game is running), the pads are not
+ * drawn. The ball HORIZONTAL POSITION counters are kept reset, so there's
+ * no ball drawn either. We bail out here if ATRACT is not set
+ *****************************************************************************/
+
+	if ( ATRACT )
+	{
+
+/******* THE VPADS ***********************************************************
+ * The players pads are two vertical blocks which are four
+ * pixels wide and fifteen pixels high.
+ * The starting scanline of each pad is derived from a timer,
+ * the well known NE555 chip. The paddle inputs are used to
+ * fire the players timer after a variable amount of time.
+ * These timers are triggered by the -256V signal, which is
+ * active hi for scanlines in range from 0 to 255.
+ * When one of the timer fires, it allows the -HSYNC signal
+ * to pass a NAND gate (7400 B7) and the output of this gate
+ * increments a four bit binary (7493/A8 7493/B8?) counter.
+ * This clock is inhibted once the counter reaches 8+4+2+1 = 15,
+ * which is decoded using a four input NAND gate (7420 A7).
+ * So the counter does count from 0..15 and stop there.
+ * The counters are held reset while the timer has not yet
+ * fired for scanlines above the pad. The -VPADx signals are
+ * also inhibited by the NAND gates of B7 (7400) after the
+ * terminal count of 15 has been reached.
+ *
+ * The horizontal position of the VPADS is decoded using a
+ * D-type latch with negative clock input, which is clocked
+ * with the 4H signal (pixel clock / 4).
+ * The 128H signal is the data which is latched, so the
+ * output of the latch is high whenever the horizontal
+ * counter has bit 7 set while bit 2 goes from hi to lo.
+ * The 256H signal is used to decide which of the two
+ * VPADx signals to use: VPAD1 if 256H enables one NOR gate
+ * G2 (7427) while VPAD2 is sent through anohter gate
+ * together with then negative -256H signal.
+ * So the left VPAD is at pixels 128..131 and the right
+ * is at pixels 256..259 whenever the respective VPADx
+ * counters are counting.
+ *****************************************************************************/
+
+		/* check for the left VPAD */
+		if ( VPAD1 )
+		{
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+0) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+1) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+2) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+3) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+4) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+5) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+6) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 128+7) = pen1;
+			vpad1_count += 1;
+		}
+		else
+		/* it isn't, was the timer fired already? */
+			if ( vpad1_timer == 0 )
+		{
+			/* no, check if it should fire now */
+			vpad1_timer = ( V >= input_port_read(device->machine, "IN1") );
+			/* if it did, start counting from the next scanline */
+			if ( vpad1_timer )
+				vpad1_count = 0;
+		}
+
+		/* check for the right VPAD */
+		if ( VPAD2 )
+		{
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+0) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+1) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+2) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+3) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+4) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+5) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+6) = pen1;
+			*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, 256+128+7) = pen1;
+			vpad2_count += 1;
+		}
+		else
+		/* it isn't, was the timer fired already? */
+			if ( vpad2_timer == 0 )
+		{
+			/* no, check if it should fire now */
+			vpad2_timer = ( V >= input_port_read(device->machine, "IN2") );
+			/* if it did, start counting from the next scanline */
+			if ( vpad2_timer )
+				vpad2_count = 0;
+		}
+
+		if ( VRESET )
+		{
+			int a, b, c;
+			/*
+			 * NOR gate 7402/G1.4 is tied to the speed counter outputs
+			 * (7493/F1) bits 1 and 3, so if one of them is high, the NOR
+			 * output is low; if both are low, the output is high.
+			 * But the NOR is used as an OR by inverting it's output
+			 * with 7400/H1.1 again, so we toggle the output.
+			 */
+			a = ( (speed & 2) || (speed & 8) ) ? 1 : 0;
+			/*
+			 * NAND gate 7400/E1.3 is also tied to bits 1 and 3.
+			 * If the counter reads 10, the output is low, otherwise high.
+			 */
+			b = ( (speed & 2) && (speed & 8) ) ? 0 : 1;
+			/*
+			 * The signals (a) and (b) go into NAND gate 7400/H1.4,
+			 * so the output is low if both inputs are high.
+			 */
+			c = ( a && b ) ? 0 : 1;
+			/*
+			 * Now since VRESET is high when we come here,
+			 * the two JK flip-flops of H2 are cleared depending
+			 * on signal (a) -> clears H2.2 (speed_q1)
+			 * signal (b) -> clears H2.1 (speed_q2)
+			 */
+			if ( c == 1 ) speed_q1 = 0;
+			if ( a == 1 ) speed_q2 = 0;
+		}
+		else
+		{
+			/*
+			 * clock 74107/H2.1 and 74107/H2.2
+			 * J of H2.2 is connected to Q of H2.1, K is tied to GND,
+			 * so Q2 is set if Q1 was set, else it is unchanged.
+			 * input J of H2.1 tied to Vcc, K comes from the NAND gate
+			 * (7400/H4.1), so if K was low the Q output of H2.2
+			 * is set, otherwise it is toggled.
+			 */
+			if ( speed_q1 )
+			{
+				if ( !speed_q2 )
+					speed_q1 ^= 1;
+				speed_q2 = 1;
+			}
+			else
+			{
+				speed_q1 ^= 1;
+			}
+		}
+
+/******* VERTICAL POSITION ***************************************************
+ * This section is made up of two presettable 4-bit binary counters
+ * (9316/B3 and 9316/A3). The first is loaded with a value from
+ * the VERTICAL VELOCITY section (outputs of 4-bit full adder 7483/B4)
+ * and the second is always with zero.
+ * The clock input for both counters is the -HSYNC signal, so the
+ * count takes place during the HBLANK time when -HSYNC goes hi
+ * again (to be exact: at pixel clock #64 of a scanline).
+ * However, both counters have 'enable counter' inputs:
+ * Counter a (9316/B3) only counts if the -VBLANK signal is hi,
+ * so it does not count during VBLANK (scanlines 0 to 15).
+ * Counter b (9316/A3) only counts if the RC output of counter A
+ * is high - this is the case whenever counter A counted to 15.
+ * *IMPORTANT*: RC is only goes high when the T enable input is high too!
+ * The VVID signal is true whenever counter A counted to a value
+ * >= 12 (bits 2+3 are hi) and the RC output counter B is set
+ * (counter B = 15). When both counters reach 15 they are reloaded.
+ *****************************************************************************/
+		/*
+		 * Output of 7400 B2.2
+		 * Are the RC outputs of both VERTICAL POSITION counters active?
+		 */
+		if ( vpos_a == 15 && !VBLANK && vpos_b == 15 )
+		{
+			pong_vertical_velocity(device->machine);
+			/*
+			 * reset VERTICAL POSITION counter A to the value output
+			 * from the VERTICAL VELOCITY 4-bit full adder
+			 */
+			vpos_a = v_velocity;
+			/*
+			 * reset VERTICAL POSITION counter B to zero
+			 * all inputs of 9316/A3 are tied to ground)
+			 */
+			vpos_b = 0;
+		}
+		else
+		{
+			/* If the RC output of VERTICAL POSITION counter A (9316/B3) is hi */
+			if ( vpos_a == 15 && !VBLANK )
+			{
+				/* Increment the VERTICAL POSITION counter B (9316/A3) */
+				vpos_b = (vpos_b + 1) % 16;		   /* SU 071 */
+				/*
+				 * raising edge of RC also resets the HIT SOUND D FF 7474/C2
+				 */
+				if ( vpos_b == 15 )
+				{
+					/* eventually enable hit sound */
+					pong_hit_sound = hit_sound;
+					hit_sound = 0;
+				}
+			}
+		}
+		/* If VBLANK is not active */
+		if ( !VBLANK )
+		{
+			/* Increment the VERTICAL POSITION counter A (9316/B3) */
+			vpos_a = (vpos_a + 1) % 16;		  /* SU 071 */
+		}
+
+		if ( V == PONG_VBLANK )
+		{
+			/* eventually enable hit VBLANK sound */
+			if ( hit_vblank > 0 )
+				hit_vblank--;
+			pong_vblank_sound = hit_vblank;
+		}
+
+		/*
+		 * output of 7410 E2.2
+		 * check if bits 2 and 3 of counter A and the RC output of counter B are set
+		 */
+		VVID = ( vpos_a >= 12 && vpos_b == 15 ) ? 1 : 0;
+
+		if ( !serve_timer )				/* SU 059 */
+		{
+			if ( VVID && V == VBLANK )	 /* VBLANK just went low ? */
+			{
+				/* check for VVID on the falling edge of VBLANK
+				 * this is done with 74107/A2.1 from the VERTICAL VELOCITY
+				 * section which is clocked with VBLANK and toggles it's
+				 * Q/-Q outputs if VVID is active (high).
+				 * A2.1 is cleared by any of the HIT1 or HIT2 signals.
+				 */
+				hit_vbl_q = hit_vbl_0 ^ 1;
+				hit_vblank = 2;
+			}
+
+/******* HORIZONTAL SYNC *****************************************************
+ * The HORIZONTAL SYNC counters are swept through now to emulate the
+ * ball position (HORIZONTAL POSITION) and HIT DETECTION stuff.
+ *****************************************************************************/
+
+			for ( HRESET = 1, H = 0; H < PONG_MAX_H; HRESET ? HRESET = 0 : H++ )
+			{
+/******* HORIZONTAL POSITION *************************************************
+ * This section is made up of two presettable 4-bit binary counters
+ * (9316/G7 and 9316/H7) and a JK flip-flop (74107/G5.2).
+ * The first counter is loaded with eight plus a value from the
+ * HIT DETECTION section (outputs Aa, Ba called hit_a, hit_b here)
+ * and the second is always loaded with a constant value of eight.
+ * The clock input for both counters is the CLOCK signal.
+ * However, both counters have 'enable counter' inputs:
+ * Counter A (9316/G7) only counts if the -HBLANK signal is hi,
+ * so it does not count during HBLANK (pixels 0 to 79 of a scanline).
+ * Counter B (9316/H7) only counts if the RC output of counter A
+ * is hi - this is the case whenever counter A counted to 15.
+ * *IMPORTANT*: RC is only goes high when the T enable input is high too!
+ * The JK flip-flop toggles it's Q output whenever the RC output
+ * of counter B goes from hi to lo.
+ * The HVID signal is true whenever counter A counted to a value
+ * >= 12 (bits 2+3 are hi), the RC output counter B is set.
+ * (counter B = 15) and the JK flip-flop output Q is hi.
+ * When both counters reach 15 and the JK flip-flop Q output is hi
+ * the counters are reloaded (and the JK flip-flop is reset).
+ *****************************************************************************/
+				/* if HBLANK is not active */
+				if ( !HBLANK )
+				{
+					/* output of 7410 G5.3
+					 * check if the RC outputs of both HORIZONTAL POSITION counters
+					 * and the Q output of the JK flip-flop are set
+					 */
+					if ( hpos_a == 15 && hpos_b == 15 && hpos_c )
+					{
+						pong_hit_detector(device->machine);
+						/*
+						 * load counter A with D=8, C=0, B=hit_b and A=hit_a
+						 * (hit_a and hit_b signals from HIT DETECTION section)
+						 */
+						hpos_a = 8 + hit_b * 2 + hit_a;
+						/*
+						 * Load counter B with D=8 (Vcc) and C,B,A=0 (GND)
+						 * constant load 8
+						 */
+						hpos_b = 8;
+						/*
+						 * on a falling edge of RC output of H7: toggle the JK flip-flop
+						 */
+						hpos_c ^= 1;
+					}
+					else
+					{
+						/* if the RC output of HORIZONTAL POSITION counter A (9316/G7) is high */
+						if ( hpos_a == 15 )
+						{
+							/* increment the HORIZONTAL POSITION counter B (9316/H7) */
+							hpos_b = (hpos_b + 1) % 16;		  /* SU 071 */
+
+							/* on a falling edge of RC output of H7: toggle the JK flip-flop */
+							if ( hpos_b == 0 )
+								hpos_c ^= 1;
+						}
+						/* increment the HORIZONTAL POSITION counter A (9316/G7) */
+						hpos_a = (hpos_a + 1) % 16;		 /* SU 071 */
+					}
+				}
+				/*
+				 * Output of 7410/E2.2
+				 * Are bits 2+3 of counter A, RC of counter B and the JK flip-flop active?
+				 */
+				HVID = ( hpos_a >= 12 && hpos_b == 15 && hpos_c ) ? 1 : 0;
+
+				if ( HVID && VVID )
+				{
+					if ( !VBLANK )
+						*BITMAP_ADDR16(device->machine->generic.tmpbitmap, V, H) = pen1;
+#ifdef	MAME_DEBUG
+					if ( vpos_a == 12 )	vpos = V;	 /* first scanline of VVID */
+					if ( hpos_a == 12 )	hpos = H;	 /* first pixel of HVID */
+#endif
+					if ( VPAD1 && H >= 128 && H < 128+8 )
+					{
+#ifdef MAME_DEBUG
+						hpos_h = hpos;
+						vpos_h = vpos;
+#endif
+						/* 7474/H3.2 is cleared by the HIT1 signal */
+						score_q = 0;
+						if ( hit_sound == 0 )
+						{
+							pong_hit_sound = hit_sound = 1;
+							if ( speed < 10 )
+								speed += 1;
+						}
+						vvel_b = (vpad1_count & 2) ? 0 : 1;
+						vvel_c = (vpad1_count & 4) ? 0 : 1;
+						vvel_d = (vpad1_count & 8) ? 0 : 1;
+						/* 74107/A2.1 is cleared by any HIT signal */
+						hit_vbl_q = 0;
+					}
+					else
+						if ( VPAD2 && H >= 256+128 && H < 256+128+8 )
+					{
+#ifdef MAME_DEBUG
+						hpos_h = hpos;
+						vpos_h = vpos;
+#endif
+						/* 7474/H3.2 is set by the HIT2 signal */
+						score_q = 1;
+						if ( hit_sound == 0 )
+						{
+							pong_hit_sound = hit_sound = 1;
+							if ( speed < 10 )
+								speed += 1;
+						}
+						vvel_b = (vpad2_count & 2) ? 0 : 1;
+						vvel_c = (vpad2_count & 4) ? 0 : 1;
+						vvel_d = (vpad2_count & 8) ? 0 : 1;
+						/* 74107/A2.1 is cleared by any HIT signal */
+						hit_vbl_q = 0;
+					}
+					else
+						if ( HRESET )  /* no hit and HBLANK starts ? */
+					{
+						/* RESET SPEED */
+						speed = 0;
+						/*
+						 * start the SCORE SOUND TIMER NE555/G4
+						 */
+						if ( ATRACT && !score_sound_timer )										 /* SU 059 */
+						{
+							/* monoflop (NE555/G4) with a 220 kOhms resistor and 1.0 æF capacitor */
+							timer_set(device->machine, ATTOTIME_IN_USEC(12*220000*10/100), NULL, 0, score_timer_cb);		/* SU 059 */
+							score_sound_timer = 1;												/* SU 059 */
+							pong_score_sound = 1;
+							/* raising edge of SC (output of NE555/G4) toggles D-type flip-flop 7474/H3.2 */
+							score_q ^= 0;
+							if ( R )
+							{
+								if ( ++score1 == ((input_port_read(device->machine, "IN0") & 2) ? 15 : 11) )
+								{
+									STOP_G = 1;
+									ATRACT = 0;
+								}
+							}
+							if ( L )
+							{
+								if ( ++score2 == ((input_port_read(device->machine, "IN0") & 2) ? 15 : 11) )
+								{
+									STOP_G = 1;
+									ATRACT = 0;
+								}
+							}
+						}
+						if ( !serve_timer )														/* SU 059 */
+						{
+							/* monoflop (NE555/G4) with a 330 kOhms resistor and 4.7 æF capacitor */
+							timer_set(device->machine, ATTOTIME_IN_USEC(12*330000*47/100), NULL, 0, serve_timer_cb);			/* SU 059 */
+							serve_timer = 1;														/* SU 059 */
+						}
+					}
+				}
+			}
+		}	/* !serve_timer */
+	}	/* ATRACT */
+
+	VRESET = 0;
+	V++;
+
+}
+
+/****** HIT DETECTOR *********************************************************
+ * It all starts with a 4-bit binary counter (7493/F1) which counts the
+ * speed of the ball motion. This counter is clocked with the HIT SOUND
+ * signal. The clock is inhibted by a NAND gate (7400/E1.4) when the counter
+ * reaches 10. The counter bits 1 and 3 (speed2 and speed8) are then sent
+ * into a combination of NAND and NOR gates. Their outputs are used to
+ * clear the two JK flip-flops H2.1 and H2.2 while VRESET is hi.
+ * The Q outputs of those JK flip-flops is sent into NAND gate 7400/H4.1
+ * and it's output again is used to generate Aa/Ba from the L/R signals
+ * of D flip-flop 7474/H3.2.
+ *****************************************************************************/
+INLINE void pong_hit_detector(running_machine *machine)
+{
+	int q, a;
+
+	q = (speed_q1 == 1 && speed_q2 == 1) ? 0 : 1;
+	a = ( L && q ) ? 0 : 1;
+	/*
+	 * The HIT DETECTOR outputs Aa and Ba (hit_a and hit_b)
+	 */
+	hit_b = ( R && q ) ? 0 : 1;
+	hit_a = ( a == 0 || hit_b == 0 ) ? 1 : 0;
+}
+
+/****** VERTICAL VELOCITY ****************************************************
+ * When a hit occurs, the vpad counter bits 1,2 and 3 of the VPAD
+ * that was hit are latched in 7474/A5.2, 7474/A5.1 and 7474/B5.1
+ * To be exact, the negated value of the bits is latched, because
+ * the 7450 chips (A6.1, A6.2 and B6.2) which are used to de-multiplex
+ * pad1/pad2 counters are AND/NOR gates.
+ * The signals are called vvel_b, vvel_c and vvel_d here.
+ * The second signal which is used is the state VVID during VBLANK,
+ * so it means the ball has hit the upper or lower screen border.
+ * This signal is called hit_vbl_q here.
+ *****************************************************************************/
+INLINE void pong_vertical_velocity(running_machine *machine)
+{
+	int a = 0;	/* A4 is tied to GND */
+	int b = 6;	/* B2 and B3 are tied to Vcc, B4 tied to GND */
+
+	/* inputs of XOR gate 7486/A4.3 */
+	if ( vvel_b != hit_vbl_q )
+		a += 1;				/* A1 */
+
+	/* inputs of XOR gate 7486/A4.2 */
+	if ( vvel_c != hit_vbl_q )
+		a += 2;				/* A2 */
+
+	/* inputs of AND/NOR gate 7450/B6.1 */
+	if ( vvel_d == hit_vbl_q )
+		b += 1;				/* equal: A3 = lo, B1 = hi */
+	else
+		a += 4;				/* else:  A3 = hi, B1 = lo */
+
+	/* Output of the 4-bit binary adder 7483/B4 */
+	v_velocity = (a + b) & 15;
+}
+
+
+/*
+ * Decode a value into it's active 7-segment display bars and
+ * draw them into PONG's screenbitmap using the logic from the
+ * schematics.
+ */
+INLINE void pong_7seg(running_machine *machine, int h0, int n)
+{
+	/*
+	 * This is what an 7448 chip produces at it's outputs
+	 * a-g for input values betwee 0 and 15:
+	 * 0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+	 * +-+	 + +-+ +-+ + + +-+ +-+ +-+ +-+ +-+		   + + +-+ +
+	 * | |	 |	 |	 | | | |   |	 | | | | |		   | | |   |
+	 * | |	 | +-+ +-+ +-+ +-+ +-+	 | +-+ +-+ +-+ +-+ +-+ +-+ +-+
+	 * | |	 | |	 |	 |	 | | |	 | | | | |	 | |		   |
+	 * +-+	 + +-+ +-+	 + +-+ +-+	 + +-+ +-+ +-+ +-+	   +-+ +-+
+	 */
+	static UINT8 decode_7seg[16][7] = {
+		{1,  1,  1,  1,  1,  1,  0},	/*	1 */
+		{0,  1,  1,  0,  0,  0,  0},	/*	0 */
+		{1,  1,  0,  1,  1,  0,  1},	/*	2 */
+		{1,  1,  1,  1,  0,  0,  1},	/*	3 */
+		{0,  1,  1,  0,  0,  1,  1},	/*	4 */
+		{1,  0,  1,  1,  0,  1,  1},	/*	5 */
+		{1,  0,  1,  1,  1,  1,  1},	/*	6 */
+		{1,  1,  1,  0,  0,  0,  0},	/*	7 */
+		{1,  1,  1,  1,  1,  1,  1},	/*	8 */
+		{1,  1,  1,  1,  0,  1,  1},	/*	9 */
+		{0,  0,  0,  1,  1,  0,  1},	/* 10 */
+		{0,  0,  1,  1,  0,  1,  1},	/* 11 */
+		{0,  1,  0,  0,  0,  1,  1},	/* 12 */
+		{1,  0,  0,  1,  0,  1,  1},	/* 13 */
+		{0,  0,  0,  1,  1,  1,  1},	/* 14 */
+		{0,  0,  0,  0,  0,  0,  0},	/* 15 */
+	};
+	int H;
+
+	n %= 16;
+
+	/*
+	 * We can step in paces of 4 pixels, because the mininum H
+	 * signal which has an effect on the display is 4H
+	 */
+	for ( H = h0; H < h0 + 32; H += 4 )
+	{
+		int f = (decode_7seg[n][5] && (!H4 && !H8 && !!H16) && !V16) ? 0 : 1;
+		int e = (decode_7seg[n][4] && V16 && (!H4 && !H8 && !!H16)) ? 0 : 1;
+		int b = (decode_7seg[n][1] && (!!(H4 && H8) && !!H16) && !V16) ? 0 : 1;
+		int c = (decode_7seg[n][2] && (!!(H4 && H8) && !!H16) && V16) ? 0 : 1;
+		int a = (decode_7seg[n][0] && !V16 && (H16 && !V8 && !V4)) ? 0 : 1;
+		int g = (decode_7seg[n][6] && !V16 && (V8 && V4 && H16)) ? 0 : 1;
+		int d = (decode_7seg[n][3] && V16 && (V8 && V4 && H16)) ? 0 : 1;
+
+		int score = (!a || !b || !c || !d || !e || !f || !g);
+
+		if ( score )
+		{
+			int pen2 = machine->pens[2];
+			*BITMAP_ADDR16(machine->generic.tmpbitmap, V, H + 0) = pen2;
+			*BITMAP_ADDR16(machine->generic.tmpbitmap, V, H + 1) = pen2;
+			*BITMAP_ADDR16(machine->generic.tmpbitmap, V, H + 2) = pen2;
+			*BITMAP_ADDR16(machine->generic.tmpbitmap, V, H + 3) = pen2;
+		}
+	}
+}
+
