178178#include " sound/esqpump.h"
179179#include " emupal.h"
180180#include " speaker.h"
181+ #include " vfxcart.h"
181182
182183#include < cstdarg>
183184#include < cstdio>
@@ -223,6 +224,7 @@ class esq5505_state : public driver_device
223224 , m_pump(*this , " pump" )
224225 , m_fdc(*this , " wd1772" )
225226 , m_floppy_connector(*this , " wd1772:0" )
227+ , m_cart(*this , " cart" )
226228 , m_panel(*this , " panel" )
227229 , m_dmac(*this , " mc68450" )
228230 , m_mdout(*this , " mdout" )
@@ -258,6 +260,7 @@ class esq5505_state : public driver_device
258260 required_device<esq_5505_5510_pump_device> m_pump;
259261 optional_device<wd1772_device> m_fdc;
260262 optional_device<floppy_connector> m_floppy_connector;
263+ optional_device<ensoniq_vfx_cartridge> m_cart;
261264 required_device<esqpanel_device> m_panel;
262265 optional_device<hd63450_device> m_dmac;
263266 required_device<midi_port_device> m_mdout;
@@ -283,7 +286,18 @@ class esq5505_state : public driver_device
283286
284287 int m_system_type = 0 ;
285288 uint8_t m_duart_io = 0 ;
286-
289+ bool m_otis_irq = false ;
290+ bool m_floppy_dskchg = false ;
291+ bool m_docirq = false ;
292+ bool m_floppy_is_loaded = false ;
293+ bool m_floppy_is_active = false ;
294+ emu_timer *m_motor_on_timer;
295+ emu_timer *m_dskchg_reset_timer;
296+
297+ TIMER_CALLBACK_MEMBER (floppy_motor_on);
298+ TIMER_CALLBACK_MEMBER (floppy_dskchg_reset);
299+
300+ static void floppy_drives (device_slot_interface &device);
287301 static void floppy_formats (format_registration &fr);
288302
289303 void eps_map (address_map &map) ATTR_COLD;
@@ -294,15 +308,157 @@ class esq5505_state : public driver_device
294308 void cpu_space_map (address_map &map) ATTR_COLD;
295309 void eps_cpu_space_map (address_map &map) ATTR_COLD;
296310
311+ void update_floppy_inputs ();
312+ void floppy_loaded (bool loaded);
313+ void floppy_load (floppy_image_device *floppy);
314+ void floppy_unload (floppy_image_device *floppy);
315+ void cartridge_loaded (bool loaded);
316+ void cartridge_load (ensoniq_vfx_cartridge *cart);
317+ void cartridge_unload (ensoniq_vfx_cartridge *cart);
318+
319+ void update_docirq_to_maincpu ();
320+ void otis_irq (int irq);
321+
297322 uint16_t m_analog_values[8 ];
298323};
299324
325+ void esq5505_state::cartridge_loaded (bool loaded)
326+ {
327+ LOG (" Cartridge %s\n " , loaded ? " Inserted" : " Ejected" );
328+ int state = loaded ? CLEAR_LINE : ASSERT_LINE;
329+
330+ // On VFX and later, DUART input bit 1 is 0 for cartridge present.
331+ LOG (" ip1 -> %d\n " , state);
332+ m_duart->ip1_w (state);
333+ }
334+
335+ void esq5505_state::cartridge_load (ensoniq_vfx_cartridge *cart)
336+ {
337+ (void ) cart;
338+ cartridge_loaded (true );
339+ }
340+
341+ void esq5505_state::cartridge_unload (ensoniq_vfx_cartridge *cart)
342+ {
343+ (void ) cart;
344+ cartridge_loaded (false );
345+ }
346+
347+ void esq5505_state::floppy_drives (device_slot_interface &device)
348+ {
349+ device.option_add_internal (" 35dd" , FLOPPY_35_DD);
350+ }
351+
300352void esq5505_state::floppy_formats (format_registration &fr)
301353{
302354 fr.add_mfm_containers ();
303355 fr.add (FLOPPY_ESQIMG_FORMAT);
304356}
305357
358+ TIMER_CALLBACK_MEMBER (esq5505_state::floppy_motor_on)
359+ {
360+ bool motor_on = param;
361+ if (m_floppy_connector)
362+ {
363+ floppy_image_device *floppy = m_floppy_connector->get_device ();
364+ if (floppy)
365+ floppy->mon_w (motor_on ? CLEAR_LINE : ASSERT_LINE); // active low
366+ }
367+ }
368+
369+ TIMER_CALLBACK_MEMBER (esq5505_state::floppy_dskchg_reset)
370+ {
371+ m_floppy_dskchg = !m_floppy_is_loaded;
372+ LOG (" Resetting floppy_dskchg -> %s\n " , m_floppy_dskchg ? " true" : " false" );
373+ update_docirq_to_maincpu ();
374+ }
375+
376+ void esq5505_state::update_floppy_inputs ()
377+ {
378+ // update the "Disk Ready" input
379+ int state = (m_floppy_is_active && m_floppy_is_loaded) ? ASSERT_LINE : CLEAR_LINE;
380+ #if VERBOSE
381+ static int prev_state = 0 ;
382+ if (prev_state != state) LOG (" ip0 -> %d\n " , state);
383+ prev_state = state;
384+ #endif
385+ m_duart->ip0_w (state);
386+
387+ // Also update the DOC IRQ in case there's a pending disk change to handle.
388+ update_docirq_to_maincpu ();
389+ }
390+
391+ void esq5505_state::floppy_loaded (bool loaded)
392+ {
393+ if (m_floppy_connector)
394+ {
395+ m_floppy_is_loaded = loaded;
396+ if (!loaded)
397+ {
398+ // Only set m_floppy_dskchg; it will be reset a short time after
399+ // the disk has been enabled while m_floppy_dskchg is true.
400+ m_floppy_dskchg = true ;
401+ }
402+
403+ LOG (" Floppy %s\n " , loaded ? " Inserted" : " Ejected" );
404+ update_floppy_inputs ();
405+ }
406+ else
407+ {
408+ LOG (" <No Floppy connector for loaded=%d>\n " , loaded);
409+ }
410+ }
411+
412+ void esq5505_state::floppy_load (floppy_image_device *floppy)
413+ {
414+ (void ) floppy;
415+ floppy_loaded (true );
416+ }
417+
418+ void esq5505_state::floppy_unload (floppy_image_device *floppy)
419+ {
420+ (void ) floppy;
421+ floppy_loaded (false );
422+ }
423+
424+ void esq5505_state::update_docirq_to_maincpu ()
425+ {
426+ bool floppy_dskchg_irq = m_floppy_is_active && m_floppy_dskchg;
427+ if (floppy_dskchg_irq) LOG (" docirq (m68k_irq1) due to disk change = %d\n " , floppy_dskchg_irq);
428+ if (floppy_dskchg_irq && m_floppy_is_loaded)
429+ {
430+ // The drives that Ensoniq use only _pulse_ DSKCHG for a brief time, when a disk is in the drive.
431+ // schedule a reset.
432+ LOG (" Scheduling DSKCHG reset\n " );
433+ m_dskchg_reset_timer->adjust (attotime::from_nsec (500 ));
434+ }
435+ bool v = m_otis_irq || floppy_dskchg_irq;
436+ if (v != m_docirq)
437+ {
438+ LOG (" docirq (m68k_irq1) -> %d\n " , v);
439+ m_maincpu->set_input_line (M68K_IRQ_1, v);
440+ m_docirq = v;
441+ }
442+ else
443+ {
444+ // LOG("m68k irq1 -- %d\n", v);
445+ }
446+ }
447+
448+ void esq5505_state::otis_irq (int irq)
449+ {
450+ if (irq != m_otis_irq)
451+ {
452+ // LOG("otis_irq -> %d\n", irq);
453+ m_otis_irq = irq;
454+ update_docirq_to_maincpu ();
455+ }
456+ else
457+ {
458+ // LOG("otis_irq -- %d\n", irq);
459+ }
460+ }
461+
306462void esq5505_state::cpu_space_map (address_map &map)
307463{
308464 map (0xfffff0 , 0xffffff ).m (m_maincpu, FUNC (m68000_base_device::autovectors_map));
@@ -317,11 +473,59 @@ void esq5505_state::eps_cpu_space_map(address_map &map)
317473
318474void esq5505_state::machine_start ()
319475{
476+ LOG (" machine_start()\n " );
477+ if (m_floppy_connector) {
478+ floppy_image_device *floppy = m_floppy_connector->get_device ();
479+ if (floppy) {
480+ floppy->setup_load_cb (floppy_image_device::load_cb (&esq5505_state::floppy_load, this ));
481+ floppy->setup_unload_cb (floppy_image_device::unload_cb (&esq5505_state::floppy_unload, this ));
482+
483+ m_motor_on_timer = timer_alloc (FUNC (esq5505_state::floppy_motor_on), this );
484+ m_dskchg_reset_timer = timer_alloc (FUNC (esq5505_state::floppy_dskchg_reset), this );
485+
486+ // Set DSKCHG according to whether there is a floppy in the drive.
487+ if (floppy->exists ()) {
488+ LOG (" \n Floppy Drive has Floppy '%s'\n " , floppy->filename ());
489+ m_floppy_dskchg = false ;
490+ } else {
491+ LOG (" \n Floppy Drive has No Floppy\n " );
492+ m_floppy_dskchg = true ;
493+ }
494+ } else {
495+ LOG (" \n Floppy Drive has No Image Device!\n " );
496+ }
497+ } else {
498+ LOG (" \n No Floppy Drive\n " );
499+ }
500+ if (m_cart) {
501+ m_cart->setup_load_cb (ensoniq_vfx_cartridge::load_cb (&esq5505_state::cartridge_load, this ));
502+ m_cart->setup_unload_cb (ensoniq_vfx_cartridge::unload_cb (&esq5505_state::cartridge_unload, this ));
503+
504+ if (m_cart->exists ()) {
505+ LOG (" \n Cartridge Slot has Cartridge '%s'\n " , m_cart->filename ());
506+ } else {
507+ LOG (" \n Cartridge Slot has No Cartridge\n " );
508+ }
509+ }
320510}
321511
322512void esq5505_state::machine_reset ()
323513{
324- floppy_image_device *floppy = m_floppy_connector ? m_floppy_connector->get_device () : nullptr ;
514+ // Check our image devices for load status.
515+ if (m_floppy_connector) {
516+ floppy_image_device *floppy = m_floppy_connector->get_device ();
517+ if (floppy && floppy->exists ()) {
518+ floppy_load (floppy);
519+ } else {
520+ floppy_unload (floppy);
521+ }
522+ }
523+
524+ if (m_cart && m_cart->exists ()) {
525+ cartridge_load (m_cart);
526+ } else {
527+ cartridge_unload (m_cart);
528+ }
325529
326530 // Default analog values: all values are 10 bits, left-justified within 16 bits.
327531 m_analog_values[0 ] = 0x7fc0 ; // pitch mod: start in the center
@@ -332,27 +536,6 @@ void esq5505_state::machine_reset()
332536 m_analog_values[5 ] = 0xffc0 ; // Volume control: full on.
333537 m_analog_values[6 ] = 0x7fc0 ; // Battery voltage: something reasonable.
334538 m_analog_values[7 ] = 0x5540 ; // vRef to check battery.
335-
336- // on VFX, bit 0 is 1 for 'cartridge present'.
337- // on VFX-SD and later, bit 0 is2 1 for floppy present, bit 1 is 1 for cartridge present
338- if (strcmp (machine ().system ().name , " vfx" ) == 0 )
339- {
340- // todo: handle VFX cart-in when we support cartridges
341- m_duart->ip0_w (ASSERT_LINE);
342- }
343- else
344- {
345- m_duart->ip1_w (CLEAR_LINE);
346-
347- if (floppy)
348- {
349- m_duart->ip0_w (CLEAR_LINE);
350- }
351- else
352- {
353- m_duart->ip0_w (ASSERT_LINE);
354- }
355- }
356539}
357540
358541uint16_t esq5505_state::lower_r (offs_t offset)
@@ -396,6 +579,7 @@ void esq5505_state::vfx_map(address_map &map)
396579 map (0x200000 , 0x20001f ).rw (" otis" , FUNC (es5505_device::read), FUNC (es5505_device::write));
397580 map (0x280000 , 0x28001f ).rw (m_duart, FUNC (mc68681_device::read), FUNC (mc68681_device::write)).umask16 (0x00ff );
398581 map (0x260000 , 0x2601ff ).rw (m_esp, FUNC (es5510_device::host_r), FUNC (es5510_device::host_w)).umask16 (0x00ff );
582+ map (0x2e0000 , 0x2fffff ).rw (m_cart, FUNC (ensoniq_vfx_cartridge::read), FUNC (ensoniq_vfx_cartridge::write)).umask16 (0x00ff );
399583 map (0xc00000 , 0xc1ffff ).rom ().region (" osrom" , 0 );
400584 map (0xff0000 , 0xffffff ).ram ().share (" osram" );
401585}
@@ -407,6 +591,7 @@ void esq5505_state::vfxsd_map(address_map &map)
407591 map (0x280000 , 0x28001f ).rw (m_duart, FUNC (mc68681_device::read), FUNC (mc68681_device::write)).umask16 (0x00ff );
408592 map (0x260000 , 0x2601ff ).rw (m_esp, FUNC (es5510_device::host_r), FUNC (es5510_device::host_w)).umask16 (0x00ff );
409593 map (0x2c0000 , 0x2c0007 ).rw (m_fdc, FUNC (wd1772_device::read), FUNC (wd1772_device::write)).umask16 (0x00ff );
594+ map (0x2e0000 , 0x2fffff ).rw (m_cart, FUNC (ensoniq_vfx_cartridge::read), FUNC (ensoniq_vfx_cartridge::write)).umask16 (0x00ff );
410595 map (0x330000 , 0x37ffff ).ram ().share (" seqram" );
411596 map (0xc00000 , 0xc3ffff ).rom ().region (" osrom" , 0 );
412597 map (0xff0000 , 0xffffff ).ram ().share (" osram" );
@@ -469,7 +654,7 @@ void esq5505_state::duart_output(uint8_t data)
469654 VFX-SD & SD-1 (32):
470655 bits 0/1/2 = analog sel
471656 bit 3 = SSEL (disk side)
472- bit 4 = DSEL (drive select? )
657+ bit 4 = DSEL (Drive Delect and floppy Motor On )
473658 bit 6 = ESPHALT
474659 bit 7 = SACK (?)
475660 */
@@ -499,7 +684,23 @@ void esq5505_state::duart_output(uint8_t data)
499684 }
500685 else
501686 {
502- floppy->ss_w (((data & 8 )>>3 )^1 );
687+ floppy->ss_w (((data & 8 ) >> 3 ) ^ 1 ); // bit 3, inverted -> floppy
688+ m_floppy_is_active = (data & 16 ) != 0 ; // bit 4 is used to activate the floppy:
689+ if (m_floppy_is_active)
690+ {
691+ // immediately assert DISK SELECT (active low)
692+ floppy->ds_w (CLEAR_LINE);
693+ // but schedule a delayed MOTOR ON, since the keyboard constantly pulses this after a file has been read.
694+ m_motor_on_timer->adjust (attotime::from_usec (100 ), 1 );
695+ }
696+ else
697+ {
698+ // immediately deassert DISK SELECT (active low)
699+ floppy->ds_w (ASSERT_LINE);
700+ // but schedule a slightly delayed MOTOR OFF, since the keyboard sometimes seems to pulse this.
701+ m_motor_on_timer->adjust (attotime::from_usec (50 ), 0 );
702+ }
703+ update_floppy_inputs ();
503704 }
504705 }
505706
@@ -594,7 +795,7 @@ void esq5505_state::common(machine_config &config)
594795 m_otis->set_region0 (" waverom" ); /* Bank 0 */
595796 m_otis->set_region1 (" waverom2" ); /* Bank 1 */
596797 m_otis->set_channels (4 ); /* channels */
597- m_otis->irq_cb ().set_inputline (m_maincpu, M68K_IRQ_1 );
798+ m_otis->irq_cb ().set ( FUNC (esq5505_state::otis_irq) );
598799 m_otis->read_port_cb ().set (FUNC (esq5505_state::analog_r)); /* ADC */
599800 m_otis->add_route (0 , " pump" , 1.0 , 0 );
600801 m_otis->add_route (1 , " pump" , 1.0 , 1 );
@@ -610,6 +811,8 @@ void esq5505_state::vfx(machine_config &config, int panel_type)
610811{
611812 common (config);
612813
814+ ENSONIQ_VFX_CARTRIDGE (config, m_cart);
815+
613816 ESQPANEL2X40_VFX (config, m_panel, panel_type);
614817 m_panel->write_tx ().set (m_duart, FUNC (mc68681_device::rx_b_w));
615818 m_panel->write_analog ().set (FUNC (esq5505_state::analog_w));
@@ -630,10 +833,7 @@ void esq5505_state::eps(machine_config &config)
630833 m_panel->write_analog ().set (FUNC (esq5505_state::analog_w));
631834
632835 WD1772 (config, m_fdc, 8_MHz_XTAL);
633- FLOPPY_CONNECTOR (config, m_floppy_connector);
634- m_floppy_connector->option_add (" 35dd" , FLOPPY_35_DD);
635- m_floppy_connector->set_default_option (" 35dd" );
636- m_floppy_connector->set_formats (esq5505_state::floppy_formats);
836+ FLOPPY_CONNECTOR (config, m_floppy_connector, esq5505_state::floppy_drives, " 35dd" , esq5505_state::floppy_formats, true );// .enable_sound(true);
637837
638838 HD63450 (config, m_dmac, 10_MHz_XTAL); // MC68450 compatible
639839 m_dmac->set_cpu_tag (m_maincpu);
@@ -656,10 +856,7 @@ void esq5505_state::vfxsd(machine_config &config, int panel_type)
656856 m_pump->add_route (3 , " aux" , 1.0 , 1 );
657857
658858 WD1772 (config, m_fdc, 8000000 );
659- FLOPPY_CONNECTOR (config, m_floppy_connector);
660- m_floppy_connector->option_add (" 35dd" , FLOPPY_35_DD);
661- m_floppy_connector->set_default_option (" 35dd" );
662- m_floppy_connector->set_formats (esq5505_state::floppy_formats);
859+ FLOPPY_CONNECTOR (config, m_floppy_connector, esq5505_state::floppy_drives, " 35dd" , esq5505_state::floppy_formats, true ).enable_sound (true );
663860}
664861
665862void esq5505_state::sd1 (machine_config &config, int panel_type)
@@ -724,7 +921,7 @@ void esq5505_state::common32(machine_config &config)
724921 m_otis->set_region0 (" waverom" ); /* Bank 0 */
725922 m_otis->set_region1 (" waverom2" ); /* Bank 1 */
726923 m_otis->set_channels (4 ); /* channels */
727- m_otis->irq_cb ().set_inputline (m_maincpu, M68K_IRQ_1 );
924+ m_otis->irq_cb ().set ( FUNC (esq5505_state::otis_irq) );
728925 m_otis->read_port_cb ().set (FUNC (esq5505_state::analog_r)); /* ADC */
729926 m_otis->add_route (0 , " pump" , 1.0 , 0 );
730927 m_otis->add_route (1 , " pump" , 1.0 , 1 );
0 commit comments