summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/microtch.cpp
blob: 987da9e53e202ea6cfda6f09e9c6424a06ff8428 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                       
  
                                      
 
                                 
 

                                   
                                                                                          
 



                                                                                                                                      
                                                                





































                                                                                      

  
                

                     

                     
 

                                                                                         
 
                                                                                                                       


                                                                                                                                   
                                 
                              
                              

                                   


                                          
 

 
                                                                                                          
 
                                                            

                                                                                                                
                                                              








                         
                                                                            
 
                                              
                                             
                                                  
                                              
                                                         
                                             
                                                  
                                              

                                                         
 
                                                                



                       
                       

                           
                       


                           
                                              
                                       


                                                                  
                            
                                             
                                       


                                                                  
                     
                                              

 
                                           
 

                                  
 
                                          


                                 
                                 

                                           
                                                                       

                                            
                                                                   



                                            


                                       


         
                                                       
 
                                              
         
                                                 
                 


                                                                  
                 
 
                                                       
                 
                                                              
                 

                       
 












                                                                                     
                 

                                               
                         







                                                                                           
                         

                 
 
 
                                      
 











                                                    
                                                                            















                                                                               


                                                              
                                       



                                        
 
 
 
                                      
 

                                                           
                          
                                  

                       
                                                                          
         
                            


                                                            
                                                                                              
                                                                          
                 
                                
                                                                      
                 
                                             
                 
                                                                           
                 
                                               
                 
                                                                           
                 
                                            
                 
                                                                          
                 

                                            
                 
                                                                           
                 
                                                 
                 
                                                                           
                 
                                                  
                 
                                                                           

                                                            








                                                              

                               
                                                                           
























                                                                                    
                                



                                                      
         
 
 
                                              
 
                                             
         
                                    


         



                                                                                           
                                                                                                                                                        

                                                                                                                                              
                                                                                          
                                                                                                                                                        

       
                                    
                           
                                                                                                                                           
                             
                                                                                                                      
                             
                                                                                                                      

               




                                                                
                                      



                                                         
                                      
 
                           
         

                                                  
         
 


                                                                  
                                    
 
// license:BSD-3-Clause
// copyright-holders:Mariusz Wojcieszek
/*
    Microtouch touch screen controller

    Written by Mariusz Wojcieszek

    Notes/ToDo:
    - calibration mode (command CX)
    - only tablet format and decimal format are supported for returning touch screen state

Known MicroTouch boards use an 80C32 (compatible: Siemens, Winbond, Philips, MHS, etc.) with external ROM and a custom MicroTouch MCU.
It seems there are different MicroTouch MCU versions, named "Kahuna", "Excalibur", and probably others, with unknown differences.


ISA board ((c) 1997 MicroTouch Systems Inc. FAB 5405800 REV 2.3)
_________________________________________________________________
|                                    ______   ______             |
|                                   MM74HC04M HC125A   ____      |
|                                                      34072   __|__
|                  _______      ____       ____  ____  ____    |    |
|                  R11APB18     78M05      34072 34072 93C46S  | DB |
|                ___________  __________   ____________        | 25 |
|                |SIEMENS   | |U1 BIOS  |  |MicroTouch|        |(P1)|
|                |SAB 80C32 | |         |  |Excalibur |        |____|
|                |__________| |_________|  |__________|          |
|             ________  _______   __________                     O <- LED
|             |_LS240_| DM74LS30M |TI       |                    |
| JP2->:::::                      |TL16C450FN  ________          |
|          JP1->::::::::::::::    |_________|  |_LS245_|         |
|__       ___                                             _____  |
   |_|_|_|   |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|     |_|
                         ISA EDGE CONNECTOR

JP1 = ADDRESS / INTERRUPT (A1, A2, A3, A4, A5, A6, I2, I3, I4, I5, I10, I11, I12, I15)
JP2 = TEST (T1, T2, T3, T4, T5, T6)
Y1 = XTAL R11APB18
U3 = MicroTouch Excalibur
U4 = 80C32
U11 = 93C46S Serial EEPROM
P1 = RS-232

    JP1 ADDRESS JUMPERS
COM  ADDRESS A1 A2 A3 A4 A5 A6
--------------------------------
COM1 3F8-3FF ON  : ON  : ON  :
COM2 2F8-2FF  : ON ON  : ON  :
COM3 3E8-3EF ON  :  : ON ON  : <- DEFAULT
COM4 2E8-2EF  : ON  : ON ON  :
COM5 3E0-2E7  : ON  : ON  : ON
COM6 2F0-2F7  : ON ON  :  : ON
COM7 3E0-3E7 ON  :  : ON  : ON
COM8 3F0-3F7 ON  : ON  :  : ON

*/

#include "emu.h"
#include "microtch.h"

//#define VERBOSE 1
#include "logmacro.h"


DEFINE_DEVICE_TYPE(MICROTOUCH, microtouch_device, "microtouch", "Microtouch Touchscreen")

microtouch_device::microtouch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	device_t(mconfig, MICROTOUCH, tag, owner, clock),
	device_serial_interface(mconfig, *this),
	m_rx_buffer_ptr(0), m_tx_buffer_num(0), m_tx_buffer_ptr(0), m_reset_done(0), m_format(0), m_mode(0), m_last_touch_state(0),
	m_last_x(0), m_last_y(0),
	m_out_touch_cb(*this),
	m_out_stx_func(*this),
	m_touch(*this, "TOUCH"),
	m_touchx(*this, "TOUCH_X"),
	m_touchy(*this, "TOUCH_Y"),
	m_timer(nullptr),
	m_output_valid(false), m_output(0)
{
}

int microtouch_device::check_command( const char* commandtocheck, int command_len, uint8_t* command_data )
{
	if ((command_len == (strlen(commandtocheck) + 2)) &&
			(command_data[0] == 0x01) &&
			(strncmp(commandtocheck, (const char*)command_data + 1, strlen(commandtocheck)) == 0) &&
			(command_data[command_len-1] == 0x0d))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

void microtouch_device::send_format_table_packet(uint8_t flag, int x, int y)
{
	m_tx_buffer[m_tx_buffer_num++] = flag;
	// lower byte (7bits) of x coordinate
	m_tx_buffer[m_tx_buffer_num++] = x & 0x7f;
	// higher byte (7bits) of x coordinate
	m_tx_buffer[m_tx_buffer_num++] = (x >> 7) & 0x7f;
	// lower byte (7bits) of y coordinate
	m_tx_buffer[m_tx_buffer_num++] = y & 0x7f;
	// higher byte (7bits) of y coordinate
	m_tx_buffer[m_tx_buffer_num++] = (y >> 7) & 0x7f;
}

void microtouch_device::send_format_decimal_packet(int x, int y)
{
	int decx, decy;

	decx = x / 16;
	if (decx > 999)
		decx = 999;
	decy = y / 16;
	if (decy > 999)
		decy = 999;

	// header byte
	m_tx_buffer[m_tx_buffer_num++] = 0x01;
	// x coordinate in decimal mode
	m_tx_buffer[m_tx_buffer_num++] = (decx / 100) + '0';
	m_tx_buffer[m_tx_buffer_num++] = ((decx / 10) % 10) + '0';
	m_tx_buffer[m_tx_buffer_num++] = (decx % 10) + '0';
	// comma (separator)
	m_tx_buffer[m_tx_buffer_num++] = ',';
	// y coordinate in decimal mode
	m_tx_buffer[m_tx_buffer_num++] = (decy / 100) + '0';
	m_tx_buffer[m_tx_buffer_num++] = ((decy / 10) % 10) + '0';
	m_tx_buffer[m_tx_buffer_num++] = (decy % 10) + '0';
	// terminator
	m_tx_buffer[m_tx_buffer_num++] = 0x0d;
}

void microtouch_device::send_touch_packet()
{
	int tx = m_touchx->read();
	int ty = m_touchy->read();

	if (m_out_touch_cb(&tx, &ty) != 0)
	{
		ty = 0x4000 - ty;

		switch (m_format)
		{
			case FORMAT_TABLET:
				send_format_table_packet(0xc8, tx, ty);
				break;
			case FORMAT_DECIMAL:
				send_format_decimal_packet(tx, ty);
				break;
			case FORMAT_UNKNOWN:
				break;
		}
		m_last_touch_state = 1;
		m_last_x = tx;
		m_last_y = ty;
	}
}

TIMER_CALLBACK_MEMBER(microtouch_device::update_output)
{
	if (m_tx_buffer_ptr < m_tx_buffer_num)
	{
		if (is_transmit_register_empty())
		{
			m_output = m_tx_buffer[m_tx_buffer_ptr++];
			m_output_valid = true;
			tra_complete();
		}

		if (m_tx_buffer_ptr == m_tx_buffer_num)
		{
			m_tx_buffer_ptr = m_tx_buffer_num = 0;
		}
		return;
	}

	if (m_reset_done == 0 || m_format == FORMAT_UNKNOWN || m_mode != MODE_STREAM)
	{
		return;
	}

	// send format tablet packet
	if (m_touch->read())
	{
		send_touch_packet();
	}
	else
	{
		if (m_last_touch_state == 1)
		{
			m_last_touch_state = 0;
			switch (m_format)
			{
				case FORMAT_TABLET:
					send_format_table_packet(0x88, m_last_x, m_last_y);
					break;
				case FORMAT_DECIMAL:
					send_format_decimal_packet(m_last_x, m_last_y);
					break;
				case FORMAT_UNKNOWN:
					break;
			}
		}
	}
}

void microtouch_device::device_start()
{
	memset(m_rx_buffer, 0, sizeof(m_rx_buffer));
	memset(m_tx_buffer, 0, sizeof(m_tx_buffer));
	m_rx_buffer_ptr = 0;
	m_tx_buffer_ptr = 0;
	m_tx_buffer_num = 0;
	m_reset_done = 0;
	m_format = 0;
	m_mode = 0;
	m_last_x = 0;
	m_last_y = 0;
	m_last_touch_state = -1;

	m_timer = timer_alloc(FUNC(microtouch_device::update_output), this);
	m_timer->adjust(attotime::from_hz(167*5), 0, attotime::from_hz(167*5));

	m_format = FORMAT_UNKNOWN;
	m_mode = MODE_INACTIVE;

	save_item(NAME(m_reset_done));
	save_item(NAME(m_last_touch_state));
	save_item(NAME(m_last_x));
	save_item(NAME(m_last_y));
	save_item(NAME(m_rx_buffer));
	save_item(NAME(m_rx_buffer_ptr));
	save_item(NAME(m_tx_buffer));
	save_item(NAME(m_tx_buffer_num));
	save_item(NAME(m_tx_buffer_ptr));
	save_item(NAME(m_format));
	save_item(NAME(m_mode));
	set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); //8N1?
	set_tra_rate(clock());
	set_rcv_rate(clock());
	m_out_touch_cb.resolve_safe(1);
	m_output_valid = false;

	save_item(NAME(m_output_valid));
	save_item(NAME(m_output));
}


void microtouch_device::rcv_complete()
{
	receive_register_extract();
	m_rx_buffer[m_rx_buffer_ptr] = get_received_char();
	m_rx_buffer_ptr++;
	if (m_rx_buffer_ptr == 16)
		return;

	if (m_rx_buffer_ptr > 0 && m_rx_buffer[m_rx_buffer_ptr-1] == 0x0d)
	{
		if (VERBOSE)
		{
			char command[16];
			memset(command, 0, sizeof(command));
			strncpy( command, (const char*)m_rx_buffer + 1, m_rx_buffer_ptr - 2 );
			LOG("Microtouch: received command %s\n", command);
		}
		// check command
		if (check_command("MS", m_rx_buffer_ptr, m_rx_buffer))
		{
			m_mode = MODE_STREAM;
		}
		else if (check_command("MI", m_rx_buffer_ptr, m_rx_buffer))
		{
			m_mode = MODE_INACTIVE;
		}
		else if (check_command("MP", m_rx_buffer_ptr, m_rx_buffer))
		{
			m_mode = MODE_POINT;
		}
		else if (check_command("R", m_rx_buffer_ptr, m_rx_buffer))
		{
			m_tx_buffer_num = 0;
			m_reset_done = 1;
		}
		else if (check_command("FT", m_rx_buffer_ptr, m_rx_buffer))
		{
			m_format = FORMAT_TABLET;
		}
		else if (check_command("FD", m_rx_buffer_ptr, m_rx_buffer))
		{
			m_format = FORMAT_DECIMAL;
		}
		else if (check_command("OI", m_rx_buffer_ptr, m_rx_buffer))
		{
			// output identity - SMT3, ver 01.00
			m_tx_buffer[m_tx_buffer_num++] = 0x01;
			m_tx_buffer[m_tx_buffer_num++] = 'Q';
			m_tx_buffer[m_tx_buffer_num++] = '1';
			m_tx_buffer[m_tx_buffer_num++] = '0';
			m_tx_buffer[m_tx_buffer_num++] = '1';
			m_tx_buffer[m_tx_buffer_num++] = '0';
			m_tx_buffer[m_tx_buffer_num++] = '0';
			m_tx_buffer[m_tx_buffer_num++] = 0x0d;
			m_rx_buffer_ptr = 0;
			return;
		}
		else if (check_command("OS", m_rx_buffer_ptr, m_rx_buffer))
		{
			// output status
			m_tx_buffer[m_tx_buffer_num++] = 0x01;

			// ---- ---x    RAM error
			// ---- --x-    ROM error
			// ---- -x--    Analog-to-digital error
			// ---- x---    NOVRAM error
			// ---x ----    ASIC error
			// --x- ----    Power on flag
			// -x-- ----    Always 1
			// x--- ----    Always 0
			m_tx_buffer[m_tx_buffer_num++] = 0x40;

			// ---- ---x    Cable NOVRAM error
			// ---- --x-    Hard NOVRAM error
			// ---x xx--    Reserved
			// --x- ----    Software reset flag
			// -x-- ----    Always 1
			// x--- ----    Always 0
			m_tx_buffer[m_tx_buffer_num++] = 0x40 | (m_reset_done << 5);
			m_tx_buffer[m_tx_buffer_num++] = 0x0d;
			m_rx_buffer_ptr = 0;
			return;
		}
		// send response
		m_tx_buffer[m_tx_buffer_num++] = 0x01;
		m_tx_buffer[m_tx_buffer_num++] = 0x30;
		m_tx_buffer[m_tx_buffer_num++] = 0x0d;
		m_rx_buffer_ptr = 0;
	}
}

INPUT_CHANGED_MEMBER(microtouch_device::touch)
{
	if (newval && (m_mode == MODE_POINT))
	{
		send_touch_packet();
	}
}

// BIOS not hooked up
ROM_START(microtouch)
	ROM_REGION(0x10000, "bios", 0)
	ROM_SYSTEM_BIOS(0, "microtouch_5_6", "MicroTouch Rev.5.6") // "Excalibur", ISA card
	ROMX_LOAD("microtouch_5604010_rev_5.6.u1", 0x0000, 0x10000, CRC(d19ee080) SHA1(c695405ec8c2ac4408a63bacfc68a5a4b878928c), ROM_BIOS(0)) // 27c512
	ROM_SYSTEM_BIOS(1, "microtouch_5_5", "MicroTouch Rev.5.5") // "Kahuna", daughterboard integrated on monitor
	ROMX_LOAD("microtouch_5603920_rev_5.5.u1", 0x0000, 0x08000, CRC(5cc164e7) SHA1(753277ce54e8be1b759c37ae760fe4a6846d1fae), ROM_BIOS(1))
	ROM_SYSTEM_BIOS(2, "microtouch_2_2", "MicroTouch Rev.2.2") // "Excalibur, ISA card
	ROMX_LOAD("microtouch_5604340_rev_2.2.u1", 0x0000, 0x10000, CRC(110f312f) SHA1(5a60d7d1f8a0b3898aabcabe43dc51e9f90306f7), ROM_BIOS(2)) // 27c512
ROM_END

static INPUT_PORTS_START(microtouch)
	PORT_START("TOUCH")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Touch screen") PORT_CHANGED_MEMBER(DEVICE_SELF, microtouch_device, touch, 0)
	PORT_START("TOUCH_X")
	PORT_BIT(0x3fff, 0x2000, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
	PORT_START("TOUCH_Y")
	PORT_BIT(0x3fff, 0x2000, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
INPUT_PORTS_END

ioport_constructor microtouch_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(microtouch);
}

void microtouch_device::tra_callback()
{
	m_out_stx_func(transmit_register_get_data_bit());
}

void microtouch_device::tra_complete()
{
	if (m_output_valid)
	{
		transmit_register_setup(m_output);
		m_output_valid = false;
	}
}

const tiny_rom_entry *microtouch_device::device_rom_region() const
{
	return ROM_NAME(microtouch);
}