summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/uzebox.c
blob: ca2952c477509e97bacb07e7934e433d59180502 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

                                 











                                                                             


                          



                                          

                             
                         
 



                                                                                      
                                                    
                                           

         
 
                                               
 









                                        
                                     
                           
                                                                                                            
                                                      

        








                                            
  


                                  
                                                                   

 
                                  
 







                                          

 

                                     
 





























                                                                                  

 







                                     
                                                                           
                                                                 






















































                                                                                                        







                                                                          



                                                                     
                                                                 



                                                                           






                                                      










                                                                                              

                                                                                              


                                                     



                                                                                              



                                                                            

                                                                                              


                                                                                              




                                               





                                                      


                                                                                            
                                                                                                    



                                                            
                                                          

                                                                        
                                                                      




                                   
                                                                                                                 
 
                                                           


                 
                                                  







                                                         
                                          


                                        
                                                                 


                                                                








                                                                                                       
 



                                                      

                                    
                

  



                                                        
                                              
                                            
                                          

                                      

                                         
                                       
                                                          

                                                       
                                                                     
 





                                          
                                               
                               
                                                    




                                                     
                                                                                     
 
                                                                             


                                                                                            
                                                                                                                                      
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
/***************************************************************************

    Belogic Uzebox

    driver by Sandro Ronco

    TODO:
    - Sound
    - SDCard
    - Mouse

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

#include "emu.h"
#include "cpu/avr8/avr8.h"
#include "sound/dac.h"
#include "imagedev/cartslot.h"

// overclocked to 8 * NTSC burst frequency
#define MASTER_CLOCK 28618180

#define INTERLACED      0

class uzebox_state : public driver_device
{
public:
	uzebox_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu")
	{
	}

	required_device<avr8_device> m_maincpu;

	DECLARE_READ8_MEMBER(port_a_r);
	DECLARE_WRITE8_MEMBER(port_a_w);
	DECLARE_READ8_MEMBER(port_b_r);
	DECLARE_WRITE8_MEMBER(port_b_w);
	DECLARE_READ8_MEMBER(port_c_r);
	DECLARE_WRITE8_MEMBER(port_c_w);
	DECLARE_READ8_MEMBER(port_d_r);
	DECLARE_WRITE8_MEMBER(port_d_w);

	virtual void machine_start();
	virtual void machine_reset();
	void line_update();
	UINT32 screen_update_uzebox(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	DECLARE_DEVICE_IMAGE_LOAD_MEMBER(uzebox_cart);

private:
	int             m_vpos;
	UINT64          m_line_start_cycles;
	UINT32          m_line_pos_cycles;
	UINT8           m_port_a;
	UINT8           m_port_b;
	UINT8           m_port_c;
	UINT8           m_port_d;
	UINT16          m_joy_data[2];
	bitmap_rgb32    m_bitmap;
};

void uzebox_state::machine_start()
{
	machine().first_screen()->register_screen_bitmap(m_bitmap);
}

void uzebox_state::machine_reset()
{
	m_vpos = 0;
	m_line_start_cycles = 0;
	m_line_pos_cycles = 0;
	m_port_a = 0;
	m_port_b = 0;
	m_port_c = 0;
	m_port_d = 0;
	m_joy_data[0] = m_joy_data[1] = 0;
}


WRITE8_MEMBER(uzebox_state::port_a_w)
{
	//  xxxx ----   NC
	//  ---- x---   SNES controller clk
	//  ---- -x--   SNES controller latch
	//  ---- --x-   SNES controller P2 data
	//  ---- ---x   SNES controller P1 data

	UINT8 changed = m_port_a ^ data;

	if (changed & data & 0x04)
	{
		m_joy_data[0] = ioport("P1")->read();
		m_joy_data[1] = ioport("P2")->read();
	}
	else if (changed & 0x08)
	{
		if (changed & data & 0x08)
		{
			m_joy_data[0] >>= 1;
			m_joy_data[1] >>= 1;
		}

		m_port_a = (m_joy_data[0] & 0x01) | ((m_joy_data[1] & 0x01) << 1);
	}

	m_port_a = (data & 0x0c) | (m_port_a & 0x03);
}

READ8_MEMBER(uzebox_state::port_a_r)
{
	return  m_port_a | 0xf0;
}

WRITE8_MEMBER(uzebox_state::port_b_w)
{
	//  xxx- ----   SDCard
	//  ---x ----   AD725 CE
	//  ---- x---   AD725 4FSC
	//  ---- -xx-   NC
	//  ---- ---x   AD725 HSYNC

	// AD725 CE is hard-wired to VCC in early revisions (C1, D1 and E1)
	if ((m_port_b & 0x10) || ioport("AD725_CE")->read() == 0)
		if ((m_port_b ^ data) & m_port_b & 0x01)
		{
			line_update();

			UINT32 cycles = (UINT32)(m_maincpu->get_elapsed_cycles() - m_line_start_cycles);
			if (cycles < 1000 && m_vpos >= 448)
				m_vpos = INTERLACED ? ((m_vpos ^ 0x01) & 0x01) : 0;
			else if (cycles > 1000)
				m_vpos += 2;

			m_line_start_cycles = m_maincpu->get_elapsed_cycles();
			m_line_pos_cycles = 0;
		}

	m_port_b = data;
}

READ8_MEMBER(uzebox_state::port_b_r)
{
	return m_port_b;
}

WRITE8_MEMBER(uzebox_state::port_c_w)
{
	//  xx-- ----   blue
	//  --xx x---   green
	//  ---- -xxx   red

	line_update();
	m_port_c = data;
}

READ8_MEMBER(uzebox_state::port_c_r)
{
	return m_port_c;
}

WRITE8_MEMBER(uzebox_state::port_d_w)
{
	//  x--- ----   sound
	//  -x-- ----   SDCard CS
	//  ---x ----   LED
	//  --x- x---   NC
	//  ---- -x--   power
	//  ---- --xx   UART MIDI

	m_port_d = data;
}

READ8_MEMBER(uzebox_state::port_d_r)
{
	return m_port_d;
}


/****************************************************\
* Address maps                                       *
\****************************************************/

static ADDRESS_MAP_START( uzebox_prg_map, AS_PROGRAM, 8, uzebox_state )
	AM_RANGE(0x0000, 0xffff) AM_ROM // 64 KB internal eprom  ATmega644
ADDRESS_MAP_END

static ADDRESS_MAP_START( uzebox_data_map, AS_DATA, 8, uzebox_state )
	AM_RANGE(0x0100, 0x10ff) AM_RAM //  4KB RAM
ADDRESS_MAP_END

static ADDRESS_MAP_START( uzebox_io_map, AS_IO, 8, uzebox_state )
	AM_RANGE(AVR8_REG_A, AVR8_REG_A) AM_READWRITE( port_a_r, port_a_w )
	AM_RANGE(AVR8_REG_B, AVR8_REG_B) AM_READWRITE( port_b_r, port_b_w )
	AM_RANGE(AVR8_REG_C, AVR8_REG_C) AM_READWRITE( port_c_r, port_c_w )
	AM_RANGE(AVR8_REG_D, AVR8_REG_D) AM_READWRITE( port_d_r, port_d_w )
ADDRESS_MAP_END

/****************************************************\
* Input ports                                        *
\****************************************************/

static INPUT_PORTS_START( uzebox )
	PORT_START( "P1" )
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Button B") PORT_PLAYER(1)
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 Button Y") PORT_PLAYER(1)
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SELECT ) PORT_NAME("P1 Select") PORT_PLAYER(1)
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("P1 Start") PORT_PLAYER(1)
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 Button A") PORT_PLAYER(1)
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 Button X") PORT_PLAYER(1)
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Button L") PORT_PLAYER(1)
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Button R") PORT_PLAYER(1)
	PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START( "P2" )
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 Button B") PORT_PLAYER(2)
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 Button Y") PORT_PLAYER(2)
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SELECT ) PORT_NAME("P2 Select") PORT_PLAYER(2)
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("P2 Start")
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 Button A") PORT_PLAYER(2)
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 Button X") PORT_PLAYER(2)
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Button L") PORT_PLAYER(2)
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Button R") PORT_PLAYER(2)
	PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START("AD725_CE")
	PORT_CONFNAME( 0x01, 0x00, "AD725 CE" )
	PORT_CONFSETTING( 0x00, "VCC" )
	PORT_CONFSETTING( 0x01, "PB4" )
INPUT_PORTS_END

/****************************************************\
* Video hardware                                     *
\****************************************************/

void uzebox_state::line_update()
{
	UINT32 cycles = (UINT32)(m_maincpu->get_elapsed_cycles() - m_line_start_cycles) / 2;
	rgb_t color = rgb_t(pal3bit(m_port_c >> 0), pal3bit(m_port_c >> 3), pal2bit(m_port_c >> 6));

	for (UINT32 x = m_line_pos_cycles; x < cycles; x++)
	{
		if (m_bitmap.cliprect().contains(x, m_vpos))
			m_bitmap.pix32(m_vpos, x) = color;
		if (!INTERLACED)
			if (m_bitmap.cliprect().contains(x, m_vpos + 1))
				m_bitmap.pix32(m_vpos + 1, x) = color;
	}

	m_line_pos_cycles = cycles;
}

UINT32 uzebox_state::screen_update_uzebox(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
	return 0;
}

DEVICE_IMAGE_LOAD_MEMBER(uzebox_state,uzebox_cart)
{
	UINT8* rom = (UINT8*)(*memregion("maincpu"));

	memset(rom, 0xff, memregion("maincpu")->bytes());

	if (image.software_entry() == NULL)
	{
		UINT32 size = image.length();
		dynamic_buffer data(size);

		image.fread(data, size);

		if (!strncmp((const char*)&data[0], "UZEBOX", 6))
			memcpy(rom, data + 0x200, size - 0x200);
		else
			memcpy(rom, data, size);
	}
	else
	{
		memcpy(rom, image.get_software_region("rom"), image.get_software_region_length("rom"));
	}

	return IMAGE_INIT_PASS;
}


/****************************************************\
* Machine definition                                 *
\****************************************************/

const avr8_config atmega644_config =
{
	"eeprom"
};

static MACHINE_CONFIG_START( uzebox, uzebox_state )

	/* basic machine hardware */
	MCFG_CPU_ADD("maincpu", ATMEGA644, MASTER_CLOCK)
	MCFG_CPU_AVR8_CONFIG(atmega644_config)
	MCFG_CPU_PROGRAM_MAP(uzebox_prg_map)
	MCFG_CPU_DATA_MAP(uzebox_data_map)
	MCFG_CPU_IO_MAP(uzebox_io_map)

	/* video hardware */
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_REFRESH_RATE(59.99)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1395))
	MCFG_SCREEN_SIZE(870, 525)
	MCFG_SCREEN_VISIBLE_AREA(150, 870-1, 40, 488-1)
	MCFG_SCREEN_UPDATE_DRIVER(uzebox_state, screen_update_uzebox)

	/* sound hardware */
	MCFG_SPEAKER_STANDARD_MONO("avr8")
	MCFG_SOUND_ADD("dac", DAC, 0)
	MCFG_SOUND_ROUTE(0, "avr8", 1.00)

	MCFG_CARTSLOT_ADD("cart1")
	MCFG_CARTSLOT_EXTENSION_LIST("bin,uze")
	MCFG_CARTSLOT_MANDATORY
	MCFG_CARTSLOT_LOAD(uzebox_state,uzebox_cart)
	MCFG_CARTSLOT_INTERFACE("uzebox")
	MCFG_SOFTWARE_LIST_ADD("eprom_list","uzebox")
MACHINE_CONFIG_END

ROM_START( uzebox )
	ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )  /* Main program store */

	ROM_REGION( 0x800, "eeprom", ROMREGION_ERASE00 )  /* on-die eeprom */
ROM_END

/*   YEAR  NAME      PARENT    COMPAT    MACHINE   INPUT     INIT      COMPANY   FULLNAME */
CONS(2010, uzebox,   0,        0,        uzebox,   uzebox, driver_device,   0,  "Belogic", "Uzebox", GAME_NO_SOUND | GAME_NOT_WORKING)