summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/jackie.cpp
blob: 199fa905b2bc201791597a8a0fda2ce63144f27f (plain) (tree)
1
2
3
4
5
6
7
8
                       
                                                 
  



                                           
  






































                                      
                
                        
                          
                          
                         

                    
 
 


                                         
                                                                                      
                                                    
                                           


                                                





                                                    
                                                         
 
                                              



                                                      






                                                    
 
                       
                                
                                   
                                   
                                   



                         

                                 
 


                                           










                                               


                                            
 

                                                               
                        
 
                                              
 
                                               


                                                  
 
                           


                                              
 
                                                                                                       
                                          
                                            

                                              



  
 
                                                    
 
                                                                                 
                                 
                                                                                        

 
                                      
 
                                     
                                              

 
                                       
 
                                      
                                              

 

 
 
                                        
 
                                   

 
 
                                        
 
                                   
                                                 

 
                                                       
 
                                           
                                            


 
 
                                        
 
                                   
                                                 

 
                                                       
 
                                           
                                            

 
 
                                        
 
                                   
                                                 

 
                                                       
 
                                           
                                            

 
                                
 


                                                                                                                                                                           
 


                                             
 
                                                                                                                                                                          
                                             

 
 
                                                                                                            
 

                             
                                                         
 
                                                      
 

                              


                                                                      




                                   
                                                

                                        
                                                                                     


                                 
                                                                         


                                      
                                                                         


                                      
                                                                         







                                      
                                                           



                 









                                                     
 
                                  
 



                              

 
 






                                                                                                                 
                                                                                               
          


      
                                                                    
 


                                         

 


                                                                              
 
                                                                    
 


                                            

 


                                                                              
 
                                            
 



                                                                                           
 
                                                                                                
 
                                                                         
                                                      
 

                        

 
                                    











                          





                                                                                
 
                                              
 

                        

 
                                        
 
                         


                 
                                         
 
                                             

                        

 
                                    
 
                                                 
 
                                      
                                                                          
                           


 


































                                                                                                                
 
                                           
 
                                                            
                                                         


                                  





































































                                                                                      
                             
                                                                                              
                                                                                                                                                        
                                                          
                                                                                   
                                                                                




                                                    
                                                                             

                                                                                                       


                                                    



                                                                                         




                                                    
                                     
                                                   

                                                                                                         

                                                                                                     
                                                                                                        
                                                   








                                          

                                                  










                                          

                                                  




                          
                                    
                                                          
                                                          

             
                                
 
                                                    
 
                                        






                                                                                                 
                                        



                           
 
                                               
 




                                

                                                        
                                                      
                                                                            
 
 
                                          

                                    


                                                             
                                                                                      
 
                                                     
                                                                             




                                                     
                                                                     

                            


                                                       

                                                        
                                                              
                                      
 
                                                                      

                                             

                            
                                               
                                                 
                                                  
 
                  

 
                   
                                           

                                                                                                                     
                                        



                                                                                                           
                                        













                                                                                                                      
 
                                                                                                                              
// license:BSD-3-Clause
// copyright-holders:David Haywood, Mirko Buffoni
/*
Happy Jackie (c) 1993 IGS.
Video Slot machine game for amusement only.

Driver by David Haywood and Mirko Buffoni
*/
/*

Anno    199x
Produttore  IGS
N.revisione

CPU

1x Z0840006PSC (main)
2x D8255AC
1x unknown AMT001
1x unknown IGS002
1x UM3567 (sound)
1x oscillator 12.000MHz
1x oscillator 3.579645

ROMs

2x D27128A (1,3)
1x MBM27128 (2)
3x 27C010 (4,5,6)
1x D27512 (7sv)
1x MBM27C512 (v110)
1x unknown (DIP20 mil300)(jack3)
3x PEEL18CV8PC (read protected)
1x TIBPAL16L8 (read protected)

Note

1x 36x2 edge connector
1x 10x2 edge connector (payout system)
1x trimmer (volume)
1x pushbutton
1x battery
5x 8x2 switches dip

*/


#include "emu.h"
#include "cpu/z80/z80.h"
#include "machine/i8255.h"
#include "machine/timer.h"
#include "sound/ym2413.h"
#include "screen.h"
#include "speaker.h"


class jackie_state : public driver_device
{
public:
	jackie_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this,"maincpu"),
		m_gfxdecode(*this, "gfxdecode"),
		m_screen(*this, "screen"),
		m_palette(*this, "palette"),
		m_bg_scroll2(*this, "bg_scroll2"),
		m_bg_scroll(*this, "bg_scroll"),
		m_reel1_ram(*this, "reel1_ram"),
		m_reel2_ram(*this, "reel2_ram"),
		m_reel3_ram(*this, "reel3_ram"),
		m_fg_tile_ram(*this, "fg_tile_ram"),
		m_fg_color_ram(*this, "fg_color_ram") { }

	required_device<cpu_device> m_maincpu;
	required_device<gfxdecode_device> m_gfxdecode;
	required_device<screen_device> m_screen;
	required_device<palette_device> m_palette;

	required_shared_ptr<uint8_t> m_bg_scroll2;
	required_shared_ptr<uint8_t> m_bg_scroll;
	required_shared_ptr<uint8_t> m_reel1_ram;
	required_shared_ptr<uint8_t> m_reel2_ram;
	required_shared_ptr<uint8_t> m_reel3_ram;
	required_shared_ptr<uint8_t> m_fg_tile_ram;
	required_shared_ptr<uint8_t> m_fg_color_ram;

	int m_exp_bank;
	tilemap_t *m_fg_tilemap;
	tilemap_t *m_reel1_tilemap;
	tilemap_t *m_reel2_tilemap;
	tilemap_t *m_reel3_tilemap;
	int m_irq_enable;
	int m_nmi_enable;
	int m_bg_enable;
	int m_hopper;
	uint8_t m_out[3];
	uint16_t m_unk_reg[3][5];

	DECLARE_WRITE8_MEMBER(fg_tile_w);
	DECLARE_WRITE8_MEMBER(fg_color_w);
	DECLARE_WRITE8_MEMBER(bg_scroll_w);
	DECLARE_WRITE8_MEMBER(reel1_ram_w);
	DECLARE_WRITE8_MEMBER(reel2_ram_w);
	DECLARE_WRITE8_MEMBER(reel3_ram_w);
	DECLARE_WRITE8_MEMBER(unk_reg1_lo_w);
	DECLARE_WRITE8_MEMBER(unk_reg2_lo_w);
	DECLARE_WRITE8_MEMBER(unk_reg3_lo_w);
	DECLARE_WRITE8_MEMBER(unk_reg1_hi_w);
	DECLARE_WRITE8_MEMBER(unk_reg2_hi_w);
	DECLARE_WRITE8_MEMBER(unk_reg3_hi_w);
	DECLARE_WRITE8_MEMBER(nmi_and_coins_w);
	DECLARE_WRITE8_MEMBER(lamps_w);
	DECLARE_READ8_MEMBER(igs_irqack_r);
	DECLARE_WRITE8_MEMBER(igs_irqack_w);
	DECLARE_READ8_MEMBER(expram_r);

	void unk_reg_lo_w( int offset, uint8_t data, int reg );
	void unk_reg_hi_w( int offset, uint8_t data, int reg );
	void show_out();

	DECLARE_CUSTOM_INPUT_MEMBER(hopper_r);

	TILE_GET_INFO_MEMBER(get_fg_tile_info);
	TILE_GET_INFO_MEMBER(get_reel1_tile_info);
	TILE_GET_INFO_MEMBER(get_reel2_tile_info);
	TILE_GET_INFO_MEMBER(get_reel3_tile_info);

	void init_jackie();
	virtual void machine_start() override;
	virtual void machine_reset() override;
	virtual void video_start() override;

	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
	TIMER_DEVICE_CALLBACK_MEMBER(irq);
	void jackie(machine_config &config);
	void jackie_io_map(address_map &map);
	void jackie_prg_map(address_map &map);
};




TILE_GET_INFO_MEMBER(jackie_state::get_fg_tile_info)
{
	int code = m_fg_tile_ram[tile_index] | (m_fg_color_ram[tile_index] << 8);
	int tile = code & 0x1fff;
	SET_TILE_INFO_MEMBER(0, code, tile != 0x1fff ? ((code >> 12) & 0xe) + 1 : 0, 0);
}

WRITE8_MEMBER(jackie_state::fg_tile_w)
{
	m_fg_tile_ram[offset] = data;
	m_fg_tilemap->mark_tile_dirty(offset);
}

WRITE8_MEMBER(jackie_state::fg_color_w)
{
	m_fg_color_ram[offset] = data;
	m_fg_tilemap->mark_tile_dirty(offset);
}




WRITE8_MEMBER(jackie_state::bg_scroll_w)
{
	m_bg_scroll[offset] = data;
}


WRITE8_MEMBER(jackie_state::reel1_ram_w)
{
	m_reel1_ram[offset] = data;
	m_reel1_tilemap->mark_tile_dirty(offset);
}

TILE_GET_INFO_MEMBER(jackie_state::get_reel1_tile_info)
{
	int code = m_reel1_ram[tile_index];
	SET_TILE_INFO_MEMBER(1, code, 0, 0);
}



WRITE8_MEMBER(jackie_state::reel2_ram_w)
{
	m_reel2_ram[offset] = data;
	m_reel2_tilemap->mark_tile_dirty(offset);
}

TILE_GET_INFO_MEMBER(jackie_state::get_reel2_tile_info)
{
	int code = m_reel2_ram[tile_index];
	SET_TILE_INFO_MEMBER(1, code, 0, 0);
}


WRITE8_MEMBER(jackie_state::reel3_ram_w)
{
	m_reel3_ram[offset] = data;
	m_reel3_tilemap->mark_tile_dirty(offset);
}

TILE_GET_INFO_MEMBER(jackie_state::get_reel3_tile_info)
{
	int code = m_reel3_ram[tile_index];
	SET_TILE_INFO_MEMBER(1, code, 0, 0);
}

void jackie_state::video_start()
{
	m_reel1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(jackie_state::get_reel1_tile_info),this),TILEMAP_SCAN_ROWS,8,32, 64, 8);
	m_reel2_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(jackie_state::get_reel2_tile_info),this),TILEMAP_SCAN_ROWS,8,32, 64, 8);
	m_reel3_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(jackie_state::get_reel3_tile_info),this),TILEMAP_SCAN_ROWS,8,32, 64, 8);

	m_reel1_tilemap->set_scroll_cols(64);
	m_reel2_tilemap->set_scroll_cols(64);
	m_reel3_tilemap->set_scroll_cols(64);

	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(jackie_state::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8,  8,  64, 32);
	m_fg_tilemap->set_transparent_pen(0);
}


uint32_t jackie_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int i,j;
	int startclipmin = 0;
	const rectangle &visarea = screen.visible_area();

	bitmap.fill(m_palette->black_pen(), cliprect);

	for (i=0;i < 0x40;i++)
	{
		m_reel1_tilemap->set_scrolly(i, m_bg_scroll[i+0x000]);
		m_reel2_tilemap->set_scrolly(i, m_bg_scroll[i+0x040]);
		m_reel3_tilemap->set_scrolly(i, m_bg_scroll[i+0x080]);
	}

	for (j=0; j < 0x100-1; j++)
	{
		rectangle clip;
		int rowenable = m_bg_scroll2[j];

		/* draw top of screen */
		clip.set(visarea.min_x, visarea.max_x, startclipmin, startclipmin+1);

		if (rowenable==0)
		{
			m_reel1_tilemap->draw(screen, bitmap, clip, 0,0);
		}
		else if (rowenable==1)
		{
			m_reel2_tilemap->draw(screen, bitmap, clip, 0,0);
		}
		else if (rowenable==2)
		{
			m_reel3_tilemap->draw(screen, bitmap, clip, 0,0);
		}
		else if (rowenable==3)
		{
		}

		startclipmin+=1;
	}

	m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);

	return 0;
}

void jackie_state::machine_start()
{
	save_item(NAME(m_exp_bank));
	// save_item(NAME(m_irq_enable)); //always 1?
	save_item(NAME(m_nmi_enable));
	// save_item(NAME(m_bg_enable)); //always 1?
	save_item(NAME(m_hopper));
	save_item(NAME(m_out));
	save_item(NAME(m_unk_reg));
}

void jackie_state::machine_reset()
{
	m_irq_enable    =   1;
	m_nmi_enable    =   0;
	m_hopper        =   0;
	m_bg_enable =   1;
}


void jackie_state::show_out()
{
#ifdef MAME_DEBUG
//  popmessage("%02x %02x %02x", m_out[0], m_out[1], m_out[2]);
	popmessage("520: %04x %04x %04x %04x %04x\n560: %04x %04x %04x %04x %04x\n5A0: %04x %04x %04x %04x %04x",
		m_unk_reg[0][0],m_unk_reg[0][1],m_unk_reg[0][2],m_unk_reg[0][3],m_unk_reg[0][4],
		m_unk_reg[1][0],m_unk_reg[1][1],m_unk_reg[1][2],m_unk_reg[1][3],m_unk_reg[1][4],
		m_unk_reg[2][0],m_unk_reg[2][1],m_unk_reg[2][2],m_unk_reg[2][3],m_unk_reg[2][4]
	);
#endif
}

void jackie_state::unk_reg_lo_w( int offset, uint8_t data, int reg )
{
	m_unk_reg[reg][offset] &= 0xff00;
	m_unk_reg[reg][offset] |= data;
	show_out();
}

WRITE8_MEMBER(jackie_state::unk_reg1_lo_w){ unk_reg_lo_w( offset, data, 0 ); }
WRITE8_MEMBER(jackie_state::unk_reg2_lo_w){ unk_reg_lo_w( offset, data, 1 ); }
WRITE8_MEMBER(jackie_state::unk_reg3_lo_w){ unk_reg_lo_w( offset, data, 2 ); }

void jackie_state::unk_reg_hi_w( int offset, uint8_t data, int reg )
{
	m_unk_reg[reg][offset] &= 0xff;
	m_unk_reg[reg][offset] |= data << 8;
	show_out();
}

WRITE8_MEMBER(jackie_state::unk_reg1_hi_w){ unk_reg_hi_w( offset, data, 0 ); }
WRITE8_MEMBER(jackie_state::unk_reg2_hi_w){ unk_reg_hi_w( offset, data, 1 ); }
WRITE8_MEMBER(jackie_state::unk_reg3_hi_w){ unk_reg_hi_w( offset, data, 2 ); }

WRITE8_MEMBER(jackie_state::nmi_and_coins_w)
{
	machine().bookkeeping().coin_counter_w(0,        data & 0x01);   // coin_a
	machine().bookkeeping().coin_counter_w(1,        data & 0x04);   // coin_c
	machine().bookkeeping().coin_counter_w(2,        data & 0x08);   // key in
	machine().bookkeeping().coin_counter_w(3,        data & 0x10);   // coin m_out mech

	output().set_led_value(6,        data & 0x20);   // led for coin m_out / m_hopper active

	m_exp_bank   = (data & 0x02) ? 1 : 0;       // expram bank number
	m_nmi_enable = data & 0x80;     // nmi enable?

	m_out[0] = data;
	show_out();
}

WRITE8_MEMBER(jackie_state::lamps_w)
{
/*
    - Lbits -
    7654 3210
    =========
    ---- --x-  Hold1 lamp.
    --x- ----  Hold2 lamp.
    ---x ----  Hold3 lamp.
    ---- x---  Hold4 lamp.
    ---- -x--  Hold5 lamp.
    ---- ---x  Start lamp.
*/
	output().set_lamp_value(1, (data >> 1) & 1);      /* Lamp 1 - HOLD 1 */
	output().set_lamp_value(2, (data >> 5) & 1);      /* Lamp 2 - HOLD 2  */
	output().set_lamp_value(3, (data >> 4) & 1);      /* Lamp 3 - HOLD 3 */
	output().set_lamp_value(4, (data >> 3) & 1);      /* Lamp 4 - HOLD 4 */
	output().set_lamp_value(5, (data >> 2) & 1);      /* Lamp 5 - HOLD 5 */
	output().set_lamp_value(6, (data & 1));           /* Lamp 6 - START */

	m_hopper            =   (~data)& 0x80;

	m_out[1] = data;
	show_out();
}

READ8_MEMBER(jackie_state::igs_irqack_r)
{
	m_irq_enable = 1;
	return 0;
}

WRITE8_MEMBER(jackie_state::igs_irqack_w)
{
//  m_maincpu->set_input_line(0, CLEAR_LINE);
	m_out[2] = data;
	show_out();
}

READ8_MEMBER(jackie_state::expram_r)
{
	uint8_t *rom = memregion("gfx3")->base();

	offset += m_exp_bank * 0x8000;
//  logerror("PC %06X: %04x = %02x\n",m_maincpu->pc(),offset,rom[offset]);
	return rom[offset];
}


void jackie_state::jackie_prg_map(address_map &map)
{
	map(0x0000, 0xefff).rom();
	map(0xf000, 0xffff).ram().region("maincpu", 0xf000);
}

void jackie_state::jackie_io_map(address_map &map)
{
	map(0x0520, 0x0524).w(this, FUNC(jackie_state::unk_reg1_lo_w));
	map(0x0d20, 0x0d24).w(this, FUNC(jackie_state::unk_reg1_hi_w));
	map(0x0560, 0x0564).w(this, FUNC(jackie_state::unk_reg2_lo_w));
	map(0x0d60, 0x0d64).w(this, FUNC(jackie_state::unk_reg2_hi_w));
	map(0x05a0, 0x05a4).w(this, FUNC(jackie_state::unk_reg3_lo_w));
	map(0x0da0, 0x0da4).w(this, FUNC(jackie_state::unk_reg3_hi_w));
	map(0x1000, 0x1107).ram().share("bg_scroll2");
	map(0x2000, 0x27ff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
	map(0x2800, 0x2fff).ram().w(m_palette, FUNC(palette_device::write8_ext)).share("palette_ext");
	map(0x4000, 0x4000).portr("DSW1");           /* DSW1 */
	map(0x4001, 0x4001).portr("DSW2");           /* DSW2 */
	map(0x4002, 0x4002).portr("DSW3");           /* DSW3 */
	map(0x4003, 0x4003).portr("DSW4");           /* DSW4 */
	map(0x4004, 0x4004).portr("DSW5");           /* DSW5 */
	map(0x5080, 0x5083).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x5090, 0x5093).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x50a0, 0x50a0).portr("BUTTONS2");
	map(0x50b0, 0x50b1).w("ymsnd", FUNC(ym2413_device::write));
	map(0x50c0, 0x50c0).r(this, FUNC(jackie_state::igs_irqack_r)).w(this, FUNC(jackie_state::igs_irqack_w));
	map(0x6000, 0x60ff).ram().w(this, FUNC(jackie_state::bg_scroll_w)).share("bg_scroll");
	map(0x6800, 0x69ff).ram().w(this, FUNC(jackie_state::reel1_ram_w)).share("reel1_ram");
	map(0x6a00, 0x6bff).ram().w(this, FUNC(jackie_state::reel2_ram_w)).share("reel2_ram");
	map(0x6c00, 0x6dff).ram().w(this, FUNC(jackie_state::reel3_ram_w)).share("reel3_ram");
	map(0x7000, 0x77ff).ram().w(this, FUNC(jackie_state::fg_tile_w)).share("fg_tile_ram");
	map(0x7800, 0x7fff).ram().w(this, FUNC(jackie_state::fg_color_w)).share("fg_color_ram");
	map(0x8000, 0xffff).r(this, FUNC(jackie_state::expram_r));
}

CUSTOM_INPUT_MEMBER(jackie_state::hopper_r)
{
	if (m_hopper) return !(m_screen->frame_number()%10);
	return machine().input().code_pressed(KEYCODE_H);
}

static INPUT_PORTS_START( jackie )
	PORT_START("DSW1")
	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SWA:8")
	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPUNKNOWN( 0x02, 0x02 )
	PORT_DIPUNKNOWN( 0x04, 0x04 )
	PORT_DIPUNKNOWN( 0x08, 0x08 )
	PORT_DIPUNKNOWN( 0x10, 0x10 )
	PORT_DIPUNKNOWN( 0x20, 0x20 )
	PORT_DIPUNKNOWN( 0x40, 0x40 )
	PORT_DIPUNKNOWN( 0x80, 0x80 )

	PORT_START("DSW2")
	PORT_DIPNAME( 0x0f, 0x07, "Main Game Chance" ) PORT_DIPLOCATION("SWB:8,7,6,5")
	PORT_DIPSETTING(    0x0f, "45%" )
	PORT_DIPSETTING(    0x0e, "50%" )
	PORT_DIPSETTING(    0x0d, "55%" )
	PORT_DIPSETTING(    0x0c, "60%" )
	PORT_DIPSETTING(    0x0b, "65%" )
	PORT_DIPSETTING(    0x0a, "70%" )
	PORT_DIPSETTING(    0x09, "75%" )
	PORT_DIPSETTING(    0x08, "80%" )
	PORT_DIPSETTING(    0x07, "83%" )
	PORT_DIPSETTING(    0x06, "85%" )
	PORT_DIPSETTING(    0x05, "88%" )
	PORT_DIPSETTING(    0x04, "90%" )
	PORT_DIPSETTING(    0x03, "92%" )
	PORT_DIPSETTING(    0x02, "94%" )
	PORT_DIPSETTING(    0x01, "96%" )
	PORT_DIPSETTING(    0x00, "98%" )
	PORT_DIPUNKNOWN( 0x10, 0x10 )
	PORT_DIPNAME( 0x20, 0x00, "Double Up Rate" ) PORT_DIPLOCATION("SWB:3")
	PORT_DIPSETTING(    0x20, DEF_STR( Hard ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Easy ) )
	PORT_DIPUNKNOWN( 0x40, 0x40 )
	PORT_DIPUNKNOWN( 0x80, 0x80 )

	PORT_START("DSW3")
	PORT_DIPUNKNOWN( 0x01, 0x01 )
	PORT_DIPUNKNOWN( 0x02, 0x02 )
	PORT_DIPUNKNOWN( 0x04, 0x04 )
	PORT_DIPUNKNOWN( 0x08, 0x08 )
	PORT_DIPUNKNOWN( 0x10, 0x10 )
	PORT_DIPUNKNOWN( 0x20, 0x20 )
	PORT_DIPNAME( 0xC0, 0x00, "Max Bet" ) PORT_DIPLOCATION("SWC:2,1")
	PORT_DIPSETTING(    0xC0, "1" )
	PORT_DIPSETTING(    0x80, "8" )
	PORT_DIPSETTING(    0x40, "16" )
	PORT_DIPSETTING(    0x00, "32" )

	PORT_START("DSW4")
	PORT_DIPUNKNOWN( 0x01, 0x01 )
	PORT_DIPUNKNOWN( 0x02, 0x02 )
	PORT_DIPUNKNOWN( 0x04, 0x04 )
	PORT_DIPUNKNOWN( 0x08, 0x08 )
	PORT_DIPUNKNOWN( 0x10, 0x10 )
	PORT_DIPUNKNOWN( 0x20, 0x20 )
	PORT_DIPUNKNOWN( 0x40, 0x40 )
	PORT_DIPUNKNOWN( 0x80, 0x80 )

	PORT_START("DSW5")
	PORT_DIPUNKNOWN( 0x01, 0x01 )
	PORT_DIPUNKNOWN( 0x02, 0x02 )
	PORT_DIPUNKNOWN( 0x04, 0x04 )
	PORT_DIPUNKNOWN( 0x08, 0x08 )
	PORT_DIPUNKNOWN( 0x10, 0x10 )
	PORT_DIPUNKNOWN( 0x20, 0x20 )
	PORT_DIPUNKNOWN( 0x40, 0x40 )
	PORT_DIPUNKNOWN( 0x80, 0x80 )

	PORT_START("SERVICE")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_9) PORT_NAME("Attendent")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF,jackie_state,hopper_r, nullptr) PORT_NAME("HPSW")    // hopper sensor
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
	PORT_SERVICE_NO_TOGGLE( 0x20, IP_ACTIVE_LOW )   // test (press during boot)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Statistics")

	PORT_START("COINS")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_NAME("Key In")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Clear")   // pays out
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_T) PORT_NAME("Togglemode") // Used
	PORT_BIT( 0xC0, IP_ACTIVE_HIGH, IPT_UNUSED )

	PORT_START("BUTTONS1")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SLOT_STOP1 )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SLOT_STOP2 )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SLOT_STOP3 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_V) PORT_NAME("Stop")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START("BUTTONS2")  // OK
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_D) PORT_NAME("Small / Right Hammer")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_A) PORT_NAME("Take/Left Hammer")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_3) PORT_NAME("W-Up")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S) PORT_NAME("Big / Center Hammer")
	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END


static const gfx_layout layout_8x8x6 =
{
	8, 8,
	RGN_FRAC(1, 3),
	6,
	{ RGN_FRAC(0,3)+8,RGN_FRAC(0,3)+0,
		RGN_FRAC(1,3)+8,RGN_FRAC(1,3)+0,
		RGN_FRAC(2,3)+8,RGN_FRAC(2,3)+0 },
	{ STEP8(0,1) },
	{ STEP8(0,2*8) },
	8*8*2
};

static const gfx_layout layout_8x32x6 =
{
	8, 32,
	RGN_FRAC(1, 3),
	6,
	{ RGN_FRAC(0,3)+8,RGN_FRAC(0,3)+0,
		RGN_FRAC(1,3)+8,RGN_FRAC(1,3)+0,
		RGN_FRAC(2,3)+8,RGN_FRAC(2,3)+0 },
	{ STEP8(0,1) },
	{ STEP32(0,2*8) },
	8*32*2
};

static GFXDECODE_START( gfx_jackie )
	GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x6,  0, 16 )
	GFXDECODE_ENTRY( "gfx2", 0, layout_8x32x6, 0, 16 )
GFXDECODE_END

void jackie_state::init_jackie()
{
	uint8_t *rom = memregion("maincpu")->base();

	for (int A = 0; A < 0xf000; A++)
	{
		rom[A] = rom[A] ^ 0x21;

		if (((A & 0x0080) == 0x0000) && ((A & 0x0008) == 0x0000)) rom[A] = rom[A] ^ 0x20;
		if ((A & 0x0282) == 0x0282) rom[A] ^= 0x01;
		if ((A & 0x0940) == 0x0940) rom[A] ^= 0x02;
	}
	memset(&rom[0xf000], 0, 0x1000);

	// Patch trap
	rom[0x7e86] = 0xc3;
}

TIMER_DEVICE_CALLBACK_MEMBER(jackie_state::irq)
{
	int scanline = param;

	if((scanline % 32) != 0)
		return;

	if((scanline % 64) == 32 && m_irq_enable)
		m_maincpu->set_input_line(0, HOLD_LINE);
	else if ((scanline % 64) == 0 && m_nmi_enable)
		m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}

MACHINE_CONFIG_START(jackie_state::jackie)

	/* basic machine hardware */
	MCFG_DEVICE_ADD("maincpu", Z80, XTAL(12'000'000) / 2)
	MCFG_DEVICE_PROGRAM_MAP(jackie_prg_map)
	MCFG_DEVICE_IO_MAP(jackie_io_map)
	MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", jackie_state, irq, "screen", 0, 1)

	MCFG_DEVICE_ADD("ppi1", I8255A, 0) // D8255AC
	MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, jackie_state, nmi_and_coins_w))
	MCFG_I8255_IN_PORTB_CB(IOPORT("SERVICE"))
	MCFG_I8255_IN_PORTC_CB(IOPORT("COINS"))

	MCFG_DEVICE_ADD("ppi2", I8255A, 0) // D8255AC
	MCFG_I8255_IN_PORTA_CB(IOPORT("BUTTONS1"))
	MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, jackie_state, lamps_w))

	/* video hardware */
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_REFRESH_RATE(57)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
	MCFG_SCREEN_SIZE(64*8, 32*8)
	MCFG_SCREEN_VISIBLE_AREA(0*8, 64*8-1, 0, 32*8-1)
	MCFG_SCREEN_UPDATE_DRIVER(jackie_state, screen_update)
	MCFG_SCREEN_PALETTE("palette")

	MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_jackie)
	MCFG_PALETTE_ADD("palette", 2048)
	MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)

	/* sound hardware */
	SPEAKER(config, "mono").front_center();
	MCFG_DEVICE_ADD("ymsnd", YM2413, 3579545)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)

MACHINE_CONFIG_END


ROM_START( jackie )
	ROM_REGION( 0x10000, "maincpu", 0 )
	ROM_LOAD( "jackiev110.u23",   0x0000, 0x10000, CRC(1b78a619) SHA1(a6eb6b6e544efa55225f2e947483614afb6ece3b) )

	ROM_REGION( 0x60000, "gfx1", 0 )
	ROM_LOAD( "6.u6",  0x00000, 0x20000, CRC(d2ed60a9) SHA1(40e2280384aa5c9e72e87a3b9e673172ff695676) )
	ROM_LOAD( "5.u5",  0x20000, 0x20000, CRC(dc01fe7c) SHA1(683834ce2f13a923c0467209b93fef693d9c3e38) )
	ROM_LOAD( "4.u4",  0x40000, 0x20000, CRC(38a42dcd) SHA1(8cc08ff4143281d9022210d6577146d725df9044) )

	ROM_REGION( 0x30000, "gfx2", 0 )
	ROM_LOAD( "3.u3",  0x00000, 0x4000, CRC(c69e962b) SHA1(492427ad1ac959cdf22d23439e0eb5932b60ec88) )
	ROM_LOAD( "2.u2",  0x10000, 0x4000, CRC(8900ffba) SHA1(065cf1810ec9738718e4c94613f726e85ba4314d) )
	ROM_LOAD( "1.u1",  0x20000, 0x4000, CRC(071d20f0) SHA1(77c87486803dccaa63732ff959c223b1313820e3) )

	ROM_REGION( 0x10000, "gfx3", 0 )
	ROM_LOAD( "jackie7sv.u22",   0x0000, 0x10000, CRC(8b4eb6da) SHA1(480784917dfaf9a0343c1d56eb590b32bf5e94fd) )

	ROM_REGION( 0x10000, "misc", 0 )
	ROM_LOAD( "16l8.u31",   0x0000, 0x104, BAD_DUMP CRC(e9cd78fb) SHA1(557d3e7ef3b25c1338b24722cac91bca788c02b8) )
	ROM_LOAD( "18cv8.u14",  0x0000, 0x155, BAD_DUMP CRC(996e8f59) SHA1(630d9b91f6e8eda781061e2a8ff6fb0fecaf034c) )
	ROM_LOAD( "18cv8.u8",   0x0000, 0x155, BAD_DUMP CRC(996e8f59) SHA1(630d9b91f6e8eda781061e2a8ff6fb0fecaf034c) )
	ROM_LOAD( "18cv8.u9",   0x0000, 0x155, BAD_DUMP CRC(996e8f59) SHA1(630d9b91f6e8eda781061e2a8ff6fb0fecaf034c) )
ROM_END


GAME( 1993, jackie, 0, jackie, jackie, jackie_state, init_jackie, ROT0, "IGS", "Happy Jackie (v110U)", MACHINE_SUPPORTS_SAVE )