mirror of
https://github.com/holub/mame
synced 2025-06-01 18:41:47 +03:00
Rewrite INS8250 to use diserial, updated Microtouch to modern and made it serial device, updated connected drivers [Carl]
This commit is contained in:
parent
d24e475f0e
commit
e82fa6e24e
@ -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++;
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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(µtouch, 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user