Rewrite INS8250 to use diserial, updated Microtouch to modern and made it serial device, updated connected drivers [Carl]

This commit is contained in:
Miodrag Milanovic 2012-02-19 16:46:00 +00:00
parent d24e475f0e
commit e82fa6e24e
17 changed files with 829 additions and 821 deletions

View File

@ -76,12 +76,12 @@ void device_serial_interface::receive_register_update_bit(int bit)
int previous_bit;
//LOG(("receive register receive bit: %1x\n",bit));
previous_bit = m_rcv_register_data & 1;
previous_bit = (m_rcv_register_data & 0x8000) && 1;
/* shift previous bit 7 out */
m_rcv_register_data = m_rcv_register_data<<1;
m_rcv_register_data = m_rcv_register_data>>1;
/* shift new bit in */
m_rcv_register_data = (m_rcv_register_data & 0xfffe) | bit;
m_rcv_register_data = (m_rcv_register_data & 0x7fff) | (bit<<15);
/* update bit count received */
m_rcv_bit_count_received++;
@ -123,47 +123,34 @@ void device_serial_interface::receive_register_update_bit(int bit)
void device_serial_interface::receive_register_extract()
{
unsigned long data_shift;
UINT8 data;
receive_register_reset();
data_shift = 0;
/* if parity is even or odd, there should be a parity bit in the stream! */
if (m_df_parity!=SERIAL_PARITY_NONE)
{
data_shift++;
}
data_shift+=m_df_stop_bit_count;
/* strip off stop bits and parity */
data = m_rcv_register_data>>data_shift;
data = m_rcv_register_data>>(16-m_rcv_bit_count);
/* mask off other bits so data byte has 0's in unused bits */
data = data & (0x0ff
>>
(8-(m_df_word_length)));
data &= ~(0xff<<m_df_word_length);
m_rcv_byte_received = data;
if(m_df_parity == SERIAL_PARITY_NONE)
return;
//unsigned char computed_parity;
//unsigned char parity_received;
/* get state of parity bit received */
//parity_received = (m_rcv_register_data>>m_df_word length) & 0x01;
/* parity enable? */
switch (m_df_parity)
{
case SERIAL_PARITY_NONE:
break;
/* check parity */
case SERIAL_PARITY_ODD:
case SERIAL_PARITY_EVEN:
{
//unsigned char computed_parity;
//unsigned char parity_received;
/* get state of parity bit received */
//parity_received = (m_rcv_register_data>>m_df_stop_bit_count) & 0x01;
/* compute parity for received bits */
//computed_parity = serial_helper_get_parity(data);
@ -182,6 +169,10 @@ void device_serial_interface::receive_register_extract()
}
break;
case SERIAL_PARITY_MARK:
case SERIAL_PARITY_SPACE:
//computed_parity = parity_received;
break;
}
}
@ -225,23 +216,34 @@ void device_serial_interface::transmit_register_setup(UINT8 data_byte)
int databit;
/* get bit from data */
databit = (transmit_data>>(m_df_word_length-1)) & 0x01;
databit = transmit_data & 0x01;
/* add bit to formatted byte */
transmit_register_add_bit(databit);
transmit_data = transmit_data<<1;
transmit_data = transmit_data>>1;
}
/* parity */
if (m_df_parity!=SERIAL_PARITY_NONE)
{
/* odd or even parity */
unsigned char parity;
/* get parity */
/* if parity = 0, data has even parity - i.e. there is an even number of one bits in the data */
/* if parity = 1, data has odd parity - i.e. there is an odd number of one bits in the data */
parity = serial_helper_get_parity(data_byte);
unsigned char parity = 0;
switch(m_df_parity)
{
case SERIAL_PARITY_EVEN:
case SERIAL_PARITY_ODD:
/* get parity */
/* if parity = 0, data has even parity - i.e. there is an even number of one bits in the data */
/* if parity = 1, data has odd parity - i.e. there is an odd number of one bits in the data */
parity = serial_helper_get_parity(data_byte);
break;
case SERIAL_PARITY_MARK:
parity = 1;
break;
case SERIAL_PARITY_SPACE:
parity = 0;
break;
}
transmit_register_add_bit(parity);
}
@ -258,9 +260,7 @@ UINT8 device_serial_interface::transmit_register_get_data_bit()
{
int bit;
bit = (m_tra_register_data>>
(m_tra_bit_count - 1 -
m_tra_bit_count_transmitted)) & 0x01;
bit = (m_tra_register_data>>(m_tra_bit_count-1-m_tra_bit_count_transmitted))&1;
m_tra_bit_count_transmitted++;

View File

@ -19,7 +19,9 @@ enum
{
SERIAL_PARITY_NONE, /* no parity. a parity bit will not be in the transmitted/received data */
SERIAL_PARITY_ODD, /* odd parity */
SERIAL_PARITY_EVEN /* even parity */
SERIAL_PARITY_EVEN, /* even parity */
SERIAL_PARITY_MARK, /* one parity */
SERIAL_PARITY_SPACE /* zero parity */
};
/*

View File

@ -303,8 +303,6 @@ void bitbanger_device::bytes_to_bits_81N(void)
void bitbanger_device::device_start(void)
{
const bitbanger_config *config = (const bitbanger_config *) static_config();
/* output config */
m_build_count = 0;
m_output_timer = timer_alloc(TIMER_OUTPUT);
@ -316,13 +314,13 @@ void bitbanger_device::device_start(void)
m_input_buffer_cursor = 0;
/* defaults */
m_mode = config->m_default_mode;
m_baud = config->m_default_baud;
m_tune = config->m_default_tune;
m_mode = m_default_mode;
m_baud = m_default_baud;
m_tune = m_default_tune;
m_current_baud = attotime::from_hz(baud_value());
/* callback */
m_input_callback.resolve(config->m_input_callback, *this);
m_input_func.resolve(m_input_callback, *this);
}
@ -333,6 +331,18 @@ void bitbanger_device::device_start(void)
void bitbanger_device::device_config_complete(void)
{
const _bitbanger_config *intf = reinterpret_cast<const _bitbanger_config *>(static_config());
if(intf != NULL)
{
*static_cast<_bitbanger_config *>(this) = *intf;
}
else
{
memset(&m_input_callback, 0, sizeof(m_input_callback));
m_default_mode = 0;
m_default_baud = 0;
m_default_tune = 0;
}
update_names();
}
@ -433,10 +443,7 @@ void bitbanger_device::set_input_line(UINT8 line)
if (m_current_input != line)
{
m_current_input = line;
if (!m_input_callback.isnull())
{
m_input_callback(line ? ASSERT_LINE : CLEAR_LINE);
}
m_input_func(line ? ASSERT_LINE : CLEAR_LINE);
}
}

View File

@ -84,7 +84,8 @@ struct _bitbanger_config
class bitbanger_device : public device_t,
public device_image_interface
public device_image_interface,
public _bitbanger_config
{
public:
// construction/destruction
@ -145,7 +146,7 @@ private:
// variables
emu_timer * m_output_timer;
emu_timer * m_input_timer;
devcb_resolved_write_line m_input_callback;
devcb_resolved_write_line m_input_func;
int m_output_value;
int m_build_count;
int m_build_byte;

View File

@ -73,68 +73,35 @@ History:
**********************************************************************/
#include "emu.h"
#include "machine/ins8250.h"
const device_type INS8250 = &device_creator<ins8250_device>;
const device_type NS16450 = &device_creator<ns16450_device>;
const device_type NS16550 = &device_creator<ns16550_device>;
#define LOG(LEVEL,N,M,A) \
do { \
if(LEVEL>=N) \
{ \
if( M ) \
logerror("%-24s",(char*)M ); \
logerror A; \
} \
} while (0)
ins8250_uart_device::ins8250_uart_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, type, name, tag, owner, clock),
device_serial_interface(mconfig, *this)
{
}
ins8250_device::ins8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ins8250_uart_device(mconfig, INS8250, "ins8250", tag, owner, clock)
{
m_device_type = TYPE_INS8250;
}
/* device types */
enum {
TYPE_INS8250 = 0,
TYPE_INS8250A,
TYPE_NS16450,
TYPE_NS16550,
TYPE_NS16550A,
TYPE_PC16550D,
ns16450_device::ns16450_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ins8250_uart_device(mconfig, NS16450, "ns16450", tag, owner, clock)
{
m_device_type = TYPE_NS16450;
}
NUM_TYPES
};
/* device tags */
static const char * const device_tags[NUM_TYPES] = { "ins8250", "ins8250a", "ns16450", "ns16550", "ns16550a", "pc16550d" };
#define VERBOSE_COM 0
#define COM_LOG(n,m,a) LOG(VERBOSE_COM,n,m,a)
typedef struct {
devcb_resolved_write_line out_intr_func;
const ins8250_interface *interface;
int device_type;
UINT8 thr; /* 0 -W transmitter holding register */
UINT8 rbr; /* 0 R- receiver buffer register */
UINT8 ier; /* 1 RW interrupt enable register */
UINT8 dll; /* 0 RW divisor latch lsb (if DLAB = 1) */
UINT8 dlm; /* 1 RW divisor latch msb (if DLAB = 1) */
UINT8 iir; /* 2 R- interrupt identification register */
UINT8 lcr; /* 3 RW line control register (bit 7: DLAB) */
UINT8 mcr; /* 4 RW modem control register */
UINT8 lsr; /* 5 R- line status register */
UINT8 msr; /* 6 R- modem status register */
UINT8 scr; /* 7 RW scratch register */
/* holds int pending state for com */
UINT8 int_pending;
// sending circuit
struct {
int active;
UINT8 data;
double time;
} send;
} ins8250_t;
ns16550_device::ns16550_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ins8250_uart_device(mconfig, NS16550, "ns16550", tag, owner, clock)
{
m_device_type = TYPE_NS16550;
}
/* int's pending */
#define COM_INT_PENDING_RECEIVED_DATA_AVAILABLE 0x0001
@ -142,67 +109,30 @@ typedef struct {
#define COM_INT_PENDING_RECEIVER_LINE_STATUS 0x0004
#define COM_INT_PENDING_MODEM_STATUS_REGISTER 0x0008
INLINE ins8250_t *get_safe_token(device_t *device)
{
assert( device != NULL );
assert( ( device->type() == INS8250 ) ||
( device->type() == INS8250A ) ||
( device->type() == NS16450 ) ||
( device->type() == NS16550 ) ||
( device->type() == NS16550A ) ||
( device->type() == PC16550D ) );
return (ins8250_t *)downcast<legacy_device_base *>(device)->token();
}
/* setup iir with the priority id */
static void ins8250_setup_iir(device_t *device)
{
ins8250_t *ins8250 = get_safe_token(device);
ins8250->iir &= ~(0x04|0x02);
/* highest to lowest */
if (ins8250->ier & ins8250->int_pending & COM_INT_PENDING_RECEIVER_LINE_STATUS)
{
ins8250->iir |=0x04|0x02;
return;
}
if (ins8250->ier & ins8250->int_pending & COM_INT_PENDING_RECEIVED_DATA_AVAILABLE)
{
ins8250->iir |=0x04;
return;
}
if (ins8250->ier & ins8250->int_pending & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY)
{
ins8250->iir |=0x02;
return;
}
/* modem status has both bits clear */
}
/* ints will continue to be set for as long as there are ints pending */
static void ins8250_update_interrupt(device_t *device)
void ins8250_uart_device::update_interrupt()
{
ins8250_t *ins8250 = get_safe_token(device);
int state;
/* if any bits are set and are enabled */
if (((ins8250->int_pending&ins8250->ier) & 0x0f) != 0)
if (((m_int_pending & m_regs.ier) & 0x0f) != 0)
{
/* trigger next highest priority int */
/* set int */
state = 1;
ins8250_setup_iir(device);
m_regs.iir &= ~(0x04|0x02);
/* highest to lowest */
if (m_regs.ier & m_int_pending & COM_INT_PENDING_RECEIVER_LINE_STATUS)
m_regs.iir |=0x04|0x02;
else if (m_regs.ier & m_int_pending & COM_INT_PENDING_RECEIVED_DATA_AVAILABLE)
m_regs.iir |=0x04;
else if (m_regs.ier & m_int_pending & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY)
m_regs.iir |=0x02;
/* int pending */
ins8250->iir &= ~0x01;
m_regs.iir &= ~0x01;
}
else
{
@ -210,128 +140,127 @@ static void ins8250_update_interrupt(device_t *device)
state = 0;
/* no ints pending */
ins8250->iir |= 0x01;
m_regs.iir |= 0x01;
/* priority level */
ins8250->iir &= ~(0x04|0x02);
m_regs.iir &= ~(0x04|0x02);
}
/* set or clear the int */
ins8250->out_intr_func(state);
m_out_int_func(state);
}
/* set pending bit and trigger int */
static void ins8250_trigger_int(device_t *device, int flag)
void ins8250_uart_device::trigger_int(int flag)
{
ins8250_t *ins8250 = get_safe_token(device);
ins8250->int_pending |= flag;
ins8250_update_interrupt(device);
m_int_pending |= flag;
update_interrupt();
}
/* clear pending bit, if any ints are pending, then int will be triggered, otherwise it
will be cleared */
static void ins8250_clear_int(device_t *device, int flag)
void ins8250_uart_device::clear_int(int flag)
{
ins8250_t *ins8250 = get_safe_token(device);
ins8250->int_pending &= ~flag;
ins8250_update_interrupt(device);
m_int_pending &= ~flag;
update_interrupt();
}
WRITE8_DEVICE_HANDLER( ins8250_w )
void ins8250_uart_device::update_clock()
{
static const char P[] = "NONENHNL"; /* names for parity select */
ins8250_t *ins8250 = get_safe_token(device);
int tmp;
int baud;
if(m_regs.dl == 0)
{
m_timer->adjust(attotime::never);
return;
}
baud = clock()/(m_regs.dl*16);
m_timer->adjust(attotime::zero, 0, attotime::from_hz(baud));
}
WRITE8_MEMBER( ins8250_uart_device::ins8250_w )
{
int tmp;
switch (offset)
{
case 0:
if (ins8250->lcr & 0x80)
if (m_regs.lcr & 0x80)
{
ins8250->dll = data;
tmp = ins8250->dlm * 256 + ins8250->dll;
COM_LOG(1,"COM_dll_w",("COM \"%s\" $%02x: [$%04x = %d baud]\n", device->tag(),
data, tmp, (tmp)?(int)(ins8250->interface->clockin/16/tmp):0));
m_regs.dl = (m_regs.dl & 0xff00) | data;
update_clock();
}
else
{
ins8250->thr = data;
COM_LOG(2,"COM_thr_w",("COM $%02x\n", data));
if ( ins8250->mcr & 0x10 )
m_regs.thr = data;
m_regs.lsr &= ~0x60;
if ( m_regs.mcr & 0x10 )
{
ins8250->lsr |= 1;
ins8250->rbr = data;
ins8250_trigger_int( device, COM_INT_PENDING_RECEIVED_DATA_AVAILABLE );
m_regs.lsr |= 1;
m_regs.rbr = data;
trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
}
if ( ins8250->interface->transmit )
ins8250->interface->transmit(device, ins8250->thr);
/* writing to thr will clear the int */
ins8250_clear_int(device, COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
}
break;
case 1:
if (ins8250->lcr & 0x80)
if (m_regs.lcr & 0x80)
{
ins8250->dlm = data;
tmp = ins8250->dlm * 256 + ins8250->dll;
COM_LOG(1,"COM_dlm_w",("COM \"%s\" $%02x: [$%04x = %d baud]\n", device->tag(),
data, tmp, (tmp)?(int)(ins8250->interface->clockin/16/tmp):0));
m_regs.dl = (m_regs.dl & 0xff) | (data << 8);
update_clock();
}
else
{
ins8250->ier = data;
COM_LOG(2,"COM_ier_w",("COM \"%s\" $%02x: enable int on RX %d, THRE %d, RLS %d, MS %d\n", device->tag(),
data, data&1, (data>>1)&1, (data>>2)&1, (data>>3)&1));
COM_LOG(2,"COM_ier_w",("COM \"%s\" lsr = $%02x, int_pending = $%02x\n", device->tag(), ins8250->lsr, ins8250->int_pending ));
ins8250_update_interrupt(device);
m_regs.ier = data;
update_interrupt();
}
break;
case 2:
COM_LOG(1,"COM_fcr_w",("COM \"%s\" $%02x (16550 only)\n", device->tag(), data));
break;
case 3:
ins8250->lcr = data;
COM_LOG(1,"COM_lcr_w",("COM \"%s\" $%02x word length %d, stop bits %d, parity %c, break %d, DLAB %d\n", device->tag(),
data, 5+(data&3), 1+((data>>2)&1), P[(data>>3)&7], (data>>6)&1, (data>>7)&1));
break;
case 4:
if ( ( ins8250->mcr & 0x1f ) != ( data & 0x1f ) )
m_regs.lcr = data;
switch ((m_regs.lcr>>3) & 7)
{
ins8250->mcr = data & 0x1f;
COM_LOG(1,"COM_mcr_w",("COM \"%s\" $%02x DTR %d, RTS %d, OUT1 %d, OUT2 %d, loopback %d\n", device->tag(),
data, data&1, (data>>1)&1, (data>>2)&1, (data>>3)&1, (data>>4)&1));
if (ins8250->interface->handshake_out)
ins8250->interface->handshake_out(device,data);
case 1:
tmp = SERIAL_PARITY_ODD;
break;
case 3:
tmp = SERIAL_PARITY_EVEN;
break;
case 5:
tmp = SERIAL_PARITY_MARK;
break;
case 7:
tmp = SERIAL_PARITY_SPACE;
break;
default:
tmp = SERIAL_PARITY_NONE;
break;
}
// if 5 data bits and stb = 1, stop bits is supposed to be 1.5
set_data_frame((m_regs.lcr & 3) + 5, (m_regs.lcr & 4)?2:1, tmp);
break;
case 4:
if ( ( m_regs.mcr & 0x1f ) != ( data & 0x1f ) )
{
m_regs.mcr = data & 0x1f;
if ( ins8250->mcr & 0x10 ) /* loopback test */
if ( m_regs.mcr & 0x10 ) /* loopback test */
{
data = ( ( ins8250->mcr & 0x0c ) << 4 ) | ( ( ins8250->mcr & 0x01 ) << 5 ) | ( ( ins8250->mcr & 0x02 ) << 3 );
if ( ( ins8250->msr & 0x20 ) != ( data & 0x20 ) )
{
data = ( ( m_regs.mcr & 0x0c ) << 4 ) | ( ( m_regs.mcr & 0x01 ) << 5 ) | ( ( m_regs.mcr & 0x02 ) << 3 );
if ( ( m_regs.msr & 0x20 ) != ( data & 0x20 ) )
data |= 0x02;
}
if ( ( ins8250->msr & 0x10 ) != ( data & 0x10 ) )
{
if ( ( m_regs.msr & 0x10 ) != ( data & 0x10 ) )
data |= 0x01;
}
if ( ( ins8250->msr & 0x40 ) && ! ( data & 0x40 ) )
{
if ( ( m_regs.msr & 0x40 ) && ! ( data & 0x40 ) )
data |= 0x04;
}
if ( ( ins8250->msr & 0x80 ) != ( data & 0x80 ) )
{
if ( ( m_regs.msr & 0x80 ) != ( data & 0x80 ) )
data |= 0x08;
}
ins8250->msr = data;
m_regs.msr = data;
}
else
{
m_out_dtr_func(m_regs.mcr & 1);
m_out_rts_func((m_regs.mcr & 2) && 1);
m_out_out1_func((m_regs.mcr & 4) && 1);
m_out_out2_func((m_regs.mcr & 8) && 1);
}
}
break;
@ -341,15 +270,13 @@ WRITE8_DEVICE_HANDLER( ins8250_w )
bits 5 - 0, you could cause an interrupt if the appropriate IER bit
is set.
*/
COM_LOG(1,"COM_lsr_w",("COM \"%s\" $%02x\n", device->tag(), data ));
ins8250->lsr = data;
m_regs.lsr = data;
tmp = 0;
tmp |= ( ins8250->lsr & 0x01 ) ? COM_INT_PENDING_RECEIVED_DATA_AVAILABLE : 0;
tmp |= ( ins8250->lsr & 0x1e ) ? COM_INT_PENDING_RECEIVER_LINE_STATUS : 0;
tmp |= ( ins8250->lsr & 0x20 ) ? COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY : 0;
ins8250_trigger_int( device, tmp );
tmp |= ( m_regs.lsr & 0x01 ) ? COM_INT_PENDING_RECEIVED_DATA_AVAILABLE : 0;
tmp |= ( m_regs.lsr & 0x1e ) ? COM_INT_PENDING_RECEIVER_LINE_STATUS : 0;
tmp |= ( m_regs.lsr & 0x20 ) ? COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY : 0;
trigger_int(tmp);
break;
case 6:
@ -358,358 +285,188 @@ WRITE8_DEVICE_HANDLER( ins8250_w )
bits 3 - 0, you could cause an interrupt if the appropriate IER bit
is set.
*/
COM_LOG(1,"COM_msr_w",("COM \"%s\" $%02x\n", device->tag(), data ));
m_regs.msr = data;
ins8250->msr = data;
if ( ins8250->msr & 0x0f )
{
ins8250_trigger_int( device, COM_INT_PENDING_MODEM_STATUS_REGISTER );
}
if ( m_regs.msr & 0x0f )
trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
break;
case 7:
ins8250->scr = data;
COM_LOG(2,"COM_scr_w",("COM \"%s\" $%02x\n", device->tag(), data));
m_regs.scr = data;
break;
}
if (ins8250->interface->refresh_connected)
ins8250->interface->refresh_connected(device);
}
READ8_DEVICE_HANDLER( ins8250_r )
READ8_MEMBER( ins8250_uart_device::ins8250_r )
{
ins8250_t *ins8250 = get_safe_token(device);
int data = 0x0ff;
switch (offset)
{
case 0:
if (ins8250->lcr & 0x80)
{
data = ins8250->dll;
COM_LOG(1,"COM_dll_r",("COM \"%s\" $%02x\n", device->tag(), data));
}
if (m_regs.lcr & 0x80)
data = (m_regs.dl & 0xff);
else
{
data = ins8250->rbr;
if( ins8250->lsr & 0x01 )
{
ins8250->lsr &= ~0x01; /* clear data ready status */
COM_LOG(2,"COM_rbr_r",("COM \"%s\" $%02x\n", device->tag(), data));
}
data = m_regs.rbr;
if( m_regs.lsr & 0x01 )
m_regs.lsr &= ~0x01; /* clear data ready status */
ins8250_clear_int(device, COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
clear_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
}
break;
case 1:
if (ins8250->lcr & 0x80)
{
data = ins8250->dlm;
COM_LOG(1,"COM_dlm_r",("COM \"%s\" $%02x\n", device->tag(), data));
}
if (m_regs.lcr & 0x80)
data = (m_regs.dl >> 8);
else
{
data = ins8250->ier & 0x0f;
COM_LOG(2,"COM_ier_r",("COM \"%s\" $%02x\n", device->tag(), data));
}
data = m_regs.ier & 0x0f;
break;
case 2:
data = ins8250->iir;
COM_LOG(2,"COM_iir_r",("COM \"%s\" $%02x\n", device->tag(), data));
data = m_regs.iir;
/* The documentation says that reading this register will
clear the int if this is the source of the int */
if ( ins8250->ier & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY )
{
ins8250_clear_int(device, COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
}
if ( m_regs.ier & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY )
clear_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
break;
case 3:
data = ins8250->lcr;
COM_LOG(2,"COM_lcr_r",("COM \"%s\" $%02x\n", device->tag(), data));
data = m_regs.lcr;
break;
case 4:
data = ins8250->mcr;
COM_LOG(2,"COM_mcr_r",("COM \"%s\" $%02x\n", device->tag(), data));
data = m_regs.mcr;
break;
case 5:
#if 0
if (ins8250->send.active && (machine.time()-ins8250->send.time>uart_byte_time(n)))
{
// currently polling is enough for pc1512
ins8250->lsr |= 0x40; /* set TSRE */
ins8250->send.active = 0;
if ( ins8250->mcr & 0x10 )
{
ins8250->lsr |= 1;
ins8250->rbr = ins8250->send.data;
}
}
#endif
ins8250->lsr |= 0x60; /* set THRE */
data = ins8250->lsr;
if( ins8250->lsr & 0x1f )
{
ins8250->lsr &= 0xe1; /* clear FE, PE and OE and BREAK bits */
COM_LOG(2,"COM_lsr_r",("COM \"%s\" $%02x, DR %d, OE %d, PE %d, FE %d, BREAK %d, THRE %d, TSRE %d\n", device->tag(),
data, data&1, (data>>1)&1, (data>>2)&1, (data>>3)&1, (data>>4)&1, (data>>5)&1, (data>>6)&1));
}
data = m_regs.lsr;
if( m_regs.lsr & 0x1f )
m_regs.lsr &= 0xe1; /* clear FE, PE and OE and BREAK bits */
/* reading line status register clears int */
ins8250_clear_int(device, COM_INT_PENDING_RECEIVER_LINE_STATUS);
clear_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
break;
case 6:
data = ins8250->msr;
ins8250->msr &= 0xf0; /* reset delta values */
COM_LOG(2,"COM_msr_r",("COM \"%s\" $%02x\n", device->tag(), data));
data = m_regs.msr;
m_regs.msr &= 0xf0; /* reset delta values */
/* reading msr clears int */
ins8250_clear_int(device, COM_INT_PENDING_MODEM_STATUS_REGISTER);
clear_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
break;
case 7:
data = ins8250->scr;
COM_LOG(2,"COM_scr_r",("COM \"%s\" $%02x\n", device->tag(), data));
data = m_regs.scr;
break;
}
if (ins8250->interface->refresh_connected)
ins8250->interface->refresh_connected(device);
return data;
}
void ins8250_receive(device_t *device, int data)
void ins8250_uart_device::update_msr(int bit, UINT8 state)
{
ins8250_t *ins8250 = get_safe_token(device);
/* check if data rate 1200 baud is set */
if( ins8250->dlm != 0x00 || ins8250->dll != 0x60 )
ins8250->lsr |= 0x08; /* set framing error */
/* if data not yet serviced */
if( ins8250->lsr & 0x01 )
ins8250->lsr |= 0x02; /* set overrun error */
/* put data into receiver buffer register */
ins8250->rbr = data;
/* set data ready status */
ins8250->lsr |= 0x01;
/* set pending state for this interrupt. */
ins8250_trigger_int(device, COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
// /* OUT2 + received line data avail interrupt enabled? */
// if( (COM_mcr[n] & 0x08) && (COM_ier[n] & 0x01) )
// {
// if (com_interface.interrupt)
// com_interface.interrupt(4-(n&1), 1);
//
// }
}
/**************************************************************************
* change the modem status register
**************************************************************************/
void ins8250_handshake_in(device_t *device, int new_msr)
{
ins8250_t *ins8250 = get_safe_token(device);
/* no change in modem status bits? */
if( ((ins8250->msr ^ new_msr) & 0xf0) == 0 )
UINT8 mask = (1<<bit);
if((m_regs.msr & mask) == (state<<bit))
return;
/* set delta status bits 0..3 and new modem status bits 4..7 */
ins8250->msr = (((ins8250->msr ^ new_msr) >> 4) & 0x0f) | (new_msr & 0xf0);
ins8250_trigger_int(device, COM_INT_PENDING_MODEM_STATUS_REGISTER);
// /* set up interrupt information register */
// COM_iir[n] &= ~(0x06 | 0x01);
// /* OUT2 + modem status interrupt enabled? */
// if( (COM_mcr[n] & 0x08) && (COM_ier[n] & 0x08) )
// {
// if (com_interface.interrupt)
// com_interface.interrupt(4-(n&1), 1);
// }
m_regs.msr = (m_regs.msr & ~mask) | (mask & (state<<bit));
m_regs.msr = (m_regs.msr & ~(mask << 4)) | (1<<(bit+4));
trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
}
static void common_start( device_t *device, int device_type )
WRITE_LINE_MEMBER(ins8250_uart_device::dcd_w)
{
ins8250_t *ins8250 = get_safe_token(device);
ins8250->interface = (const ins8250_interface*)device->static_config();
ins8250->device_type = device_type;
ins8250->out_intr_func.resolve(ins8250->interface->out_intr_cb, *device);
update_msr(3, (state&&1));
}
static DEVICE_START( ins8250 )
WRITE_LINE_MEMBER(ins8250_uart_device::dsr_w)
{
common_start( device, TYPE_INS8250 );
update_msr(1, (state&&1));
}
static DEVICE_START( ins8250a )
WRITE_LINE_MEMBER(ins8250_uart_device::ri_w)
{
common_start( device, TYPE_INS8250A );
update_msr(2, (state&&1));
}
static DEVICE_START( ns16450 )
WRITE_LINE_MEMBER(ins8250_uart_device::cts_w)
{
common_start( device, TYPE_NS16450 );
update_msr(0, (state&&1));
}
static DEVICE_START( ns16550 )
void ins8250_uart_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
common_start( device, TYPE_NS16550 );
}
static DEVICE_START( ns16550a )
{
common_start( device, TYPE_NS16550A );
}
static DEVICE_START( pc16550d )
{
common_start( device, TYPE_PC16550D );
}
static DEVICE_RESET( ins8250 )
{
ins8250_t *ins8250 = get_safe_token(device);
ins8250->ier = 0;
ins8250->iir = 1;
ins8250->lcr = 0;
ins8250->mcr = 0;
ins8250->lsr = (1<<5) | (1<<6);
ins8250->send.active=0;
/* refresh with reset state of register */
if (ins8250->interface->refresh_connected)
ins8250->interface->refresh_connected(device);
}
DEVICE_GET_INFO( ins8250 )
{
switch ( state )
receive_register_update_bit(m_rx_line);
if(is_receive_register_full())
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ins8250_t); break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
if(m_regs.lsr & 0x01)
{
m_regs.lsr |= 0x02; //overrun
trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
}
else
{
m_regs.lsr |= 0x01;
receive_register_extract();
m_regs.rbr = get_received_char();
trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
}
receive_register_reset();
}
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ins8250); break;
case DEVINFO_FCT_STOP: /* nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(ins8250); break;
if(is_transmit_register_empty())
{
if(!(m_regs.lsr & 0x20))
{
transmit_register_setup(m_regs.thr);
m_regs.lsr &= ~0x40;
m_regs.lsr |= 0x20;
trigger_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
}
else
m_regs.lsr |= 0x40;
}
else
m_out_tx_func(transmit_register_get_data_bit());
}
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor INS8250/INS8250B"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "INS8250"); break;
case DEVINFO_STR_VERSION: strcpy(info->s, "1.00"); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break;
void ins8250_uart_device::device_start()
{
m_out_tx_func.resolve(m_out_tx_cb, *this);
m_out_dtr_func.resolve(m_out_dtr_cb, *this);
m_out_rts_func.resolve(m_out_rts_cb, *this);
m_out_int_func.resolve(m_out_int_cb, *this);
m_out_out1_func.resolve(m_out_out1_cb, *this);
m_out_out2_func.resolve(m_out_out2_cb, *this);
m_timer = timer_alloc();
}
void ins8250_uart_device::device_reset()
{
memset(&m_regs, '\0', sizeof(m_regs));
m_regs.ier = 0;
m_regs.iir = 1;
m_regs.lcr = 0;
m_regs.mcr = 0;
m_regs.lsr = (1<<5) | (1<<6);
m_int_pending = 0;
m_rx_line = 0;
m_timer->adjust(attotime::never);
receive_register_reset();
transmit_register_reset();
m_out_rts_func(0);
m_out_dtr_func(0);
m_out_out1_func(0);
m_out_out2_func(0);
}
void ins8250_uart_device::device_config_complete()
{
const ins8250_interface *intf = reinterpret_cast<const ins8250_interface *>(static_config());
if(intf != NULL)
{
*static_cast<ins8250_interface *>(this) = *intf;
}
else
{
memset(&m_out_tx_cb, 0, sizeof(m_out_tx_cb));
memset(&m_out_dtr_cb, 0, sizeof(m_out_dtr_cb));
memset(&m_out_rts_cb, 0, sizeof(m_out_rts_cb));
memset(&m_out_int_cb, 0, sizeof(m_out_int_cb));
memset(&m_out_out1_cb, 0, sizeof(m_out_out1_cb));
memset(&m_out_out2_cb, 0, sizeof(m_out_out2_cb));
}
}
DEVICE_GET_INFO( ins8250a )
{
switch ( state )
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor INS8250A/INS82C50A"); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ins8250a); break;
default: DEVICE_GET_INFO_CALL(ins8250); break;
}
}
DEVICE_GET_INFO( ns16450 )
{
switch ( state )
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor NS16450/PC16450"); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ns16450); break;
default: DEVICE_GET_INFO_CALL(ins8250); break;
}
}
DEVICE_GET_INFO( ns16550 )
{
switch ( state )
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor NS16550/PC16550"); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ns16550); break;
default: DEVICE_GET_INFO_CALL(ins8250); break;
}
}
DEVICE_GET_INFO( ns16550a )
{
switch ( state )
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor NS16550A/PC16550A"); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ns16550a); break;
default: DEVICE_GET_INFO_CALL(ins8250); break;
}
}
DEVICE_GET_INFO( pc16550d )
{
switch ( state )
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor PC16550D"); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(pc16550d); break;
default: DEVICE_GET_INFO_CALL(ins8250); break;
}
}
DEFINE_LEGACY_DEVICE(INS8250, ins8250);
DEFINE_LEGACY_DEVICE(INS8250A, ins8250a);
DEFINE_LEGACY_DEVICE(NS16450, ns16450);
DEFINE_LEGACY_DEVICE(NS16550, ns16550);
DEFINE_LEGACY_DEVICE(NS16550A, ns16550a);
DEFINE_LEGACY_DEVICE(PC16550D, pc16550d);

View File

@ -7,77 +7,120 @@
#ifndef __INS8250_H_
#define __INS8250_H_
#include "devlegcy.h"
DECLARE_LEGACY_DEVICE(INS8250, ins8250);
DECLARE_LEGACY_DEVICE(INS8250A, ins8250a);
DECLARE_LEGACY_DEVICE(NS16450, ns16450);
DECLARE_LEGACY_DEVICE(NS16550, ns16550);
DECLARE_LEGACY_DEVICE(NS16550A, ns16550a);
DECLARE_LEGACY_DEVICE(PC16550D, pc16550d);
#define UART8250_HANDSHAKE_OUT_DTR 0x01
#define UART8250_HANDSHAKE_OUT_RTS 0x02
#define UART8250_HANDSHAKE_IN_DSR 0x020
#define UART8250_HANDSHAKE_IN_CTS 0x010
#define UART8250_INPUTS_RING_INDICATOR 0x0040
#define UART8250_INPUTS_DATA_CARRIER_DETECT 0x0080
#include "emu.h"
/***************************************************************************
TYPE DEFINITIONS
CLASS DEFINITIONS
***************************************************************************/
typedef void (*ins8250_transmit_func)(device_t *device, int data);
typedef void (*ins8250_handshake_out_func)(device_t *device, int data);
typedef void (*ins8250_refresh_connect_func)(device_t *device);
#define INS8250_TRANSMIT(name) void name(device_t *device, int data)
#define INS8250_HANDSHAKE_OUT(name) void name(device_t *device, int data)
#define INS8250_REFRESH_CONNECT(name) void name(device_t *device)
typedef struct
struct ins8250_interface
{
long clockin;
devcb_write_line out_intr_cb;
devcb_write_line m_out_tx_cb;
devcb_write_line m_out_dtr_cb;
devcb_write_line m_out_rts_cb;
devcb_write_line m_out_int_cb;
devcb_write_line m_out_out1_cb;
devcb_write_line m_out_out2_cb;
};
ins8250_transmit_func transmit;
ins8250_handshake_out_func handshake_out;
class ins8250_uart_device : public device_t,
public device_serial_interface,
public ins8250_interface
{
public:
ins8250_uart_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock);
DECLARE_WRITE8_MEMBER( ins8250_w );
DECLARE_READ8_MEMBER( ins8250_r );
DECLARE_WRITE_LINE_MEMBER( dcd_w );
DECLARE_WRITE_LINE_MEMBER( dsr_w );
DECLARE_WRITE_LINE_MEMBER( ri_w );
DECLARE_WRITE_LINE_MEMBER( cts_w );
DECLARE_WRITE_LINE_MEMBER( rx_w ) { m_rx_line = state; }
void input_callback(UINT8 state) { m_input_state = state; }
// refresh object connected to this port
ins8250_refresh_connect_func refresh_connected;
} ins8250_interface;
protected:
virtual void device_start();
virtual void device_config_complete();
virtual void device_reset();
enum {
TYPE_INS8250 = 0,
TYPE_INS8250A,
TYPE_NS16450,
TYPE_NS16550,
TYPE_NS16550A,
TYPE_PC16550D,
};
int m_device_type;
private:
struct {
UINT8 thr; /* 0 -W transmitter holding register */
UINT8 rbr; /* 0 R- receiver buffer register */
UINT8 ier; /* 1 RW interrupt enable register */
UINT16 dl; /* 0/1 RW divisor latch (if DLAB = 1) */
UINT8 iir; /* 2 R- interrupt identification register */
UINT8 lcr; /* 3 RW line control register (bit 7: DLAB) */
UINT8 mcr; /* 4 RW modem control register */
UINT8 lsr; /* 5 R- line status register */
UINT8 msr; /* 6 R- modem status register */
UINT8 scr; /* 7 RW scratch register */
} m_regs;
UINT8 m_int_pending;
UINT8 m_rx_line;
devcb_resolved_write_line m_out_tx_func;
devcb_resolved_write_line m_out_dtr_func;
devcb_resolved_write_line m_out_rts_func;
devcb_resolved_write_line m_out_int_func;
devcb_resolved_write_line m_out_out1_func;
devcb_resolved_write_line m_out_out2_func;
void update_interrupt();
void update_clock();
void trigger_int(int flag);
void clear_int(int flag);
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
void update_msr(int bit, UINT8 state);
emu_timer *m_timer;
};
class ins8250_device : public ins8250_uart_device
{
public:
ins8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class ns16450_device : public ins8250_uart_device
{
public:
ns16450_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class ns16550_device : public ins8250_uart_device
{
public:
ns16550_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
extern const device_type INS8250;
extern const device_type NS16450;
extern const device_type NS16550;
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
#define MCFG_INS8250_ADD(_tag, _intrf) \
MCFG_DEVICE_ADD(_tag, INS8250, 0) \
#define MCFG_INS8250_ADD(_tag, _intrf, _clock) \
MCFG_DEVICE_ADD(_tag, INS8250, _clock) \
MCFG_DEVICE_CONFIG(_intrf)
#define MCFG_NS16450_ADD(_tag, _intrf) \
MCFG_DEVICE_ADD(_tag, NS16450, 0) \
#define MCFG_NS16450_ADD(_tag, _intrf, _clock) \
MCFG_DEVICE_ADD(_tag, NS16450, _clock) \
MCFG_DEVICE_CONFIG(_intrf)
#define MCFG_NS16550_ADD(_tag, _intrf) \
MCFG_DEVICE_ADD(_tag, NS16550, 0) \
#define MCFG_NS16550_ADD(_tag, _intrf, _clock) \
MCFG_DEVICE_ADD(_tag, NS16550, _clock) \
MCFG_DEVICE_CONFIG(_intrf)
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
void ins8250_receive(device_t *device, int data);
void ins8250_handshake_in(device_t *device, int new_msr);
READ8_DEVICE_HANDLER( ins8250_r );
WRITE8_DEVICE_HANDLER( ins8250_w );
#endif /* __INS8250_H_ */
#endif

View File

@ -9,49 +9,23 @@
*/
#include "emu.h"
#include "microtch.h"
#define LOG 0
enum MICROTOUCH_FORMAT
const device_type MICROTOUCH = &device_creator<microtouch_device>;
microtouch_device::microtouch_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, type, name, tag, owner, clock)
{
FORMAT_UNKNOWN,
FORMAT_TABLET,
FORMAT_DECIMAL
};
}
ALLOW_SAVE_TYPE(MICROTOUCH_FORMAT);
enum MICROTOUCH_MODE
microtouch_device::microtouch_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MICROTOUCH, "Microtouch Touchscreen", tag, owner, clock)
{
MODE_INACTIVE,
MODE_STREAM,
MODE_POINT
};
}
ALLOW_SAVE_TYPE(MICROTOUCH_MODE);
static struct
{
UINT8 rx_buffer[16];
int rx_buffer_ptr;
emu_timer* timer;
UINT8 tx_buffer[16];
UINT8 tx_buffer_num;
UINT8 tx_buffer_ptr;
int reset_done;
MICROTOUCH_FORMAT format;
MICROTOUCH_MODE mode;
int last_touch_state;
int last_x;
int last_y;
microtouch_tx_func tx_callback;
microtouch_touch_func touch_callback;
} microtouch;
static int microtouch_check_command( const char* commandtocheck, int command_len, UINT8* command_data )
int microtouch_device::check_command( const char* commandtocheck, int command_len, UINT8* command_data )
{
if ( (command_len == (strlen(commandtocheck) + 2)) &&
(command_data[0] == 0x01) &&
@ -66,20 +40,20 @@ static int microtouch_check_command( const char* commandtocheck, int command_len
}
}
static void microtouch_send_format_table_packet(UINT8 flag, int x, int y)
void microtouch_device::send_format_table_packet(UINT8 flag, int x, int y)
{
microtouch.tx_buffer[microtouch.tx_buffer_num++] = flag;
m_tx_buffer[m_tx_buffer_num++] = flag;
// lower byte (7bits) of x coordinate
microtouch.tx_buffer[microtouch.tx_buffer_num++] = x & 0x7f;
m_tx_buffer[m_tx_buffer_num++] = x & 0x7f;
// higher byte (7bits) of x coordinate
microtouch.tx_buffer[microtouch.tx_buffer_num++] = (x >> 7) & 0x7f;
m_tx_buffer[m_tx_buffer_num++] = (x >> 7) & 0x7f;
// lower byte (7bits) of y coordinate
microtouch.tx_buffer[microtouch.tx_buffer_num++] = y & 0x7f;
m_tx_buffer[m_tx_buffer_num++] = y & 0x7f;
// higher byte (7bits) of y coordinate
microtouch.tx_buffer[microtouch.tx_buffer_num++] = (y >> 7) & 0x7f;
};
m_tx_buffer[m_tx_buffer_num++] = (y >> 7) & 0x7f;
}
static void microtouch_send_format_decimal_packet(int x, int y)
void microtouch_device::send_format_decimal_packet(int x, int y)
{
int decx, decy;
@ -91,201 +65,284 @@ static void microtouch_send_format_decimal_packet(int x, int y)
decy = 999;
// header byte
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x01;
m_tx_buffer[m_tx_buffer_num++] = 0x01;
// x coordinate in decimal mode
microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decx / 100) + '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = ((decx / 10) % 10) + '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decx % 10) + '0';
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)
microtouch.tx_buffer[microtouch.tx_buffer_num++] = ',';
m_tx_buffer[m_tx_buffer_num++] = ',';
// y coordinate in decimal mode
microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decy / 100) + '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = ((decy / 10) % 10) + '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decy % 10) + '0';
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
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x0d;
m_tx_buffer[m_tx_buffer_num++] = 0x0d;
}
static void microtouch_send_touch_packet(running_machine &machine)
void microtouch_device::send_touch_packet()
{
int tx = input_port_read(machine, "TOUCH_X");
int ty = input_port_read(machine, "TOUCH_Y");
int tx = input_port_read(*this, "TOUCH_X");
int ty = input_port_read(*this, "TOUCH_Y");
if ( microtouch.touch_callback == NULL ||
microtouch.touch_callback( machine, &tx, &ty ) != 0 )
if ( m_out_touch_cb == NULL ||
m_out_touch_cb( &tx, &ty ) != 0 )
{
ty = 0x4000 - ty;
switch( microtouch.format )
switch( m_format )
{
case FORMAT_TABLET:
microtouch_send_format_table_packet(0xc8, tx, ty);
send_format_table_packet(0xc8, tx, ty);
break;
case FORMAT_DECIMAL:
microtouch_send_format_decimal_packet(tx, ty);
send_format_decimal_packet(tx, ty);
break;
case FORMAT_UNKNOWN:
break;
}
microtouch.last_touch_state = 1;
microtouch.last_x = tx;
microtouch.last_y = ty;
m_last_touch_state = 1;
m_last_x = tx;
m_last_y = ty;
}
}
static TIMER_CALLBACK(microtouch_timer_callback)
void microtouch_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if ( microtouch.tx_buffer_ptr < microtouch.tx_buffer_num )
if ( m_tx_buffer_ptr < m_tx_buffer_num )
{
microtouch.tx_callback( machine, microtouch.tx_buffer[microtouch.tx_buffer_ptr++] );
if ( microtouch.tx_buffer_ptr == microtouch.tx_buffer_num )
tx( m_tx_buffer[m_tx_buffer_ptr++] );
if ( m_tx_buffer_ptr == m_tx_buffer_num )
{
microtouch.tx_buffer_ptr = microtouch.tx_buffer_num = 0;
m_tx_buffer_ptr = m_tx_buffer_num = 0;
}
return;
}
if ( (microtouch.reset_done == 0) ||
(microtouch.format == FORMAT_UNKNOWN) ||
(microtouch.mode != MODE_STREAM))
if ( (m_reset_done == 0) ||
(m_format == FORMAT_UNKNOWN) ||
(m_mode != MODE_STREAM))
{
return;
}
// send format tablet packet
if ( input_port_read(machine, "TOUCH") & 0x01 )
if ( input_port_read(*this, "TOUCH") & 0x01 )
{
microtouch_send_touch_packet(machine);
send_touch_packet();
}
else
{
if ( microtouch.last_touch_state == 1 )
if ( m_last_touch_state == 1 )
{
microtouch.last_touch_state = 0;
switch( microtouch.format )
m_last_touch_state = 0;
switch( m_format )
{
case FORMAT_TABLET:
microtouch_send_format_table_packet(0x88, microtouch.last_x, microtouch.last_y);
send_format_table_packet(0x88, m_last_x, m_last_y);
break;
case FORMAT_DECIMAL:
microtouch_send_format_decimal_packet(microtouch.last_x, microtouch.last_y);
send_format_decimal_packet(m_last_x, m_last_y);
break;
case FORMAT_UNKNOWN:
break;
}
}
}
};
}
void microtouch_init(running_machine &machine, microtouch_tx_func tx_cb, microtouch_touch_func touch_cb)
void microtouch_device::device_config_complete()
{
memset(&microtouch, 0, sizeof(microtouch));
microtouch.last_touch_state = -1;
microtouch.tx_callback = tx_cb;
microtouch.touch_callback = touch_cb;
microtouch.timer = machine.scheduler().timer_alloc(FUNC(microtouch_timer_callback));
microtouch.timer->adjust(attotime::from_hz(167*5), 0, attotime::from_hz(167*5));
microtouch.format = FORMAT_UNKNOWN;
microtouch.mode = MODE_INACTIVE;
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.reset_done);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.last_touch_state);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.last_x);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.last_y);
state_save_register_item_array(machine, "microtouch", NULL, 0, microtouch.rx_buffer);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.rx_buffer_ptr);
state_save_register_item_array(machine, "microtouch", NULL, 0, microtouch.tx_buffer);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.tx_buffer_num);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.tx_buffer_ptr);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.format);
state_save_register_item(machine, "microtouch", NULL, 0, microtouch.mode);
};
void microtouch_rx(int count, UINT8* data)
{
int i;
for ( i = 0; (i < count) && ((microtouch.rx_buffer_ptr + i) < 16); i++ )
const microtouch_interface *intf = reinterpret_cast<const microtouch_interface *>(static_config());
if(intf != NULL)
*static_cast<microtouch_interface *>(this) = *intf;
else
{
microtouch.rx_buffer[i+microtouch.rx_buffer_ptr] = data[i];
microtouch.rx_buffer_ptr++;
memset(&m_out_tx_cb, 0, sizeof(m_out_tx_cb));
memset(&m_out_touch_cb, 0, sizeof(m_out_touch_cb));
}
}
if (microtouch.rx_buffer_ptr > 0 && (microtouch.rx_buffer[microtouch.rx_buffer_ptr-1] == 0x0d))
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();
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));
m_out_tx_func.resolve(m_out_tx_cb, *this);
}
WRITE8_MEMBER(microtouch_device::rx)
{
m_rx_buffer[m_rx_buffer_ptr] = data;
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 (LOG)
{
char command[16];
memset(command, 0, sizeof(command));
strncpy( command, (const char*)microtouch.rx_buffer + 1, microtouch.rx_buffer_ptr - 2 );
strncpy( command, (const char*)m_rx_buffer + 1, m_rx_buffer_ptr - 2 );
logerror("Microtouch: received command %s\n", command);
}
// check command
if ( microtouch_check_command( "MS", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
if ( check_command( "MS", m_rx_buffer_ptr, m_rx_buffer ) )
{
microtouch.mode = MODE_STREAM;
m_mode = MODE_STREAM;
}
else if ( microtouch_check_command( "MI", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
else if ( check_command( "MI", m_rx_buffer_ptr, m_rx_buffer ) )
{
microtouch.mode = MODE_INACTIVE;
m_mode = MODE_INACTIVE;
}
else if ( microtouch_check_command( "MP", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
else if ( check_command( "MP", m_rx_buffer_ptr, m_rx_buffer ) )
{
microtouch.mode = MODE_POINT;
m_mode = MODE_POINT;
}
else if ( microtouch_check_command( "R", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
else if ( check_command( "R", m_rx_buffer_ptr, m_rx_buffer ) )
{
microtouch.tx_buffer_num = 0;
microtouch.reset_done = 1;
m_tx_buffer_num = 0;
m_reset_done = 1;
}
else if ( microtouch_check_command( "FT", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
else if ( check_command( "FT", m_rx_buffer_ptr, m_rx_buffer ) )
{
microtouch.format = FORMAT_TABLET;
m_format = FORMAT_TABLET;
}
else if ( microtouch_check_command( "FD", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
else if ( check_command( "FD", m_rx_buffer_ptr, m_rx_buffer ) )
{
microtouch.format = FORMAT_DECIMAL;
m_format = FORMAT_DECIMAL;
}
else if ( microtouch_check_command("OI", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) )
else if ( check_command("OI", m_rx_buffer_ptr, m_rx_buffer ) )
{
// output identity - SMT3, ver 01.00
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x01;
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 'Q';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = '1';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = '1';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = '0';
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x0d;
microtouch.rx_buffer_ptr = 0;
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;
}
// send response
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x01;
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x30;
microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x0d;
microtouch.rx_buffer_ptr = 0;
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;
}
};
static INPUT_CHANGED( microtouch_touch )
INPUT_CHANGED_MEMBER( microtouch_device::touch )
{
if ( newval && ( microtouch.mode == MODE_POINT ) )
if ( newval && ( m_mode == MODE_POINT ) )
{
microtouch_send_touch_packet( field.machine() );
send_touch_packet();
}
}
INPUT_PORTS_START(microtouch)
static INPUT_PORTS_START(microtouch)
PORT_START("TOUCH")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME( "Touch screen" ) PORT_CHANGED( microtouch_touch, 0 )
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);
}
const device_type MICROTOUCH_SERIAL = &device_creator<microtouch_serial_device>;
microtouch_serial_device::microtouch_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: microtouch_device(mconfig, MICROTOUCH_SERIAL, "Microtouch Serial Touchscreen", tag, owner, clock),
device_serial_interface(mconfig, *this)
{
}
void microtouch_serial_device::device_config_complete()
{
const microtouch_serial_interface *intf = reinterpret_cast<const microtouch_serial_interface *>(static_config());
if(intf != NULL)
*static_cast<microtouch_serial_interface *>(this) = *intf;
else
{
memset(&m_out_stx_cb, 0, sizeof(m_out_stx_cb));
}
memset(&(microtouch_interface::m_out_tx_cb), 0, sizeof(microtouch_interface::m_out_tx_cb));
memset(&m_out_touch_cb, 0, sizeof(m_out_touch_cb));
}
void microtouch_serial_device::device_start()
{
microtouch_device::device_start();
m_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
set_data_frame(8, 1, SERIAL_PARITY_NONE); //8N1?
m_out_stx_func.resolve(m_out_stx_cb, *this);
m_count = 0;
m_output_valid = false;
save_item(NAME(m_count));
save_item(NAME(m_output_valid));
save_item(NAME(m_output));
save_item(NAME(m_rx_line));
}
void microtouch_serial_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if(is_transmit_register_empty())
{
if(m_output_valid)
{
transmit_register_setup(m_output);
m_output_valid = false;
}
}
else
m_out_stx_func(transmit_register_get_data_bit());
receive_register_update_bit(m_rx_line);
if(is_receive_register_full())
{
receive_register_extract();
microtouch_device::rx(*memory_nonspecific_space(machine()), 0, get_received_char());
receive_register_reset();
}
if((m_count == 0) && (m_output_valid == false))
microtouch_device::device_timer(timer, id, param, ptr);
++m_count %= 8;
}

View File

@ -1,12 +1,104 @@
#ifndef _MICROTOUCH_H
#define _MICROTOUCH_H
INPUT_PORTS_EXTERN(microtouch);
#include "emu.h"
typedef void (*microtouch_tx_func)(running_machine &machine, UINT8 data);
typedef int (*microtouch_touch_func)(running_machine &machine, int *touch_x, int *touch_y);
typedef int (*microtouch_touch_func)(int *touch_x, int *touch_y);
#define MICROTOUCH_TOUCH(name) int name(int *touch_x, int *touch_y)
void microtouch_init(running_machine &machine, microtouch_tx_func tx_cb, microtouch_touch_func touch_cb);
void microtouch_rx(int count, UINT8* data);
struct microtouch_interface
{
devcb_write8 m_out_tx_cb;
microtouch_touch_func m_out_touch_cb;
};
class microtouch_device :
public device_t,
public microtouch_interface
{
public:
microtouch_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock);
microtouch_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ioport_constructor device_input_ports() const;
DECLARE_WRITE8_MEMBER(rx);
DECLARE_INPUT_CHANGED_MEMBER(touch);
protected:
virtual void device_start();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
virtual void device_config_complete();
virtual void tx(UINT8 data) { m_out_tx_func(0, data); }
emu_timer* m_timer;
private:
int check_command( const char* commandtocheck, int command_len, UINT8* command_data );
void send_format_table_packet(UINT8 flag, int x, int y);
void send_format_decimal_packet(int x, int y);
void send_touch_packet();
enum
{
FORMAT_UNKNOWN,
FORMAT_TABLET,
FORMAT_DECIMAL
};
enum
{
MODE_INACTIVE,
MODE_STREAM,
MODE_POINT
};
UINT8 m_rx_buffer[16];
int m_rx_buffer_ptr;
UINT8 m_tx_buffer[16];
UINT8 m_tx_buffer_num;
UINT8 m_tx_buffer_ptr;
int m_reset_done;
int m_format;
int m_mode;
int m_last_touch_state;
int m_last_x;
int m_last_y;
devcb_resolved_write8 m_out_tx_func;
};
extern const device_type MICROTOUCH;
#define MCFG_MICROTOUCH_ADD(_tag, _intrf) \
MCFG_DEVICE_ADD(_tag, MICROTOUCH, 0) \
MCFG_DEVICE_CONFIG(_intrf)
struct microtouch_serial_interface
{
devcb_write_line m_out_stx_cb;
};
class microtouch_serial_device
: public microtouch_device,
public device_serial_interface,
public microtouch_serial_interface
{
public:
microtouch_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_WRITE_LINE_MEMBER(rx) {m_rx_line = state;}
protected:
virtual void device_start();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
virtual void device_config_complete();
virtual void tx(UINT8 data) {m_output = data; m_output_valid = true;}
virtual void input_callback(UINT8 state) { m_input_state = state; }
private:
int m_count;
bool m_output_valid;
UINT8 m_output;
UINT8 m_rx_line;
devcb_resolved_write_line m_out_stx_func;
};
extern const device_type MICROTOUCH_SERIAL;
#define MCFG_MICROTOUCH_SERIAL_ADD(_tag, _intrf, _clock) \
MCFG_DEVICE_ADD(_tag, MICROTOUCH_SERIAL, _clock) \
MCFG_DEVICE_CONFIG(_intrf)
#endif //_MICROTOUCH_H

View File

@ -55,7 +55,7 @@ typedef struct
PC16552D_CHANNEL ch[2];
int frequency;
void (* irq_handler)(running_machine &machine, int channel, int value);
void (* tx_callback)(int channel, int count, UINT8* data);
void (* tx_callback)(running_machine &machine, int channel, int count, UINT8* data);
} PC16552D_REGS;
#define MAX_PC16552D_CHIPS 4
@ -151,7 +151,7 @@ static TIMER_CALLBACK( tx_fifo_timer_callback )
ch = &duart[chip].ch[channel];
if (duart[chip].tx_callback)
duart[chip].tx_callback(channel, ch->tx_fifo_num, ch->tx_fifo);
duart[chip].tx_callback(machine, channel, ch->tx_fifo_num, ch->tx_fifo);
ch->tx_fifo_num = 0;
@ -387,7 +387,7 @@ static void duart_w(running_machine &machine, int chip, int reg, UINT8 data)
/*****************************************************************************/
void pc16552d_init(running_machine &machine, int chip, int frequency, void (* irq_handler)(running_machine &machine, int channel, int value), void (* tx_callback)(int channel, int count, UINT8* data))
void pc16552d_init(running_machine &machine, int chip, int frequency, void (* irq_handler)(running_machine &machine, int channel, int value), void (* tx_callback)(running_machine &machine, int channel, int count, UINT8* data))
{
memset(&duart[chip], 0, sizeof(PC16552D_REGS));

View File

@ -1,7 +1,7 @@
#ifndef PC16552D_H
#define PC16552D_H
void pc16552d_init(running_machine &machine, int chip, int frequency, void (* irq_handler)(running_machine &machine, int channel, int value), void (* tx_callback)(int channel, int count, UINT8* data));
void pc16552d_init(running_machine &machine, int chip, int frequency, void (* irq_handler)(running_machine &machine, int channel, int value), void (* tx_callback)(running_machine &machine, int channel, int count, UINT8* data));
void pc16552d_rx_data(running_machine &machine, int chip, int channel, UINT8 data);
READ8_HANDLER(pc16552d_0_r);

View File

@ -157,11 +157,14 @@ class adp_state : public driver_device
public:
adp_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_h63484(*this, "h63484")
m_h63484(*this, "h63484"),
m_microtouch(*this, "microtouch")
{ }
required_device<h63484_device> m_h63484;
required_device<microtouch_device> m_microtouch;
DECLARE_WRITE8_MEMBER(microtouch_tx);
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
/* misc */
@ -262,20 +265,20 @@ static void duart_irq_handler( device_t *device, UINT8 vector )
{
adp_state *state = device->machine().driver_data<adp_state>();
device_set_input_line_and_vector(state->m_maincpu, 4, HOLD_LINE, vector);
};
}
static void duart_tx( device_t *device, int channel, UINT8 data )
{
adp_state *state = device->machine().driver_data<adp_state>();
if (channel == 0)
{
microtouch_rx(1, &data);
state->m_microtouch->rx(*memory_nonspecific_space(device->machine()), 0, data);
}
};
}
static void microtouch_tx( running_machine &machine, UINT8 data )
WRITE8_MEMBER( adp_state::microtouch_tx )
{
adp_state *state = machine.driver_data<adp_state>();
duart68681_rx_data(state->m_duart, 0, data);
duart68681_rx_data(m_duart, 0, data);
}
static UINT8 duart_input( device_t *device )
@ -283,10 +286,15 @@ static UINT8 duart_input( device_t *device )
return input_port_read(device->machine(), "DSW1");
}
static const microtouch_interface adb_microtouch_config =
{
DEVCB_DRIVER_MEMBER(adp_state, microtouch_tx),
NULL
};
static MACHINE_START( skattv )
{
adp_state *state = machine.driver_data<adp_state>();
microtouch_init(machine, microtouch_tx, 0);
state->m_maincpu = machine.device("maincpu");
state->m_duart = machine.device("duart68681");
@ -530,8 +538,6 @@ INPUT_PORTS_END
#endif
static INPUT_PORTS_START( skattv )
PORT_INCLUDE(microtouch)
PORT_START("DSW1")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_COIN5 )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN6 )
@ -661,6 +667,7 @@ static MACHINE_CONFIG_START( quickjac, adp_state )
MCFG_MACHINE_RESET(skattv)
MCFG_DUART68681_ADD( "duart68681", XTAL_8_664MHz / 2, skattv_duart68681_config )
MCFG_MICROTOUCH_ADD( "microtouch", adb_microtouch_config )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
@ -692,6 +699,7 @@ static MACHINE_CONFIG_START( skattv, adp_state )
MCFG_MACHINE_RESET(skattv)
MCFG_DUART68681_ADD( "duart68681", XTAL_8_664MHz / 2, skattv_duart68681_config )
MCFG_MICROTOUCH_ADD( "microtouch", adb_microtouch_config )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
@ -719,6 +727,7 @@ static MACHINE_CONFIG_START( backgamn, adp_state )
MCFG_CPU_PROGRAM_MAP(backgamn_mem)
MCFG_DUART68681_ADD( "duart68681", XTAL_8_664MHz / 2, skattv_duart68681_config )
MCFG_MICROTOUCH_ADD( "microtouch", adb_microtouch_config )
MCFG_MACHINE_START(skattv)
MCFG_MACHINE_RESET(skattv)

View File

@ -35,7 +35,6 @@
#include "includes/cd32.h"
#include "sound/cdda.h"
#include "imagedev/chd_cd.h"
#include "machine/microtch.h"
#include "machine/amigafdc.h"
#define CD32PAL_XTAL_X1 XTAL_28_37516MHz
@ -760,6 +759,12 @@ static const i2cmem_interface i2cmem_interface =
I2CMEM_SLAVE_ADDRESS, NVRAM_PAGE_SIZE, NVRAM_SIZE
};
static const microtouch_interface cd32_microtouch_config =
{
DEVCB_DRIVER_MEMBER(cd32_state, microtouch_tx),
NULL
};
static MACHINE_CONFIG_START( cd32base, cd32_state )
/* basic machine hardware */
@ -800,6 +805,8 @@ static MACHINE_CONFIG_START( cd32base, cd32_state )
MCFG_MOS8520_ADD("cia_0", AMIGA_68EC020_PAL_CLOCK / 10, cia_0_intf)
MCFG_MOS8520_ADD("cia_1", AMIGA_68EC020_PAL_CLOCK / 10, cia_1_intf)
MCFG_MICROTOUCH_ADD( "microtouch", cd32_microtouch_config )
/* fdc */
MCFG_AMIGA_FDC_ADD("fdc", AMIGA_68000_NTSC_CLOCK)
MACHINE_CONFIG_END
@ -1375,8 +1382,6 @@ static DRIVER_INIT(mgprem11)
static INPUT_PORTS_START( odeontw2 )
// PORT_INCLUDE( cd32 )
PORT_INCLUDE( microtouch )
PORT_START("CIA0PORTA")
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -1440,14 +1445,15 @@ INPUT_PORTS_END
static void serial_w(running_machine &machine, UINT16 data)
{
cd32_state *state = machine.driver_data<cd32_state>();
UINT8 data8 = data & 0xff;
if ( data8 != 0x00 )
microtouch_rx(1, &data8);
state->m_microtouch->rx(*memory_nonspecific_space(machine), 0, data8);
}
static void microtouch_tx(running_machine &machine, UINT8 data)
WRITE8_MEMBER (cd32_state::microtouch_tx)
{
amiga_serial_in_w(machine, data);
amiga_serial_in_w(machine(), data);
}
static DRIVER_INIT( odeontw2 )
@ -1472,9 +1478,6 @@ static DRIVER_INIT( odeontw2 )
/* input hack */
state->m_input_hack = NULL;
/* touch screen */
microtouch_init(machine, microtouch_tx, NULL);
}
/***************************************************************************************************/

View File

@ -85,8 +85,16 @@ class magtouch_state : public driver_device
{
public:
magtouch_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_uart(*this, "ns16450_0"),
m_microtouch(*this, "microtouch")
{ }
required_device<ns16450_device> m_uart;
required_device<microtouch_serial_device> m_microtouch;
DECLARE_WRITE_LINE_MEMBER(microtouch_out);
DECLARE_WRITE_LINE_MEMBER(microtouch_in);
};
@ -96,15 +104,14 @@ public:
*
*************************************/
static void magtouch_microtouch_tx_callback(running_machine &machine, UINT8 data)
WRITE_LINE_MEMBER(magtouch_state::microtouch_out)
{
ins8250_receive(machine.device("ns16450_0"), data);
};
m_microtouch->rx(state);
}
static INS8250_TRANSMIT( magtouch_com_transmit )
WRITE_LINE_MEMBER(magtouch_state::microtouch_in)
{
UINT8 data8 = data;
microtouch_rx(1, &data8);
m_uart->rx_w(state);
}
static WRITE_LINE_DEVICE_HANDLER( at_com_interrupt_1 )
@ -114,11 +121,17 @@ static WRITE_LINE_DEVICE_HANDLER( at_com_interrupt_1 )
static const ins8250_interface magtouch_com0_interface =
{
1843200,
DEVCB_DRIVER_LINE_MEMBER(magtouch_state, microtouch_out),
DEVCB_NULL,
DEVCB_NULL,
DEVCB_LINE(at_com_interrupt_1),
magtouch_com_transmit,
NULL,
NULL
DEVCB_NULL,
DEVCB_NULL
};
static const microtouch_serial_interface magtouch_microtouch_interface =
{
DEVCB_DRIVER_LINE_MEMBER(magtouch_state, microtouch_in)
};
/*************************************
@ -161,12 +174,10 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( magtouch_io, AS_IO, 32 )
AM_IMPORT_FROM(pcat32_io_common)
AM_RANGE(0x02e0, 0x02e7) AM_READWRITE8(magtouch_io_r, magtouch_io_w, 0xffffffff)
AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ns16450_0", ins8250_r, ins8250_w, 0xffffffff)
AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8_MODERN("ns16450_0", ns16450_device, ins8250_r, ins8250_w, 0xffffffff)
ADDRESS_MAP_END
static INPUT_PORTS_START( magtouch )
PORT_INCLUDE(microtouch)
PORT_START("IN0")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Clear") PORT_CODE(KEYCODE_C)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_SERVICE)
@ -191,7 +202,7 @@ static MACHINE_START( magtouch )
memory_configure_bank(machine, "rombank", 0, 0x80, machine.region("game_prg")->base(), 0x8000 );
memory_set_bank(machine, "rombank", 0);
microtouch_init(machine, magtouch_microtouch_tx_callback, NULL);
// microtouch_init(machine, magtouch_microtouch_tx_callback, NULL);
}
static MACHINE_CONFIG_START( magtouch, magtouch_state )
@ -212,8 +223,8 @@ static MACHINE_CONFIG_START( magtouch, magtouch_state )
// MCFG_FRAGMENT_ADD( at_kbdc8042 )
MCFG_FRAGMENT_ADD( pcat_common )
MCFG_NS16450_ADD( "ns16450_0", magtouch_com0_interface )
MCFG_NS16450_ADD( "ns16450_0", magtouch_com0_interface, XTAL_1_8432MHz )
MCFG_MICROTOUCH_SERIAL_ADD( "microtouch", magtouch_microtouch_interface, 9600 ) // rate?
MACHINE_CONFIG_END

View File

@ -129,8 +129,10 @@ public:
meritm_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_v9938_0(*this, "v9938_0"),
m_v9938_1(*this, "v9938_1") { }
m_v9938_1(*this, "v9938_1"),
m_microtouch(*this, "microtouch") { }
DECLARE_WRITE8_MEMBER(microtouch_tx);
UINT8* m_ram;
device_t *m_z80pio[2];
int m_vint;
@ -144,6 +146,7 @@ public:
ds1204_t m_ds1204;
required_device<v9938_device> m_v9938_0;
required_device<v9938_device> m_v9938_1;
required_device<microtouch_device> m_microtouch;
};
@ -271,22 +274,24 @@ static void ds1204_init(running_machine &machine, const UINT8* key, const UINT8*
*
*************************************/
static void pc16650d_tx_callback(int channel, int count, UINT8* data)
static void pc16650d_tx_callback(running_machine &machine, int channel, int count, UINT8* data)
{
microtouch_rx(count, data);
};
meritm_state *state = machine.driver_data<meritm_state>();
for(int i = 0; i < count; i++)
state->m_microtouch->rx(*memory_nonspecific_space(machine), 0, data[i]);
}
static void meritm_microtouch_tx_callback(running_machine &machine, UINT8 data)
WRITE8_MEMBER(meritm_state::microtouch_tx)
{
pc16552d_rx_data(machine, 0, 0, data);
};
pc16552d_rx_data(space.machine(), 0, 0, data);
}
/*************************************
*
* Microtouch touch coordinate transformation
*
*************************************/
static int meritm_touch_coord_transform(running_machine &machine, int *touch_x, int *touch_y)
MICROTOUCH_TOUCH(meritm_touch_coord_transform)
{
int xscr = (int)((double)(*touch_x)/0x4000*544);
int yscr = (int)((double)(*touch_y)/0x4000*480);
@ -311,6 +316,12 @@ static int meritm_touch_coord_transform(running_machine &machine, int *touch_x,
return 1;
}
static const microtouch_interface meritm_microtouch_config =
{
DEVCB_DRIVER_MEMBER(meritm_state, microtouch_tx),
meritm_touch_coord_transform
};
/*************************************
*
* Video
@ -627,8 +638,6 @@ ADDRESS_MAP_END
*************************************/
static INPUT_PORTS_START(meritm_crt260)
PORT_INCLUDE(microtouch)
PORT_START("PIO1_PORTA")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -997,7 +1006,6 @@ static MACHINE_START(meritm_crt250_crt252_crt258)
{
MACHINE_START_CALL(meritm_crt250_questions);
pc16552d_init(machine, 0, UART_CLK, NULL, pc16650d_tx_callback);
microtouch_init(machine, meritm_microtouch_tx_callback, meritm_touch_coord_transform);
}
static MACHINE_START(meritm_crt260)
@ -1014,7 +1022,6 @@ static MACHINE_START(meritm_crt260)
meritm_switch_banks(machine);
MACHINE_START_CALL(merit_common);
pc16552d_init(machine, 0, UART_CLK, NULL, pc16650d_tx_callback);
microtouch_init(machine, meritm_microtouch_tx_callback, meritm_touch_coord_transform);
state_save_register_global(machine, state->m_bank);
state_save_register_global(machine, state->m_psd_a15);
state_save_register_global_pointer(machine, state->m_ram, 0x8000);
@ -1089,6 +1096,8 @@ static MACHINE_CONFIG_START( meritm_crt250, meritm_state )
MCFG_SOUND_ADD("aysnd", AY8910, SYSTEM_CLK/12)
MCFG_SOUND_CONFIG(ay8910_config)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MCFG_MICROTOUCH_ADD("microtouch", meritm_microtouch_config)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( meritm_crt250_questions, meritm_crt250 )

View File

@ -96,21 +96,27 @@ class pcat_nit_state : public driver_device
{
public:
pcat_nit_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_uart(*this, "ns16450_0"),
m_microtouch(*this, "microtouch")
{ }
UINT8 *m_banked_nvram;
required_device<ns16450_device> m_uart;
required_device<microtouch_serial_device> m_microtouch;
DECLARE_WRITE_LINE_MEMBER(microtouch_out);
DECLARE_WRITE_LINE_MEMBER(microtouch_in);
};
static void pcat_nit_microtouch_tx_callback(running_machine &machine, UINT8 data)
WRITE_LINE_MEMBER(pcat_nit_state::microtouch_out)
{
ins8250_receive(machine.device("ns16450_0"), data);
};
m_microtouch->rx(state);
}
static INS8250_TRANSMIT( pcat_nit_com_transmit )
WRITE_LINE_MEMBER(pcat_nit_state::microtouch_in)
{
UINT8 data8 = data;
microtouch_rx(1, &data8);
m_uart->rx_w(state);
}
static WRITE_LINE_DEVICE_HANDLER( at_com_interrupt_1 )
@ -120,11 +126,17 @@ static WRITE_LINE_DEVICE_HANDLER( at_com_interrupt_1 )
static const ins8250_interface pcat_nit_com0_interface =
{
1843200,
DEVCB_DRIVER_LINE_MEMBER(pcat_nit_state, microtouch_out),
DEVCB_NULL,
DEVCB_NULL,
DEVCB_LINE(at_com_interrupt_1),
pcat_nit_com_transmit,
NULL,
NULL
DEVCB_NULL,
DEVCB_NULL
};
static const microtouch_serial_interface pcat_nit_microtouch_interface =
{
DEVCB_DRIVER_LINE_MEMBER(pcat_nit_state, microtouch_in)
};
/*************************************
@ -194,12 +206,10 @@ static ADDRESS_MAP_START( pcat_nit_io, AS_IO, 32 )
AM_IMPORT_FROM(pcat32_io_common)
AM_RANGE(0x0278, 0x027f) AM_READ8(pcat_nit_io_r, 0xffffffff) AM_WRITENOP
AM_RANGE(0x0280, 0x0283) AM_READNOP
AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ns16450_0", ins8250_r, ins8250_w, 0xffffffff)
AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8_MODERN("ns16450_0", ns16450_device, ins8250_r, ins8250_w, 0xffffffff)
ADDRESS_MAP_END
static INPUT_PORTS_START( pcat_nit )
PORT_INCLUDE(microtouch)
PORT_START("IN0")
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Clear") PORT_CODE(KEYCODE_C)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_SERVICE)
@ -224,7 +234,7 @@ static MACHINE_START( streetg2 )
memory_configure_bank(machine, "rombank", 0, 0x80, machine.region("game_prg")->base(), 0x8000 );
memory_set_bank(machine, "rombank", 0);
microtouch_init(machine, pcat_nit_microtouch_tx_callback, NULL);
//microtouch_init(machine, pcat_nit_microtouch_tx_callback, NULL);
}
static MACHINE_CONFIG_START( pcat_nit, pcat_nit_state )
@ -245,7 +255,8 @@ static MACHINE_CONFIG_START( pcat_nit, pcat_nit_state )
// MCFG_FRAGMENT_ADD( at_kbdc8042 )
MCFG_FRAGMENT_ADD( pcat_common )
MCFG_NS16450_ADD( "ns16450_0", pcat_nit_com0_interface )
MCFG_NS16450_ADD( "ns16450_0", pcat_nit_com0_interface, XTAL_1_8432MHz )
MCFG_MICROTOUCH_SERIAL_ADD( "microtouch", pcat_nit_microtouch_interface, 9600 ) // rate?
MCFG_NVRAM_ADD_0FILL("nvram")

View File

@ -121,9 +121,12 @@ class tmaster_state : public driver_device
public:
tmaster_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this,"maincpu")
m_maincpu(*this,"maincpu"),
m_microtouch(*this,"microtouch")
{ }
DECLARE_WRITE8_MEMBER(microtouch_tx);
int m_okibank;
UINT8 m_rtc_ram[8];
bitmap_ind16 m_bitmap[2][2];
@ -141,6 +144,7 @@ public:
device_t *m_duart68681;
required_device<cpu_device> m_maincpu;
optional_device<microtouch_device> m_microtouch;
};
@ -179,18 +183,23 @@ static void duart_irq_handler(device_t *device, UINT8 vector)
static void duart_tx(device_t *device, int channel, UINT8 data)
{
tmaster_state *state = device->machine().driver_data<tmaster_state>();
if ( channel == 0 )
{
microtouch_rx(1, &data);
state->m_microtouch->rx(*memory_nonspecific_space(device->machine()), 0, data);
}
};
static void microtouch_tx(running_machine &machine, UINT8 data)
WRITE8_MEMBER( tmaster_state::microtouch_tx )
{
tmaster_state *state = machine.driver_data<tmaster_state>();
duart68681_rx_data(state->m_duart68681, 0, data);
duart68681_rx_data(m_duart68681, 0, data);
}
static const microtouch_interface tmaster_microtouch_config =
{
DEVCB_DRIVER_MEMBER(tmaster_state, microtouch_tx),
NULL
};
/***************************************************************************
@ -766,8 +775,6 @@ ADDRESS_MAP_END
***************************************************************************/
static INPUT_PORTS_START( tm )
PORT_INCLUDE( microtouch )
PORT_START("COIN")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN5 ) // "M. Coin 1 Input"
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN6 ) // "M. Coin 2 Input"
@ -788,8 +795,6 @@ static INPUT_PORTS_START( tm )
INPUT_PORTS_END
static INPUT_PORTS_START( tmaster )
PORT_INCLUDE( microtouch )
PORT_START("COIN")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) // "M. Coin 1 Input"
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) // "M. Coin 2 Input"
@ -863,11 +868,6 @@ INPUT_PORTS_END
***************************************************************************/
static MACHINE_START( tmaster )
{
microtouch_init(machine, microtouch_tx, 0);
}
static MACHINE_RESET( tmaster )
{
tmaster_state *state = machine.driver_data<tmaster_state>();
@ -904,10 +904,10 @@ static MACHINE_CONFIG_START( tm3k, tmaster_state )
MCFG_CPU_PROGRAM_MAP(tmaster_map)
MCFG_TIMER_ADD_SCANLINE("scantimer", tm3k_interrupt, "screen", 0, 1)
MCFG_MACHINE_START(tmaster)
MCFG_MACHINE_RESET(tmaster)
MCFG_DUART68681_ADD( "duart68681", XTAL_8_664MHz / 2 /*??*/, tmaster_duart68681_config )
MCFG_MICROTOUCH_ADD( "microtouch", tmaster_microtouch_config )
MCFG_NVRAM_ADD_0FILL("nvram")

View File

@ -8,13 +8,19 @@ CuboCD32 definitions
#define __CUBOCD32_H__
#include "includes/amiga.h"
#include "machine/microtch.h"
class cd32_state : public amiga_state
{
public:
cd32_state(const machine_config &mconfig, device_type type, const char *tag)
: amiga_state(mconfig, type, tag) { }
: amiga_state(mconfig, type, tag),
m_microtouch(*this, "microtouch")
{ }
required_device<microtouch_device> m_microtouch;
DECLARE_WRITE8_MEMBER(microtouch_tx);
UINT16 m_potgo_value;
int m_cd32_shifter[2];
void (*m_input_hack)(running_machine &machine);