From 736962d5e71c467e7563a47f38e4987dc3eb6090 Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 29 Oct 2019 15:43:32 -0400 Subject: mk68564: Emulate BRG; fix cut-and-paste error in pinout (nw) --- src/devices/machine/z80sio.cpp | 64 +++++++++++++++++++++++++++++++++++------- src/devices/machine/z80sio.h | 14 +++++++-- src/mame/drivers/msbc1.cpp | 4 +-- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/devices/machine/z80sio.cpp b/src/devices/machine/z80sio.cpp index 9b259c5c824..fe3e3dc016b 100644 --- a/src/devices/machine/z80sio.cpp +++ b/src/devices/machine/z80sio.cpp @@ -78,6 +78,7 @@ #define LOG_SYNC (1U << 9) #define LOG_BIT (1U << 10) #define LOG_RTS (1U << 11) +#define LOG_BRG (1U << 12) //#define VERBOSE (LOG_CMD | LOG_SETUP | LOG_SYNC | LOG_BIT | LOG_TX ) //#define LOG_OUTPUT_STREAM std::cout @@ -95,6 +96,7 @@ #define LOGDCD(...) LOGMASKED(LOG_DCD, __VA_ARGS__) #define LOGSYNC(...) LOGMASKED(LOG_SYNC, __VA_ARGS__) #define LOGBIT(...) LOGMASKED(LOG_BIT, __VA_ARGS__) +#define LOGBRG(...) LOGMASKED(LOG_BRG, __VA_ARGS__) #ifdef _MSC_VER #define FUNCNAME __func__ @@ -979,6 +981,8 @@ mk68564_channel::mk68564_channel(const machine_config &mconfig, const char *tag, , m_tx_auto_enable(false) , m_brg_tc(0) , m_brg_control(0) + , m_brg_state(false) + , m_brg_timer(nullptr) { } @@ -1055,9 +1059,12 @@ void mk68564_channel::device_start() { z80sio_channel::device_start(); + m_brg_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mk68564_channel::brg_timeout), this)); + save_item(NAME(m_tx_auto_enable)); save_item(NAME(m_brg_tc)); save_item(NAME(m_brg_control)); + save_item(NAME(m_brg_state)); } @@ -1117,6 +1124,8 @@ void mk68564_channel::device_reset() m_tx_auto_enable = false; m_brg_tc = 0; m_brg_control = 0; + m_brg_state = false; + m_brg_timer->adjust(attotime::never); } bool z80sio_channel::is_tx_idle() const @@ -2758,7 +2767,6 @@ uint8_t mk68564_channel::tcreg_r() //------------------------------------------------- void mk68564_channel::tcreg_w(uint8_t data) { - logerror("Time constant = %d\n", data); m_brg_tc = data; } @@ -2769,7 +2777,8 @@ void mk68564_channel::tcreg_w(uint8_t data) //------------------------------------------------- uint8_t mk68564_channel::brgctl_r() { - return m_brg_control; + // unused bits are all zero + return m_brg_control & 0x0f; } @@ -2779,15 +2788,20 @@ uint8_t mk68564_channel::brgctl_r() //------------------------------------------------- void mk68564_channel::brgctl_w(uint8_t data) { - // TODO: actually emulate this - logerror("BRG %sabled, divide by %d, RxC %sternal, TxC %sternal\n", - BIT(data, 0) ? "en" : "dis", - BIT(data, 1) ? 64 : 4, - BIT(data, 2) ? "in" : "ex", - BIT(data, 3) ? "in" : "ex"); + if (BIT(data, 0)) + LOGBRG("%s: BRG enabled, divide by %d, RxC %sternal, TxC %sternal (TC = %d, %.1f Hz)\n", + machine().describe_context(), + BIT(data, 1) ? 64 : 4, + BIT(data, 2) ? "in" : "ex", + BIT(data, 3) ? "in" : "ex", + m_brg_tc, + clocks_to_attotime((m_brg_tc ? m_brg_tc : 256) * (BIT(data, 1) ? 64 : 4)).as_hz()); + else + LOGBRG("%s: BRG disabled\n", machine().describe_context()); - // unused bits are always zero m_brg_control = data & 0x0f; + m_brg_state = false; + brg_update(); } @@ -2909,7 +2923,37 @@ void mk68564_device::write(offs_t offset, uint8_t data) break; default: - LOG("Write %02X to unused/read-only register %02X\n", data, offset & 0x1f); + logerror("Write %02X to unused/read-only register %02X\n", data, offset & 0x1f); break; } } + +//************************************************************************** +// MK68564 BAUD RATE GENERATOR +//************************************************************************** + +void mk68564_device::set_xtal(uint32_t clock) +{ + assert(!configured()); + subdevice(CHANA_TAG)->set_clock(clock); + subdevice(CHANB_TAG)->set_clock(clock); +} + +void mk68564_channel::brg_update() +{ + if (BIT(m_brg_control, 2)) + rxc_w(m_brg_state); + if (BIT(m_brg_control, 3)) + txc_w(m_brg_state); + + if (BIT(m_brg_control, 0)) + m_brg_timer->adjust(clocks_to_attotime((m_brg_tc ? m_brg_tc : 256) * (BIT(m_brg_control, 1) ? 32 : 2))); + else + m_brg_timer->adjust(attotime::never); +} + +TIMER_CALLBACK_MEMBER(mk68564_channel::brg_timeout) +{ + m_brg_state = !m_brg_state; + brg_update(); +} diff --git a/src/devices/machine/z80sio.h b/src/devices/machine/z80sio.h index df1044ef6f8..0f73998aa05 100644 --- a/src/devices/machine/z80sio.h +++ b/src/devices/machine/z80sio.h @@ -55,9 +55,9 @@ D5 3| |46 D4 D7 4| |45 D6 _INTR 5| |44 R/_W - IEO 6| |43 _IACK - IEI 7| |42 _DTACK - _M1 8| |41 _CS + CLK 6| |43 _IACK + XTAL1 7| |42 _DTACK + XTAL2 8| |41 _CS _RESET 9| |40 _RxRDYB _RxRDYA 10| |39 _TxRDYB _TxRDYA 11| DIP48 |38 GND @@ -365,9 +365,14 @@ private: uint8_t brgctl_r(); void brgctl_w(uint8_t data); + void brg_update(); + TIMER_CALLBACK_MEMBER(brg_timeout); + bool m_tx_auto_enable; uint8_t m_brg_tc; uint8_t m_brg_control; + bool m_brg_state; + emu_timer *m_brg_timer; }; @@ -515,6 +520,9 @@ class mk68564_device : public i8274_new_device public: mk68564_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void set_xtal(uint32_t clock); + void set_xtal(const XTAL &clock) { set_xtal(clock.value()); } + uint8_t read(offs_t offset); void write(offs_t offset, uint8_t data); diff --git a/src/mame/drivers/msbc1.cpp b/src/mame/drivers/msbc1.cpp index b8225d552d6..958e2bbd4f7 100644 --- a/src/mame/drivers/msbc1.cpp +++ b/src/mame/drivers/msbc1.cpp @@ -102,8 +102,8 @@ void msbc1_state::msbc1(machine_config &config) M68000(config, m_maincpu, 12.5_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &msbc1_state::msbc1_mem); - MK68564(config, "sio1", 3.6864_MHz_XTAL); - MK68564(config, "sio2", 3.6864_MHz_XTAL); + MK68564(config, "sio1", 8_MHz_XTAL / 2).set_xtal(3.6864_MHz_XTAL); + MK68564(config, "sio2", 8_MHz_XTAL / 2).set_xtal(3.6864_MHz_XTAL); } /* ROM definition */ -- cgit v1.2.3