summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/rz1.cpp
blob: 96468340ad9dfdb2c37b01e910f832aa34e05fb5 (plain) (tree)
1
2
3
4
5
6
7
8
9







                                                                            
                   
 

                                                                
 

                                                                          
 
                                                              
 

                                                                  
 





                 


                                                                            
                   
                                
                          

                          
 

                 










                                                                                   
                                            

                                                                       
                                                      
                              



                                         
                                  
                                               
 





                                                  
                                                  

                                                



                                        
                                       



                                        
 
                                               
                                           
                                               


                                           
 
                         
                         






                                                                            










                                                                                           







                                                                            






                                                                                                          

                         






                                                                                                           

                         






                                                                                                         

                         






                                                                                                                 

                         






                                                                                                                  

                         






                                                                                                         

                         






                                                                                                             

                         






                                                                                                             






                                                                            









                                                                              




















                                                                                       

                                       
                                                 



                                       
                                                 

 

                                   
                                                               





                                                                                                    
                 

 

                                    
                        
 

                                                                

 








                                         

                                    


                                                   
                        

 








                                                      

                                   
                 






                                           



                                







                                                             




                                  
 


                                                                                               




                                   

                                  





                               

                                   


                                                                        
 





                                                                            






                                                                       
 
                         


                                                                             

                                                  


                                                                           
                                      



                                               


                                                                 
 
                                                  

                                                                       
                                                     

                                                                       
                                                     













                                                                                                             
                                          
                                                                                                                          


                                                                                                                          






                                                                            

                                                                                                                   
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************

    Casio RZ-1

    Sampling drum machine

    Sound ROM info:

    Each ROM chip holds 1.49s of sounds and can be opened as raw
    PCM data: signed 8-bit, mono, 20,000 Hz.

    * Sound A: Toms 1~3, Kick, Snare, Rimshot, Closed Hi-Hat, Open Hi-Hat,
        and Metronome Click (in that order).

    * Sound B: Clap, Ride, Cowbell, and Crash (in that order).

    Note: Holding EDIT/RECORD, DELETE, INSERT/AUTO-COMPENSATE and
    CHAIN/BEAT at startup causes the system to go into a RAM test.

    TODO:
    - Metronome
    - MIDI
    - Cassette
    - Audio input

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

#include "emu.h"
#include "screen.h"
#include "cpu/upd7810/upd7811.h"
#include "video/hd44780.h"
#include "sound/upd934g.h"
#include "speaker.h"

#include "rz1.lh"


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

class rz1_state : public driver_device
{
public:
	rz1_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu"),
		m_hd44780(*this, "hd44780"),
		m_pg{ {*this, "upd934g_c"}, {*this, "upd934g_b"} },
		m_samples{ {*this, "samples_a"}, {*this, "samples_b"}},
		m_keys(*this, "kc%u", 0), m_port_a(0),
		m_port_b(0xff)
	{ }

	void rz1(machine_config &config);

	DECLARE_PALETTE_INIT(rz1);
	HD44780_PIXEL_UPDATE(lcd_pixel_update);

protected:
	virtual void machine_start() override;
	virtual void machine_reset() override;

private:
	required_device<upd7811_device> m_maincpu;
	required_device<hd44780_device> m_hd44780;
	required_device<upd934g_device> m_pg[2];
	required_memory_region m_samples[2];
	required_ioport_array<8> m_keys;

	void map(address_map &map);

	DECLARE_READ8_MEMBER(port_a_r);
	DECLARE_WRITE8_MEMBER(port_a_w);
	DECLARE_WRITE8_MEMBER(port_b_w);
	DECLARE_READ8_MEMBER(port_c_r);
	DECLARE_WRITE8_MEMBER(port_c_w);

	DECLARE_READ8_MEMBER(upd934g_c_data_r);
	DECLARE_WRITE8_MEMBER(upd934g_c_w);
	DECLARE_READ8_MEMBER(upd934g_b_data_r);
	DECLARE_WRITE8_MEMBER(upd934g_b_w);
	DECLARE_READ8_MEMBER(key_r);
	DECLARE_WRITE8_MEMBER(leds_w);

	uint8_t m_port_a;
	uint8_t m_port_b;
};


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

void rz1_state::map(address_map &map)
{
//  map(0x0000, 0x0fff).rom().region("maincpu", 0);
	map(0x2000, 0x3fff).ram();
	map(0x4000, 0x7fff).rom().region("program", 0);
	map(0x8000, 0x8fff).w(this, FUNC(rz1_state::upd934g_c_w));
	map(0x9000, 0x9fff).rw(this, FUNC(rz1_state::key_r), FUNC(rz1_state::upd934g_b_w));
	map(0xa000, 0xbfff).ram(); // sample ram 1
	map(0xc000, 0xdfff).ram(); // sample ram 2
	map(0xe000, 0xe001).w(this, FUNC(rz1_state::leds_w));
}


//**************************************************************************
//  INPUT PORT DEFINITIONS
//**************************************************************************

static INPUT_PORTS_START( rz1 )
	PORT_START("kc0")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TOM1")               PORT_CODE(KEYCODE_F1)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TOM3")               PORT_CODE(KEYCODE_F2)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIM")                PORT_CODE(KEYCODE_F3)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("OPEN HH")            PORT_CODE(KEYCODE_F4)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CLAPS")              PORT_CODE(KEYCODE_F5)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("COWBELL")            PORT_CODE(KEYCODE_F6)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TOM2")               PORT_CODE(KEYCODE_F7)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B D")                PORT_CODE(KEYCODE_F8)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S D")                PORT_CODE(KEYCODE_F9)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CLOSED HH")          PORT_CODE(KEYCODE_F10)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RIDE")               PORT_CODE(KEYCODE_F11)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CRASH")              PORT_CODE(KEYCODE_F12)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc2")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SAMPLE 1")           PORT_CODE(KEYCODE_1)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SAMPLE 2")           PORT_CODE(KEYCODE_2)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SAMPLE 3")           PORT_CODE(KEYCODE_3)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SAMPLE 4")           PORT_CODE(KEYCODE_4)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MUTE")               PORT_CODE(KEYCODE_M)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ACCENT")             PORT_CODE(KEYCODE_A)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc3")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("START/STOP")         PORT_CODE(KEYCODE_S)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CONTINUE START")     PORT_CODE(KEYCODE_C)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SAMPLING")           PORT_CODE(KEYCODE_L)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TEMPO \xe2\x96\xb3") PORT_CODE(KEYCODE_PLUS_PAD)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TEMPO \xe2\x96\xbd") PORT_CODE(KEYCODE_MINUS_PAD)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET/COPY")         PORT_CODE(KEYCODE_R)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc4")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PATTERN")                PORT_CODE(KEYCODE_P)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SONG")                   PORT_CODE(KEYCODE_O)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EDIT/RECORD")            PORT_CODE(KEYCODE_E)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DELETE")                 PORT_CODE(KEYCODE_DEL)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("INSERT/AUTO-COMPENSATE") PORT_CODE(KEYCODE_INSERT)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CHAIN/BEAT")             PORT_CODE(KEYCODE_B)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc5")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MT SAVE")            PORT_CODE(KEYCODE_5)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MT LOAD")            PORT_CODE(KEYCODE_6)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MIDI CH")            PORT_CODE(KEYCODE_7)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MIDI CLOCK")         PORT_CODE(KEYCODE_8)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNUSED)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc6")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 (1/2)")            PORT_CODE(KEYCODE_0_PAD)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1 (1/4)")            PORT_CODE(KEYCODE_1_PAD)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2 (1/6)")            PORT_CODE(KEYCODE_2_PAD)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3 (1/8)")            PORT_CODE(KEYCODE_3_PAD)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4 (1/12)")           PORT_CODE(KEYCODE_4_PAD)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5 (1/16)")           PORT_CODE(KEYCODE_5_PAD)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)

	PORT_START("kc7")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6 (1/24)")           PORT_CODE(KEYCODE_6_PAD)
	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 (1/32)")           PORT_CODE(KEYCODE_7_PAD)
	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 (1/48)")           PORT_CODE(KEYCODE_8_PAD)
	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 (1/96)")           PORT_CODE(KEYCODE_9_PAD)
	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\xe2\x96\xb3 (YES)") PORT_CODE(KEYCODE_UP)
	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\xe2\x96\xbd (NO)")  PORT_CODE(KEYCODE_DOWN)
	PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END


//**************************************************************************
//  MACHINE EMULATION
//**************************************************************************

HD44780_PIXEL_UPDATE( rz1_state::lcd_pixel_update )
{
	// char size is 5x8
	if (x > 4 || y > 7)
		return;

	if (line < 1 && pos < 16)
		bitmap.pix16(1 + y, 1 + line*8*6 + pos*6 + x) = state ? 1 : 2;
}

READ8_MEMBER( rz1_state::upd934g_c_data_r )
{
	if (offset < 0x8000)
		return m_samples[1]->base()[offset];
	else
	{
		if (offset < 0xc000)
			return m_maincpu->space(AS_PROGRAM).read_byte(offset + 0x2000);
		else
			return 0;
	}
}

READ8_MEMBER( rz1_state::upd934g_b_data_r )
{
	if (offset < 0x8000)
		return m_samples[0]->base()[offset];
	else
		return 0;
}

WRITE8_MEMBER( rz1_state::upd934g_c_w )
{
	m_pg[0]->write(space, offset >> 8, data);
}

WRITE8_MEMBER( rz1_state::upd934g_b_w )
{
	m_pg[1]->write(space, offset >> 8, data);
}

READ8_MEMBER( rz1_state::port_a_r )
{
	if ((BIT(m_port_b, 7) == 0) && (BIT(m_port_b, 6) == 1))
	{
		// Not clear why, but code expects to read busy flag from PA5 rather than PA7
		return bitswap<8>(m_hd44780->read(space, BIT(m_port_b, 5)), 5, 6, 7, 4, 3, 2, 1, 0);
	}

	logerror("port_a_r (PB = %02x)\n", m_port_b);
	return 0;
}

WRITE8_MEMBER( rz1_state::port_a_w )
{
	m_port_a = data;

	if ((BIT(m_port_b, 7) == 0) && (BIT(m_port_b, 6) == 0))
		m_hd44780->write(space, BIT(m_port_b, 5), data);
}

// 7-------  lcd e
// -6------  lcd rw
// --5-----  lcd rs
// ---4----  percussion generator reset
// ----3---  metronome trigger
// -----2--  power-on mute for line-out
// ------1-  change-over signal tom3/bd
// -------0  change-over signal tom1/tom2

WRITE8_MEMBER( rz1_state::port_b_w )
{
	if (0)
		logerror("port_b_w: %02x\n", data);

	m_port_b = data;
}

// 7-------  foot-sustain input
// -6------  cassette data out
// --5-----  cassette remote control
// ---4----  change-over signal for sampling ram
// ----3---  cassette data in
// -----2--  control signal for percussion generator c
// ------1-  midi in
// -------0  midi out

READ8_MEMBER( rz1_state::port_c_r )
{
	return 0;
}

WRITE8_MEMBER( rz1_state::port_c_w )
{
	logerror("port_c_w: %02x\n", data);
}

READ8_MEMBER( rz1_state::key_r )
{
	uint8_t data = 0;

	if (BIT(m_port_a, 0) == 0) data |= m_keys[0]->read();
	if (BIT(m_port_a, 1) == 0) data |= m_keys[1]->read();
	if (BIT(m_port_a, 2) == 0) data |= m_keys[2]->read();
	if (BIT(m_port_a, 3) == 0) data |= m_keys[3]->read();
	if (BIT(m_port_a, 4) == 0) data |= m_keys[4]->read();
	if (BIT(m_port_a, 5) == 0) data |= m_keys[5]->read();
	if (BIT(m_port_a, 6) == 0) data |= m_keys[6]->read();
	if (BIT(m_port_a, 7) == 0) data |= m_keys[7]->read();

	return data;
}

WRITE8_MEMBER( rz1_state::leds_w )
{
	output().set_value("led_song",      BIT(data, 0) == 0 ? 1 : BIT(data, 1) == 0 ? 2 : 0);
	output().set_value("led_pattern",   BIT(data, 2) == 0 ? 1 : BIT(data, 3) == 0 ? 2 : 0);
	output().set_value("led_startstop", BIT(data, 4) == 0 ? 1 : 0);
}

void rz1_state::machine_start()
{
	// register for save states
	save_item(NAME(m_port_a));
	save_item(NAME(m_port_b));
}

void rz1_state::machine_reset()
{
}

PALETTE_INIT_MEMBER(rz1_state, rz1)
{
	palette.set_pen_color(0, rgb_t(138, 146, 148)); // background
	palette.set_pen_color(1, rgb_t(92, 83, 88));    // lcd pixel on
	palette.set_pen_color(2, rgb_t(131, 136, 139)); // lcd pixel off
}

//**************************************************************************
//  MACHINE DEFINTIONS
//**************************************************************************

MACHINE_CONFIG_START( rz1_state::rz1 )
	MCFG_DEVICE_ADD("maincpu", UPD7811, 12_MHz_XTAL)
	MCFG_DEVICE_PROGRAM_MAP(map)
	MCFG_UPD7810_PORTA_READ_CB(READ8(*this, rz1_state, port_a_r))
	MCFG_UPD7810_PORTA_WRITE_CB(WRITE8(*this, rz1_state, port_a_w))
	MCFG_UPD7810_PORTB_WRITE_CB(WRITE8(*this, rz1_state, port_b_w))
	MCFG_UPD7810_PORTC_READ_CB(READ8(*this, rz1_state, port_c_r))
	MCFG_UPD7810_PORTC_WRITE_CB(WRITE8(*this, rz1_state, port_c_w))

	// video hardware
	MCFG_SCREEN_ADD("screen", LCD)
	MCFG_SCREEN_REFRESH_RATE(50)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
	MCFG_SCREEN_SIZE(6*16+1, 10)
	MCFG_SCREEN_VISIBLE_AREA(0, 6*16, 0, 10-1)
	MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update)
	MCFG_SCREEN_PALETTE("palette")

	MCFG_PALETTE_ADD("palette", 3)
	MCFG_PALETTE_INIT_OWNER(rz1_state, rz1)

	MCFG_HD44780_ADD("hd44780")
	MCFG_HD44780_LCD_SIZE(1, 16)
	MCFG_HD44780_PIXEL_UPDATE_CB(rz1_state, lcd_pixel_update)

	MCFG_DEFAULT_LAYOUT(layout_rz1)

	SPEAKER(config, "speaker").front_center();
	MCFG_DEVICE_ADD("upd934g_c", UPD934G, 1333000)
	MCFG_UPD934G_DATA_CB(READ8(*this, rz1_state, upd934g_c_data_r))
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0)
	MCFG_DEVICE_ADD("upd934g_b", UPD934G, 1280000)
	MCFG_UPD934G_DATA_CB(READ8(*this, rz1_state, upd934g_b_data_r))
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0)
MACHINE_CONFIG_END


//**************************************************************************
//  ROM DEFINITIONS
//**************************************************************************

ROM_START( rz1 )
	ROM_REGION(0x1000, "maincpu", 0)
	ROM_LOAD("upd7811.bin", 0x0000, 0x1000, CRC(597ac04a) SHA1(96451a764296eaa22aaad3cba121226dcba865f4))

	ROM_REGION(0x4000, "program", 0)
	ROM_LOAD("program.bin", 0x0000, 0x4000, CRC(b44b2652) SHA1(b77f8daece9adb177b6ce1ef518fc3238b8c0a9c))

	ROM_REGION(0x8000, "samples_a", 0)
	ROM_LOAD("sound_a.cm5", 0x0000, 0x8000, CRC(c643ff24) SHA1(e886314d22a9a5473bfa2cb237ecafcf0daedfc1)) // HN613256P

	ROM_REGION(0x8000, "samples_b", 0)
	ROM_LOAD("sound_b.cm6", 0x0000, 0x8000, CRC(ee5b703e) SHA1(cbf2e92c68901f236678d704e9e695a5c84ff49e)) // HN613256P
ROM_END


//**************************************************************************
//  SYSTEM DRIVERS
//**************************************************************************

//    YEAR  NAME  PARENT  COMPAT  MACHINE  INPUT  CLASS      INIT        COMPANY  FULLNAME  FLAGS
CONS( 1986, rz1,  0,      0,      rz1,     rz1,   rz1_state, empty_init, "Casio", "RZ-1",   MACHINE_SUPPORTS_SAVE )