summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/keyboard.ipp
blob: 12221dde05c85545bb3ddceee3b66bd75b126154 (plain) (tree)
1
2
3
4
5
6
7

                              

                                 


            




                                                                       

                     


                  
                            













                                                                                                                                            
                            

                                                                       



                                                                                                                                                                           




                          
                            









                                                                        
                            






                                                                                          
                            






                                                                   
                            






                                                                                      

                                                                                                                                               






                                                      
                            

                                                                                                                    
                                                                                      



                                                              
                            

                                                                  

                                          



                                   
                            
                                                                            










                                                                
                                                                                        











                                                                 

                                


 
                            







                                                                                          
                                                                                         



 

                                                                                        





                                      

                                                                            


 
 
                            





                                                                 








                                                                                      
                                   
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
#ifndef MAME_MACHINE_KEYBOARD_IPP
#define MAME_MACHINE_KEYBOARD_IPP

#pragma once

// Work around for MSVC warning that identifies some of these as unused
#ifdef _MSC_VER
#pragma warning ( disable : 4505 )
#endif

#include "keyboard.h"

#include <numeric>


template <uint8_t ROW_COUNT>
template <typename... T>
device_matrix_keyboard_interface<ROW_COUNT>::device_matrix_keyboard_interface(machine_config const &mconfig, device_t &device, T &&... tags)
	: device_interface(device, "matrix_keyboard")
	, m_scan_timer(nullptr)
	, m_typematic_timer(nullptr)
	, m_key_rows{ { device, std::forward<T>(tags) }... }
	, m_next_row(0U)
	, m_processing(0U)
	, m_typematic_row(0U)
	, m_typematic_column(0U)
{
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::interface_pre_start()
{
	if (!m_scan_timer)
		m_scan_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_matrix_keyboard_interface<ROW_COUNT>::scan_row), this));
	if (!m_typematic_timer)
		m_typematic_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_matrix_keyboard_interface<ROW_COUNT>::typematic), this));
	reset_key_state();
	typematic_stop();
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::interface_post_start()
{
	device().save_item(NAME(m_key_states));
	device().save_item(NAME(m_next_row));
	device().save_item(NAME(m_processing));
	device().save_item(NAME(m_typematic_row));
	device().save_item(NAME(m_typematic_column));
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::start_processing(const attotime &period)
{
	m_processing = 1U;
	m_scan_timer->adjust(period, 0, period);
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::stop_processing()
{
	m_scan_timer->reset();
	m_processing = 0U;
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::reset_key_state()
{
	std::fill(std::begin(m_key_states), std::end(m_key_states), ioport_value(0U));
	m_next_row = 0U;
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::typematic_start(uint8_t row, uint8_t column, attotime const &delay, attotime const &interval)
{
	m_typematic_row = row;
	m_typematic_column = column;
	m_typematic_timer->adjust(delay, 0, interval);
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::typematic_restart(attotime const &delay, attotime const &interval)
{
	if ((m_typematic_row != uint8_t(~0U)) || (m_typematic_column != uint8_t(~0U)))
		m_typematic_timer->adjust(delay, 0, interval);
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::typematic_stop()
{
	m_typematic_row = uint8_t(~0U);
	m_typematic_column = uint8_t(~0U);
	m_typematic_timer->reset();
}


template <uint8_t ROW_COUNT>
TIMER_CALLBACK_MEMBER(device_matrix_keyboard_interface<ROW_COUNT>::scan_row)
{
	assert(m_next_row < ARRAY_LENGTH(m_key_rows));
	assert(m_next_row < ARRAY_LENGTH(m_key_states));

	will_scan_row(m_next_row);

	ioport_value &state(m_key_states[m_next_row]);
	ioport_value const keys(m_key_rows[m_next_row]->read());
	ioport_value const change(state ^ keys);

	ioport_value mask(1U);
	for (uint8_t column = 0U; m_processing && (state != keys); ++column, mask <<= 1)
	{
		if (change & mask)
		{
			state ^= mask;
			if (keys & mask)
				key_make(m_next_row, column);
			else
				key_break(m_next_row, column);
		}
	}

	m_next_row = (m_next_row + 1) % ARRAY_LENGTH(m_key_rows);
	if (m_next_row == 0)
		scan_complete();
}


template <uint8_t ROW_COUNT>
TIMER_CALLBACK_MEMBER(device_matrix_keyboard_interface<ROW_COUNT>::typematic)
{
	assert((m_typematic_row != uint8_t(~0U)) || (m_typematic_column != uint8_t(~0U)));
	key_repeat(m_typematic_row, m_typematic_column);
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::key_repeat(uint8_t row, uint8_t column)
{
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::key_break(uint8_t row, uint8_t column)
{
	if (typematic_is(row, column))
		typematic_stop();
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::will_scan_row(uint8_t row)
{
}


template <uint8_t ROW_COUNT>
void device_matrix_keyboard_interface<ROW_COUNT>::scan_complete()
{
}


template <uint8_t ROW_COUNT>
bool device_matrix_keyboard_interface<ROW_COUNT>::are_all_keys_up()
{
	return 0U == std::accumulate(
			std::begin(m_key_rows),
			std::end(m_key_rows),
			ioport_value(0),
			[] (ioport_value a, auto const &b) { return a | b->read(); });
}

#endif // MAME_MACHINE_KEYBOARD_IPP