mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
(MESS) ql: Added RS-232 ports. [Curt Coder]
This commit is contained in:
parent
dd4763f134
commit
d0db21bb01
@ -133,6 +133,39 @@ WRITE8_MEMBER( ql_state::ipc_port1_w )
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ipc_port2_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER( ql_state::ipc_port2_r )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
0 Serial data input (SER2 RxD, SER1 TxD)
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7 ZX8302 serial link input/output (COMDATA)
|
||||
|
||||
*/
|
||||
|
||||
UINT8 data = 0;
|
||||
|
||||
// SER2 serial data input
|
||||
data |= m_ser2->rx();
|
||||
|
||||
// COMDATA
|
||||
data |= m_comdata << 7;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ipc_port2_w -
|
||||
//-------------------------------------------------
|
||||
@ -143,13 +176,13 @@ WRITE8_MEMBER( ql_state::ipc_port2_w )
|
||||
|
||||
bit description
|
||||
|
||||
0 Serial data input (SER2 RxD, SER1 TxD)
|
||||
0
|
||||
1 Speaker output
|
||||
2 Interrupt output (IPL0-2)
|
||||
3 Interrupt output (IPL1)
|
||||
4 Serial Clear-to-Send output (SER1 CTS)
|
||||
5 Serial Data Terminal Ready output (SER2 DTR)
|
||||
6 not connected
|
||||
6
|
||||
7 ZX8302 serial link input/output (COMDATA)
|
||||
|
||||
*/
|
||||
@ -173,11 +206,10 @@ WRITE8_MEMBER( ql_state::ipc_port2_w )
|
||||
m_ipl = ipl;
|
||||
}
|
||||
|
||||
// clear to send
|
||||
//rs232_cts_w(m_ser1, !BIT(data, 4));
|
||||
// TODO SER1 clear to send
|
||||
|
||||
// data terminal ready
|
||||
//rs232_dtr_w(m_ser2, !BIT(data, 5));
|
||||
// SER2 data terminal ready
|
||||
m_ser2->dtr_w(!BIT(data, 5));
|
||||
|
||||
// COMDATA
|
||||
m_comdata = BIT(data, 7);
|
||||
@ -186,35 +218,6 @@ WRITE8_MEMBER( ql_state::ipc_port2_w )
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ipc_port2_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER( ql_state::ipc_port2_r )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
0 Serial data input (SER2 RxD, SER1 TxD)
|
||||
1 Speaker output
|
||||
2 Interrupt output (IPL0-2)
|
||||
3 Interrupt output (IPL1)
|
||||
4 Serial Clear-to-Send output (SER2 CTS)
|
||||
5 Serial Data Terminal Ready output (SER1 DTR)
|
||||
6 not connected
|
||||
7 ZX8302 serial link input/output (COMDATA)
|
||||
|
||||
*/
|
||||
|
||||
// int irq = (m_ser2_rxd | m_ser1_txd);
|
||||
|
||||
// m_ipc->set_input_line(INPUT_LINE_IRQ0, irq);
|
||||
|
||||
return (m_comdata << 7);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ipc_t1_r -
|
||||
//-------------------------------------------------
|
||||
@ -777,9 +780,9 @@ static ZX8302_INTERFACE( ql_zx8302_intf )
|
||||
DEVCB_DRIVER_LINE_MEMBER(ql_state, ql_baudx4_w),
|
||||
DEVCB_DRIVER_LINE_MEMBER(ql_state, ql_comdata_w),
|
||||
DEVCB_NULL, // TXD1
|
||||
DEVCB_NULL, // TXD2
|
||||
DEVCB_DEVICE_LINE_MEMBER(RS232_B_TAG, serial_port_device, tx),
|
||||
DEVCB_NULL, // DTR1
|
||||
DEVCB_NULL, // CTS2
|
||||
DEVCB_DEVICE_LINE_MEMBER(RS232_B_TAG, rs232_port_device, cts_r),
|
||||
DEVCB_NULL, // NETOUT
|
||||
DEVCB_NULL, // NETIN
|
||||
DEVCB_DRIVER_LINE_MEMBER(ql_state, zx8302_mdselck_w),
|
||||
@ -882,6 +885,34 @@ static MICRODRIVE_CONFIG( mdv2_config )
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rs232_port_interface rs232a_intf
|
||||
//-------------------------------------------------
|
||||
|
||||
static const rs232_port_interface rs232a_intf =
|
||||
{
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rs232_port_interface rs232b_intf
|
||||
//-------------------------------------------------
|
||||
|
||||
static const rs232_port_interface rs232b_intf =
|
||||
{
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACHINE INITIALIZATION
|
||||
@ -997,12 +1028,12 @@ static MACHINE_CONFIG_START( ql, ql_state )
|
||||
// devices
|
||||
MCFG_ZX8301_ADD(ZX8301_TAG, X1, ql_zx8301_intf)
|
||||
MCFG_ZX8302_ADD(ZX8302_TAG, X1, ql_zx8302_intf)
|
||||
|
||||
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ql_floppy_interface)
|
||||
MCFG_WD1772_ADD(WD1772_TAG,ql_wd17xx_interface)
|
||||
|
||||
MCFG_MICRODRIVE_ADD(MDV_1, mdv1_config)
|
||||
MCFG_MICRODRIVE_ADD(MDV_2, mdv2_config)
|
||||
MCFG_RS232_PORT_ADD(RS232_A_TAG, rs232a_intf, default_rs232_devices, NULL, NULL) // wired as DCE
|
||||
MCFG_RS232_PORT_ADD(RS232_B_TAG, rs232b_intf, default_rs232_devices, NULL, NULL) // wired as DTE
|
||||
|
||||
// cartridge
|
||||
MCFG_CARTSLOT_ADD("cart")
|
||||
|
@ -4,6 +4,7 @@
|
||||
#define __QL__
|
||||
|
||||
#include "machine/ram.h"
|
||||
#include "machine/serial.h"
|
||||
#include "machine/wd17xx.h"
|
||||
|
||||
#define SCREEN_TAG "screen"
|
||||
@ -14,6 +15,8 @@
|
||||
#define ZX8301_TAG "ic22"
|
||||
#define ZX8302_TAG "ic23"
|
||||
#define WD1772_TAG "wd1772"
|
||||
#define RS232_A_TAG "ser1"
|
||||
#define RS232_B_TAG "ser2"
|
||||
|
||||
#define ROMBANK_TAG "rombank"
|
||||
#define RAMBANK_TAG "rambank"
|
||||
@ -75,6 +78,8 @@ public:
|
||||
m_speaker(*this, "speaker"),
|
||||
m_mdv1(*this, MDV_1),
|
||||
m_mdv2(*this, MDV_2),
|
||||
m_ser1(*this, RS232_A_TAG),
|
||||
m_ser2(*this, RS232_A_TAG),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_fdc(*this, WD1772_TAG),
|
||||
m_printer(*this, PRINTER_TAG),
|
||||
@ -97,6 +102,8 @@ public:
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<microdrive_image_device> m_mdv1;
|
||||
required_device<microdrive_image_device> m_mdv2;
|
||||
required_device<rs232_port_device> m_ser1;
|
||||
required_device<rs232_port_device> m_ser2;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<wd1772_device> m_fdc;
|
||||
required_device<printer_image_device> m_printer;
|
||||
|
@ -33,72 +33,9 @@
|
||||
#define LOG 0
|
||||
|
||||
|
||||
// IPC serial state
|
||||
enum
|
||||
{
|
||||
IPC_START,
|
||||
IPC_DATA,
|
||||
IPC_STOP
|
||||
};
|
||||
|
||||
|
||||
// baud rate
|
||||
enum
|
||||
{
|
||||
BAUD_19200 = 0x00,
|
||||
BAUD_9600 = 0x01,
|
||||
BAUD_4800 = 0x02,
|
||||
BAUD_2400 = 0x03,
|
||||
BAUD_1200 = 0x04,
|
||||
BAUD_600 = 0x05,
|
||||
BAUD_300 = 0x06,
|
||||
BAUD_75 = 0x07,
|
||||
BAUD_MASK = 0x07,
|
||||
};
|
||||
|
||||
// transmit mode
|
||||
enum
|
||||
{
|
||||
MODE_SER1 = 0x00,
|
||||
MODE_SER2 = 0x08,
|
||||
MODE_MDV = 0x10,
|
||||
MODE_NET = 0x18,
|
||||
MODE_MASK = 0x18,
|
||||
};
|
||||
|
||||
// interrupts
|
||||
enum
|
||||
{
|
||||
INT_GAP = 0x01,
|
||||
INT_INTERFACE = 0x02,
|
||||
INT_TRANSMIT = 0x04,
|
||||
INT_FRAME = 0x08,
|
||||
INT_EXTERNAL = 0x10,
|
||||
};
|
||||
|
||||
// status register
|
||||
enum
|
||||
{
|
||||
STATUS_NETWORK_PORT = 0x01,
|
||||
STATUS_TX_BUFFER_FULL = 0x02,
|
||||
STATUS_RX_BUFFER_FULL = 0x04,
|
||||
STATUS_MICRODRIVE_GAP = 0x08,
|
||||
};
|
||||
|
||||
// transmit bits
|
||||
enum
|
||||
{
|
||||
TXD_START = 0,
|
||||
TXD_STOP = 9,
|
||||
TXD_STOP2 = 10,
|
||||
};
|
||||
|
||||
|
||||
// Monday 1st January 1979 00:00:00 UTC
|
||||
enum
|
||||
{
|
||||
RTC_BASE_ADJUST = 283996800,
|
||||
};
|
||||
static const int RTC_BASE_ADJUST = 283996800;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -224,70 +161,6 @@ inline void zx8302_device::transmit_ipc_data()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// transmit_bit - transmit serial bit
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void zx8302_device::transmit_bit(int state)
|
||||
{
|
||||
switch (m_tcr & MODE_MASK)
|
||||
{
|
||||
case MODE_SER1:
|
||||
m_out_txd1_func(state);
|
||||
break;
|
||||
|
||||
case MODE_SER2:
|
||||
m_out_txd2_func(state);
|
||||
break;
|
||||
|
||||
case MODE_MDV:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case MODE_NET:
|
||||
m_out_netout_func(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// transmit_data - transmit serial data
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void zx8302_device::transmit_serial_data()
|
||||
{
|
||||
switch (m_tx_bits)
|
||||
{
|
||||
case TXD_START:
|
||||
if (!(m_irq & INT_TRANSMIT))
|
||||
{
|
||||
transmit_bit(0);
|
||||
m_tx_bits++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
transmit_bit(BIT(m_tdr, 0));
|
||||
m_tdr >>= 1;
|
||||
m_tx_bits++;
|
||||
break;
|
||||
|
||||
case TXD_STOP:
|
||||
transmit_bit(1);
|
||||
m_tx_bits++;
|
||||
break;
|
||||
|
||||
case TXD_STOP2:
|
||||
transmit_bit(1);
|
||||
m_tx_bits = TXD_START;
|
||||
m_status &= ~STATUS_TX_BUFFER_FULL;
|
||||
trigger_interrupt(INT_TRANSMIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
@ -296,8 +169,10 @@ inline void zx8302_device::transmit_serial_data()
|
||||
//-------------------------------------------------
|
||||
// zx8302_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
zx8302_device::zx8302_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ZX8302, "Sinclair ZX8302", tag, owner, clock),
|
||||
device_serial_interface(mconfig, *this),
|
||||
m_idr(1),
|
||||
m_irq(0),
|
||||
m_ctr(time(NULL) + RTC_BASE_ADJUST),
|
||||
@ -308,7 +183,6 @@ zx8302_device::zx8302_device(const machine_config &mconfig, const char *tag, dev
|
||||
m_ipc_rx(0),
|
||||
m_ipc_busy(0),
|
||||
m_baudx4(0),
|
||||
m_tx_bits(0),
|
||||
m_track(0)
|
||||
{
|
||||
}
|
||||
@ -340,7 +214,6 @@ void zx8302_device::device_start()
|
||||
m_in_raw2_func.resolve(in_raw2_cb, *this);
|
||||
|
||||
// allocate timers
|
||||
m_txd_timer = timer_alloc(TIMER_TXD);
|
||||
m_baudx4_timer = timer_alloc(TIMER_BAUDX4);
|
||||
m_rtc_timer = timer_alloc(TIMER_RTC);
|
||||
m_gap_timer = timer_alloc(TIMER_GAP);
|
||||
@ -362,7 +235,6 @@ void zx8302_device::device_start()
|
||||
save_item(NAME(m_ipc_rx));
|
||||
save_item(NAME(m_ipc_busy));
|
||||
save_item(NAME(m_baudx4));
|
||||
save_item(NAME(m_tx_bits));
|
||||
save_item(NAME(m_mdv_data));
|
||||
save_item(NAME(m_track));
|
||||
}
|
||||
@ -376,10 +248,6 @@ void zx8302_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_TXD:
|
||||
transmit_serial_data();
|
||||
break;
|
||||
|
||||
case TIMER_BAUDX4:
|
||||
m_baudx4 = !m_baudx4;
|
||||
m_out_baudx4_func(m_baudx4);
|
||||
@ -404,6 +272,80 @@ void zx8302_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// tra_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
void zx8302_device::tra_callback()
|
||||
{
|
||||
switch (m_tcr & MODE_MASK)
|
||||
{
|
||||
case MODE_SER1:
|
||||
m_out_txd1_func(transmit_register_get_data_bit());
|
||||
break;
|
||||
|
||||
case MODE_SER2:
|
||||
m_out_txd2_func(transmit_register_get_data_bit());
|
||||
break;
|
||||
|
||||
case MODE_MDV:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case MODE_NET:
|
||||
m_out_netout_func(transmit_register_get_data_bit());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// tra_complete -
|
||||
//-------------------------------------------------
|
||||
|
||||
void zx8302_device::tra_complete()
|
||||
{
|
||||
m_status &= ~STATUS_TX_BUFFER_FULL;
|
||||
|
||||
trigger_interrupt(INT_TRANSMIT);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rcv_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
void zx8302_device::rcv_callback()
|
||||
{
|
||||
switch (m_tcr & MODE_MASK)
|
||||
{
|
||||
case MODE_NET:
|
||||
receive_register_update_bit(m_in_netin_func());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rcv_complete -
|
||||
//-------------------------------------------------
|
||||
|
||||
void zx8302_device::rcv_complete()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_callback -
|
||||
//-------------------------------------------------
|
||||
|
||||
void zx8302_device::input_callback(UINT8 state)
|
||||
{
|
||||
m_input_state = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rtc_r - real time clock read
|
||||
//-------------------------------------------------
|
||||
@ -455,8 +397,10 @@ WRITE8_MEMBER( zx8302_device::control_w )
|
||||
|
||||
m_tcr = data;
|
||||
|
||||
m_txd_timer->adjust(attotime::zero, 0, attotime::from_hz(baud));
|
||||
m_baudx4_timer->adjust(attotime::zero, 0, attotime::from_hz(baudx4));
|
||||
|
||||
set_tra_rate(baud);
|
||||
set_data_frame(8, 2, SERIAL_PARITY_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,6 +94,7 @@ struct zx8302_interface
|
||||
// ======================> zx8302_device
|
||||
|
||||
class zx8302_device : public device_t,
|
||||
public device_serial_interface,
|
||||
public zx8302_interface
|
||||
{
|
||||
public:
|
||||
@ -121,17 +122,70 @@ protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
virtual void device_config_complete();
|
||||
|
||||
// device_serial_interface overrides
|
||||
virtual void tra_callback();
|
||||
virtual void tra_complete();
|
||||
virtual void rcv_callback();
|
||||
virtual void rcv_complete();
|
||||
virtual void input_callback(UINT8 state);
|
||||
|
||||
inline void trigger_interrupt(UINT8 line);
|
||||
inline void transmit_ipc_data();
|
||||
inline void transmit_bit(int state);
|
||||
inline void transmit_serial_data();
|
||||
|
||||
private:
|
||||
static const device_timer_id TIMER_TXD = 0;
|
||||
static const device_timer_id TIMER_BAUDX4 = 1;
|
||||
static const device_timer_id TIMER_RTC = 2;
|
||||
static const device_timer_id TIMER_GAP = 3;
|
||||
static const device_timer_id TIMER_IPC = 4;
|
||||
enum
|
||||
{
|
||||
TIMER_BAUDX4 = 0,
|
||||
TIMER_RTC,
|
||||
TIMER_GAP,
|
||||
TIMER_IPC
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
IPC_START,
|
||||
IPC_DATA,
|
||||
IPC_STOP
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BAUD_19200 = 0,
|
||||
BAUD_9600,
|
||||
BAUD_4800,
|
||||
BAUD_2400,
|
||||
BAUD_1200,
|
||||
BAUD_600,
|
||||
BAUD_300,
|
||||
BAUD_75,
|
||||
BAUD_MASK = 0x07
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_SER1 = 0x00,
|
||||
MODE_SER2 = 0x08,
|
||||
MODE_MDV = 0x10,
|
||||
MODE_NET = 0x18,
|
||||
MODE_MASK = 0x18,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
INT_GAP = 0x01,
|
||||
INT_INTERFACE = 0x02,
|
||||
INT_TRANSMIT = 0x04,
|
||||
INT_FRAME = 0x08,
|
||||
INT_EXTERNAL = 0x10,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
STATUS_NETWORK_PORT = 0x01,
|
||||
STATUS_TX_BUFFER_FULL = 0x02,
|
||||
STATUS_RX_BUFFER_FULL = 0x04,
|
||||
STATUS_MICRODRIVE_GAP = 0x08,
|
||||
};
|
||||
|
||||
devcb_resolved_write_line m_out_ipl1l_func;
|
||||
devcb_resolved_write_line m_out_baudx4_func;
|
||||
@ -168,15 +222,11 @@ private:
|
||||
int m_ipc_busy; // IPC busy
|
||||
int m_baudx4; // IPC baud x4
|
||||
|
||||
// serial transmit state
|
||||
int m_tx_bits; // bits transmitted
|
||||
|
||||
// microdrive state
|
||||
UINT8 m_mdv_data[2]; // track data register
|
||||
int m_track; // current track
|
||||
|
||||
// timers
|
||||
emu_timer *m_txd_timer; // transmit timer
|
||||
emu_timer *m_baudx4_timer; // baud x4 timer
|
||||
emu_timer *m_rtc_timer; // real time clock timer
|
||||
emu_timer *m_gap_timer; // microdrive gap timer
|
||||
|
Loading…
Reference in New Issue
Block a user