Merge remote-tracking branch 'upstream/master'

This commit is contained in:
AJR 2017-06-06 11:45:33 -04:00
commit 23e74ee804
10 changed files with 511 additions and 4 deletions

View File

@ -2362,7 +2362,7 @@ end
--@src/devices/bus/ti99/joyport/joyport.h,BUSES["TI99"] = true
--@src/devices/bus/ti99/peb/peribox.h,BUSES["TI99"] = true
--@src/devices/bus/ti99/internal/genboard.h,BUSES["TI99"] = true
--@src/devices/bus/ti99/hexbus/hexbus.h,BUSES["TI99"] = true
---------------------------------------------------
if (BUSES["TI99"]~=null) then
@ -2392,6 +2392,10 @@ if (BUSES["TI99"]~=null) then
MAME_DIR .. "src/devices/bus/ti99/gromport/multiconn.h",
MAME_DIR .. "src/devices/bus/ti99/gromport/singleconn.cpp",
MAME_DIR .. "src/devices/bus/ti99/gromport/singleconn.h",
MAME_DIR .. "src/devices/bus/ti99/hexbus/hexbus.cpp",
MAME_DIR .. "src/devices/bus/ti99/hexbus/hexbus.h",
MAME_DIR .. "src/devices/bus/ti99/hexbus/hx5102.cpp",
MAME_DIR .. "src/devices/bus/ti99/hexbus/hx5102.h",
MAME_DIR .. "src/devices/bus/ti99/joyport/handset.cpp",
MAME_DIR .. "src/devices/bus/ti99/joyport/handset.h",
MAME_DIR .. "src/devices/bus/ti99/joyport/joyport.cpp",

View File

@ -0,0 +1,282 @@
// license:LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************
=========== Hexbus peripheral bus ===========
The Hexbus is a 4-bit peripheral bus with master/slave coordination. Bytes
are written over the bus in two passes. Hexbus was the designated standard
peripheral bus for TI computers before TI left the home computer market.
The Hexbus was also named IPB = Intelligent Peripheral Bus [1]
Existing devices are floppy drive, RS232 serial adapter, and
a "Wafertape" drive (kind of tape streamer)
Hexbus connector (console)
+---+---+---+---+
| 4 | 3 | 2 | 1 | 4 = L; 3 = BAV*; 2 = ADB1; 1 = ADB0
+---+---+---+---+
| 8 | 7 | 6 | 5 | 8 = ADB3; 7 = ADB2; 6 = nc; 5 = HSK*
+---+---+---+---+
ADBx = Hexbus data bit X (x=0..3)
HSK* = Handshake
BAV* = Bus available (0=yes)
Theory of operation
-------------------
The bus connects all devices in a daisy chain. The lines are inactive high
and pulled down by any device that sets them to 0.
HSK* is a synchronization line for transmitting single bytes.
BAV* is a synchronization line for complete request-response pairs
Before a byte can be sent, the sender must check the BAV* line. When it is
inactive (1), it pulls it down, and then starts transmitting. The line
is raised again when the response has been fully received.
For transmitting a byte, the HSK* line must first be pulled down by the
sender. Then, the lower nibble is transmitted first, and the sender
releases the HSK* line. Every receiver that has completely received the
nibble and is ready for the next one releases the HSK* line. The sender
must check the HSK* line until it goes high again (which means that the
slowest receiver has got the nibble). This is repeated for the high nibble.
When the BAV* signal is asserted (0), the HSK* line must not be high for
more than 20 ms, or a bus timeout occurs.
The device address is transmitted as part of the request header. All
devices with a non-matching device code must ignore the rest of the
message until BAV* goes inactive (1) again.
If there is no matching device, HSK* will remain 1 after the end of the
master's request, and after 20ms, a timeout will occur. Declaring a timeout
is a matter of the devices, not of the bus.
Message format
--------------
+-------------+-------------+-------------+-------------+
| Device Code | Command code| LogUnitNum | RecNum LSB |
+-------------+-------------+-------------+-------------+
| RecNum MSB | Buflen LSB | Buflen MSB | DataLen LSB |
+-------------+-------------+-------------+-------------+
| DataLen MSB | |
+-------------+ |
| Data ... (not padded) |
| |
| |
+-------------+-------------+-------------+-------------+
Device codes
------------
0 - all devices (but none will respond, forcing a timeout)
1-8 - Tape mass storage
10-17 - Printer / plotter
20-27 - RS-232 interface
30-37 - TV interface (color)
40-47 - TV interface (B/W)
50-57 - Centronics interface
60-67 - Calculator in slave mode
70-77 - Modem
80-87 - GPIB interface (?)
90-97 - Bar code reader
100-107 - Floppy disk drive
Usage in MAME
-------------
Single device usage:
mame <driver> -hexbus <device>
Multiple device usage:
mame <driver> -hexbus chain -hexbus:chain:1 <device> ... -hexbus:chain:4 <device>
We currently assume a maximum length of 4 devices which can be increased
if desired. The chain positions should be used starting from 1 with no
gaps, but this is not enforced.
References
----------
[1] Intelligent Peripheral Bus: Structure, Timing, and Protocol Specification
Texas Instruments Inc., Consumer Products Group, Calculator Division,
7/3/82, Revision 2.8
Michael Zapf
June 2017
*****************************************************************************/
#include "emu.h"
#include "hexbus.h"
// Devices
#include "hx5102.h"
// Hexbus instance
DEFINE_DEVICE_TYPE_NS(TI_HEXBUS, bus::ti99::hexbus, hexbus_device, "ti_hexbus", "Hexbus")
// Hexbus daisy chain
DEFINE_DEVICE_TYPE_NS(TI_HEXBUS_CHAIN, bus::ti99::hexbus, hexbus_chain_device, "ti_hexbus_chain", "Hexbus chain")
// Single slot of the Hexbus
DEFINE_DEVICE_TYPE_NS(TI_HEXBUS_SLOT, bus::ti99::hexbus, hexbus_slot_device, "ti_hexbus_slot", "Hexbus position")
namespace bus { namespace ti99 { namespace hexbus {
enum
{
NOTCONN = -1
};
hexbus_device::hexbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, TI_HEXBUS, tag, owner, clock),
device_slot_interface(mconfig, *this),
m_master(nullptr),
m_slave(nullptr)
{
}
void hexbus_device::device_start()
{
}
void hexbus_device::device_config_complete()
{
m_slave = static_cast<hexbus_attached_device*>(subdevices().first());
if (m_slave != nullptr)
m_slave->set_hexbus(this);
}
void hexbus_device::send()
{
uint8_t sum = m_master->get_value();
if (m_slave != nullptr)
{
sum &= m_slave->get_value();
m_slave->receive(sum);
}
m_master->receive(sum);
}
// ------------------------------------------------------------------------
hexbus_chain_device::hexbus_chain_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
hexbus_attached_device(mconfig, TI_HEXBUS_CHAIN, tag, owner, clock)
{
}
uint8_t hexbus_chain_device::get_value()
{
uint8_t sum = 0xff;
// Do the wired AND
for (device_t &child : subdevices())
{
hexbus_slot_device* slot = downcast<hexbus_slot_device *>(&child);
sum &= slot->get_value();
}
return sum;
}
void hexbus_chain_device::receive(uint8_t value)
{
// Propagate
for (device_t &child : subdevices())
{
hexbus_slot_device* slot = downcast<hexbus_slot_device *>(&child);
slot->receive(value);
}
}
void hexbus_chain_device::device_start()
{
}
SLOT_INTERFACE_START( ti_hexbus_chain_slot )
// SLOT_INTERFACE("hx5102", TI_HX5102) // not an option yet
SLOT_INTERFACE_END
MACHINE_CONFIG_MEMBER( hexbus_chain_device::device_add_mconfig )
MCFG_HEXBUS_SLOT_ADD( "1", ti_hexbus_chain_slot )
MCFG_HEXBUS_SLOT_ADD( "2", ti_hexbus_chain_slot )
MCFG_HEXBUS_SLOT_ADD( "3", ti_hexbus_chain_slot )
MCFG_HEXBUS_SLOT_ADD( "4", ti_hexbus_chain_slot )
MACHINE_CONFIG_END
// ------------------------------------------------------------------------
int hexbus_slot_device::get_index_from_tagname()
{
const char *mytag = tag();
int maxlen = strlen(mytag);
int i;
for (i=maxlen-1; i >=0; i--)
if (mytag[i] < 48 || mytag[i] > 57) break;
return atoi(mytag+i+1);
}
hexbus_slot_device::hexbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TI_HEXBUS_SLOT, tag, owner, clock),
device_slot_interface(mconfig, *this),
m_hexbdev(nullptr)
{
}
/* Called from the Hexbus instance */
int hexbus_slot_device::get_index()
{
if (m_hexbdev == nullptr) return NOTCONN;
return get_index_from_tagname();
}
uint8_t hexbus_slot_device::get_value()
{
return (m_hexbdev != nullptr)? m_hexbdev->get_value() : 0xff;
}
void hexbus_slot_device::receive(uint8_t value)
{
if (m_hexbdev != nullptr)
m_hexbdev->receive(value);
}
void hexbus_slot_device::device_start()
{
}
void hexbus_slot_device::device_config_complete()
{
m_hexbus = dynamic_cast<hexbus_device*>(owner());
m_hexbdev = downcast<hexbus_attached_device *>(subdevices().first());
}
// ------------------------------------------------------------------------
hexbus_attached_device::hexbus_attached_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_slot_card_interface(mconfig, *this)
{
}
void hexbus_attached_device::device_start()
{
}
void hexbus_attached_device::hexbus_send(uint8_t value)
{
m_value = value;
m_hexbus->send();
}
} } } // end namespace bus::ti99::hexbus
SLOT_INTERFACE_START( ti_hexbus_conn )
// SLOT_INTERFACE("hx5102", TI_HX5102) // not an option yet
SLOT_INTERFACE("chain", TI_HEXBUS_CHAIN)
SLOT_INTERFACE_END

View File

@ -0,0 +1,141 @@
// license:LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************
Hexbus peripheral bus
See hexbus.cpp for documentation
Michael Zapf
June 2017
-hexbus:1 hx5102 -hexbus:2 ...
*****************************************************************************/
#ifndef MAME_BUS_TI99_HEXBUS_HEXBUS_H
#define MAME_BUS_TI99_HEXBUS_HEXBUS_H
#pragma once
#include "bus/ti99/ti99defs.h"
namespace bus { namespace ti99 { namespace hexbus {
enum
{
MAX_DEVICES = 4
};
class hexbus_attached_device;
class hexbus_slot_device;
class hexbus_device : public device_t, public device_slot_interface
{
friend class hexbus_attached_device;
public:
hexbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void connect_master(hexbus_attached_device *masterdev) { m_master = masterdev; }
protected:
void device_start() override;
void device_config_complete() override;
private:
hexbus_attached_device *m_master;
hexbus_attached_device *m_slave;
// Called from a slot, samples all values from the devices, and propagates
// the logical product to all connected devices
void send();
};
/*****************************************************************************
The parent class for all Hexbus devices
******************************************************************************/
class hexbus_attached_device : public device_t, public device_slot_card_interface
{
friend class hexbus_slot_device;
friend class hexbus_device;
protected:
hexbus_attached_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
void device_start() override;
void hexbus_send(uint8_t value);
uint8_t hexbus_receive() { return m_busvalue; }
virtual void receive(uint8_t value) { m_busvalue = value; }
virtual uint8_t get_value() { return m_value; }
private:
void set_hexbus(hexbus_device* hexbus) { m_hexbus = hexbus; }
uint8_t m_value;
uint8_t m_busvalue;
hexbus_device *m_hexbus; // Link to the Hexbus
};
// ------------------------------------------------------------------------
class hexbus_chain_device : public hexbus_attached_device
{
public:
hexbus_chain_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void device_add_mconfig(machine_config &config) override;
private:
void device_start() override;
void receive(uint8_t value) override;
uint8_t get_value() override;
};
// ------------------------------------------------------------------------
class hexbus_slot_device : public device_t, public device_slot_interface
{
friend class hexbus_attached_device;
friend class hexbus_chain_device;
public:
hexbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// Called from the hexbus (direction to attached device)
void receive(uint8_t value);
// Called from the hexbus
uint8_t get_value();
protected:
void device_start() override;
void device_config_complete() override;
// Called from the Hexbus instance
int get_index();
private:
int get_index_from_tagname();
hexbus_attached_device* m_hexbdev;
hexbus_device* m_hexbus;
};
#define MCFG_HEXBUS_ADD( _tag ) \
MCFG_DEVICE_ADD(_tag, TI_HEXBUS, 0) \
MCFG_DEVICE_SLOT_INTERFACE( ti_hexbus_conn, nullptr, false)
#define MCFG_HEXBUS_SLOT_ADD(_tag, _slot_intf) \
MCFG_DEVICE_ADD(_tag, TI_HEXBUS_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, nullptr, false)
} } } // end namespace bus::ti99::hexbus
SLOT_INTERFACE_EXTERN( ti_hexbus_conn );
DECLARE_DEVICE_TYPE_NS(TI_HEXBUS, bus::ti99::hexbus, hexbus_device)
DECLARE_DEVICE_TYPE_NS(TI_HEXBUS_CHAIN, bus::ti99::hexbus, hexbus_chain_device)
DECLARE_DEVICE_TYPE_NS(TI_HEXBUS_SLOT, bus::ti99::hexbus, hexbus_slot_device)
#endif // MAME_BUS_TI99_HEXBUS_HEXBUS_H

View File

@ -0,0 +1,28 @@
// license:LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************
Hexbus floppy disk drive
HX5102
Work in progress
Michael Zapf
June 2017
*****************************************************************************/
#include "emu.h"
#include "hx5102.h"
DEFINE_DEVICE_TYPE_NS(TI_HX5102, bus::ti99::hexbus, hx5102_device, "ti_hx5102", "TI Hexbus Floppy")
namespace bus { namespace ti99 { namespace hexbus {
hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock):
hexbus_attached_device(mconfig, TI_HX5102, tag, owner, clock)
{
}
} } } // end namespace bus::ti99::hexbus

View File

@ -0,0 +1,34 @@
// license:LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************
Hexbus floppy disk drive
HX5102
See hx5102.cpp for documentation
Michael Zapf
June 2017
*****************************************************************************/
#ifndef MAME_BUS_TI99_HEXBUS_HX5102_H
#define MAME_BUS_TI99_HEXBUS_HX5102_H
#pragma once
#include "hexbus.h"
namespace bus { namespace ti99 { namespace hexbus {
class hx5102_device : public hexbus_attached_device
{
public:
hx5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
} } } // end namespace bus::ti99::hexbus
DECLARE_DEVICE_TYPE_NS(TI_HX5102, bus::ti99::hexbus, hx5102_device)
#endif // MAME_BUS_TI99_HEXBUS_HX5102_H

View File

@ -2232,8 +2232,12 @@ enum
SHSK = 0x01
};
oso_device::oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TI99_OSO, tag, owner, clock), m_data(0), m_status(0), m_control(0), m_xmit(0)
oso_device::oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
bus::ti99::hexbus::hexbus_attached_device(mconfig, TI99_OSO, tag, owner, clock),
m_data(0),
m_status(0),
m_control(0),
m_xmit(0)
{
}
@ -2296,6 +2300,10 @@ void oso_device::device_start()
{
logerror("Starting\n");
m_status = m_xmit = m_control = m_data = 0;
m_hexbus = downcast<bus::ti99::hexbus::hexbus_device*>(machine().device(TI_HEXBUS_TAG));
m_hexbus->connect_master(this);
save_item(NAME(m_data));
save_item(NAME(m_status));
save_item(NAME(m_control));

View File

@ -20,6 +20,7 @@
#include "bus/ti99/ti99defs.h"
#include "bus/ti99/gromport/gromport.h"
#include "bus/ti99/hexbus/hexbus.h"
#include "bus/ti99/internal/ioport.h"
#include "machine/ram.h"
@ -371,7 +372,7 @@ private:
/*
Custom chip: OSO
*/
class oso_device : public device_t
class oso_device : public bus::ti99::hexbus::hexbus_attached_device
{
public:
oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@ -384,6 +385,8 @@ private:
uint8_t m_status;
uint8_t m_control;
uint8_t m_xmit;
bus::ti99::hexbus::hexbus_device* m_hexbus;
};
class mainboard8_device : public device_t

View File

@ -43,6 +43,7 @@
#define MAPPER_TAG "mapper"
#define MAINBOARD8_TAG "mainboard8"
#define SPEECHSYN_TAG "speech"
#define TI_HEXBUS_TAG "hexbus"
#define ROM0_REG "rom0_region"
#define ROM1_REG "rom1_region"

View File

@ -1,3 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Joakim Larsson Edstrom
/*
* The Dbox-1 CPU board.
*__________________________________________________________________________________________________________

View File

@ -183,6 +183,7 @@ Known Issues (MZ, 2010-11-07)
#include "bus/ti99/internal/998board.h"
#include "bus/ti99/gromport/gromport.h"
#include "bus/ti99/hexbus/hexbus.h"
#include "bus/ti99/joyport/joyport.h"
#include "bus/ti99/internal/ioport.h"
@ -763,6 +764,9 @@ static MACHINE_CONFIG_START( ti99_8 )
MCFG_IOPORT_EXTINT_HANDLER( WRITELINE(ti99_8_state, extint) )
MCFG_IOPORT_READY_HANDLER( DEVWRITELINE(MAINBOARD8_TAG, bus::ti99::internal::mainboard8_device, pbox_ready) )
// Hexbus
MCFG_HEXBUS_ADD( TI_HEXBUS_TAG )
// Sound hardware
MCFG_SPEAKER_STANDARD_MONO("sound_out")
MCFG_SOUND_ADD(TISOUNDCHIP_TAG, SN76496, 3579545) /* 3.579545 MHz */