From 8459b00d4e31632053fe05051e083085f7bb1784 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Thu, 11 Apr 2019 23:58:29 +0200 Subject: ti99: Replace emu_timers by monoflop circuits. (nw) --- src/devices/bus/ti99/peb/bwg.cpp | 56 ++++-------- src/devices/bus/ti99/peb/bwg.h | 19 ++-- src/devices/bus/ti99/peb/ti_fdc.cpp | 174 +++++++++++++++--------------------- src/devices/bus/ti99/peb/ti_fdc.h | 25 +++--- 4 files changed, 112 insertions(+), 162 deletions(-) diff --git a/src/devices/bus/ti99/peb/bwg.cpp b/src/devices/bus/ti99/peb/bwg.cpp index ffb3d5bc677..d6dd01b54d7 100644 --- a/src/devices/bus/ti99/peb/bwg.cpp +++ b/src/devices/bus/ti99/peb/bwg.cpp @@ -45,6 +45,7 @@ #include "emu.h" #include "bwg.h" #include "formats/ti99_dsk.h" +#include "machine/rescap.h" // ---------------------------------- // Flags for debugging @@ -90,16 +91,15 @@ snug_bwg_device::snug_bwg_device(const machine_config &mconfig, const char *tag, m_lastK(false), m_dataregLB(false), m_MOTOR_ON(), - m_lastmop(0), m_address(0), - m_motor_on_timer(nullptr), m_dsrrom(nullptr), m_buffer_ram(*this, BUFFER), m_sel_floppy(0), m_wd1773(*this, FDC_TAG), m_clock(*this, CLOCK_TAG), m_crulatch0_7(*this, "crulatch0_7"), - m_crulatch8_15(*this, "crulatch8_15") + m_crulatch8_15(*this, "crulatch8_15"), + m_motormf(*this, "motormf") { } /* @@ -399,13 +399,7 @@ WRITE_LINE_MEMBER(snug_bwg_device::den_w) WRITE_LINE_MEMBER(snug_bwg_device::mop_w) { - // Activate motor on rising edge - if (state==ASSERT_LINE && m_lastmop==CLEAR_LINE) - { // Monoflop lets motor run for 4.23s - LOGMASKED(LOG_CRU, "Trigger motor (bit 1)\n"); - set_floppy_motors_running(true); - } - m_lastmop = state; + m_motormf->b_w(state); } WRITE_LINE_MEMBER(snug_bwg_device::waiten_w) @@ -495,38 +489,20 @@ WRITE_LINE_MEMBER(snug_bwg_device::dden_w) m_wd1773->dden_w(state != 0); } -/* - Monoflop has gone back to the OFF state. -*/ -void snug_bwg_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - set_floppy_motors_running(false); -} - /* All floppy motors are operated by the same line. */ -void snug_bwg_device::set_floppy_motors_running(bool run) +WRITE_LINE_MEMBER(snug_bwg_device::motorona_w) { - if (run) - { - if (m_MOTOR_ON==CLEAR_LINE) LOGMASKED(LOG_MOTOR, "Motor START\n"); - m_MOTOR_ON = ASSERT_LINE; - m_motor_on_timer->adjust(attotime::from_msec(4230)); - } - else - { - if (m_MOTOR_ON==ASSERT_LINE) LOGMASKED(LOG_MOTOR, "Motor STOP\n"); - m_MOTOR_ON = CLEAR_LINE; - } + m_MOTOR_ON = state; + LOGMASKED(LOG_MOTOR, "Motor %s\n", state? "on" : "off"); - // The motor-on line is connected to pin 20 which is falsely called "MO" - // in the schematics; should be called "READY" as we are using the WD1773. - m_wd1773->set_force_ready(run); + // The monoflop is connected to the READY line + m_wd1773->set_force_ready(state==ASSERT_LINE); // Set all motors for (auto & elem : m_floppy) - if (elem != nullptr) elem->mon_w((run)? 0 : 1); + if (elem != nullptr) elem->mon_w((state==ASSERT_LINE)? 0 : 1); // The motor-on line also connects to the wait state logic operate_ready_line(); @@ -535,7 +511,6 @@ void snug_bwg_device::set_floppy_motors_running(bool run) void snug_bwg_device::device_start() { m_dsrrom = memregion(TI99_DSRROM)->base(); - m_motor_on_timer = timer_alloc(MOTOR_TIMER); m_cru_base = 0x1100; save_item(NAME(m_DRQ)); @@ -547,7 +522,6 @@ void snug_bwg_device::device_start() save_item(NAME(m_lastK)); save_item(NAME(m_dataregLB)); save_item(NAME(m_MOTOR_ON)); - save_item(NAME(m_lastmop)); save_item(NAME(m_address)); } @@ -564,8 +538,6 @@ void snug_bwg_device::device_reset() m_select_value = 0x74000; } - m_lastmop = 0; - m_DRQ = CLEAR_LINE; m_IRQ = CLEAR_LINE; m_MOTOR_ON = CLEAR_LINE; @@ -672,6 +644,14 @@ void snug_bwg_device::device_add_mconfig(machine_config& config) LS259(config, m_crulatch8_15); // U12 m_crulatch8_15->q_out_cb<0>().set(FUNC(snug_bwg_device::dsel4_w)); m_crulatch8_15->q_out_cb<2>().set(FUNC(snug_bwg_device::dden_w)); + + // TODO: Replace this by the actual 74HC4538 + TTL74123(config, m_motormf, 0); + m_motormf->out_cb().set(FUNC(snug_bwg_device::motorona_w)); + m_motormf->set_connection_type(TTL74123_GROUNDED); + m_motormf->set_resistor_value(RES_K(200)); + m_motormf->set_capacitor_value(CAP_U(47)); + m_motormf->set_clear_pin_value(1); } ioport_constructor snug_bwg_device::device_input_ports() const diff --git a/src/devices/bus/ti99/peb/bwg.h b/src/devices/bus/ti99/peb/bwg.h index 3f0f976b3ac..db94cb03c08 100644 --- a/src/devices/bus/ti99/peb/bwg.h +++ b/src/devices/bus/ti99/peb/bwg.h @@ -22,6 +22,7 @@ #include "machine/wd_fdc.h" #include "machine/ram.h" #include "machine/74259.h" +#include "machine/74123.h" namespace bus { namespace ti99 { namespace peb { @@ -47,8 +48,6 @@ protected: ioport_constructor device_input_ports() const override; private: - void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - DECLARE_FLOPPY_FORMATS( floppy_formats ); DECLARE_WRITE_LINE_MEMBER( fdc_irq_w ); @@ -66,6 +65,8 @@ private: DECLARE_WRITE_LINE_MEMBER( sidsel_w ); DECLARE_WRITE_LINE_MEMBER( dden_w ); + DECLARE_WRITE_LINE_MEMBER( motorona_w ); + void select_drive(int n, int state); // Debugger accessors @@ -78,11 +79,8 @@ private: // Set the current floppy void set_drive(); - // Operate the floppy motors - void set_floppy_motors_running(bool run); - // Holds the status of the DRQ and IRQ lines. - int m_DRQ, m_IRQ; + int m_DRQ, m_IRQ; // DIP switch state int m_dip1, m_dip2, m_dip34; @@ -105,15 +103,9 @@ private: // Signal motor_on. When true, makes all drives turning. int m_MOTOR_ON; - // Needed for triggering the motor monoflop - uint8_t m_lastmop; - // Recent address int m_address; - // count 4.23s from rising edge of motor_on - emu_timer* m_motor_on_timer; - // DSR ROM uint8_t* m_dsrrom; @@ -135,6 +127,9 @@ private: // Latched CRU outputs required_device m_crulatch0_7; required_device m_crulatch8_15; + + // Motor monoflop + required_device m_motormf; }; } } } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/ti_fdc.cpp b/src/devices/bus/ti99/peb/ti_fdc.cpp index 2ff368f375e..7194a445286 100644 --- a/src/devices/bus/ti99/peb/ti_fdc.cpp +++ b/src/devices/bus/ti99/peb/ti_fdc.cpp @@ -15,6 +15,7 @@ #include "emu.h" #include "ti_fdc.h" #include "formats/ti99_dsk.h" +#include "machine/rescap.h" #define LOG_WARN (1U<<1) // Warnings #define LOG_CONFIG (1U<<2) @@ -38,7 +39,6 @@ namespace bus { namespace ti99 { namespace peb { // ---------------------------------- #define FDC_TAG "fd1771" #define MOTOR_TIMER 1 -#define NONE -1 #define TI_FDC_TAG "ti_dssd_controller" @@ -49,15 +49,14 @@ ti_fdc_device::ti_fdc_device(const machine_config &mconfig, const char *tag, dev 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_motor_on_timer(nullptr), m_fd1771(*this, FDC_TAG), + m_crulatch(*this, "crulatch"), + m_motormf(*this, "motormf"), m_dsrrom(nullptr), - m_current(NONE) + m_sel_floppy(0) { } @@ -68,7 +67,7 @@ void ti_fdc_device::operate_ready_line() { // This is the wait state logic line_state nready = (m_WDsel && // Are we accessing 5ffx (even addr)? - m_WAITena && // and the wait state generation is active (SBO 2) + m_crulatch->q2_r() && // 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? @@ -100,13 +99,6 @@ WRITE_LINE_MEMBER( ti_fdc_device::fdc_hld_w ) LOGMASKED(LOG_SIGNALS, "HLD callback = %d\n", m_HLD); } - -// bool ti_fdc_device::dvena_r() -// { -// LOGMASKED(LOG_SIGNALS, "reading DVENA = %d\n", m_DVENA); -// return (m_DVENA==ASSERT_LINE); -// } - SETADDRESS_DBIN_MEMBER( ti_fdc_device::setaddress_dbin ) { // Selection login in the PAL and some circuits on the board @@ -245,14 +237,28 @@ WRITE_LINE_MEMBER(ti_fdc_device::dskpgena_w) LOGMASKED(LOG_CRU, "Map DSR (bit 0) = %d\n", m_selected); } +/* + Trigger the motor monoflop. +*/ 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"); - set_floppy_motors_running(true); - } + m_motormf->b_w(state); +} + +WRITE_LINE_MEMBER(ti_fdc_device::dvena_w) +{ + m_DVENA = state; + LOGMASKED(LOG_MOTOR, "Motor %s\n", state? "on" : "off"); + + // The monoflop is connected to the READY line + m_fd1771->set_force_ready(state==ASSERT_LINE); + + // Set all motors + for (auto & elem : m_floppy) + if (elem != nullptr) elem->mon_w((state==ASSERT_LINE)? 0 : 1); + + // The motor-on line also connects to the wait state logic + operate_ready_line(); } WRITE_LINE_MEMBER(ti_fdc_device::waiten_w) @@ -262,7 +268,6 @@ WRITE_LINE_MEMBER(ti_fdc_device::waiten_w) // 1: TMS9900 is stopped until IRQ or DRQ are set // 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); } @@ -276,110 +281,70 @@ WRITE_LINE_MEMBER(ti_fdc_device::sidsel_w) { // Select side of disk (bit 7) LOGMASKED(LOG_CRU, "Set side (bit 7) = %d\n", state); - if (m_current != NONE) m_floppy[m_current]->ss_w(state); + if (m_sel_floppy != 0) m_floppy[m_sel_floppy-1]->ss_w(state); } -WRITE_LINE_MEMBER(ti_fdc_device::dsel_w) +/* + Drive selects +*/ +WRITE_LINE_MEMBER(ti_fdc_device::dsel1_w) { - 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 - if (m_floppy[1] == nullptr) dsel &= 0x05; // 101 - if (m_floppy[0] == nullptr) dsel &= 0x06; // 110 - - switch (dsel) - { - case 0: - m_current = NONE; - LOGMASKED(LOG_CRU, "All drives deselected\n"); - break; - case 1: - m_current = 0; - break; - case 2: - m_current = 1; - break; - case 3: - // The schematics do not reveal any countermeasures against multiple selection - // so we assume that the highest value wins. - m_current = 1; - LOGMASKED(LOG_WARN, "Warning - multiple drives selected\n"); - break; - case 4: - m_current = 2; - break; - default: - m_current = 2; - LOGMASKED(LOG_WARN, "Warning - multiple drives selected\n"); - break; - } - LOGMASKED(LOG_CRU, "New DSEL = %d\n", dsel); + select_drive(1, state); +} - 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); - } +WRITE_LINE_MEMBER(ti_fdc_device::dsel2_w) +{ + select_drive(2, state); } -/* - Monoflop has gone back to the OFF state. -*/ -void ti_fdc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +WRITE_LINE_MEMBER(ti_fdc_device::dsel3_w) { - set_floppy_motors_running(false); + select_drive(3, state); } -/* - All floppy motors are operated by the same line. -*/ -void ti_fdc_device::set_floppy_motors_running(bool run) +void ti_fdc_device::select_drive(int n, int state) { - if (run) + if (state == CLEAR_LINE) { - if (m_DVENA==CLEAR_LINE) LOGMASKED(LOG_MOTOR, "Motor START\n"); - m_DVENA = ASSERT_LINE; - m_motor_on_timer->adjust(attotime::from_msec(4230)); + LOGMASKED(LOG_CRU, "Unselect drive DSK%d\n", n); + + // Only when no bit is set, unselect all drives. + if ((m_crulatch->q4_r() == 0) && (m_crulatch->q5_r() == 0) + && (m_crulatch->q6_r() == 0)) + { + m_fd1771->set_floppy(nullptr); + m_sel_floppy = 0; + } } else { - if (m_DVENA==ASSERT_LINE) LOGMASKED(LOG_MOTOR, "Motor STOP\n"); - m_DVENA = CLEAR_LINE; - } - - // The monoflop is connected to the READY line - m_fd1771->set_force_ready(run); - - // Set all motors - for (auto & elem : m_floppy) - if (elem != nullptr) elem->mon_w((run)? 0 : 1); + LOGMASKED(LOG_CRU, "Select drive DSK%d\n", n); + if (m_sel_floppy != 0 && m_sel_floppy != n) + { + LOGMASKED(LOG_WARN, "Warning: DSK%d selected while DSK%d not yet unselected\n", n, m_sel_floppy); + } - // The motor-on line also connects to the wait state logic - operate_ready_line(); + if (m_floppy[n-1] != nullptr) + { + m_sel_floppy = n; + m_fd1771->set_floppy(m_floppy[n-1]); + m_floppy[n-1]->ss_w(m_crulatch->q7_r()); + } + } } void ti_fdc_device::device_start() { m_dsrrom = memregion(TI99_DSRROM)->base(); - m_motor_on_timer = timer_alloc(MOTOR_TIMER); m_cru_base = 0x1100; - // In case we implement a callback after all: - // m_fd1771->setup_ready_cb(wd_fdc_device::rline_cb(&ti_fdc_device::dvena_r, this)); save_item(NAME(m_address)); save_item(NAME(m_DRQ)); save_item(NAME(m_IRQ)); save_item(NAME(m_DVENA)); save_item(NAME(m_inDsrArea)); - save_item(NAME(m_WAITena)); save_item(NAME(m_WDsel)); - save_item(NAME(m_current)); + save_item(NAME(m_sel_floppy)); } void ti_fdc_device::device_reset() @@ -399,7 +364,6 @@ void ti_fdc_device::device_reset() m_DVENA = CLEAR_LINE; m_fd1771->set_force_ready(false); - m_WAITena = false; m_selected = false; m_inDsrArea = false; m_WDsel = false; @@ -412,8 +376,7 @@ void ti_fdc_device::device_reset() LOGMASKED(LOG_CONFIG, "No floppy attached to connector %d\n", i); } - m_current = 0; - m_fd1771->set_floppy(m_floppy[m_current]); + m_sel_floppy = 0; } void ti_fdc_device::device_config_complete() @@ -458,10 +421,17 @@ void ti_fdc_device::device_add_mconfig(machine_config& config) m_crulatch->q_out_cb<1>().set(FUNC(ti_fdc_device::kaclk_w)); m_crulatch->q_out_cb<2>().set(FUNC(ti_fdc_device::waiten_w)); m_crulatch->q_out_cb<3>().set(FUNC(ti_fdc_device::hlt_w)); - m_crulatch->q_out_cb<4>().set(FUNC(ti_fdc_device::dsel_w)); - m_crulatch->q_out_cb<5>().set(FUNC(ti_fdc_device::dsel_w)); - m_crulatch->q_out_cb<6>().set(FUNC(ti_fdc_device::dsel_w)); + m_crulatch->q_out_cb<4>().set(FUNC(ti_fdc_device::dsel1_w)); + m_crulatch->q_out_cb<5>().set(FUNC(ti_fdc_device::dsel2_w)); + m_crulatch->q_out_cb<6>().set(FUNC(ti_fdc_device::dsel3_w)); m_crulatch->q_out_cb<7>().set(FUNC(ti_fdc_device::sidsel_w)); + + TTL74123(config, m_motormf, 0); + m_motormf->out_cb().set(FUNC(ti_fdc_device::dvena_w)); + m_motormf->set_connection_type(TTL74123_GROUNDED); + m_motormf->set_resistor_value(RES_K(200)); + m_motormf->set_capacitor_value(CAP_U(47)); + m_motormf->set_clear_pin_value(1); } const tiny_rom_entry *ti_fdc_device::device_rom_region() const diff --git a/src/devices/bus/ti99/peb/ti_fdc.h b/src/devices/bus/ti99/peb/ti_fdc.h index ef16913e206..3a54e0e7c7e 100644 --- a/src/devices/bus/ti99/peb/ti_fdc.h +++ b/src/devices/bus/ti99/peb/ti_fdc.h @@ -20,6 +20,7 @@ #include "machine/74259.h" #include "machine/wd_fdc.h" #include "imagedev/floppy.h" +#include "machine/74123.h" namespace bus { namespace ti99 { namespace peb { @@ -44,8 +45,6 @@ protected: const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; - void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - private: DECLARE_FLOPPY_FORMATS( floppy_formats ); @@ -57,9 +56,15 @@ private: DECLARE_WRITE_LINE_MEMBER(kaclk_w); DECLARE_WRITE_LINE_MEMBER(waiten_w); DECLARE_WRITE_LINE_MEMBER(hlt_w); - DECLARE_WRITE_LINE_MEMBER(dsel_w); DECLARE_WRITE_LINE_MEMBER(sidsel_w); + DECLARE_WRITE_LINE_MEMBER(dvena_w); + DECLARE_WRITE_LINE_MEMBER(dsel1_w); + DECLARE_WRITE_LINE_MEMBER(dsel2_w); + DECLARE_WRITE_LINE_MEMBER(dsel3_w); + + void select_drive(int n, int state); + // For debugger access void debug_read(offs_t offset, uint8_t* value); @@ -75,9 +80,6 @@ private: // Holds the status of the DRQ, IRQ, and HLD lines. int m_DRQ, m_IRQ, m_HLD; - // Latched CRU outputs - required_device m_crulatch; - // Signal DVENA. When true, makes some drive turning. int m_DVENA; @@ -90,12 +92,15 @@ private: // WD chip selected bool m_WDsel; - // count 4.23s from rising edge of motor_on - emu_timer* m_motor_on_timer; - // Link to the FDC1771 controller on the board. required_device m_fd1771; + // Latched CRU outputs + required_device m_crulatch; + + // Motor monoflop + required_device m_motormf; + // DSR ROM uint8_t* m_dsrrom; @@ -103,7 +108,7 @@ private: floppy_image_device* m_floppy[3]; // Currently selected floppy drive - int m_current; + int m_sel_floppy; }; } } } // end namespace bus::ti99::peb -- cgit v1.2.3