mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Merge pull request #5794 from JoakimLarsson/epc_4
WIP: TWIB board - EPC terminal adapter for IBM mainframe and Alfaskop system
This commit is contained in:
commit
530101b53f
@ -1383,6 +1383,8 @@ if (BUSES["ISA"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/isa/myb3k_fdc.h",
|
||||
MAME_DIR .. "src/devices/bus/isa/eis_sad8852.cpp",
|
||||
MAME_DIR .. "src/devices/bus/isa/eis_sad8852.h",
|
||||
MAME_DIR .. "src/devices/bus/isa/eis_twib.cpp",
|
||||
MAME_DIR .. "src/devices/bus/isa/eis_twib.h",
|
||||
MAME_DIR .. "src/devices/bus/isa/lbaenhancer.cpp",
|
||||
MAME_DIR .. "src/devices/bus/isa/lbaenhancer.h",
|
||||
MAME_DIR .. "src/devices/bus/isa/np600.cpp",
|
||||
|
259
src/devices/bus/isa/eis_twib.cpp
Normal file
259
src/devices/bus/isa/eis_twib.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Joakim Larsson Edstrom
|
||||
/***********************************************************************************************************
|
||||
*
|
||||
* Ericsson Information Systems/Nokia Data/ICL, SAD 8852 IBM 3270/5250 terminal emulation adapter
|
||||
*
|
||||
* This board is a terminal adapter for XT class PC machines to be connected as a terminal to
|
||||
* IBM mainframes. There are two on board connectors, a BNC connector to act as a 3270 terminal
|
||||
* and a twinax connector for the older 5250 terminal.
|
||||
*
|
||||
* TODO:
|
||||
* - Hook up 8274 fully
|
||||
* - Add bitbanger device and hook it up to an (emulated?!) IBM mainframe
|
||||
*
|
||||
************************************************************************************************************/
|
||||
/*
|
||||
Links:
|
||||
------
|
||||
https://github.com/MattisLind/alfaskop_emu
|
||||
|
||||
Ericsson manufactured board - marked 83016053-30, assembled in 1984 indicated by chip dates
|
||||
+--------------------------------------------------------------------------------------+ ___
|
||||
|O 83016053-30 IC11 IC20 X1 |o|_||
|
||||
| IC14 IC15 74LS74 74S37 19.170MHz |____|
|
||||
| NDK 4Y ||
|
||||
| RS232 IC13 IC18 ||
|
||||
| IC12 ULA 2C143E Ferranti ||---
|
||||
| X.27 i8274 MPSC P1|| |= Twinax (5250)
|
||||
| serial controller IC19 IC17 ||---
|
||||
| P3 IC16 754528P LM339 1234567890 ||
|
||||
| IC10 SW2 DIP ||
|
||||
| 74LS08 IC21 RP2 Resistor SIL ||
|
||||
| W2 74LS30 IC2 IC8 ||
|
||||
| IC5 IC1 IC7 74LS125 74LS240 ||
|
||||
| 74LS04 74LS244 RP1 74LS86 W1 CSA1 CSA2 ||---
|
||||
| IC4 IC3 Resistor DIL IC6 ooooo o5 o5 IC9 P2|| |- BNC(3270)
|
||||
| 74LS00 74LS00 1234567890 74LS86 ooooo 1o o4 1o o4 74LS245 ||---
|
||||
| SW1 DIP 2o o3 2o o3 ____|
|
||||
+----------------------------------------------------------------------------------|o___|
|
||||
||||||||||||||||||||||||| |
|
||||
Notes |
|
||||
------------------------------------------------------------------------------ |
|
||||
IC13-IC16 unpopulated IC:s
|
||||
CSA1,CSA2 unpopulated jumper areas
|
||||
W2 unpopulated jumper area
|
||||
P3 unpopulated connector RS232/X.27(RS422)
|
||||
|
||||
General description
|
||||
-------------------
|
||||
This is a passive ISA8 board that should be fitted into an Ericsson PC (epc) and
|
||||
driven by suitable software. It was replaced by the ISA16 SAD8852 intelligent TWIB
|
||||
board for WS286 and higher a few years later.
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "eis_twib.h"
|
||||
#include "machine/z80sio.h"
|
||||
|
||||
#define LOG_READ (1U << 1)
|
||||
#define LOG_IRQ (1U << 2)
|
||||
|
||||
//#define VERBOSE (LOG_IRQ)
|
||||
//#define LOG_OUTPUT_STREAM std::cout
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__)
|
||||
#define LOGIRQ(...) LOGMASKED(LOG_IRQ, __VA_ARGS__)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define FUNCNAME __func__
|
||||
#else
|
||||
#define FUNCNAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICE_TYPE(ISA8_EIS_TWIB, isa8_eistwib_device, "eistwib", "EIS TWIB IBM mainframe terminal adapter")
|
||||
|
||||
//-------------------------------------------------
|
||||
// Access methods from ISA bus
|
||||
//-------------------------------------------------
|
||||
READ8_MEMBER( isa8_eistwib_device::twib_r )
|
||||
{
|
||||
LOGR("%s : offset=%d\n", FUNCNAME, offset);
|
||||
return m_uart8274->cd_ba_r(offset);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( isa8_eistwib_device::twib_w )
|
||||
{
|
||||
LOG("%s : offset=%d data=0x%02x\n", FUNCNAME, offset, data);
|
||||
m_uart8274->cd_ba_w(offset, data);
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(isa8_eistwib_device::tick_bitclock)
|
||||
{
|
||||
m_uart8274->txca_w(m_bitclock);
|
||||
m_uart8274->rxca_w(m_bitclock);
|
||||
m_sdlclogger->clock_w(m_bitclock);
|
||||
m_bitclock = !m_bitclock;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
// UI I/O
|
||||
//----------------------------------------------------------
|
||||
static INPUT_PORTS_START( eistwib_ports )
|
||||
PORT_START("SW1")
|
||||
PORT_DIPNAME( 0x3f0, 0x380, "I/O Base address" )
|
||||
PORT_DIPSETTING( 0x000, "0x000" )
|
||||
PORT_DIPSETTING( 0x010, "0x010" )
|
||||
PORT_DIPSETTING( 0x020, "0x020" )
|
||||
PORT_DIPSETTING( 0x030, "0x030" )
|
||||
PORT_DIPSETTING( 0x040, "0x040" )
|
||||
PORT_DIPSETTING( 0x050, "0x050" )
|
||||
PORT_DIPSETTING( 0x060, "0x060" )
|
||||
PORT_DIPSETTING( 0x070, "0x070" )
|
||||
PORT_DIPSETTING( 0x080, "0x080" )
|
||||
PORT_DIPSETTING( 0x090, "0x090" )
|
||||
PORT_DIPSETTING( 0x0a0, "0x0a0" )
|
||||
PORT_DIPSETTING( 0x0b0, "0x0b0" )
|
||||
PORT_DIPSETTING( 0x0c0, "0x0c0" )
|
||||
PORT_DIPSETTING( 0x0d0, "0x0d0" )
|
||||
PORT_DIPSETTING( 0x0e0, "0x0e0" )
|
||||
PORT_DIPSETTING( 0x0f0, "0x0f0" )
|
||||
PORT_DIPSETTING( 0x100, "0x100" )
|
||||
PORT_DIPSETTING( 0x110, "0x110" )
|
||||
PORT_DIPSETTING( 0x120, "0x120" )
|
||||
PORT_DIPSETTING( 0x130, "0x130" )
|
||||
PORT_DIPSETTING( 0x140, "0x140" )
|
||||
PORT_DIPSETTING( 0x150, "0x150" )
|
||||
PORT_DIPSETTING( 0x160, "0x160" )
|
||||
PORT_DIPSETTING( 0x170, "0x170" )
|
||||
PORT_DIPSETTING( 0x180, "0x180" )
|
||||
PORT_DIPSETTING( 0x190, "0x190" )
|
||||
PORT_DIPSETTING( 0x1a0, "0x1a0" )
|
||||
PORT_DIPSETTING( 0x1b0, "0x1b0" )
|
||||
PORT_DIPSETTING( 0x1c0, "0x1c0" )
|
||||
PORT_DIPSETTING( 0x1d0, "0x1d0" )
|
||||
PORT_DIPSETTING( 0x1e0, "0x1e0" )
|
||||
PORT_DIPSETTING( 0x1f0, "0x1f0" )
|
||||
PORT_DIPSETTING( 0x200, "0x200" )
|
||||
PORT_DIPSETTING( 0x210, "0x210" )
|
||||
PORT_DIPSETTING( 0x220, "0x220" )
|
||||
PORT_DIPSETTING( 0x230, "0x230" )
|
||||
PORT_DIPSETTING( 0x240, "0x240" )
|
||||
PORT_DIPSETTING( 0x250, "0x250" )
|
||||
PORT_DIPSETTING( 0x260, "0x260" )
|
||||
PORT_DIPSETTING( 0x270, "0x270" )
|
||||
PORT_DIPSETTING( 0x280, "0x280" )
|
||||
PORT_DIPSETTING( 0x290, "0x290" )
|
||||
PORT_DIPSETTING( 0x2a0, "0x2a0" )
|
||||
PORT_DIPSETTING( 0x2b0, "0x2b0" )
|
||||
PORT_DIPSETTING( 0x2c0, "0x2c0" )
|
||||
PORT_DIPSETTING( 0x2d0, "0x2d0" )
|
||||
PORT_DIPSETTING( 0x2e0, "0x2e0" )
|
||||
PORT_DIPSETTING( 0x2f0, "0x2f0" )
|
||||
PORT_DIPSETTING( 0x300, "0x300" )
|
||||
PORT_DIPSETTING( 0x310, "0x310" )
|
||||
PORT_DIPSETTING( 0x320, "0x320" )
|
||||
PORT_DIPSETTING( 0x330, "0x330" )
|
||||
PORT_DIPSETTING( 0x340, "0x340" )
|
||||
PORT_DIPSETTING( 0x350, "0x350" )
|
||||
PORT_DIPSETTING( 0x360, "0x360" )
|
||||
PORT_DIPSETTING( 0x370, "0x370" )
|
||||
PORT_DIPSETTING( 0x380, "0x380" )
|
||||
PORT_DIPSETTING( 0x390, "0x390" )
|
||||
PORT_DIPSETTING( 0x3a0, "0x3a0" )
|
||||
PORT_DIPSETTING( 0x3b0, "0x3b0" )
|
||||
PORT_DIPSETTING( 0x3c0, "0x3c0" )
|
||||
PORT_DIPSETTING( 0x3d0, "0x3d0" )
|
||||
PORT_DIPSETTING( 0x3e0, "0x3e0" )
|
||||
PORT_DIPSETTING( 0x3f0, "0x3f0" )
|
||||
|
||||
PORT_START("W1") // Jumper area, field 0=no jumper 1=LPT 2=COM 3=n/a
|
||||
PORT_DIPNAME(0x01, 0x00, "ISA IRQ2")
|
||||
PORT_DIPSETTING(0x00, "no jumper")
|
||||
PORT_DIPSETTING(0x01, "8274 INT")
|
||||
PORT_DIPNAME(0x02, 0x00, "ISA IRQ3")
|
||||
PORT_DIPSETTING(0x00, "no jumper")
|
||||
PORT_DIPSETTING(0x02, "8274 INT")
|
||||
PORT_DIPNAME(0x04, 0x04, "ISA IRQ4")
|
||||
PORT_DIPSETTING(0x00, "no jumper")
|
||||
PORT_DIPSETTING(0x04, "8274 INT")
|
||||
PORT_DIPNAME(0x08, 0x00, "ISA IRQ5")
|
||||
PORT_DIPSETTING(0x00, "no jumper")
|
||||
PORT_DIPSETTING(0x08, "8274 INT")
|
||||
PORT_DIPNAME(0x10, 0x00, "ISA IRQ6")
|
||||
PORT_DIPSETTING(0x00, "no jumper")
|
||||
PORT_DIPSETTING(0x10, "8274 INT")
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor isa8_eistwib_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( eistwib_ports );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Board configuration
|
||||
//-------------------------------------------------
|
||||
void isa8_eistwib_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
SDLC_LOGGER(config, m_sdlclogger, 0); // To decode the frames
|
||||
I8274_NEW(config, m_uart8274, (XTAL(14'318'181)/ 3) / 2); // Half the 4,77 MHz ISA bus CLK signal
|
||||
//m_uart8274->out_rtsa_callback().set([this] (int state) { m_rts = state; });
|
||||
m_uart8274->out_txda_callback().set([this] (int state) { m_txd = state; m_sdlclogger->data_w(state); });
|
||||
m_uart8274->out_int_callback().set([this] (int state)
|
||||
{ // Jumper field W1 decides what IRQs to pull
|
||||
if (m_isairq->read() & 0x01) { LOGIRQ("TWIB IRQ2: %d\n", state); m_isa->irq2_w(state); }
|
||||
if (m_isairq->read() & 0x02) { LOGIRQ("TWIB IRQ3: %d\n", state); m_isa->irq3_w(state); }
|
||||
if (m_isairq->read() & 0x04) { LOGIRQ("TWIB IRQ4: %d\n", state); m_isa->irq4_w(state); }
|
||||
if (m_isairq->read() & 0x08) { LOGIRQ("TWIB IRQ5: %d\n", state); m_isa->irq5_w(state); }
|
||||
if (m_isairq->read() & 0x10) { LOGIRQ("TWIB IRQ6: %d\n", state); m_isa->irq6_w(state); }
|
||||
});
|
||||
|
||||
TIMER(config, "bitclock").configure_periodic(FUNC(isa8_eistwib_device::tick_bitclock), attotime::from_hz(300000));
|
||||
}
|
||||
|
||||
isa8_eistwib_device::isa8_eistwib_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, ISA8_EIS_TWIB, tag, owner, clock)
|
||||
, device_isa8_card_interface(mconfig, *this)
|
||||
, m_uart8274(*this, "terminal")
|
||||
, m_sdlclogger(*this, "logger")
|
||||
, m_bitclock(false)
|
||||
, m_rts(false)
|
||||
, m_txd(false)
|
||||
, m_sw1(*this, "SW1")
|
||||
, m_isairq(*this, "W1")
|
||||
, m_installed(false)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Overloading methods
|
||||
//-------------------------------------------------
|
||||
void isa8_eistwib_device::device_start()
|
||||
{
|
||||
set_isa_device();
|
||||
m_installed = false;
|
||||
m_bitclock = false;
|
||||
save_item(NAME(m_installed));
|
||||
save_item(NAME(m_bitclock));
|
||||
}
|
||||
|
||||
void isa8_eistwib_device::device_reset()
|
||||
{
|
||||
int base = m_sw1->read();
|
||||
if (!m_installed)
|
||||
{
|
||||
LOG("Installing twib device at %04x\n", base);
|
||||
m_isa->install_device(
|
||||
base, base + 0x0f,
|
||||
read8_delegate(FUNC( isa8_eistwib_device::twib_r ), this),
|
||||
write8_delegate(FUNC( isa8_eistwib_device::twib_w ), this));
|
||||
m_installed = true;
|
||||
}
|
||||
// CD and CTS input are tied to ground
|
||||
m_uart8274->ctsa_w(0);
|
||||
m_uart8274->dcda_w(0);
|
||||
}
|
52
src/devices/bus/isa/eis_twib.h
Normal file
52
src/devices/bus/isa/eis_twib.h
Normal file
@ -0,0 +1,52 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: Joakim Larsson Edstrom
|
||||
#ifndef MAME_BUS_ISA_EIS_TWIB_H
|
||||
#define MAME_BUS_ISA_EIS_TWIB_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "isa.h"
|
||||
#include "machine/z80sio.h"
|
||||
#include "machine/timer.h"
|
||||
#include "machine/sdlc.h"
|
||||
|
||||
class isa8_eistwib_device :
|
||||
public device_t,
|
||||
public device_isa8_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
isa8_eistwib_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ8_MEMBER(twib_r);
|
||||
DECLARE_WRITE8_MEMBER(twib_w);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// devices
|
||||
required_device<i8274_new_device> m_uart8274;
|
||||
required_device<sdlc_logger_device> m_sdlclogger;
|
||||
|
||||
// optional information overrides
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
|
||||
// Timers
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tick_bitclock);
|
||||
bool m_bitclock;
|
||||
bool m_rts;
|
||||
bool m_txd;
|
||||
|
||||
// helpers
|
||||
required_ioport m_sw1;
|
||||
required_ioport m_isairq;
|
||||
bool m_installed;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(ISA8_EIS_TWIB, isa8_eistwib_device)
|
||||
|
||||
#endif // MAME_BUS_ISA_EIS_TWIB_H
|
@ -66,6 +66,7 @@
|
||||
#include "ne2000.h"
|
||||
#include "3c505.h"
|
||||
#include "eis_sad8852.h"
|
||||
#include "eis_twib.h"
|
||||
#include "np600.h"
|
||||
|
||||
// communication ports
|
||||
@ -129,6 +130,7 @@ void pc_isa8_cards(device_slot_interface &device)
|
||||
device.option_add("chessmsr", ISA8_CHESSMSR);
|
||||
device.option_add("finalchs", ISA8_FINALCHS);
|
||||
device.option_add("epc_mda", ISA8_EPC_MDA);
|
||||
device.option_add("epc_twib", ISA8_EIS_TWIB);
|
||||
}
|
||||
|
||||
void pc_isa16_cards(device_slot_interface &device)
|
||||
@ -171,6 +173,7 @@ void pc_isa16_cards(device_slot_interface &device)
|
||||
device.option_add("chessmsr", ISA8_CHESSMSR);
|
||||
device.option_add("finalchs", ISA8_FINALCHS);
|
||||
device.option_add("epc_mda", ISA8_EPC_MDA);
|
||||
device.option_add("epc_twib", ISA8_EIS_TWIB);
|
||||
// 16-bit
|
||||
device.option_add("ide", ISA16_IDE);
|
||||
device.option_add("ne2000", NE2000);
|
||||
|
@ -2156,7 +2156,7 @@ bool i8086_common_cpu_device::common_op(uint8_t op)
|
||||
|
||||
case 0xf0: // i_lock
|
||||
case 0xf1: // 0xf1 is 0xf0; verified on real CPU
|
||||
logerror("%06x: Warning - BUSLOCK\n", m_pc);
|
||||
//logerror("%06x: Warning - BUSLOCK\n", m_pc); // Why warn for using lock instruction?
|
||||
m_lock = true;
|
||||
m_no_interrupt = 1;
|
||||
CLK(NOP);
|
||||
|
@ -68,8 +68,9 @@
|
||||
#define LOG_DCD (1U << 8)
|
||||
#define LOG_SYNC (1U << 9)
|
||||
#define LOG_BIT (1U << 10)
|
||||
#define LOG_RTS (1U << 11)
|
||||
|
||||
//#define VERBOSE (LOG_INT | LOG_READ | LOG_SETUP | LOG_TX | LOG_CMD | LOG_CTS)
|
||||
//#define VERBOSE (LOG_CMD | LOG_SETUP | LOG_SYNC | LOG_BIT | LOG_TX )
|
||||
//#define LOG_OUTPUT_STREAM std::cout
|
||||
|
||||
#include "logmacro.h"
|
||||
@ -81,6 +82,7 @@
|
||||
#define LOGTX(...) LOGMASKED(LOG_TX, __VA_ARGS__)
|
||||
#define LOGRCV(...) LOGMASKED(LOG_RCV, __VA_ARGS__)
|
||||
#define LOGCTS(...) LOGMASKED(LOG_CTS, __VA_ARGS__)
|
||||
#define LOGRTS(...) LOGMASKED(LOG_RTS, __VA_ARGS__)
|
||||
#define LOGDCD(...) LOGMASKED(LOG_DCD, __VA_ARGS__)
|
||||
#define LOGSYNC(...) LOGMASKED(LOG_SYNC, __VA_ARGS__)
|
||||
#define LOGBIT(...) LOGMASKED(LOG_BIT, __VA_ARGS__)
|
||||
@ -297,7 +299,7 @@ inline void z80sio_channel::set_rts(int state)
|
||||
{
|
||||
if (bool(m_rts) != bool(state))
|
||||
{
|
||||
LOG("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index);
|
||||
LOGRTS("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index);
|
||||
out_rts_cb(m_rts = state);
|
||||
}
|
||||
}
|
||||
@ -341,7 +343,9 @@ inline void z80sio_channel::tx_setup_idle()
|
||||
break;
|
||||
case WR4_SYNC_MODE_SDLC:
|
||||
// SDLC transmit examples don't show flag being loaded, implying it's hard-coded on the transmit side
|
||||
tx_setup(0x7e, 8, true, false, false);
|
||||
//tx_setup(0x7e, 8, true, false, false);
|
||||
// Verified on a 8274, the 0x7e SYNC byte is required in CR7 to start transmitting, other values fails
|
||||
tx_setup(m_wr7, 8, true, false, false);
|
||||
break;
|
||||
}
|
||||
m_tx_in_pkt = false;
|
||||
@ -1073,6 +1077,8 @@ bool z80sio_channel::is_tx_idle() const
|
||||
//-------------------------------------------------
|
||||
void z80sio_channel::transmit_enable()
|
||||
{
|
||||
LOGTX("%s\n", FUNCNAME);
|
||||
|
||||
if (transmit_allowed())
|
||||
{
|
||||
if (is_tx_idle())
|
||||
@ -1113,7 +1119,7 @@ void z80sio_channel::transmit_enable()
|
||||
//-------------------------------------------------
|
||||
void z80sio_channel::transmit_complete()
|
||||
{
|
||||
LOG("%s %s\n",FUNCNAME, tag());
|
||||
if (!m_rts) LOGTX("%s %s\n",FUNCNAME, tag());
|
||||
|
||||
if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC)
|
||||
sync_tx_sr_empty();
|
||||
@ -1131,7 +1137,7 @@ void z80sio_channel::sync_tx_sr_empty()
|
||||
{
|
||||
if (!transmit_allowed())
|
||||
{
|
||||
LOGTX("%s() Channel %c Transmitter Disabled m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_wr5);
|
||||
if (!m_rts) LOGTX("%s() Channel %c Transmitter Disabled m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_wr5);
|
||||
m_tx_flags = 0;
|
||||
}
|
||||
else if (m_tx_forced_sync ||
|
||||
@ -1420,10 +1426,10 @@ int z80sio_channel::get_tx_word_length() const
|
||||
* Break/Abort latch. */
|
||||
uint8_t z80sio_channel::do_sioreg_rr0()
|
||||
{
|
||||
LOGR("%s\n", FUNCNAME);
|
||||
uint8_t tmp = m_rr0 & ~RR0_TX_BUFFER_EMPTY;
|
||||
if (get_tx_empty())
|
||||
tmp |= RR0_TX_BUFFER_EMPTY;
|
||||
LOGR("%s: %02x\n", FUNCNAME, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -1507,7 +1513,7 @@ void z80sio_channel::do_sioreg_wr0_resets(uint8_t data)
|
||||
LOGCMD("Z80SIO Channel %c : CRC_RESET_NULL\n", 'A' + m_index);
|
||||
break;
|
||||
case WR0_CRC_RESET_RX: /* In Synchronous mode: all Os (zeros) (CCITT-O CRC-16) */
|
||||
LOGCMD("Z80SIO Channel %c : CRC_RESET_RX - not implemented\n", 'A' + m_index);
|
||||
LOGCMD("Z80SIO Channel %c : CRC_RESET_RX\n", 'A' + m_index);
|
||||
m_rx_crc = ((m_wr4 & WR4_SYNC_MODE_MASK) == WR4_SYNC_MODE_SDLC) ? ~uint16_t(0U) : uint16_t(0U);
|
||||
m_rx_crc_en = false;
|
||||
break;
|
||||
@ -1520,6 +1526,8 @@ void z80sio_channel::do_sioreg_wr0_resets(uint8_t data)
|
||||
// Command is accepted in active part of packet only
|
||||
if (m_tx_in_pkt)
|
||||
m_rr0 &= ~RR0_TX_UNDERRUN;
|
||||
else
|
||||
LOGCMD(" - not accepted as not in active part of packet\n");
|
||||
break;
|
||||
default: /* Will not happen unless someone messes with the mask */
|
||||
logerror("Z80SIO Channel %c : %s Wrong CRC reset/init command:%02x\n", 'A' + m_index, FUNCNAME, data & WR0_CRC_RESET_CODE_MASK);
|
||||
@ -1531,7 +1539,7 @@ void z80sio_channel::do_sioreg_wr0(uint8_t data)
|
||||
m_wr0 = data;
|
||||
|
||||
if ((data & WR0_COMMAND_MASK) != WR0_NULL)
|
||||
LOGSETUP(" * %s %c Reg %02x <- %02x \n", owner()->tag(), 'A' + m_index, 0, data);
|
||||
LOGSETUP("\n * %s %c Reg %02x <- %02x \n", owner()->tag(), 'A' + m_index, 0, data);
|
||||
switch (data & WR0_COMMAND_MASK)
|
||||
{
|
||||
case WR0_NULL:
|
||||
@ -1601,31 +1609,15 @@ void z80sio_channel::do_sioreg_wr1(uint8_t data)
|
||||
{
|
||||
/* TODO: implement vector modifications when WR1 bit D2 is changed */
|
||||
m_wr1 = data;
|
||||
LOG("Z80SIO \"%s\" Channel %c : External Interrupt Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR1_EXT_INT_ENABLE) ? 1 : 0);
|
||||
LOG("Z80SIO \"%s\" Channel %c : Transmit Interrupt Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR1_TX_INT_ENABLE) ? 1 : 0);
|
||||
LOG("Z80SIO \"%s\" Channel %c : Status Affects Vector %u\n", owner()->tag(), 'A' + m_index, (data & WR1_STATUS_VECTOR) ? 1 : 0);
|
||||
LOG("Z80SIO \"%s\" Channel %c : Wait/Ready Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR1_WRDY_ENABLE) ? 1 : 0);
|
||||
LOG("Z80SIO \"%s\" Channel %c : Wait/Ready Function %s\n", owner()->tag(), 'A' + m_index, (data & WR1_WRDY_FUNCTION) ? "Ready" : "Wait");
|
||||
LOG("Z80SIO \"%s\" Channel %c : Wait/Ready on %s\n", owner()->tag(), 'A' + m_index, (data & WR1_WRDY_ON_RX_TX) ? "Receive" : "Transmit");
|
||||
|
||||
switch (data & WR1_RX_INT_MODE_MASK)
|
||||
{
|
||||
case WR1_RX_INT_DISABLE:
|
||||
LOG("Z80SIO \"%s\" Channel %c : Receiver Interrupt Disabled\n", owner()->tag(), 'A' + m_index);
|
||||
break;
|
||||
|
||||
case WR1_RX_INT_FIRST:
|
||||
LOG("Z80SIO \"%s\" Channel %c : Receiver Interrupt on First Character\n", owner()->tag(), 'A' + m_index);
|
||||
break;
|
||||
|
||||
case WR1_RX_INT_ALL_PARITY:
|
||||
LOG("Z80SIO \"%s\" Channel %c : Receiver Interrupt on All Characters, Parity Affects Vector\n", owner()->tag(), 'A' + m_index);
|
||||
break;
|
||||
|
||||
case WR1_RX_INT_ALL:
|
||||
LOG("Z80SIO \"%s\" Channel %c : Receiver Interrupt on All Characters\n", owner()->tag(), 'A' + m_index);
|
||||
break;
|
||||
}
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c :\n", owner()->tag(), 'A' + m_index);
|
||||
LOGSETUP(" - External Interrupt Enable %u\n", (data & WR1_EXT_INT_ENABLE) ? 1 : 0);
|
||||
LOGSETUP(" - Transmit Interrupt Enable %u\n", (data & WR1_TX_INT_ENABLE) ? 1 : 0);
|
||||
LOGSETUP(" - Status Affects Vector %u\n", (data & WR1_STATUS_VECTOR) ? 1 : 0);
|
||||
LOGSETUP(" - Wait/Ready Enable %u\n", (data & WR1_WRDY_ENABLE) ? 1 : 0);
|
||||
LOGSETUP(" - Wait/Ready Function %s\n", (data & WR1_WRDY_FUNCTION) ? "Ready" : "Wait");
|
||||
LOGSETUP(" - Wait/Ready on %s\n", (data & WR1_WRDY_ON_RX_TX) ? "Rx" : "Tx");
|
||||
LOGSETUP(" - Receiver Interrupt %s\n", std::array<char const *, 4>
|
||||
{{"Disabled", "on First Character", "on All Characters, Parity Affects Vector", "on All Characters"}}[(m_wr2 >> 3) & 0x03]);
|
||||
|
||||
if (!(data & WR1_WRDY_ENABLE))
|
||||
set_ready(false);
|
||||
@ -1638,7 +1630,19 @@ void z80sio_channel::do_sioreg_wr1(uint8_t data)
|
||||
void z80sio_channel::do_sioreg_wr2(uint8_t data)
|
||||
{
|
||||
m_wr2 = data;
|
||||
LOG("Z80SIO \"%s\" Channel %c : Interrupt Vector %02x\n", owner()->tag(), 'A' + m_index, data);
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : ", owner()->tag(), 'A' + m_index);
|
||||
if (m_index == 0)
|
||||
{
|
||||
LOGSETUP(" - INT/DMA priority and mode: %02x\n", m_wr2 & 0x07);
|
||||
LOGSETUP(" - Interrupt mode: %s\n", std::array<char const *, 4> {{"85-1", "85-2", "85-3", "86"}}[(m_wr2 >> 3) & 0x03]);
|
||||
LOGSETUP(" - Vector mode: %s\n", (m_wr2 & 0x20) ? "Vectored" : "Non-vectored");
|
||||
LOGSETUP(" - Rx INT mask: %d\n", (m_wr2 >> 6) & 0x01 );
|
||||
LOGSETUP(" - Pin 10: %s\n", (m_wr2 & 0x80) ? "SYNCB" : "RTSB");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGSETUP("Interrupt Vector %02x\n", m_wr2);
|
||||
}
|
||||
}
|
||||
|
||||
void z80sio_channel::do_sioreg_wr3(uint8_t data)
|
||||
@ -1647,12 +1651,13 @@ void z80sio_channel::do_sioreg_wr3(uint8_t data)
|
||||
LOGSETUP("Z80SIO Channel %c : Sync Character Load Inhibit %u\n", 'A' + m_index, (data & WR3_SYNC_CHAR_LOAD_INHIBIT) ? 1 : 0);
|
||||
LOGSETUP("Z80SIO Channel %c : Receive CRC Enable %u\n", 'A' + m_index, (data & WR3_RX_CRC_ENABLE) ? 1 : 0);
|
||||
LOGSETUP("Z80SIO Channel %c : Auto Enables %u\n", 'A' + m_index, (data & WR3_AUTO_ENABLES) ? 1 : 0);
|
||||
LOGSETUP("Z80SIO Channel %c : Receiver Bits/Character %u\n", 'A' + m_index, get_rx_word_length());
|
||||
if (data & WR3_ENTER_HUNT_PHASE)
|
||||
LOGCMD("Z80SIO Channel %c : Enter Hunt Phase\n", 'A' + m_index);
|
||||
LOGSETUP("Z80SIO Channel %c : Enter Hunt Phase %u\n", 'A' + m_index, (data & WR3_ENTER_HUNT_PHASE) ? 1 : 0);
|
||||
//if (data & WR3_ENTER_HUNT_PHASE)
|
||||
//LOGCMD("Z80SIO Channel %c : Enter Hunt Phase\n", 'A' + m_index);
|
||||
|
||||
bool const was_allowed(receive_allowed());
|
||||
m_wr3 = data;
|
||||
LOG("Z80SIO Channel %c : Receiver Bits/Character %u\n", 'A' + m_index, get_rx_word_length()); // depends on m_wr3 being updated
|
||||
|
||||
if (!was_allowed && receive_allowed())
|
||||
{
|
||||
@ -1668,25 +1673,27 @@ void z80sio_channel::do_sioreg_wr3(uint8_t data)
|
||||
void z80sio_channel::do_sioreg_wr4(uint8_t data)
|
||||
{
|
||||
m_wr4 = data;
|
||||
LOG("Z80SIO \"%s\" Channel %c : Parity Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0);
|
||||
LOG("Z80SIO \"%s\" Channel %c : Parity %s\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd");
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Parity Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0);
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Parity %s\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd");
|
||||
if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC)
|
||||
LOG("Z80SIO \"%s\" Channel %c : Synchronous Mode\n", owner()->tag(), 'A' + m_index);
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Synchronous Mode %s\n", owner()->tag(), 'A' + m_index,
|
||||
std::array<char const *, 4> {{"Monosync", "Bisync", "HDLC/SDLC", "External"}}[(m_wr4 >> 4) & 0x03]);
|
||||
else
|
||||
LOG("Z80SIO \"%s\" Channel %c : Stop Bits %g\n", owner()->tag(), 'A' + m_index, (((m_wr4 & WR4_STOP_BITS_MASK) >> 2) + 1) / 2.);
|
||||
LOG("Z80SIO \"%s\" Channel %c : Clock Mode %uX\n", owner()->tag(), 'A' + m_index, get_clock_mode());
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Stop Bits %g\n", owner()->tag(), 'A' + m_index, (((m_wr4 & WR4_STOP_BITS_MASK) >> 2) + 1) / 2.);
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Clock Mode %uX\n", owner()->tag(), 'A' + m_index, get_clock_mode());
|
||||
}
|
||||
|
||||
void z80sio_channel::do_sioreg_wr5(uint8_t data)
|
||||
{
|
||||
m_wr5 = data;
|
||||
LOG("Z80SIO Channel %c : Transmitter Enable %u\n", 'A' + m_index, (data & WR5_TX_ENABLE) ? 1 : 0);
|
||||
LOG("Z80SIO Channel %c : Transmitter Bits/Character %u\n", 'A' + m_index, get_tx_word_length());
|
||||
LOG("Z80SIO Channel %c : Transmit CRC Enable %u\n", 'A' + m_index, (data & WR5_TX_CRC_ENABLE) ? 1 : 0);
|
||||
LOG("Z80SIO Channel %c : %s Frame Check Polynomial\n", 'A' + m_index, (data & WR5_CRC16) ? "CRC-16" : "SDLC");
|
||||
LOG("Z80SIO Channel %c : Send Break %u\n", 'A' + m_index, (data & WR5_SEND_BREAK) ? 1 : 0);
|
||||
LOG("Z80SIO Channel %c : Request to Send %u\n", 'A' + m_index, (data & WR5_RTS) ? 1 : 0);
|
||||
LOG("Z80SIO Channel %c : Data Terminal Ready %u\n", 'A' + m_index, (data & WR5_DTR) ? 1 : 0);
|
||||
LOGSETUP("Z80SIO Channel %c\n", 'A' + m_index);
|
||||
LOGSETUP(" - Transmitter Enable %u\n", (data & WR5_TX_ENABLE) ? 1 : 0);
|
||||
LOGSETUP(" - Transmitter Bits/Character %u\n", get_tx_word_length());
|
||||
LOGSETUP(" - Transmit CRC Enable %u\n", (data & WR5_TX_CRC_ENABLE) ? 1 : 0);
|
||||
LOGSETUP(" - %s Frame Check Polynomial\n", (data & WR5_CRC16) ? "CRC-16" : "SDLC");
|
||||
LOGSETUP(" - Send Break %u\n", (data & WR5_SEND_BREAK) ? 1 : 0);
|
||||
LOGSETUP(" - Request to Send %u\n", (data & WR5_RTS) ? 1 : 0);
|
||||
LOGSETUP(" - Data Terminal Ready %u\n", (data & WR5_DTR) ? 1 : 0);
|
||||
|
||||
if (~data & WR5_TX_ENABLE)
|
||||
m_uart->clear_interrupt(m_index, INT_TRANSMIT);
|
||||
@ -1694,13 +1701,13 @@ void z80sio_channel::do_sioreg_wr5(uint8_t data)
|
||||
|
||||
void z80sio_channel::do_sioreg_wr6(uint8_t data)
|
||||
{
|
||||
LOG("Z80SIO \"%s\" Channel %c : Transmit Sync/Sync 1/SDLC Address %02x\n", owner()->tag(), 'A' + m_index, data);
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Transmit Sync/Sync 1/SDLC Address %02x\n", owner()->tag(), 'A' + m_index, data);
|
||||
m_wr6 = data;
|
||||
}
|
||||
|
||||
void z80sio_channel::do_sioreg_wr7(uint8_t data)
|
||||
{
|
||||
LOG("Z80SIO \"%s\" Channel %c : Receive Sync/Sync 2/SDLC Flag %02x\n", owner()->tag(), 'A' + m_index, data);
|
||||
LOGSETUP("Z80SIO \"%s\" Channel %c : Receive Sync/Sync 2/SDLC Flag %02x\n", owner()->tag(), 'A' + m_index, data);
|
||||
m_wr7 = data;
|
||||
}
|
||||
|
||||
@ -1714,7 +1721,7 @@ void z80sio_channel::control_write(uint8_t data)
|
||||
if (reg != 0)
|
||||
{
|
||||
LOGSETUP(" * %s %c Reg %02x <- %02x - %s\n", tag(), 'A' + m_index, reg, data, std::array<char const *, 8>
|
||||
{{"WR0", "WR1", "WR2", "WR3 - Async Rx setup", "WR4 - Async Clock, Parity and stop bits", "WR5 - Async Tx setup", "WR6", "WR7"}}[reg]);
|
||||
{{"WR0", "WR1", "WR2", "WR3", "WR4", "WR5", "WR6", "WR7"}}[reg]);
|
||||
// mask out register index
|
||||
m_wr0 &= ~WR0_REGISTER_MASK;
|
||||
}
|
||||
@ -1771,10 +1778,14 @@ void z80sio_channel::data_write(uint8_t data)
|
||||
m_tx_data = data;
|
||||
set_tx_empty(get_tx_empty() , false);
|
||||
if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC)
|
||||
{
|
||||
LOGTX("Z80SIO: WR4_STOP_BITS_SYNC detected\n");
|
||||
m_tx_in_pkt = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ALL_SENT is only meaningful in async mode, in sync mode it's always 1
|
||||
LOGTX("Z80SIO: WR4_STOP_BITS_SYNC *not* detected\n");
|
||||
m_rr1 &= ~RR1_ALL_SENT;
|
||||
m_all_sent_delay = 0;
|
||||
}
|
||||
@ -2208,7 +2219,7 @@ WRITE_LINE_MEMBER( z80sio_channel::dcd_w )
|
||||
{
|
||||
if (bool(m_dcd) != bool(state))
|
||||
{
|
||||
LOG("Z80SIO Channel %c : DCD %u\n", 'A' + m_index, state);
|
||||
LOGDCD("Z80SIO Channel %c : DCD %u\n", 'A' + m_index, state);
|
||||
|
||||
bool const was_allowed(receive_allowed());
|
||||
m_dcd = state;
|
||||
@ -2228,7 +2239,7 @@ WRITE_LINE_MEMBER( z80sio_channel::sync_w )
|
||||
{
|
||||
if (bool(m_sync) != bool(state))
|
||||
{
|
||||
LOG("Z80SIO Channel %c : Sync %u\n", 'A' + m_index, state);
|
||||
LOGSYNC("Z80SIO Channel %c : Sync %u\n", 'A' + m_index, state);
|
||||
|
||||
m_sync = state;
|
||||
|
||||
@ -2389,9 +2400,9 @@ WRITE_LINE_MEMBER( z80sio_channel::txc_w )
|
||||
m_tx_count = get_clock_mode() / 2;
|
||||
// Send out a delayed half bit
|
||||
bool new_txd = BIT(m_tx_delay , 3);
|
||||
LOGBIT("%.6f TX %d DLY %x\n" , machine().time().as_double() , new_txd , m_tx_delay & 0xf);
|
||||
if (new_txd != m_txd && !(m_wr5 & WR5_SEND_BREAK))
|
||||
{
|
||||
LOGBIT("%.6f TX %d DLY %x\n" , machine().time().as_double() , new_txd , m_tx_delay & 0xf);
|
||||
out_txd_cb(new_txd);
|
||||
}
|
||||
m_txd = new_txd;
|
||||
|
@ -59,6 +59,7 @@
|
||||
//#include "bus/isa/isa_cards.h"
|
||||
#include "bus/isa/ega.h"
|
||||
#include "bus/isa/mda.h"
|
||||
#include "bus/isa/eis_twib.h"
|
||||
#include "machine/pc_lpt.h"
|
||||
|
||||
#include "machine/ram.h"
|
||||
@ -720,6 +721,7 @@ 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_twib", ISA8_EIS_TWIB);
|
||||
// device.option_add("epc_hdc1065", ISA8_EPC_HDC1065);
|
||||
// device.option_add("epc_mb1080", ISA8_EPC_MB1080);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user