summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/juicebox.cpp
blob: 387537611ce7e519b1d5f63894d1a20662e33f42 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                       
                                     












                                                                                
                           
                   
                    
                   
                     

                    





                                   
               



                      
  



                                           
                                                                                        



                                                   

           






                                                   
                                              
                                                  
                                                              
                         
                     
 




                                                                                  

                                              
                                                                                     



                                     


                                                    
                                            

  
                                                                           












                                                                       






                                                                            
                                 
 


                                     

 
                                
 

                                    

 
                                   
 
                     
                                       
         
                                              




                            
                                               


                    
                                             
 
                                                
                                       
         
                                  
                 
                                                                           
                                                      
                 
                                       
                 
                                                                           
                                                      


                    
                                                                        
                                                   



                 
                                                  
 
                                     
                       


































                                                                            


                                                                    




                                          
                                                                                  
                                                              
                                                    



                                                                    
                                                    






                                                                             
                                                                                                                                                       


                    
                                                   
 

                            


                                          


                                                                                                                                   








                                              
                          



                                                                   
                                                                                   




                                               
                                                                                   



                                                                 

 

      
                                                  
 
                                                  



      
                                    
 

                                                            
                   
 
















                                                                                                                                                                                                    

 
                                    
 
                           
                    





                                                                            


                                                   
                                                                                                                     

                                                             




                                                                            
                                    



                     
                                              

                                                  
 
                                          





                                                                             
                                              
 
                                                                          
 
                                                  
                                                                                                                             
                                                                                        
                                                                                                                
 
                                                     

                                                                                        
                                                                              
 

                                                    





                                                      




                                                                                                                                                                  








                                                                            
                                                                                                                           
                                                                        
                                                                                                                          
                                                             
                                                                                                                        

       
                                                                                                       
// license:BSD-3-Clause
// copyright-holders:Tim Schuerewegen
/*******************************************************************************

    Mattel Juice Box

    (C) 2011 Tim Schuerewegen

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

#include "emu.h"
#include "cpu/arm7/arm7.h"
#include "machine/s3c44b0.h"
#include "machine/smartmed.h"
#include "sound/dac.h"
#include "sound/volt_reg.h"
#include "emupal.h"
#include "rendlay.h"
#include "screen.h"
#include "softlist.h"
#include "speaker.h"


//#define JUICEBOX_ENTER_DEBUG_MENU
//#define JUICEBOX_DISPLAY_ROM_ID

#define VERBOSE_LEVEL ( 0 )

struct jb_smc_t
{
	int add_latch;
	int cmd_latch;
	int busy;
};

class juicebox_state : public driver_device
{
public:
	juicebox_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_s3c44b0(*this, "s3c44b0")
		, m_smartmedia(*this, "smartmedia")
	{ }

	void juicebox(machine_config &config);

	void init_juicebox();

	DECLARE_INPUT_CHANGED_MEMBER(port_changed);

private:
	required_device<cpu_device> m_maincpu;
	required_device<s3c44b0_device> m_s3c44b0;
	required_device<smartmedia_image_device> m_smartmedia;
	uint32_t port[9];
	jb_smc_t smc;

	#if defined(JUICEBOX_ENTER_DEBUG_MENU) || defined(JUICEBOX_DISPLAY_ROM_ID)
	int port_g_read_count;
	#endif
	DECLARE_READ32_MEMBER(juicebox_nand_r);
	DECLARE_WRITE32_MEMBER(juicebox_nand_w);
	virtual void machine_start() override;
	virtual void machine_reset() override;
	inline void verboselog(int n_level, const char *s_fmt, ...) ATTR_PRINTF(3,4);
	void smc_reset();
	void smc_init();
	uint8_t smc_read();
	void smc_write(uint8_t data);
	DECLARE_READ32_MEMBER(s3c44b0_gpio_port_r);
	DECLARE_WRITE32_MEMBER(s3c44b0_gpio_port_w);
	DECLARE_WRITE16_MEMBER(s3c44b0_i2s_data_w);
	void juicebox_map(address_map &map);
};

inline void juicebox_state::verboselog(int n_level, const char *s_fmt, ...)
{
	if (VERBOSE_LEVEL >= n_level)
	{
		va_list v;
		char buf[32768];
		va_start( v, s_fmt);
		vsprintf( buf, s_fmt, v);
		va_end( v);
		logerror( "%s: %s", machine().describe_context(), buf);
	}
}


/***************************************************************************
    MACHINE HARDWARE
***************************************************************************/


// SMARTMEDIA

void juicebox_state::smc_reset( )
{
	verboselog(5, "smc_reset\n");
	smc.add_latch = 0;
	smc.cmd_latch = 0;
}

void juicebox_state::smc_init( )
{
	verboselog(5, "smc_init\n");
	smc_reset();
}

uint8_t juicebox_state::smc_read( )
{
	uint8_t data;
	if (m_smartmedia->is_present())
	{
		data = m_smartmedia->data_r();
	}
	else
	{
		data = 0xFF;
	}
	verboselog(5, "smc_read %08X\n", data);
	return data;
}

void juicebox_state::smc_write( uint8_t data)
{
	verboselog(5, "smc_write %08X\n", data);
	if (m_smartmedia->is_present())
	{
		if (smc.cmd_latch)
		{
			verboselog(5, "smartmedia_command_w %08X\n", data);
			m_smartmedia->command_w(data);
		}
		else if (smc.add_latch)
		{
			verboselog(5, "smartmedia_address_w %08X\n", data);
			m_smartmedia->address_w(data);
		}
		else
		{
			verboselog(5, "smartmedia_data_w %08X\n", data);
			m_smartmedia->data_w(data);
		}
	}
}

READ32_MEMBER(juicebox_state::s3c44b0_gpio_port_r)
{
	uint32_t data = port[offset];
	switch (offset)
	{
		case S3C44B0_GPIO_PORT_A :
		{
			data = 0x00000210;
		}
		break;
		case S3C44B0_GPIO_PORT_B :
		{
			data = 0x00000000;
		}
		break;
		case S3C44B0_GPIO_PORT_C :
		{
			// 0C0062C4 -> bit 8 is turned on
			//data |= 1 << 13;
			data = 0x0000FF15;
			data &= (1 << 2) | (1 << 9) | (1 << 10) | (1 << 11);
			data |= (1 << 2) | (1 << 9) | (1 << 10) | (1 << 11);
		}
		break;
		case S3C44B0_GPIO_PORT_D :
		{
			data = 0x00000010;
		}
		break;
		case S3C44B0_GPIO_PORT_E :
		{
			data = 0x000000DF;
		}
		break;
		case S3C44B0_GPIO_PORT_F :
		{
			data = data | (0 << 7);
			data = 0x0000009F;
			data &= ~0xE0;
			if (smc.cmd_latch) data = data | 0x00000020;
			if (smc.add_latch) data = data | 0x00000040;
			if (!smc.busy) data = data | 0x00000080;
		}
		break;
		case S3C44B0_GPIO_PORT_G :
		{
			data = 0x0000009F;
			data = (data & ~0x1F) | (ioport( "PORTG")->read() & 0x1F);
			#if defined(JUICEBOX_ENTER_DEBUG_MENU)
			if (port_g_read_count++ < 1)
			{
				data = 0x00000095; // PLAY + REVERSE
			}
			#elif defined(JUICEBOX_DISPLAY_ROM_ID)
			if (port_g_read_count++ < 3)
			{
				data = 0x0000008A; // RETURN + FORWARD + STAR
			}
			#endif
		}
		break;
	}
//  data = ((machine().rand() & 0xFF) << 24) | ((machine().rand() & 0xFF) << 16) | ((machine().rand() & 0xFF) << 8) | ((machine().rand() & 0xFF) << 0);
	return data;
}

WRITE32_MEMBER(juicebox_state::s3c44b0_gpio_port_w)
{
	port[offset] = data;
	switch (offset)
	{
		case S3C44B0_GPIO_PORT_F :
		{
			smc.cmd_latch = ((data & 0x00000020) != 0);
			smc.add_latch = ((data & 0x00000040) != 0);
			verboselog( 5, "s3c44b0_gpio_port_w - nand cle %d ale %d\n", (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0);
		}
		break;
	}
}

// ...

READ32_MEMBER(juicebox_state::juicebox_nand_r)
{
	uint32_t data = 0;
	if (ACCESSING_BITS_0_7) data = data | (smc_read() <<  0);
	if (ACCESSING_BITS_8_15) data = data | (smc_read() <<  8);
	if (ACCESSING_BITS_16_23) data = data | (smc_read() << 16);
	if (ACCESSING_BITS_24_31) data = data | (smc_read() << 24);
	verboselog( 5, "juicebox_nand_r %08X %08X %08X\n", offset, mem_mask, data);
	return data;
}

WRITE32_MEMBER(juicebox_state::juicebox_nand_w)
{
	verboselog( 5, "juicebox_nand_w %08X %08X %08X\n", offset, mem_mask, data);
	if (ACCESSING_BITS_0_7) smc_write((data >>  0) & 0xFF);
	if (ACCESSING_BITS_8_15) smc_write((data >>  8) & 0xFF);
	if (ACCESSING_BITS_16_23) smc_write((data >> 16) & 0xFF);
	if (ACCESSING_BITS_24_31) smc_write((data >> 24) & 0xFF);
}

// ...

INPUT_CHANGED_MEMBER(juicebox_state::port_changed)
{
	m_s3c44b0->request_eint((uintptr_t)param);
}

// ...

void juicebox_state::machine_start()
{
	address_space &space = m_maincpu->space(AS_PROGRAM);

	smc_init();

	space.install_readwrite_handler(0x01c00000, 0x01c0000b, read32_delegate(FUNC(s3c44b0_device::cpuwrap_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::cpuwrap_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d00000, 0x01d0002b, read32_delegate(FUNC(s3c44b0_device::uart_0_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::uart_0_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d04000, 0x01d0402b, read32_delegate(FUNC(s3c44b0_device::uart_1_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::uart_1_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d14000, 0x01d14013, read32_delegate(FUNC(s3c44b0_device::sio_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::sio_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d18000, 0x01d18013, read32_delegate(FUNC(s3c44b0_device::iis_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::iis_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d20000, 0x01d20057, read32_delegate(FUNC(s3c44b0_device::gpio_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::gpio_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d30000, 0x01d3000b, read32_delegate(FUNC(s3c44b0_device::wdt_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::wdt_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d40000, 0x01d4000b, read32_delegate(FUNC(s3c44b0_device::adc_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::adc_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d50000, 0x01d5004f, read32_delegate(FUNC(s3c44b0_device::pwm_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::pwm_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d60000, 0x01d6000f, read32_delegate(FUNC(s3c44b0_device::iic_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::iic_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01d80000, 0x01d8000f, read32_delegate(FUNC(s3c44b0_device::clkpow_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::clkpow_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01e00000, 0x01e0003f, read32_delegate(FUNC(s3c44b0_device::irq_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::irq_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01e80000, 0x01e8001b, read32_delegate(FUNC(s3c44b0_device::zdma_0_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::zdma_0_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01e80020, 0x01e8003b, read32_delegate(FUNC(s3c44b0_device::zdma_1_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::zdma_1_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01f00000, 0x01f00047, read32_delegate(FUNC(s3c44b0_device::lcd_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::lcd_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01f80000, 0x01f8001b, read32_delegate(FUNC(s3c44b0_device::bdma_0_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::bdma_0_w), &(*m_s3c44b0)));
	space.install_readwrite_handler(0x01f80020, 0x01f8003b, read32_delegate(FUNC(s3c44b0_device::bdma_1_r), &(*m_s3c44b0)),  write32_delegate(FUNC(s3c44b0_device::bdma_1_w), &(*m_s3c44b0)));
}

void juicebox_state::machine_reset()
{
	m_maincpu->reset();
	smc_reset();
}

/***************************************************************************
    ADDRESS MAPS
***************************************************************************/

void juicebox_state::juicebox_map(address_map &map)
{
	map(0x00000000, 0x007fffff).rom();
	map(0x04000000, 0x04ffffff).rw(FUNC(juicebox_state::juicebox_nand_r), FUNC(juicebox_state::juicebox_nand_w));
	map(0x0c000000, 0x0c1fffff).ram().mirror(0x00600000);
}

/***************************************************************************
    MACHINE DRIVERS
***************************************************************************/

void juicebox_state::init_juicebox()
{
	// do nothing
}

MACHINE_CONFIG_START(juicebox_state::juicebox)
	MCFG_DEVICE_ADD("maincpu", ARM7, 66000000)
	MCFG_DEVICE_PROGRAM_MAP(juicebox_map)

	MCFG_PALETTE_ADD("palette", 32768)

	MCFG_SCREEN_ADD("screen", LCD)
	MCFG_SCREEN_REFRESH_RATE(60)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
	MCFG_SCREEN_SIZE(240, 160)
	MCFG_SCREEN_VISIBLE_AREA(0, 240 - 1, 0, 160 - 1)
	config.set_default_layout(layout_lcd);

	MCFG_SCREEN_UPDATE_DEVICE("s3c44b0", s3c44b0_device, video_update)

	SPEAKER(config, "speaker").front_center();
	MCFG_DEVICE_ADD("dac", DAC_16BIT_R2R_TWOS_COMPLEMENT, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0) // unknown DAC
	MCFG_DEVICE_ADD("vref", VOLTAGE_REGULATOR, 0) MCFG_VOLTAGE_REGULATOR_OUTPUT(5.0)
	MCFG_SOUND_ROUTE(0, "dac", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE(0, "dac", -1.0, DAC_VREF_NEG_INPUT)

	MCFG_DEVICE_ADD("s3c44b0", S3C44B0, 10000000)
	MCFG_S3C44B0_GPIO_PORT_R_CB(READ32(*this, juicebox_state, s3c44b0_gpio_port_r))
	MCFG_S3C44B0_GPIO_PORT_W_CB(WRITE32(*this, juicebox_state, s3c44b0_gpio_port_w))
	MCFG_S3C44B0_I2S_DATA_W_CB(WRITE16("dac", dac_word_interface, data_w))

	MCFG_DEVICE_ADD("smartmedia", SMARTMEDIA, 0)

	/* software lists */
	MCFG_SOFTWARE_LIST_ADD("cart_list","juicebox")
MACHINE_CONFIG_END

static INPUT_PORTS_START( juicebox )
	PORT_START( "PORTG" )
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, juicebox_state, port_changed, (void *)0) PORT_NAME("RETURN") PORT_PLAYER(1)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, juicebox_state, port_changed, (void *)0) PORT_NAME("PLAY") PORT_PLAYER(1)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, juicebox_state, port_changed, (void *)0) PORT_NAME("FORWARD") PORT_PLAYER(1)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, juicebox_state, port_changed, (void *)0) PORT_NAME("REVERSE") PORT_PLAYER(1)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_CHANGED_MEMBER(DEVICE_SELF, juicebox_state, port_changed, (void *)0) PORT_NAME("STAR") PORT_PLAYER(1)
INPUT_PORTS_END

/***************************************************************************
    GAME DRIVERS
***************************************************************************/

ROM_START( juicebox )
	ROM_REGION( 0x800000, "maincpu", 0 )
	ROM_SYSTEM_BIOS( 0, "juicebox", "Juice Box v.28 08242004" )
	ROMX_LOAD( "juicebox.rom", 0, 0x800000, CRC(ac731197) SHA1(8278891c3531b3b6b5fec2a97a3ef6f0de1ac81d), ROM_BIOS(0) )
	ROM_SYSTEM_BIOS( 1, "uclinuxp", "uClinux 2.4.24-uc0 (patched)" )
	ROMX_LOAD( "newboot.rom", 0, 0x1A0800, CRC(443f48b7) SHA1(38f0dc07b5cf02b972a851aa9e87f5d93d03f629), ROM_BIOS(1) )
	ROM_SYSTEM_BIOS( 2, "uclinux", "uClinux 2.4.24-uc0" )
	ROMX_LOAD( "image.rom", 0, 0x19E400, CRC(6c0308bf) SHA1(5fe21a38a4cd0d86bb60920eb100138b0e924d90), ROM_BIOS(2) )
ROM_END

COMP(2004, juicebox, 0, 0, juicebox, juicebox, juicebox_state, init_juicebox, "Mattel", "Juice Box", 0)