/*****************************************************************************************

    mpu4.c

    MPU4 highly preliminary driver.

    A.G.E Code Copyright (C) 2004-2006 by J. Wallace and the AGEMAME Development Team.
    Visit http://www.mameworld.net/agemame/ for more information.

    M.A.M.E Core Copyright (c) 1996-2006, Nicola Salmoria and the MAME Team,
    used under license from http://mamedev.org


******************************************************************************************
  23-09-2006: Converted 7Segment code to cleaner version, but have yet to add new 16k EPROM, as
              the original image was purported to come from a Barcrest BBS service, and is probably
              more 'official'.
  07-09-2006: It appears that the video firmware is intended to be a 16k EPROM, not 64k as dumped.
              In fact, the current dump is just the code repeated 4 times, when nothing earlier than
              0xC000 is ever called. Presumably, the ROM is loaded into C000, and the remainder of the
              'ROM' space is in fact the extra 32k of RAM apparently needed to hold the video board data.
              For now, we'll continue to use the old dump, as I am unsure as to how to map this in MAME.
              Changed Turn Over's name, it's either 12 Pound or 20 Pound Turn Over, depending on settings.

              Not that I know how to hook this up, but the O3 pin from IC2 seems to be able to influence
              the audio filter in some way - see the circuit diagram on my site for the layout.

              At this stage, I cannot see how to progress any further with the emulation, so I have transferred
              a non-AWP version of this driver to MAME for further study.

  06-09-2006: Connect 4 added - VFD is currently reversed, although it looks to me like
              that's the correct behaviour, and that my 'correction' for Old Timer was wrong.
              Yamaha sound does work, but is horrendous - presumably there's a filter on the
              sound that I haven't spotted. Trackball is apparently connected to AUX1, via
              Schmitt triggers - I wish I had a clue what this meant (El Condor).

  05-09-2006: And the award for most bone-headed bug goes to.. me! the 6840 handler wasn't
              resetting the clocks after timeout, so the wave frequencies were way off.
              Machines now hang on reset due to a lack of reel support.
              CHR decoding now included, but still requires knowledge of the data table
              location - this should be present in the ROMs somewhere.
              6850 ACIA code now taken from the SAC-1, with a few alterations for the clocking
              in and out - doesn't seem to be copying the right data, though.

  11-08-2006: It appears that the PIA IRQ's are not connected after all - but even
              disabling these won't get around the PTM issues.
              It also looks like the video card CHR is just a word-based version
              of the original, byte-based chip, meaning that should be fairly simple
              to emulate too, when the time comes.

  08-07-2006: Revised mapping of peripherals, and found method of calculating CHR
              values - although their use is still unknown.

  11-05-2006: El Condor, working from schematics and photos at present
  28-04-2006: El Condor
  20-05-2004: Re-Animator

  See http://www.mameworld.net/agemame/techinfo/mpu4main.php for map.
  See http://www.mameworld.net/agemame/techinfo/mpu4.php for Video Card information.

--- Board Setup ---

The MPU4 BOARD is the driver board, originally designed to run Fruit Machines made by the Barcrest Group, but later
licensed to other firms as a general purpose unit (even some old Photo-Me booths used the unit).

This original board uses a ~1.72 Mhz 6809B CPU, and a number of PIA6821 chips for multiplexing inputs and the like.

A 6840PTM is used for internal timing, one of it's functions is to act with an AY8913 chip as a crude analogue sound device.
(Data is transmitted through a PIA, with a square wave from the PTM being used as part of the filtering process)

A MPU4 GAME CARD (cartridge) plugs into the MPU4 board containing the game, and a protection PAL (the 'characteriser').
This PAL, as well as protecting the games, also controlled some of the lamp address matrix for many games, and acted as
an anti-tampering device which helped to prevent the hacking of certain titles in a manner which broke UK gaming laws.

One of the advantages of the hardware setup was that the developer could change the nature of the game card
up to a point, adding extra lamp support, different amounts of RAM, and (in many cases) an OKI MSM6376 and related PIA and PTM
for improved ADPCM sample support (This was eventually endorsed in the most recent official 'MOD' of the board)

For the Barcrest MPU4 Video system, the cartridge contains the MPU4 video bios in the usual ROM space (occupying 16k), interface chips
to connect an additional Video board, and a 6850 serial IO to communicate with said board. This version of the game card does not
have the OKI chip, or the characteriser.

The VIDEO BOARD is driven by a 10mhz 68000 processor, and contains a 6840PTM, 6850 serial IO (the other end of the
communications), an SAA1099 for stereo sound and SCN2674 gfx chip.

The VIDEO CARTRIDGE plugs into the video board, and contains the program roms for the video based game. Like the MPU4 game
card, in some cases an extra OKI sound chip is added to the video board's game card,as well as extra RAM.
There is a protection chip similar to and replacing the MPU4 Characteriser, which is often fed question data to descramble
(unknown how it works). In non-question cases, however, the protection chip works near identically to the original.

A decent schematic for the MPU4 board, amongst other info is available,
see http://www.mameworld.net/agemame/techinfo/mpu4.php .

(This appears to have an error in it regarding the IRQ generation of the PIAs, as
IC3 causes an infinite loop if IRQA is connected)

No video card schematics ever left the PCB factory, but some decent scans of the board have been made,
now also available for review.

Additional: 68k HALT line is tied to the reset circuit of the MPU4.

Emulating the standalone MPU4 is a priority, unless this works, the video won't run.
The copy of this driver held by AGEMAME is currently set up to run two UK standalone
games (Celebration Club and Connect 4), as well as a title using one of the later 'mods' (Old Timer,
a Dutch machine). Interestingly, on the Video card version of the MPU4, the 6840 IRQ
is in fact the FIRQ, in order to help with communications.

Everything here is preliminary...  the boards are quite fussy with regards their self tests
and the timing may have to be perfect for them to function correctly.  (as the comms are
timer driven, the video is capable of various raster effects etc.)

Datasheets are available for the main components, The AGEMAME site mirrors a few of the harder-to-find ones.

--- Preliminary MPU4 Memorymap  ---

(NV) indicates an item which is not present on the video version, which has a Comms card instead.

   hex     |r/w| D D D D D D D D |
 location  |   | 7 6 5 4 3 2 1 0 | function
-----------+---+-----------------+--------------------------------------------------------------------------
 0000-07FF |R/W| D D D D D D D D | 2k RAM
-----------+---+-----------------+--------------------------------------------------------------------------
 0800      |R/W|                 | Characteriser (Security PAL) (NV)
-----------+---+-----------------+--------------------------------------------------------------------------
 0880      |R/W| D D D D D D D D | PIA6821 on soundboard (Oki MSM6376@16MHz,(NV)
                                   port A = ??
                                   port B (882)
                                          b7 = 0 if OKI busy
                                               1 if OKI ready
                                          b6 = ??
                                          b5 = volume control clock
                                          b4 = volume control direction (0= up, 1 = down)
                                          b3 = ??
                                          b2 = ??
                                          b1 = ??
                                          b0 = ??
-----------+---+-----------------+--------------------------------------------------------------------------
 0850 ?    | W | ??????????????? | page latch (NV)
-----------+---+-----------------+--------------------------------------------------------------------------
 08C0      |   |                 | MC6840 on sound board(NV?)
-----------+---+-----------------+--------------------------------------------------------------------------
 0900-     |R/W| D D D D D D D D | MC6840 PTM IC2


  Clock1 <--------------------------------------
     |                                          |
     V                                          |
  Output1 ---> Clock2                           |
                                                |
               Output2 --+-> Clock3             |
                         |                      |
                         |   Output3 ---> 'to audio amp' ??
                         |
                         +--------> CA1 IC3 (

IRQ line connected to CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 0A00-0A03 |R/W| D D D D D D D D | PIA6821 IC3 port A Lamp Drives 1,2,3,4,6,7,8,9 (sic)(IC14)

                                            CA1 <= output2 from PTM6840 (IC2)
                                            CA2 => alpha data

                                            port B Lamp Drives 10,11,12,13,14,15,16,17 (sic)(IC13)

                                            CB2 => alpha reset (clock on Dutch systems)
                                            Schematic shows IRQ A and B connected, but program hangs?

-----------+---+-----------------+--------------------------------------------------------------------------
 0B00-0B03 |R/W| D D D D D D D D | PIA6821 IC4 port A = data for 7seg leds (pins 10 - 17, via IC32)

                                               CA1 INPUT, 50 Hz input (used to generate IRQ)
                                               CA2 OUTPUT, connected to pin2 74LS138 CE for multiplexer
                                                          (B on LED strobe multiplexer)
                                               IRQA connected to IRQ of CPU
                                               port B
                                                      PB7 = INPUT, serial port Receive data (Rx)
                                                      PB6 = INPUT, reel A sensor
                                                      PB5 = INPUT, reel B sensor
                                                      PB4 = INPUT, reel C sensor
                                                      PB3 = INPUT, reel D sensor
                                                      PB2 = INPUT, Connected to CA1 (50Hz signal)
                                                      PB1 = INPUT, undercurrent sense
                                                      PB0 = INPUT, overcurrent  sense

                                               CB1 INPUT,  used to generate IRQ on edge of serial input line
                                               CB2 OUTPUT, enable signal for reel optics
                                               IRQB connected to IRQ of CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 0C00-0C03 |R/W| D D D D D D D D | PIA6821 IC5 port A

                                                      PA0-PA7, INPUT AUX1 connector

                                               CA2  OUTPUT, serial port Transmit line
                                               CA1  not connected
                                               IRQA connected to IRQ of CPU

                                               port B

                                                      PB0-PB7 INPUT, AUX2 connector

                                               CB1  INPUT,  connected to PB7 (Aux2 connector pin 4)

                                               CB2  OUTPUT, AY8910 chip select line
                                               IRQB connected to IRQ of CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 0D00-0D03 |R/W| D D D D D D D D | PIA6821 IC6

                                    port A

                                          PA0 - PA7 (INPUT/OUTPUT) data port AY8910 sound chip

                                          CA1 INPUT,  not connected
                                          CA2 OUTPUT, BC1 pin AY8910 sound chip
                                          IRQA , connected to IRQ CPU

                                    port B

                                          PB0-PB3 OUTPUT, reel A
                                          PB4-PB7 OUTPUT, reel B

                                          CB1 INPUT,  not connected
                                          CB2 OUTPUT, B01R pin AY8910 sound chip
                                          IRQB , connected to IRQ CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 0E00-0E03 |R/W| D D D D D D D D | PIA6821 IC7

                                    port A

                                          PA0-PA3 OUTPUT, reel C
                                          PA4-PA7 OUTPUT, reel D
                                          CA1     INPUT,  not connected
                                          CA2     OUTPUT, A on LED strobe multiplexer
                                          IRQA , connected to IRQ CPU

                                    port B

                                          PB0-PB7 OUTPUT mech meter or reel E + F
                                          CB1     INPUT, not connected
                                          CB2     OUTPUT,enable mech meter latch
                                          IRQB , connected to IRQ CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 0F00-0F03 |R/W| D D D D D D D D | PIA6821 IC8

                                   port A

                                          PA0-PA7 INPUT  multiplexed inputs data

                                          CA1     INPUT, not connected
                                          CA2    OUTPUT, C on LED strobe multiplexer
                                          IRQA           connected to IRQ CPU

                                   port B

                                          PB0-PB7 OUTPUT  triacs outputs connector PL6
                                          used for slides / hoppers

                                          CB1     INPUT, not connected
                                          CB2    OUTPUT, pin1 alpha display PL7 (clock signal)
                                          IRQB           connected to IRQ CPU

-----------+---+-----------------+--------------------------------------------------------------------------
 1000-FFFF | R | D D D D D D D D | ROM (can be banked switched by 0x850 in 8 banks of 64 k ) (NV)
-----------+---+-----------------+--------------------------------------------------------------------------

 TODO: - confirm map, based on 6809 code.
       - Get MPU4 board working properly, so that video layer will operate.
       - Confirm that MC6850 emulation is sufficient.

*****************************************************************************************/

#include "driver.h"

#include "machine/6821pia.h"
#include "machine/6840ptm.h"

// MPU4
#include "ui.h"
#include "cpu/m6809/m6809.h"
#include "sound/ay8910.h"
#include "vidhrdw/awpvid.h" //Fruit Machines Only
#include "machine/lamps.h"
#include "machine/steppers.h" // stepper motor
#include "machine/vacfdisp.h"  // vfd
#include "machine/mmtr.h"

#ifdef MAME_DEBUG
#define LOG(x)	logerror x
#define LOG_CHR(x)	logerror x
#define LOG_IC3(x)	logerror x
#define LOG_IC8(x)	logerror x
#define LOGSTUFF(x) logerror x
#else
#define LOG(x)
#define LOG_CHR(x)
#define LOG_IC3(x)
#define LOG_IC8(x)
#define LOGSTUFF(x)
#endif

#include "mpu4.lh"

void draw_MPU4_led(UINT8 id, UINT8 value)
{
	output_set_digit_value(id,value);
}

// local vars /////////////////////////////////////////////////////////////
static int mmtr_latch;		  // mechanical meter latch
static int drive;
static int alpha_data_line;
static int alpha_clock;
static int ay8910_address;
static int expansion_latch;
static int global_volume;
static int serial_data;
static int signal_50hz;
static int ic4_input_b;
static int IC23GC;
static int IC23GB;
static int IC23GA;
static int prot_col;

// user interface stuff ///////////////////////////////////////////////////

static UINT8 Lamps[128];		// 128 multiplexed lamps
//static UINT8 inputs[32];		// 32  multiplexed inputs - but a further 8 possible per AUX.
								// Two connectors 'orange' (sampled every 8ms) and 'black' (sampled every 16ms)
								// Each connector carries two banks of eight inputs and two enable signals

static int optic_pattern;
static UINT16 lamp_strobe;
static UINT8  lamp_data;

static UINT8  IC3ca1;
static UINT8  yamdata;

//static int   led_mux_strobe;
static UINT8 chr_data[128];

static UINT8 led_segs[8]; 

/*
LED Segments related to pins (5 is not connected):
Unlike the controllers emulated in the layout code, each
segment of an MPU4 LED can be set individually, even
being used as individual lamps.
   _9_
  |   |
  3   8
  |   |
   _2_
  |   |
  4   7
  |   |
   _6_1

8 display enables (pins 10 - 17) 
*/
static int    input_strobe;	  // IC23 74LS138 A = CA2 IC7, B = CA2 IC4, C = CA2 IC8
static int    output_strobe;  // same

static const UINT8 MPU4_matrix1[] =
{   //1   2    3    4     5   6    8     9 
	0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
	0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
	0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
	0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
};

static const UINT8 MPU4_matrix2[] =
{
	//10  11   12   13   14   15   16   17     drives (lamp strobe) ->
	0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,//1
	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,//2 | selects (input strobe)
	0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,//3 V
	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,//4
	0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,//5
	0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,//7
	0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,//8
	0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 //9
};

void update_lamps(void)
{
	int x;
	Lamps[MPU4_matrix1[(16*input_strobe)+0]] = (lamp_strobe & 0x0001) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+1]] = (lamp_strobe & 0x0002) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+2]] = (lamp_strobe & 0x0004) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+3]] = (lamp_strobe & 0x0008) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+4]] = (lamp_strobe & 0x0010) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+5]] = (lamp_strobe & 0x0020) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+6]] = (lamp_strobe & 0x0040) != 0;
	Lamps[MPU4_matrix1[(16*input_strobe)+7]] = (lamp_strobe & 0x0080) != 0;

	Lamps[MPU4_matrix2[(16*input_strobe)+0]] = (lamp_strobe & 0x0100) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+1]] = (lamp_strobe & 0x0200) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+2]] = (lamp_strobe & 0x0400) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+3]] = (lamp_strobe & 0x0800) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+4]] = (lamp_strobe & 0x1000) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+5]] = (lamp_strobe & 0x2000) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+6]] = (lamp_strobe & 0x4000) != 0;
	Lamps[MPU4_matrix2[(16*input_strobe)+7]] = (lamp_strobe & 0x8000) != 0;
	Lamps_SetBrightness(0, 127, Lamps);

	for ( x = 0; x < 128; x++ )
	{
		LOG_CHR(("Lamp %02X %02X", x, Lamps[x]));
	}
}

// video initialisation ///////////////////////////////////////////////////

VIDEO_START( mpu4 )
{
	awp_reel_setup(6);
	return 0;
}

// video update ///////////////////////////////////////////////////////////

VIDEO_UPDATE( mpu4 )
{
	int x;
	awp_lamp_draw();

	if (screen == 0)
	{
		draw_16seg(bitmap,0,3,9);
	}
	draw_MPU4_led(0, led_segs[0]);
	draw_MPU4_led(1, led_segs[1]);
	draw_MPU4_led(2, led_segs[2]);
	draw_MPU4_led(3, led_segs[3]);
	draw_MPU4_led(4, led_segs[4]);
	draw_MPU4_led(5, led_segs[5]);
	draw_MPU4_led(6, led_segs[6]);
	draw_MPU4_led(7, led_segs[7]);

	for ( x = 0; x < 6; x++ )
	{
		draw_reel(x,steps[x],symbols[x]);
	}

	return 0;
}
// palette initialisation /////////////////////////////////////////////////

PALETTE_INIT( mpu4 )
{
	palette_set_color(machine, 0,0x00,0x00,0x00);
	palette_set_color(machine, 1,0x00,0x00,0xFF);
	palette_set_color(machine, 2,0x00,0xFF,0x00);
	palette_set_color(machine, 3,0x00,0xFF,0xFF);
	palette_set_color(machine, 4,0xFF,0x00,0x00);
	palette_set_color(machine, 5,0xFF,0x00,0xFF);
	palette_set_color(machine, 6,0xFF,0xFF,0x00);
	palette_set_color(machine, 7,0xFF,0xFF,0xFF);
	palette_set_color(machine, 8,0x80,0x80,0x80);
	palette_set_color(machine, 9,0x00,0x00,0x80);
	palette_set_color(machine,10,0x00,0x80,0x00);
	palette_set_color(machine,11,0x00,0x80,0x80);
	palette_set_color(machine,12,0x80,0x00,0x00);
	palette_set_color(machine,13,0x80,0x00,0x80);
	palette_set_color(machine,14,0x80,0x80,0x00);
	palette_set_color(machine,15,0x80,0x80,0x80);
}

///////////////////////////////////////////////////////////////////////////
// called if board is reset ///////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

static MACHINE_RESET( mpu4 )
{
	vfd_reset(0);	// reset display1

// reset stepper motors /////////////////////////////////////////////////
	{
		int pattern =0,i;

		for ( i = 0; i < 6; i++)
		{
			Stepper_reset_position(i);
			if ( Stepper_optic_state(i) ) pattern |= 1<<i;
		}
		optic_pattern = pattern;
	}

	lamp_strobe    = 0;
	lamp_data      = 0;

	IC23GC    = 0;
	IC23GB    = 0;
	IC23GA    = 0;
	prot_col  = 0;

// init rom bank ////////////////////////////////////////////////////////

	{
		UINT8 *rom = memory_region(REGION_CPU1);

		memory_configure_bank(1, 0, 8, &rom[0x01000], 0x10000);

		memory_set_bank(1,0);//?
	}

}

///////////////////////////////////////////////////////////////////////////

static MACHINE_RESET( mpu4_vid )
{
	vfd_reset(0);	// reset display1

// reset stepper motors /////////////////////////////////////////////////
	{
		int pattern =0,i;

		for ( i = 0; i < 6; i++)
		{
			Stepper_reset_position(i);
			if ( Stepper_optic_state(i) ) pattern |= 1<<i;
		}
		optic_pattern = pattern;
	}

	//led_mux_strobe = 0;
	lamp_strobe    = 0;
	lamp_data      = 0;

	IC23GC    = 0;
	IC23GB    = 0;
	IC23GA    = 0;
	prot_col  = 0;
}

//////////////////////////////////////////////////////////////////////////
void cpu0_irq(int state)
{
	cpunum_set_input_line(0, M6809_IRQ_LINE, state?ASSERT_LINE:CLEAR_LINE);//?
	logerror("6809 int%d \n",state);
}

//////////////////////////////////////////////////////////////////////////
void cpu0_firq(int state)
{
	cpunum_set_input_line(0, M6809_FIRQ_LINE, state?ASSERT_LINE:CLEAR_LINE);//?
	logerror("6809 fint%d \n",state);
}

///////////////////////////////////////////////////////////////////////////
static WRITE8_HANDLER( bankswitch_w )
{
//	memory_set_bank(1,data & 0x07);//BFM setting, may not be correct
	LOG(("Bank %d \n",data & 0x07));
}

// IC2 6840 PTM handler ///////////////////////////////////////////////////////

static WRITE8_HANDLER( ic2_o1_callback )
{
	ptm6840_set_c2(0,data);

	// copy output value to IC2 c2
	// this output is the clock for timer2,
	// the output from timer2 is the input clock for timer3
	// the output from timer3 is used as a square wave for the audio output (how?)
	// and as an external clock source for timer 1!

}

static WRITE8_HANDLER( ic2_o2_callback )
{
	pia_set_input_ca1(0, data); // copy output value to IC3 ca1
	IC3ca1 = data;
	ptm6840_set_c3(   0, data); // copy output value to IC2 c3
}

static WRITE8_HANDLER( ic2_o3_callback )
{
	ptm6840_set_c1(   0, data); // copy output value to IC2 c1
	//pia_set_input_a(3, data);

}

static const ptm6840_interface ptm_ic2_intf = 
{
	6880000/4,
	0,0,0,
	ic2_o1_callback, ic2_o2_callback, ic2_o3_callback,
	cpu0_irq
};

static const ptm6840_interface ptm_ic2b_intf = 
{
	6880000/4,
	0,0,0,
	ic2_o1_callback, ic2_o2_callback, ic2_o3_callback,
	cpu0_firq
};

/***************************************************************************
	6821 PIA handlers
***************************************************************************/

static WRITE8_HANDLER( pia_ic3_porta_w )
{
	LOG_IC3(("%04x IC3 PIA Port A Set to %2x (lamp strobes 1 - 9)\n", activecpu_get_previouspc(),data));

	lamp_strobe = (lamp_strobe & 0xFF00) | data;
	update_lamps();
}

static WRITE8_HANDLER( pia_ic3_portb_w )
{
	LOG_IC3(("%04x IC3 PIA Port B Set to %2x  (lamp strobes 10 - 17)\n", activecpu_get_previouspc(),data));

	lamp_strobe = (lamp_strobe & 0x00FF) | (data<<8);
	update_lamps();
}

static READ8_HANDLER( pia_ic3_ca1_r )
{
	LOG_IC3(("%04x IC3 PIA Read CA1 (PTM) %x \n",activecpu_get_previouspc(),IC3ca1));
	return IC3ca1;
}

static READ8_HANDLER( pia_ic3_ca2_r )
{
	LOG_IC3(("%04x IC3 PIA Read CA2\n",activecpu_get_previouspc()));
	return alpha_data_line;
}

static WRITE8_HANDLER( pia_ic3_ca2_w )
{
	LOG_IC3(("%04x IC3 PIA Write CA2 (alpha data), %02X\n", activecpu_get_previouspc(),data&0xFF));

	alpha_data_line = data;
}

static WRITE8_HANDLER( pia_ic3_cb2_w )
{
	LOG_IC3(("%04x IC3 PIA Write CB (alpha reset), %02X\n",activecpu_get_previouspc(),data&0xff));

	if ( data & 1 ) vfd_reset(0);
}

/*
UNUSED FUNCTION
static READ8_HANDLER( pia_ic3_cb1_r )
{
//	LOG_IC3(("%04x IC3 PIA Read CB1\n",activecpu_get_previouspc()));
	return 0;
}*/

// IC3, lamp data lines + alpha numeric display 

static const pia6821_interface pia_ic3_intf = 
{
	/*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, pia_ic3_ca2_r, 0,
	/*outputs: A/B,CA/B2       */ pia_ic3_porta_w, pia_ic3_portb_w, pia_ic3_ca2_w, pia_ic3_cb2_w,
	/*irqs   : A/B             */ 0, 0
};

static WRITE8_HANDLER( pia_ic4_porta_w )
{
	if (!IC23GC)
	{
		if (!IC23GB)
		{
			if (IC23GA)
			{
				switch (input_strobe)
				{
					case 0x00:
					led_segs[0] = data;
					case 0x01:
					led_segs[1] = data;
					case 0x02:
					led_segs[2] = data;
					case 0x03:
					led_segs[3] = data;
					case 0x04:
					led_segs[4] = data;
					case 0x05:
					led_segs[5] = data;
					case 0x06:
					led_segs[6] = data;
					case 0x07:
					led_segs[7] = data;
				}
			}
		}
	}
	LOG(("%04x IC4 PIA Port A Set to %2x\n", activecpu_get_previouspc(),data));
}

static READ8_HANDLER( pia_ic4_portb_r )
{

	if ( serial_data  ) 
	{
		ic4_input_b |=  0x80;
		pia_set_input_cb1(1, 1);
	}
	else
	{
		ic4_input_b &= ~0x80;
		pia_set_input_cb1(1, 0);
	}

	if ( optic_pattern & 0x01 ) ic4_input_b |=  0x40; // reel A tab
	else                        ic4_input_b &= ~0x40;

	if ( optic_pattern & 0x02 ) ic4_input_b |=  0x20; // reel B tab
	else                        ic4_input_b &= ~0x20;

	if ( optic_pattern & 0x04 ) ic4_input_b |=  0x10; // reel C tab
	else                        ic4_input_b &= ~0x10;

	if ( optic_pattern & 0x08 ) ic4_input_b |=  0x08; // reel D tab
	else                        ic4_input_b &= ~0x08;

	if ( signal_50hz ) 			ic4_input_b |=  0x04; // 50 Hz
	else   	                    ic4_input_b &= ~0x04;

	// if ( lamp_overcurrent  ) ic4_input_b |= 0x02;
	// if ( lamp_undercurrent ) ic4_input_b |= 0x01;

	LOG(("%04x IC4 PIA Read of Port B %x\n",activecpu_get_previouspc(),ic4_input_b));
	return ic4_input_b;
}

static READ8_HANDLER( pia_ic4_ca1_r )
{
	LOG(("%04x IC4 50Hz %x\n",activecpu_get_previouspc(),signal_50hz));
	return signal_50hz;
}

static WRITE8_HANDLER( pia_ic4_ca2_w )
{
	LOG_IC3(("%04x IC4 PIA Write CA (input MUX strobe /LED B), %02X\n", activecpu_get_previouspc(),data&0xFF));

	if ( data )  input_strobe |=  0x02;
	else         input_strobe &= ~0x02;

	output_strobe = input_strobe; // same strobe lines are used for input and output
	IC23GB = data;
}

static WRITE8_HANDLER( pia_ic4_cb2_w )
{
	LOG_IC3(("%04x IC4 W CB2 (Reel Optics) (T39, connector PL13 pin 2), %02X\n",activecpu_get_previouspc(),data&0xff));
}

/*
UNUSED FUNCTION
static READ8_HANDLER( pia_ic4_cb1_r )
{
	return 0; //serial data
}

static WRITE8_HANDLER( pia_ic4_portb_w )
{
	logerror("%04x IC4 PIA Port B Set to %2x\n", activecpu_get_previouspc(),data);
}

static READ8_HANDLER( pia_ic4_porta_r )
{
	logerror("%04x IC4 PIA Read of Port A\n",activecpu_get_previouspc());
	return 0;
}

static READ8_HANDLER( pia_ic4_cb2_r )
{
	return 0;
}
*/

// IC4, 7 seg leds, 50Hz timer reel sensors, current sensors

static const pia6821_interface pia_ic4_intf =
{
	/*inputs : A/B,CA/B1,CA/B2 */ 0, pia_ic4_portb_r, pia_ic4_ca1_r, 0, 0, 0,
	/*outputs: A/B,CA/B2       */ pia_ic4_porta_w, 0, pia_ic4_ca2_w, pia_ic4_cb2_w,
	/*irqs   : A/B             */ cpu0_irq, cpu0_irq
};

static READ8_HANDLER( pia_ic5_porta_r )
{
	LOG(("%04x IC5 PIA Read of Port A (AUX1)\n",activecpu_get_previouspc()));
	return readinputportbytag("AUX1");
//	return 0;
}

static READ8_HANDLER( pia_ic5_portb_r )
{
	//int result = 0;
	LOG(("%04x IC5 PIA Read of Port B (coin input AUX2)\n",activecpu_get_previouspc()));

	//result = coin_latch()
	return readinputportbytag("AUX2");
	//return result;
}

static WRITE8_HANDLER( pia_ic5_ca2_w )
{
	LOG(("%04x IC5 PIA Write CA2 (Serial Tx) %2x\n",activecpu_get_previouspc(),data));
	serial_data = data;
}

static WRITE8_HANDLER( pia_ic5_cb2_w )
{
	LOG(("%04x IC5 PIA Write CB2 %2x\n",activecpu_get_previouspc(),data));
	//ay8912 chipsel

/*
UNUSED FUNCTION
static READ8_HANDLER( pia_ic5_cb1_r )
{
	LOG(("%04x IC5 PIA Read of CB1\n",activecpu_get_previouspc()));
	return readinputportbytag("AUX2") & 0x80;
}

static WRITE8_HANDLER( pia_ic5_portb_w )
{
	LOG(("%04x IC5 PIA Port B Set to %2x\n", activecpu_get_previouspc(), data));
//	pia_set_input_b(2, data);
//	led_mux_strobe = data;
}

static READ8_HANDLER( pia_ic5_ca1_r )
{
	LOG(("%04x IC5 PIA Read of CA1\n",activecpu_get_previouspc()));
	return 0;
}

static READ8_HANDLER( pia_ic5_ca2_r )
{
	LOG(("%04x IC5 PIA Read of CA2\n",activecpu_get_previouspc()));
	return 0;
}

static READ8_HANDLER( pia_ic5_cb2_r )
{
	LOG(("%04x IC5 PIA Read of CB2\n",activecpu_get_previouspc()));
	return 0;
}

*/
}

static const pia6821_interface pia_ic5_intf =
{
	/*inputs : A/B,CA/B1,CA/B2 */ pia_ic5_porta_r, pia_ic5_portb_r, 0, 0, 0, 0,//CB1 connected to PB7 Aux 2
	/*outputs: A/B,CA/B2       */ 0, 0, pia_ic5_ca2_w,  pia_ic5_cb2_w,
	/*irqs   : A/B             */ 0, 0
};

/* ---------------------------------------
   Yamaha sound function selection - 
   ---------------------------------------
The databus of the Yamaha sound chip is connected to IC6 Port A.
Data is read from/written to the Yamaha chip through this port. 

If this sounds familiar, Amstrad did something very similar with their home computers.

The PSG function, defined by the BC1,BC2 and BDIR signals, is controlled by CA2 and CB2 of IC6. 

PSG function selection:
-----------------------
BDIR = IC6 CB2 and BC1 = IC6 CA2

Pin            | PSG Function 
BDIR BC1       | 
0    0         | Inactive 
0    1         | Read from selected PSG register. When function is set, the PSG will make the register data available to Port A
1    0         | Write to selected PSG register. When set, the PSG will take the data at Port A and write it into the selected PSG register
1    1         | Select PSG register. When set, the PSG will take the data at Port A and select a register
*/
/* PSG function selected */

static void update_yam(void)
{
	switch (ay8910_address)
	{
  		case 0x00: 
		{
			/* Inactive */
			break;
	    }
	  	case 0x01: 
		{	/* CA2 = 1 CB2 = 0? : Read from selected PSG register and make the register data available to Port A */
			pia_set_input_a(3, AY8910_read_port_0_r(0));
			LOG(("Yamaha Read \n"));
			break;
	  	}
	  	case 0x02:
		{/* CA2 = 0 CB2 = 1? : Write to selected PSG register and write data to Port A */
	  		AY8910_write_port_0_w(0, pia_get_output_a(3));
			LOG(("Yamaha Write \n"));
			break;
	  	}
	  	case 0x03: 
		{/* CA2 = 1 CB2 = 1? : The register will now be selected and the user can read from or write to it.  The register will remain selected until another is chosen.*/
	  		AY8910_control_port_0_w(0, pia_get_output_a(3));
			LOG(("Yamaha Select \n"));
			break;
	  	}
		default:
		{
			LOG(("Yamaha error \n"));
		}
	}
}

static READ8_HANDLER( pia_ic6_porta_r )
{
	LOG(("%04x IC6 PIA Read of Port A\n",activecpu_get_previouspc()));
	update_yam();
	return yamdata;
}

static WRITE8_HANDLER( pia_ic6_portb_w )
{
	LOG(("%04x IC6 PIA Port B Set to %2x (Reel A and B)\n", activecpu_get_previouspc(),data));

//	Stepper_update(0, (data >> 4) & 0x0F );
//	Stepper_update(1, data        & 0x0F );
	Stepper_update(0, data >> 4);
	Stepper_update(1, (data));

	if ( Stepper_optic_state(0) ) optic_pattern |=  0x01;
	else                          optic_pattern &= ~0x01;
	if ( Stepper_optic_state(1) ) optic_pattern |=  0x02;
	else                          optic_pattern &= ~0x02;

	if (!optic_pattern == 0)
	pia_set_input_cb2(1,0);	// signal is connected to IC4 CB2
	pia_set_input_cb2(1,1);

}

static WRITE8_HANDLER( pia_ic6_porta_w )
{
	LOG(("%04x IC6 PIA Write A %2x\n", activecpu_get_previouspc(),data));
  	yamdata = data;
    update_yam();
}

static WRITE8_HANDLER( pia_ic6_ca2_w )
{
	LOG(("%04x IC6 PIA write CA2 %2x (AY8912 BC1)\n", activecpu_get_previouspc(),data));

	if ( data ) ay8910_address |=  0x01;
	else        ay8910_address &= ~0x01;

	update_yam();
}

static WRITE8_HANDLER( pia_ic6_cb2_w )
{
	LOG(("%04x IC6 PIA write CB2 %2x (AY8912 BCDIR)\n", activecpu_get_previouspc(),data));

	if ( data ) ay8910_address |=  0x02;
	else        ay8910_address &= ~0x02;

	update_yam();
}

/*
UNUSED FUNCTION
static READ8_HANDLER( pia_ic6_portb_r )
{
	LOG(("%04x IC6 PIA Read of Port B\n",activecpu_get_previouspc()));
	return 0;
}

static READ8_HANDLER( pia_ic6_ca2_r )
{
	return ay8910_address & 0x01;
}

static READ8_HANDLER( pia_ic6_cb2_r )
{
	return ay8910_address & 0x02;
}

static READ8_HANDLER( pia_ic6_cb1_r )
{
	return 0;
}

*/

static const pia6821_interface pia_ic6_intf =
{
	/*inputs : A/B,CA/B1,CA/B2 */ pia_ic6_porta_r, 0, 0, 0, 0, 0,
	/*outputs: A/B,CA/B2       */ pia_ic6_porta_w, pia_ic6_portb_w, pia_ic6_ca2_w, pia_ic6_cb2_w,
	/*irqs   : A/B             */ 0, 0
};

static WRITE8_HANDLER( pia_ic7_porta_w )
{
	LOG(("%04x IC7 PIA Port A Set to %2x (Reel C and D)\n", activecpu_get_previouspc(),data));

	Stepper_update(2, (data >> 4) & 0x0F );
	Stepper_update(3, data        & 0x0F );
}

static WRITE8_HANDLER( pia_ic7_portb_w )
{
	int  changed = mmtr_latch ^ data;
	long cycles  = MAME_TIME_TO_CYCLES(0, mame_timer_get_time() );

	mmtr_latch = data;
	if (drive)
	{
		if ( changed & 0x01 )	Mechmtr_update(0, cycles, data & 0x01 );
		if ( changed & 0x02 )	Mechmtr_update(1, cycles, data & 0x02 );
		if ( changed & 0x04 )	Mechmtr_update(2, cycles, data & 0x04 );
		if ( changed & 0x08 )	Mechmtr_update(3, cycles, data & 0x08 );
		if ( changed & 0x10 )	Mechmtr_update(4, cycles, data & 0x10 );
		if ( changed & 0x20 )	Mechmtr_update(5, cycles, data & 0x20 );
		if ( changed & 0x40 )	Mechmtr_update(6, cycles, data & 0x40 );
		if ( changed & 0x80 )	Mechmtr_update(7, cycles, data & 0x80 );
	}

	LOG(("%04x IC7 PIA Port B Set to %2x (Meters, Reel E and F)\n", activecpu_get_previouspc(),data));
//	Stepper_update(4, (data >> 4) & 0x0F );
//	Stepper_update(5, data        & 0x0F );
}

static WRITE8_HANDLER( pia_ic7_ca2_w )
{
	LOG(("%04x IC7 PIA write CA2 %2x (input strobe bit 0 / LED A)\n", activecpu_get_previouspc(),data));

	if ( data ) input_strobe |=  0x01;
	else        input_strobe &= ~0x01;

	output_strobe = input_strobe; // same strobe lines are used for input and output

	IC23GA = data;
}

static WRITE8_HANDLER( pia_ic7_cb2_w )
{
	LOG(("%04x IC7 PIA write CB2 %2x (meter driver PL3)\n", activecpu_get_previouspc(),data));
	drive = data;
}

/*
UNUSED FUNCTION
static READ8_HANDLER( pia_ic7_porta_r )
{
	logerror("%04x IC7 PIA Read of Port A\n",activecpu_get_previouspc());
	return 0;
}

static READ8_HANDLER( pia_ic7_portb_r )
{
	logerror("%04x IC7 PIA Read of Port B\n",activecpu_get_previouspc());
	return 0;
}

static READ8_HANDLER( pia_ic7_cb2_r )
{
	logerror("%04x IC7 PIA read CB2 (meter driver PL3)\n", activecpu_get_previouspc());
	return 0;
}
*/
static const pia6821_interface pia_ic7_intf =
{
	/*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0,
	/*outputs: A/B,CA/B2       */ pia_ic7_porta_w, pia_ic7_portb_w, pia_ic7_ca2_w, pia_ic7_cb2_w,
	/*irqs   : A/B             */ 0,0
};

static READ8_HANDLER( pia_ic8_porta_r )
{
	LOG_IC8(("%04x IC8 PIA Read of Port A (MUX input data)\n",activecpu_get_previouspc()));

	// strobe 
	if (input_strobe & 0x06)
	{
		pia_set_input_cb1(2, (readinputportbytag("AUX2") & 0x80));
	}
	return readinputport(input_strobe);
}

static WRITE8_HANDLER( pia_ic8_portb_w )
{
	LOG_IC8(("%04x IC8 PIA Port B Set to %2x (OUTPUT PORT, TRIACS)\n", activecpu_get_previouspc(),data));
}

static READ8_HANDLER( pia_ic8_ca2_r )
{
	LOG_IC8(("%04x IC8 PIA Read of CA2 (LED Multiplexer 'C')\n",activecpu_get_previouspc()));
	return IC23GC;
}

static WRITE8_HANDLER( pia_ic8_ca2_w )
{
	LOG_IC8(("%04x IC8 PIA write CA2 (input_strobe bit 2 / LED C) %02X\n", activecpu_get_previouspc(), data & 0xFF));

	if ( data ) input_strobe |=  0x04;
	else        input_strobe &= ~0x04;

	output_strobe = input_strobe; // same strobe lines are used for input and output

	IC23GC = data;
}

static READ8_HANDLER( pia_ic8_cb2_r )
{
	LOG_IC8(("%04x IC8 PIA Read of CB2 (Alpha CLK)\n",activecpu_get_previouspc()));
	return alpha_clock;
}

static WRITE8_HANDLER( pia_ic8_cb2_w )
{
	LOG_IC8(("%04x IC8 PIA write CB2 (alpha clock) %02X\n", activecpu_get_previouspc(), data & 0xFF));

	if ( !alpha_clock && (data & 1) )
	{
		vfd_shift_data(0, alpha_data_line&0x01?0:1);
	}
	alpha_clock = data;
}

/*
UNUSED FUNCTION

static WRITE8_HANDLER( pia_ic8_porta_w )
{
	LOG_IC8(("%04x IC8 PIA Port A Set to %2x (MUX'd Inputs)\n", activecpu_get_previouspc(),data));
}

static READ8_HANDLER( pia_ic8_portb_r )
{
	LOG_IC8(("%04x IC8 PIA Read of Port B\n (Triacs)",activecpu_get_previouspc()));
	return 0;
}

static READ8_HANDLER( pia_ic8_ca1_r )
{
	LOG_IC8(("%04x IC8 PIA Read of CA1 (Should be unconnected)\n",activecpu_get_previouspc()));
	return 0;
}


*/
static const pia6821_interface pia_ic8_intf =
{
	/*inputs : A/B,CA/B1,CA/B2 */ pia_ic8_porta_r, 0, 0, 0, pia_ic8_ca2_r, pia_ic8_cb2_r,
	/*outputs: A/B,CA/B2       */ 0, pia_ic8_portb_w, pia_ic8_ca2_w, pia_ic8_cb2_w,
	/*irqs   : A/B             */ 0, 0
};

static WRITE8_HANDLER( pia_gb_porta_w )
{
	LOG(("%04x GAMEBOARD: PIA Port A Set to %2x\n", activecpu_get_previouspc(),data));
}

static WRITE8_HANDLER( pia_gb_portb_w )
{
	int changed = expansion_latch^data;

	LOG(("%04x GAMEBOARD: PIA Port B Set to %2x\n", activecpu_get_previouspc(),data));

	expansion_latch = data;

	if ( changed & 0x20)
	{ // digital volume clock line changed
		if ( !(data & 0x20) )
		{ // changed from high to low,
			if ( !(data & 0x10) )
			{
				if ( global_volume < 31 ) global_volume++; //steps unknown
			}
			else
			{
				if ( global_volume > 0  ) global_volume--;
			}

			{
//				float percent = (32-global_volume)/32.0; //volume_override?1.0:(32-global_volume)/32.0;
//				LOG(("GAMEBOARD: OKI volume %f \n",percent));
//				sndti_set_output_gain(SOUND_OKIM6295,  0, 0, percent);
			}
		}
	}
}

static READ8_HANDLER( pia_gb_porta_r )
{
	LOG(("%04x GAMEBOARD: PIA Read of Port A\n",activecpu_get_previouspc()));
	return 0;
}

static READ8_HANDLER( pia_gb_portb_r )
{
	LOG(("%04x GAMEBOARD: PIA Read of Port B\n",activecpu_get_previouspc()));
	//
	// b7, 1 = OKI ready, 0 = OKI busy
	// b5, vol clock
	// b4, 1 = Vol down, 0 = Vol up
	//

//if (offset == 0x40)
//{
//	return OKIM6295_status_r(0);
//}
	return 0x40;
}

static READ8_HANDLER( pia_gb_ca1_r )
{
	LOG(("%04x GAMEBOARD: PIA Read of Port CA1\n",activecpu_get_previouspc()));

	return 0;
}

static READ8_HANDLER( pia_gb_ca2_r )
{
	LOG(("%04x GAMEBOARD: PIA Read of Port CA2\n",activecpu_get_previouspc()));

	return 0;
}

static READ8_HANDLER( pia_gb_cb1_r )
{
	LOG(("%04x GAMEBOARD: PIA Read of Port CB1\n",activecpu_get_previouspc()));

	return 0;
}

static READ8_HANDLER( pia_gb_cb2_r )
{
	LOG(("%04x GAMEBOARD: PIA Read of Port CB2\n",activecpu_get_previouspc()));

	return 0;
}

static WRITE8_HANDLER( pia_gb_ca2_w )
{
	LOG(("%04x GAMEBOARD: OKI RESET (offset = %d),data = %02X\n", activecpu_get_previouspc(), offset, data&0xFF));
//{
//	return OKIM6295_status_r(0);
//}

}

static WRITE8_HANDLER( pia_onb_w )
{
	LOG(("%04x GAMEBOARD: pia write (offset = %d),data = %02X\n", activecpu_get_previouspc(), offset, data));
}

static READ8_HANDLER( pia_onb_r )
{
	LOG(("%04x GAMEBOARD: pia read  (offset = %d)\n", activecpu_get_previouspc(),offset ));
	return 0;
}

static const pia6821_interface pia_gameboard_intf =
{
	/*inputs : A/B,CA/B1,CA/B2 */ 0, pia_gb_portb_r, 0, 0, 0, 0,
	/*outputs: A/B,CA/B2       */ 0, 0, pia_gb_ca2_w, 0,
	/*irqs   : A/B             */ 0, 0
};

// input ports for MPU4 board ////////////////////////////////////////

INPUT_PORTS_START( mpu4 )

	PORT_START_TAG("IN1A")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("00")
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("01")
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("02")
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("03")
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("04")
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("05")
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("06")
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("07")

	PORT_START_TAG("IN1B")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("08")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("09")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("10")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("11")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("12")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("13")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("14")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("15")

	PORT_START_TAG("IN2A")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("16")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("17")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("18")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("19")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("20")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("21")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("22")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("23")

	PORT_START_TAG("IN2B")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("24")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("25")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("26")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("27")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("28")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("29")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("30")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("31")

	PORT_START_TAG("AUX1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("0")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("5")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("6")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("7")

	PORT_START_TAG("AUX2")
	PORT_DIPNAME( 0x01, 0x00, "10p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x01, "Disabled")
	PORT_DIPNAME( 0x02, 0x00, "20p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x02, "Disabled")
	PORT_DIPNAME( 0x04, 0x00, "50p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x04, "Disabled")
	PORT_DIPNAME( 0x08, 0x00, "100p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x08, "Disabled")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_COIN1) PORT_NAME("10p")PORT_IMPULSE(100)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_COIN2) PORT_NAME("20p")PORT_IMPULSE(100)
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN3) PORT_NAME("50p")PORT_IMPULSE(100)
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_COIN4) PORT_NAME("100p")PORT_IMPULSE(100)

	//2X8 dips
INPUT_PORTS_END

INPUT_PORTS_START( connect4 )

	PORT_START_TAG("IN1A")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("00")
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("01")
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("02")
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("03")
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("04")
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("05")
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("06")
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("07")

	PORT_START_TAG("IN1B")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("08")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("09")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("10")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("11")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("12")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("13")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("14")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("15")

	PORT_START_TAG("IN2A")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("16")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("17")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("18")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("19")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("20")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("21")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Refill Key") PORT_CODE(KEYCODE_R) PORT_TOGGLE
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Software Reset")

	PORT_START_TAG("IN2B")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Select")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("25")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_START2) PORT_NAME("Pass")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START1) PORT_NAME("Play")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("28")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("29")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("30")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Drop")

	PORT_START_TAG("AUX1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("0")
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1")
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2")
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3")
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4")
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("5")
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("6")
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("39")

	PORT_START_TAG("AUX2")
	PORT_DIPNAME( 0x01, 0x00, "10p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x01, "Disabled")
	PORT_DIPNAME( 0x02, 0x00, "20p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x02, "Disabled")
	PORT_DIPNAME( 0x04, 0x00, "50p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x04, "Disabled")
	PORT_DIPNAME( 0x08, 0x00, "100p Enable?" )
	PORT_DIPSETTING(    0x00, "Enabled")
	PORT_DIPSETTING(    0x08, "Disabled")

	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_COIN1) PORT_NAME("10p")PORT_IMPULSE(5)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_COIN2) PORT_NAME("20p")PORT_IMPULSE(5)
	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN3) PORT_NAME("50p")PORT_IMPULSE(5)
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_COIN4) PORT_NAME("100p")PORT_IMPULSE(5)

	//2X8 dips
INPUT_PORTS_END

static MACHINE_START( mpu4 )
{
	pia_config(0, PIA_STANDARD_ORDERING, &pia_ic3_intf);
	pia_config(1, PIA_STANDARD_ORDERING, &pia_ic4_intf);
	pia_config(2, PIA_STANDARD_ORDERING, &pia_ic5_intf);
	pia_config(3, PIA_STANDARD_ORDERING, &pia_ic6_intf);
	pia_config(4, PIA_STANDARD_ORDERING, &pia_ic7_intf);
	pia_config(5, PIA_STANDARD_ORDERING, &pia_ic8_intf);

	pia_config(6, PIA_ALTERNATE_ORDERING, &pia_gameboard_intf);

	pia_reset();

// setup ptm ////////////////////////////////////////////////////////////

	ptm6840_config(0, &ptm_ic2_intf );

// setup 224 lamps //////////////////////////////////////////////////////

	Lamps_init(224);

// setup 8 mechanical meters ////////////////////////////////////////////

	Mechmtr_init(8);

// setup 4 default 96 half step reels ///////////////////////////////////

	Stepper_init(0, STEPPER_48STEP_REEL);
	Stepper_init(1, STEPPER_48STEP_REEL);
	Stepper_init(2, STEPPER_48STEP_REEL);
	Stepper_init(3, STEPPER_48STEP_REEL); 
	// Stepper_init(4, STEPPER_48STEP_REEL);
	// Stepper_init(5, STEPPER_48STEP_REEL);
  
// setup the standard oki MSC1937 display ///////////////////////////////

	vfd_init(0, VFDTYPE_MSC1937,0);

	return 0;
}

static MACHINE_START( mpu4d )
{
	pia_config(0, PIA_STANDARD_ORDERING, &pia_ic3_intf);
	pia_config(1, PIA_STANDARD_ORDERING, &pia_ic4_intf);
	pia_config(2, PIA_STANDARD_ORDERING, &pia_ic5_intf);
	pia_config(3, PIA_STANDARD_ORDERING, &pia_ic6_intf);
	pia_config(4, PIA_STANDARD_ORDERING, &pia_ic7_intf);
	pia_config(5, PIA_STANDARD_ORDERING, &pia_ic8_intf);

	pia_config(6, PIA_ALTERNATE_ORDERING, &pia_gameboard_intf);

	pia_reset();
// setup ptm ////////////////////////////////////////////////////////////

	ptm6840_config(0, &ptm_ic2_intf );

// setup 224 lamps //////////////////////////////////////////////////////

	Lamps_init(224);

// setup 8 mechanical meters ////////////////////////////////////////////

	Mechmtr_init(8);

// setup 4 default 96 half step reels ///////////////////////////////////

	Stepper_init(0, STEPPER_48STEP_REEL);
	Stepper_init(1, STEPPER_48STEP_REEL);
	Stepper_init(2, STEPPER_48STEP_REEL);
	Stepper_init(3, STEPPER_48STEP_REEL); 
	// Stepper_init(4, STEPPER_48STEP_REEL);
	// Stepper_init(5, STEPPER_48STEP_REEL);
  
// setup the standard oki MSC1937 display ///////////////////////////////

	vfd_init(0, VFDTYPE_MSC1937,1);	// does oldtimer use a OKI MSC1937 alpha display controller?

	return 0;
}

/*
Characteriser (CHR)

I haven't been able to work out all the ways of finding the CHR data, but there must be a flag in the ROMs
somewhere to pick it out. As built, the CHR is a PAL which holds an internal data table that is inaccessible to
anything other than the CPU. However, the programmers decided to best use this protection device in read/write/compare
cycles, storing almost the entire 'hidden' data table in the ROMs in plain sight. Only later rebuilds by BwB
avoided this 'feature' of the development kit, and as such, only low level access can defeat their protection.

For most Barcrest games, though, the following can be used:

To calculate the values necessary to program the CHR, we must first find the version string, 
which starts at ff28 and terminates at ff2f for club celebration ff2f then represents the CHR address.
For some reason, the tables always start and end with '00 00'.

From that point on, every word represents a call and response pair, until we have generated 8 8 byte rows of data.

The initial 'PALTEST' routine as found in the Barcrest programs simply writes the first 'call' to the CHR space,
to read back the 'response'. There is no attempt to alter the order or anything else of that matter, just
a simple runthrough of the entire data table. The only 'catch' in this is to note that the CHR chip always scans
through the table starting at the last accessed data value - there are duplications within the table to catch out
the unwary.

However, a final 8 byte row, that controls the lamp matrix is not tested - to date, no-one outside of Barcrest knows
how this is generated, and currently trial and error is the only sensible method. It is noted that the default,
of all 00, is sometimes the correct answer, particularly in non-Barcrest use of the CHR chip.

Despite the potential to radically overhaul the design, the video card version of the chip appears to just be a 
16-bit version of the previous design.It is unclear, however, if it has any capacity to affect lamp matrices in the same
way as before. That said, the 'quiz' games on the board did use an address-scrambling PAL for encryption, and the very
last mod had a characteriser capable of scrambling the ROM address lines. 
*/
static WRITE8_HANDLER( characteriser_w )
{
	int x;
	int call=data;
		LOG_CHR(("Characteriser write offset %02X data %02X\n",offset,data));
		for ( x = prot_col; x < 128; x++ )
		{
			if	((chr_data[(x)] == call) && ((x & 1) == 0))
			{
				prot_col = (x)+1;
				LOG_CHR(("Characteriser find column %02X\n",prot_col));
				break;
			}
		}
}

static READ8_HANDLER( characteriser_r )
{
	LOG_CHR(("Characteriser read offset %02X \n",offset));
	LOG_CHR(("Characteriser read data %02X \n",chr_data[prot_col]));
	return chr_data[prot_col];
}
// generate a 50 Hz signal (based on an RC time) //////////////////////////

static INTERRUPT_GEN( gen_50hz )
{
	signal_50hz = signal_50hz?0:1;

	LOGSTUFF(("50hz generate %x\n",signal_50hz));

//	pia_set_input_ca1(1,signal_50hz);	// signal is connected to IC4 CA1
	pia_set_input_ca1(1,0);	// signal is connected to IC4 CA1
	pia_set_input_ca1(1,1);	// signal is connected to IC4 CA1
}

// memory map for barcrest mpu4 board /////////////////////////////////////

static ADDRESS_MAP_START( memmap_d, ADDRESS_SPACE_PROGRAM, 8 )

	AM_RANGE(0x0000, 0x07ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)

//	AM_RANGE(0x0800, 0x0810) AM_WRITE(characteriser_w)
//	AM_RANGE(0x0800, 0x0810) AM_READ( characteriser_r)
 
	AM_RANGE(0x0850, 0x0850) AM_WRITE(bankswitch_w)	  // write bank (rom page select)

	AM_RANGE(0x0880, 0x0883) AM_WRITE(pia_6_w)	  // PIA6821 on game board
	AM_RANGE(0x0880, 0x0883) AM_READ( pia_6_r)

//	AM_RANGE(0x08C0, 0x08C7) AM_READ( ptm6840_2_r)  // 6840PTM for sound board
//	AM_RANGE(0x08C0, 0x08C7) AM_WRITE(ptm6840_2_w)

//	AM_RANGE(0x08E0, 0x08E7) AM_READ( 68681_duart_r) dataport
//	AM_RANGE(0x08E0, 0x08E7) AM_WRITE( 68681_duart_w)

	AM_RANGE(0x0900, 0x0907) AM_READ( ptm6840_0_r)  // 6840PTM
	AM_RANGE(0x0900, 0x0907) AM_WRITE(ptm6840_0_w)

	AM_RANGE(0x0A00, 0x0A03) AM_WRITE(pia_0_w)	  // PIA6821 IC3
	AM_RANGE(0x0A00, 0x0A03) AM_READ( pia_0_r)

	AM_RANGE(0x0B00, 0x0B03) AM_WRITE(pia_1_w)	  // PIA6821 IC4
	AM_RANGE(0x0B00, 0x0B03) AM_READ( pia_1_r)

	AM_RANGE(0x0C00, 0x0C03) AM_WRITE(pia_2_w)	  // PIA6821 IC5
	AM_RANGE(0x0C00, 0x0C03) AM_READ( pia_2_r)

	AM_RANGE(0x0D00, 0x0D03) AM_WRITE(pia_3_w)	  // PIA6821 IC6
	AM_RANGE(0x0D00, 0x0D03) AM_READ( pia_3_r)

	AM_RANGE(0x0E00, 0x0E03) AM_WRITE(pia_4_w)	  // PIA6821 IC7
	AM_RANGE(0x0E00, 0x0E03) AM_READ( pia_4_r)

	AM_RANGE(0x0F00, 0x0F03) AM_WRITE(pia_5_w)	  // PIA6821 IC8
	AM_RANGE(0x0F00, 0x0F03) AM_READ( pia_5_r)

//	AM_RANGE(0x0000, 0x0fff) AM_ROM				  // 64k ROM
	AM_RANGE(0x1000, 0xffff) AM_READ(MRA8_BANK1)		  // 64k  paged ROM (4 pages)
ADDRESS_MAP_END

static ADDRESS_MAP_START( memmap, ADDRESS_SPACE_PROGRAM, 8 )

	AM_RANGE(0x0000, 0x07ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)

	AM_RANGE(0x0800, 0x0810) AM_WRITE(characteriser_w)
	AM_RANGE(0x0800, 0x0810) AM_READ( characteriser_r)
 
	AM_RANGE(0x0850, 0x0850) AM_WRITE(bankswitch_w)	  // write bank (rom page select)

	AM_RANGE(0x0880, 0x0883) AM_WRITE(pia_6_w)	  // PIA6821 on game board
	AM_RANGE(0x0880, 0x0883) AM_READ( pia_6_r)

//	AM_RANGE(0x08C0, 0x08C7) AM_READ( ptm6840_1_r)  // 6840PTM on game board
//	AM_RANGE(0x08C0, 0x08C7) AM_WRITE(ptm6840_1_w)

//	AM_RANGE(0x08E0, 0x08E7) AM_READ( 68681_duart_r)
//	AM_RANGE(0x08E0, 0x08E7) AM_WRITE( 68681_duart_w)

	AM_RANGE(0x0900, 0x0907) AM_READ( ptm6840_0_r)  // 6840PTM
	AM_RANGE(0x0900, 0x0907) AM_WRITE(ptm6840_0_w)

	AM_RANGE(0x0A00, 0x0A03) AM_WRITE(pia_0_w)	  // PIA6821 IC3
	AM_RANGE(0x0A00, 0x0A03) AM_READ( pia_0_r)

	AM_RANGE(0x0B00, 0x0B03) AM_WRITE(pia_1_w)	  // PIA6821 IC4
	AM_RANGE(0x0B00, 0x0B03) AM_READ( pia_1_r)

	AM_RANGE(0x0C00, 0x0C03) AM_WRITE(pia_2_w)	  // PIA6821 IC5
	AM_RANGE(0x0C00, 0x0C03) AM_READ( pia_2_r)

	AM_RANGE(0x0D00, 0x0D03) AM_WRITE(pia_3_w)	  // PIA6821 IC6
	AM_RANGE(0x0D00, 0x0D03) AM_READ( pia_3_r)

	AM_RANGE(0x0E00, 0x0E03) AM_WRITE(pia_4_w)	  // PIA6821 IC7
	AM_RANGE(0x0E00, 0x0E03) AM_READ( pia_4_r)

	AM_RANGE(0x0F00, 0x0F03) AM_WRITE(pia_5_w)	  // PIA6821 IC8
	AM_RANGE(0x0F00, 0x0F03) AM_READ( pia_5_r)

//	AM_RANGE(0x0000, 0x0fff) AM_ROM				  // 64k ROM
	AM_RANGE(0x1000, 0xffff) AM_READ(MRA8_BANK1)		  // 64k  paged ROM (4 pages)

ADDRESS_MAP_END

// machine driver for barcrest mpu4 board /////////////////////////////////

static MACHINE_DRIVER_START( mpu4 )

	MDRV_MACHINE_START(mpu4)							// main mpu4 board initialisation
	MDRV_MACHINE_RESET(mpu4)
	MDRV_CPU_ADD_TAG("main", M6809, 6880000/4 )			// 6809 CPU
	MDRV_CPU_PROGRAM_MAP(memmap,0)						// setup read and write memorymap

	MDRV_CPU_PERIODIC_INT(gen_50hz, TIME_IN_HZ(50) )	// generate 50 hz signal

	MDRV_SPEAKER_STANDARD_MONO("mono")
	MDRV_SOUND_ADD(AY8910, 6880000/4)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)

	MDRV_NVRAM_HANDLER(generic_0fill)					// load/save nv RAM
	MDRV_DEFAULT_LAYOUT(layout_mpu4)
	/* video hardware */
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_SIZE(288, 34)
	MDRV_VISIBLE_AREA(0, 288-1, 0, 34-1)
	MDRV_FRAMES_PER_SECOND(50)
	MDRV_VIDEO_START( mpu4)
	MDRV_VIDEO_UPDATE(mpu4)

	MDRV_PALETTE_LENGTH(16)
	MDRV_COLORTABLE_LENGTH(16)
	MDRV_PALETTE_INIT(mpu4)

MACHINE_DRIVER_END

static MACHINE_DRIVER_START( mpu4d )

	MDRV_MACHINE_START(mpu4d)							// main mpu4 board initialisation
	MDRV_MACHINE_RESET(mpu4)
	MDRV_CPU_ADD_TAG("main", M6809, 6880000/4 )			// 6809 CPU
	MDRV_CPU_PROGRAM_MAP(memmap_d,0)		  			// setup read and write memorymap

	MDRV_CPU_PERIODIC_INT(gen_50hz, TIME_IN_HZ(50) )	// generate 50 hz signal

	MDRV_SPEAKER_STANDARD_MONO("mono")
	MDRV_SOUND_ADD(AY8910, 6880000/4)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)

	MDRV_NVRAM_HANDLER(generic_0fill)					// load/save nv RAM
	MDRV_DEFAULT_LAYOUT(layout_mpu4)
	/* video hardware */
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_SIZE(288, 34)
	MDRV_VISIBLE_AREA(0, 288-1, 0, 34-1)
	MDRV_FRAMES_PER_SECOND(50)
	MDRV_VIDEO_START( mpu4)
	MDRV_VIDEO_UPDATE(mpu4)

	MDRV_PALETTE_LENGTH(16)
	MDRV_COLORTABLE_LENGTH(16)
	MDRV_PALETTE_INIT(mpu4)

MACHINE_DRIVER_END

DRIVER_INIT (ccelbrtn)
{
	int x;
	UINT8 *rom;
	rom = memory_region(REGION_CPU1);
	for ( x = 0; x < 128; x++ )
	{
		chr_data[x] = rom[(0xff30)+(x)];
		LOG_CHR(("%02X",chr_data[x]));
	}
}

ROM_START( oldtimer )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )	/* 64k for code */
	ROM_LOAD( "dot11.bin",  0x0000, 0x10000,  CRC(da095666) )
ROM_END

ROM_START( ccelbrtn )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )	/* 64k for code */
	ROM_LOAD( "cels.p1",  0x0000, 0x10000,  CRC(19d2162f) )
ROM_END

ROM_START( connect4 )
	ROM_REGION( 0x10000, REGION_CPU1, ROMREGION_ERASE00  )	/* 64k for code */
	ROM_LOAD( "connect4.p2",  0x8000, 0x4000,  CRC(6090633c) )
	ROM_LOAD( "connect4.p1",  0xC000, 0x4000,  CRC(b1af50c0) )
ROM_END

GAME( 198?, oldtimer,0,       mpu4d,    mpu4,    	0,	  0,     "Barcrest", 			"Old Timer",        GAME_NOT_WORKING|GAME_NO_SOUND )
GAME( 198?, ccelbrtn,0,       mpu4,     mpu4,    ccelbrtn,0,     "Barcrest", 			"Club Celebration", GAME_NOT_WORKING|GAME_IMPERFECT_SOUND )
GAME( 198?, connect4,0,		  mpu4,     connect4,   0,	  0,     "Dolbeck Systems", 	"Connect 4", 		GAME_NOT_WORKING|GAME_IMPERFECT_SOUND )
