summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/ti99/internal/datamux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/ti99/internal/datamux.cpp')
-rw-r--r--src/devices/bus/ti99/internal/datamux.cpp99
1 files changed, 51 insertions, 48 deletions
diff --git a/src/devices/bus/ti99/internal/datamux.cpp b/src/devices/bus/ti99/internal/datamux.cpp
index d0e7d05a6c1..8359e213d8d 100644
--- a/src/devices/bus/ti99/internal/datamux.cpp
+++ b/src/devices/bus/ti99/internal/datamux.cpp
@@ -72,27 +72,27 @@
#include "datamux.h"
#include "cpu/tms9900/tms99com.h"
-#define LOG_WARN (1U<<1) // Warnings
-#define LOG_READY (1U<<2) // READY line
-#define LOG_ACCESS (1U<<3) // Access to this GROM
-#define LOG_ADDRESS (1U<<4) // Address register
-#define LOG_WAITCOUNT (1U<<5) // Wait state counter
+#define LOG_WARN (1U << 1) // Warnings
+#define LOG_READY (1U << 2) // READY line
+#define LOG_ACCESS (1U << 3) // Access to this GROM
+#define LOG_ADDRESS (1U << 4) // Address register
+#define LOG_WAITCOUNT (1U << 5) // Wait state counter
-#define VERBOSE ( LOG_GENERAL | LOG_WARN )
+#define VERBOSE (LOG_GENERAL | LOG_WARN)
#include "logmacro.h"
-DEFINE_DEVICE_TYPE_NS(TI99_DATAMUX, bus::ti99::internal, datamux_device, "ti99_datamux", "TI-99 Databus multiplexer")
+DEFINE_DEVICE_TYPE(TI99_DATAMUX, bus::ti99::internal::datamux_device, "ti99_datamux", "TI-99 Databus multiplexer")
-namespace bus { namespace ti99 { namespace internal {
+namespace bus::ti99::internal {
/*
Constructor
*/
datamux_device::datamux_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TI99_DATAMUX, tag, owner, clock),
- m_video(*owner, TI_VDP_TAG),
- m_sound(*owner, TI_SOUNDCHIP_TAG),
+ m_video(*owner, TI99_VDP_TAG),
+ m_sound(*owner, TI99_SOUNDCHIP_TAG),
m_ioport(*owner, TI99_IOPORT_TAG),
m_gromport(*owner, TI99_GROMPORT_TAG),
m_ram16b(*owner, TI99_EXPRAM_TAG),
@@ -101,6 +101,7 @@ datamux_device::datamux_device(const machine_config &mconfig, const char *tag, d
m_grom0(*owner, TI99_GROM0_TAG),
m_grom1(*owner, TI99_GROM1_TAG),
m_grom2(*owner, TI99_GROM2_TAG),
+ m_tms9901(*owner, TI99_TMS9901_TAG),
m_ready(*this),
m_addr_buf(0),
m_dbin(CLEAR_LINE),
@@ -123,31 +124,25 @@ datamux_device::datamux_device(const machine_config &mconfig, const char *tag, d
void datamux_device::read_all(uint16_t addr, uint8_t *value)
{
- // Valid access
- bool validaccess = ((addr & 0x0400)==0);
-
- if (validaccess)
+ // GROM access
+ if ((addr & 0xfc01)==0x9800)
{
- // GROM access
- if ((addr & 0xf801)==0x9800)
+ if (m_console_groms_present)
{
- if (m_console_groms_present)
- {
- m_grom0->readz(value);
- m_grom1->readz(value);
- m_grom2->readz(value);
- }
- // GROMport (GROMs)
- m_gromport->readz(addr, value);
- m_grom_idle = false;
+ m_grom0->readz(value);
+ m_grom1->readz(value);
+ m_grom2->readz(value);
}
+ // GROMport (GROMs)
+ m_gromport->readz(addr, value);
+ m_grom_idle = false;
+ }
- // Video
- if ((addr & 0xf801)==0x8800)
- {
- // Forward to VDP unless we have an EVPC
- if (m_video != nullptr) *value = m_video->read(addr>>1); // A14 determines data or register read
- }
+ // Video
+ if ((addr & 0xfc01)==0x8800)
+ {
+ // Forward to VDP unless we have an EVPC
+ if (m_video != nullptr) *value = m_video->read((addr>>1)&1); // A14 determines data or register read
}
// GROMport (ROMs)
@@ -185,10 +180,10 @@ void datamux_device::write_all(uint16_t addr, uint8_t value)
}
// Video
- if ((addr & 0xf801)==0x8800)
+ if ((addr & 0xfc01)==0x8c00)
{
// Forward to VDP unless we have an EVPC
- if (m_video != nullptr) m_video->write(addr>>1, value); // A14 determines data or register write
+ if (m_video != nullptr) m_video->write((addr>>1)&1, value); // A14 determines data or register write
}
// I/O port gets all accesses
@@ -210,6 +205,9 @@ void datamux_device::setaddress_all(uint16_t addr)
// Cartridge ROM
bool iscartrom = ((addr & 0xe000)==0x6000);
+ // Speech (1001 0wxx xxxx xxx0)
+ bool sbe = ((addr & 0xf801)==0x9000) && validaccess;
+
// Always deliver to GROM so that the select line may be cleared
line_state gsq = isgrom? ASSERT_LINE : CLEAR_LINE;
if (isgrom) m_grom_idle = false;
@@ -233,6 +231,7 @@ void datamux_device::setaddress_all(uint16_t addr)
// I/O port gets all accesses
m_memen_state = ASSERT_LINE;
m_ioport->memen_in(m_memen_state);
+ m_ioport->sbe(sbe);
m_ioport->setaddress_dbin(addr, m_dbin);
}
@@ -318,14 +317,14 @@ void datamux_device::debugger_write(uint16_t addr, uint16_t data)
if ((addrb & 0xe000)==0x6000)
{
m_gromport->romgq_line(ASSERT_LINE);
- m_gromport->write(addr+1, data & 0xff);
- m_gromport->write(addr, (data>>8) & 0xff);
+ m_gromport->write(addrb+1, data & 0xff);
+ m_gromport->write(addrb, (data>>8) & 0xff);
m_gromport->romgq_line(m_romgq_state); // reset to previous state
}
m_ioport->memen_in(ASSERT_LINE);
- m_ioport->write(addr+1, data & 0xff);
- m_ioport->write(addr, (data>>8) & 0xff);
+ m_ioport->write(addrb+1, data & 0xff);
+ m_ioport->write(addrb, (data>>8) & 0xff);
m_ioport->memen_in(m_memen_state); // reset to previous state
}
}
@@ -378,7 +377,7 @@ uint16_t datamux_device::read(offs_t offset)
// Reading the even address now (addr)
uint8_t hbyte = 0;
read_all(m_addr_buf, &hbyte);
- LOGMASKED(LOG_ACCESS, "Read even byte from address %04x -> %02x\n", m_addr_buf, hbyte);
+ LOGMASKED(LOG_ACCESS, "%04x -> %02x\n", m_addr_buf, hbyte);
value = (hbyte<<8) | m_latch;
}
@@ -442,6 +441,10 @@ void datamux_device::setaddress(offs_t offset, uint16_t busctrl)
LOGMASKED(LOG_ADDRESS, "Set address %04x\n", m_addr_buf);
+ // Trigger the TMS9901 clock when A10 is 1
+ if ((m_addr_buf & 0x0020) != 0)
+ m_tms9901->update_clock();
+
if ((m_addr_buf & 0xe000) == 0x0000)
{
return; // console ROM
@@ -482,7 +485,7 @@ void datamux_device::setaddress(offs_t offset, uint16_t busctrl)
The datamux is connected to the clock line in order to operate
the wait state counter and to read/write the bytes.
*/
-WRITE_LINE_MEMBER( datamux_device::clock_in )
+void datamux_device::clock_in(int state)
{
// return immediately if the datamux is currently inactive
if (m_waitcount>0)
@@ -506,9 +509,11 @@ WRITE_LINE_MEMBER( datamux_device::clock_in )
}
if (m_waitcount==2)
{
+ // Clear the latch (if no device responds on the bus, we assume the data lines as 0)
+ m_latch = 0;
// read odd byte
read_all(m_addr_buf+1, &m_latch);
- LOGMASKED(LOG_ACCESS, "Read odd byte from address %04x -> %02x\n", m_addr_buf+1, m_latch);
+ LOGMASKED(LOG_ACCESS, "%04x -> %02x\n", m_addr_buf+1, m_latch);
// do the setaddress for the even address
setaddress_all(m_addr_buf);
}
@@ -547,7 +552,7 @@ void datamux_device::ready_join()
m_ready((m_sysready==CLEAR_LINE || m_muxready==CLEAR_LINE)? CLEAR_LINE : ASSERT_LINE);
}
-WRITE_LINE_MEMBER( datamux_device::ready_line )
+void datamux_device::ready_line(int state)
{
if (state != m_sysready) LOGMASKED(LOG_READY, "READY line from PBox = %d\n", state);
m_sysready = (line_state)state;
@@ -556,7 +561,7 @@ WRITE_LINE_MEMBER( datamux_device::ready_line )
}
/* Called from VDP via console. */
-WRITE_LINE_MEMBER( datamux_device::gromclk_in )
+void datamux_device::gromclk_in(int state)
{
// Don't propagate the clock in idle phase
if (m_grom_idle) return;
@@ -580,10 +585,9 @@ WRITE_LINE_MEMBER( datamux_device::gromclk_in )
DEVICE LIFECYCLE FUNCTIONS
***************************************************************************/
-void datamux_device::device_start(void)
+void datamux_device::device_start()
{
m_muxready = ASSERT_LINE;
- m_ready.resolve();
// Register persistable state variables
save_item(NAME(m_addr_buf));
@@ -598,11 +602,11 @@ void datamux_device::device_start(void)
save_item(NAME(m_grom_idle));
}
-void datamux_device::device_stop(void)
+void datamux_device::device_stop()
{
}
-void datamux_device::device_reset(void)
+void datamux_device::device_reset()
{
m_consolerom = (uint16_t*)owner()->memregion(TI99_CONSOLEROM)->base();
m_use32k = (ioport("RAM")->read()==1);
@@ -636,5 +640,4 @@ ioport_constructor datamux_device::device_input_ports() const
return INPUT_PORTS_NAME(datamux);
}
-} } } // end namespace bus::ti99::internal
-
+} // end namespace bus::ti99::internal