(MESS) ql: Added RS-232 ports. [Curt Coder]

This commit is contained in:
Curt Coder 2013-05-21 13:36:16 +00:00
parent dd4763f134
commit d0db21bb01
4 changed files with 219 additions and 187 deletions

View File

@ -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")

View File

@ -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;

View File

@ -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);
}

View File

@ -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