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); } }
//------------------------------------------------- // 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 }
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); }
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) }
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()); }
/*-------------------------------------------------------------------------*//** * 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); }
//------------------------------------------------- // 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 }
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; } }
/*-------------------------------------------------------------------------*//** 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); } }