summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/sv8000.c
blob: 8ee62b23aa661523d8a07dbeb0ab9cb4a3336964 (plain) (tree)
1
2
3
4
5
6
7
8
9
              
                                          


                                                                            
                                                                           


                                   
                                      








                                                        
         

                                                                     









                                                                             
                         







                                                                                      

                                               



                                          


                                                 
 











                                               

                                                  




                                              
                                                 
                                              



                                  

                       









                           






                                                                 
                                                              






















                                                                                            






































                                                                                                                                        




                                  








                     
                                  







                                  







































                                                                                                           
                                      
                                




                                            
                                                  






                                           
                                      


                                    
                                          


                                    
                                          


                                    
                                          






                                            
                                                  




                                           
                                      





                                            
                                                  



                        



                                         
                                    







                                         
                                    




                                                                  









                                                                     
                                          


                     
                                  


                     
                                          







                                          

                                          
                                                

                                                         
                                                         



                             
                     




                                                             

                                                             




                                          
                                                

 



                                               



                            



                                                                                  
                    




                                                          
 

                                                
                                       





                                                                       




                                                                            
                                                                           
 






                                                                    


                                                                                      


                                                                                       
                                                        



                                                                                                         



                                                                      




















                                                                                                                                  
                                                                                                                             
// license:BSD
// copyright-holders:Wilbert Pol, Robbbert
/***************************************************************************

    Bandai Super Vision 8000 (TV Jack 8000)
      driver by Wilbert Pol, Robbbert, ranger_lennier, and Charles McDonald

        2014/01/07 Skeleton driver.

The Bandai Super Vision 8000 contains:
- NEC D78C (Z80)
- AY-3-8910
- AMI S68047P (6847 variant)
- NEC D8255C

Looking at the code of the cartridges it seems there is:
- 1KB of main system RAM
- 3KB of video RAM

    TODO:
    - Check configuration of S68047P pins through 8910 port A against
      schematics
    - Verify clock

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


#include "emu.h"
#include "cpu/z80/z80.h"
#include "imagedev/cartslot.h"
#include "machine/i8255.h"
#include "sound/ay8910.h"
#include "video/mc6847.h"


class sv8000_state : public driver_device
{
public:
	sv8000_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_s68047p(*this, "s68047p")
		, m_videoram(*this, "videoram")
		, m_io_row0(*this, "ROW0")
		, m_io_row1(*this, "ROW1")
		, m_io_row2(*this, "ROW2")
		, m_io_joy(*this, "JOY")
	{ }

	DECLARE_DEVICE_IMAGE_LOAD_MEMBER( cart );

	DECLARE_READ8_MEMBER( ay_port_a_r );
	DECLARE_READ8_MEMBER( ay_port_b_r );
	DECLARE_WRITE8_MEMBER( ay_port_a_w );
	DECLARE_WRITE8_MEMBER( ay_port_b_w );

	DECLARE_READ8_MEMBER( i8255_porta_r );
	DECLARE_WRITE8_MEMBER( i8255_porta_w );
	DECLARE_READ8_MEMBER( i8255_portb_r );
	DECLARE_WRITE8_MEMBER( i8255_portb_w );
	DECLARE_READ8_MEMBER( i8255_portc_r );
	DECLARE_WRITE8_MEMBER( i8255_portc_w );

	DECLARE_READ8_MEMBER( mc6847_videoram_r );

private:
	virtual void machine_start();
	virtual void machine_reset();

	required_device<cpu_device> m_maincpu;
	required_device<s68047_device> m_s68047p;
	required_shared_ptr<UINT8> m_videoram;
	required_ioport m_io_row0;
	required_ioport m_io_row1;
	required_ioport m_io_row2;
	required_ioport m_io_joy;

	UINT8 m_column;

	// graphics signals
	UINT8 m_ag;
	UINT8 m_gm2;
	UINT8 m_gm1;
	UINT8 m_gm0;
	UINT8 m_as;
	UINT8 m_css;
	UINT8 m_intext;
	UINT8 m_inv;
};


static ADDRESS_MAP_START(sv8000_mem, AS_PROGRAM, 8, sv8000_state)
	ADDRESS_MAP_UNMAP_HIGH
	AM_RANGE( 0x0000, 0x0fff ) AM_ROM
	AM_RANGE( 0x8000, 0x83ff ) AM_RAM // Work RAM??
	AM_RANGE( 0xc000, 0xcbff ) AM_RAM AM_SHARE("videoram")
ADDRESS_MAP_END


static ADDRESS_MAP_START(sv8000_io, AS_IO, 8, sv8000_state)
	ADDRESS_MAP_UNMAP_HIGH
	ADDRESS_MAP_GLOBAL_MASK(0xff)
	AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("i8255", i8255_device, read, write)
	AM_RANGE(0xc0, 0xc0) AM_DEVWRITE("ay8910", ay8910_device, data_w)   // Not sure yet
	AM_RANGE(0xc1, 0xc1) AM_DEVWRITE("ay8910", ay8910_device, address_w) // Not sure yet
ADDRESS_MAP_END


/* Input ports */
// On the main console:
//
//  1 2 3                              1 2 3
//  4 5 6                              4 5 6
//  7 8 9                              7 8 9
//  * 0 #                              * 0 #
//
//  Button/dial?    POWER   RESET    Button/dial?
//
static INPUT_PORTS_START( sv8000 )
	PORT_START("ROW0")
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_NAME("Left 1")
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_NAME("Left 4") // Guess
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_NAME("Left 7") // Guess
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_NAME("Left *") // Guess
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Right 1")
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Right 4") // Guess
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Right 7") // Guess
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Right *") // Guess

	PORT_START("ROW1")
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_NAME("Left 2")
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_NAME("Left 5") // Guess
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_NAME("Left 8") // Guess
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_NAME("Left 0")
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Right 2")
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Right 5") // Guess
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Right 8") // Guess
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Right 0")

	PORT_START("ROW2")
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_NAME("Left 3")
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_NAME("Left 6") // Guess
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_NAME("Left 9") // Guess
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_NAME("Left #") // Guess
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Right 3")
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Right 6") // Guess
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Right 9") // Guess
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Right #") // Guess

	PORT_START("JOY")
	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_NAME("Left Right")
	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_NAME("Left Left")
	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_NAME("Left Down")
	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_NAME("Left Up")
	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_NAME("Right Right")
	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_NAME("Right Left")
	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_NAME("Right Down")
	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_NAME("Right Up")
INPUT_PORTS_END


void sv8000_state::machine_start()
{
	m_ag = 0;
	m_gm2 = 0;
	m_gm1 = 0;
	m_gm0 = 0;
	m_as = 0;
	m_css = 0;
	m_intext = 0;
	m_inv = 0;

	save_item(NAME(m_column));
	save_item(NAME(m_ag));
	save_item(NAME(m_gm2));
	save_item(NAME(m_gm1));
	save_item(NAME(m_gm0));
	save_item(NAME(m_as));
	save_item(NAME(m_css));
	save_item(NAME(m_intext));
	save_item(NAME(m_inv));
}


void sv8000_state::machine_reset()
{
	m_column = 0xff;
}


DEVICE_IMAGE_LOAD_MEMBER( sv8000_state, cart )
{
	UINT8 *cart = memregion("maincpu")->base();

	if (image.software_entry() == NULL)
	{
		UINT32 filesize = image.length();

		if (filesize != 0x1000)
		{
			image.seterror(IMAGE_ERROR_UNSPECIFIED, "Incorrect or not support cartridge size");
			return IMAGE_INIT_FAIL;
		}

		if (image.fread( cart, filesize) != filesize)
		{
			image.seterror(IMAGE_ERROR_UNSPECIFIED, "Error loading file");
			return IMAGE_INIT_FAIL;
		}
	}
	else
	{
		memcpy(cart, image.get_software_region("rom"), image.get_software_region_length("rom"));
	}

	return IMAGE_INIT_PASS;
}


READ8_MEMBER( sv8000_state::i8255_porta_r )
{
	//logerror("i8255_porta_r\n");
	return m_io_joy->read();
}


WRITE8_MEMBER( sv8000_state::i8255_porta_w )
{
	//logerror("i8255_porta_w: %02X\n", data);
}


READ8_MEMBER( sv8000_state::i8255_portb_r )
{
	UINT8 data = 0xff;

	//logerror("i8255_portb_r\n");

	if ( ! ( m_column & 0x01 ) )
	{
		data &= m_io_row0->read();
	}
	if ( ! ( m_column & 0x02 ) )
	{
		data &= m_io_row1->read();
	}
	if ( ! ( m_column & 0x04 ) )
	{
		data &= m_io_row2->read();
	}
	return data;
}


WRITE8_MEMBER( sv8000_state::i8255_portb_w )
{
	//logerror("i8255_portb_w: %02X\n", data);
}


READ8_MEMBER( sv8000_state::i8255_portc_r )
{
	//logerror("i8255_portc_r\n");
	return 0xFF;
}


WRITE8_MEMBER( sv8000_state::i8255_portc_w )
{
	//logerror("i8255_portc_w: %02X\n", data);
	m_column = data;
}


READ8_MEMBER( sv8000_state::ay_port_a_r )
{
	UINT8 data = 0xFF;

	//logerror("ay_port_a_r\n");
	return data;
}


READ8_MEMBER( sv8000_state::ay_port_b_r )
{
	UINT8 data = 0xff;

	//logerror("ay_port_b_r\n");
	return data;
}


// Possibly connected to S68047P for selecting text/graphics modes
// misvader:
// 0x42 01000010 set on normal text screen
// 0x5A 01011010 set for a 256x192 bit mapped screen 3KB in 6KB mode?
//
// spfire:
// 0x42 01000010 text
// 0x5A 01011010 graphics 3KB in 6KB mode?
//
// othello:
// 0x02 00000010 normal text screen
// 0x58 01011000 graphics 3KB in 6KB mode?
//
// gunprof:
// 0x00 00000000 text
// 0x38 00111000 graphics 3KB mode
//
// pacpac:
// 0x00 00000000 text
// 0x5A 01011010 graphics 3KB in 6KB mode?
//
// submar:
// 0x00 00000000 text
// 0x5A 01011010 graphics 3KB in 6KB mode?
//
// beamgala:
// 0x5A 01011010 graphics 3KB in 6KB mode?
//
WRITE8_MEMBER( sv8000_state::ay_port_a_w )
{
	//logerror("ay_port_a_w: %02X\n", data);

	// Lacking schematics, these are all wild guesses
	// Having bit 1 set makes black display as blue??
	m_ag = BIT(data, 4);
	m_gm2 = BIT(data, 6);
	m_gm1 = BIT(data, 3);
	m_gm0 = BIT(data, 3);
	m_css = m_ag;

	m_s68047p->ag_w( m_ag ? ASSERT_LINE : CLEAR_LINE );
	m_s68047p->gm2_w( m_gm2 ? ASSERT_LINE : CLEAR_LINE );
	m_s68047p->gm1_w( m_gm1 ? ASSERT_LINE : CLEAR_LINE );
	m_s68047p->gm0_w( m_gm0 ? ASSERT_LINE : CLEAR_LINE );
	m_s68047p->css_w( m_css ? ASSERT_LINE : CLEAR_LINE );
	m_s68047p->hack_black_becomes_blue( BIT(data, 1) );
}


WRITE8_MEMBER( sv8000_state::ay_port_b_w )
{
	//logerror("ay_port_b_w: %02X\n", data);
}

READ8_MEMBER( sv8000_state::mc6847_videoram_r )
{
	if (offset == ~0) return 0xff;

	if ( m_ag )
	{
		if ( m_gm2 )
		{
			// 256 x 192 / 6KB
			offset = ( ( offset & 0x1fc0 ) >> 1 ) | ( offset & 0x1f );
			return m_videoram[offset % 0xc00];
		}
		else
		{
			// 256 x 96 / 3KB
			return m_videoram[offset % 0xc00];
		}
	}

	// Standard text
	UINT8 data = m_videoram[offset % 0xc00];
	if (!data) data = 0x20; //bodge

	m_s68047p->inv_w( ( data & 0x80 ) ? ASSERT_LINE : CLEAR_LINE );

	return data;
}

static MACHINE_CONFIG_START( sv8000, sv8000_state )
	/* basic machine hardware */
	MCFG_CPU_ADD("maincpu",Z80, XTAL_10_738635MHz/3)  /* Not verified */
	MCFG_CPU_PROGRAM_MAP(sv8000_mem)
	MCFG_CPU_IO_MAP(sv8000_io)
	MCFG_CPU_VBLANK_INT_DRIVER("screen", sv8000_state,  irq0_line_hold)

	MCFG_DEVICE_ADD("i8255", I8255, 0)
	MCFG_I8255_IN_PORTA_CB(READ8(sv8000_state, i8255_porta_r))
	MCFG_I8255_OUT_PORTA_CB(WRITE8(sv8000_state, i8255_porta_w))
	MCFG_I8255_IN_PORTB_CB(READ8(sv8000_state, i8255_portb_r))
	MCFG_I8255_OUT_PORTB_CB(WRITE8(sv8000_state, i8255_portb_w))
	MCFG_I8255_IN_PORTC_CB(READ8(sv8000_state, i8255_portc_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(sv8000_state, i8255_portc_w))

	/* video hardware */
	// S68047P - Unknown whether the internal or an external character rom is used
	MCFG_DEVICE_ADD("s68047p", S68047, XTAL_10_738635MHz/3 )  // Clock not verified
	MCFG_MC6847_INPUT_CALLBACK(READ8(sv8000_state, mc6847_videoram_r))

	MCFG_SCREEN_MC6847_NTSC_ADD("screen", "s68047p")

	/* sound hardware */
	MCFG_SPEAKER_STANDARD_MONO("mono")
	MCFG_SOUND_ADD("ay8910", AY8910, XTAL_10_738635MHz/3/2)  /* Exact model and clock not verified */
	MCFG_AY8910_PORT_A_READ_CB(READ8(sv8000_state, ay_port_a_r))
	MCFG_AY8910_PORT_B_READ_CB(READ8(sv8000_state, ay_port_b_r))
	MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(sv8000_state, ay_port_a_w))
	MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(sv8000_state, ay_port_b_w))
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)

	/* cartridge */
	MCFG_CARTSLOT_ADD("cart")
	MCFG_CARTSLOT_EXTENSION_LIST("bin")
	MCFG_CARTSLOT_MANDATORY
	MCFG_CARTSLOT_LOAD(sv8000_state,cart)
	MCFG_CARTSLOT_INTERFACE("sv8000_cart")

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

/* ROM definition */
ROM_START( sv8000 )
	ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF )
ROM_END

/* Driver */

/*    YEAR  NAME    PARENT  COMPAT   MACHINE  INPUT   INIT                  COMPANY   FULLNAME                            FLAGS */
CONS( 1979, sv8000, 0,      0,       sv8000,  sv8000, driver_device,   0,   "Bandai", "Super Vision 8000 (TV Jack 8000)", 0 )