Example #1
0
void z80dart_channel::update_serial()
{
	int data_bit_count = get_rx_word_length();
	stop_bits_t stop_bits = get_stop_bits();

	parity_t parity;
	if (m_wr[4] & WR4_PARITY_ENABLE)
	{
		if (m_wr[4] & WR4_PARITY_EVEN)
			parity = PARITY_EVEN;
		else
			parity = PARITY_ODD;
	}
	else
		parity = PARITY_NONE;

	set_data_frame(1, data_bit_count, parity, stop_bits);

	int clocks = get_clock_mode();

	if (m_rxc > 0)
	{
		set_rcv_rate(m_rxc / clocks);
	}

	if (m_txc > 0)
	{
		set_tra_rate(m_txc / clocks);
	}
}
Example #2
0
//-------------------------------------------------
//  update_serial -
//-------------------------------------------------
void z80sio_channel::update_serial()
{
	int data_bit_count = get_rx_word_length();
	stop_bits_t stop_bits = get_stop_bits();
	parity_t parity;

	LOG(("Z80SIO update_serial\n"));

	if (m_wr4 & WR4_PARITY_ENABLE)
	{
		if (m_wr4 & WR4_PARITY_EVEN)
			parity = PARITY_EVEN;
		else
			parity = PARITY_ODD;
	}
	else
		parity = PARITY_NONE;

	set_data_frame(1, data_bit_count, parity, stop_bits);

	int clocks = get_clock_mode();

	if (m_rxc > 0)
	{
		set_rcv_rate(m_rxc / clocks);
	}

	if (m_txc > 0)
	{
		set_tra_rate(m_txc / clocks);
	}
	receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset
}
Example #3
0
void z80dart_channel::update_serial()
{
	int clocks = get_clock_mode();

	if (m_rxc > 0)
	{
		set_rcv_rate(m_rxc / clocks);
	}

	if (m_txc > 0)
	{
		set_tra_rate(m_txc / clocks);
	}

	int num_data_bits = get_rx_word_length();
	int stop_bit_count = get_stop_bits();
	int parity_code = SERIAL_PARITY_NONE;

	if (m_wr[1] & WR4_PARITY_ENABLE)
	{
		if (m_wr[1] & WR4_PARITY_EVEN)
			parity_code = SERIAL_PARITY_EVEN;
		else
			parity_code = SERIAL_PARITY_ODD;
	}

	set_data_frame(num_data_bits, stop_bit_count, parity_code);
}
Example #4
0
void z80dart_channel::update_serial()
{
	int data_bit_count = get_rx_word_length();
	stop_bits_t stop_bits = get_stop_bits();

	parity_t parity;
	if (m_wr[4] & WR4_PARITY_ENABLE)
	{
		if (m_wr[4] & WR4_PARITY_EVEN)
			parity = PARITY_EVEN;
		else
			parity = PARITY_ODD;
	}
	else
		parity = PARITY_NONE;

	set_data_frame(1, data_bit_count, parity, stop_bits);

	int clocks = get_clock_mode();

	if (m_rxc > 0)
	{
		set_rcv_rate(m_rxc / clocks);
	}

	if (m_txc > 0)
	{
		set_tra_rate(m_txc / clocks);
	}
	receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset (FIXME: doing this without checking is stupid)
}
Example #5
0
void z80sio_channel::do_sioreg_wr4(uint8_t data)
{
	m_wr4 = data;
	LOG("Z80SIO \"%s\" Channel %c : Parity Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0);
	LOG("Z80SIO \"%s\" Channel %c : Parity %s\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd");
	LOG("Z80SIO \"%s\" Channel %c : Stop Bits %s\n", m_owner->tag(), 'A' + m_index, stop_bits_tostring(get_stop_bits()));
	LOG("Z80SIO \"%s\" Channel %c : Clock Mode %uX\n", m_owner->tag(), 'A' + m_index, get_clock_mode());
}
Example #6
0
/*-------------------------------------------------------------------------*//**
 * See "mss_rtc.h" for details of how to use this function.
 */
void
MSS_RTC_set_binary_count
(
    uint64_t new_rtc_value
)
{
    uint8_t clock_mode;

    /* 
     * This function can only be used when the RTC is configured to operate in
     * binary counter mode. 
     */
    clock_mode = get_clock_mode();
    ASSERT(MSS_RTC_BINARY_MODE == clock_mode);
    
    if(MSS_RTC_BINARY_MODE == clock_mode)
    {
        uint32_t rtc_upper_32_bit_value;
        
        rtc_upper_32_bit_value = (uint32_t)(new_rtc_value >> 32u) & MASK_32_BIT;

        /* Assert if the values cross the limit */
        ASSERT(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT);

        if(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT)
        {
            uint32_t upload_in_progress;
            
            /*
             * Write the RTC new value. 
             */
            RTC->DATE_TIME_LOWER_REG = (uint32_t)new_rtc_value;
            RTC->DATE_TIME_UPPER_REG =
                    (uint32_t)(( new_rtc_value >> 32u) & MAX_BINARY_HIGHER_COUNT);

            /* Data is copied, now issue upload command */
            RTC->CONTROL_REG = CONTROL_UPLOAD_MASK;
            
            /* Wait for the upload to complete. */
            do {
                upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;
            } while(upload_in_progress);
        }
Example #7
0
//-------------------------------------------------
//  update_serial -
//-------------------------------------------------
void z80sio_channel::update_serial()
{
	int data_bit_count = get_rx_word_length();
	stop_bits_t stop_bits = get_stop_bits();
	parity_t parity;

	LOG("%s\n", FUNCNAME);

	if (m_wr4 & WR4_PARITY_ENABLE)
	{
		LOG("- Parity enabled\n");
		if (m_wr4 & WR4_PARITY_EVEN)
			parity = PARITY_EVEN;
		else
			parity = PARITY_ODD;
	}
	else
		parity = PARITY_NONE;

	set_data_frame(1, data_bit_count, parity, stop_bits);

	int clocks = get_clock_mode();

	if (m_rxc > 0)
	{
		LOG("- RxC:%d/%d = %d\n", m_rxc, clocks, m_rxc / clocks);
		set_rcv_rate(m_rxc / clocks);
	}

	if (m_txc > 0)
	{
		LOG("- TxC:%d/%d = %d\n", m_txc, clocks, m_txc / clocks);
		set_tra_rate(m_txc / clocks);
	}
	receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset
}
Example #8
0
void z80dart_channel::control_write(UINT8 data)
{
	int reg = m_wr[0] & WR0_REGISTER_MASK;

	LOG(("Z80DART \"%s\" Channel %c : Control Register Write '%02x'\n", m_owner->tag(), 'A' + m_index, data));

	// write data to selected register
	if (reg < 6)
		m_wr[reg] = data;

	if (reg != 0)
	{
		// mask out register index
		m_wr[0] &= ~WR0_REGISTER_MASK;
	}

	switch (reg)
	{
	case 0:
		switch (data & WR0_COMMAND_MASK)
		{
		case WR0_NULL:
			LOG(("Z80DART \"%s\" Channel %c : Null\n", m_owner->tag(), 'A' + m_index));
			break;

		case WR0_SEND_ABORT:
			LOG(("Z80DART \"%s\" Channel %c : Send Abort\n", m_owner->tag(), 'A' + m_index));
			logerror("Z80DART \"%s\" Channel %c : unsupported command: Send Abort\n", m_owner->tag(), 'A' + m_index);
			break;

		case WR0_RESET_EXT_STATUS:
			// reset external/status interrupt
			m_rr[0] &= ~(RR0_DCD | RR0_RI | RR0_CTS | RR0_BREAK_ABORT);

			if (!m_dcd) m_rr[0] |= RR0_DCD;
			if (m_ri) m_rr[0] |= RR0_RI;
			if (m_cts) m_rr[0] |= RR0_CTS;

			m_rx_rr0_latch = 0;

			LOG(("Z80DART \"%s\" Channel %c : Reset External/Status Interrupt\n", m_owner->tag(), 'A' + m_index));
			break;

		case WR0_CHANNEL_RESET:
			// channel reset
			LOG(("Z80DART \"%s\" Channel %c : Channel Reset\n", m_owner->tag(), 'A' + m_index));
			device_reset();
			break;

		case WR0_ENABLE_INT_NEXT_RX:
			// enable interrupt on next receive character
			LOG(("Z80DART \"%s\" Channel %c : Enable Interrupt on Next Received Character\n", m_owner->tag(), 'A' + m_index));
			m_rx_first = 1;
			break;

		case WR0_RESET_TX_INT:
			// reset transmitter interrupt pending
			LOG(("Z80DART \"%s\" Channel %c : Reset Transmitter Interrupt Pending\n", m_owner->tag(), 'A' + m_index));
			logerror("Z80DART \"%s\" Channel %c : unsupported command: Reset Transmitter Interrupt Pending\n", m_owner->tag(), 'A' + m_index);
			break;

		case WR0_ERROR_RESET:
			// error reset
			LOG(("Z80DART \"%s\" Channel %c : Error Reset\n", m_owner->tag(), 'A' + m_index));
			m_rr[1] &= ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR);
			break;

		case WR0_RETURN_FROM_INT:
			// return from interrupt
			LOG(("Z80DART \"%s\" Channel %c : Return from Interrupt\n", m_owner->tag(), 'A' + m_index));
			m_uart->z80daisy_irq_reti();
			break;
		}
		break;

	case 1:
		LOG(("Z80DART \"%s\" Channel %c : External Interrupt Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_EXT_INT_ENABLE) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Transmit Interrupt Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_TX_INT_ENABLE) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Status Affects Vector %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_STATUS_VECTOR) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Wait/Ready Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_WRDY_ENABLE) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Wait/Ready Function %s\n", m_owner->tag(), 'A' + m_index, (data & WR1_WRDY_FUNCTION) ? "Ready" : "Wait"));
		LOG(("Z80DART \"%s\" Channel %c : Wait/Ready on %s\n", m_owner->tag(), 'A' + m_index, (data & WR1_WRDY_ON_RX_TX) ? "Receive" : "Transmit"));

		switch (data & WR1_RX_INT_MODE_MASK)
		{
		case WR1_RX_INT_DISABLE:
			LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt Disabled\n", m_owner->tag(), 'A' + m_index));
			break;

		case WR1_RX_INT_FIRST:
			LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on First Character\n", m_owner->tag(), 'A' + m_index));
			break;

		case WR1_RX_INT_ALL_PARITY:
			LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters, Parity Affects Vector\n", m_owner->tag(), 'A' + m_index));
			break;

		case WR1_RX_INT_ALL:
			LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters\n", m_owner->tag(), 'A' + m_index));
			break;
		}

		m_uart->check_interrupts();
		break;

	case 2:
		// interrupt vector
		if (m_index == z80dart_device::CHANNEL_B)
			m_rr[2] = ( m_rr[2] & 0x0e ) | ( m_wr[2] & 0xF1);;

		m_uart->check_interrupts();
		LOG(("Z80DART \"%s\" Channel %c : Interrupt Vector %02x\n", m_owner->tag(), 'A' + m_index, data));
		break;

	case 3:
		LOG(("Z80DART \"%s\" Channel %c : Receiver Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR3_RX_ENABLE) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Auto Enables %u\n", m_owner->tag(), 'A' + m_index, (data & WR3_AUTO_ENABLES) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Receiver Bits/Character %u\n", m_owner->tag(), 'A' + m_index, get_rx_word_length()));

		update_serial();
		break;

	case 4:
		LOG(("Z80DART \"%s\" Channel %c : Parity Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Parity %s\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd"));
		LOG(("Z80DART \"%s\" Channel %c : Stop Bits %s\n", m_owner->tag(), 'A' + m_index, stop_bits_tostring(get_stop_bits())));
		LOG(("Z80DART \"%s\" Channel %c : Clock Mode %uX\n", m_owner->tag(), 'A' + m_index, get_clock_mode()));

		update_serial();
		break;

	case 5:
		LOG(("Z80DART \"%s\" Channel %c : Transmitter Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_TX_ENABLE) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Transmitter Bits/Character %u\n", m_owner->tag(), 'A' + m_index, get_tx_word_length()));
		LOG(("Z80DART \"%s\" Channel %c : Send Break %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_SEND_BREAK) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Request to Send %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_RTS) ? 1 : 0));
		LOG(("Z80DART \"%s\" Channel %c : Data Terminal Ready %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_DTR) ? 1 : 0));

		update_serial();

		if (data & WR5_RTS)
		{
			// when the RTS bit is set, the _RTS output goes low
			set_rts(0);
			m_rts = 1;
		}
		else
		{
			// when the RTS bit is reset, the _RTS output goes high after the transmitter empties
			m_rts = 0;
		}

		// data terminal ready output follows the state programmed into the DTR bit*/
		set_dtr((data & WR5_DTR) ? 0 : 1);
		break;

	case 6:
		LOG(("Z80DART \"%s\" Channel %c : Transmit Sync %02x\n", m_owner->tag(), 'A' + m_index, data));
		m_sync = (m_sync & 0xff00) | data;
		break;

	case 7:
		LOG(("Z80DART \"%s\" Channel %c : Receive Sync %02x\n", m_owner->tag(), 'A' + m_index, data));
		m_sync = (data << 8) | (m_sync & 0xff);
		break;
	}
}
Example #9
0
/*-------------------------------------------------------------------------*//**
  See "mss_rtc.h" for details of how to use this function.
 */
void
MSS_RTC_set_calendar_count
(
    const mss_rtc_calendar_t *new_rtc_value
)
{
    uint8_t error = 0u;
    uint8_t clock_mode;
    
    const uint8_t g_rtc_max_count_lut[] =
    {
       /* Calendar mode */
        59u,    /* Seconds */
        59u,    /* Minutes */
        23u,    /* Hours   */
        31u,    /* Days    */
        12u,    /* Months  */
        254u,   /* Years   */
        7u,     /* Weekdays*/
        52u     /* Week    */
    };

    const uint8_t g_rtc_min_count_lut[] =
    {
       /* Calendar mode */
        0u, /* Seconds */
        0u, /* Minutes */
        0u, /* Hours   */
        1u, /* Days    */
        1u, /* Months  */
        0u, /* Years   */
        1u, /* Weekdays*/
        1u  /* Week    */
    };
    
    /* Assert if the values cross the limit */
    ASSERT(new_rtc_value->second >= g_rtc_min_count_lut[SECONDS]);
    ASSERT(new_rtc_value->second <= g_rtc_max_count_lut[SECONDS]);
    ASSERT(new_rtc_value->minute >= g_rtc_min_count_lut[MINUTES]);
    ASSERT(new_rtc_value->minute <= g_rtc_max_count_lut[MINUTES]);
    ASSERT(new_rtc_value->hour >= g_rtc_min_count_lut[HOURS]);
    ASSERT(new_rtc_value->hour <= g_rtc_max_count_lut[HOURS]);
    ASSERT(new_rtc_value->day >= g_rtc_min_count_lut[DAYS]);
    ASSERT(new_rtc_value->day <= g_rtc_max_count_lut[DAYS]);
    ASSERT(new_rtc_value->month >= g_rtc_min_count_lut[MONTHS]);
    ASSERT(new_rtc_value->month <= g_rtc_max_count_lut[MONTHS]);
    ASSERT(new_rtc_value->year >= g_rtc_min_count_lut[YEARS]);
    ASSERT(new_rtc_value->year <= g_rtc_max_count_lut[YEARS]);
    ASSERT(new_rtc_value->weekday >= g_rtc_min_count_lut[WEEKDAYS]);
    ASSERT(new_rtc_value->weekday <= g_rtc_max_count_lut[WEEKDAYS]);
    ASSERT(new_rtc_value->week >= g_rtc_min_count_lut[WEEKS]);
    ASSERT(new_rtc_value->week <= g_rtc_max_count_lut[WEEKS]);

    if(new_rtc_value->second < g_rtc_min_count_lut[SECONDS]) {error = 1u;}
    if(new_rtc_value->second > g_rtc_max_count_lut[SECONDS]) {error = 1u;}
    if(new_rtc_value->minute < g_rtc_min_count_lut[MINUTES]) {error = 1u;}
    if(new_rtc_value->minute > g_rtc_max_count_lut[MINUTES]) {error = 1u;}
    if(new_rtc_value->hour < g_rtc_min_count_lut[HOURS]) {error = 1u;}
    if(new_rtc_value->hour > g_rtc_max_count_lut[HOURS]) {error = 1u;}
    if(new_rtc_value->day < g_rtc_min_count_lut[DAYS]) {error = 1u;}
    if(new_rtc_value->day > g_rtc_max_count_lut[DAYS]) {error = 1u;}
    if(new_rtc_value->month < g_rtc_min_count_lut[MONTHS]) {error = 1u;}
    if(new_rtc_value->month > g_rtc_max_count_lut[MONTHS]) {error = 1u;}
    if(new_rtc_value->year < g_rtc_min_count_lut[YEARS]) {error = 1u;}
    if(new_rtc_value->year > g_rtc_max_count_lut[YEARS]) {error = 1u;}
    if(new_rtc_value->weekday < g_rtc_min_count_lut[WEEKDAYS]) {error = 1u;}
    if(new_rtc_value->weekday > g_rtc_max_count_lut[WEEKDAYS]) {error = 1u;}
    if(new_rtc_value->week < g_rtc_min_count_lut[WEEKS]) {error = 1u;}
    if(new_rtc_value->week > g_rtc_max_count_lut[WEEKS]) {error = 1u;}

    /* 
     * This function can only be used when the RTC is configured to operate in
     * calendar counter mode. 
     */
    clock_mode = get_clock_mode();
    ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);
    
    if((0u == error) && (MSS_RTC_CALENDAR_MODE == clock_mode))
    {
        uint32_t upload_in_progress;
        
        /*
         * Write the RTC new value. 
         */
        RTC->SECONDS_REG = new_rtc_value->second;
        RTC->MINUTES_REG = new_rtc_value->minute;
        RTC->HOURS_REG = new_rtc_value->hour;
        RTC->DAY_REG = new_rtc_value->day;
        RTC->MONTH_REG = new_rtc_value->month;
        RTC->YEAR_REG = new_rtc_value->year;
        RTC->WEEKDAY_REG = new_rtc_value->weekday;
        RTC->WEEK_REG = new_rtc_value->week;

        /* Data is copied, now issue upload command */
        RTC->CONTROL_REG = CONTROL_UPLOAD_MASK ;
        
        /* Wait for the upload to complete. */
        do {
            upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;
        } while(upload_in_progress);
    }
}