mirror of
https://github.com/holub/mame
synced 2025-05-30 01:23:07 +03:00
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:
parent
1ecbc8f95f
commit
5ac1220284
@ -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")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user