From 042bcdabe6c1cc1cbfade5ffae23affe3e0bf590 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Tue, 9 Apr 2019 22:33:17 +0200 Subject: ti99: Remove redundant variables; fix problem with TI FDC in Geneve where SIDSEL signal is lost when no drive is selected. --- src/devices/bus/ti99/peb/ti_fdc.cpp | 119 ++++++++++++++++++++---------------- src/devices/bus/ti99/peb/ti_fdc.h | 18 +----- 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 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; -- cgit v1.2.3