summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Michael Zapf <Michael.Zapf@mizapf.de>2019-04-09 22:33:17 +0200
committer Michael Zapf <Michael.Zapf@mizapf.de>2019-04-09 22:33:17 +0200
commit042bcdabe6c1cc1cbfade5ffae23affe3e0bf590 (patch)
tree2edd616ad1b29c88a56e8dd42e65ae90aa06e515
parente16e8ddfe54e6540707be3305669f239abf5cd0b (diff)
ti99: Remove redundant variables; fix problem with TI FDC in Geneve where SIDSEL signal is lost when no drive is selected.
-rw-r--r--src/devices/bus/ti99/peb/ti_fdc.cpp119
-rw-r--r--src/devices/bus/ti99/peb/ti_fdc.h18
2 files changed, 70 insertions, 67 deletions
diff --git a/src/devices/bus/ti99/peb/ti_fdc.cpp b/src/devices/bus/ti99/peb/ti_fdc.cpp
index 79d27cd5460..2ff368f375e 100644
--- a/src/devices/bus/ti99/peb/ti_fdc.cpp
+++ b/src/devices/bus/ti99/peb/ti_fdc.cpp
@@ -19,12 +19,14 @@
#define LOG_WARN (1U<<1) // Warnings
#define LOG_CONFIG (1U<<2)
#define LOG_RW (1U<<3)
-#define LOG_CRU (1U<<4)
-#define LOG_READY (1U<<5)
-#define LOG_SIGNALS (1U<<6)
-#define LOG_DATA (1U<<7)
-#define LOG_MOTOR (1U<<8)
-#define LOG_ADDRESS (1U<<9)
+#define LOG_PORTS (1U<<4) // too noisy in RW
+#define LOG_CRU (1U<<5)
+#define LOG_READY (1U<<6)
+#define LOG_SIGNALS (1U<<7)
+#define LOG_DRQ (1U<<8) // too noisy in SIGNALS
+#define LOG_DATA (1U<<9)
+#define LOG_MOTOR (1U<<10)
+#define LOG_ADDRESS (1U<<11)
#define VERBOSE ( LOG_CONFIG | LOG_WARN )
#include "logmacro.h"
@@ -46,13 +48,12 @@ ti_fdc_device::ti_fdc_device(const machine_config &mconfig, const char *tag, dev
m_address(0),
m_DRQ(0),
m_IRQ(0),
+ m_HLD(0),
m_crulatch(*this, "crulatch"),
m_DVENA(0),
m_inDsrArea(false),
m_WAITena(false),
m_WDsel(false),
- m_DSEL(0),
- m_SIDSEL(0),
m_motor_on_timer(nullptr),
m_fd1771(*this, FDC_TAG),
m_dsrrom(nullptr),
@@ -66,15 +67,13 @@ ti_fdc_device::ti_fdc_device(const machine_config &mconfig, const char *tag, dev
void ti_fdc_device::operate_ready_line()
{
// This is the wait state logic
- LOGMASKED(LOG_SIGNALS, "address=%04x, DRQ=%d, INTRQ=%d, MOTOR=%d\n", m_address & 0xffff, m_DRQ, m_IRQ, m_DVENA);
line_state nready = (m_WDsel && // Are we accessing 5ffx (even addr)?
m_WAITena && // and the wait state generation is active (SBO 2)
(m_DRQ==CLEAR_LINE) && // and we are waiting for a byte
(m_IRQ==CLEAR_LINE) && // and there is no interrupt yet
(m_DVENA==ASSERT_LINE) // and the motor is turning?
)? ASSERT_LINE : CLEAR_LINE; // In that case, clear READY and thus trigger wait states
-
- LOGMASKED(LOG_READY, "READY line = %d\n", (nready==CLEAR_LINE)? 1:0);
+ LOGMASKED(LOG_READY, "Address=%04x, DRQ=%d, INTRQ=%d, MOTOR=%d -> READY=%d\n", m_address & 0xffff, m_DRQ, m_IRQ, m_DVENA, (nready==CLEAR_LINE)? 1:0);
m_slot->set_ready((nready==CLEAR_LINE)? ASSERT_LINE : CLEAR_LINE);
}
@@ -91,10 +90,17 @@ WRITE_LINE_MEMBER( ti_fdc_device::fdc_irq_w )
WRITE_LINE_MEMBER( ti_fdc_device::fdc_drq_w )
{
m_DRQ = state? ASSERT_LINE : CLEAR_LINE;
- LOGMASKED(LOG_SIGNALS, "DRQ callback = %d\n", m_DRQ);
+ LOGMASKED(LOG_DRQ, "DRQ callback = %d\n", m_DRQ);
operate_ready_line();
}
+WRITE_LINE_MEMBER( ti_fdc_device::fdc_hld_w )
+{
+ m_HLD = state? ASSERT_LINE : CLEAR_LINE;
+ LOGMASKED(LOG_SIGNALS, "HLD callback = %d\n", m_HLD);
+}
+
+
// bool ti_fdc_device::dvena_r()
// {
// LOGMASKED(LOG_SIGNALS, "reading DVENA = %d\n", m_DVENA);
@@ -111,7 +117,7 @@ SETADDRESS_DBIN_MEMBER( ti_fdc_device::setaddress_dbin )
if (!m_inDsrArea || !m_selected) return;
- LOGMASKED(LOG_ADDRESS, "set address = %04x\n", offset & 0xffff);
+ LOGMASKED(LOG_ADDRESS, "Set address = %04x\n", offset & 0xffff);
// Is the WD chip on the card being selected?
m_WDsel = m_inDsrArea && ((m_address & 0x1ff1)==0x1ff0);
@@ -150,18 +156,21 @@ READ8Z_MEMBER(ti_fdc_device::readz)
if (m_WDsel && ((m_address & 9)==0))
{
if (!machine().side_effects_disabled()) reply = m_fd1771->read((offset >> 1)&0x03);
+ LOGMASKED(LOG_PORTS, "%04x -> %02x\n", offset & 0xffff, reply);
}
else
{
reply = m_dsrrom[m_address & 0x1fff];
+ LOGMASKED(LOG_RW, "%04x -> %02x\n", offset & 0xffff, reply);
}
*value = reply;
- LOGMASKED(LOG_RW, "%04x -> %02x\n", offset & 0xffff, *value);
}
}
void ti_fdc_device::write(offs_t offset, uint8_t data)
{
+ // As this is a memory-mapped access we must prevent the debugger
+ // from messing with the operation
if (machine().side_effects_disabled()) return;
if (m_inDsrArea && m_selected)
@@ -175,12 +184,17 @@ void ti_fdc_device::write(offs_t offset, uint8_t data)
// flags may be reset by the read operation.
// Note that incoming/outgoing data are inverted for FD1771
- LOGMASKED(LOG_RW, "%04x <- %02x\n", offset & 0xffff, ~data & 0xff);
- if (m_WDsel && ((m_address & 9)==8))
+ if (m_WDsel)
{
- // As this is a memory-mapped access we must prevent the debugger
- // from messing with the operation
- if (!machine().side_effects_disabled()) m_fd1771->write((offset >> 1)&0x03, data);
+ if ((m_address & 9)==8)
+ {
+ m_fd1771->write((offset >> 1)&0x03, data);
+ LOGMASKED(LOG_PORTS, "%04x <- %02x\n", offset & 0xffff, ~data & 0xff);
+ }
+ else
+ {
+ LOGMASKED(LOG_RW, "%04x <- %02x (ignored)\n", m_address & 0xffff, ~data & 0xff);
+ }
}
}
}
@@ -190,30 +204,31 @@ void ti_fdc_device::write(offs_t offset, uint8_t data)
7 6 5 4 3 2 1 0
+-----+-----+-----+------+-----+-----+-----+-----+
- | Side| 1 | 0 |DVENA*| DSK3| DSK2| DSK1| HLD |
+ | Side| 1 | 0 |DVENA*| D3C*| D2C*| D1C*| HLD |
+-----+-----+-----+------+-----+-----+-----+-----+
- We have only 8 bits for query; within this implementation this means
- we only use the base address (offset 0).
+ See schematics for the meaning of the bits.
*/
READ8Z_MEMBER(ti_fdc_device::crureadz)
{
if ((offset & 0xff00)==m_cru_base)
{
- uint8_t reply = 0;
if ((offset & 0x0070) == 0)
{
- // Selected drive
- reply |= ((m_DSEL)<<1);
- // The DVENA state is returned as inverted
- if (m_DVENA==CLEAR_LINE) reply |= 0x10;
- // Always 1
- reply |= 0x40;
- // Selected side
- if (m_SIDSEL==ASSERT_LINE) reply |= 0x80;
+ switch ((offset >> 1) & 0x07)
+ {
+ case 0: *value = (m_HLD==ASSERT_LINE)? 1:0; break;
+ case 1: *value = (m_crulatch->q4_r()==ASSERT_LINE && m_DVENA==ASSERT_LINE)? 1:0; break;
+ case 2: *value = (m_crulatch->q5_r()==ASSERT_LINE && m_DVENA==ASSERT_LINE)? 1:0; break;
+ case 3: *value = (m_crulatch->q6_r()==ASSERT_LINE && m_DVENA==ASSERT_LINE)? 1:0; break;
+ case 4: *value = (m_DVENA==CLEAR_LINE)? 1:0; break;
+ case 5: *value = 0; break;
+ case 6: *value = 1; break;
+ case 7: *value = (m_crulatch->q7_r()==ASSERT_LINE)? 1:0; break;
+ }
}
- *value = BIT(reply, (offset >> 1) & 0x07);
- LOGMASKED(LOG_CRU, "Read CRU = %02x\n", *value);
+ else *value = 0;
+ LOGMASKED(LOG_CRU, "Read CRU %04x = %02x\n", offset, *value);
}
}
@@ -235,7 +250,7 @@ WRITE_LINE_MEMBER(ti_fdc_device::kaclk_w)
// Activate motor
if (state)
{ // On rising edge, set motor_running for 4.23s
- LOGMASKED(LOG_CRU, "trigger motor (bit 1)\n");
+ LOGMASKED(LOG_CRU, "Trigger motor (bit 1)\n");
set_floppy_motors_running(true);
}
}
@@ -248,32 +263,25 @@ WRITE_LINE_MEMBER(ti_fdc_device::waiten_w)
// OR the motor stops rotating - rotates for 4.23s after write
// to CRU bit 1
m_WAITena = state;
- LOGMASKED(LOG_CRU, "arm wait state logic (bit 2) = %d\n", state);
+ LOGMASKED(LOG_CRU, "Arm wait state logic (bit 2) = %d\n", state);
}
WRITE_LINE_MEMBER(ti_fdc_device::hlt_w)
{
// Load disk heads (HLT pin) (bit 3). Not implemented.
- LOGMASKED(LOG_CRU, "set head load (bit 3) = %d\n", state);
-}
-
-WRITE_LINE_MEMBER(ti_fdc_device::dsel_w)
-{
- m_DSEL = m_crulatch->q4_r() | (m_crulatch->q5_r() << 1) | (m_crulatch->q6_r() << 2);
- set_drive();
+ LOGMASKED(LOG_CRU, "Set head load (bit 3) = %d\n", state);
}
WRITE_LINE_MEMBER(ti_fdc_device::sidsel_w)
{
// Select side of disk (bit 7)
- m_SIDSEL = state ? ASSERT_LINE : CLEAR_LINE;
- LOGMASKED(LOG_CRU, "set side (bit 7) = %d\n", state);
+ LOGMASKED(LOG_CRU, "Set side (bit 7) = %d\n", state);
if (m_current != NONE) m_floppy[m_current]->ss_w(state);
}
-void ti_fdc_device::set_drive()
+WRITE_LINE_MEMBER(ti_fdc_device::dsel_w)
{
- int dsel = m_DSEL;
+ int dsel = m_crulatch->q4_r() | (m_crulatch->q5_r() << 1) | (m_crulatch->q6_r() << 2);
// If the selected floppy drive is not attached, remove that line
if (m_floppy[2] == nullptr) dsel &= 0x03; // 011
@@ -284,7 +292,7 @@ void ti_fdc_device::set_drive()
{
case 0:
m_current = NONE;
- LOGMASKED(LOG_CRU, "all drives deselected\n");
+ LOGMASKED(LOG_CRU, "All drives deselected\n");
break;
case 1:
m_current = 0;
@@ -306,9 +314,18 @@ void ti_fdc_device::set_drive()
LOGMASKED(LOG_WARN, "Warning - multiple drives selected\n");
break;
}
- LOGMASKED(LOG_CRU, "new DSEL = %d\n", m_DSEL);
+ LOGMASKED(LOG_CRU, "New DSEL = %d\n", dsel);
- m_fd1771->set_floppy((m_current == NONE)? nullptr : m_floppy[m_current]);
+ if (m_current != NONE)
+ {
+ // When a new drive is selected, propagate the SIDSEL signal to that drive
+ m_fd1771->set_floppy(m_floppy[m_current]);
+ m_floppy[m_current]->ss_w(m_crulatch->q7_r());
+ }
+ else
+ {
+ m_fd1771->set_floppy(nullptr);
+ }
}
/*
@@ -362,8 +379,6 @@ void ti_fdc_device::device_start()
save_item(NAME(m_inDsrArea));
save_item(NAME(m_WAITena));
save_item(NAME(m_WDsel));
- save_item(NAME(m_DSEL));
- save_item(NAME(m_SIDSEL));
save_item(NAME(m_current));
}
@@ -384,7 +399,6 @@ void ti_fdc_device::device_reset()
m_DVENA = CLEAR_LINE;
m_fd1771->set_force_ready(false);
- m_DSEL = 0;
m_WAITena = false;
m_selected = false;
m_inDsrArea = false;
@@ -433,6 +447,7 @@ void ti_fdc_device::device_add_mconfig(machine_config& config)
FD1771(config, m_fd1771, 1_MHz_XTAL);
m_fd1771->intrq_wr_callback().set(FUNC(ti_fdc_device::fdc_irq_w));
m_fd1771->drq_wr_callback().set(FUNC(ti_fdc_device::fdc_drq_w));
+ m_fd1771->hld_wr_callback().set(FUNC(ti_fdc_device::fdc_hld_w));
FLOPPY_CONNECTOR(config, "0", tifdc_floppies, "525dd", ti_fdc_device::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, "1", tifdc_floppies, "525dd", ti_fdc_device::floppy_formats).enable_sound(true);
diff --git a/src/devices/bus/ti99/peb/ti_fdc.h b/src/devices/bus/ti99/peb/ti_fdc.h
index 4c07bcb142e..ef16913e206 100644
--- a/src/devices/bus/ti99/peb/ti_fdc.h
+++ b/src/devices/bus/ti99/peb/ti_fdc.h
@@ -51,6 +51,7 @@ private:
DECLARE_WRITE_LINE_MEMBER(fdc_irq_w);
DECLARE_WRITE_LINE_MEMBER(fdc_drq_w);
+ DECLARE_WRITE_LINE_MEMBER(fdc_hld_w);
DECLARE_WRITE_LINE_MEMBER(dskpgena_w);
DECLARE_WRITE_LINE_MEMBER(kaclk_w);
@@ -65,17 +66,14 @@ private:
// Wait state logic
void operate_ready_line();
- // Set the current floppy
- void set_drive();
-
// Operate the floppy motors
void set_floppy_motors_running(bool run);
// Recent address
int m_address;
- // Holds the status of the DRQ and IRQ lines.
- int m_DRQ, m_IRQ;
+ // Holds the status of the DRQ, IRQ, and HLD lines.
+ int m_DRQ, m_IRQ, m_HLD;
// Latched CRU outputs
required_device<ls259_device> m_crulatch;
@@ -92,16 +90,6 @@ private:
// WD chip selected
bool m_WDsel;
- // Indicates which drive has been selected. Values are 0, 1, 2, and 4.
- // 000 = no drive
- // 001 = drive 1
- // 010 = drive 2
- // 100 = drive 3
- int m_DSEL;
-
- // Signal SIDSEL. 0 or 1, indicates the selected head.
- int m_SIDSEL;
-
// count 4.23s from rising edge of motor_on
emu_timer* m_motor_on_timer;