From b5ae4a8876c8c057c432ff0ecbaa9e108c03dfe2 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 13:51:13 +0200 Subject: [PATCH 01/12] i8251.cpp: modernized debug printouts --- src/devices/machine/i8251.cpp | 96 +++++++++++++++-------------------- 1 file changed, 40 insertions(+), 56 deletions(-) diff --git a/src/devices/machine/i8251.cpp b/src/devices/machine/i8251.cpp index 1712796e64d..5c1638acffd 100644 --- a/src/devices/machine/i8251.cpp +++ b/src/devices/machine/i8251.cpp @@ -23,9 +23,20 @@ To Do: #include "emu.h" #include "i8251.h" -//#define VERBOSE 1 +#define LOG_STAT (1U << 1) +#define LOG_COM (1U << 2) +#define LOG_MODE (1U << 3) +#define LOG_BITS (1U << 4) + +//#define VERBOSE (LOG_BITS|LOG_GENERAL) +//#define LOG_OUTPUT_STREAM std::cout + #include "logmacro.h" +#define LOGSTAT(...) LOGMASKED(LOG_STAT, __VA_ARGS__) +#define LOGCOM(...) LOGMASKED(LOG_COM, __VA_ARGS__) +#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__) +#define LOGBITS(...) LOGMASKED(LOG_BITS, __VA_ARGS__) //************************************************************************** // DEVICE DEFINITIONS @@ -153,6 +164,7 @@ void i8251_device::receive_clock() //logerror("I8251\n"); /* get bit received from other side and update receive register */ + //LOGBITS("8251: Rx Sampled %d\n", m_rxd); receive_register_update_bit(m_rxd); if (is_receive_register_synchronized()) m_rxc_count = sync ? m_br_factor : (3 * m_br_factor / 2); @@ -316,7 +328,9 @@ bool i8251_device::is_tx_enabled() const void i8251_device::check_for_tx_start() { if (is_tx_enabled() && (m_status & (I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY)) == I8251_STATUS_TX_EMPTY) + { start_tx(); + } } /*------------------------------------------------- @@ -357,6 +371,7 @@ void i8251_device::transmit_clock() if (!is_transmit_register_empty()) { uint8_t data = transmit_register_get_data_bit(); + LOGBITS("8251: Tx Present a %d\n", data); m_txd_handler(data); } } @@ -454,6 +469,7 @@ void i8251_device::device_reset() /* no character to read by cpu */ /* transmitter is ready and is empty */ m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY; + LOGSTAT("status is reset to %02x\n", m_status); m_mode_byte = 0; m_command = 0; m_rx_data = 0; @@ -478,67 +494,26 @@ void i8251_device::device_reset() void i8251_device::command_w(uint8_t data) { /* command */ - LOG("I8251: Command byte\n"); - m_command = data; - LOG("Command byte: %02x\n", data); - - if (BIT(data, 7)) - LOG("hunt mode\n"); - - if (BIT(data, 5)) - LOG("/rts set to 0\n"); - else - LOG("/rts set to 1\n"); - - if (BIT(data, 2)) - LOG("receive enable\n"); - else - LOG("receive disable\n"); - - if (BIT(data, 1)) - LOG("/dtr set to 0\n"); - else - LOG("/dtr set to 1\n"); - - if (BIT(data, 0)) - LOG("transmit enable\n"); - else - LOG("transmit disable\n"); - - - /* 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 - */ + LOG("I8251: Command byte: %02x\n", data); + LOGCOM(" Tx enable: %d\n", data & 0x01 ? 1 : 0); // bit 0: 0 = transmit disable 1 = transmit enable + LOGCOM(" DTR : %d\n", data & 0x02 ? 1 : 0); // bit 1: 0 = /DTR set to 1 1 = /DTR set to 0 + LOGCOM(" Rx enable: %d\n", data & 0x04 ? 1 : 0); // bit 2: 0 = receive disable 1 = receive enable + LOGCOM(" Send BRK : %d\n", data & 0x08 ? 1 : 0); // bit 3: 0 = normal operation 1 = send break character + LOGCOM(" Err reset: %d\n", data & 0x10 ? 1 : 0); // bit 4: 0 = normal operation 1 = reset error flag + LOGCOM(" RTS : %d\n", data & 0x20 ? 1 : 0); // bit 5: 0 = /RTS set to 1 1 = /RTS set to 0 + LOGCOM(" Reset : %d\n", data & 0x40 ? 1 : 0); // bit 6: 0 = normal operation 1 = internal reset + LOGCOM(" Hunt mode: %d\n", data & 0x80 ? 1 : 0); // bit 7: 0 = normal operation 1 = hunt mode m_rts_handler(!BIT(data, 5)); m_dtr_handler(!BIT(data, 1)); if (BIT(data, 4)) + { + LOGSTAT("status errors are reset\n"); m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR); + } if (BIT(data, 6)) { @@ -596,7 +571,6 @@ void i8251_device::mode_w(uint8_t data) 3 = x64 Synchronous - bit 7: Number of sync characters 0 = 1 character 1 = 2 character @@ -746,6 +720,7 @@ uint8_t i8251_device::status_r() // Syndet always goes off after status read update_syndet(false); + return status; } @@ -763,6 +738,7 @@ void i8251_device::data_w(uint8_t data) /* writing clears */ m_status &=~I8251_STATUS_TX_READY; + LOGSTAT("8251: status cleared TX_READY by data_w\n"); update_tx_ready(); // Store state of tx enable when writing to DB buffer @@ -788,11 +764,17 @@ void i8251_device::receive_character(uint8_t ch) m_rx_data = ch; + LOGSTAT("status RX READY test %02x\n", m_status); /* char has not been read and another has arrived! */ if (m_status & I8251_STATUS_RX_READY) + { m_status |= I8251_STATUS_OVERRUN_ERROR; + LOGSTAT("status overrun set\n"); + } + LOGSTAT("status pre RX READY set %02x\n", m_status); m_status |= I8251_STATUS_RX_READY; + LOGSTAT("status post RX READY set %02x\n", m_status); update_rx_ready(); } @@ -810,6 +792,7 @@ uint8_t i8251_device::data_r() if (!machine().side_effects_disabled()) { m_status &= ~I8251_STATUS_RX_READY; + LOGSTAT("status RX_READY cleared\n"); update_rx_ready(); } return m_rx_data; @@ -836,7 +819,8 @@ void i8251_device::write(offs_t offset, uint8_t data) WRITE_LINE_MEMBER(i8251_device::write_rxd) { m_rxd = state; -// device_serial_interface::rx_w(state); + LOGBITS("8251: Presented a %d\n", m_rxd); + // device_serial_interface::rx_w(state); } WRITE_LINE_MEMBER(i8251_device::write_cts) From 7c6ca794ae462b264b3ca9d99c8005d67720d8c1 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 13:54:41 +0200 Subject: [PATCH 02/12] m6801.cpp: more logging and reduced unneeded updates of Tx line --- src/devices/cpu/m6800/m6801.cpp | 50 ++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index 28339b33005..31076690bef 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -10,8 +10,10 @@ #define LOG_RX (1U << 3) #define LOG_RXTICK (1U << 4) #define LOG_PORT (1U << 5) +#define LOG_SER (1U << 6) -//#define VERBOSE (LOG_GENERAL | LOG_TX | LOG_RX | LOG_PORT) +//#define VERBOSE (LOG_SER) +//#define LOG_OUTPUT_STREAM std::cout //#define LOG_OUTPUT_STREAM std::cerr #include "logmacro.h" @@ -20,6 +22,7 @@ #define LOGRX(...) LOGMASKED(LOG_RX, __VA_ARGS__) #define LOGRXTICK(...) LOGMASKED(LOG_RXTICK, __VA_ARGS__) #define LOGPORT(...) LOGMASKED(LOG_PORT, __VA_ARGS__) +#define LOGSER(...) LOGMASKED(LOG_SER, __VA_ARGS__) #define CT m_counter.w.l @@ -413,11 +416,13 @@ void m6801_cpu_device::set_rmcr(uint8_t data) switch ((m_rmcr & M6801_RMCR_CC_MASK) >> 2) { case 0: + LOGSER("6801: Using external serial clock: false\n"); m_sci_timer->enable(false); m_use_ext_serclock = false; break; case 3: // external clock + LOGSER("6801: Using external serial clock: true\n"); m_use_ext_serclock = true; m_sci_timer->enable(false); break; @@ -427,7 +432,7 @@ void m6801_cpu_device::set_rmcr(uint8_t data) { int divisor = M6801_RMCR_SS[m_rmcr & M6801_RMCR_SS_MASK]; attotime period = cycles_to_attotime(divisor); - + LOGSER("6801: Setting serial rate, Divisor: %d Hz: %d\n", divisor, period.as_hz()); m_sci_timer->adjust(period, 0, period); m_use_ext_serclock = false; } @@ -442,10 +447,12 @@ int m6801_cpu_device::m6800_rx() void m6801_cpu_device::serial_transmit() { - LOGTXTICK("Tx Tick\n"); + LOGTXTICK("6801 Tx Tick presenting: %d\n", m_tx); if (m_trcsr & M6801_TRCSR_TE) { + int old_m_tx = m_tx; // Detect line change + // force Port 2 bit 4 as output m_port_ddr[1] |= M6801_PORT2_IO4; @@ -486,7 +493,7 @@ void m6801_cpu_device::serial_transmit() m_txbits++; - LOGTX("Transmit START Data %02x\n", m_tsr); + LOGTX("6801 Transmit START Data %02x\n", m_tsr); } break; @@ -498,7 +505,7 @@ void m6801_cpu_device::serial_transmit() m_txbits = M6801_SERIAL_START; - LOGTX("Transmit STOP\n"); + LOGTX("6801 Transmit STOP\n"); break; default: @@ -508,7 +515,7 @@ void m6801_cpu_device::serial_transmit() // shift transmit register m_tsr >>= 1; - LOGTX("Transmit Bit %u: %u\n", m_txbits, m_tx); + LOGTX("6801 Tx Present Bit %u: %u\n", m_txbits, m_tx); m_txbits++; break; @@ -516,7 +523,10 @@ void m6801_cpu_device::serial_transmit() break; } - m_out_sertx_func((m_tx == 1) ? ASSERT_LINE : CLEAR_LINE); + if (old_m_tx != m_tx) // call callback only if line has changed + { + m_out_sertx_func((m_tx == 1) ? ASSERT_LINE : CLEAR_LINE); + } m_port2_written = 1; write_port2(); } @@ -524,7 +534,7 @@ void m6801_cpu_device::serial_transmit() void m6801_cpu_device::serial_receive() { - LOGRXTICK("Rx Tick TRCSR %02x bits %u check %02x\n", m_trcsr, m_rxbits, m_trcsr & M6801_TRCSR_RE); + LOGRXTICK("6801 Rx Tick TRCSR %02x bits %u check %02x\n", m_trcsr, m_rxbits, m_trcsr & M6801_TRCSR_RE); if (m_trcsr & M6801_TRCSR_RE) { @@ -535,11 +545,11 @@ void m6801_cpu_device::serial_receive() { m_rxbits++; - LOGRX("Received WAKE UP bit %u\n", m_rxbits); + LOGRX("6801 Received WAKE UP bit %u\n", m_rxbits); if (m_rxbits == 10) { - LOGRX("Receiver Wake Up\n"); + LOGRX("6801 Receiver Wake Up\n"); m_trcsr &= ~M6801_TRCSR_WU; m_rxbits = M6801_SERIAL_START; @@ -547,7 +557,7 @@ void m6801_cpu_device::serial_receive() } else { - LOGRX("Receiver Wake Up interrupted\n"); + LOGRX("6801 Receiver Wake Up interrupted\n"); m_rxbits = M6801_SERIAL_START; } @@ -563,21 +573,21 @@ void m6801_cpu_device::serial_receive() // start bit found m_rxbits++; - LOGRX("Received START bit\n"); + LOGRX("6801 Received START bit\n"); } break; case M6801_SERIAL_STOP: if (m6800_rx() == 1) { - LOGRX("Received STOP bit\n"); + LOGRX("6801 Received STOP bit\n"); if (m_trcsr & M6801_TRCSR_RDRF) { // overrun error m_trcsr |= M6801_TRCSR_ORFE; - LOGRX("Receive Overrun Error\n"); + LOGRX("6801 Receive Overrun Error\n"); CHECK_IRQ_LINES(); } @@ -588,7 +598,7 @@ void m6801_cpu_device::serial_receive() // transfer data into receive register m_rdr = m_rsr; - LOGRX("Receive Data Register: %02x\n", m_rdr); + LOGRX("6801 Receive Data Register: %02x\n", m_rdr); // set RDRF flag m_trcsr |= M6801_TRCSR_RDRF; @@ -609,7 +619,7 @@ void m6801_cpu_device::serial_receive() m_trcsr |= M6801_TRCSR_ORFE; m_trcsr &= ~M6801_TRCSR_RDRF; - LOGRX("Receive Framing Error\n"); + LOGRX("6801 Receive Framing Error\n"); CHECK_IRQ_LINES(); } @@ -624,7 +634,7 @@ void m6801_cpu_device::serial_receive() // receive bit into register m_rsr |= (m6800_rx() << 7); - LOGRX("Received DATA bit %u: %u\n", m_rxbits, BIT(m_rsr, 7)); + LOGRX("6801 RX sampled DATA bit %u: %u\n", m_rxbits, BIT(m_rsr, 7)); m_rxbits++; break; @@ -1192,13 +1202,13 @@ WRITE8_MEMBER( m6801_cpu_device::m6801_io_w ) break; case IO_RMCR: - LOG("Rate and Mode Control Register: %02x\n", data); + LOGSER("Rate and Mode Control Register: %02x\n", data); set_rmcr(data); break; case IO_TRCSR: - LOG("Transmit/Receive Control and Status Register: %02x\n", data); + LOGSER("Transmit/Receive Control and Status Register: %02x\n", data); if ((data & M6801_TRCSR_TE) && !(m_trcsr & M6801_TRCSR_TE)) { @@ -1216,7 +1226,7 @@ WRITE8_MEMBER( m6801_cpu_device::m6801_io_w ) break; case IO_TDR: - LOGTX("Transmit Data Register: %02x\n", data); + LOGSER("6801 Transmit Data Register: $%02x/%d\n", data, data); if (m_trcsr_read_tdre) { From d7125bedbcfbc40632beaae726ad261dfd29e436 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 13:57:21 +0200 Subject: [PATCH 03/12] mc6845.cpp: more logging and reduced (not eliminated) warning spam significantly at startup when register values doesn't make sense --- src/devices/video/mc6845.cpp | 48 +++++++++++++++++++++++++++++------- src/devices/video/mc6845.h | 1 + 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index 1c0862f1564..cef7b7d036e 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -45,12 +45,18 @@ #include "screen.h" -#define LOG_REGS (1 << 0U) -#define LOG_CONFIG (1 << 1U) -#define VERBOSE (0) +#define LOG_SETUP (1 << 1U) +#define LOG_REGS (1 << 2U) +#define LOG_CONF (1 << 3U) + +//#define VERBOSE (LOG_SETUP|LOG_CONF|LOG_REGS) +//#define LOG_OUTPUT_STREAM std::cout #include "logmacro.h" +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGREGS(...) LOGMASKED(LOG_REGS, __VA_ARGS__) +#define LOGCONF(...) LOGMASKED(LOG_CONF, __VA_ARGS__) DEFINE_DEVICE_TYPE(MC6845, mc6845_device, "mc6845", "Motorola MC6845 CRTC") DEFINE_DEVICE_TYPE(MC6845_1, mc6845_1_device, "mc6845_1", "Motorola MC6845-1 CRTC") @@ -213,7 +219,19 @@ uint8_t mc6845_device::register_r() void mc6845_device::register_w(uint8_t data) { - LOGMASKED(LOG_REGS, "%s:M6845 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); + LOGREGS("%s:M6845 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); + + /* Omits LOGSETUP logs of cursor registers as they tend to be spammy */ + if (m_register_address_latch < 0x0e && + m_register_address_latch != 0x0a && + m_register_address_latch != 0x0b) LOGSETUP(" * %02x <= %3u [%02x] %s\n", m_register_address_latch, + data, data, std::array + {{ "R0 - Horizontal Total", "R1 - Horizontal Displayed", "R2 - Horizontal Sync Position", + "R3 - Sync Width", "R4 - Vertical Total", "R5 - Vertical Total Adjust", + "R6 - Vertical Displayed", "R7 - Vertical Sync Position", "R8 - Interlace & Skew", + "R9 - Maximum Raster Address", "R10 - Cursor Start Address", "R11 - Cursor End Address", + "R12 - Start Address (H)", "R13 - Start Address (L)", "R14 - Cursor (H)", + "R15 - Cursor (L)" }}[(m_register_address_latch & 0x0f)]); switch (m_register_address_latch) { @@ -342,7 +360,7 @@ uint8_t mos8563_device::register_r() void mos8563_device::register_w(uint8_t data) { - LOGMASKED(LOG_REGS, "%s:MOS8563 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); + LOGREGS("%s:MOS8563 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); switch (m_register_address_latch) { @@ -429,7 +447,7 @@ uint8_t hd6345_device::register_r() void hd6345_device::register_w(uint8_t data) { - LOGMASKED(LOG_REGS, "%s:HD6345 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); + LOGREGS("%s:HD6345 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); switch (m_register_address_latch) { @@ -571,8 +589,8 @@ void mc6845_device::recompute_parameters(bool postload) else visarea.set(0 + m_visarea_adjust_min_x, max_visible_x + m_visarea_adjust_max_x, 0 + m_visarea_adjust_min_y, max_visible_y + m_visarea_adjust_max_y); - LOGMASKED(LOG_CONFIG, "M6845 config screen: HTOTAL: %d VTOTAL: %d MAX_X: %d MAX_Y: %d HSYNC: %d-%d VSYNC: %d-%d Freq: %ffps\n", - horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, hsync_on_pos, hsync_off_pos - 1, vsync_on_pos, vsync_off_pos - 1, refresh.as_hz()); + LOGCONF("M6845 config screen: HTOTAL: %d VTOTAL: %d MAX_X: %d MAX_Y: %d HSYNC: %d-%d VSYNC: %d-%d Freq: %ffps\n", + horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, hsync_on_pos, hsync_off_pos - 1, vsync_on_pos, vsync_off_pos - 1, refresh.as_hz()); if (has_screen()) screen().configure(horiz_pix_total, vert_pix_total, visarea, refresh.as_attoseconds()); @@ -1073,6 +1091,12 @@ uint32_t mc6845_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma { assert(!m_update_row_cb.isnull()); + if (m_display_disabled_msg_shown == true) + { + logerror("M6845: Valid screen parameters - display reenabled!!!\n"); + m_display_disabled_msg_shown = false; + } + /* call the set up function if any */ if (!m_begin_update_cb.isnull()) m_begin_update_cb(bitmap, cliprect); @@ -1095,7 +1119,11 @@ uint32_t mc6845_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma } else { - LOGMASKED(LOG_CONFIG, "M6845: Invalid screen parameters - display disabled!!!\n"); + if (m_display_disabled_msg_shown == false) + { + logerror("M6845: Invalid screen parameters - display disabled!!!\n"); + m_display_disabled_msg_shown = true; + } } return 0; @@ -1143,6 +1171,7 @@ void mc6845_device::device_start() m_supports_status_reg_d7 = false; m_supports_transparent = false; m_has_valid_parameters = false; + m_display_disabled_msg_shown = false; m_line_enable_ff = false; m_vsync_ff = 0; m_raster_counter = 0; @@ -1214,6 +1243,7 @@ void mc6845_device::device_start() save_item(NAME(m_line_address)); save_item(NAME(m_cursor_x)); save_item(NAME(m_has_valid_parameters)); + save_item(NAME(m_display_disabled_msg_shown)); } diff --git a/src/devices/video/mc6845.h b/src/devices/video/mc6845.h index d124dc6fde6..f20b83e5eff 100644 --- a/src/devices/video/mc6845.h +++ b/src/devices/video/mc6845.h @@ -219,6 +219,7 @@ protected: uint16_t m_vsync_on_pos; uint16_t m_vsync_off_pos; bool m_has_valid_parameters; + bool m_display_disabled_msg_shown; uint16_t m_current_disp_addr; /* the display address currently drawn (used only in mc6845_update) */ From dd737543f03a269c80fccdf56a4ad7820fd81d88 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 13:58:25 +0200 Subject: [PATCH 04/12] pit8253.cpp: introduced logmacro.h based logging --- src/devices/machine/pit8253.cpp | 44 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/devices/machine/pit8253.cpp b/src/devices/machine/pit8253.cpp index 28173bad237..06afd19e931 100644 --- a/src/devices/machine/pit8253.cpp +++ b/src/devices/machine/pit8253.cpp @@ -30,10 +30,16 @@ ***************************************************************************/ -#define VERBOSE 0 +#define LOG_1 (1U << 1) +#define LOG_2 (1U << 2) -#define LOG1(msg) do { if (VERBOSE >= 1) logerror msg; } while (0) -#define LOG2(msg) do { if (VERBOSE >= 2) logerror msg; } while (0) +//#define VERBOSE (LOG_1 | LOG_2) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOG1(...) LOGMASKED(LOG_1, __VA_ARGS__) +#define LOG2(...) LOGMASKED(LOG_2, __VA_ARGS__) DEFINE_DEVICE_TYPE(PIT_COUNTER, pit_counter_device, "pit_counter", "PIT Counter") DEFINE_DEVICE_TYPE(PIT8253, pit8253_device, "pit8253", "Intel 8253 PIT") @@ -288,7 +294,7 @@ void pit_counter_device::set_output(int output) if (output != m_output) { m_output = output; - LOG2(("set_output(): %s\n", output ? "low to high" : "high to low")); + LOG2("set_output() timer %d: %s\n", m_index, output ? "low to high" : "high to low"); downcast(owner())->m_out_handler[m_index](output); } @@ -305,8 +311,8 @@ void pit_counter_device::simulate(int64_t elapsed_cycles) static const uint32_t CYCLES_NEVER = (0xffffffff); uint32_t cycles_to_output = 0; - LOG2(("simulate(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x\n", - (int)elapsed_cycles, mode, bcd, m_phase, m_gate, m_output, m_value)); + LOG2("simulate2(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x\n", + (int)elapsed_cycles, mode, bcd, m_phase, m_gate, m_output, m_value); switch (mode) { @@ -688,8 +694,8 @@ void pit_counter_device::simulate(int64_t elapsed_cycles) m_updatetimer->adjust(next_fire_time - machine().time()); } - LOG2(("simulate(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x, cycles_to_output = %04x\n", - (int)elapsed_cycles, mode, bcd, m_phase, m_gate, m_output, m_value, cycles_to_output)); + LOG2("simulate2(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x, cycles_to_output = %04x\n", + (int)elapsed_cycles, mode, bcd, m_phase, m_gate, m_output, m_value, cycles_to_output); } /* This brings timer "timer" up to date */ @@ -701,7 +707,7 @@ void pit_counter_device::update() attotime elapsed_time = now - m_last_updated; int64_t elapsed_cycles = elapsed_time.as_double() * m_clockin; - LOG2(("update(): %d elapsed_cycles\n", elapsed_cycles)); + LOG2("update(): %d elapsed_cycles\n", elapsed_cycles); if (m_clockin) m_last_updated += elapsed_cycles * attotime::from_hz(m_clockin); @@ -799,7 +805,7 @@ uint8_t pit_counter_device::read() } } - LOG2(("read(): data=0x%02x\n", data)); + LOG2("read(): data=0x%02x\n", data); return data; } @@ -807,7 +813,7 @@ uint8_t pit8253_device::read(offs_t offset) { offset &= 3; - LOG2(("read(): offset %d\n", offset)); + LOG2("read(): offset %d\n", offset); if (offset == 3) { @@ -824,7 +830,7 @@ uint8_t pit8253_device::read(offs_t offset) void pit_counter_device::load_count(uint16_t newcount) { int mode = CTRL_MODE(m_control); - LOG1(("load_count(): %04x\n", newcount)); + LOG1("load_count(): %04x\n", newcount); if (newcount == 1) { @@ -910,7 +916,7 @@ void pit8253_device::readback_command(uint8_t data) void pit8254_device::readback_command(uint8_t data) { - LOG1(("write(): readback %02x\n", data & 0x3f)); + LOG1("write(): readback %02x\n", data & 0x3f); /* Bit 0 of data must be 0. Todo: find out what the hardware does if it isn't. */ int read_command = (data >> 4) & 3; @@ -930,7 +936,7 @@ void pit_counter_device::control_w(uint8_t data) if (CTRL_ACCESS(data) == 0) { - LOG1(("write(): readback\n")); + LOG1("write(): readback\n"); /* Latch current timer value */ /* Experimentally verified: this command does not affect the mode control register */ @@ -938,7 +944,7 @@ void pit_counter_device::control_w(uint8_t data) } else { - LOG1(("write(): bytes=%d mode=%d bcd=%d\n", (data >> 4) & 3, (data >> 1) & 7, data & 1)); + LOG1("write(): bytes=%d mode=%d bcd=%d\n", (data >> 4) & 3, (data >> 1) & 7, data & 1); m_control = (data & 0x3f); m_null_count = 1; @@ -1021,7 +1027,7 @@ void pit8253_device::write(offs_t offset, uint8_t data) { offset &= 3; - LOG2(("write(): offset=%d data=0x%02x\n", offset, data)); + LOG2("write(): offset=%d data=0x%02x\n", offset, data); if (offset == 3) { @@ -1038,7 +1044,7 @@ void pit8253_device::write(offs_t offset, uint8_t data) void pit_counter_device::gate_w(int state) { - LOG2(("gate_w(): state=%d\n", state)); + LOG2("gate_w(): state=%d\n", state); if (state != m_gate) { @@ -1059,7 +1065,7 @@ void pit_counter_device::gate_w(int state) void pit_counter_device::set_clockin(double new_clockin) { - LOG2(("set_clockin(): clockin = %f\n", new_clockin)); + LOG2("set_clockin(): clockin = %f\n", new_clockin); update(); m_clockin = new_clockin; @@ -1069,7 +1075,7 @@ void pit_counter_device::set_clockin(double new_clockin) void pit_counter_device::set_clock_signal(int state) { - LOG2(("set_clock_signal(): state = %d\n", state)); + LOG2("set_clock_signal(): state = %d\n", state); /* Trigger on low to high transition */ if (!m_clock_signal && state) From dda15d1b6d4eacd17599508d9c3b4b5eb98fb7c3 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 14:06:08 +0200 Subject: [PATCH 05/12] eispc.cpp: Split out of the Ericsson PC (epc) from pc.cpp and added a serial keyboard --- scripts/target/mame/mess.lua | 8 + src/mame/drivers/eispc.cpp | 962 ++++++++++++++++++++++++++++++++++ src/mame/drivers/pc.cpp | 52 -- src/mame/machine/eispc_kb.cpp | 446 ++++++++++++++++ src/mame/machine/eispc_kb.h | 45 ++ src/mame/mame.lst | 4 +- src/mame/mess.flt | 1 + 7 files changed, 1465 insertions(+), 53 deletions(-) create mode 100644 src/mame/drivers/eispc.cpp create mode 100644 src/mame/machine/eispc_kb.cpp create mode 100644 src/mame/machine/eispc_kb.h diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index f60a7dc253e..5e30b516a2e 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1119,6 +1119,7 @@ function linkProjects_mame_mess(_target, _subtarget) "entex", "epoch", "epson", + "ericsson", "exidy", "fairch", "fairlight", @@ -2182,6 +2183,13 @@ files { MAME_DIR .. "src/mame/machine/qx10kbd.h", } +createMESSProjects(_target, _subtarget, "ericsson") +files { + MAME_DIR .. "src/mame/drivers/eispc.cpp", + MAME_DIR .. "src/mame/machine/eispc_kb.cpp", + MAME_DIR .. "src/mame/machine/eispc_kb.h", +} + createMESSProjects(_target, _subtarget, "exidy") files { MAME_DIR .. "src/mame/machine/sorcerer.cpp", diff --git a/src/mame/drivers/eispc.cpp b/src/mame/drivers/eispc.cpp new file mode 100644 index 00000000000..f8e051badc4 --- /dev/null +++ b/src/mame/drivers/eispc.cpp @@ -0,0 +1,962 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edström +/*************************************************************************************************** + * + * Ericsson Information Systems PC "compatibles" + * + * The Ericsson PC was the the first original Ericsson design for the office PC market replacing the + * Step/One which was an OEM:ed clone of the Matsushita Mybrain 3000 (see myb3k.cpp driver). + * + ************************************************************** + * Ericsson PC + *------------ + * Links: https://youtu.be/6uilOdMJc24 + * Form Factor: Desktop + * CPU: 8088 @ 4.77MHz + * RAM: 256K + * Bus: 6x ISA + * Video: Monchrome or Color 80x25 character mode. 320x200 and 640x400 grahics modes + * Display: Orange Gas Plasma (GP) display + * Mass storage: 2 x 5.25" 360K or 1 20Mb HDD + * On board ports: Beeper, + * Ports: serial, parallel + * Internal Options: Up to 640K RAM through add-on RAM card + * Misc: The hardware was not 100% PC compatible so non BIOS based software would not run. 50.000+ units sold + * + * TODO: + * - Add keyboard, first HLE as in pc.cpp and then LLE when the keyboard controller is dumped + * - Add the on-board FDC and boot DOS 1.xx + * - Complete the Ericsson 1070 MDA ISA board and test all the graphics modes inclusing 640x400 (aka HR) + * - Add the Ericsson 1065 HDC and boot from a hard drive + * + * Credits: The driver code is inspired from m24.cpp, myb3k.cpp and genpc.cpp. Information about the EPC has + * been contributed by many, mainly the people at Dalby Computer museum http://www.datormuseum.se/ + * A dead pcb was donated by rfka01 and rom dumps by ZnaxQue@sweclockers.com + * + ************************************************************************************************************/ +/* + Links: + ------ + + */ + +#include "emu.h" + +#include "machine/eispc_kb.h" + +// Devices +#include "cpu/i86/i86.h" +#include "machine/am9517a.h" +#include "machine/i8251.h" +#include "machine/i8255.h" +#include "machine/pit8253.h" +#include "machine/pic8259.h" +#include "machine/upd765.h" +#include "machine/ins8250.h" + +// Expansion cards +//#include "bus/isa/isa.h" +//#include "bus/isa/isa_cards.h" +#include "bus/isa/ega.h" +#include "bus/isa/mda.h" +#include "machine/pc_lpt.h" + +#include "machine/ram.h" +#include "machine/timer.h" +#include "sound/spkrdev.h" +#include "speaker.h" +#include "imagedev/floppy.h" +#include "formats/imd_dsk.h" +#include "formats/pc_dsk.h" +#include "bus/rs232/rs232.h" + +#define LOG_PPI (1U << 1) +#define LOG_PIT (1U << 2) +#define LOG_PIC (1U << 3) +#define LOG_KBD (1U << 4) +#define LOG_DMA (1U << 5) +#define LOG_IRQ (1U << 6) +#define LOG_FDC (1U << 7) +#define LOG_LPT (1U << 8) +#define LOG_NMI (1U << 9) +#define LOG_BITS (1U << 10) + +//#define VERBOSE (LOG_BITS|LOG_KBD|LOG_IRQ) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOGPPI(...) LOGMASKED(LOG_PPI, __VA_ARGS__) +#define LOGPIT(...) LOGMASKED(LOG_PIT, __VA_ARGS__) +#define LOGPIC(...) LOGMASKED(LOG_PIC, __VA_ARGS__) +#define LOGKBD(...) LOGMASKED(LOG_KBD, __VA_ARGS__) +#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__) +#define LOGIRQ(...) LOGMASKED(LOG_IRQ, __VA_ARGS__) +#define LOGFDC(...) LOGMASKED(LOG_FDC, __VA_ARGS__) +#define LOGLPT(...) LOGMASKED(LOG_LPT, __VA_ARGS__) +#define LOGNMI(...) LOGMASKED(LOG_NMI, __VA_ARGS__) +#define LOGBITS(...) LOGMASKED(LOG_BITS, __VA_ARGS__) + +class epc_state : public driver_device +{ +public: + epc_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_ram(*this, RAM_TAG) + , m_isabus(*this, "isabus") + , m_dma8237a(*this, "dma8237") + , m_ppi8255(*this, "ppi8255") + , m_io_dsw(*this, "DSW") + , m_io_j10(*this, "J10") + , m_lpt(*this, "lpt") + , m_kbd8251(*this, "kbd8251") + , m_keyboard(*this, "keyboard") + , m_pic8259(*this, "pic8259") + , m_pit8253(*this, "pit8253") + , m_speaker(*this, "speaker") + , m_fdc(*this, "fdc") + , m_floppy_connectors(*this, "fdc:%u", 0) + , m_uart(*this, "uart8250") + { } + + void epc(machine_config &config); + void init_epc(); + + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + required_device m_maincpu; + required_device m_ram; + required_device m_isabus; + + // DMA + DECLARE_WRITE_LINE_MEMBER(dma_tc_w); + DECLARE_WRITE_LINE_MEMBER(dreq0_ck_w); + DECLARE_WRITE_LINE_MEMBER( epc_dma_hrq_changed ); + DECLARE_WRITE_LINE_MEMBER( epc_dma8237_out_eop ); + DECLARE_READ8_MEMBER( epc_dma_read_byte ); + DECLARE_WRITE8_MEMBER( epc_dma_write_byte ); + template uint8_t epc_dma8237_io_r(offs_t offset); + template void epc_dma8237_io_w(offs_t offset, uint8_t data); + template DECLARE_WRITE_LINE_MEMBER(epc_dack_w); + required_device m_dma8237a; + uint8_t m_dma_segment[4]; + uint8_t m_dma_active; + bool m_tc; + bool m_txd; + bool m_rxrdy; + bool m_int; + bool m_dreq0_ck; + + // PPI + required_device m_ppi8255; + DECLARE_WRITE8_MEMBER(ppi_portb_w); + DECLARE_READ8_MEMBER(ppi_portc_r); + uint8_t m_ppi_portb; + required_ioport m_io_dsw; + required_ioport m_io_j10; + + // Printer port + optional_device m_lpt; + + // Keyboard Controller/USART + required_device m_kbd8251; + required_device m_keyboard; + emu_timer *m_kbdclk_timer; + TIMER_CALLBACK_MEMBER(rxtxclk_w); + int m_rxtx_clk_state; + + // Interrupt Controller + required_device m_pic8259; + DECLARE_WRITE_LINE_MEMBER(int_w); + uint8_t m_nmi_enabled; + uint8_t m_8087_int = 0; + const uint8_t m_parer_int = 0; + const uint8_t m_iochck_int = 0; + void update_nmi(); + + // Timer + required_device m_pit8253; + + // Speaker + DECLARE_WRITE_LINE_MEMBER(speaker_ck_w); + required_device m_speaker; + + void epc_map(address_map &map); + void epc_io(address_map &map); + + // FDC + void check_fdc_irq(); + void check_fdc_drq(); + required_device m_fdc; + uint8_t m_ocr; + bool m_irq; // System signal after glue logic + bool m_drq; // System signal after glue logic + bool m_fdc_irq; // FDC output pin + bool m_fdc_drq; // FDC output pin + + optional_device_array m_floppy_connectors; + DECLARE_FLOPPY_FORMATS( epc_floppy_formats ); + + // UART + required_device m_uart; +}; + +void epc_state::check_fdc_irq() +{ + bool pirq = m_irq; + m_irq = m_fdc_irq && (m_ocr & 4) && (m_ocr & 8); // IRQ enabled and not in reset? + if(m_irq != pirq) // has the state changed? + { + LOGIRQ("FDC: IRQ6 request: %d\n", m_irq); + m_pic8259->ir6_w(m_irq); + } +} + +void epc_state::check_fdc_drq() +{ + bool pdrq = m_drq; + m_drq = m_fdc_drq && (m_ocr & 4) && (m_ocr & 8); // DREQ enabled and not in reset? + if(m_drq != pdrq) // has the state changed? + { + LOGDMA("FDC: DMA channel 2 request: %d\n", m_drq); + m_dma8237a->dreq2_w(m_drq); + } +} + +void epc_state::epc_map(address_map &map) +{ + map.unmap_value_high(); + map(0x20000, 0x9ffff).noprw(); // Base RAM - mapped to avoid unmaped errors when BIOS is probing RAM size + // 0xa0000-0xaffff is reserved + map(0xb0000, 0xb7fff).noprw(); // Monochrome RAM - mapped to avoid unaped errors when BIOS is probing RAM size + map(0xb0000, 0xb7fff).noprw(); // Monochrome RAM - mapped to avoid unaped errors when BIOS is probing RAM size + map(0xb8000, 0xbffff).noprw(); // Color/Graphics RAM - mapped to avoid unaped errors when BIOS is probing RAM size + map(0xc0000, 0xeffff).noprw(); // Expansion ROM area - Hard Disk BIOS etc + map(0xf0000, 0xfffff).rom().region("bios", 0); +} + +void epc_state::epc_io(address_map &map) +{ + map(0x0000, 0x000f).mirror(0x10).lrw8("dma8237_rw", + [this](offs_t offset) -> uint8_t + { + uint8_t data = m_dma8237a->read(offset); + LOGDMA("dma8237_r %04x\n", offset); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGDMA("dma8237_w %04x: %02x\n", offset, data); + m_dma8237a->write(offset, data); + } + ); + + map(0x0020, 0x0021).mirror(0x1e).lrw8("pic8259_rw", + [this](offs_t offset) -> uint8_t + { + uint8_t data = m_pic8259->read(offset); + LOGPIC("pic8259_r %04x: %02x\n", offset, data); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGPIC("pic8259_w %04x: %02x\n", offset, data); + m_pic8259->write(offset, data); + } + ); + + map(0x0040, 0x0043).mirror(0x1c).lrw8("pit8253_rw", + [this](offs_t offset) -> uint8_t + { + uint8_t data = m_pit8253->read(offset); + LOGPIT("pit8253_r %04x\n", offset); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGPIT("pit8253_w %04x: %02x\n", offset, data); + m_pit8253->write(offset, data); + } + ); + + map(0x0060, 0x0060).mirror(0x1c).lrw8("kbd_8251_data_rw", + [this]() -> uint8_t + { + uint8_t data = m_kbd8251->data_r(); + LOGKBD("kbd8251_r %02x\n", data); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGKBD("kbd8251_w 0x60 %02x\n", data); + m_kbd8251->data_w(data); + } + ); + // NOTE: PPI Port A is not mapped + map(0x0061, 0x0061).mirror(0x1c).lrw8("ppi8255_rw", // PPI Port B + [this](offs_t offset) -> uint8_t + { + uint8_t data = m_ppi8255->read(1); + LOGPPI("ppi8255_r Port B: %02x\n", data); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGPPI("ppi8255_w Port B: %02x\n", data); + m_ppi8255->write(1, data); + } + ); + + map(0x0062, 0x0062).mirror(0x1c).lrw8("ppi8255_rw", // PPI Port C + [this](offs_t offset) -> uint8_t + { + uint8_t data = m_ppi8255->read(2); + LOGPPI("ppi8255_r Port C: %02x\n", data); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGPPI("ppi8255_w Port C: %02x\n", data); + m_ppi8255->write(2, data); + } + ); + + map(0x0063, 0x0063).lrw8("ppi8255_rw", // PPI Control register + [this](offs_t offset) -> uint8_t + { + uint8_t data = m_ppi8255->read(3); + LOGPPI("ppi8255_r Control: %02x\n", data); + return data; + }, + [this](offs_t offset, uint8_t data) + { + LOGPPI("ppi8255_w Control: %02x\n", data); + m_ppi8255->write(3, data); + } + ); + + map(0x0070, 0x0070).mirror(0x0e).lw8("i8251_data_w", + [this](offs_t offset, uint8_t data) + { + LOGKBD("kbd8251_w 0x70: %02x\n", data); + m_kbd8251->data_w(data); + } + ); + + map(0x0071, 0x0071).mirror(0x0e).lrw8("kbd_8251_stat_ctrl_rw", + [this](offs_t offset) -> uint8_t + { + uint8_t stat = m_kbd8251->status_r(); + //LOGKBD("kbd8251_status_r %02x\n", stat); + return stat; + }, + [this](offs_t offset, uint8_t data) + { + LOGKBD("kbd8251_control_w 0x71: %02x\n", data); + m_kbd8251->control_w(data); + } + ); + + map(0x0080, 0x0083).mirror(0xc).lw8("dma_segement_w", + [this](offs_t offset, uint8_t data) + { + LOGDMA("dma_segment_w %04x: %02x\n", offset, data); + m_dma_segment[offset] = data & 0x0f; + } + ); + + map(0x00a0, 0x00a1).mirror(0xe).lw8("nmi_enable_w", + [this](offs_t offset, uint8_t data) + { + LOGNMI("nmi_enable_w %04x: %02x\n", offset, data); + m_nmi_enabled = BIT(data,7); + update_nmi(); + } + ); + + // FDC Output Control Register (same as PC XT DOR) + map(0x03f2, 0x03f3).lw8("ocr_w", // B0-B1 Drive select 0-3 + [this](offs_t offset, uint8_t data) // B2 FDC Reset line + { // B3 Enable FDC DMA/IRQ + LOGFDC("FDC OCR: %02x\n", data);// B4-B7 Motor on for selected drive + uint8_t pocr = m_ocr; + uint8_t fid = m_ocr & 3; + m_ocr = data; + if ((m_ocr & 4) && m_floppy_connectors[fid]) // Not in reset and there is a floppy drive attached + { + floppy_image_device *floppy = m_floppy_connectors[fid]->get_device(); // try to retrieve the floppy + if (floppy) + { + LOGFDC(" - Motor %s for drive %d\n", (m_ocr & (0x10 << fid)) ? "ON" : "OFF", fid); + floppy->mon_w(!(m_ocr & (0x10 << fid))); + LOGFDC(" - Setting a floppy for drive %d\n", fid); + m_fdc->set_floppy((m_ocr & (0x10 << fid)) ? floppy : nullptr); + } + } + if (((pocr ^ m_ocr) & 4) && (m_ocr & 4) == 0) // If FDC reset state bit has changed to low then reset the FDC + m_fdc->reset(); + check_fdc_irq(); + check_fdc_drq(); + } + ); + + map(0x03f4, 0x03f5).m(m_fdc, FUNC(i8272a_device::map)); + + map(0x03bc, 0x03be).lrw8("lpt_rw", + [this](address_space &space, offs_t offset, uint8_t mem_mask) -> uint8_t + { + uint8_t data = m_lpt->read(space, offset); + LOGLPT("LPT read offset %02x: %02x\n", offset, data); + return data; + }, + [this](address_space &space, offs_t offset, uint8_t data) + { + LOGLPT("LPT write offset %02x: %02x\n", offset, data); + m_lpt->write(space, offset, data); + } + ); + + map(0x03f8, 0x03ff).rw(m_uart, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w)); +} + +void epc_state::machine_start() +{ + m_maincpu->space(AS_PROGRAM).install_ram(0, m_ram->size() - 1, m_ram->pointer()); + + std::fill_n(&m_dma_segment[0], 4, 0); + m_dma_active = 0; + m_tc = false; + m_int = 1; + m_txd = false; + m_rxrdy = false; + m_dreq0_ck = true; + m_rxtx_clk_state = 0; + + save_item(NAME(m_dma_segment)); + save_item(NAME(m_dma_active)); + save_item(NAME(m_tc)); + save_item(NAME(m_int)); + save_item(NAME(m_txd)); + save_item(NAME(m_rxrdy)); + save_item(NAME(m_ocr)); + m_ocr = 0x00; + save_item(NAME(m_ppi_portb)); + save_item(NAME(m_dreq0_ck)); + save_item(NAME(m_rxtx_clk_state)); +} + +void epc_state::machine_reset() +{ + m_ppi_portb = 0; + m_keyboard->rst_line_w(ASSERT_LINE); + m_nmi_enabled = 0; + m_kbd8251->write_cts(0); // Held low always +} + +void epc_state::init_epc() +{ + /* Keyboard UART Rxc/Txc is 19.2 kHz from x96 divider */ + m_kbdclk_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(epc_state::rxtxclk_w), this)); + m_kbdclk_timer->adjust(attotime::from_hz((XTAL(18'432'000) / 96) / 5)); +} + +TIMER_CALLBACK_MEMBER(epc_state::rxtxclk_w) +{ + m_kbd8251->write_rxc(m_rxtx_clk_state); + m_kbd8251->write_txc(m_rxtx_clk_state); + m_rxtx_clk_state ^= 0x01; + m_kbdclk_timer->adjust(attotime::from_hz((XTAL(18'432'000) / 96) / 5)); +} + + +template +uint8_t epc_state::epc_dma8237_io_r(offs_t offset) +{ + LOGDMA("epc_dma8237_io_r: %d\n", Channel); + if (Channel == 2) + return m_fdc->dma_r(); + else + return m_isabus->dack_r(Channel); +} + +template +void epc_state::epc_dma8237_io_w(offs_t offset, uint8_t data) +{ + LOGDMA("epc_dma8237_io_w: %d - %02x\n", Channel, data); + if (Channel == 2) + m_fdc->dma_w(data); + else + m_isabus->dack_w(Channel, data); +} + +template +WRITE_LINE_MEMBER(epc_state::epc_dack_w) +{ + LOGDMA("epc_dack_w: %d - %d\n", Channel, state); + + m_isabus->dack_line_w(Channel, state); + + if (!state) + { + m_dma_active |= 1 << Channel; + if (Channel == 0) + m_dma8237a->dreq0_w(0); + if (m_tc) + m_isabus->eop_w(Channel, ASSERT_LINE); + } + else + { + m_dma_active &= ~(1 << Channel); + if (m_tc) + m_isabus->eop_w(Channel, CLEAR_LINE); + } +} + +WRITE_LINE_MEMBER(epc_state::dma_tc_w) +{ + m_tc = (state == ASSERT_LINE); + for (int channel = 0; channel < 4; channel++) + { + if (BIT(m_dma_active, channel)) + { + LOGDMA("dma_tc_w ch %d: %d\n", channel, state); + m_isabus->eop_w(channel, state); + } + } + + // Special treatment for on board FDC + if (BIT(m_dma_active, 2)) + { + m_fdc->tc_w(0); + } + else + { + m_fdc->tc_w(1); + } +} + +WRITE_LINE_MEMBER(epc_state::dreq0_ck_w) +{ + if (state && !m_dreq0_ck && !BIT(m_dma_active, 0)) + m_dma8237a->dreq0_w(1); + + m_dreq0_ck = state; +} + +WRITE_LINE_MEMBER(epc_state::speaker_ck_w) +{ + m_speaker->level_w((m_ppi_portb & 0x02) && state ? 1 : 0); +} + +/********************************************************** + * + * PPI8255 interface + * + * + * PORT A (not used) + * + * Reads of port A is shadowed by UART8251A's read register + * gaining some compatibility with PC software. The UART8251 + * communicates with the serial keyboard and extends it with + * write capability enabling keyboard led control as with a + * PC AT keyboard. + * + * PORT B (output) + * 0 - PB0 - - Control signal for the sound generator (short beeps) + * 1 - PB1 - - Control signal for the sound generator + * 2 - PB2 - - Unused + * 3 - PB3 - - Data select for the configuration switches 0=SW1-4 1=SW5-8 + * 4 - PB4 - * - Enable ram parity check + * 5 - PB5 - * - Enable expansion I/O check + * 6 - PB6 - * - Keyboard reset + * 7 - PB7 - - Reset keyboard interrupt + * + * PORT C + * 0 - PC0 - - Dipswitch SW 1/5 PB3=0/PB3=1 + * 1 - PC1 - - Dipswitch SW 2/6 PB3=0/PB3=1 + * 2 - PC2 - - Dipswitch SW 3/7 PB3=0/PB3=1 + * 3 - PC3 - - Dipswitch SW 4/8 PB3=0/PB3=1 + * 4 - PC4 - SPK - Speaker/cassette data (spare in PC XT spec) + * 5 - PC5 - OUT2 - OUT2 from 8253 (ibmpcjr compatible) + * 6 - PC6 - + * 7 - PC7 - + * + * Ericsson PC SW: + * 1 - Not used. Must be set to OFF + * 2 - OFF - 8087 present + * ON - No 8087 present *) + * 3 - Not Used. Don't care but OFF *) + * 4 - Not Used. Must be set to ON + * 5+6 - Used to select display + * OFF OFF - Monochrome HR graphics monitor 3111 installed + 1020 color secondary monitor + * ON OFF - Monochrome HR graphics monitor 3111 installed + optional 1020 color main monitor *) + * OFF ON - Not used + * ON ON - Not used + * 7+8 - Used to select number of disk drives + * OFF OFF - Not used + * ON OFF - Not used + * OFF ON - two disk drives, system units 1030-1 and 1030-2 + * ON ON - one disk drive, system units 1030-3, 1030-4, 1031-1 and 1031-2 + * + * *) - Factory settings + * + **********************************************************/ + +READ8_MEMBER( epc_state::ppi_portc_r ) +{ + uint8_t data; + + // Read 4 configurations dip switches depending on PB3 + data = (m_io_dsw->read() >> ((m_ppi_portb & 0x08) ? 4 : 0) & 0x0f); + + // TODO: verify what PC4-PC7 is used for, if anything + + LOGPPI("PPI Port C read: %02x\n", data); + + return data; +} + +WRITE8_MEMBER( epc_state::ppi_portb_w ) +{ + LOGPPI("PPI Port B write: %02x\n", data); + LOGPPI(" PB0 - Enable beeper : %d\n", (data & 0x01) ? 1 : 0); + LOGPPI(" PB1 - Beeper data : %d\n", (data & 0x02) ? 1 : 0); + LOGPPI(" PB2 - Unused : %d\n", (data & 0x04) ? 1 : 0); + LOGPPI(" PB3 - Port C dip switch select : %d\n", (data & 0x08) ? 1 : 0); + LOGPPI(" PB4 - RAM parity enable : %d\n", (data & 0x10) ? 1 : 0); + LOGPPI(" PB5 - ISA error checking enable : %d\n", (data & 0x20) ? 1 : 0); + LOGPPI(" PB6 - Reset keyboard : %d\n", (data & 0x40) ? 1 : 0); + LOGPPI(" PB7 - Reset keyboard interrupt : %d\n", (data & 0x80) ? 1 : 0); + + uint8_t changed = m_ppi_portb ^ data; + + m_ppi_portb = data; + + if (changed & 0x40) + { + if (m_ppi_portb & 0x40) + { + LOGKBD("PB6 set, clearing Keyboard RESET\n"); + m_keyboard->rst_line_w(CLEAR_LINE); + } + else + { + LOGKBD("PB6 cleared, asserting Keyboard RESET\n"); + m_keyboard->rst_line_w(ASSERT_LINE); + } + } + + if (changed & m_ppi_portb & 0x80) + { + LOGIRQ("PB7 set, clearing IRQ1 and releasing HOLD\n"); + m_pic8259->ir1_w(CLEAR_LINE); + m_keyboard->hold_w(ASSERT_LINE); + } +} + +WRITE_LINE_MEMBER(epc_state::int_w) +{ + if (m_int != state) + { + LOGIRQ("int_w: %d\n", state); + m_int = state; + m_maincpu->set_input_line(0, m_int); + } +} + +static void epc_isa8_cards(device_slot_interface &device) +{ + device.option_add("epc_mda", ISA8_EPC_MDA); + device.option_add("ega", ISA8_EGA); + // device.option_add("epc_hdc1065", ISA8_EPC_HDC1065); + // device.option_add("epc_mb1080", ISA8_EPC_MB1080); +} + +FLOPPY_FORMATS_MEMBER( epc_state::epc_floppy_formats ) + FLOPPY_PC_FORMAT, + FLOPPY_IMD_FORMAT +FLOPPY_FORMATS_END + +static void epc_sd_floppies(device_slot_interface &device) +{ + device.option_add("525sd", FLOPPY_525_SD); +} + +void epc_state::epc(machine_config &config) +{ + I8088(config, m_maincpu, XTAL(14'318'181) / 3.0); // TWE crystal marked X1 verified divided through a 82874 + m_maincpu->set_addrmap(AS_PROGRAM, &epc_state::epc_map); + m_maincpu->set_addrmap(AS_IO, &epc_state::epc_io); + m_maincpu->set_irq_acknowledge_callback("pic8259", FUNC(pic8259_device::inta_cb)); + + // DMA + AM9517A(config, m_dma8237a, XTAL(14'318'181) / 3.0); // TWE crystal marked X1 verified + m_dma8237a->out_hreq_callback().set(FUNC(epc_state::epc_dma_hrq_changed)); + m_dma8237a->out_eop_callback().set(FUNC(epc_state::dma_tc_w)); + m_dma8237a->in_memr_callback().set(FUNC(epc_state::epc_dma_read_byte)); + m_dma8237a->out_memw_callback().set(FUNC(epc_state::epc_dma_write_byte)); + m_dma8237a->in_ior_callback<1>().set(FUNC(epc_state::epc_dma8237_io_r<1>)); + m_dma8237a->in_ior_callback<2>().set(FUNC(epc_state::epc_dma8237_io_r<2>)); + m_dma8237a->in_ior_callback<3>().set(FUNC(epc_state::epc_dma8237_io_r<3>)); + m_dma8237a->out_iow_callback<0>().set(FUNC(epc_state::epc_dma8237_io_w<0>)); + m_dma8237a->out_iow_callback<1>().set(FUNC(epc_state::epc_dma8237_io_w<1>)); + m_dma8237a->out_iow_callback<2>().set(FUNC(epc_state::epc_dma8237_io_w<2>)); + m_dma8237a->out_iow_callback<3>().set(FUNC(epc_state::epc_dma8237_io_w<3>)); + m_dma8237a->out_dack_callback<0>().set(FUNC(epc_state::epc_dack_w<0>)); + m_dma8237a->out_dack_callback<1>().set(FUNC(epc_state::epc_dack_w<1>)); + m_dma8237a->out_dack_callback<2>().set(FUNC(epc_state::epc_dack_w<2>)); + m_dma8237a->out_dack_callback<3>().set(FUNC(epc_state::epc_dack_w<3>)); + + // TTL-level serial keyboard callback + EISPC_KB(config, "keyboard").txd_cb().set([this](bool state) + { + LOGBITS("KBD->EPC: %d\n", state); + m_kbd8251->write_rxd(state); + }); + + // Keyboard USART + I8251( config, m_kbd8251, XTAL(14'318'181) / 6.0 ); // TWE crystal marked X1 verified divided through a 82874 + + m_kbd8251->txd_handler().set([this](bool state) + { + if (m_txd != state) + { + LOGBITS("EPC->KBD: %d\n", state); + m_txd = state; + m_keyboard->rxd_w(m_txd); + } + }); + + m_kbd8251->rxrdy_handler().set([this](bool state) + { + m_rxrdy = state; + LOGKBD("KBD RxRdy: %d HOLD: %d\n", m_rxrdy ? 1 : 0, m_rxrdy ? 0 : 1); + m_keyboard->hold_w(!m_rxrdy); + if (m_rxrdy) + { + LOGIRQ("RxRdy set, asserting IRQ1\n"); + m_pic8259->ir1_w(ASSERT_LINE); // Cleared by setting PB7 + } + }); + m_kbd8251->dtr_handler().set([this](bool state) // Controls RCLK for INS8250, either 19.2KHz or INS8250 BAUDOUT + { + LOGKBD("KBD DTR: %d\n", state ? 1 : 0); // TODO: Implement clock selection mux, need to check what state does what + }); + + // Interrupt Controller + PIC8259(config, m_pic8259); + m_pic8259->out_int_callback().set(FUNC(epc_state::int_w)); + + // Parallel port + I8255A(config, m_ppi8255); + m_ppi8255->out_pa_callback().set([this] (uint8_t data) { LOGPPI("PPI: write %02x to unused Port A\n", data); } ); // Port A is not used + m_ppi8255->out_pb_callback().set(FUNC(epc_state::ppi_portb_w)); + m_ppi8255->in_pc_callback().set(FUNC(epc_state::ppi_portc_r)); + + // system board Parallel port + PC_LPT(config, m_lpt); + m_lpt->irq_handler().set([this](int state) + { // Jumper field J10 decides what IRQ to pull + if ((m_io_j10->read() & 0x03) == 0x01) { LOGIRQ("LPT IRQ2: %d\n", state); m_pic8259->ir2_w(state); } + if ((m_io_j10->read() & 0x0c) == 0x04) { LOGIRQ("LPT IRQ3: %d\n", state); m_pic8259->ir3_w(state); } + if ((m_io_j10->read() & 0x30) == 0x10) { LOGIRQ("LPT IRQ4: %d\n", state); m_pic8259->ir4_w(state); } + if ((m_io_j10->read() & 0xc0) == 0x40) { LOGIRQ("LPT IRQ7: %d\n", state); m_pic8259->ir7_w(state); } // Factory setting + }); + + // Timer + PIT8253(config, m_pit8253); + m_pit8253->set_clk<0>((XTAL(14'318'181) / 3.0) / 2.0 ); + m_pit8253->set_clk<1>((XTAL(14'318'181) / 3.0) / 2.0 ); + m_pit8253->set_clk<2>((XTAL(14'318'181) / 3.0) / 2.0 ); + m_pit8253->out_handler<0>().set(m_pic8259, FUNC(pic8259_device::ir0_w)); + m_pit8253->out_handler<1>().set(FUNC(epc_state::dreq0_ck_w)); + m_pit8253->out_handler<2>().set(FUNC(epc_state::speaker_ck_w)); + + // Speaker + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 1.00); + + // ISA bus + ISA8(config, m_isabus, XTAL(14'318'181) / 3.0); // TEW crystal marked X1 verified + m_isabus->set_memspace(m_maincpu, AS_PROGRAM); + m_isabus->set_iospace(m_maincpu, AS_IO); + //m_isabus->irq2_callback().set(m_pic8259, FUNC(pic8259_device::ir2_w)); // Reserved in service manual + m_isabus->irq3_callback().set(m_pic8259, FUNC(pic8259_device::ir3_w)); + m_isabus->irq4_callback().set(m_pic8259, FUNC(pic8259_device::ir4_w)); + m_isabus->irq5_callback().set(m_pic8259, FUNC(pic8259_device::ir5_w)); + m_isabus->irq6_callback().set(m_pic8259, FUNC(pic8259_device::ir6_w)); + m_isabus->irq7_callback().set(m_pic8259, FUNC(pic8259_device::ir7_w)); + m_isabus->drq1_callback().set(m_dma8237a, FUNC(am9517a_device::dreq1_w)); + m_isabus->drq2_callback().set(m_dma8237a, FUNC(am9517a_device::dreq2_w)); + m_isabus->drq3_callback().set(m_dma8237a, FUNC(am9517a_device::dreq3_w)); + //m_isabus->iochck_callback().set(FUNC(epc_state::chck_w)); // TODO: Check schematics + m_isabus->iochck_callback().set([this] (int state) + { + if (m_nmi_enabled && !state && 0) + { + LOGNMI("IOCHCK: NMI Requested\n"); + update_nmi(); + } + }); + + ISA8_SLOT(config, "isa1", 0, m_isabus, epc_isa8_cards, "epc_mda", false); + ISA8_SLOT(config, "isa2", 0, m_isabus, epc_isa8_cards, nullptr, false); + ISA8_SLOT(config, "isa3", 0, m_isabus, epc_isa8_cards, nullptr, false); + ISA8_SLOT(config, "isa4", 0, m_isabus, epc_isa8_cards, nullptr, false); + ISA8_SLOT(config, "isa5", 0, m_isabus, epc_isa8_cards, nullptr, false); + ISA8_SLOT(config, "isa6", 0, m_isabus, epc_isa8_cards, nullptr, false); + + // System board has 128kB memory with parity, expansion can be achieved through the + // 128kB Memory Expansion Board 1090 and/or the 128kB Multifunction Board MB1080-001 + // and/or the 384kB MB1080-002. The MB1080 DRAM might need to be dynamically added as + // base address and also a video memory hole is configuarable. + RAM(config, m_ram).set_default_size("128K").set_extra_options("256K, 384K, 512K, 640K"); + + // FDC + I8272A(config, m_fdc, XTAL(16'000'000) / 2, false); // TEW crystal marked X3 verified + m_fdc->intrq_wr_callback().set([this] (int state){ m_fdc_irq = state; check_fdc_irq(); }); + m_fdc->drq_wr_callback().set([this] (int state){ m_fdc_drq = state; check_fdc_drq(); }); + FLOPPY_CONNECTOR(config, m_floppy_connectors[0], epc_sd_floppies, "525sd", epc_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy_connectors[1], epc_sd_floppies, "525sd", epc_floppy_formats); + //SOFTWARE_LIST(config, "epc_flop_list").set_original("epc_flop"); + + // system board UART + INS8250(config, m_uart, XTAL(18'432'000) / 10); // TEW crystal marked X2 verified. TODO: Let 8051 DTR control RCLK (see above) + m_uart->out_tx_callback().set("uart", FUNC(rs232_port_device::write_txd)); + m_uart->out_dtr_callback().set("uart", FUNC(rs232_port_device::write_dtr)); + m_uart->out_rts_callback().set("uart", FUNC(rs232_port_device::write_rts)); + m_uart->out_int_callback().set([this](int state) + { // Jumper field J10 decides what IRQ to pull + if ((m_io_j10->read() & 0x03) == 0x02) { LOGIRQ("UART IRQ2: %d\n", state); m_pic8259->ir2_w(state); } + if ((m_io_j10->read() & 0x0c) == 0x08) { LOGIRQ("UART IRQ3: %d\n", state); m_pic8259->ir3_w(state); } + if ((m_io_j10->read() & 0x30) == 0x20) { LOGIRQ("UART IRQ4: %d\n", state); m_pic8259->ir4_w(state); } // Factory setting + if ((m_io_j10->read() & 0xc0) == 0x80) { LOGIRQ("UART IRQ7: %d\n", state); m_pic8259->ir7_w(state); } + }); + + rs232_port_device &rs232(RS232_PORT(config, "uart", default_rs232_devices, nullptr)); + rs232.rxd_handler().set(m_uart, FUNC(ins8250_uart_device::rx_w)); + rs232.dcd_handler().set(m_uart, FUNC(ins8250_uart_device::dcd_w)); + rs232.dsr_handler().set(m_uart, FUNC(ins8250_uart_device::dsr_w)); + rs232.ri_handler().set(m_uart, FUNC(ins8250_uart_device::ri_w)); + rs232.cts_handler().set(m_uart, FUNC(ins8250_uart_device::cts_w)); + + + +} + +void epc_state::update_nmi() +{ + if (m_nmi_enabled && + ((m_8087_int && (m_io_dsw->read() & 0x02)) || // FPU int only if FPU is enabled by DSW2 + (m_parer_int != 0) || // Parity error is always false as it is an emulator, at least for now + (m_iochck_int != 0))) // Same goes for ISA board errors + { + LOGNMI(" NMI asserted\n"); + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + } + else + { + LOGNMI(" NMI Cleared\n"); + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); + } +} + +WRITE_LINE_MEMBER( epc_state::epc_dma_hrq_changed ) +{ + LOGDMA("epc_dma_hrq_changed %d\n", state); + + m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); + + /* Assert HLDA */ + m_dma8237a->hack_w(state); +} + + +READ8_MEMBER( epc_state::epc_dma_read_byte ) +{ + if ((m_dma_active & 0x0f) == 0) + { + LOGDMA("epc_dma_read_byte failed\n"); + return 0xff; + } + + const int seg = (BIT(m_dma_active, 2) ? 0 : 2) | (BIT(m_dma_active, 3) ? 0 : 1); + return m_maincpu->space(AS_PROGRAM).read_byte(offset | u32(m_dma_segment[seg]) << 16); +} + +WRITE8_MEMBER( epc_state::epc_dma_write_byte ) +{ + if ((m_dma_active & 0x0f) == 0) + { + LOGDMA("epc_dma_write_byte failed\n"); + return; + } + + const int seg = (BIT(m_dma_active, 2) ? 0 : 2) | (BIT(m_dma_active, 3) ? 0 : 1); + m_maincpu->space(AS_PROGRAM).write_byte(offset | u32(m_dma_segment[seg]) << 16, data); +} + + +static INPUT_PORTS_START( epc_ports ) + PORT_START("DSW") + PORT_DIPNAME( 0x01, 0x01, "Not used") + PORT_DIPSETTING( 0x00, "ON - Don't use") + PORT_DIPSETTING( 0x01, "OFF - Factory Setting") + PORT_DIPNAME( 0x02, 0x00, "8087 installed") + PORT_DIPSETTING( 0x00, DEF_STR(No) ) + PORT_DIPSETTING( 0x02, DEF_STR(Yes) ) + PORT_DIPNAME( 0x04, 0x04, "Not used") + PORT_DIPSETTING( 0x00, "ON - Don't care") + PORT_DIPSETTING( 0x04, "OFF - Factory Setting") + PORT_DIPNAME( 0x08, 0x00, "Not used") + PORT_DIPSETTING( 0x00, "ON - Factory Setting") + PORT_DIPSETTING( 0x08, "OFF - Don't use") + PORT_DIPNAME( 0x30, 0x30, "Main monitor") + PORT_DIPSETTING( 0x00, "Not used" ) + PORT_DIPSETTING( 0x10, "Optional 1020 color" ) + PORT_DIPSETTING( 0x20, "Not used" ) + PORT_DIPSETTING( 0x30, "3111 HR Monochrome" ) + PORT_DIPNAME( 0xc0, 0x40, "Number of floppy drives") + PORT_DIPSETTING( 0x00, "1" ) + PORT_DIPSETTING( 0x40, "2" ) + PORT_DIPSETTING( 0x80, "Not used" ) + PORT_DIPSETTING( 0xc0, "Not used" ) + + PORT_START("J10") // Jumper area, field 0=no jumper 1=LPT 2=COM 3=n/a + PORT_DIPNAME(0x03, 0x00, "IRQ2") + PORT_DIPSETTING(0x00, "no jumper") + PORT_DIPSETTING(0x01, "LPT") + PORT_DIPSETTING(0x02, "COM") + PORT_DIPNAME(0x0c, 0x00, "IRQ3") + PORT_DIPSETTING(0x00, "no jumper") + PORT_DIPSETTING(0x04, "LPT") + PORT_DIPSETTING(0x08, "COM") + PORT_DIPNAME(0x30, 0x20, "IRQ4") + PORT_DIPSETTING(0x00, "no jumper") + PORT_DIPSETTING(0x10, "LPT") + PORT_DIPSETTING(0x20, "COM") + PORT_DIPNAME(0xc0, 0x40, "IRQ7") + PORT_DIPSETTING(0x00, "no jumper") + PORT_DIPSETTING(0x40, "LPT") + PORT_DIPSETTING(0x80, "COM") +INPUT_PORTS_END + +ROM_START( epc ) + ROM_REGION(0x10000,"bios", 0) + ROM_DEFAULT_BIOS("p860110") + ROM_SYSTEM_BIOS(0, "p840705", "P840705") + ROMX_LOAD("ericsson_8088.bin", 0xe000, 0x2000, CRC(3953c38d) SHA1(2bfc1f1d11d0da5664c3114994fc7aa3d6dd010d), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "p860110", "P860110") + ROMX_LOAD("epcbios1.bin", 0xe000, 0x02000, CRC(79a83706) SHA1(33528c46a24d7f65ef5a860fbed05afcf797fc55), ROM_BIOS(1)) + ROMX_LOAD("epcbios2.bin", 0xa000, 0x02000, CRC(3ca764ca) SHA1(02232fedef22d31a641f4b65933b9e269afce19e), ROM_BIOS(1)) + ROMX_LOAD("epcbios3.bin", 0xc000, 0x02000, CRC(70483280) SHA1(b44b09da94d77b0269fc48f07d130b2d74c4bb8f), ROM_BIOS(1)) +ROM_END + + +COMP( 1985, epc, 0, 0, epc, epc_ports, epc_state, init_epc, "Ericsson Information System", "Ericsson PC" , MACHINE_NOT_WORKING ) +//COMP( 1985, eppc, ibm5150, 0, pccga, pccga, pc_state, empty_init, "Ericsson Information System", "Ericsson Portable PC", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/pc.cpp b/src/mame/drivers/pc.cpp index 5402f35320a..0461f45a095 100644 --- a/src/mame/drivers/pc.cpp +++ b/src/mame/drivers/pc.cpp @@ -46,7 +46,6 @@ public: void ncrpc4i(machine_config &config); void kaypro16(machine_config &config); void kaypropc(machine_config &config); - void epc(machine_config &config); void m15(machine_config &config); void bondwell(machine_config &config); void siemens(machine_config &config); @@ -86,7 +85,6 @@ private: static void cfg_single_360K(device_t *device); static void cfg_single_720K(device_t *device); - void epc_io(address_map &map); void ibm5550_io(address_map &map); void pc16_io(address_map &map); void pc16_map(address_map &map); @@ -533,55 +531,6 @@ ROM_START( mc1702 ) ROM_END -/************************************************************** Ericsson PC *** - -Links: https://youtu.be/6uilOdMJc24 -Form Factor: Desktop -CPU: 8088 @ 4.77MHz -RAM: 256K -Bus: 6x ISA -Video: Monchrome or Color 80x25 character mode. 320x200 and 640x400 (CGA?) grahics modes -Display: Orange Gas Plasma (GP) display -Mass storage: 2 x 5.25" 360K or 1 20Mb HDD -On board ports: Beeper, -Ports: serial, parallel -Internal Options: Up to 640K RAM through add-on RAM card -Misc: The hardware was not 100% PC compatible so non BIOS based software would not run. 50.000+ units sold - -******************************************************************************/ - -void pc_state::epc_io(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x00ff).m("mb", FUNC(ibm5160_mb_device::map)); - map(0x0070, 0x0071).rw("i8251", FUNC(i8251_device::read), FUNC(i8251_device::write)); -} - -void pc_state::epc(machine_config &config) -{ - pccga(config); - - i8088_cpu_device &maincpu(I8088(config.replace(), "maincpu", 4772720)); - maincpu.set_addrmap(AS_PROGRAM, &pc_state::pc8_map); - maincpu.set_addrmap(AS_IO, &pc_state::epc_io); - maincpu.set_irq_acknowledge_callback("mb:pic8259", FUNC(pic8259_device::inta_cb)); - - subdevice("isa1")->set_default_option("ega"); - I8251(config, "i8251", 0); // clock? -} - -ROM_START( epc ) - ROM_REGION(0x10000,"bios", 0) - ROM_DEFAULT_BIOS("p860110") - ROM_SYSTEM_BIOS(0, "p840705", "P840705") - ROMX_LOAD("ericsson_8088.bin", 0xe000, 0x2000, CRC(3953c38d) SHA1(2bfc1f1d11d0da5664c3114994fc7aa3d6dd010d), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "p860110", "P860110") - ROMX_LOAD("epcbios1.bin", 0xe000, 0x02000, CRC(79a83706) SHA1(33528c46a24d7f65ef5a860fbed05afcf797fc55), ROM_BIOS(1)) - ROMX_LOAD("epcbios2.bin", 0xa000, 0x02000, CRC(3ca764ca) SHA1(02232fedef22d31a641f4b65933b9e269afce19e), ROM_BIOS(1)) - ROMX_LOAD("epcbios3.bin", 0xc000, 0x02000, CRC(70483280) SHA1(b44b09da94d77b0269fc48f07d130b2d74c4bb8f), ROM_BIOS(1)) -ROM_END - - /************************************************ Ericsson Portable PC - EPPC *** Links: https://youtu.be/Qmke4L4Jls8 , https://youtu.be/yXK01gBQE6Q @@ -1358,7 +1307,6 @@ ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS COMP( 1984, dgone, ibm5150, 0, dgone, pccga, pc_state, empty_init, "Data General", "Data General/One" , MACHINE_NOT_WORKING ) -COMP( 1985, epc, ibm5150, 0, epc, pccga, pc_state, empty_init, "Ericsson Information System", "Ericsson PC" , MACHINE_NOT_WORKING ) COMP( 1985, eppc, ibm5150, 0, pccga, pccga, pc_state, empty_init, "Ericsson Information System", "Ericsson Portable PC", MACHINE_NOT_WORKING ) COMP( 1985, bw230, ibm5150, 0, bondwell, bondwell, pc_state, init_bondwell, "Bondwell Holding", "BW230 (PRO28 Series)", 0 ) COMP( 1992, iskr3104, ibm5150, 0, iskr3104, pccga, pc_state, empty_init, "Schetmash", "Iskra 3104", MACHINE_NOT_WORKING ) diff --git a/src/mame/machine/eispc_kb.cpp b/src/mame/machine/eispc_kb.cpp new file mode 100644 index 00000000000..cac16464e82 --- /dev/null +++ b/src/mame/machine/eispc_kb.cpp @@ -0,0 +1,446 @@ +// license:BSD-3-Clause +// copyright-holders: Joakim Larsson Edström +/********************************************************************** + + Ericsson PC keyboard emulation + + TTL-level bi-directional serial matrix keyboard + + The mc6801 contains an internal ROM that handles scanning of the keyboard, + controlling the 2 or 3 LEDs and also the programming of the scan code for + a single programmable key. + + There are two known variants of the keyboard. The first had the Ericsson + internal name "Sgt Pepper" where the hardware was OEMed/manufactured by + FACIT and had two LEDs while the second variant called "Roger Moore" had + three LEDs and was manufactured by Ericsson. + + Both keyboard hooks up directly to the port of a 6801 MCU. There are + 16 column lines driven by Port 3 and Port 4 that goes low one at a time + during the scan process and when a key is pressed one of the six corresponding + row lines goes low and fed to through a 74HC04 inverter into port 1, where a + high bit means a key was pressed. + + The connector has TX/Hold, Rx and Reset. Reset is connected directly to the + MCU so the host CPU can keep it in RESET until it needs the keyboard. + Rx is connected to the RX line of the SCI in the MCU, P23 - bit 3 of port 2. + Tx/Hold is bidirectional, connected to the TX line of the SCI in the MCU, P24 + bit 4 of port 2, but can also be kept low by the host CPU to temporarily inhibit + the keyboard from sending more scan codes. This is sensed by P16 through a + 74HC04 inverter. + + The data is exchanged in both direction asynchronously at 1200 baud, 8 databits, + 1 start and 1 stop bit. At startup the host CPU sends a $00 (zero) byte to the + keyboard simultaneously with the MCU sending a $A5 to the CPU to ensure full + duplex operation. If the $A5 byte is not received EPC will display a "Keyboard + Error" message on the screen. + + P17 and P20 are connected to LEDs on Caps Lock and Num Lock keys. The latter + keyboard variant Roger Moore also had a LED on Scroll Lock connected to P22. + P20, P21 and P22 are pulled high to bring the MCU into MODE 7 at RESET. NMI + and IRQ are pulled high and not connected to anything externally. + + +--+--+--+--+--+-6x10K--o +5v + +-------+ | | | | | | + | P30|<------x--x--x--x--x--x--- COLUMNS x = 1N4448 diod towards P3/P4 + | P31|<------x--x--x--x--x--x--- x 16 in serie with key button + | P32|<------x--x--x--x--x--x--- + | P33|<------x--x--x--x--x--x--- A pressed button pulls a P1 row + | P34|<------x--x--x--x--x--x--- low when its P3/P4 column is + | P35|<------x--x--x--x--x--x--- being scanned + | P36|<------x--x--x--x--x--x--- + | P37|<------x--x--x--x--x--x--- + | P40|<------x--x--x--x--x--x--- + | P41|<------x--x--x--x--x--x--- + | P42|<------x--x--x--x--x--x--- + | P43|<------x--x--x--x--x--x--- + | P44|<------x--x--x--x--x--x--- + | P45|<------x--x--x--x--x--x--- + | P46|<------x--x--x--x--x--x--- + | P47|<------x--x--x--x--x--x--- + | | | | | | | | + | M6801 | | | | | | | + | | 6 x 74HC04 hex inverter + |P10-P15|<------+--+--+--+--+--+ ROWS x 6 + +-------+ + + Credits + ------- + The internal ROM was dumped in collaboration with Dalby Datormuseum, whom + also provided documentation and schematics of the keyboard + + https://sites.google.com/site/dalbydatormuseum/home + https://github.com/MattisLind/6801reader + + **********************************************************************/ + +#include "emu.h" +#include "eispc_kb.h" +#include "cpu/m6800/m6801.h" + +//************************************************************************** +// CONFIGURABLE LOGGING +//************************************************************************** +#define LOG_PORTS (1U << 1) +#define LOG_RESET (1U << 2) +#define LOG_BITS (1U << 3) +#define LOG_UI (1U << 4) + +//#define VERBOSE (LOG_UI) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOGPORTS(...) LOGMASKED(LOG_PORTS, __VA_ARGS__) +#define LOGRST(...) LOGMASKED(LOG_RESET, __VA_ARGS__) +#define LOGBITS(...) LOGMASKED(LOG_BITS, __VA_ARGS__) +#define LOGUI(...) LOGMASKED(LOG_UI, __VA_ARGS__) + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define M6801_TAG "mcu" + +#define PCM(handler, parameter) PORT_CHANGED_MEMBER(DEVICE_SELF, eispc_keyboard_device, handler, parameter) + +namespace { + +INPUT_PORTS_START(eispc_kb) + PORT_START("P15") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR('6') PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PCM(key, 0) // 77 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') PCM(key, 0) // 78 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') PCM(key, 0) // 76 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("* PRINT") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('*') PORT_CHAR(UCHAR_MAMEKEY(PRTSCR)) PCM(key, 0) // 55 + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("R Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PCM(key, 0) // 54 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PCM(key, 0) // 53 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(". :") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') PCM(key, 0) // 52 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PCM(key, 0) // 63 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PCM(key, 0) // 64 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 0) // no scancode is sent + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PCM(key, 0) // 29 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(", ;") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') PCM(key, 0) // 51 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') PCM(key, 0) // 32 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') PCM(key, 0) // 45 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') PCM(key, 0) // 46 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') PCM(key, 0) // 36 + + PORT_START("P14") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 1) // 00 - keyboard error + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_PAUSE) PORT_CHAR(UCHAR_MAMEKEY(PAUSE)) PCM(key, 1) // 70 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') PORT_CHAR(UCHAR_MAMEKEY(HOME)) PCM(key, 1) // 71 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 1) // ff - keyboard error + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(']') PCM(key, 1) // 27 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00e5) PORT_CHAR(0x00c5) PORT_CHAR('[') PCM(key, 1) // 26 å Å + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PCM(key, 1) // 25 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PCM(key, 1) // 59 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PCM(key, 1) // 60 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PCM(key, 1) // 17 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PCM(key, 1) // 18 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PCM(key, 1) // 24 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PCM(key, 1) // 19 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PCM(key, 1) // 20 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PCM(key, 1) // 21 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PCM(key, 1) // 23 + + PORT_START("P13") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) PCM(key, 2) // 69 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 2) // ff - keyboard error + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(DEL)) PCM(key, 2) // 14 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PCM(key, 2) // 13 + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PCM(key, 2) // 12 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PCM(key, 2) // 11 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PCM(key, 2) // 10 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PCM(key, 2) // 02 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PCM(key, 2) // 01 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') PCM(key, 2) // 03 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PCM(key, 2) // 04 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PCM(key, 2) // 09 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PCM(key, 2) // 05 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PCM(key, 2) // 06 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') PCM(key, 2) // 07 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') PCM(key, 2) // 08 + + PORT_START("P12") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PCM(key, 3) // 73 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PCM(key, 3) // 74 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP) PORT_CHAR('8') PORT_CHAR(UCHAR_MAMEKEY(UP)) PCM(key, 3) // 72 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') PCM(key, 3) // 41 + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') PCM(key, 3) // 40 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PCM(key, 3) // 39 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PCM(key, 3) // 38 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PCM(key, 3) // 61 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PCM(key, 3) // 62 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PCM(key, 3) // 16 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) PCM(key, 3) // 15 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PCM(key, 3) // 37 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PCM(key, 3) // 33 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PCM(key, 3) // 34 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PCM(key, 3) // 35 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PCM(key, 3) // 22 + + PORT_START("P11") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PCM(key, 4) // 83 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PCM(key, 4) // 28 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PCM(key, 4) // 82 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 89 - no key + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 86 - no key + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 87 - no key + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 88 - no key + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PCM(key, 4) // 67 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PCM(key, 4) // 68 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // scan code ff - keyboard error + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PCM(key, 4) // 43 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PCM(key, 4) // 58 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_LALT) PCM(key, 4) // 56 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 85 - no key + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PCM(key, 4) // 47 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PCM(key, 4) // 57 + + PORT_START("P10") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN) PCM(key, 5) // 81 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 5) // ff - keyboard error + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PCM(key, 5) // 80 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW LINE") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PCM(key, 5) // 84 (programmable, default is 28) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PCM(key, 5) // 79 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR('4') PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PCM(key, 5) // 75 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 5) // ff - keyboard error + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PCM(key, 5) // 65 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PCM(key, 5) // 66 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PCM(key, 5) // 42 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PCM(key, 5) // 44 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PCM(key, 5) // 50 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PCM(key, 5) // 30 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PCM(key, 5) // 31 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PCM(key, 5) // 48 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PCM(key, 5) // 49 +INPUT_PORTS_END + + +//------------------------------------------------- +// ROM( eispc_kb ) +//------------------------------------------------- + +ROM_START( eispc_kb ) + ROM_REGION( 0x800, M6801_TAG, 0 ) + ROM_LOAD( "sgtpepper-1.2.bin", 0x000, 0x800, CRC(7107b841) SHA1(a939dd50622575c31fea9c7adb7a7db5403a7aca) ) +ROM_END + +} // anonymous namespace + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EISPC_KB, eispc_keyboard_device, "eispc_kb", "Ericsson PC keyboard") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// eispc_keyboard_device - constructor +//------------------------------------------------- + +eispc_keyboard_device::eispc_keyboard_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + uint32_t clock) + : device_t(mconfig, EISPC_KB, tag, owner, clock) + , m_mcu(*this, M6801_TAG) + , m_rows(*this, "P1%u", 0) + , m_txd_cb(*this) + , m_rxd_high(true) + , m_txd_high(true) + , m_hold(true) + , m_col_select(0) +{ +} + +INPUT_CHANGED_MEMBER( eispc_keyboard_device::key ) +{ + if (oldval && !newval) + { + LOGUI("Key Pressed - name: %s field: %04x param: %04x oldval: %04x newval: %04x\n", field.name(), field.defvalue(), param, oldval, newval); + int idx = *((int *)(¶m)); + if (idx >= sizeof(keys)) + logerror("Out of bounds access in keys array\n"); + else + keys[idx] |= (uint16_t) field.defvalue(); + } + else if (newval && !oldval) + { + LOGUI("Key Released - name: %s field: %04x param: %04x oldval: %04x newval: %04x\n", field.name(), field.defvalue(), param, oldval, newval); + int idx = *((int *)(¶m)); + if (idx >= sizeof(keys)) + logerror("Out of bounds access in keys array\n"); + else + keys[idx] &= ~(uint16_t)field.defvalue(); + } + for (int i = 0; i < 6; i++) LOGUI("%04x ", keys[i]); LOGUI("\n"); +} + +WRITE_LINE_MEMBER(eispc_keyboard_device::rxd_w) +{ + LOGBITS("KBD bit presented: %d\n", state); + m_rxd_high = CLEAR_LINE != state; +} + +WRITE_LINE_MEMBER(eispc_keyboard_device::hold_w) +{ + m_hold = CLEAR_LINE == state; +} + +WRITE_LINE_MEMBER(eispc_keyboard_device::rst_line_w) +{ + if (state == CLEAR_LINE) + { + m_mcu->resume(SUSPEND_REASON_RESET); + LOGRST("KBD: Keyboard mcu reset line is cleared\n"); + } + else + { + m_mcu->suspend(SUSPEND_REASON_RESET, 0); + LOGRST("KBD: Keyboard mcu reset line is asserted\n"); + } + +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void eispc_keyboard_device::device_reset() +{ + LOGRST("KBD: Keyboard is in reset until host computer explicitly releases the reset line\n"); + m_mcu->suspend(SUSPEND_REASON_RESET, 0); + for (auto & elem : keys) elem = 0; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void eispc_keyboard_device::device_start() +{ + m_txd_cb.resolve_safe(); + + save_item(NAME(m_rxd_high)); + save_item(NAME(m_txd_high)); + save_item(NAME(m_col_select)); + + m_rxd_high = true; + m_txd_high = true; + m_col_select = 0; +} + + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void eispc_keyboard_device::device_add_mconfig(machine_config &config) +{ + M6801(config, m_mcu, XTAL(4'915'200)); // Crystal verified from schematics and visual inspection + m_mcu->set_addrmap(AS_PROGRAM, &eispc_keyboard_device::eispc_kb_mem); + + m_mcu->in_p1_cb().set([this] + { + uint8_t data = 0; // Indicate what keys are pressed in selected column + + for (int i = 0; i < 6; i++) data |= (keys[i] & m_col_select ? 1 << i : 0); + + // Update txd bit + data &= 0x3f; + data |= ((!m_hold || !m_txd_high) ? 0 : 0x40); + + if ((data & 0x3f) != 0 && data != m_p1) + { + LOGUI("Reading port 1: %02x m_col_select:%04x\n", data, m_col_select); + m_p1 = data; + } + return data; + }); + + m_mcu->out_p1_cb().set([this](uint8_t data) + { + LOGPORTS("Writing %02x PORT 1\n", data); + }); + + m_mcu->in_p2_cb().set([this] + { + uint8_t data = M6801_MODE_7 | (m_rxd_high ? (1 << 3) : 0); + LOGPORTS("Reading port 2: %02x\n", data); + //LOGBITS("KBD: Reading rxd_high: %02x\n", m_rxd_high); + return data; + }); + + m_mcu->out_p2_cb().set([this](uint8_t data) + { + LOGPORTS("Writing port 2: %02x\n", data); + LOGBITS("KBD: writing bit: %02x\n", BIT(data, 4)); + }); + + m_mcu->out_ser_tx_cb().set([this](bool state) + { + m_txd_high = CLEAR_LINE != state; + LOGBITS("KBD: writing bit: %02x\n", m_txd_high); + m_txd_cb(state); + }); + + m_mcu->in_p3_cb().set([this] + { + LOGPORTS("Reading Port 3\n"); + return 0x00; + }); + + m_mcu->out_p3_cb().set([this](uint8_t data) + { + m_col_select &= 0xff00; + m_col_select |= ~data; + }); + + m_mcu->in_p4_cb().set([this] + { + LOGPORTS("Reading Port 4\n"); + return 0x00; + }); + + m_mcu->out_p4_cb().set([this](uint8_t data) + { + m_col_select &= 0x00ff; + m_col_select |= (~data << 8); + }); +} + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor eispc_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( eispc_kb ); +} + +//------------------------------------------------- +// ADDRESS_MAP( eispc_kb_mem ) +//------------------------------------------------- + +void eispc_keyboard_device::eispc_kb_mem(address_map &map) +{ + map(0x0000, 0x001f).rw(M6801_TAG, FUNC(m6801_cpu_device::m6801_io_r), FUNC(m6801_cpu_device::m6801_io_w)); + map(0x0080, 0x00ff).ram(); + map(0xf800, 0xffff).rom().region(M6801_TAG, 0); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *eispc_keyboard_device::device_rom_region() const +{ + return ROM_NAME( eispc_kb ); +} diff --git a/src/mame/machine/eispc_kb.h b/src/mame/machine/eispc_kb.h new file mode 100644 index 00000000000..66547409a47 --- /dev/null +++ b/src/mame/machine/eispc_kb.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edström +#ifndef MAME_MACHINE_EISPC_KB_H +#define MAME_MACHINE_EISPC_KB_H + +#pragma once + +#include "cpu/m6800/m6801.h" + +DECLARE_DEVICE_TYPE(EISPC_KB, eispc_keyboard_device) + +class eispc_keyboard_device : public device_t +{ +public: + auto txd_cb() { return m_txd_cb.bind(); } + + eispc_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0); + + DECLARE_INPUT_CHANGED_MEMBER(key); + DECLARE_WRITE_LINE_MEMBER(rxd_w); + DECLARE_WRITE_LINE_MEMBER(hold_w); + DECLARE_WRITE_LINE_MEMBER(rst_line_w); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + virtual tiny_rom_entry const *device_rom_region() const override; + + required_device m_mcu; + required_ioport_array<6> m_rows; + devcb_write_line m_txd_cb; // Callback for KBD-> EPC + + bool m_rxd_high; // state of Rx input line + bool m_txd_high; // state of Tx output line + bool m_hold; + uint16_t m_col_select; + uint16_t keys[6]; + uint8_t m_p1; + + void eispc_kb_mem(address_map &map); +}; + +#endif // MAME_MACHINE_EISPC_KB_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 6007b355e35..8310c0e9866 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -12715,6 +12715,9 @@ splndrbt2 // (c) 1985 Alpha Denshi Co. splndrbta // (c) 1985 Alpha Denshi Co. splndrbtb // (c) 1985 Alpha Denshi Co. +@source:eispc.cpp +epc // 1984 Ericsson PC + @source:ertictac.cpp ertictac // (c) 1992 Sisteme ertictaca // (c) 1992 Sisteme @@ -31659,7 +31662,6 @@ comport // Compaq Portable dgone // 1984 Data General/One eagle1600 // eaglespirit // Eagle PC Spirit -epc // 1984 Ericsson PC eppc // 1985 Ericsson Portable PC hyo88t // Hyosung Topstar 88T ibm5550 // diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 91f9f9f0af8..079b8b3921b 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -220,6 +220,7 @@ ec184x.cpp ec65.cpp ec7915.cpp einstein.cpp +eispc.cpp elan_eu3a05.cpp elan_eu3a14.cpp electron.cpp From 5f8e64d325592fc1cf20d5944a6f0d2b86a9e658 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 14:07:13 +0200 Subject: [PATCH 06/12] ega.cpp: converted to logmacro.h --- src/devices/bus/isa/ega.cpp | 60 +++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/devices/bus/isa/ega.cpp b/src/devices/bus/isa/ega.cpp index 5da3c263384..32175304f20 100644 --- a/src/devices/bus/isa/ega.cpp +++ b/src/devices/bus/isa/ega.cpp @@ -448,22 +448,31 @@ located at I/O port 0x3CE, and a data register located at I/O port 0x3CF. #include "screen.h" +#define LOG_READ (1U << 1) +#define LOG_SETUP (1U << 2) +#define LOG_MODE (1U << 3) -#define VERBOSE_EGA 1 +//#define VERBOSE (LOG_GENERAL | LOG_SETUP | LOG_MODE) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif #define EGA_SCREEN_NAME "ega_screen" #define EGA_CRTC_NAME "crtc_ega_ega" - #define EGA_MODE_GRAPHICS 1 #define EGA_MODE_TEXT 2 - -/* - Prototypes -*/ - - ROM_START( ega ) ROM_REGION(0x4000, "user1", 0) ROM_DEFAULT_BIOS("ega") @@ -776,7 +785,7 @@ CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics ) { uint16_t *p = &bitmap.pix16(y); -// logerror( "pc_ega_graphics: y = %d, x_count = %d, ma = %d, ra = %d\n", y, x_count, ma, ra ); + LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra ); if ( m_graphics_controller.data[5] & 0x10 ) { @@ -838,7 +847,7 @@ CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_text ) uint16_t *p = &bitmap.pix16(y); int i; -// logerror( "pc_ega_text: y = %d, x_count = %d, ma = %d, ra = %d\n", y, x_count, ma, ra ); + LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra ); for ( i = 0; i < x_count; i++ ) { @@ -901,10 +910,7 @@ void isa8_ega_device::change_mode() ! ( m_sequencer.data[0x04] & 0x01 ) && ( m_graphics_controller.data[0x06] & 0x01 ) ) { - if ( VERBOSE_EGA ) - { - logerror("change_mode(): Switch to graphics mode\n"); - } + LOGMODE("%s: Switch to graphics mode\n", FUNCNAME); m_video_mode = EGA_MODE_GRAPHICS; } @@ -914,10 +920,7 @@ void isa8_ega_device::change_mode() ( m_sequencer.data[0x04] & 0x01 ) && ! ( m_graphics_controller.data[0x06] & 0x01 ) ) { - if ( VERBOSE_EGA ) - { - logerror("chnage_mode(): Switching to text mode\n"); - } + LOGMODE("%s: Switching to text mode\n", FUNCNAME); m_video_mode = EGA_MODE_TEXT; @@ -1195,10 +1198,7 @@ READ8_MEMBER( isa8_ega_device::pc_ega8_3X0_r ) WRITE8_MEMBER( isa8_ega_device::pc_ega8_3X0_w ) { - if ( VERBOSE_EGA ) - { -// logerror("pc_ega_3X0_w: offset = %02x, data = %02x\n", offset, data ); - } + LOGSETUP("%s: offset = %02x, data = %02x\n", FUNCNAME, offset, data ); switch ( offset ) { @@ -1263,10 +1263,7 @@ READ8_MEMBER(isa8_ega_device::pc_ega8_3c0_r ) { int data = 0xff; - if ( VERBOSE_EGA ) - { -// logerror("pc_ega_3c0_r: offset = %02x\n", offset ); - } + LOGR("%s: offset = %02x\n", FUNCNAME, offset ); switch ( offset ) { @@ -1322,10 +1319,7 @@ WRITE8_MEMBER(isa8_ega_device::pc_ega8_3c0_w ) }; int index; - if ( VERBOSE_EGA ) - { -// logerror("pc_ega_3c0_w: offset = %02x, data = %02x\n", offset, data ); - } + LOGSETUP("%s: offset = %02x, data = %02x\n", FUNCNAME, offset, data ); switch ( offset ) { @@ -1339,7 +1333,7 @@ WRITE8_MEMBER(isa8_ega_device::pc_ega8_3c0_w ) { index = m_attribute.index & 0x1F; - logerror("AR%02X = 0x%02x\n", index, data ); + LOGSETUP(" - AR%02X = 0x%02x\n", index, data ); /* Clear unused bits */ m_attribute.data[ index ] = data & ar_reg_mask[ index ]; @@ -1368,7 +1362,7 @@ WRITE8_MEMBER(isa8_ega_device::pc_ega8_3c0_w ) case 5: index = m_sequencer.index & 0x07; - logerror("SR%02X = 0x%02x\n", index & 0x07, data ); + LOGSETUP(" - SR%02X = 0x%02x\n", index & 0x07, data ); /* Clear unused bits */ m_sequencer.data[ index ] = data & sr_reg_mask[ index ]; @@ -1390,7 +1384,7 @@ WRITE8_MEMBER(isa8_ega_device::pc_ega8_3c0_w ) case 15: index = m_graphics_controller.index & 0x0F; - logerror("GR%02X = 0x%02x\n", index, data ); + LOGSETUP(" - GR%02X = 0x%02x\n", index, data ); /* Clear unused bits */ m_graphics_controller.data[ index ] = data & gr_reg_mask[ index ]; From a4b3c33dc3f47e60c2df5f5e630e2b8c41d8b4bf Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 14:14:17 +0200 Subject: [PATCH 07/12] mda: Added Ericsson Monochrome HR Graphics Board 1070 (might be splitted out later) and introduced logmacro.h --- src/devices/bus/isa/isa_cards.cpp | 2 + src/devices/bus/isa/mda.cpp | 607 +++++++++++++++++++++++++++--- src/devices/bus/isa/mda.h | 81 ++++ src/emu/xtal.cpp | 1 + 4 files changed, 648 insertions(+), 43 deletions(-) diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index c97866bdf5e..4c0a41f430d 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -126,6 +126,7 @@ void pc_isa8_cards(device_slot_interface &device) device.option_add("chessmdr", ISA8_CHESSMDR); device.option_add("chessmsr", ISA8_CHESSMSR); device.option_add("finalchs", ISA8_FINALCHS); + device.option_add("epc_mda", ISA8_EPC_MDA); } void pc_isa16_cards(device_slot_interface &device) @@ -166,6 +167,7 @@ void pc_isa16_cards(device_slot_interface &device) device.option_add("chessmdr", ISA8_CHESSMDR); device.option_add("chessmsr", ISA8_CHESSMSR); device.option_add("finalchs", ISA8_FINALCHS); + device.option_add("epc_mda", ISA8_EPC_MDA); // 16-bit device.option_add("ide", ISA16_IDE); device.option_add("ne2000", NE2000); diff --git a/src/devices/bus/isa/mda.cpp b/src/devices/bus/isa/mda.cpp index 823ff040676..d7f6625d75c 100644 --- a/src/devices/bus/isa/mda.cpp +++ b/src/devices/bus/isa/mda.cpp @@ -12,6 +12,31 @@ #include "screen.h" +#define LOG_READ (1U << 1) +#define LOG_SETUP (1U << 2) +#define LOG_ROW (1U << 3) +#define LOG_MODE (1U << 4) +#define LOG_CHRG (1U << 5) +#define LOG_STAT (1U << 6) + +//#define VERBOSE (LOG_MODE|LOG_SETUP|LOG_ROW) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGROW(...) LOGMASKED(LOG_ROW, __VA_ARGS__) +#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__) +#define LOGCHRG(...) LOGMASKED(LOG_CHRG, __VA_ARGS__) +#define LOGSTAT(...) LOGMASKED(LOG_STAT, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif + #define MDA_SCREEN_NAME "mda_screen" #define MC6845_NAME "mc6845" @@ -19,20 +44,7 @@ Hercules video card */ #define HERCULES_SCREEN_NAME "hercules_screen" - -#define VERBOSE_MDA 0 /* MDA (Monochrome Display Adapter) */ - -#define MDA_CLOCK 16.257_MHz_XTAL - -#define MDA_LOG(N,M,A) \ - do { \ - if(VERBOSE_MDA>=N) \ - { \ - if( M ) \ - logerror("%11.6f: %-24s",machine().time().as_double(),(char*)M ); \ - logerror A; \ - } \ - } while (0) +#define MDA_CLOCK XTAL(16'257'000) static const unsigned char mda_palette[4][3] = { @@ -211,7 +223,6 @@ void isa8_mda_device::device_reset() The character cell size is 9x15. Column 9 is column 8 repeated for character codes 176 to 223. ***************************************************************************/ - MC6845_UPDATE_ROW( isa8_mda_device::mda_text_inten_update_row ) { const rgb_t *palette = m_palette->palette()->entry_list_raw(); @@ -219,7 +230,7 @@ MC6845_UPDATE_ROW( isa8_mda_device::mda_text_inten_update_row ) uint16_t chr_base = ( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; int i; - if ( y == 0 ) MDA_LOG(1,"mda_text_inten_update_row",("\n")); + if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); for ( i = 0; i < x_count; i++ ) { uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; @@ -292,7 +303,7 @@ MC6845_UPDATE_ROW( isa8_mda_device::mda_text_blink_update_row ) uint16_t chr_base = ( ra & 0x08 ) ? 0x800 | ( ra & 0x07 ) : ra; int i; - if ( y == 0 ) MDA_LOG(1,"mda_text_blink_update_row",("\n")); + if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); for ( i = 0; i < x_count; i++ ) { uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; @@ -360,7 +371,6 @@ MC6845_UPDATE_ROW( isa8_mda_device::mda_text_blink_update_row ) } } - MC6845_UPDATE_ROW( isa8_mda_device::crtc_update_row ) { if (m_update_row_type == -1) @@ -462,17 +472,17 @@ WRITE8_MEMBER( isa8_mda_device::io_write) { switch( offset ) { - case 0: case 2: case 4: case 6: + case 0x00: case 0x02: case 0x04: case 0x06: m_crtc->address_w(data); break; - case 1: case 3: case 5: case 7: + case 0x01: case 0x03: case 0x05: case 0x07: m_crtc->register_w(data); break; - case 8: + case 0x08: mode_control_w(space, offset, data); break; - case 12: case 13: case 14: - m_lpt->write(space, offset - 12, data); + case 0x0c: case 0x0d: case 0x0e: + m_lpt->write(space, offset - 0x0c, data); break; } } @@ -482,18 +492,18 @@ READ8_MEMBER( isa8_mda_device::io_read) int data = 0xff; switch( offset ) { - case 0: case 2: case 4: case 6: + case 0x00: case 0x02: case 0x04: case 0x06: /* return last written mc6845 address value here? */ break; - case 1: case 3: case 5: case 7: + case 0x01: case 0x03: case 0x05: case 0x07: data = m_crtc->register_r(); break; - case 10: + case 0x0a: data = status_r(space, offset); break; - /* 12, 13, 14 are the LPT ports */ - case 12: case 13: case 14: - data = m_lpt->read(space, offset - 12); + /* LPT ports */ + case 0x0c: case 0x0d: case 0x0e: + data = m_lpt->read(space, offset - 0x0c); break; } return data; @@ -624,7 +634,7 @@ MC6845_UPDATE_ROW( isa8_hercules_device::hercules_gfx_update_row ) uint32_t *p = &bitmap.pix32(y); uint16_t gfx_base = ( ( m_mode_control & 0x80 ) ? 0x8000 : 0x0000 ) | ( ( ra & 0x03 ) << 13 ); int i; - if ( y == 0 ) MDA_LOG(1,"hercules_gfx_update_row",("\n")); + if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); for ( i = 0; i < x_count; i++ ) { uint8_t data = m_videoram[ gfx_base + ( ( ma + i ) << 1 ) ]; @@ -681,19 +691,19 @@ WRITE8_MEMBER( isa8_hercules_device::io_write ) { switch( offset ) { - case 0: case 2: case 4: case 6: + case 0x00: case 0x02: case 0x04: case 0x06: m_crtc->address_w(data); break; - case 1: case 3: case 5: case 7: + case 0x01: case 0x03: case 0x05: case 0x07: m_crtc->register_w(data); break; - case 8: + case 0x08: mode_control_w(space, offset, data); break; - case 12: case 13: case 14: + case 0x0c: case 0x0d: case 0x0e: m_lpt->write(space, offset - 12, data); break; - case 15: + case 0x0f: m_configuration_switch = data; break; } @@ -725,18 +735,18 @@ READ8_MEMBER( isa8_hercules_device::io_read ) int data = 0xff; switch( offset ) { - case 0: case 2: case 4: case 6: + case 0x00: case 0x02: case 0x04: case 0x06: /* return last written mc6845 address value here? */ break; - case 1: case 3: case 5: case 7: + case 0x01: case 0x03: case 0x05: case 0x07: data = m_crtc->register_r(); break; - case 10: + case 0x0a: data = status_r(space, offset); break; - /* 12, 13, 14 are the LPT ports */ - case 12: case 13: case 14: - data = m_lpt->read(space, offset - 12); + /* LPT ports */ + case 0xc: case 0xd: case 0xe: + data = m_lpt->read(space, offset - 0x0c); break; } return data; @@ -809,7 +819,7 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::mda_lowres_text_inten_update_row ) uint16_t chr_base = ra; int i; - if ( y == 0 ) MDA_LOG(1,"mda_lowres_text_inten_update_row",("\n")); + if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); for ( i = 0; i < x_count; i++ ) { uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; @@ -873,7 +883,7 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::mda_lowres_text_blink_update_row ) uint16_t chr_base = ra; int i; - if ( y == 0 ) MDA_LOG(1,"mda_lowres_text_blink_update_row",("\n")); + if ( y == 0 ) LOGROW("%11.6f: %-24s\n", machine().time().as_double(), FUNCNAME); for ( i = 0; i < x_count; i++ ) { uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; @@ -965,3 +975,514 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::crtc_update_row ) break; } } + +/***************************************************************************** + + Ericsson PC Monochrome HR Graphics Board 1070 + +******************************************************************************/ + +/* PCB layouts and assembly years from online pictures and physical unit. + Ericsson - marked SPVT02 8301 60 53-10, assembled in 1985 indicated by chip dates + +--------------------------------------------------------------------------------------+ ___ + | IC1 IC2 IC3 IC4 IC5 +-IC15--EPROM-+ IC6 IC7 IC8 S1 || + | |8363 65 14-80| || + | IC9 IC10 IC11 IC12 IC13 IC14|CG 50821 A64 |+------------------++-IC24 EPROM--+ || + | +-------------+| CRTC HD46505SP-1 ||10-40VP | || + | IC16 IC17 IC18 IC19 IC20 IC21 IC22 | IC23 HD68A45SP ||402 28 A19 | J4|| not + | +------------------++-------------+ || mounted + | IC25 IC26 IC27 IC28 IC29 IC30 IC31 IC32 IC33 IC34 || + | O-|__ + | IC35 IC36 IC37 IC38 IC39 IC40 IC41 IC42 IC43 IC44 || | + | ||DB15 + | IC45 IC46 IC47 IC48 IC49 IC50 IC51 IC52 IC53 IC54 || | + | ||__| + | IC55 IC56 IC57 IC58 IC59 IC60 IC61 IC62 IC63 IC64 O-| + | J1A || + | IC65 IC66 IC67 IC68 IC69 IC70 IC71 IC72 +--------------------------------------------+| + +-----------------------------------------+ ||||||||| ||||||||||||||||||||||||| | + I85565 A85571 (labels) | + | + + IC's (from photos) + ------------------------------------------------------------------------------ + IC1 74F109 IC26 74F86 IC51 TMS4416-15NL 4 x 16Kbits DRAM + IC2 74LS393 IC27 74LS08 IC52 74ALS574 + IC3 74F64 IC28 74F153 IC53 74LS138 + IC4 74ALS299 IC29 74LS174 IC54 74F86 + IC5 74LS375 IC30 74LS374 IC55 74F109 + IC6 74LS151 IC31 74LS374 IC56 74F32 + IC7 74LS153 IC32 74ALS574 IC57 74F109 + IC8 74LS389? IC33 74LS08 IC58 74F00? + IC9 74F02 IC34 74LS245 IC59 74LS244 + IC10 74ALS109 IC35 74F10? IC60 TMS4416-15NL 4 x 16Kbits DRAM + IC11 Crystal 17.040MHz IC36 74LS02 IC61 TMS4416-15NL 4 x 16Kbits DRAM + IC12 74F64 IC37 74LS00 IC62 74ALS574 + IC13 74ALS299 IC38 74F374 IC63 74LS138 + IC14 PAL? 10-70ART40101 IC39 74LS125 IC64 74LS245 + IC15 EPROM 8363 65 14-80 CG 50821 A64 IC40 74LS244 IC65 74LS00 + IC16 Crystal 19.170MHz IC41 74LS244 IC66 74LS02 + IC17 74LS10 IC42 74LS574 IC67 74LS51 + IC18 74F08 IC43 74LS32 IC68 74LS04 + IC19 74ALS574 IC44 MC10124 - TTL to MECL converter IC69 74LS153 + IC20 74LS299 IC45 74LS109 IC70 74LS109 + IC21 74LS273 IC46 74LS00 IC71 74LS138 + IC22 74ALS574 IC47 74F194 IC72 74LS139 + IC23 CRTC HD46505SP,HD68A45SP IC48 74F04 + IC24 EPROM 2764, 10-40 VP 402 28 A19 IC49 74LS174 + IC25 74ALS109 IC50 TMS4416-15NL 4 x 16Kbits DRAM + + General description + ------------------- + The PCB has a 2 bit DIP switch S1 and a DB15 non standard video connector. There is also an unsoldered J4 connector + above the DB15 but no hole prepared for a connector in the plate. Above the J4 connector there is a two pin PCB connector + that probably receives the power for the monitor for the DB15 from the PSU. + + Just below IC65 and IC66 there are two labels saying "I 85565" and "A E85571" respectively + + Video cable, card DB15 <---> monitor DB25 + --------------------------------------------------- + Ericsson 2 +VS 4 Ericsson + Monochrome 3 VS return 2 Monochrome HR + HR Graphics 10 +VS 17 Monitors 3111 (Amber) or + Board 1070 11 VS return 15 3712/3715 (Black & White) + 4 VSYNC 6 + 12 VSYNC 19 + 5 HSYNC 7 + 13 HSYNC 20 + 6 High intensity 8 + 14 High intensity 21 + 7 Video 9 + 15 Video 22 + 8 GND 11 + + This board is normaly used with an Ericsson monitor due to the non standard connector. + Trivia: https://www.pinterest.se/pin/203084264425177097/ + */ + +#define EPC_MDA_SCREEN "epc_mda_screen" + +#if 0 +static GFXDECODE_START( pcepc ) + GFXDECODE_ENTRY( "gfx1", 0x0000, pc_16_charlayout, 1, 1 ) +GFXDECODE_END +#endif + +ROM_START( epc ) + ROM_REGION(0x2000,"chargen", 0) + ROM_LOAD("8363_65_14_80_cg_50821_a64.bin", 0x00000, 0x2000, CRC(be709786) SHA1(38ab26224bbe66bbe2bb2ccac29b41cbf78bdbf8)) + //ROM_LOAD("10_40_vp_402_28_ic_24_a19.bin", 0x00000, 0x2000, CRC(2aa53b92) SHA1(87051a037249eb631d7d2191bc0e925125c60f39)) +ROM_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** +DEFINE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device, "isa_epc_mda", "Ericsson PC Monochrome HR Graphics Board 1070") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- +/* There are two crystals on the board: 19.170Mhz and 17.040MHz TODO: verify use */ +/* Text modes uses 720x400 base resolution and the Graphics modes 320/640x200/400 */ +/* This matches the difference between the crystals so we assume this for now */ +void isa8_epc_mda_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, EPC_MDA_SCREEN, SCREEN_TYPE_RASTER)); + screen.set_raw(XTAL(19'170'000) / 4, 720, 0, 720, 400, 0, 400); + //screen.set_screen_update(MC6845_NAME, FUNC(h46505_device::screen_update)); + screen.set_screen_update(MC6845_NAME, FUNC(mc6845_device::screen_update)); + + PALETTE(config, m_palette).set_entries(4); + + HD6845S(config, m_crtc, XTAL(19'170'000) / 16); // clock and divider are guesswork + m_crtc->set_screen(EPC_MDA_SCREEN); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + + m_crtc->set_update_row_callback(FUNC(isa8_epc_mda_device::crtc_update_row), this); + m_crtc->out_hsync_callback().set(FUNC(isa8_epc_mda_device::hsync_changed)); + m_crtc->out_vsync_callback().set(FUNC(isa8_epc_mda_device::vsync_changed)); + + //MCFG_GFXDECODE_ADD("gfxdecode", "palette", pcepc) +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *isa8_epc_mda_device::device_rom_region() const +{ + return ROM_NAME( epc ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// isa8_epc_mda_device - constructor +//------------------------------------------------- + +isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + isa8_mda_device(mconfig, ISA8_EPC_MDA, tag, owner, clock) + , m_soft_chr_gen(nullptr) + , m_s1(*this, "S1") + , m_color_mode(0) + , m_mode_control2(0) + , m_screen(*this, EPC_MDA_SCREEN) + , m_io_monitor(*this, "MONITOR") + , m_chargen(*this, "chargen") + , m_installed(false) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void isa8_epc_mda_device::device_start() +{ + if (m_palette != nullptr && !m_palette->started()) + throw device_missing_dependencies(); + + /* Palette for use with the Ericsson Amber Monochrome HR CRT monitor 3111, P3 phospor 602nm 255,183, 0 */ + m_3111_pal[0] = rgb_t( 0, 0, 0); // black + m_3111_pal[1] = rgb_t( 143, 103, 0); // dim + m_3111_pal[2] = rgb_t( 191, 137, 0); // normal + m_3111_pal[3] = rgb_t( 255, 183, 0); // bright + + /* Palette for use with the Ericsson B&W Monochrome HR CRT monitor 3712/3715 */ + m_371x_pal[0] = rgb_t( 0, 0, 0); // black + m_371x_pal[1] = rgb_t( 143, 143, 143); // dim + m_371x_pal[2] = rgb_t( 191, 191, 191); // normal + m_371x_pal[3] = rgb_t( 255, 255, 255); // bright + + /* Init a default palette */ + m_pal = &m_3111_pal; // In case screen starts rendering before device_reset where we read the settings + + m_videoram.resize(0x8000); + set_isa_device(); + m_installed = false; +} + +void isa8_epc_mda_device::device_reset() +{ + m_framecnt = 0; + m_mode_control = 0; + m_vsync = 0; + m_hsync = 0; + + m_color_mode = m_s1->read(); + LOGSETUP("%s: m_color_mode:%02x\n", FUNCNAME, m_color_mode); + m_pal = (m_io_monitor-> read() & 1) == 1 ? &m_371x_pal : &m_3111_pal; + m_vmode = 0; + + if (m_installed == false) + { + m_isa->install_device(0x3b0, 0x3bf, read8_delegate( FUNC(isa8_epc_mda_device::io_read), this ), write8_delegate( FUNC(isa8_epc_mda_device::io_write), this ) ); + m_isa->install_bank(0xb0000, 0xb7fff, "bank_epc", &m_videoram[0]); // Monochrome emulation mode VRAM address + + // This check allows a color monitor adapter to be installed at this address range if color emulation is disabled + if (m_color_mode & 1) + { + m_isa->install_device(0x3d0, 0x3df, read8_delegate( FUNC(isa8_epc_mda_device::io_read), this ), write8_delegate( FUNC(isa8_epc_mda_device::io_write), this ) ); + m_isa->install_bank(0xb8000, 0xbffff, "bank_epc", &m_videoram[0]); // Color emulation mode VRAM address, but same 32KB areas as there are only this amount on the board + } + m_installed = true; + } +} + +/* + * Register Address table from the manual + * Ericsson name MDA mode CGA mode Standard name + *------------------------------------------------------------------------------- + * 6845 Address Registers 0x3b4 0x3d4 wo CRT Index reg + * 6845 Data Registers 0x3b5 0x3d5 wo CRT Data reg + * Mode Register 1 0x3b8 0x3d8 rw MDA/CGA mode reg (bit 0,1 & 4 incompatible) + * Mode Register 2 0x3bf 0x3df rw CRT/CPU page reg (incompatible w PCjr only) + * Status Register 0x3ba 0x3da r CGA/MDA status reg (incompatible) + * w EGA/VGA feature ccontrol reg (not used by this board) + */ +WRITE8_MEMBER( isa8_epc_mda_device::io_write) +{ + LOG("%s: %04x <- %02x\n", FUNCNAME, offset, data); + hd6845s_device *hd6845s = subdevice(MC6845_NAME); + switch( offset ) + { + case 0x04: + //LOGSETUP(" - HD6845S address write\n"); + hd6845s->address_w( data ); + break; + case 0x05: + //LOGSETUP(" - HD6845S register write\n"); + hd6845s->register_w( data ); + break; + case 0x08: // Mode 1 reg + LOGMODE(" - Mode register 1 write: %02x\n", data); + LOGMODE(" MSB attribute: %s\n", (data & 0x20) == 0 ? "intensity" : "blink"); + LOGMODE(" Horizontal px: %s\n", (data & 0x10) == 0 ? "320/LR" : "640/HR"); + LOGMODE(" Video : %s\n", (data & 0x08) == 0 ? "Disabled" : "Enabled"); + LOGMODE(" Mode : %s\n", (data & 0x02) == 0 ? "Text" : "Graphics"); + LOGMODE(" Text columns : %d\n", (data & 0x01) == 0 ? 40 : 80); + m_mode_control = data; + m_vmode &= ~(VM_GRAPH | VM_COLS80 | VM_HOR640); + m_vmode |= ((m_mode_control & 0x01) ? VM_COLS80 : 0); + m_vmode |= ((m_mode_control & 0x02) ? VM_GRAPH : 0); + m_vmode |= ((m_mode_control & 0x10) ? VM_HOR640 : 0); + m_update_row_type = ((data & 0x20) == 0 ? MDA_LOWRES_TEXT_INTEN : MDA_LOWRES_TEXT_BLINK); + { + rectangle rect(0, get_xres() - 1, 0, get_yres() -1); + m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50)); + } + LOGMODE("Video Mode:%02x\n\n", m_vmode); + break; + case 0x0f: // Mode 2 reg + LOGMODE(" - Mode register 2 write: %02x\n", data); + LOGMODE(" Vertical px : %s\n", (data & MR2_VER400) == 0 ? "200" : "400"); + LOGMODE(" Character set: %s\n", (data & MR2_CHRSET) == 0 ? "0" : "1"); + LOGMODE(" Emulated : %s\n", (data & MR2_COLEMU) == 0 ? "Color" : "Monochrome"); + m_mode_control2 = data; + m_vmode &= ~(VM_MONO | VM_VER400); + m_vmode |= ((m_mode_control2 & 0x04) ? VM_MONO : 0); + m_vmode |= ((m_mode_control2 & 0x80) ? VM_VER400 : 0); + { + rectangle rect(0, get_xres() - 1, 0, get_yres() -1); + m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50)); + } + LOGMODE("Video Mode:%02x\n\n", m_vmode); + break; + default: + LOG("EPC MDA: io_write at wrong offset:%02x\n", offset); + logerror("EPC MDA: io_write at wrong offset:%02x\n", offset); + } +} + +READ8_MEMBER( isa8_epc_mda_device::io_read) +{ + LOG("%s: %04x <- ???\n", FUNCNAME, offset); + int data = 0xff; + hd6845s_device *hd6845s = subdevice(MC6845_NAME); + switch( offset ) + { + case 0x04: + LOGR(" - hd6845s address read\n"); + break; + case 0x05: + LOGR(" - hd6845s register read\n"); + data = hd6845s->register_r(); + break; + case 0x08: // Mode 1 reg + data = m_mode_control; + LOGMODE(" - Mode register 1 read: %02x\n", data); + break; + case 0x0a: // Status reg: b7-6=00 board ID; b3 vert retrace; b0 horiz retrace; b5,4,2,1 unused + data = (m_vsync != 0 ? 0x08 : 0x00) | (m_hsync != 0 ? 0x01 : 0x00); + LOGSTAT(" - Status register read: %02x\n", data); + break; + case 0x0f: // Mode 2 reg + data = m_mode_control2; + LOGMODE(" - Mode register 2 read: %02x\n", data); + break; + default: + LOG("EPC MDA: io_read at wrong offset:%02x\n", offset); + logerror("EPC MDA: io_read at wrong offset:%02x\n", offset); + } + LOG(" !!!: %04x <- %02x\n", offset, data); + return data; +} + +inline int isa8_epc_mda_device::get_xres() +{ + return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_HOR640) ? 640 : 320 ) : 720; +} + +inline int isa8_epc_mda_device::get_yres() +{ + return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_VER400) ? 400 : 200 ) : 400; +} + +MC6845_UPDATE_ROW( isa8_epc_mda_device::crtc_update_row ) +{ + uint32_t *p = &bitmap.pix32(y); + uint16_t chr_base = ra; + int i; + + // Get som debug data from a couple of rows now and then + if ( y < (16 * 0 + 0x20) && (m_framecnt & 0xff) == 0 ) + { + LOGROW("%11.6f %s\n - y:%d chr_base:%d ra:%d ma:%d x_count:%d\n", machine().time().as_double(), FUNCNAME, + y, y % 16, ra, ma, x_count); + } + + // Video Off handling + if ((m_mode_control & MR1_VIDEO) == 0) + { + for (int i = 0; i < get_xres(); i++) + { + bitmap.pix32(y, i) = rgb_t::black(); + } + } + + // Graphic modes using only pixeldata, soft fonts are 8x8 or 8x16 but this is transparant to the code + else if ((m_vmode & VM_GRAPH) != 0) + { + logerror("EPC MDA: graphic modes not supported yet\n"); + } + + // Text modes using one of two 9x16 fonts in character rom + else + { + // Adjust row pointer if in monochrome text mode as we insert two scanlines per row of characters (see below) + if (m_vmode & VM_MONO) + { + p = &bitmap.pix32((y / 14) * 16 + y % 14); + } + + // Loop over each character in a row + for ( i = 0; i < x_count; i++ ) + { + uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; + uint8_t chr = m_videoram[ offset ]; + uint8_t attr = m_videoram[ offset + 1 ]; + uint8_t data = m_chargen[ ((m_mode_control2 & MR2_CHRSET) ? 0x1000 : 0) + chr_base + chr * 16]; + + // Default to light text on dark background + uint8_t fg = 2; + uint8_t bg = 0; + + if (y == 0 && i == 0) LOGCHRG(" - Offset: %04x Chr: '%c'[%02x] Attr: %02x Chr_base: %04x\n", offset, chr, chr, attr, chr_base); + + // Prepare some special monochrome emulation cases + if ( m_vmode & VM_MONO) + { + // Handle invisible characters + if ( (attr & (ATTR_FOREG | ATTR_BACKG)) == 0 ) + { + data = 0x00; + } + // Handle reversed characters + else if ( (attr & (ATTR_BACKG)) == ATTR_BACKG ) + { + fg = 0; + bg = 2; + } + } + else // prepare some special color emulation cases + { + // Handle invisible characters + if ( (attr & (ATTR_FOREG)) == ((attr & ATTR_BACKG) >> 4)) + { + data = 0x00; + } + // Handle reversed characters + else if ( (attr & ATTR_BACKG) == ATTR_BACKG || + (attr & ATTR_FOREG) == 0 ) + { + fg = 0; + bg = 2; + } + } + + // Handle intense foreground + if ((attr & ATTR_INTEN) != 0 && fg == 2) + { + fg = 3; + } + + // Handle intense background if blinking is disabled + if ((m_mode_control & MR1_BLINK) == 0 && + (attr & ATTR_BLINK) != 0 && bg == 2) + { + bg = 3; + } + + // Handle cursor and blinks + if ( i == (cursor_x)) + { + if ( m_framecnt & 0x08 ) + { + data = 0xFF; + } + } + else + { + if ( (m_mode_control & MR1_BLINK) && + ( attr & ATTR_BLINK ) && ( m_framecnt & 0x10 ) ) + { + data = 0x00; + } + } + + *p = (*m_pal)[( data & 0x80 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x40 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x20 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x10 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x08 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x04 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x02 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x01 ) ? fg : bg]; p++; + if (chr >= 0xc0 && chr <= 0xdf) + *p = (*m_pal)[( data & 0x01 ) ? fg : bg]; // 9th pixel col is a copy of col 8 + else + *p = (*m_pal)[bg]; // 9th pixel col is just background + p++; + + // Insert two extra scanlines in monochrome text mode to get 400 lines and support underline, needs verification on actual hardware. + // The technical manual says that the character box is 9x16 pixels in 80x25 character mode which equals 720x400 resolution but the + // CRTC calls back for only 350 lines. Assumption is that there is hardware adding these lines and that handles underlining. In color + // emulation text mode all 400 lines are called for in 80x25 and this mode does not support underlining according to the technical manual + if ( ra == 13 && (m_vmode & VM_MONO) ) + { + uint16_t row = ra + (y / 14) * 16; // Calculate correct row number including the extra 2 lines per each row of characters + for ( int j = 0; j < 9; j++) + { + if (chr >= 0xb3 && chr <= 0xdf) // Handle the meta graphics characters + { + bitmap.pix32(row + 1, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; + bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; + } + else + { + // Handle underline + bitmap.pix32(row + 1, j + i * 9) =(*m_pal)[( attr & ATTR_FOREG ) == ATTR_ULINE ? fg : bg]; + bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[bg]; + } + } + } + } + } +} + +//-------------------------------------------------------------------- +// Port definitions +//-------------------------------------------------------------------- +static INPUT_PORTS_START( epc_mda ) + PORT_START("S1") + PORT_DIPNAME( 0x01, 0x00, "Color emulation") PORT_DIPLOCATION("S1:1") + PORT_DIPSETTING( 0x00, "Disabled" ) + PORT_DIPSETTING( 0x01, "Enabled" ) + PORT_DIPUNUSED_DIPLOC(0x02, 0x02, "S1:2") + + PORT_START("MONITOR") + PORT_CONFNAME( 0x01, 0x00, "Ericsson Monochrome HR Monitors") PORT_CHANGED_MEMBER(DEVICE_SELF, isa8_epc_mda_device, monitor_changed, 0) + PORT_CONFSETTING( 0x00, "Amber 3111") + PORT_CONFSETTING( 0x01, "B&W 3712/3715") +INPUT_PORTS_END + +INPUT_CHANGED_MEMBER(isa8_epc_mda_device::monitor_changed) +{ + if ((m_io_monitor->read() & 1) == 1) + { + m_pal = &m_371x_pal; + } + else + { + m_pal = &m_3111_pal; + } +} + +ioport_constructor isa8_epc_mda_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( epc_mda ); +} diff --git a/src/devices/bus/isa/mda.h b/src/devices/bus/isa/mda.h index c8b259f1fb3..9b640fb3665 100644 --- a/src/devices/bus/isa/mda.h +++ b/src/devices/bus/isa/mda.h @@ -137,4 +137,85 @@ private: // device type definition DECLARE_DEVICE_TYPE(ISA8_EC1840_0002, isa8_ec1840_0002_device) +// ======================> isa8_epc_mda_device + +class isa8_epc_mda_device : + public isa8_mda_device +{ +public: + // construction/destruction + isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_READ8_MEMBER(io_read) override; + virtual DECLARE_WRITE8_MEMBER(io_write) override; + + /* Monitor */ + DECLARE_INPUT_CHANGED_MEMBER(monitor_changed); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + +private: + inline int get_xres(); + inline int get_yres(); + //virtual DECLARE_WRITE8_MEMBER(mode_control_w) override; + + enum { + VM_COLS80 = 0x01, + VM_GRAPH = 0x02, + VM_HOR640 = 0x04, + VM_MONO = 0x08, + VM_VER400 = 0x10 + }; + + enum { + MR1_COLS80 = 0x01, + MR1_GRAPH = 0x02, + MR1_VIDEO = 0x08, + MR1_HOR640 = 0x10, + MR1_BLINK = 0x20 + }; + + enum { + MR2_COLEMU = 0x04, + MR2_CHRSET = 0x40, + MR2_VER400 = 0x80 + }; + + enum { + ATTR_BLINK = 0x80, + ATTR_BACKG = 0x70, + ATTR_INTEN = 0x08, + ATTR_FOREG = 0x07, + ATTR_ULINE = 0x01, + }; + virtual MC6845_UPDATE_ROW( crtc_update_row ) override; + //MC6845_UPDATE_ROW( mda_lowres_text_inten_update_row ); + //MC6845_UPDATE_ROW( mda_lowres_text_blink_update_row ); + + std::unique_ptr m_soft_chr_gen; + required_ioport m_s1; + uint8_t m_color_mode; + uint8_t m_mode_control2; + required_device m_screen; + required_ioport m_io_monitor; + required_region_ptr m_chargen; + + uint8_t m_vmode; + rgb_t (*m_pal)[4]; + rgb_t m_3111_pal[4]; + rgb_t m_371x_pal[4]; + bool m_installed; +}; + +// device type definition +DECLARE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device) + #endif // MAME_BUS_ISA_MDA_H diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp index e0b6c0c2229..db180406b7c 100644 --- a/src/emu/xtal.cpp +++ b/src/emu/xtal.cpp @@ -259,6 +259,7 @@ const double XTAL::known_xtals[] = { 18'720'000, /* 18.72_MHz_XTAL Nokia MikroMikko 1 */ 18'867'000, /* 18.867_MHz_XTAL Decision Data IS-482 */ 18'869'600, /* 18.8696_MHz_XTAL Memorex 2178 */ + 19'170'000, /* Ericsson ISA8 Monochrome HR Graphics Board */ 19'339'600, /* 19.3396_MHz_XTAL TeleVideo TVI-955 80-column display clock */ 19'584'000, /* 19.584_MHz_XTAL ADM-42 */ 19'600'000, /* 19.6_MHz_XTAL Universal Mr. Do - Model 8021 PCB */ From 3245b9d3bac834814e6b4253c7b56cd63e6a023d Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Thu, 26 Sep 2019 22:57:33 +0200 Subject: [PATCH 08/12] Review comments fixed --- src/devices/bus/isa/mda.cpp | 54 +++++++++++++++++------------------ src/devices/bus/isa/mda.h | 1 + src/devices/video/mc6845.cpp | 1 - src/mame/machine/eispc_kb.cpp | 16 +++++------ src/mame/machine/eispc_kb.h | 2 +- 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/devices/bus/isa/mda.cpp b/src/devices/bus/isa/mda.cpp index d7f6625d75c..1f0cd0b6b11 100644 --- a/src/devices/bus/isa/mda.cpp +++ b/src/devices/bus/isa/mda.cpp @@ -96,7 +96,7 @@ static GFXDECODE_START( gfx_pcmda ) GFXDECODE_END -WRITE_LINE_MEMBER(isa8_mda_device::pc_cpu_line) +WRITE_LINE_MEMBER( isa8_mda_device::pc_cpu_line ) { m_isa->irq7_w(state); } @@ -453,7 +453,7 @@ WRITE8_MEMBER( isa8_mda_device::mode_control_w ) * 2-1 reserved * 0 horizontal drive enable */ -READ8_MEMBER( isa8_mda_device::status_r) +READ8_MEMBER( isa8_mda_device::status_r ) { // Faking pixel stream here m_pixel++; @@ -468,7 +468,7 @@ READ8_MEMBER( isa8_mda_device::status_r) * monochrome display adapter * *************************************************************************/ -WRITE8_MEMBER( isa8_mda_device::io_write) +WRITE8_MEMBER( isa8_mda_device::io_write ) { switch( offset ) { @@ -487,7 +487,7 @@ WRITE8_MEMBER( isa8_mda_device::io_write) } } -READ8_MEMBER( isa8_mda_device::io_read) +READ8_MEMBER( isa8_mda_device::io_read ) { int data = 0xff; switch( offset ) @@ -1125,15 +1125,15 @@ const tiny_rom_entry *isa8_epc_mda_device::device_rom_region() const //------------------------------------------------- isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - isa8_mda_device(mconfig, ISA8_EPC_MDA, tag, owner, clock) - , m_soft_chr_gen(nullptr) - , m_s1(*this, "S1") - , m_color_mode(0) - , m_mode_control2(0) - , m_screen(*this, EPC_MDA_SCREEN) - , m_io_monitor(*this, "MONITOR") - , m_chargen(*this, "chargen") - , m_installed(false) + isa8_mda_device(mconfig, ISA8_EPC_MDA, tag, owner, clock), + m_soft_chr_gen(nullptr), + m_s1(*this, "S1"), + m_color_mode(0), + m_mode_control2(0), + m_screen(*this, EPC_MDA_SCREEN), + m_io_monitor(*this, "MONITOR"), + m_chargen(*this, "chargen"), + m_installed(false) { } @@ -1164,6 +1164,7 @@ void isa8_epc_mda_device::device_start() m_videoram.resize(0x8000); set_isa_device(); m_installed = false; + m_hd6845s = subdevice(MC6845_NAME); } void isa8_epc_mda_device::device_reset() @@ -1204,19 +1205,18 @@ void isa8_epc_mda_device::device_reset() * Status Register 0x3ba 0x3da r CGA/MDA status reg (incompatible) * w EGA/VGA feature ccontrol reg (not used by this board) */ -WRITE8_MEMBER( isa8_epc_mda_device::io_write) +WRITE8_MEMBER(isa8_epc_mda_device::io_write ) { LOG("%s: %04x <- %02x\n", FUNCNAME, offset, data); - hd6845s_device *hd6845s = subdevice(MC6845_NAME); switch( offset ) { case 0x04: - //LOGSETUP(" - HD6845S address write\n"); - hd6845s->address_w( data ); + //LOGSETUP(" - HD6845S address write\n"); + m_hd6845s->address_w( data ); break; case 0x05: - //LOGSETUP(" - HD6845S register write\n"); - hd6845s->register_w( data ); + //LOGSETUP(" - HD6845S register write\n"); + m_hd6845s->register_w( data ); break; case 0x08: // Mode 1 reg LOGMODE(" - Mode register 1 write: %02x\n", data); @@ -1254,15 +1254,13 @@ WRITE8_MEMBER( isa8_epc_mda_device::io_write) break; default: LOG("EPC MDA: io_write at wrong offset:%02x\n", offset); - logerror("EPC MDA: io_write at wrong offset:%02x\n", offset); } } -READ8_MEMBER( isa8_epc_mda_device::io_read) +READ8_MEMBER( isa8_epc_mda_device::io_read ) { LOG("%s: %04x <- ???\n", FUNCNAME, offset); int data = 0xff; - hd6845s_device *hd6845s = subdevice(MC6845_NAME); switch( offset ) { case 0x04: @@ -1270,7 +1268,7 @@ READ8_MEMBER( isa8_epc_mda_device::io_read) break; case 0x05: LOGR(" - hd6845s register read\n"); - data = hd6845s->register_r(); + data = m_hd6845s->register_r(); break; case 0x08: // Mode 1 reg data = m_mode_control; @@ -1302,7 +1300,7 @@ inline int isa8_epc_mda_device::get_yres() return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_VER400) ? 400 : 200 ) : 400; } -MC6845_UPDATE_ROW( isa8_epc_mda_device::crtc_update_row ) +MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) { uint32_t *p = &bitmap.pix32(y); uint16_t chr_base = ra; @@ -1458,19 +1456,19 @@ MC6845_UPDATE_ROW( isa8_epc_mda_device::crtc_update_row ) // Port definitions //-------------------------------------------------------------------- static INPUT_PORTS_START( epc_mda ) - PORT_START("S1") + PORT_START( "S1" ) PORT_DIPNAME( 0x01, 0x00, "Color emulation") PORT_DIPLOCATION("S1:1") PORT_DIPSETTING( 0x00, "Disabled" ) PORT_DIPSETTING( 0x01, "Enabled" ) PORT_DIPUNUSED_DIPLOC(0x02, 0x02, "S1:2") - PORT_START("MONITOR") - PORT_CONFNAME( 0x01, 0x00, "Ericsson Monochrome HR Monitors") PORT_CHANGED_MEMBER(DEVICE_SELF, isa8_epc_mda_device, monitor_changed, 0) + PORT_START( "MONITOR" ) + PORT_CONFNAME( 0x01, 0x00, "Ericsson Monochrome HR Monitors") PORT_CHANGED_MEMBER( DEVICE_SELF, isa8_epc_mda_device, monitor_changed, 0 ) PORT_CONFSETTING( 0x00, "Amber 3111") PORT_CONFSETTING( 0x01, "B&W 3712/3715") INPUT_PORTS_END -INPUT_CHANGED_MEMBER(isa8_epc_mda_device::monitor_changed) +INPUT_CHANGED_MEMBER( isa8_epc_mda_device::monitor_changed ) { if ((m_io_monitor->read() & 1) == 1) { diff --git a/src/devices/bus/isa/mda.h b/src/devices/bus/isa/mda.h index 9b640fb3665..9959f3a6094 100644 --- a/src/devices/bus/isa/mda.h +++ b/src/devices/bus/isa/mda.h @@ -213,6 +213,7 @@ private: rgb_t m_3111_pal[4]; rgb_t m_371x_pal[4]; bool m_installed; + hd6845s_device *m_hd6845s; }; // device type definition diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index cef7b7d036e..4ce9ed843a3 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -1243,7 +1243,6 @@ void mc6845_device::device_start() save_item(NAME(m_line_address)); save_item(NAME(m_cursor_x)); save_item(NAME(m_has_valid_parameters)); - save_item(NAME(m_display_disabled_msg_shown)); } diff --git a/src/mame/machine/eispc_kb.cpp b/src/mame/machine/eispc_kb.cpp index cac16464e82..5f8a2e76e2f 100644 --- a/src/mame/machine/eispc_kb.cpp +++ b/src/mame/machine/eispc_kb.cpp @@ -260,25 +260,25 @@ eispc_keyboard_device::eispc_keyboard_device( INPUT_CHANGED_MEMBER( eispc_keyboard_device::key ) { - if (oldval && !newval) + if (oldval && !newval) { LOGUI("Key Pressed - name: %s field: %04x param: %04x oldval: %04x newval: %04x\n", field.name(), field.defvalue(), param, oldval, newval); int idx = *((int *)(¶m)); - if (idx >= sizeof(keys)) + if (idx >= ARRAY_LENGTH(m_keys)) logerror("Out of bounds access in keys array\n"); else - keys[idx] |= (uint16_t) field.defvalue(); + m_keys[idx] |= (uint16_t) field.defvalue(); } else if (newval && !oldval) { LOGUI("Key Released - name: %s field: %04x param: %04x oldval: %04x newval: %04x\n", field.name(), field.defvalue(), param, oldval, newval); int idx = *((int *)(¶m)); - if (idx >= sizeof(keys)) + if (idx >= ARRAY_LENGTH(m_keys)) logerror("Out of bounds access in keys array\n"); else - keys[idx] &= ~(uint16_t)field.defvalue(); + m_keys[idx] &= ~(uint16_t)field.defvalue(); } - for (int i = 0; i < 6; i++) LOGUI("%04x ", keys[i]); LOGUI("\n"); + for (int i = 0; i < 6; i++) LOGUI("%04x ", m_keys[i]); LOGUI("\n"); } WRITE_LINE_MEMBER(eispc_keyboard_device::rxd_w) @@ -315,7 +315,7 @@ void eispc_keyboard_device::device_reset() { LOGRST("KBD: Keyboard is in reset until host computer explicitly releases the reset line\n"); m_mcu->suspend(SUSPEND_REASON_RESET, 0); - for (auto & elem : keys) elem = 0; + for (auto & elem : m_keys) elem = 0; } @@ -351,7 +351,7 @@ void eispc_keyboard_device::device_add_mconfig(machine_config &config) { uint8_t data = 0; // Indicate what keys are pressed in selected column - for (int i = 0; i < 6; i++) data |= (keys[i] & m_col_select ? 1 << i : 0); + for (int i = 0; i < 6; i++) data |= (m_keys[i] & m_col_select ? 1 << i : 0); // Update txd bit data &= 0x3f; diff --git a/src/mame/machine/eispc_kb.h b/src/mame/machine/eispc_kb.h index 66547409a47..aec7ee2a170 100644 --- a/src/mame/machine/eispc_kb.h +++ b/src/mame/machine/eispc_kb.h @@ -36,7 +36,7 @@ protected: bool m_txd_high; // state of Tx output line bool m_hold; uint16_t m_col_select; - uint16_t keys[6]; + uint16_t m_keys[6]; uint8_t m_p1; void eispc_kb_mem(address_map &map); From 5dc9cca08d7d92f2ad00d55b1fa36c683f6cc454 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Sun, 29 Sep 2019 22:05:52 +0200 Subject: [PATCH 09/12] eispc_kb.cpp: experiment with removing direct calls to resume/suspend --- src/devices/bus/isa/mda.cpp | 8 +------- src/mame/machine/eispc_kb.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/devices/bus/isa/mda.cpp b/src/devices/bus/isa/mda.cpp index 1f0cd0b6b11..f660b48a1dd 100644 --- a/src/devices/bus/isa/mda.cpp +++ b/src/devices/bus/isa/mda.cpp @@ -1060,13 +1060,7 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::crtc_update_row ) Trivia: https://www.pinterest.se/pin/203084264425177097/ */ -#define EPC_MDA_SCREEN "epc_mda_screen" - -#if 0 -static GFXDECODE_START( pcepc ) - GFXDECODE_ENTRY( "gfx1", 0x0000, pc_16_charlayout, 1, 1 ) -GFXDECODE_END -#endif +#define EPC_MDA_SCREEN "epc_mda_screen" // TODO: use a device finder reference instead ROM_START( epc ) ROM_REGION(0x2000,"chargen", 0) diff --git a/src/mame/machine/eispc_kb.cpp b/src/mame/machine/eispc_kb.cpp index 5f8a2e76e2f..a1ac3a64626 100644 --- a/src/mame/machine/eispc_kb.cpp +++ b/src/mame/machine/eispc_kb.cpp @@ -297,11 +297,14 @@ WRITE_LINE_MEMBER(eispc_keyboard_device::rst_line_w) if (state == CLEAR_LINE) { m_mcu->resume(SUSPEND_REASON_RESET); + //m_mcu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); LOGRST("KBD: Keyboard mcu reset line is cleared\n"); } else { - m_mcu->suspend(SUSPEND_REASON_RESET, 0); + // set_input_line suspends with a true argument which causes "Keyboard error" + m_mcu->suspend(SUSPEND_REASON_RESET, false); + //m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); LOGRST("KBD: Keyboard mcu reset line is asserted\n"); } @@ -313,8 +316,6 @@ WRITE_LINE_MEMBER(eispc_keyboard_device::rst_line_w) void eispc_keyboard_device::device_reset() { - LOGRST("KBD: Keyboard is in reset until host computer explicitly releases the reset line\n"); - m_mcu->suspend(SUSPEND_REASON_RESET, 0); for (auto & elem : m_keys) elem = 0; } From 0e6638a6a4ab7d447de3a5ca5b3050ca61c7c43b Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Tue, 1 Oct 2019 23:07:33 +0200 Subject: [PATCH 10/12] eispc_kb: Simplification, removed port changed handler and internal state of keyboard --- src/mame/machine/eispc_kb.cpp | 231 +++++++++++++++------------------- src/mame/machine/eispc_kb.h | 4 +- 2 files changed, 99 insertions(+), 136 deletions(-) diff --git a/src/mame/machine/eispc_kb.cpp b/src/mame/machine/eispc_kb.cpp index a1ac3a64626..63d21058550 100644 --- a/src/mame/machine/eispc_kb.cpp +++ b/src/mame/machine/eispc_kb.cpp @@ -27,7 +27,7 @@ Tx/Hold is bidirectional, connected to the TX line of the SCI in the MCU, P24 bit 4 of port 2, but can also be kept low by the host CPU to temporarily inhibit the keyboard from sending more scan codes. This is sensed by P16 through a - 74HC04 inverter. + 74HC04 inverter. The keyboard is specified to be able to buffer up to 20 scan codes. The data is exchanged in both direction asynchronously at 1200 baud, 8 databits, 1 start and 1 stop bit. At startup the host CPU sends a $00 (zero) byte to the @@ -102,118 +102,116 @@ #define M6801_TAG "mcu" -#define PCM(handler, parameter) PORT_CHANGED_MEMBER(DEVICE_SELF, eispc_keyboard_device, handler, parameter) - namespace { INPUT_PORTS_START(eispc_kb) PORT_START("P15") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR('6') PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PCM(key, 0) // 77 - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') PCM(key, 0) // 78 - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') PCM(key, 0) // 76 - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("* PRINT") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('*') PORT_CHAR(UCHAR_MAMEKEY(PRTSCR)) PCM(key, 0) // 55 - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("R Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PCM(key, 0) // 54 - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PCM(key, 0) // 53 - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(". :") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') PCM(key, 0) // 52 - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PCM(key, 0) // 63 - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PCM(key, 0) // 64 - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 0) // no scancode is sent - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PCM(key, 0) // 29 - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(", ;") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') PCM(key, 0) // 51 - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') PCM(key, 0) // 32 - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') PCM(key, 0) // 45 - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') PCM(key, 0) // 46 - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') PCM(key, 0) // 36 + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR('6') PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) // 77 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') // 78 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') // 76 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("* PRINT") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('*') PORT_CHAR(UCHAR_MAMEKEY(PRTSCR)) // 55 + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("R Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // 54 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') // 53 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(". :") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') // 52 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) // 63 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) // 64 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED ) // no scancode is sent + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) // 29 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(", ;") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') // 51 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') // 32 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') // 45 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') // 46 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') // 36 PORT_START("P14") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 1) // 00 - keyboard error - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_PAUSE) PORT_CHAR(UCHAR_MAMEKEY(PAUSE)) PCM(key, 1) // 70 - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') PORT_CHAR(UCHAR_MAMEKEY(HOME)) PCM(key, 1) // 71 - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 1) // ff - keyboard error - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(']') PCM(key, 1) // 27 - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00e5) PORT_CHAR(0x00c5) PORT_CHAR('[') PCM(key, 1) // 26 å Å - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PCM(key, 1) // 25 - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PCM(key, 1) // 59 - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PCM(key, 1) // 60 - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PCM(key, 1) // 17 - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PCM(key, 1) // 18 - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PCM(key, 1) // 24 - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PCM(key, 1) // 19 - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PCM(key, 1) // 20 - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PCM(key, 1) // 21 - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PCM(key, 1) // 23 + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED ) // 00 - keyboard error + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_PAUSE) PORT_CHAR(UCHAR_MAMEKEY(PAUSE)) // 70 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') PORT_CHAR(UCHAR_MAMEKEY(HOME)) // 71 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) // ff - keyboard error + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(']') // 27 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(0x00e5) PORT_CHAR(0x00c5) PORT_CHAR('[') // 26 å Å + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') // 25 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) // 59 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) // 60 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') // 17 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') // 18 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') // 24 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') // 19 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') // 20 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') // 21 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') // 23 PORT_START("P13") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) PCM(key, 2) // 69 - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 2) // ff - keyboard error - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(DEL)) PCM(key, 2) // 14 - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PCM(key, 2) // 13 - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PCM(key, 2) // 12 - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PCM(key, 2) // 11 - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PCM(key, 2) // 10 - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PCM(key, 2) // 02 - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PCM(key, 2) // 01 - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') PCM(key, 2) // 03 - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PCM(key, 2) // 04 - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PCM(key, 2) // 09 - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PCM(key, 2) // 05 - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PCM(key, 2) // 06 - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') PCM(key, 2) // 07 - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') PCM(key, 2) // 08 + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) // 69 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) // ff - keyboard error + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(DEL)) // 14 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') // 13 + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') // 12 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') // 11 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') // 10 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') // 02 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) // 01 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') // 03 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') // 04 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') // 09 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') // 05 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') // 06 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') // 07 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') // 08 PORT_START("P12") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PCM(key, 3) // 73 - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PCM(key, 3) // 74 - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP) PORT_CHAR('8') PORT_CHAR(UCHAR_MAMEKEY(UP)) PCM(key, 3) // 72 - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') PCM(key, 3) // 41 - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') PCM(key, 3) // 40 - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PCM(key, 3) // 39 - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PCM(key, 3) // 38 - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PCM(key, 3) // 61 - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PCM(key, 3) // 62 - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PCM(key, 3) // 16 - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) PCM(key, 3) // 15 - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PCM(key, 3) // 37 - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PCM(key, 3) // 33 - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PCM(key, 3) // 34 - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PCM(key, 3) // 35 - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PCM(key, 3) // 22 + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') PORT_CHAR(UCHAR_MAMEKEY(PGUP)) // 73 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) // 74 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP) PORT_CHAR('8') PORT_CHAR(UCHAR_MAMEKEY(UP)) // 72 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') // 41 + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') // 40 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') // 39 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') // 38 + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) // 61 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) // 62 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') // 16 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) // 15 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') // 37 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') // 33 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') // 34 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') // 35 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') // 22 PORT_START("P11") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PCM(key, 4) // 83 - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PCM(key, 4) // 28 - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PCM(key, 4) // 82 - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 89 - no key - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 86 - no key - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 87 - no key - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 88 - no key - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PCM(key, 4) // 67 - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PCM(key, 4) // 68 - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // scan code ff - keyboard error - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PCM(key, 4) // 43 - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PCM(key, 4) // 58 - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_LALT) PCM(key, 4) // 56 - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 4) // 85 - no key - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PCM(key, 4) // 47 - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PCM(key, 4) // 57 + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) // 83 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) // 28 + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') PORT_CHAR(UCHAR_MAMEKEY(INSERT)) // 82 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) // 89 - no key + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED ) // 86 - no key + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED ) // 87 - no key + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) // 88 - no key + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) // 67 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) // 68 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED ) // scan code ff - keyboard error + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') // 43 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) // 58 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_LALT) // 56 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED ) // 85 - no key + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') // 47 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') // 57 PORT_START("P10") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN) PCM(key, 5) // 81 - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 5) // ff - keyboard error - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PCM(key, 5) // 80 - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW LINE") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PCM(key, 5) // 84 (programmable, default is 28) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PCM(key, 5) // 79 - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR('4') PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PCM(key, 5) // 75 - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) PCM(key, 5) // ff - keyboard error - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PCM(key, 5) // 65 - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PCM(key, 5) // 66 - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PCM(key, 5) // 42 - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PCM(key, 5) // 44 - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PCM(key, 5) // 50 - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PCM(key, 5) // 30 - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PCM(key, 5) // 31 - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PCM(key, 5) // 48 - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PCM(key, 5) // 49 + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN) // 81 + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) // ff - keyboard error + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) // 80 + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW LINE") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) // 84 (programmable, default is 28) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) // 79 + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR('4') PORT_CHAR(UCHAR_MAMEKEY(LEFT)) // 75 + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) // ff - keyboard error + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) // 65 + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) // 66 + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // 42 + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') // 44 + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') // 50 + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') // 30 + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') // 31 + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') // 48 + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') // 49 INPUT_PORTS_END @@ -258,29 +256,6 @@ eispc_keyboard_device::eispc_keyboard_device( { } -INPUT_CHANGED_MEMBER( eispc_keyboard_device::key ) -{ - if (oldval && !newval) - { - LOGUI("Key Pressed - name: %s field: %04x param: %04x oldval: %04x newval: %04x\n", field.name(), field.defvalue(), param, oldval, newval); - int idx = *((int *)(¶m)); - if (idx >= ARRAY_LENGTH(m_keys)) - logerror("Out of bounds access in keys array\n"); - else - m_keys[idx] |= (uint16_t) field.defvalue(); - } - else if (newval && !oldval) - { - LOGUI("Key Released - name: %s field: %04x param: %04x oldval: %04x newval: %04x\n", field.name(), field.defvalue(), param, oldval, newval); - int idx = *((int *)(¶m)); - if (idx >= ARRAY_LENGTH(m_keys)) - logerror("Out of bounds access in keys array\n"); - else - m_keys[idx] &= ~(uint16_t)field.defvalue(); - } - for (int i = 0; i < 6; i++) LOGUI("%04x ", m_keys[i]); LOGUI("\n"); -} - WRITE_LINE_MEMBER(eispc_keyboard_device::rxd_w) { LOGBITS("KBD bit presented: %d\n", state); @@ -310,16 +285,6 @@ WRITE_LINE_MEMBER(eispc_keyboard_device::rst_line_w) } -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void eispc_keyboard_device::device_reset() -{ - for (auto & elem : m_keys) elem = 0; -} - - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -352,7 +317,7 @@ void eispc_keyboard_device::device_add_mconfig(machine_config &config) { uint8_t data = 0; // Indicate what keys are pressed in selected column - for (int i = 0; i < 6; i++) data |= (m_keys[i] & m_col_select ? 1 << i : 0); + for (int i = 0; i < 6; i++) data |= ( (~m_rows[i]->read() & m_col_select) ? 0x20 >> i : 0 ); // Update txd bit data &= 0x3f; diff --git a/src/mame/machine/eispc_kb.h b/src/mame/machine/eispc_kb.h index aec7ee2a170..eb582262f23 100644 --- a/src/mame/machine/eispc_kb.h +++ b/src/mame/machine/eispc_kb.h @@ -23,20 +23,18 @@ public: protected: virtual void device_start() override; - virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; virtual tiny_rom_entry const *device_rom_region() const override; required_device m_mcu; required_ioport_array<6> m_rows; - devcb_write_line m_txd_cb; // Callback for KBD-> EPC + devcb_write_line m_txd_cb; // Callback for KBD-> EPC bool m_rxd_high; // state of Rx input line bool m_txd_high; // state of Tx output line bool m_hold; uint16_t m_col_select; - uint16_t m_keys[6]; uint8_t m_p1; void eispc_kb_mem(address_map &map); From 05ed4e2497e28a6bb51ddcc87633991827872305 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Mon, 7 Oct 2019 20:06:35 +0200 Subject: [PATCH 11/12] eispc.cpp: Fixed indention and added some TODO:s --- src/mame/drivers/eispc.cpp | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/mame/drivers/eispc.cpp b/src/mame/drivers/eispc.cpp index f8e051badc4..f0d593f5cd6 100644 --- a/src/mame/drivers/eispc.cpp +++ b/src/mame/drivers/eispc.cpp @@ -825,11 +825,11 @@ void epc_state::epc(machine_config &config) FLOPPY_CONNECTOR(config, m_floppy_connectors[1], epc_sd_floppies, "525sd", epc_floppy_formats); //SOFTWARE_LIST(config, "epc_flop_list").set_original("epc_flop"); - // system board UART + // system board UART TODO: Implement the descrete "Baud Rate Clock" from schematics that generates clocks for the 8250 INS8250(config, m_uart, XTAL(18'432'000) / 10); // TEW crystal marked X2 verified. TODO: Let 8051 DTR control RCLK (see above) - m_uart->out_tx_callback().set("uart", FUNC(rs232_port_device::write_txd)); - m_uart->out_dtr_callback().set("uart", FUNC(rs232_port_device::write_dtr)); - m_uart->out_rts_callback().set("uart", FUNC(rs232_port_device::write_rts)); + m_uart->out_tx_callback().set("uart", FUNC(rs232_port_device::write_txd)); + m_uart->out_dtr_callback().set("uart", FUNC(rs232_port_device::write_dtr)); + m_uart->out_rts_callback().set("uart", FUNC(rs232_port_device::write_rts)); m_uart->out_int_callback().set([this](int state) { // Jumper field J10 decides what IRQ to pull if ((m_io_j10->read() & 0x03) == 0x02) { LOGIRQ("UART IRQ2: %d\n", state); m_pic8259->ir2_w(state); } @@ -838,15 +838,12 @@ void epc_state::epc(machine_config &config) if ((m_io_j10->read() & 0xc0) == 0x80) { LOGIRQ("UART IRQ7: %d\n", state); m_pic8259->ir7_w(state); } }); - rs232_port_device &rs232(RS232_PORT(config, "uart", default_rs232_devices, nullptr)); - rs232.rxd_handler().set(m_uart, FUNC(ins8250_uart_device::rx_w)); - rs232.dcd_handler().set(m_uart, FUNC(ins8250_uart_device::dcd_w)); - rs232.dsr_handler().set(m_uart, FUNC(ins8250_uart_device::dsr_w)); - rs232.ri_handler().set(m_uart, FUNC(ins8250_uart_device::ri_w)); - rs232.cts_handler().set(m_uart, FUNC(ins8250_uart_device::cts_w)); - - - + rs232_port_device &rs232(RS232_PORT(config, "uart", default_rs232_devices, nullptr)); + rs232.rxd_handler().set(m_uart, FUNC(ins8250_uart_device::rx_w)); + rs232.dcd_handler().set(m_uart, FUNC(ins8250_uart_device::dcd_w)); + rs232.dsr_handler().set(m_uart, FUNC(ins8250_uart_device::dsr_w)); + rs232.ri_handler().set(m_uart, FUNC(ins8250_uart_device::ri_w)); + rs232.cts_handler().set(m_uart, FUNC(ins8250_uart_device::cts_w)); } void epc_state::update_nmi() @@ -949,7 +946,7 @@ INPUT_PORTS_END ROM_START( epc ) ROM_REGION(0x10000,"bios", 0) ROM_DEFAULT_BIOS("p860110") - ROM_SYSTEM_BIOS(0, "p840705", "P840705") + ROM_SYSTEM_BIOS(0, "p840705", "P840705") // TODO: Fix "Keyboard error" for this bios ROMX_LOAD("ericsson_8088.bin", 0xe000, 0x2000, CRC(3953c38d) SHA1(2bfc1f1d11d0da5664c3114994fc7aa3d6dd010d), ROM_BIOS(0)) ROM_SYSTEM_BIOS(1, "p860110", "P860110") ROMX_LOAD("epcbios1.bin", 0xe000, 0x02000, CRC(79a83706) SHA1(33528c46a24d7f65ef5a860fbed05afcf797fc55), ROM_BIOS(1)) From 7261e08a8b7574510e76568557b470fa72205019 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Mon, 7 Oct 2019 20:07:24 +0200 Subject: [PATCH 12/12] pit8253.cpp: Fixed some log messages --- src/devices/machine/pit8253.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/machine/pit8253.cpp b/src/devices/machine/pit8253.cpp index 06afd19e931..ddf63ff00fb 100644 --- a/src/devices/machine/pit8253.cpp +++ b/src/devices/machine/pit8253.cpp @@ -311,7 +311,7 @@ void pit_counter_device::simulate(int64_t elapsed_cycles) static const uint32_t CYCLES_NEVER = (0xffffffff); uint32_t cycles_to_output = 0; - LOG2("simulate2(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x\n", + LOG2("simulate(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x\n", (int)elapsed_cycles, mode, bcd, m_phase, m_gate, m_output, m_value); switch (mode) @@ -694,7 +694,7 @@ void pit_counter_device::simulate(int64_t elapsed_cycles) m_updatetimer->adjust(next_fire_time - machine().time()); } - LOG2("simulate2(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x, cycles_to_output = %04x\n", + LOG2("simulate(): simulating %d cycles in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x, cycles_to_output = %04x\n", (int)elapsed_cycles, mode, bcd, m_phase, m_gate, m_output, m_value, cycles_to_output); }