Retooled ZIP emulation into more expansible Removable Disk emulation, ZIP 100 and 250 types remain selectable, alongside the new 86Box (ie. generic) option.

This commit is contained in:
OBattler
2025-07-25 16:30:40 +02:00
parent 733e0e3dca
commit 64e85fdfbc
38 changed files with 1254 additions and 1051 deletions

View File

@@ -31,7 +31,7 @@ extern "C" {
#include <86box/hdc.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/zip.h>
#include <86box/rdisk.h>
#include <86box/mo.h>
#include <86box/plat.h>
#include <86box/machine.h>
@@ -102,7 +102,7 @@ struct Pixmaps {
PixmapSetEmptyActive floppy_525;
PixmapSetEmptyActive floppy_35;
PixmapSetEmptyActive cdrom;
PixmapSetEmptyActive zip;
PixmapSetEmptyActive rdisk;
PixmapSetEmptyActive mo;
PixmapSetActive hd;
PixmapSetEmptyActive net;
@@ -283,7 +283,7 @@ struct MachineStatus::States {
pixmaps.floppy_525.load(QIcon(":/settings/qt/icons/floppy_525.ico"));
pixmaps.floppy_35.load(QIcon(":/settings/qt/icons/floppy_35.ico"));
pixmaps.cdrom.load(QIcon(":/settings/qt/icons/cdrom.ico"));
pixmaps.zip.load(QIcon(":/settings/qt/icons/zip.ico"));
pixmaps.rdisk.load(QIcon(":/settings/qt/icons/rdisk.ico"));
pixmaps.mo.load(QIcon(":/settings/qt/icons/mo.ico"));
pixmaps.hd.load(QIcon(":/settings/qt/icons/hard_disk.ico"));
pixmaps.net.load(QIcon(":/settings/qt/icons/network.ico"));
@@ -298,8 +298,8 @@ struct MachineStatus::States {
for (auto &c : cdrom) {
c.pixmaps = &pixmaps.cdrom;
}
for (auto &z : zip) {
z.pixmaps = &pixmaps.zip;
for (auto &z : rdisk) {
z.pixmaps = &pixmaps.rdisk;
}
for (auto &m : mo) {
m.pixmaps = &pixmaps.mo;
@@ -316,7 +316,7 @@ struct MachineStatus::States {
StateEmptyActive cassette;
std::array<StateEmptyActive, FDD_NUM> fdd;
std::array<StateEmptyActive, CDROM_NUM> cdrom;
std::array<StateEmptyActive, ZIP_NUM> zip;
std::array<StateEmptyActive, RDISK_NUM> rdisk;
std::array<StateEmptyActive, MO_NUM> mo;
std::array<StateActive, HDD_BUS_USB> hdds;
std::array<StateEmptyActive, NET_CARD_MAX> net;
@@ -397,21 +397,21 @@ MachineStatus::iterateCDROM(const std::function<void(int)> &cb)
}
void
MachineStatus::iterateZIP(const std::function<void(int)> &cb)
MachineStatus::iterateRDisk(const std::function<void(int)> &cb)
{
auto hdc_name = QString(hdc_get_internal_name(hdc_current[0]));
for (size_t i = 0; i < ZIP_NUM; i++) {
for (size_t i = 0; i < RDISK_NUM; i++) {
/* Could be Internal or External IDE.. */
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() &&
if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && !hasIDE() &&
(hdc_name.left(3) != QStringLiteral("ide")) &&
(hdc_name.left(5) != QStringLiteral("xtide")) &&
(hdc_name.left(5) != QStringLiteral("mcide")))
continue;
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() &&
if ((rdisk_drives[i].bus_type == RDISK_BUS_SCSI) && !hasSCSI() &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (zip_drives[i].bus_type != 0) {
if (rdisk_drives[i].bus_type != 0) {
cb(i);
}
}
@@ -475,9 +475,9 @@ MachineStatus::refreshEmptyIcons()
}
for (size_t i = 0; i < CDROM_NUM; ++i)
d->cdrom[i].setEmpty(machine_status.cdrom[i].empty);
for (size_t i = 0; i < ZIP_NUM; i++) {
d->zip[i].setEmpty(machine_status.zip[i].empty);
d->zip[i].setWriteProtected(machine_status.zip[i].write_prot);
for (size_t i = 0; i < RDISK_NUM; i++) {
d->rdisk[i].setEmpty(machine_status.rdisk[i].empty);
d->rdisk[i].setWriteProtected(machine_status.rdisk[i].write_prot);
}
for (size_t i = 0; i < MO_NUM; i++) {
d->mo[i].setEmpty(machine_status.mo[i].empty);
@@ -515,13 +515,13 @@ MachineStatus::refreshIcons()
ui_sb_update_icon_write(SB_CDROM | i, 0);
}
}
for (size_t i = 0; i < ZIP_NUM; i++) {
d->zip[i].setActive(machine_status.zip[i].active);
d->zip[i].setWriteActive(machine_status.zip[i].write_active);
if (machine_status.zip[i].active)
ui_sb_update_icon(SB_ZIP | i, 0);
if (machine_status.zip[i].write_active)
ui_sb_update_icon_write(SB_ZIP | i, 0);
for (size_t i = 0; i < RDISK_NUM; i++) {
d->rdisk[i].setActive(machine_status.rdisk[i].active);
d->rdisk[i].setWriteActive(machine_status.rdisk[i].write_active);
if (machine_status.rdisk[i].active)
ui_sb_update_icon(SB_RDISK | i, 0);
if (machine_status.rdisk[i].write_active)
ui_sb_update_icon_write(SB_RDISK | i, 0);
}
for (size_t i = 0; i < MO_NUM; i++) {
d->mo[i].setActive(machine_status.mo[i].active);
@@ -558,9 +558,9 @@ MachineStatus::clearActivity()
cdrom.setActive(false);
cdrom.setWriteActive(false);
}
for (auto &zip : d->zip) {
zip.setActive(false);
zip.setWriteActive(false);
for (auto &rdisk : d->rdisk) {
rdisk.setActive(false);
rdisk.setWriteActive(false);
}
for (auto &mo : d->mo) {
mo.setActive(false);
@@ -600,8 +600,8 @@ MachineStatus::refresh(QStatusBar *sbar)
for (size_t i = 0; i < CDROM_NUM; i++) {
sbar->removeWidget(d->cdrom[i].label.get());
}
for (size_t i = 0; i < ZIP_NUM; i++) {
sbar->removeWidget(d->zip[i].label.get());
for (size_t i = 0; i < RDISK_NUM; i++) {
sbar->removeWidget(d->rdisk[i].label.get());
}
for (size_t i = 0; i < MO_NUM; i++) {
sbar->removeWidget(d->mo[i].label.get());
@@ -700,38 +700,38 @@ MachineStatus::refresh(QStatusBar *sbar)
sbar->addWidget(d->cdrom[i].label.get());
});
iterateZIP([this, sbar](int i) {
d->zip[i].label = std::make_unique<ClickableLabel>();
d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty());
if (QString(zip_drives[i].image_path).isEmpty())
d->zip[i].setWriteProtected(false);
else if (QString(zip_drives[i].image_path).left(5) == "wp://")
d->zip[i].setWriteProtected(true);
iterateRDisk([this, sbar](int i) {
d->rdisk[i].label = std::make_unique<ClickableLabel>();
d->rdisk[i].setEmpty(QString(rdisk_drives[i].image_path).isEmpty());
if (QString(rdisk_drives[i].image_path).isEmpty())
d->rdisk[i].setWriteProtected(false);
else if (QString(rdisk_drives[i].image_path).left(5) == "wp://")
d->rdisk[i].setWriteProtected(true);
else
d->zip[i].setWriteProtected(zip_drives[i].read_only);
d->zip[i].setActive(false);
d->zip[i].setWriteActive(false);
d->zip[i].refresh();
connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
MediaMenu::ptr->zipMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->zipMenus[i]->sizeHint().height()));
d->rdisk[i].setWriteProtected(rdisk_drives[i].read_only);
d->rdisk[i].setActive(false);
d->rdisk[i].setWriteActive(false);
d->rdisk[i].refresh();
connect((ClickableLabel *) d->rdisk[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
MediaMenu::ptr->rdiskMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->rdiskMenus[i]->sizeHint().height()));
});
connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::dropped, [i](QString str) {
MediaMenu::ptr->zipMount(i, str, false);
connect((ClickableLabel *) d->rdisk[i].label.get(), &ClickableLabel::dropped, [i](QString str) {
MediaMenu::ptr->rdiskMount(i, str, false);
});
d->zip[i].label->setToolTip(MediaMenu::ptr->zipMenus[i]->title());
d->zip[i].label->setAcceptDrops(true);
sbar->addWidget(d->zip[i].label.get());
d->rdisk[i].label->setToolTip(MediaMenu::ptr->rdiskMenus[i]->title());
d->rdisk[i].label->setAcceptDrops(true);
sbar->addWidget(d->rdisk[i].label.get());
});
iterateMO([this, sbar](int i) {
d->mo[i].label = std::make_unique<ClickableLabel>();
d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty());
if (QString(zip_drives[i].image_path).isEmpty())
if (QString(rdisk_drives[i].image_path).isEmpty())
d->mo[i].setWriteProtected(false);
else if (QString(zip_drives[i].image_path).left(5) == "wp://")
else if (QString(rdisk_drives[i].image_path).left(5) == "wp://")
d->mo[i].setWriteProtected(true);
else
d->mo[i].setWriteProtected(zip_drives[i].read_only);
d->mo[i].setWriteProtected(rdisk_drives[i].read_only);
d->mo[i].setActive(false);
d->mo[i].setWriteActive(false);
d->mo[i].refresh();
@@ -924,9 +924,9 @@ MachineStatus::updateTip(int tag)
if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item])
d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title());
break;
case SB_ZIP:
if (d->zip[item].label && MediaMenu::ptr->zipMenus[item])
d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title());
case SB_RDISK:
if (d->rdisk[item].label && MediaMenu::ptr->rdiskMenus[item])
d->rdisk[item].label->setToolTip(MediaMenu::ptr->rdiskMenus[item]->title());
break;
case SB_MO:
if (d->mo[item].label && MediaMenu::ptr->moMenus[item])