the V53 SCU is a i8251 clone, but with the command / mode registers separated, and only Asynchronous transfer mode available, this splits the function into something we can use for that purpose (nw)

This commit is contained in:
mamehaze 2015-03-10 11:40:07 +00:00
parent 1ecbc8f95f
commit 5ac1220284
6 changed files with 360 additions and 333 deletions

View File

@ -3,7 +3,7 @@
// V33 / V33A cores with onboard peripherals
// Interrupt Controller is uPD71059 equivalent (a PIC8259 clone?)
// DMA Controller can operate in modes providing a subset of the uPD71071 or uPD71037 functionality (some modes unavailable / settings ignored) (uPD71071 mode is an extended am9517a, uPD71037 mode is ??)
// DMA Controller can operate in modes providing a subset of the uPD71071 or uPD71037 functionality (some modes unavailable / settings ignored) (uPD71071 mode is an extended 8237A, uPD71037 mode is plain 8237A)
// Serial Controller is based on the uPD71051 but with some changes (i8251 clone?)
// Timer Unit is functionally identical to uPD71054 (which in turn is said to be the same as a pit8253)
@ -216,7 +216,7 @@ void v53_base_device::install_peripheral_io()
}
else // uPD71071 mode
{
space(AS_IO).install_readwrite_handler(base+0x00, base+0x0f, read8_delegate(FUNC(upd71071_v53_device::read), (upd71071_v53_device*)m_dma_71071mode), write8_delegate(FUNC(upd71071_v53_device::write), (upd71071_v53_device*)m_dma_71071mode), 0xffff);
space(AS_IO).install_readwrite_handler(base+0x00, base+0x0f, read8_delegate(FUNC(upd71071_v53_device::read), (upd71071_v53_device*)m_v53dmau), write8_delegate(FUNC(upd71071_v53_device::write), (upd71071_v53_device*)m_v53dmau), 0xffff);
}
}
@ -231,9 +231,7 @@ void v53_base_device::install_peripheral_io()
}
else
{
space(AS_IO).install_readwrite_handler(base+0x00, base+0x01, read8_delegate(FUNC(v53_base_device::icu_0_r), this), write8_delegate(FUNC(v53_base_device::icu_0_w), this), 0x00ff);
space(AS_IO).install_readwrite_handler(base+0x02, base+0x03, read8_delegate(FUNC(v53_base_device::icu_1_r), this), write8_delegate(FUNC(v53_base_device::icu_1_w), this), 0x00ff);
space(AS_IO).install_readwrite_handler(base+0x00, base+0x03, read8_delegate(FUNC(pic8259_device::read), (pic8259_device*)m_v53icu), write8_delegate(FUNC(pic8259_device::write), (pic8259_device*)m_v53icu), 0x00ff);
}
}
@ -277,32 +275,8 @@ void v53_base_device::install_peripheral_io()
}
/*** ICU ***/
READ8_MEMBER(v53_base_device::icu_0_r)
{
printf("v53: icu_0_r\n");
return 0;
}
WRITE8_MEMBER(v53_base_device::icu_0_w)
{
printf("v53: icu_0_w %02x\n", data);
}
READ8_MEMBER(v53_base_device::icu_1_r)
{
printf("v53: icu_1_r\n");
return 0;
}
WRITE8_MEMBER(v53_base_device::icu_1_w)
{
printf("v53: icu_1_w %02x\n", data);
}
/*** SCU ***/
READ8_MEMBER(v53_base_device::scu_srb_r)
@ -346,15 +320,15 @@ WRITE8_MEMBER(v53_base_device::scu_simk_w)
/*** TCU ***/
WRITE8_MEMBER(v53_base_device::tmu_tct0_w) { m_pit->write(space, 0, data); }
WRITE8_MEMBER(v53_base_device::tmu_tct1_w) { m_pit->write(space, 1, data); }
WRITE8_MEMBER(v53_base_device::tmu_tct2_w) { m_pit->write(space, 2, data); }
WRITE8_MEMBER(v53_base_device::tmu_tmd_w) { m_pit->write(space, 3, data); }
WRITE8_MEMBER(v53_base_device::tmu_tct0_w) { m_v53tcu->write(space, 0, data); }
WRITE8_MEMBER(v53_base_device::tmu_tct1_w) { m_v53tcu->write(space, 1, data); }
WRITE8_MEMBER(v53_base_device::tmu_tct2_w) { m_v53tcu->write(space, 2, data); }
WRITE8_MEMBER(v53_base_device::tmu_tmd_w) { m_v53tcu->write(space, 3, data); }
READ8_MEMBER(v53_base_device::tmu_tst0_r) { return m_pit->read(space, 0); }
READ8_MEMBER(v53_base_device::tmu_tst1_r) { return m_pit->read(space, 1); }
READ8_MEMBER(v53_base_device::tmu_tst2_r) { return m_pit->read(space, 2); }
READ8_MEMBER(v53_base_device::tmu_tst0_r) { return m_v53tcu->read(space, 0); }
READ8_MEMBER(v53_base_device::tmu_tst1_r) { return m_v53tcu->read(space, 1); }
READ8_MEMBER(v53_base_device::tmu_tst2_r) { return m_v53tcu->read(space, 2); }
/*** DMA ***/
@ -363,7 +337,7 @@ WRITE_LINE_MEMBER(v53_base_device::dreq0_trampoline_w)
{
if (!(m_SCTL & 0x02))
{
m_dma_71071mode->dreq0_w(state);
m_v53dmau->dreq0_w(state);
}
else
{
@ -375,7 +349,7 @@ WRITE_LINE_MEMBER(v53_base_device::dreq1_trampoline_w)
{
if (!(m_SCTL & 0x02))
{
m_dma_71071mode->dreq1_w(state);
m_v53dmau->dreq1_w(state);
}
else
{
@ -387,7 +361,7 @@ WRITE_LINE_MEMBER(v53_base_device::dreq2_trampoline_w)
{
if (!(m_SCTL & 0x02))
{
m_dma_71071mode->dreq2_w(state);
m_v53dmau->dreq2_w(state);
}
else
{
@ -399,7 +373,7 @@ WRITE_LINE_MEMBER(v53_base_device::dreq3_trampoline_w)
{
if (!(m_SCTL & 0x02))
{
m_dma_71071mode->dreq3_w(state);
m_v53dmau->dreq3_w(state);
}
else
{
@ -411,7 +385,7 @@ WRITE_LINE_MEMBER(v53_base_device::hack_trampoline_w)
{
if (!(m_SCTL & 0x02))
{
m_dma_71071mode->hack_w(state);
m_v53dmau->hack_w(state);
}
else
{
@ -459,7 +433,7 @@ ADDRESS_MAP_END
WRITE_LINE_MEMBER(v53_base_device::dma_hrq_changed)
{
// pass this back to the driver? / expose externally?
m_dma_71071mode->hack_w(state);
m_v53dmau->hack_w(state);
}
WRITE8_MEMBER(v53_base_device::dma_io_3_w)
@ -481,7 +455,7 @@ READ8_MEMBER(v53_base_device::get_pic_ack)
WRITE_LINE_MEMBER( v53_base_device::upd71059_irq_w)
{
printf("upd71059_irq_w %d", state);
printf("upd71059_irq_w %d\n", state);
}
static MACHINE_CONFIG_FRAGMENT( v53 )
@ -489,7 +463,7 @@ static MACHINE_CONFIG_FRAGMENT( v53 )
MCFG_PIT8253_CLK0(16000000/2/8)
//MCFG_PIT8253_OUT0_HANDLER(WRITELINE(v53_base_device, pit_out0))
MCFG_DEVICE_ADD("upd71071dma", UPD71071_V53, 4000000)
MCFG_DEVICE_ADD("upd71071dma", V53_DMAU, 4000000)
MCFG_I8237_OUT_HREQ_CB(WRITELINE(v53_base_device, dma_hrq_changed))
MCFG_I8237_OUT_IOW_3_CB(WRITE8(v53_base_device, dma_io_3_w))
MCFG_I8237_IN_MEMR_CB(READ8(v53_base_device, dma_memin_r))
@ -497,7 +471,7 @@ static MACHINE_CONFIG_FRAGMENT( v53 )
MCFG_PIC8259_ADD( "upd71059pic", WRITELINE(v53_base_device, upd71059_irq_w), VCC, READ8(v53_base_device,get_pic_ack))
MCFG_DEVICE_ADD("upd71051", I8251, 0)
MCFG_DEVICE_ADD("v53scu", V53_SCU, 0)
MACHINE_CONFIG_END
@ -510,10 +484,10 @@ machine_config_constructor v53_base_device::device_mconfig_additions() const
v53_base_device::v53_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, offs_t fetch_xor, UINT8 prefetch_size, UINT8 prefetch_cycles, UINT32 chip_type)
: nec_common_device(mconfig, type, name, tag, owner, clock, shortname, true, fetch_xor, prefetch_size, prefetch_cycles, chip_type),
m_io_space_config( "io", ENDIANNESS_LITTLE, 16, 16, 0, ADDRESS_MAP_NAME( v53_internal_port_map ) ),
m_pit(*this, "pit"),
m_dma_71071mode(*this, "upd71071dma"),
m_upd71059(*this, "upd71059pic"),
m_upd71051(*this, "upd71051")
m_v53tcu(*this, "pit"),
m_v53dmau(*this, "upd71071dma"),
m_v53icu(*this, "upd71059pic"),
m_v53scu(*this, "v53scu")
{
}

View File

@ -62,11 +62,6 @@ public:
DECLARE_READ8_MEMBER(scu_simk_r);
DECLARE_WRITE8_MEMBER(scu_simk_w);
// ICU
DECLARE_READ8_MEMBER(icu_0_r);
DECLARE_WRITE8_MEMBER(icu_0_w);
DECLARE_READ8_MEMBER(icu_1_r);
DECLARE_WRITE8_MEMBER(icu_1_w);
void install_peripheral_io();
@ -81,10 +76,10 @@ public:
}
}
required_device<pit8253_device> m_pit;
required_device<upd71071_v53_device> m_dma_71071mode;
required_device<pic8259_device> m_upd71059;
required_device<i8251_device> m_upd71051;
required_device<pit8253_device> m_v53tcu;
required_device<upd71071_v53_device> m_v53dmau;
required_device<pic8259_device> m_v53icu;
required_device<v53_scu_device> m_v53scu;
DECLARE_WRITE_LINE_MEMBER(dreq0_trampoline_w);
DECLARE_WRITE_LINE_MEMBER(dreq1_trampoline_w);

View File

@ -4,7 +4,12 @@
AMD AM9517A
Intel 8237A
NEC UPD71071
NEC uPD71037
NEC uPD71071 (extended version of above)
a variant is used in the V53 CPU which offers subsets of both the
uPD71071 and uPD71037 functionality depending on a mode bit.
Multimode DMA Controller emulation
@ -17,7 +22,6 @@
TODO:
- memory-to-memory transfer
- external EOP
*/
@ -47,7 +51,7 @@
//**************************************************************************
const device_type AM9517A = &device_creator<am9517a_device>;
const device_type UPD71071_V53 = &device_creator<upd71071_v53_device>;
const device_type V53_DMAU = &device_creator<upd71071_v53_device>;
//**************************************************************************
@ -471,7 +475,7 @@ inline void am9517a_device::end_of_process()
am9517a_device::am9517a_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname)
: device_t(mconfig, AM9517A, name, tag, owner, clock, shortname, __FILE__),
: device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
device_execute_interface(mconfig, *this),
m_icount(0),
m_hack(0),
@ -525,7 +529,7 @@ am9517a_device::am9517a_device(const machine_config &mconfig, const char *tag, d
}
upd71071_v53_device::upd71071_v53_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: am9517a_device(mconfig, UPD71071_V53, "UPD71071 (V53)", tag, owner, clock, "upd71071_v53")
: am9517a_device(mconfig, V53_DMAU, "V53 DMAU", tag, owner, clock, "v53_dmau")
{
}

View File

@ -183,7 +183,7 @@ protected:
// device type definition
extern const device_type AM9517A;
extern const device_type UPD71071_V53;
extern const device_type V53_DMAU;
/***************************************************************************

View File

@ -3,6 +3,12 @@
i8251.c
Intel 8251 Universal Synchronous/Asynchronous Receiver Transmitter code
NEC uPD71051 is a clone
The V53/V53A use a customized version with only the Asynchronous mode
and a split command / mode register
*********************************************************************/
@ -23,11 +29,30 @@
//**************************************************************************
const device_type I8251 = &device_creator<i8251_device>;
const device_type V53_SCU = &device_creator<v53_scu_device>;
//-------------------------------------------------
// i8251_device - constructor
//-------------------------------------------------
i8251_device::i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname)
: device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
device_serial_interface(mconfig, *this),
m_txd_handler(*this),
m_dtr_handler(*this),
m_rts_handler(*this),
m_rxrdy_handler(*this),
m_txrdy_handler(*this),
m_txempty_handler(*this),
m_syndet_handler(*this),
m_cts(1),
m_dsr(1),
m_rxd(0),
m_rxc(0),
m_txc(0)
{
}
i8251_device::i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, I8251, "8251 USART", tag, owner, clock, "i8251", __FILE__),
device_serial_interface(mconfig, *this),
@ -46,6 +71,12 @@ i8251_device::i8251_device(const machine_config &mconfig, const char *tag, devic
{
}
v53_scu_device::v53_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: i8251_device(mconfig, V53_SCU, "V53 SCU", tag, owner, clock, "v53_scu")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
@ -325,6 +356,282 @@ void i8251_device::device_reset()
control_w
-------------------------------------------------*/
WRITE8_MEMBER(i8251_device::command_w)
{
/* command */
LOG(("I8251: Command byte\n"));
m_command = data;
LOG(("Command byte: %02x\n", data));
if (data & (1<<7))
{
LOG(("hunt mode\n"));
}
if (data & (1<<5))
{
LOG(("/rts set to 0\n"));
}
else
{
LOG(("/rts set to 1\n"));
}
if (data & (1<<2))
{
LOG(("receive enable\n"));
}
else
{
LOG(("receive disable\n"));
}
if (data & (1<<1))
{
LOG(("/dtr set to 0\n"));
}
else
{
LOG(("/dtr set to 1\n"));
}
if (data & (1<<0))
{
LOG(("transmit enable\n"));
/* if we get a tx enable with a disable pending, cancel the disable */
m_disable_tx_pending = false;
}
else
{
if (m_tx_busy)
{
if (!m_disable_tx_pending)
{
LOG(("Tx busy, set pending disable\n"));
}
m_disable_tx_pending = true;
m_command |= (1<<0);
}
else
{
LOG(("transmit disable\n"));
if ((data & (1<<0))==0)
{
/* held in high state when transmit disable */
m_txd_handler(1);
}
}
}
/* bit 7:
0 = normal operation
1 = hunt mode
bit 6:
0 = normal operation
1 = internal reset
bit 5:
0 = /RTS set to 1
1 = /RTS set to 0
bit 4:
0 = normal operation
1 = reset error flag
bit 3:
0 = normal operation
1 = send break character
bit 2:
0 = receive disable
1 = receive enable
bit 1:
0 = /DTR set to 1
1 = /DTR set to 0
bit 0:
0 = transmit disable
1 = transmit enable
*/
m_rts_handler(!BIT(data, 5));
m_dtr_handler(!BIT(data, 1));
if (data & (1<<4))
{
m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR);
}
if (data & (1<<6))
{
// datasheet says "returns to mode format", not
// completely resets the chip. behavior of DEC Rainbow
// backs this up.
m_flags |= I8251_EXPECTING_MODE;
}
update_rx_ready();
update_tx_ready();
}
WRITE8_MEMBER(i8251_device::mode_w)
{
LOG(("I8251: Mode byte\n"));
m_mode_byte = data;
/* Synchronous or Asynchronous? */
if ((data & 0x03) != 0)
{
/* Asynchronous
bit 7,6: stop bit length
0 = inhibit
1 = 1 bit
2 = 1.5 bits
3 = 2 bits
bit 5: parity type
0 = parity odd
1 = parity even
bit 4: parity test enable
0 = disable
1 = enable
bit 3,2: character length
0 = 5 bits
1 = 6 bits
2 = 7 bits
3 = 8 bits
bit 1,0: baud rate factor
0 = defines command byte for synchronous or asynchronous
1 = x1
2 = x16
3 = x64
*/
LOG(("I8251: Asynchronous operation\n"));
LOG(("Character length: %d\n", (((data >> 2) & 0x03) + 5)));
parity_t parity;
if (data & (1 << 4))
{
LOG(("enable parity checking\n"));
if (data & (1 << 5))
{
LOG(("even parity\n"));
parity = PARITY_EVEN;
}
else
{
LOG(("odd parity\n"));
parity = PARITY_ODD;
}
}
else
{
LOG(("parity check disabled\n"));
parity = PARITY_NONE;
}
stop_bits_t stop_bits;
switch ((data >> 6) & 0x03)
{
case 0:
default:
stop_bits = STOP_BITS_0;
LOG(("stop bit: inhibit\n"));
break;
case 1:
stop_bits = STOP_BITS_1;
LOG(("stop bit: 1 bit\n"));
break;
case 2:
stop_bits = STOP_BITS_1_5;
LOG(("stop bit: 1.5 bits\n"));
break;
case 3:
stop_bits = STOP_BITS_2;
LOG(("stop bit: 2 bits\n"));
break;
}
int data_bits_count = ((data >> 2) & 0x03) + 5;
set_data_frame(1, data_bits_count, parity, stop_bits);
receive_register_reset();
switch (data & 0x03)
{
case 1: m_br_factor = 1; break;
case 2: m_br_factor = 16; break;
case 3: m_br_factor = 64; break;
}
m_rxc_count = m_txc_count = 0;
#if 0
/* data bits */
m_receive_char_length = (((data >> 2) & 0x03) + 5);
if (data & (1 << 4))
{
/* parity */
m_receive_char_length++;
}
/* stop bits */
m_receive_char_length++;
m_receive_flags &= ~I8251_TRANSFER_RECEIVE_SYNCHRONISED;
m_receive_flags |= I8251_TRANSFER_RECEIVE_WAITING_FOR_START_BIT;
#endif
/* not expecting mode byte now */
m_flags &= ~I8251_EXPECTING_MODE;
// m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY;
}
else
{
/* bit 7: Number of sync characters
0 = 1 character
1 = 2 character
bit 6: Synchronous mode
0 = Internal synchronisation
1 = External synchronisation
bit 5: parity type
0 = parity odd
1 = parity even
bit 4: parity test enable
0 = disable
1 = enable
bit 3,2: character length
0 = 5 bits
1 = 6 bits
2 = 7 bits
3 = 8 bits
bit 1,0 = 0
*/
LOG(("I8251: Synchronous operation\n"));
/* setup for sync byte(s) */
m_flags |= I8251_EXPECTING_SYNC_BYTE;
m_sync_byte_offset = 0;
if (data & 0x07)
{
m_sync_byte_count = 1;
}
else
{
m_sync_byte_count = 2;
}
}
}
WRITE8_MEMBER(i8251_device::control_w)
{
if (m_flags & I8251_EXPECTING_MODE)
@ -348,279 +655,12 @@ WRITE8_MEMBER(i8251_device::control_w)
}
else
{
LOG(("I8251: Mode byte\n"));
m_mode_byte = data;
/* Synchronous or Asynchronous? */
if ((data & 0x03)!=0)
{
/* Asynchronous
bit 7,6: stop bit length
0 = inhibit
1 = 1 bit
2 = 1.5 bits
3 = 2 bits
bit 5: parity type
0 = parity odd
1 = parity even
bit 4: parity test enable
0 = disable
1 = enable
bit 3,2: character length
0 = 5 bits
1 = 6 bits
2 = 7 bits
3 = 8 bits
bit 1,0: baud rate factor
0 = defines command byte for synchronous or asynchronous
1 = x1
2 = x16
3 = x64
*/
LOG(("I8251: Asynchronous operation\n"));
LOG(("Character length: %d\n", (((data>>2) & 0x03)+5)));
parity_t parity;
if (data & (1<<4))
{
LOG(("enable parity checking\n"));
if (data & (1<<5))
{
LOG(("even parity\n"));
parity = PARITY_EVEN;
}
else
{
LOG(("odd parity\n"));
parity = PARITY_ODD;
}
}
else
{
LOG(("parity check disabled\n"));
parity = PARITY_NONE;
}
stop_bits_t stop_bits;
switch ((data>>6) & 0x03)
{
case 0:
default:
stop_bits = STOP_BITS_0;
LOG(("stop bit: inhibit\n"));
break;
case 1:
stop_bits = STOP_BITS_1;
LOG(("stop bit: 1 bit\n"));
break;
case 2:
stop_bits = STOP_BITS_1_5;
LOG(("stop bit: 1.5 bits\n"));
break;
case 3:
stop_bits = STOP_BITS_2;
LOG(("stop bit: 2 bits\n"));
break;
}
int data_bits_count = ((data>>2) & 0x03)+5;
set_data_frame(1, data_bits_count, parity, stop_bits);
receive_register_reset();
switch (data & 0x03)
{
case 1: m_br_factor = 1; break;
case 2: m_br_factor = 16; break;
case 3: m_br_factor = 64; break;
}
m_rxc_count = m_txc_count = 0;
#if 0
/* data bits */
m_receive_char_length = (((data>>2) & 0x03)+5);
if (data & (1<<4))
{
/* parity */
m_receive_char_length++;
}
/* stop bits */
m_receive_char_length++;
m_receive_flags &=~I8251_TRANSFER_RECEIVE_SYNCHRONISED;
m_receive_flags |= I8251_TRANSFER_RECEIVE_WAITING_FOR_START_BIT;
#endif
/* not expecting mode byte now */
m_flags &= ~I8251_EXPECTING_MODE;
// m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY;
}
else
{
/* bit 7: Number of sync characters
0 = 1 character
1 = 2 character
bit 6: Synchronous mode
0 = Internal synchronisation
1 = External synchronisation
bit 5: parity type
0 = parity odd
1 = parity even
bit 4: parity test enable
0 = disable
1 = enable
bit 3,2: character length
0 = 5 bits
1 = 6 bits
2 = 7 bits
3 = 8 bits
bit 1,0 = 0
*/
LOG(("I8251: Synchronous operation\n"));
/* setup for sync byte(s) */
m_flags |= I8251_EXPECTING_SYNC_BYTE;
m_sync_byte_offset = 0;
if (data & 0x07)
{
m_sync_byte_count = 1;
}
else
{
m_sync_byte_count = 2;
}
}
mode_w(space, offset, data);
}
}
else
{
/* command */
LOG(("I8251: Command byte\n"));
m_command = data;
LOG(("Command byte: %02x\n", data));
if (data & (1<<7))
{
LOG(("hunt mode\n"));
}
if (data & (1<<5))
{
LOG(("/rts set to 0\n"));
}
else
{
LOG(("/rts set to 1\n"));
}
if (data & (1<<2))
{
LOG(("receive enable\n"));
}
else
{
LOG(("receive disable\n"));
}
if (data & (1<<1))
{
LOG(("/dtr set to 0\n"));
}
else
{
LOG(("/dtr set to 1\n"));
}
if (data & (1<<0))
{
LOG(("transmit enable\n"));
/* if we get a tx enable with a disable pending, cancel the disable */
m_disable_tx_pending = false;
}
else
{
if (m_tx_busy)
{
if (!m_disable_tx_pending)
{
LOG(("Tx busy, set pending disable\n"));
}
m_disable_tx_pending = true;
m_command |= (1<<0);
}
else
{
LOG(("transmit disable\n"));
if ((data & (1<<0))==0)
{
/* held in high state when transmit disable */
m_txd_handler(1);
}
}
}
/* bit 7:
0 = normal operation
1 = hunt mode
bit 6:
0 = normal operation
1 = internal reset
bit 5:
0 = /RTS set to 1
1 = /RTS set to 0
bit 4:
0 = normal operation
1 = reset error flag
bit 3:
0 = normal operation
1 = send break character
bit 2:
0 = receive disable
1 = receive enable
bit 1:
0 = /DTR set to 1
1 = /DTR set to 0
bit 0:
0 = transmit disable
1 = transmit enable
*/
m_rts_handler(!BIT(data, 5));
m_dtr_handler(!BIT(data, 1));
if (data & (1<<4))
{
m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR);
}
if (data & (1<<6))
{
// datasheet says "returns to mode format", not
// completely resets the chip. behavior of DEC Rainbow
// backs this up.
m_flags |= I8251_EXPECTING_MODE;
}
update_rx_ready();
update_tx_ready();
command_w(space, offset, data);
}
}

View File

@ -40,6 +40,7 @@ class i8251_device : public device_t,
{
public:
// construction/destruction
i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname);
i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// static configuration helpers
@ -55,6 +56,8 @@ public:
DECLARE_WRITE8_MEMBER(data_w);
DECLARE_READ8_MEMBER(status_r);
DECLARE_WRITE8_MEMBER(control_w);
DECLARE_WRITE8_MEMBER(command_w);
DECLARE_WRITE8_MEMBER(mode_w);
DECLARE_WRITE_LINE_MEMBER( write_rxd );
DECLARE_WRITE_LINE_MEMBER( write_cts );
@ -132,7 +135,18 @@ private:
bool m_disable_tx_pending;
};
class v53_scu_device : public i8251_device
{
public:
// construction/destruction
v53_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
// device type definition
extern const device_type I8251;
extern const device_type V53_SCU;
#endif /* __I8251_H__ */