Skip to content

Commit 6897837

Browse files
committed
esq5505.cpp: Add VFX-family ROM & EEPROM Cartridge support, and improve floppy support.
Second attempt, simpler and hopefully better.
1 parent f0b27b1 commit 6897837

File tree

3 files changed

+457
-35
lines changed

3 files changed

+457
-35
lines changed

src/mame/ensoniq/esq5505.cpp

Lines changed: 232 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
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+
300352
void 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+
306462
void 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

318474
void 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("\nFloppy Drive has Floppy '%s'\n", floppy->filename());
489+
m_floppy_dskchg = false;
490+
} else {
491+
LOG("\nFloppy Drive has No Floppy\n");
492+
m_floppy_dskchg = true;
493+
}
494+
} else {
495+
LOG("\nFloppy Drive has No Image Device!\n");
496+
}
497+
} else {
498+
LOG("\nNo 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("\nCartridge Slot has Cartridge '%s'\n", m_cart->filename());
506+
} else {
507+
LOG("\nCartridge Slot has No Cartridge\n");
508+
}
509+
}
320510
}
321511

322512
void 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

358541
uint16_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

665862
void 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

Comments
 (0)