ZX-Spectrum Beta-disk interfaces improvements, all V2-V5 models should work fine now

This commit is contained in:
MetalliC 2020-05-31 10:27:03 +03:00
parent 8a0dff1cf1
commit 0b3a042237
9 changed files with 136 additions and 79 deletions

View File

@ -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
{

View File

@ -54,12 +54,11 @@ protected:
required_device<spectrum_expansion_slot_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;
};

View File

@ -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();
}

View File

@ -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();
};

View File

@ -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))
{

View File

@ -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);

View File

@ -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())

View File

@ -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);

View File

@ -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();
}