diff --git a/src/devices/bus/spectrum/beta.cpp b/src/devices/bus/spectrum/beta.cpp index 68f85d69d4f..1fa6ab60bdf 100644 --- a/src/devices/bus/spectrum/beta.cpp +++ b/src/devices/bus/spectrum/beta.cpp @@ -12,12 +12,16 @@ - 4k ROM - FORMAT, COPY etc. must be loaded from a disk to be used - disks are password protected - - uses 1771 disk controller + - uses FD1771 disk controller + - disk format: FM, 7 or 10 256-byte sectors per track, 2 system sectors + - supports up to 3 drives https://www.youtube.com/watch?v=gSJIuZjbFYs Original Beta Disk release with V3 ROM: - same features as above - uses a 1793 controller + - disk format: MFM, 16 256-byte sectors per track, 9 system sectors + - supports up to 4 drives Re-release dubbed "Beta Disk plus" with V4 ROM: - many operations moved into a larger capacity (8k) ROM rather @@ -30,8 +34,10 @@ Many clones exist, some specific to the various Spectrum clones. (not yet added) + Original Beta Disk (V2) clones + - Sandy FDD2 SP-DOS (match 2.0 ROM, only name text and checksum was changed) + Original Beta Disk (V3) clones - - Sandy FDD2 SP-DOS - AC DOS P.Z.APINA Beta Disk plus (V4) clones @@ -71,7 +77,9 @@ while master_latch is enabled access to regular Spectrum IO is blocked (output /IORQ forced to 1) but enabled BDI ports: - IO write to port 0b1xxxx111 -> D7 BDI ROM_latch (0=enable, 1=disble), D6 - FDC DDEN, D4 - SIDE, D3 - FDC HLT, D2 - FDC /MR (reset), D0-1 - floppy drive select. + IO write to port 0b1xxxx111 -> + V2: D7 BDI ROM_latch (0=enable, 1=disble), D4 - FDC HLT, D3 - SIDE, D0-2 - floppy drive select (bitmask, active low). + V3-V4: D7 BDI ROM_latch (0=enable, 1=disble), D6 - FDC DDEN, D4 - SIDE, D3 - FDC HLT, D2 - FDC /MR (reset), D0-1 - floppy drive select (binary value). IO read port 0b1xxxx111 <- D7 - FDC INTRQ, D6 - FDC DRQ IO read/write ports 0b0YYxx111 - access FDC ports YY @@ -98,7 +106,6 @@ DEFINE_DEVICE_TYPE(SPECTRUM_BETAPLUS, spectrum_betaplus_device, "spectrum_betapl static void beta_floppies(device_slot_interface &device) { - device.option_add("525sd", FLOPPY_525_SD); device.option_add("525qd", FLOPPY_525_QD); } @@ -173,6 +180,8 @@ ROM_END void spectrum_betav2_device::device_add_mconfig_base(machine_config& config) { + FLOPPY_CONNECTOR(config, "fdc:0", beta_floppies, "525qd", spectrum_betav2_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", beta_floppies, "525qd", spectrum_betav2_device::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, "fdc:2", beta_floppies, nullptr, spectrum_betav2_device::floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, "fdc:3", beta_floppies, nullptr, spectrum_betav2_device::floppy_formats).enable_sound(true); @@ -187,9 +196,6 @@ void spectrum_betav2_device::device_add_mconfig(machine_config &config) FD1771(config, m_fdc, 4_MHz_XTAL / 4); m_fdc->hld_wr_callback().set(FUNC(spectrum_betav2_device::fdc_hld_w)); - FLOPPY_CONNECTOR(config, "fdc:0", beta_floppies, "525sd", spectrum_betav2_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", beta_floppies, "525sd", spectrum_betav2_device::floppy_formats).enable_sound(true); - device_add_mconfig_base(config); } @@ -198,9 +204,6 @@ void spectrum_betav3_device::device_add_mconfig(machine_config& config) FD1793(config, m_fdc, 4_MHz_XTAL / 4); m_fdc->hld_wr_callback().set(FUNC(spectrum_betav3_device::fdc_hld_w)); - FLOPPY_CONNECTOR(config, "fdc:0", beta_floppies, "525qd", spectrum_betav2_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", beta_floppies, "525qd", spectrum_betav2_device::floppy_formats).enable_sound(true); - device_add_mconfig_base(config); } @@ -235,6 +238,7 @@ spectrum_betav2_device::spectrum_betav2_device(const machine_config &mconfig, de , m_fdc(*this, "fdc") , m_floppy(*this, "fdc:%u", 0) , m_exp(*this, "exp") + , m_control(0) { } @@ -292,9 +296,8 @@ void spectrum_betav2_device::device_reset() { // always paged in on boot? (no mode switch like beta128) m_romcs = 1; - m_romlatch = 0; m_control = 0; -// m_masterportdisable = 1; + m_masterportdisable = 1; } //************************************************************************** @@ -315,7 +318,7 @@ void spectrum_betav2_device::fetch(offs_t offset) else m_romcs = 0; - if (!m_romlatch) + if (!(m_control & 0x80)) { if (offset < 0x4000) m_romcs = 1; @@ -337,65 +340,99 @@ void spectrum_betav2_device::pre_data_fetch(offs_t offset) uint8_t spectrum_betav2_device::iorq_r(offs_t offset) { - uint8_t data = m_exp->iorq_r(offset); + uint8_t data = 0xff; -// if (!m_masterportdisable) - if (m_romcs) + if (!m_masterportdisable) { - switch (offset & 0xff) + switch (offset & 0xe7) { - case 0x1f: case 0x3f: case 0x5f: case 0x7f: + case 0x07: case 0x27: case 0x47: case 0x67: data = m_fdc->read((offset >> 5) & 0x03); break; - case 0xff: + case 0x87: case 0xa7 : case 0xc7 : case 0xe7 : data &= 0x3f; // actually open bus data |= m_fdc->drq_r() ? 0x40 : 0; data |= m_fdc->intrq_r() ? 0x80 : 0; break; } } + else + data = m_exp->iorq_r(offset); return data; } void spectrum_betav2_device::iorq_w(offs_t offset, uint8_t data) { -// if ((offset & 0x03) == 0x00) -// { -// m_masterportdisable = data & 0x80; -// } + if ((offset & 3) == 0) + m_masterportdisable = data & 0x80; -// if (!m_masterportdisable) - if (m_romcs) + if (!m_masterportdisable) { - switch (offset & 0xff) + switch (offset & 0x87) { - case 0x1f: case 0x3f: case 0x5f: case 0x7f: + case 0x07: m_fdc->write((offset >> 5) & 0x03, data); break; - case 0xff: - m_romlatch = data & 0x80; + case 0x87: + m_control = data; + + floppy_image_device* floppy = nullptr; + for (int i = 0; i < 3; i++) + if (!(data & (1 << i))) + { + floppy = m_floppy[i]->get_device(); + break; + } + + m_fdc->set_floppy(floppy); + if (floppy) + floppy->ss_w(BIT(data, 3) ? 0 : 1); + + m_fdc->hlt_w(BIT(data, 4)); + + motors_control(); + break; + } + } + else + m_exp->iorq_w(offset, data); +} + +void spectrum_betav3_device::iorq_w(offs_t offset, uint8_t data) +{ + if ((offset & 3) == 0) + m_masterportdisable = data & 0x80; + + if (!m_masterportdisable) + { + switch (offset & 0x87) + { + case 0x07: + m_fdc->write((offset >> 5) & 0x03, data); + break; + + case 0x87: + m_control = data; floppy_image_device* floppy = m_floppy[data & 3]->get_device(); - m_control = data; m_fdc->set_floppy(floppy); if (floppy) floppy->ss_w(BIT(data, 4) ? 0 : 1); m_fdc->dden_w(BIT(data, 6)); - // bit 3 connected to pin 23 "HLT" of FDC and via diode to INDEX - //m_fdc->hlt_w(BIT(data, 3)); // not handled in current wd_fdc + m_fdc->hlt_w(BIT(data, 3)); m_fdc->mr_w(BIT(data, 2)); motors_control(); break; } } - - m_exp->iorq_w(offset, data); + else + m_exp->iorq_w(offset, data); } uint8_t spectrum_betav2_device::mreq_r(offs_t offset) @@ -422,12 +459,26 @@ void spectrum_betav2_device::mreq_w(offs_t offset, uint8_t data) void spectrum_betav2_device::fdc_hld_w(int state) { - // TODO: HLD connected to RDY pin (current wd_fdc have no external RDY control) + m_fdc->set_force_ready(state); // HLD connected to RDY pin m_motor_active = state; motors_control(); } void spectrum_betav2_device::motors_control() +{ + for (int i = 0; i < 3; i++) + { + floppy_image_device* floppy = m_floppy[i]->get_device(); + if (!floppy) + continue; + if (m_motor_active && !(m_control & (1 << i))) + floppy->mon_w(CLEAR_LINE); + else + floppy->mon_w(ASSERT_LINE); + } +} + +void spectrum_betav3_device::motors_control() { for (int i = 0; i < 4; i++) { @@ -459,7 +510,7 @@ INPUT_CHANGED_MEMBER(spectrum_betaplus_device::magic_button) { m_slot->nmi_w(ASSERT_LINE); m_romcs = 1; - m_romlatch = 0; + m_control &= ~0x80; } else { diff --git a/src/devices/bus/spectrum/beta.h b/src/devices/bus/spectrum/beta.h index 95571910c86..6781bb1902f 100644 --- a/src/devices/bus/spectrum/beta.h +++ b/src/devices/bus/spectrum/beta.h @@ -54,12 +54,11 @@ protected: required_device m_exp; int m_romcs; - int m_romlatch; -// int m_masterportdisable; + int m_masterportdisable; u8 m_control; bool m_motor_active; void fdc_hld_w(int state); - void motors_control(); + virtual void motors_control(); void fetch(offs_t offset); }; @@ -75,6 +74,8 @@ public: protected: virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry *device_rom_region() const override; + virtual void iorq_w(offs_t offset, uint8_t data) override; + virtual void motors_control() override; }; diff --git a/src/devices/bus/spectrum/beta128.cpp b/src/devices/bus/spectrum/beta128.cpp index d24d1c0f76f..85423618b79 100644 --- a/src/devices/bus/spectrum/beta128.cpp +++ b/src/devices/bus/spectrum/beta128.cpp @@ -10,21 +10,6 @@ due to changes in the 128k ROM structure etc. (enable address is moved from 3cxx to 3dxx for example) - Issues: - - Using the FD1793 device a 'CAT' operation in the 'spectrum' driver - will always report 'No Disk' but using the Soviet clone KR1818VG93 - it properly gives the disk catalogue. Despite this files can still - be loaded from disk. - - The 128k Spectrum drivers have a similar issues, although even if - you replace the controller doing a 'CAT' operation seems to have - an adverse effect on the system memory setup as things become - corrupt (LOADing or MERGEing a program afterwards can cause a reset) - - Neither of these issues occur in other Spectrum emulators using - the same ROMs and floppy images. - TODO: there were many unofficial ROMs available for this, make them @@ -55,7 +40,6 @@ INPUT_PORTS_START(beta128) PORT_CONFNAME(0x03, 0x01, "System Switch") //PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_beta128_device, switch_changed, 0) PORT_CONFSETTING(0x00, "Off (128)") PORT_CONFSETTING(0x01, "Normal (auto-boot)") - //PORT_CONFSETTING(0x02, "Reset") // TODO: implement RESET callback INPUT_PORTS_END //------------------------------------------------- @@ -95,8 +79,7 @@ ROM_START(beta128) ROMX_LOAD("trd501.rom", 0x0000, 0x4000, CRC(3e3cdd4c) SHA1(8303ba0cc79daa6c04cd1e6ce27e8b6886a3f0de), ROM_BIOS(0)) ROM_SYSTEM_BIOS(1, "trd503", "TR-DOS v5.03") ROMX_LOAD("trd503.rom", 0x0000, 0x4000, CRC(10751aba) SHA1(21695e3f2a8f796386ce66eea8a246b0ac44810c), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(2, "trd504", "TR-DOS v5.04 (hack)") - ROMX_LOAD("trd504.rom", 0x0000, 0x4000, CRC(ba310874) SHA1(05e55e37df8eee6c68601ba9cf6c92195852ce3f), ROM_BIOS(2)) + // trd504.rom CRC ba310874 is bad dump of 5.03 with edited version text, no actual code changes. ROM_END //------------------------------------------------- @@ -156,6 +139,7 @@ void spectrum_beta128_device::device_start() save_item(NAME(m_romcs)); save_item(NAME(m_control)); save_item(NAME(m_motor_active)); + save_item(NAME(m_128rom_bit)); } //------------------------------------------------- @@ -170,7 +154,7 @@ void spectrum_beta128_device::device_reset() else m_romcs = 0; - m_control = 0; + m_128rom_bit = false; } //************************************************************************** @@ -189,46 +173,55 @@ void spectrum_beta128_device::pre_opcode_fetch(offs_t offset) if (!machine().side_effects_disabled()) { - if ((offset == 0x0066) || (offset & 0xff00) == 0x3d00) + u8 offs = offset >> 8; + + if (offs == 0x3d && m_128rom_bit) m_romcs = 1; - else if (offset >= 0x4000) + else if (offs == 0x3c && m_128rom_bit && m_switch->read() == 0x01) + m_romcs = 1; + else if (offs >= 0x40) m_romcs = 0; } } uint8_t spectrum_beta128_device::iorq_r(offs_t offset) { - uint8_t data = m_exp->iorq_r(offset); + uint8_t data = 0xff; if (m_romcs) { - switch (offset & 0xff) + switch (offset & 0x83) { - case 0x1f: case 0x3f: case 0x5f: case 0x7f: + case 0x03: data = m_fdc->read((offset >> 5) & 0x03); break; - case 0xff: + case 0x83: data &= 0x3f; // actually open bus data |= m_fdc->drq_r() ? 0x40 : 0; data |= m_fdc->intrq_r() ? 0x80 : 0; break; } - } + } else + data = m_exp->iorq_r(offset); + return data; } void spectrum_beta128_device::iorq_w(offs_t offset, uint8_t data) { + if ((offset & 0x8002) == 0) + m_128rom_bit = bool(data & 0x10); + if (m_romcs) { - switch (offset & 0xff) + switch (offset & 0x83) { - case 0x1f: case 0x3f: case 0x5f: case 0x7f: + case 0x03: m_fdc->write((offset >> 5) & 0x03, data); break; - case 0xff: + case 0x83: floppy_image_device* floppy = m_floppy[data & 3]->get_device(); m_control = data; @@ -237,15 +230,17 @@ void spectrum_beta128_device::iorq_w(offs_t offset, uint8_t data) floppy->ss_w(BIT(data, 4) ? 0 : 1); m_fdc->dden_w(BIT(data, 6)); - // bit 3 connected to pin 23 "HLT" of FDC and via diode to INDEX - //m_fdc->hlt_w(BIT(data, 3)); // not handled in current wd_fdc + m_fdc->hlt_w(BIT(data, 3)); + // bit 3 also connected to FDC /IP pin via diode, AND logic: if this bit is 0 - /IP will be forcibly set to low. + // used for bitbang index pulses generation to stop FDD drive motor with no disk inserted, currently not emulated. m_fdc->mr_w(BIT(data, 2)); motors_control(); break; } } - m_exp->iorq_w(offset, data); + else + m_exp->iorq_w(offset, data); } uint8_t spectrum_beta128_device::mreq_r(offs_t offset) @@ -273,6 +268,7 @@ INPUT_CHANGED_MEMBER(spectrum_beta128_device::magic_button) { if (newval && !oldval) { + m_romcs = 1; m_slot->nmi_w(ASSERT_LINE); } else @@ -283,7 +279,7 @@ INPUT_CHANGED_MEMBER(spectrum_beta128_device::magic_button) void spectrum_beta128_device::fdc_hld_w(int state) { - // TODO: HLD connected to RDY pin (current wd_fdc have no external RDY control) + m_fdc->set_force_ready(state); // HLD connected to RDY pin m_motor_active = state; motors_control(); } diff --git a/src/devices/bus/spectrum/beta128.h b/src/devices/bus/spectrum/beta128.h index 97e7dfccb6d..d82379d8605 100644 --- a/src/devices/bus/spectrum/beta128.h +++ b/src/devices/bus/spectrum/beta128.h @@ -56,6 +56,7 @@ protected: int m_romcs; u8 m_control; bool m_motor_active; + bool m_128rom_bit; void fdc_hld_w(int state); void motors_control(); }; diff --git a/src/mame/drivers/elwro800.cpp b/src/mame/drivers/elwro800.cpp index 68ff8044b7e..56af1b1e650 100644 --- a/src/mame/drivers/elwro800.cpp +++ b/src/mame/drivers/elwro800.cpp @@ -320,7 +320,7 @@ void elwro800_state::elwro800jr_io_w(offs_t offset, uint8_t data) if (!BIT(cs,0)) { // CFE - spectrum_port_fe_w(data); + spectrum_port_fe_w(offset, data); } else if (!BIT(cs,1)) { diff --git a/src/mame/drivers/spec128.cpp b/src/mame/drivers/spec128.cpp index a31014f9673..fd9fd5012ae 100644 --- a/src/mame/drivers/spec128.cpp +++ b/src/mame/drivers/spec128.cpp @@ -227,6 +227,8 @@ WRITE8_MEMBER(spectrum_state::spectrum_128_port_7ffd_w) /* update memory */ spectrum_128_update_memory(); + + m_exp->iorq_w(offset | 1, data); } void spectrum_state::spectrum_128_update_memory() @@ -255,7 +257,7 @@ void spectrum_state::spectrum_128_io(address_map &map) { map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w)); map(0x0000, 0x0000).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w)).select(0xfffe); - map(0x0001, 0x0001).w(FUNC(spectrum_state::spectrum_128_port_7ffd_w)).mirror(0x7ffc); // (A15 | A1) == 0, note: reading from this port does write to it by value from data bus + map(0x0001, 0x0001).w(FUNC(spectrum_state::spectrum_128_port_7ffd_w)).select(0x7ffc); // (A15 | A1) == 0, note: reading from this port does write to it by value from data bus map(0x8000, 0x8000).w("ay8912", FUNC(ay8910_device::data_w)).mirror(0x3ffd); map(0xc000, 0xc000).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0x3ffd); map(0x0001, 0x0001).r(FUNC(spectrum_state::spectrum_128_ula_r)); // .mirror(0xfffe); diff --git a/src/mame/drivers/spectrum.cpp b/src/mame/drivers/spectrum.cpp index 13127a78e0d..e3e2b36a1a2 100644 --- a/src/mame/drivers/spectrum.cpp +++ b/src/mame/drivers/spectrum.cpp @@ -341,7 +341,7 @@ READ8_MEMBER(spectrum_state::spectrum_rom_r) bit 2-0: border colour */ -void spectrum_state::spectrum_port_fe_w(uint8_t data) +void spectrum_state::spectrum_port_fe_w(offs_t offset, uint8_t data) { unsigned char Changed; @@ -365,6 +365,9 @@ void spectrum_state::spectrum_port_fe_w(uint8_t data) m_cassette->output((data & (1<<3)) ? -1.0 : +1.0); } + if (m_exp) + m_exp->iorq_w(offset, data); + m_port_fe_data = data; } @@ -457,6 +460,7 @@ READ8_MEMBER(spectrum_state::spectrum_port_ula_r) offset |= 1; //logerror("fb: %04x\n", offset); +#if 0 // TODO make this expansion devices friendly // Arkanoid, Cobra, Renegade, Short Circuit, Terra Cresta if (offset == 0x28ff) return floating_bus_r(); @@ -464,6 +468,7 @@ READ8_MEMBER(spectrum_state::spectrum_port_ula_r) // Sidewize if (offset == 0x40ff) return floating_bus_r(); +#endif // Pass through to expansion device if present if (m_exp->get_card_device()) diff --git a/src/mame/includes/spectrum.h b/src/mame/includes/spectrum.h index bf73a5c09e5..db0fbdd4e3c 100644 --- a/src/mame/includes/spectrum.h +++ b/src/mame/includes/spectrum.h @@ -146,7 +146,7 @@ protected: DECLARE_READ8_MEMBER(spectrum_data_r); DECLARE_WRITE8_MEMBER(spectrum_data_w); - void spectrum_port_fe_w(uint8_t data); + void spectrum_port_fe_w(offs_t offset, uint8_t data); DECLARE_READ8_MEMBER(spectrum_port_fe_r); DECLARE_READ8_MEMBER(spectrum_port_ula_r); DECLARE_READ8_MEMBER(spectrum_clone_port_ula_r); diff --git a/src/mame/machine/beta.cpp b/src/mame/machine/beta.cpp index 1f1cdf723b9..632d4965f8e 100644 --- a/src/mame/machine/beta.cpp +++ b/src/mame/machine/beta.cpp @@ -136,8 +136,9 @@ void beta_disk_device::param_w(uint8_t data) m_wd179x->dden_w(BIT(data, 6)); m_wd179x->mr_w(BIT(data, 2)); - // bit 3 connected to pin 23 "HLT" of FDC and via diode to INDEX - //m_wd179x->hlt_w(BIT(data, 3)); // not handled in current wd_fdc + m_wd179x->hlt_w(BIT(data, 3)); + // bit 3 also connected to FDC /IP pin via diode, AND logic: if this bit is 0 - /IP will be forcibly set to low. + // used for bitbang index pulses generation to stop FDD drive motor with no disk inserted, currently not emulated. motors_control(); } @@ -173,7 +174,7 @@ void beta_disk_device::data_w(uint8_t data) void beta_disk_device::fdc_hld_w(int state) { - // TODO: HLD connected to RDY pin (current wd_fdc have no external RDY control) + m_wd179x->set_force_ready(state); // HLD connected to RDY pin m_motor_active = state; motors_control(); }