Added initial support for baudrate generator

This commit is contained in:
Joakim Larsson Edstrom 2016-03-27 14:08:43 +02:00
parent 72d1fb813d
commit 993f19c8d2
2 changed files with 167 additions and 58 deletions

View File

@ -76,7 +76,7 @@ TODO:
// MACROS / CONSTANTS
//**************************************************************************
#define VERBOSE 0
#define VERBOSE 2
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
#if VERBOSE == 2
@ -85,8 +85,10 @@ TODO:
#ifdef _MSC_VER
#define FUNCNAME __func__
#define LLFORMAT "%I64%"
#else
#define FUNCNAME __PRETTY_FUNCTION__
#define LLFORMAT "%lld"
#endif
#define CHANA_TAG "cha"
@ -163,10 +165,12 @@ z80scc_device::z80scc_device(const machine_config &mconfig, const char *tag, dev
device_z80daisy_interface(mconfig, *this),
m_chanA(*this, CHANA_TAG),
m_chanB(*this, CHANB_TAG),
#if 0
m_rxca(0),
m_txca(0),
m_rxcb(0),
m_txcb(0),
#endif
m_out_txda_cb(*this),
m_out_dtra_cb(*this),
m_out_rtsa_cb(*this),
@ -198,7 +202,7 @@ scc80230_device::scc80230_device(const machine_config &mconfig, const char *tag,
: z80scc_device(mconfig, SCC80230, "SCC 80230", tag, owner, clock, TYPE_SCC80230, "scc80230", __FILE__){ }
scc8530_device::scc8530_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: z80scc_device(mconfig, SCC8530N, "SCC 8530", tag, owner, clock, TYPE_SCC8530, "scc8530", __FILE__){ }
: z80scc_device(mconfig, SCC8530N, "SCC 8530", tag, owner, clock, TYPE_SCC8530, "scc8530", __FILE__){ }
scc85C30_device::scc85C30_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: z80scc_device(mconfig, SCC85C30, "SCC 85C30", tag, owner, clock, TYPE_SCC85C30, "scc85C30", __FILE__){ }
@ -236,13 +240,17 @@ void z80scc_device::device_start()
m_out_rxdrqb_cb.resolve_safe();
m_out_txdrqb_cb.resolve_safe();
#if 0
// configure channel A
m_chanA->m_rxc = m_rxca;
m_chanA->m_txc = m_txca;
m_chanA->baudtimer = timer_alloc(0);
// configure channel B
m_chanB->m_rxc = m_rxcb;
m_chanB->m_txc = m_txcb;
m_chanB->baudtimer = timer_alloc(1);
#endif
// state saving
save_item(NAME(m_int_state));
@ -257,12 +265,22 @@ void z80scc_device::device_start()
void z80scc_device::device_reset()
{
LOG(("%s %s \n",FUNCNAME, tag()));
LOG(("%s %s \n",tag(), FUNCNAME));
m_chanA->reset();
m_chanB->reset();
}
#if 0
static void z80scc_device::configure_channels(device_t &device, int rxa, int txa, int rxb, int txb)
{
m_chanA->m_rxc = rxa;
m_chanA->m_txc = txa;
m_chanB->m_rxc = rxa;
m_chanB->m_txc = txa;
}
#endif
/*
* Interrupts
Each of the SCC's two channels contain three sources of interrupts, making a total of six interrupt
@ -277,7 +295,7 @@ int z80scc_device::z80daisy_irq_state()
int state = 0;
int i;
LOG(("%s %s A:%d%d%d B:%d%d%d ",FUNCNAME, tag(),
LOG(("%s %s A:%d%d%d B:%d%d%d ",tag(), FUNCNAME,
m_int_state[0], m_int_state[1], m_int_state[2],
m_int_state[3], m_int_state[4], m_int_state[5]));
@ -307,7 +325,7 @@ int z80scc_device::z80daisy_irq_ack()
{
int i;
LOG(("%s %s - needs fixing for SCC\n",FUNCNAME, tag()));
LOG(("%s %s - needs fixing for SCC\n",tag(), FUNCNAME));
// loop over all interrupt sources
for (i = 0; i < 6; i++)
@ -320,7 +338,7 @@ int z80scc_device::z80daisy_irq_ack()
//m_chanA->m_rr0 &= ~z80scc_channel::RR0_INTERRUPT_PENDING;
check_interrupts();
//LOG(("%s %s \n",FUNCNAME, tag(), m_chanB->m_rr2));
//LOG(("%s %s : Interrupt Acknowledge Vector %02x\n",tag(), FUNCNAME, m_chanB->m_rr2));
return m_chanB->m_rr2;
}
@ -340,7 +358,7 @@ void z80scc_device::z80daisy_irq_reti()
{
int i;
LOG(("%s %s \n",FUNCNAME, tag()));
LOG(("%s %s \n",tag(), FUNCNAME));
// loop over all interrupt sources
for (i = 0; i < 6; i++)
@ -366,7 +384,7 @@ void z80scc_device::z80daisy_irq_reti()
void z80scc_device::check_interrupts()
{
int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE;
LOG(("%s %s \n",FUNCNAME, tag()));
LOG(("%s %s \n",tag(), FUNCNAME));
m_out_int_cb(state);
}
@ -377,7 +395,7 @@ void z80scc_device::check_interrupts()
void z80scc_device::reset_interrupts()
{
LOG(("%s %s \n",FUNCNAME, tag()));
LOG(("%s %s \n",tag(), FUNCNAME));
// reset internal interrupt sources
for (auto & elem : m_int_state)
{
@ -404,7 +422,7 @@ UINT8 z80scc_device::modify_vector(UINT8 vec, int i, UINT8 src)
1 1 1 Ch A Special Receive Condition
*/
// Add channel offset according to table above
src |= (i == CHANNEL_A ? 0x04 : 0x00 );
src |= (i == CHANNEL_A ? 0x04 : 0x00 );
// Modify vector according to Hi/lo bit of WR9
if (m_chanA->m_wr9 & z80scc_channel::WR9_BIT_SHSL) // Affect V4-V6
@ -425,12 +443,12 @@ UINT8 z80scc_device::modify_vector(UINT8 vec, int i, UINT8 src)
void z80scc_device::trigger_interrupt(int index, int state)
{
UINT8 vector = m_chanB->m_wr2;
UINT8 source;
UINT8 source = 0;
int priority;
int prio_level;
int prio_level = 0;
LOG(("%s %s:%c %d \n",FUNCNAME, tag(), 'A' + index, state));
LOG(("%s %s:%c %d \n",tag(), FUNCNAME, 'A' + index, state));
/* The Master Interrupt Enable (MIE) bit, WR9 D3, must be set to enable the SCC to generate interrupts.*/
if (!(m_chanA->m_wr9 & z80scc_channel::WR9_BIT_MIE))
@ -484,7 +502,7 @@ void z80scc_device::trigger_interrupt(int index, int state)
vector = modify_vector(vector, index, source);
}
//LOG(("Z80SCC \"%s\": %c : Interrupt Request %u\n", tag(), 'A' + index, state));
LOG(("Z80SCC \"%s\": %c : Interrupt Request %u\n", tag(), 'A' + index, state));
// update vector register // TODO: What if interrupts are nested? May we loose the modified vector or even get the wrong one?
m_chanB->m_wr2 = vector;
@ -671,6 +689,7 @@ WRITE8_MEMBER( z80scc_device::ba_cd_inv_w )
z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, Z80SCC_CHANNEL, "Z80 SCC channel", tag, owner, clock, "z80scc_channel", __FILE__),
device_serial_interface(mconfig, *this),
m_brg_counter(0),
m_rx_error(0),
m_rx_clock(0),
m_rx_first(0),
@ -716,6 +735,9 @@ void z80scc_channel::device_start()
m_rx_fifo_sz = (m_uart->m_variant & SET_ESCC) ? 8 : 3;
m_rx_fifo_wp = m_rx_fifo_rp = 0;
// baudrate clocks and timers
baudtimer = timer_alloc(TIMER_ID_BAUD);
// state saving
save_item(NAME(m_rr0));
save_item(NAME(m_rr1));
@ -828,6 +850,32 @@ void z80scc_channel::device_reset()
void z80scc_channel::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
// LOG(("%s %d\n", FUNCNAME, id));
switch(id)
{
case TIMER_ID_BAUD:
{
int brconst = m_wr13 << 8 | m_wr12 | 1; // If the counter is 1 the effect is passthrough ehh?! To avoid div0...
if (m_wr14 & WR14_BRG_ENABLE)
{
int rate = m_owner->clock() / brconst;
attotime attorate = attotime::from_hz(rate);
timer.adjust(attorate, id, attorate);
txc_w(m_brg_counter & 1);
rxc_w(m_brg_counter & 1);
m_brg_counter++; // Will just keep track of state in timer mode, not hardware counter value.
}
else
{
LOG((" - turning off Baudrate timer\n"));
timer.adjust(attotime::never, 0, attotime::never);
}
}
break;
default:
logerror("Spurious timer %d event\n", id);
}
device_serial_interface::device_timer(timer, id, param, ptr);
}
@ -840,7 +888,7 @@ void z80scc_channel::tra_callback()
{
if (!(m_wr5 & WR5_TX_ENABLE))
{
LOG(("%d %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit mark
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(1);
@ -849,7 +897,7 @@ void z80scc_channel::tra_callback()
}
else if (m_wr5 & WR5_SEND_BREAK)
{
LOG(("%d %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit break
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(0);
@ -860,7 +908,7 @@ void z80scc_channel::tra_callback()
{
int db = transmit_register_get_data_bit();
LOG(("%d %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5));
// transmit data
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(db);
@ -869,7 +917,7 @@ void z80scc_channel::tra_callback()
}
else
{
LOG(("%d %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, m_owner->tag(), 'A' + m_index);
}
}
@ -883,7 +931,7 @@ void z80scc_channel::tra_complete()
{
if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK) && !(m_rr0 & RR0_TX_BUFFER_EMPTY))
{
LOG(("%d %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5));
transmit_register_setup(m_tx_data);
@ -895,7 +943,7 @@ void z80scc_channel::tra_complete()
}
else if (m_wr5 & WR5_SEND_BREAK)
{
LOG(("%d %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit break
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(0);
@ -904,7 +952,7 @@ void z80scc_channel::tra_complete()
}
else
{
LOG(("%d %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// transmit mark
if (m_index == z80scc_device::CHANNEL_A)
m_uart->m_out_txda_cb(1);
@ -915,7 +963,7 @@ void z80scc_channel::tra_complete()
// if transmit buffer is empty
if (m_rr0 & RR0_TX_BUFFER_EMPTY)
{
LOG(("%d %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5));
// then all characters have been sent
m_rr1 |= RR1_ALL_SENT;
@ -939,7 +987,7 @@ void z80scc_channel::rcv_callback()
#if 1
else
{
LOG(("%d %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index));
LOG((LLFORMAT " %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index));
logerror("Z80SCC %s() \"%s \"Channel %c Received data dit but receiver is disabled\n", __func__, m_owner->tag(), 'A' + m_index);
}
#endif
@ -956,7 +1004,7 @@ void z80scc_channel::rcv_complete()
receive_register_extract();
data = get_received_char();
LOG(("%d %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data));
LOG((LLFORMAT " %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data));
receive_data(data);
}
@ -1081,7 +1129,7 @@ int z80scc_channel::get_tx_word_length()
* Break/Abort latch. */
UINT8 z80scc_channel::do_sccreg_rr0()
{
LOG(("%s %s\n",FUNCNAME, tag()));
LOG(("%s %s <- %02x\n",tag(), FUNCNAME, m_rr0));
return m_rr0;
}
@ -1090,7 +1138,7 @@ UINT8 z80scc_channel::do_sccreg_rr0()
* codes for the I-Field in the SDLC Receive Mode. */
UINT8 z80scc_channel::do_sccreg_rr1()
{
LOG(("%s %s\n",FUNCNAME, tag()));
LOG(("%s %s <- %02x\n",tag(), FUNCNAME, m_rr1));
return m_rr1;
}
@ -1710,14 +1758,14 @@ void z80scc_channel::do_sccreg_wr11(UINT8 data)
void z80scc_channel::do_sccreg_wr12(UINT8 data)
{
m_wr12 = data;
LOG(("Z80SCC \"%s\": %c : %s %02x Low byte of Time Constant for Baudrate generator - not implemented \n", m_owner->tag(), 'A' + m_index, __func__, data));
LOG(("Z80SCC \"%s\": %c : %s %02x Low byte of Time Constant for Baudrate generator\n", m_owner->tag(), 'A' + m_index, __func__, data));
}
/* WR13 contains the upper byte of the time constant for the baud rate generator. */
void z80scc_channel::do_sccreg_wr13(UINT8 data)
{
m_wr13 = data;
LOG(("Z80SCC \"%s\": %c : %s %02x High byte of Time Constant for Baudrate generator - not implemented \n", m_owner->tag(), 'A' + m_index, __func__, data));
LOG(("Z80SCC \"%s\": %c : %s %02x High byte of Time Constant for Baudrate generator\n", m_owner->tag(), 'A' + m_index, __func__, data));
}
/*
@ -1759,7 +1807,7 @@ void z80scc_channel::do_sccreg_wr14(UINT8 data)
/* Issuing this command disables the DPLL, resets the clock missing latches in RR10, and forces a continuous Search mode state.*/
LOG(("Z80SCC \"%s\": %c : %s Misc Control Bits Disable DPLL Command - not implemented\n", m_owner->tag(), 'A' + m_index, __func__));
break;
case WR14_CMD_SS_BGR:
case WR14_CMD_SS_BRG:
/* Issuing this command forces the clock for the DPLL to come from the output of the BRG. */
LOG(("Z80SCC \"%s\": %c : %s Misc Control Bits Baudrate Generator Input DPLL Command - not implemented\n", m_owner->tag(), 'A' + m_index, __func__));
break;
@ -1780,6 +1828,26 @@ void z80scc_channel::do_sccreg_wr14(UINT8 data)
default:
logerror("Z80SCC \"%s\": %c : %s Mics Control Bits command %02x - not implemented \n", m_owner->tag(), 'A' + m_index, __func__, data);
}
/* Based on baudrate code from 8530scc.cpp */
if ( !(m_wr14 & WR14_BRG_ENABLE) && (data & WR14_BRG_ENABLE) ) // baud rate generator beeing enabled?
{
LOG(("Z80SCC \"%s\": %c : %s Mics Control Bits Baudrate generator enabled with \n", m_owner->tag(), 'A' + m_index, __func__));
m_brg_counter = m_wr13 << 8 | m_wr12 | 1; // If the counter is 1 the effect is passthrough ehh?! To avoid div0...
if (data & WR14_BRG_SOURCE) // Do we use the PCLK as baudrate source
{
int rate = m_owner->clock() / m_brg_counter;
LOG(("PCLK as source, rate (%d) = PCLK (%d) / (%d)\n", rate, m_owner->clock(), m_brg_counter));
baudtimer->adjust(attotime::from_hz(rate), TIMER_ID_BAUD, attotime::from_hz(rate)); // Start the baudrate generator
}
else
LOG(("external clock source\n"));
}
else if ( (m_wr14 & WR14_BRG_ENABLE) && !(data & WR14_BRG_ENABLE) ) // baud rate generator beeing disabled?
{
baudtimer->adjust(attotime::never, TIMER_ID_BAUD, attotime::never); // Stop the baudrate generator
m_brg_counter = 0;
}
// TODO: Add info on the other bits of this register
m_wr14 = data;
}
@ -2181,7 +2249,34 @@ WRITE_LINE_MEMBER( z80scc_channel::sync_w )
//-------------------------------------------------
WRITE_LINE_MEMBER( z80scc_channel::rxc_w )
{
/* Support for external clock as source for BRG yet to be finished */
#if 0
//LOG(("Z80SCC \"%s\": %c : Receiver Clock Pulse\n", m_owner->tag(), m_index + 'A'));
if ( ((m_wr3 & WR3_RX_ENABLE) | (m_wr5 & WR5_TX_ENABLE)) && m_wr14 & WR14_BRG_ENABLE)
{
if (!(m_wr14 & WR14_BRG_SOURCE)) // Is the Baud rate Generator driven by RTxC?
{
printf("x");
if (!m_brg_counter) // Zero crossing?!
{
printf(".");
m_brg_counter = m_wr13 << 8 | m_wr12; // Reload BRG counter
if ((m_wr11 & WR11_TRACLK_SRC_MASK) == WR11_TRACLK_SRC_BR) // Is transmitt clock driven by BRG?
{
printf("+");
txc_w(state);
}
}
else
{
m_brg_counter--;
if ((m_wr11 & WR11_RCVCLK_SRC_MASK) == WR11_RCVCLK_SRC_BR) // Is receive clock driven by BRG and not zero cross
return;
}
}
}
#endif
if (m_wr3 & WR3_RX_ENABLE)
{
int clocks = get_clock_mode();
@ -2194,7 +2289,6 @@ WRITE_LINE_MEMBER( z80scc_channel::rxc_w )
m_rx_clock++;
if (m_rx_clock == clocks)
m_rx_clock = 0;
}
}
}
@ -2240,7 +2334,7 @@ void z80scc_channel::update_serial()
else
parity = PARITY_NONE;
LOG(("%d %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, 1,
LOG((LLFORMAT " %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, 1,
data_bit_count, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', (stop_bits + 1) / 2));
set_data_frame(1, data_bit_count, parity, stop_bits);

View File

@ -137,7 +137,7 @@ public:
UINT8 do_sccreg_rr5();
UINT8 do_sccreg_rr6();
UINT8 do_sccreg_rr7();
// UINT8 do_sccreg_rr8();
// UINT8 do_sccreg_rr8(); Short cutted due to frequent use
UINT8 do_sccreg_rr9();
UINT8 do_sccreg_rr10();
UINT8 do_sccreg_rr11();
@ -236,21 +236,21 @@ protected:
// Read registers
enum
{
REG_RR0_STATUS = 0, // SIO
REG_RR0_STATUS = 0, // SIO
REG_RR1_SPEC_RCV_COND = 1, // SIO
REG_RR2_INTERRUPT_VECT = 2, // SIO
REG_RR3_INTERUPPT_PEND = 3,
REG_RR4_WR4_OR_RR0 = 4,
REG_RR5_WR5_OR_RR0 = 5,
REG_RR6_LSB_OR_RR2 = 6,
REG_RR7_MSB_OR_RR3 = 7,
REG_RR4_WR4_OR_RR0 = 4,
REG_RR5_WR5_OR_RR0 = 5,
REG_RR6_LSB_OR_RR2 = 6,
REG_RR7_MSB_OR_RR3 = 7,
REG_RR8_RECEIVE_DATA = 8,
REG_RR9_WR3_OR_RR13 = 9,
REG_RR9_WR3_OR_RR13 = 9,
REG_RR10_MISC_STATUS = 10,
REG_RR11_WR10_OR_RR15 = 11,
REG_RR12_LO_TIME_CONST = 12,
REG_RR13_HI_TIME_CONST = 13,
REG_RR14_WR7_OR_R10 = 14,
REG_RR14_WR7_OR_R10 = 14,
REG_RR15_WR15_EXT_STAT = 15
};
@ -259,10 +259,10 @@ protected:
{
REG_WR0_COMMAND_REGPT = 0, // SIO
REG_WR1_INT_DMA_ENABLE = 1, // SIO
REG_WR2_INT_VECTOR = 2, // SIO
REG_WR3_RX_CONTROL = 3, // SIO
REG_WR4_RX_TX_MODES = 4, // SIO
REG_WR5_TX_CONTROL = 5, // SIO
REG_WR2_INT_VECTOR = 2, // SIO
REG_WR3_RX_CONTROL = 3, // SIO
REG_WR4_RX_TX_MODES = 4, // SIO
REG_WR5_TX_CONTROL = 5, // SIO
REG_WR6_SYNC_OR_SDLC_A = 6, // SIO
REG_WR7_SYNC_OR_SDLC_F = 7, // SIO
REG_WR8_TRANSMIT_DATA = 8,
@ -271,21 +271,21 @@ protected:
REG_WR11_CLOCK_MODES = 11,
REG_WR12_LO_BAUD_GEN = 12,
REG_WR13_HI_BAUD_GEN = 13,
REG_WR14_MISC_CTRL = 14,
REG_WR14_MISC_CTRL = 14,
REG_WR15_EXT_ST_INT_CTRL= 15
};
enum
{
RR0_RX_CHAR_AVAILABLE = 0x01, // SIO bit
RR0_ZC = 0x02, // SCC bit
RR0_TX_BUFFER_EMPTY = 0x04, // SIO
RR0_DCD = 0x08, // SIO
RR0_RI = 0x10, // DART bit? TODO: investigate function and remove
RR0_SYNC_HUNT = 0x10, // SIO bit, not supported
RR0_CTS = 0x20, // SIO bit
RR0_TX_UNDERRUN = 0x40, // SIO bit, not supported
RR0_BREAK_ABORT = 0x80 // SIO bit, not supported
RR0_ZC = 0x02, // SCC bit
RR0_TX_BUFFER_EMPTY = 0x04, // SIO
RR0_DCD = 0x08, // SIO
RR0_RI = 0x10, // DART bit? TODO: investigate function and remove
RR0_SYNC_HUNT = 0x10, // SIO bit, not supported
RR0_CTS = 0x20, // SIO bit
RR0_TX_UNDERRUN = 0x40, // SIO bit, not supported
RR0_BREAK_ABORT = 0x80 // SIO bit, not supported
};
enum
@ -456,16 +456,31 @@ protected:
enum
{
WR14_DPLL_CMD_MASK = 0xe0, // Command
WR14_CMD_NULL = 0x00, // 0 0 0
WR14_CMD_ESM = 0x20, // 0 0 1
WR14_CMD_RMC = 0x40, // 0 1 0
WR14_CMD_NULL = 0x00, // 0 0 0
WR14_CMD_ESM = 0x20, // 0 0 1
WR14_CMD_RMC = 0x40, // 0 1 0
WR14_CMD_DISABLE_DPLL = 0x60, // 0 1 1
WR14_CMD_SS_BGR = 0x80, // 1 0 0
WR14_CMD_SS_BRG = 0x80, // 1 0 0
WR14_CMD_SS_RTXC = 0xa0, // 1 0 1
WR14_CMD_SET_FM = 0xc0, // 1 1 0
WR14_CMD_SET_NRZI = 0xe0 // 1 1 1
WR14_CMD_SET_FM = 0xc0, // 1 1 0
WR14_CMD_SET_NRZI = 0xe0, // 1 1 1
WR14_BRG_ENABLE = 0x01,
WR14_BRG_SOURCE = 0x02,
WR14_DTR_REQ_FUNC = 0x04,
WR14_AUTO_ECHO = 0x08,
WR14_LOCAL_LOOPBACK = 0x010
};
enum
{
TIMER_ID_BAUD,
TIMER_ID_XTAL,
TIMER_ID_RTXC,
TIMER_ID_TRXC
};
emu_timer *baudtimer;
UINT16 m_brg_counter;
void update_serial();
void set_dtr(int state);
void set_rts(int state);