diff options
-rw-r--r-- | scripts/src/machine.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | src/devices/machine/mb89374.cpp | 617 | ||||
-rw-r--r-- | src/devices/machine/mb89374.h | 170 | ||||
-rw-r--r-- | src/mame/drivers/model1.cpp | 61 | ||||
-rw-r--r-- | src/mame/includes/model1.h | 4 | ||||
-rw-r--r-- | src/mame/machine/m1comm.cpp | 130 | ||||
-rw-r--r-- | src/mame/machine/m1comm.h | 61 |
8 files changed, 947 insertions, 109 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index fc21510f620..120c158a560 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -1660,6 +1660,18 @@ end --------------------------------------------------- -- +--@src/devices/machine/mb89374.h,MACHINES["MB89374"] = true +--------------------------------------------------- + +if (MACHINES["MB89374"]~=null) then + files { + MAME_DIR .. "src/devices/machine/mb89374.cpp", + MAME_DIR .. "src/devices/machine/mb89374.h", + } +end + +--------------------------------------------------- +-- --@src/devices/machine/mc146818.h,MACHINES["MC146818"] = true --------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 94ce17252dd..1c2af45b3bf 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -480,6 +480,7 @@ MACHINES["MB87078"] = true --MACHINES["MB8795"] = true MACHINES["MB89352"] = true MACHINES["MB89371"] = true +MACHINES["MB89374"] = true --MACHINES["MC14411"] = true MACHINES["MC146818"] = true MACHINES["MC2661"] = true diff --git a/src/devices/machine/mb89374.cpp b/src/devices/machine/mb89374.cpp new file mode 100644 index 00000000000..f1950c16fb4 --- /dev/null +++ b/src/devices/machine/mb89374.cpp @@ -0,0 +1,617 @@ +// license:BSD-3-Clause +// copyright-holders:Ariane Fugmann +/** + MB89374 + + Fujitsu + Data Link Controller + + **/ + +#include "emu.h" +#include "mb89374.h" +#include "emuopts.h" + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(MB89374, mb89374_device, "mb89374", "MB89374 Data Link Controller") + + +enum +{ + REGISTER_SMR0 = 0x00, + REGISTER_SMR1, + REGISTER_SMR2, + REGISTER_CHRR0, + REGISTER_CHRR1, + + REGISTER_MSR = 0x06, + REGISTER_MCR, + REGISTER_RXSR0, + REGISTER_RXSR1, + REGISTER_RXCR, + REGISTER_RXIER, + REGISTER_TXSR, + REGISTER_TXCR, + REGISTER_TXIER, + REGISTER_SDR, + REGISTER_TXBCR0, + REGISTER_TXBCR1, + REGISTER_TXFR0, + REGISTER_TXFR1, + REGISTER_SMR3, + REGISTER_PORTR, + REGISTER_REQR, + REGISTER_MASKR, + REGISTER_B1PSR, + REGISTER_B1PCR, + REGISTER_BG1DR, + + REGISTER_B2SR = 0x1c, + REGISTER_B2CR, + REGISTER_BG2DR +}; + +#define SMR0_MASK 0xf0 + +#define SMR1_MASK 0xe3 + +#define MSR_MASK 0x80 + +#define MCR_MASK 0x14 + +#define RXSR1_MASK 0x08 + +#define RXCR_MASK 0x7c +#define RXCR_HUNT BIT(m_rxcr, 1) +#define RXCR_RXE BIT(m_rxcr, 7) + +#define RXIER_RXDI BIT(m_rxier, 7) + +#define TXSR_MASK 0x60 +#define TXSR_TXRDY BIT(m_txsr, 0) +#define TXSR_TXEND BIT(m_txsr, 4) + +#define TXCR_TXRST BIT(m_txcr, 3) +#define TXCR_TXE BIT(m_txcr, 7) + +#define TXIER_MASK 0x60 +#define TXIER_TXDI BIT(m_txier, 7) + +#define TXFR1_MASK 0x70 + +#define SMR3_MASK 0x80 + +#define REQR_MASK 0x38 + +#define MASKR_MASK 0x38 +#define MASKR_MRXDRQ BIT(m_maskr, 6) +#define MASKR_MTXDRQ BIT(m_maskr, 7) + +#define B1PSR_MASK 0xfc + +#define B2SR_MASK 0xfe + +//------------------------------------------------- +// mb89374_device - constructor +//------------------------------------------------- + +mb89374_device::mb89374_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) + : device_t(mconfig, MB89374, tag, owner, clock), + device_execute_interface(mconfig, *this), + m_icount(0), + m_out_irq_cb(*this), + m_out_po_cb{ { *this }, { *this }, { *this }, { *this } } +{ + // prepare localhost "filename" + m_localhost[0] = 0; + strcat(m_localhost, "socket."); + strcat(m_localhost, mconfig.options().comm_localhost()); + strcat(m_localhost, ":"); + strcat(m_localhost, mconfig.options().comm_localport()); + + // prepare remotehost "filename" + m_remotehost[0] = 0; + strcat(m_remotehost, "socket."); + strcat(m_remotehost, mconfig.options().comm_remotehost()); + strcat(m_remotehost, ":"); + strcat(m_remotehost, mconfig.options().comm_remoteport()); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------ + +void mb89374_device::device_start() +{ + // set our instruction counter + m_icountptr = &m_icount; + + // resolve callbacks + m_out_irq_cb.resolve_safe(); + for(auto &cb : m_out_po_cb) + cb.resolve_safe(); + + // state saving + save_item(NAME(m_irq)); + save_item(NAME(m_po)); + save_item(NAME(m_pi)); + save_item(NAME(m_ci)); + + save_item(NAME(m_smr0)); + save_item(NAME(m_smr1)); + save_item(NAME(m_smr2)); + save_item(NAME(m_chrr0)); + save_item(NAME(m_chrr1)); + save_item(NAME(m_msr)); + save_item(NAME(m_mcr)); + save_item(NAME(m_rxsr0)); + save_item(NAME(m_rxsr1)); + save_item(NAME(m_rxcr)); + save_item(NAME(m_rxier)); + save_item(NAME(m_txsr)); + save_item(NAME(m_txcr)); + save_item(NAME(m_txier)); + save_item(NAME(m_sdr)); + save_item(NAME(m_txbcr0)); + save_item(NAME(m_txbcr1)); + save_item(NAME(m_txfr0)); + save_item(NAME(m_txfr1)); + save_item(NAME(m_smr3)); + save_item(NAME(m_portr)); + save_item(NAME(m_reqr)); + save_item(NAME(m_maskr)); + save_item(NAME(m_b1psr)); + save_item(NAME(m_b1pcr)); + save_item(NAME(m_bg1dr)); + save_item(NAME(m_b2sr)); + save_item(NAME(m_b2cr)); + save_item(NAME(m_bg2dr)); + + save_item(NAME(m_intr_delay)); + save_item(NAME(m_sock_delay)); + + save_item(NAME(m_rx_buffer)); + save_item(NAME(m_rx_offset)); + save_item(NAME(m_rx_length)); + + save_item(NAME(m_tx_buffer)); + save_item(NAME(m_tx_offset)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void mb89374_device::device_reset() +{ + m_smr0 = SMR0_MASK; + m_smr1 = SMR1_MASK; + m_smr2 = 0x00; + m_chrr0 = 0x00; + m_chrr1 = 0x00; + m_msr = MSR_MASK; + m_mcr = MCR_MASK; + m_rxsr0 = 0x00; + m_rxsr1 = RXSR1_MASK; + m_rxcr = RXCR_MASK; + m_rxier = 0x00; + m_txsr = TXSR_MASK; + m_txcr = 0x00; + m_txier = TXIER_MASK; + m_sdr = 0x00; + m_txbcr0 = 0x00; + m_txbcr1 = 0x00; + m_txfr0 = 0x00; + m_txfr1 = TXFR1_MASK; + m_smr3 = SMR3_MASK; + m_portr = 0x00; + m_reqr = REQR_MASK; + m_maskr = MASKR_MASK; + m_b1psr = B1PSR_MASK; + m_b1pcr = 0x00; + m_bg1dr = 0x00; + m_b2sr = B2SR_MASK; + m_b2cr = 0x00; + m_bg2dr = 0x00; + + set_irq(0); + set_po0(0); + set_po1(0); + set_po2(0); + set_po3(0); + + m_intr_delay = 0; + m_sock_delay = 0x20; + + m_rx_length = 0x0000; + m_rx_offset = 0x0000; + + m_tx_offset = 0x0000; +} + + +//------------------------------------------------- +// execute_run - +//------------------------------------------------- + +void mb89374_device::execute_run() +{ + while (m_icount > 0) + { + // TODO waste some cycles before triggering ints + if (m_intr_delay > 0) + { + m_intr_delay--; + if (m_intr_delay == 0) + { + } + } + if (m_sock_delay > 0) + { + m_sock_delay--; + if (m_sock_delay == 0) + { + m_sock_delay = 0x20; + checkSockets(); + } + } + m_icount--; + } +} + + +//------------------------------------------------- +// read - handler for register reading +//------------------------------------------------- + +READ8_MEMBER(mb89374_device::read) +{ + uint8_t data = 0xff; + switch (offset & 0x1f) + { + case REGISTER_RXSR0: + data = m_rxsr0; + break; + + case REGISTER_RXSR1: + data = m_rxsr1; + break; + + case REGISTER_TXSR: + data = m_txsr; + break; + + case REGISTER_SDR: + m_sdr = rxRead(); + data = m_sdr; + break; + + case REGISTER_PORTR: + data = m_portr; + break; + + default: + logerror("MB89374 unimplemented register read @%02X\n", offset); + } + return data; +} + + +//------------------------------------------------- +// write - handler for register writing +//------------------------------------------------- + +WRITE8_MEMBER(mb89374_device::write) +{ + switch (offset & 0x1f) + { + case REGISTER_SMR2: + m_smr2 = data; + break; + + case REGISTER_MCR: + m_mcr = data | MCR_MASK; + break; + + case REGISTER_RXCR: + m_rxcr = data | RXCR_MASK; + if (RXCR_HUNT) + rxReset(); + break; + + case REGISTER_RXIER: + m_rxier = data; + + case REGISTER_TXSR: + m_txsr = data | TXSR_MASK; + txReset(); + break; + + case REGISTER_TXCR: + m_txcr = data; + if (TXCR_TXRST) + txReset(); + break; + + case REGISTER_TXIER: + m_txier = data | TXIER_MASK; + break; + + case REGISTER_SMR3: + m_smr3 = data | SMR3_MASK; + break; + + case REGISTER_PORTR: + m_portr = data; + break; + + case REGISTER_MASKR: + m_maskr = data | MASKR_MASK; + set_po2((!MASKR_MTXDRQ && TXCR_TXE && TXIER_TXDI) ? 1 : 0); + break; + + default: + logerror("MB89374 unimplemented register write @%02X = %02X\n", offset, data); + } +} + + +//------------------------------------------------- +// pi0_w - handler for RxCI#/PI0 +//------------------------------------------------- + +WRITE_LINE_MEMBER(mb89374_device::pi0_w) +{ + m_pi[0] = state; +} + + +//------------------------------------------------- +// pi1_w - handler for TxCI#/PI1 +//------------------------------------------------- + +WRITE_LINE_MEMBER(mb89374_device::pi1_w) +{ + m_pi[1] = state; +} + + +//------------------------------------------------- +// pi2_w - handler for TxDACK#/PI2 +//------------------------------------------------- + +WRITE_LINE_MEMBER(mb89374_device::pi2_w) +{ + m_pi[2] = state; +} + + +//------------------------------------------------- +// pi3_w - handler for RxDACK#/PI3 +//------------------------------------------------- + +WRITE_LINE_MEMBER(mb89374_device::pi3_w) +{ + m_pi[3] = state; +} + + +//------------------------------------------------- +// ci_w - handler for TxLAST#/CI# +//------------------------------------------------- + +WRITE_LINE_MEMBER(mb89374_device::ci_w) +{ + m_ci = state; + if (m_ci == 1 && m_pi[2] == 0) + { + txComplete(); + } + +} + + +//------------------------------------------------- +// read - handler for dma reading (rx buffer) +//------------------------------------------------- + +READ8_MEMBER(mb89374_device::dma_r) +{ + uint8_t data = rxRead(); + if (m_rx_offset == m_rx_length) + set_po3(0); // transfer finished; release dma + return data; +} + + +//------------------------------------------------- +// write - handler for dma writing (tx buffer) +//------------------------------------------------- + +WRITE8_MEMBER(mb89374_device::dma_w) +{ + txWrite(data); +} + + +//************************************************************************** +// buffer logic +//************************************************************************** + +void mb89374_device::rxReset() +{ + m_rx_length = 0; + m_rx_offset = 0; + m_rxsr0 = 0x06; // RXIDL | DIDL +} + +uint8_t mb89374_device::rxRead() +{ + uint8_t data = m_rx_buffer[m_rx_offset]; + m_rx_offset++; + if (m_rx_offset == m_rx_length) + m_rxsr0 |= 0x40; // EOF + if (m_rx_offset >= m_rx_length) + rxReset(); + return data; +} + +void mb89374_device::txReset() +{ + m_tx_offset = 0; + m_txsr |= 0x05; +} + +void mb89374_device::txWrite(uint8_t data) +{ + m_tx_buffer[m_tx_offset] = data; + m_tx_offset++; + m_txsr = 0x6b; + + // prevent overflow + if (m_tx_offset >= 0x0f00) + m_tx_offset = 0x0eff; +} + +void mb89374_device::txComplete() +{ + if (m_tx_offset > 0) + { + if (m_line_rx && m_line_tx) + { + m_socket_buffer[0x00] = m_tx_offset & 0xff; + m_socket_buffer[0x01] = (m_tx_offset >> 8) & 0xff; + for (int i = 0x00 ; i < m_tx_offset ; i++) + { + m_socket_buffer[i + 2] = m_tx_buffer[i]; + } + + std::uint32_t dataSize = m_tx_offset + 2; + std::uint32_t written; + + m_line_tx->write(&m_socket_buffer, 0, dataSize, written); + } + } + + m_txsr = 0x6f; + + txReset(); +} + +void mb89374_device::checkSockets() +{ + // check rx socket + if (!m_line_rx) + { + osd_printf_verbose("MB89374 listen on %s\n", m_localhost); + uint64_t filesize; // unused + osd_file::open(m_localhost, OPEN_FLAG_CREATE, m_line_rx, filesize); + } + + // check tx socket + if (!m_line_tx) + { + osd_printf_verbose("MB89374 connect to %s\n", m_remotehost); + uint64_t filesize; // unused + osd_file::open(m_remotehost, 0, m_line_tx, filesize); + } + + if (m_line_rx && m_line_tx) + { + if (RXCR_RXE) + { + if (m_rx_length == 0) + { + std::uint32_t recv = 0; + m_line_rx->read(m_socket_buffer, 0, 2, recv); + if (recv > 0) + { + if (recv == 2) + m_rx_length = m_socket_buffer[0x01] << 8 | m_socket_buffer[0x00]; + else + { + m_rx_length = m_socket_buffer[0x00]; + m_line_rx->read(m_socket_buffer, 0, 1, recv); + while (recv == 0) {} + m_rx_length |= m_socket_buffer[0x00] << 8; + } + + int offset = 0; + int togo = m_rx_length; + while (togo > 0) + { + m_line_rx->read(m_socket_buffer, 0, togo, recv); + for (int i = 0x00 ; i < recv ; i++) + { + m_rx_buffer[offset] = m_socket_buffer[i]; + offset++; + } + togo -= recv; + } + + m_rx_offset = 0; + m_rxsr0 = 0x01; // RXRDY + if (m_rx_offset + 1 == m_rx_length) + m_rxsr0 |= 0x40; // EOF + m_rxsr1 = 0xc8; + set_po3(!MASKR_MRXDRQ && RXIER_RXDI ? 1 : 0); + } + } + } + } +} + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +inline void mb89374_device::set_irq(int state) +{ + if (m_irq != state) + { + m_out_irq_cb(state); + m_irq = state; + } +} + +inline void mb89374_device::set_po0(int state) +{ + if (m_po[0] != state) + { + m_out_po_cb[0](state); + m_po[0] = state; + } +} + +inline void mb89374_device::set_po1(int state) +{ + if (m_po[1] != state) + { + m_out_po_cb[1](state); + m_po[1] = state; + } +} + +inline void mb89374_device::set_po2(int state) +{ + if (m_po[2] != state) + { + m_out_po_cb[2](state); + m_po[2] = state; + } +} + +inline void mb89374_device::set_po3(int state) +{ + if (m_po[3] != state) + { + m_out_po_cb[3](state); + m_po[3] = state; + } +} diff --git a/src/devices/machine/mb89374.h b/src/devices/machine/mb89374.h new file mode 100644 index 00000000000..3011124d87f --- /dev/null +++ b/src/devices/machine/mb89374.h @@ -0,0 +1,170 @@ +// license:BSD-3-Clause +// copyright-holders:Ariane Fugmann +/* +MB89374 + +Fujitsu +Data Link Controller + + _____ _____ + CLK 1 |* \_/ | 42 Vcc + FORMAT# 2 | | 41 RxDACK#/PI3 + RESET# 3 | | 40 TxDACK#/PI2 + RD#/DS# 4 | | 39 RxDRQ/PO3 + WR#/R/W# 5 | | 38 TxDRQ/PO2 + CS# 6 | | 37 IRQT + A4 7 | | 36 Vss + A3 8 | | 35 IRQ + A2 9 | | 34 FD#/DTR# + A1 10 | MB89374 | 33 SCLK/DSR# + A0 11 | | 32 TxLAST#/CI# + Vss 12 | | 31 TxCI#/PI1 + D7 13 | | 30 TxCO#/PO1 + D6 14 | | 29 TxD + D5 15 | | 28 RxD + D4 16 | | 27 RxCI#/PI0 + D3 17 | | 26 RxCO#/PO0 + D2 18 | | 25 DCD# + D1 19 | | 24 CTS# + D0 20 | | 23 TCLK + Vss 21 |_____________| 22 LOC#/RTS# +*/ + +#ifndef MAME_MACHINE_MB89374_H +#define MAME_MACHINE_MB89374_H + +#pragma once + +#include "osdcore.h" + +//************************************************************************** +// DEVICE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_MB89374_IRQ_CB(_devcb) \ + devcb = &downcast<mb89374_device &>(*device).set_out_irq_callback(DEVCB_##_devcb); + +#define MCFG_MB89374_PO0_CB(_devcb) \ + devcb = &downcast<mb89374_device &>(*device).set_out_po_callback<0>(DEVCB_##_devcb); + +#define MCFG_MB89374_PO1_CB(_devcb) \ + devcb = &downcast<mb89374_device &>(*device).set_out_po_callback<1>(DEVCB_##_devcb); + +#define MCFG_MB89374_PO2_CB(_devcb) \ + devcb = &downcast<mb89374_device &>(*device).set_out_po_callback<2>(DEVCB_##_devcb); + +#define MCFG_MB89374_PO3_CB(_devcb) \ + devcb = &downcast<mb89374_device &>(*device).set_out_po_callback<3>(DEVCB_##_devcb); + + +class mb89374_device : public device_t, + public device_execute_interface +{ +public: + // construction/destruction + mb89374_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template <class Object> devcb_base &set_out_irq_callback(Object &&cb) { return m_out_irq_cb.set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> devcb_base &set_out_po_callback(Object &&cb) { return m_out_po_cb[N].set_callback(std::forward<Object>(cb)); } + + // read/write handlers + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + + DECLARE_WRITE_LINE_MEMBER( pi0_w ); + DECLARE_WRITE_LINE_MEMBER( pi1_w ); + DECLARE_WRITE_LINE_MEMBER( pi2_w ); + DECLARE_WRITE_LINE_MEMBER( pi3_w ); + + DECLARE_WRITE_LINE_MEMBER( ci_w ); + + DECLARE_READ8_MEMBER( dma_r ); + DECLARE_WRITE8_MEMBER( dma_w ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void execute_run() override; + + int m_icount; + +private: + // internal state + inline void set_irq(int state); + inline void set_po0(int state); + inline void set_po1(int state); + inline void set_po2(int state); + inline void set_po3(int state); + + devcb_write_line m_out_irq_cb; + devcb_write_line m_out_po_cb[4]; + + // pins + int m_irq; + int m_po[4]; + int m_pi[4]; + int m_ci; + + // registers + uint8_t m_smr0; + uint8_t m_smr1; + uint8_t m_smr2; + uint8_t m_chrr0; + uint8_t m_chrr1; + uint8_t m_msr; + uint8_t m_mcr; + uint8_t m_rxsr0; + uint8_t m_rxsr1; + uint8_t m_rxcr; + uint8_t m_rxier; + uint8_t m_txsr; + uint8_t m_txcr; + uint8_t m_txier; + uint8_t m_sdr; + uint8_t m_txbcr0; + uint8_t m_txbcr1; + uint8_t m_txfr0; + uint8_t m_txfr1; + uint8_t m_smr3; + uint8_t m_portr; + uint8_t m_reqr; + uint8_t m_maskr; + uint8_t m_b1psr; + uint8_t m_b1pcr; + uint8_t m_bg1dr; + uint8_t m_b2sr; + uint8_t m_b2cr; + uint8_t m_bg2dr; + + uint16_t m_intr_delay; + uint16_t m_sock_delay; + + // 512 byte fifos (not in hardware) + uint8_t m_rx_buffer[0x200]; + uint16_t m_rx_offset; + uint16_t m_rx_length; + + uint8_t m_tx_buffer[0x200]; + uint16_t m_tx_offset; + + void rxReset(); + uint8_t rxRead(); + + void txReset(); + void txWrite(uint8_t data); + void txComplete(); + + osd_file::ptr m_line_rx; + osd_file::ptr m_line_tx; + char m_localhost[256]; + char m_remotehost[256]; + uint8_t m_socket_buffer[0x200]; + void checkSockets(); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(MB89374, mb89374_device) + +#endif // MAME_MACHINE_MB89374_H diff --git a/src/mame/drivers/model1.cpp b/src/mame/drivers/model1.cpp index 07fa23ce0c8..9d095739047 100644 --- a/src/mame/drivers/model1.cpp +++ b/src/mame/drivers/model1.cpp @@ -885,10 +885,6 @@ void model1_state::model1_mem(address_map &map) map(0x900000, 0x903fff).ram().w(this, FUNC(model1_state::p_w)).share("palette"); map(0x910000, 0x91bfff).ram().share("color_xlat"); - map(0xb00000, 0xb00fff).rw(m_m1comm, FUNC(m1comm_device::share_r), FUNC(m1comm_device::share_w)); - map(0xb01000, 0xb01000).rw(m_m1comm, FUNC(m1comm_device::cn_r), FUNC(m1comm_device::cn_w)); - map(0xb01002, 0xb01002).rw(m_m1comm, FUNC(m1comm_device::fg_r), FUNC(m1comm_device::fg_w)); - map(0xc00000, 0xc0003f).rw(this, FUNC(model1_state::io_r), FUNC(model1_state::io_w)); map(0xc00040, 0xc00043).rw(this, FUNC(model1_state::network_ctl_r), FUNC(model1_state::network_ctl_w)); @@ -916,6 +912,15 @@ void model1_state::model1_io(address_map &map) map(0xd80000, 0xd80003).r(this, FUNC(model1_state::model1_tgp_copro_r)); } +void model1_state::model1_comm_mem(address_map &map) +{ + model1_mem(map); + + map(0xb00000, 0xb00fff).rw(m_m1comm, FUNC(m1comm_device::share_r), FUNC(m1comm_device::share_w)); + map(0xb01000, 0xb01000).rw(m_m1comm, FUNC(m1comm_device::cn_r), FUNC(m1comm_device::cn_w)); + map(0xb01002, 0xb01002).rw(m_m1comm, FUNC(m1comm_device::fg_r), FUNC(m1comm_device::fg_w)); +} + void model1_state::model1_vr_mem(address_map &map) { map(0x000000, 0x0fffff).rom(); @@ -1286,9 +1291,6 @@ ROM_START( vformula ) ROM_LOAD32_BYTE( "mpr-14900.41", 0x000002, 0x80000, CRC(aa7c017d) SHA1(0fa2b59a8bb5f5907b2b2567e69d11c73b398dc1) ) ROM_LOAD32_BYTE( "mpr-14901.42", 0x000003, 0x80000, CRC(175b7a9a) SHA1(c86602e771cd49bab425b4ba7926d2f44858bd39) ) - ROM_REGION( 0x20000, "commboard", 0 ) /* Comms Board */ - ROM_LOAD( "epr-15624.17", 0x00000, 0x20000, CRC(9b3ba315) SHA1(0cd0983cc8b2f2d6b41617d0d0a24cc6c188e62a) ) - ROM_REGION( 0x2000, "tgp", 0 ) /* TGP program rom */ // The real internal TGP rom ROM_LOAD("315-5573.bin", 0, 0x2000, CRC(ec913af2) SHA1(a18bf6c9d7b35f8b9e513a7d279f13a30b32a961) ) @@ -1561,9 +1563,6 @@ ROM_START( wingwar360 ) ROM_REGION( 0x10000, "ioboard", 0 ) ROM_LOAD("epr-16891.6", 0x00000, 0x10000, CRC(a33f84d1) SHA1(3079397c7241c1a6f494fa310faff0989dfa04a0) ) - ROM_REGION( 0x20000, "commboard", 0 ) - ROM_LOAD("epr-15112.17", 0x00000, 0x20000, CRC(4950e771) SHA1(99014124e0324dd114cb22f55159d18b597a155a) ) - // Dumper's note: Video & Drive is the control board in the attendants' tower, same hardware as G-Loc R360 with the two program roms being the only difference. ROM_REGION( 0x400000, "controlboard", 0 ) ROM_LOAD("ic22_18851.bin", 0x00000, 0x20000, CRC(85f75bd7) SHA1(43cc8f8c81631d71b661e55e15f3fe8803a8a7e9) ) @@ -1652,8 +1651,16 @@ MACHINE_CONFIG_START(model1_state::model1) MCFG_CLOCK_ADD("m1uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate) MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_txc)) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("m1uart", i8251_device, write_rxc)) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(model1_state::wingwar) + model1(config); + + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(model1_comm_mem) - MCFG_M1COMM_ADD("m1comm") + MCFG_M1COMM_ADD(M1COMM_TAG) + // use EPR-15112 MACHINE_CONFIG_END MACHINE_CONFIG_START(model1_state::swa) @@ -1725,8 +1732,20 @@ MACHINE_CONFIG_START(model1_state::model1_vr) MCFG_CLOCK_ADD("m1uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate) MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_txc)) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("m1uart", i8251_device, write_rxc)) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(model1_state::vr) + model1_vr(config); + + MCFG_M1COMM_ADD(M1COMM_TAG) + // use EPR-15112 +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(model1_state::vformula) + model1_vr(config); - MCFG_M1COMM_ADD("m1comm") + MCFG_M1COMM_ADD(M1COMM_TAG) + // use EPR-15624 MACHINE_CONFIG_END DRIVER_INIT_MEMBER(model1_state,wingwar360) @@ -1793,12 +1812,12 @@ WRITE16_MEMBER(model1_state::r360_w) } } -GAME( 1993, vf, 0, model1, vf, model1_state, 0, ROT0, "Sega", "Virtua Fighter", MACHINE_IMPERFECT_GRAPHICS ) -GAMEL(1992, vr, 0, model1_vr, vr, model1_state, 0, ROT0, "Sega", "Virtua Racing", MACHINE_IMPERFECT_GRAPHICS, layout_vr ) -GAME( 1993, vformula, vr, model1_vr, vr, model1_state, 0, ROT0, "Sega", "Virtua Formula", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, swa, 0, swa, swa, model1_state, 0, ROT0, "Sega", "Star Wars Arcade", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) -GAME( 1994, wingwar, 0, model1, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (World)", MACHINE_NOT_WORKING ) -GAME( 1994, wingwaru, wingwar, model1, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (US)", MACHINE_NOT_WORKING ) -GAME( 1994, wingwarj, wingwar, model1, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (Japan)", MACHINE_NOT_WORKING ) -GAME( 1994, wingwar360, wingwar, model1, wingwar, model1_state, wingwar360, ROT0, "Sega", "Wing War R360 (US)", MACHINE_NOT_WORKING ) -GAME( 1993, netmerc, 0, netmerc, vf, model1_state, 0, ROT0, "Sega", "Sega NetMerc", MACHINE_NOT_WORKING ) +GAME( 1993, vf, 0, model1, vf, model1_state, 0, ROT0, "Sega", "Virtua Fighter", MACHINE_IMPERFECT_GRAPHICS ) +GAMEL(1992, vr, 0, vr, vr, model1_state, 0, ROT0, "Sega", "Virtua Racing", MACHINE_IMPERFECT_GRAPHICS, layout_vr ) +GAME( 1993, vformula, vr, vformula, vr, model1_state, 0, ROT0, "Sega", "Virtua Formula", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1993, swa, 0, swa, swa, model1_state, 0, ROT0, "Sega", "Star Wars Arcade", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) +GAME( 1994, wingwar, 0, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (World)", MACHINE_NOT_WORKING ) +GAME( 1994, wingwaru, wingwar, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (US)", MACHINE_NOT_WORKING ) +GAME( 1994, wingwarj, wingwar, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (Japan)", MACHINE_NOT_WORKING ) +GAME( 1994, wingwar360, wingwar, wingwar, wingwar, model1_state, wingwar360, ROT0, "Sega", "Wing War R360 (US)", MACHINE_NOT_WORKING ) +GAME( 1993, netmerc, 0, netmerc, vf, model1_state, 0, ROT0, "Sega", "Sega NetMerc", MACHINE_NOT_WORKING ) diff --git a/src/mame/includes/model1.h b/src/mame/includes/model1.h index 9140d66e51a..4ea3866ae15 100644 --- a/src/mame/includes/model1.h +++ b/src/mame/includes/model1.h @@ -186,11 +186,15 @@ public: }; void model1(machine_config &config); + void wingwar(machine_config &config); void swa(machine_config &config); void netmerc(machine_config &config); void model1_vr(machine_config &config); + void vr(machine_config &config); + void vformula(machine_config &config); void model1_io(address_map &map); void model1_mem(address_map &map); + void model1_comm_mem(address_map &map); void model1_vr_io(address_map &map); void model1_vr_mem(address_map &map); void model1_vr_tgp_map(address_map &map); diff --git a/src/mame/machine/m1comm.cpp b/src/mame/machine/m1comm.cpp index 4b76be4351f..98cc02aa1bb 100644 --- a/src/mame/machine/m1comm.cpp +++ b/src/mame/machine/m1comm.cpp @@ -52,13 +52,12 @@ Notes: */ #include "emu.h" -#include "emuopts.h" #include "machine/m1comm.h" +#include "emuopts.h" -#define Z80_TAG "m1commcpu" - -#define VERBOSE 0 -#include "logmacro.h" +#define Z80_TAG "commcpu" +#define DMA_TAG "commdma" +#define DLC_TAG "commdlc" /************************************* * M1COMM Memory Map @@ -76,23 +75,30 @@ void m1comm_device::m1comm_mem(address_map &map) void m1comm_device::m1comm_io(address_map &map) { map.global_mask(0x7f); - map(0x00, 0x1f).rw(this, FUNC(m1comm_device::dlc_reg_r), FUNC(m1comm_device::dlc_reg_w)); - map(0x20, 0x2f).rw(this, FUNC(m1comm_device::dma_reg_r), FUNC(m1comm_device::dma_reg_w)); + map(0x00, 0x1f).rw(m_dlc, FUNC(mb89374_device::read), FUNC(mb89374_device::write)); + map(0x20, 0x2f).rw(m_dma, FUNC(am9517a_device::read), FUNC(am9517a_device::write)); map(0x40, 0x5f).mask(0x01).rw(this, FUNC(m1comm_device::syn_r), FUNC(m1comm_device::syn_w)); map(0x60, 0x7f).mask(0x01).rw(this, FUNC(m1comm_device::zfg_r), FUNC(m1comm_device::zfg_w)); } - ROM_START( m1comm ) ROM_REGION( 0x20000, Z80_TAG, ROMREGION_ERASEFF ) - ROM_LOAD( "epr-15112.17", 0x0000, 0x20000, CRC(4950e771) SHA1(99014124e0324dd114cb22f55159d18b597a155a) ) + ROM_DEFAULT_BIOS("epr-15112") + + // found on Virtua Racing and WingWar + ROM_SYSTEM_BIOS( 0, "epr-15112", "EPR-15112" ) + ROMX_LOAD( "epr-15112.17", 0x0000, 0x20000, CRC(4950e771) SHA1(99014124e0324dd114cb22f55159d18b597a155a), ROM_BIOS(1) ) + + // found on Virtua Formula + ROM_SYSTEM_BIOS( 1, "epr-15624", "EPR-15624" ) + ROMX_LOAD( "epr-15624.17", 0x0000, 0x20000, CRC(9b3ba315) SHA1(0cd0983cc8b2f2d6b41617d0d0a24cc6c188e62a), ROM_BIOS(2) ) ROM_END //************************************************************************** // GLOBAL VARIABLES //************************************************************************** -DEFINE_DEVICE_TYPE(M1COMM, m1comm_device, "m1comm", "Model 1 Communication Board") +DEFINE_DEVICE_TYPE(M1COMM, m1comm_device, "m1comm", "Model-1 Communication Board") //------------------------------------------------- // device_add_mconfig - add device configuration @@ -102,16 +108,30 @@ MACHINE_CONFIG_START(m1comm_device::device_add_mconfig) MCFG_CPU_ADD(Z80_TAG, Z80, 8000000) /* 32 MHz / 4 */ MCFG_CPU_PROGRAM_MAP(m1comm_mem) MCFG_CPU_IO_MAP(m1comm_io) + + MCFG_DEVICE_ADD(DMA_TAG, AM9517A, 8000000) /* 32 MHz / 4 */ + MCFG_I8237_OUT_HREQ_CB(WRITELINE(m1comm_device, dma_hreq_w)) + MCFG_I8237_IN_MEMR_CB(READ8(m1comm_device, dma_mem_r)) + MCFG_I8237_OUT_MEMW_CB(WRITE8(m1comm_device, dma_mem_w)) + MCFG_I8237_OUT_DACK_2_CB(DEVWRITELINE(DLC_TAG, mb89374_device, pi3_w)) + MCFG_I8237_OUT_DACK_3_CB(DEVWRITELINE(DLC_TAG, mb89374_device, pi2_w)) + MCFG_I8237_OUT_EOP_CB(DEVWRITELINE(DLC_TAG, mb89374_device, ci_w)) + MCFG_I8237_IN_IOR_2_CB(DEVREAD8(DLC_TAG, mb89374_device, dma_r)) + MCFG_I8237_OUT_IOW_3_CB(DEVWRITE8(DLC_TAG, mb89374_device, dma_w)) + + MCFG_DEVICE_ADD(DLC_TAG, MB89374, 8000000) /* 32 MHz / 4 */ + MCFG_MB89374_PO2_CB(DEVWRITELINE(DMA_TAG, am9517a_device, dreq3_w)) + MCFG_MB89374_PO3_CB(DEVWRITELINE(DMA_TAG, am9517a_device, dreq2_w)) + MCFG_MB89374_IRQ_CB(WRITELINE(m1comm_device, dlc_int7_w)) MACHINE_CONFIG_END //------------------------------------------------- // rom_region - device-specific ROM region //------------------------------------------------- - -const tiny_rom_entry *m1comm_device::device_rom_region() const -{ - return ROM_NAME( m1comm ); -} +const tiny_rom_entry *m1comm_device::device_rom_region() const +{ + return ROM_NAME( m1comm ); +} //************************************************************************** // LIVE DEVICE @@ -123,8 +143,11 @@ const tiny_rom_entry *m1comm_device::device_rom_region() const m1comm_device::m1comm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, M1COMM, tag, owner, clock), - m_commcpu(*this, Z80_TAG) + m_cpu(*this, Z80_TAG), + m_dma(*this, DMA_TAG), + m_dlc(*this, DLC_TAG) { +#ifdef M1COMM_SIMULATION // prepare localhost "filename" m_localhost[0] = 0; strcat(m_localhost, "socket."); @@ -140,6 +163,7 @@ m1comm_device::m1comm_device(const machine_config &mconfig, const char *tag, dev strcat(m_remotehost, mconfig.options().comm_remoteport()); m_framesync = mconfig.options().comm_framesync() ? 0x01 : 0x00; +#endif } //------------------------------------------------- @@ -160,81 +184,53 @@ void m1comm_device::device_reset() m_zfg = 0; m_cn = 0; m_fg = 0; - - m_commcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); } -READ8_MEMBER(m1comm_device::dlc_reg_r) +void m1comm_device::device_reset_after_children() { - // dirty hack to keep Z80 in RESET state - if (!m_cn) - { - device_reset(); - return 0xff; - } - // dirty hack to keep Z80 in RESET state + m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_dma->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_dlc->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); +} - uint8_t result = m_dlc_reg[offset]; - LOG("m1comm-dlc_reg_r: read register %02x for value %02x\n", offset, result); - return result; +WRITE_LINE_MEMBER(m1comm_device::dma_hreq_w) +{ + m_cpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); + m_dma->hack_w(state); } -WRITE8_MEMBER(m1comm_device::dlc_reg_w) +READ8_MEMBER(m1comm_device::dma_mem_r) { - m_dlc_reg[offset] = data; - LOG("m1comm-dlc_reg_w: write register %02x for value %02x\n", offset, data); + return m_cpu->space(AS_PROGRAM).read_byte(offset); } -READ8_MEMBER(m1comm_device::dma_reg_r) +WRITE8_MEMBER(m1comm_device::dma_mem_w) { - uint8_t result = m_dma_reg[offset]; - LOG("m1comm-dma_reg_r: read register %02x for value %02x\n", offset, result); - return result; + m_cpu->space(AS_PROGRAM).write_byte(offset, data); } -WRITE8_MEMBER(m1comm_device::dma_reg_w) +WRITE_LINE_MEMBER(m1comm_device::dlc_int7_w) { - LOG("m1comm-dma_reg_w: %02x %02x\n", offset, data); - m_dma_reg[offset] = data; + m_cpu->set_input_line_and_vector(0, state ? ASSERT_LINE : CLEAR_LINE, 0xff); } READ8_MEMBER(m1comm_device::syn_r) { - uint8_t result = m_syn | 0xfc; - LOG("m1comm-syn_r: read register %02x for value %02x\n", offset, result); - return result; + return m_syn | 0xfc; } WRITE8_MEMBER(m1comm_device::syn_w) { m_syn = data & 0x03; - - switch (data & 0x02) - { - case 0x00: - LOG("m1comm-syn_w: VINT disabled\n"); - break; - - case 0x02: - LOG("m1comm-syn_w: VINT enabled\n"); - break; - - default: - LOG("m1comm-syn_w: %02x\n", data); - break; - } } READ8_MEMBER(m1comm_device::zfg_r) { - uint8_t result = m_zfg | (~m_fg << 7) | 0x7e; - LOG("m1comm-zfg_r: read register %02x for value %02x\n", offset, result); - return result; + return m_zfg | (~m_fg << 7) | 0x7e; } WRITE8_MEMBER(m1comm_device::zfg_w) { - LOG("m1comm-zfg_w: %02x\n", data); m_zfg = data & 0x01; } @@ -259,9 +255,16 @@ WRITE8_MEMBER(m1comm_device::cn_w) #ifndef M1COMM_SIMULATION if (!m_cn) + { device_reset(); + device_reset_after_children(); + } else - m_commcpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + { + m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + m_dma->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + m_dlc->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + } #else if (!m_cn) { @@ -301,8 +304,7 @@ void m1comm_device::check_vint_irq() #ifndef M1COMM_SIMULATION if (m_syn & 0x02) { - m_commcpu->set_input_line_and_vector(0, HOLD_LINE, 0xef); - LOG("m1comm-INT5\n"); + m_cpu->set_input_line_and_vector(0, HOLD_LINE, 0xef); } #else comm_tick(); diff --git a/src/mame/machine/m1comm.h b/src/mame/machine/m1comm.h index dd657bc71cc..24c5dbc4723 100644 --- a/src/mame/machine/m1comm.h +++ b/src/mame/machine/m1comm.h @@ -9,6 +9,11 @@ #include "osdcore.h" #include "cpu/z80/z80.h" +#include "machine/am9517a.h" +#include "machine/mb89374.h" + +#define M1COMM_TAG "m1comm" +#define M1COMM_CPU_REGION "m1comm:commcpu" #define MCFG_M1COMM_ADD(_tag ) \ MCFG_DEVICE_ADD(_tag, M1COMM, 0) @@ -23,31 +28,17 @@ public: // construction/destruction m1comm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // internal API - stuff that happens on the comm board - // MB89374 registers - DECLARE_READ8_MEMBER(dlc_reg_r); - DECLARE_WRITE8_MEMBER(dlc_reg_w); - // MB89237A registers - DECLARE_READ8_MEMBER(dma_reg_r); - DECLARE_WRITE8_MEMBER(dma_reg_w); - // single bit registers (74LS74) - DECLARE_READ8_MEMBER(syn_r); - DECLARE_WRITE8_MEMBER(syn_w); - DECLARE_READ8_MEMBER(zfg_r); - DECLARE_WRITE8_MEMBER(zfg_w); + // public API - stuff that gets called from the model1 // shared memory 4k + // reads/writes at I/O 0xB00xxx DECLARE_READ8_MEMBER(share_r); DECLARE_WRITE8_MEMBER(share_w); - // public API - stuff that gets called from the model1 - // shared memory 4k - // reads/writes at I/O 0xB00xxx - // - share_r - // - share_w // single bit registers (74LS74) // reads/writes at I/O 0xB01000 DECLARE_READ8_MEMBER(cn_r); DECLARE_WRITE8_MEMBER(cn_w); + // reads/writes at I/O 0xB01002 DECLARE_READ8_MEMBER(fg_r); DECLARE_WRITE8_MEMBER(fg_w); @@ -61,21 +52,44 @@ protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; + virtual void device_reset_after_children() override; + virtual const tiny_rom_entry *device_rom_region() const override; + // optional information overrides virtual void device_add_mconfig(machine_config &config) override; private: - required_device<z80_device> m_commcpu; + required_device<z80_device> m_cpu; + required_device<am9517a_device> m_dma; + required_device<mb89374_device> m_dlc; + + // MB89374 handler + DECLARE_WRITE_LINE_MEMBER(dlc_int7_w); + + // MB89237A handler + DECLARE_WRITE_LINE_MEMBER(dma_hreq_w); + DECLARE_READ8_MEMBER(dma_mem_r); + DECLARE_WRITE8_MEMBER(dma_mem_w); + + // single bit registers (74LS74) + DECLARE_READ8_MEMBER(syn_r); + DECLARE_WRITE8_MEMBER(syn_w); + DECLARE_READ8_MEMBER(zfg_r); + DECLARE_WRITE8_MEMBER(zfg_w); + + // shared memory 4k + // reads/writes at 0xC000-FFFF + // - share_r + // - share_w uint8_t m_shared[0x1000]; // 2x 2k = 4k; model1 accesses this with 16bit data and 11bit address (A0 to A10) - uint8_t m_dlc_reg[0x20]; // MB89374 registers - uint8_t m_dma_reg[0x20]; // MB89237A registers - uint8_t m_syn; // bit0 is stored; purpose unknown, bit1 is used to enable/disable VINT/IRQ5 - uint8_t m_zfg; // z80 flip gate? purpose unknown, bit0 is stored + uint8_t m_syn; // bit0 is used to trigger DOP line on VINT, bit1 is used to enable/disable VINT/IRQ5 + uint8_t m_zfg; // z80 flip gate, bit0 is stored uint8_t m_cn; // bit0 is used to enable/disable the comm board - uint8_t m_fg; // flip gate? purpose unknown, bit0 is stored, bit7 is connected to ZFG bit 0 + uint8_t m_fg; // flip gate, bit0 is stored, bit7 is connected to ZFG bit 0 +#ifdef M1COMM_SIMULATION osd_file::ptr m_line_rx; // rx line - can be either differential, simple serial or toslink osd_file::ptr m_line_tx; // tx line - is differential, simple serial and toslink char m_localhost[256]; @@ -84,7 +98,6 @@ private: uint8_t m_buffer1[0x200]; uint8_t m_framesync; -#ifdef M1COMM_SIMULATION uint8_t m_linkenable; uint16_t m_linktimer; uint8_t m_linkalive; |