Merge branch 'master' of ssh://webhost.codesrc.com/home/michael/projects/SCSI2SD
[SCSI2SD.git] / software / scsi2sd-util / TargetPanel.cc
index f84f91d..eb04e55 100644 (file)
@@ -51,7 +51,9 @@ namespace
        void CtrlGetFixedString(wxTextEntry* ctrl, char* dest, size_t len)
        {
                memset(dest, ' ', len);
-               strncpy(dest, ctrl->GetValue().ToAscii(), len);
+               std::string str(ctrl->GetValue().ToAscii());
+               // Don't use strncpy - we need to avoid NULL's
+               memcpy(dest, str.c_str(), std::min(len, str.size()));
        }
 
        bool CtrlIsAscii(wxTextEntry* ctrl)
@@ -102,7 +104,14 @@ TargetPanel::TargetPanel(wxWindow* parent, const TargetConfig& initialConfig) :
        Bind(wxEVT_SPINCTRL, &TargetPanel::onInput<wxSpinEvent>, this, ID_scsiIdCtrl);
 
        fgs->Add(new wxStaticText(this, wxID_ANY, wxT("Device Type")));
-       wxString deviceTypes[] = {wxT("Hard Drive"), wxT("Removable"), wxT("CDROM")};
+       wxString deviceTypes[] =
+       {
+               wxT("Hard Drive"),
+               wxT("Removable"),
+               wxT("CDROM"),
+               wxT("3.5\" Floppy"),
+               wxT("Magneto optical")
+       };
        myDeviceTypeCtrl =
                new wxChoice(
                        this,
@@ -123,21 +132,38 @@ TargetPanel::TargetPanel(wxWindow* parent, const TargetConfig& initialConfig) :
                        this,
                        ID_parityCtrl,
                        wxT("Enable Parity"));
+       myParityCtrl->SetToolTip(wxT("Enable to require valid SCSI parity bits when receiving data. Some hosts don't provide parity. SCSI2SD always outputs valid parity bits."));
        fgs->Add(myParityCtrl);
-       fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
        Bind(wxEVT_CHECKBOX, &TargetPanel::onInput<wxCommandEvent>, this, ID_parityCtrl);
 
-       fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
        myUnitAttCtrl =
                new wxCheckBox(
                        this,
                        ID_unitAttCtrl,
                        wxT("Enable Unit Attention"));
-
+       myUnitAttCtrl->SetToolTip(wxT("Enable this to inform the host of changes after hot-swapping SD cards. Causes problems with Mac Plus."));
        fgs->Add(myUnitAttCtrl);
-       fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
        Bind(wxEVT_CHECKBOX, &TargetPanel::onInput<wxCommandEvent>, this, ID_unitAttCtrl);
 
+       fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
+       myScsi2Ctrl =
+               new wxCheckBox(
+                       this,
+                       ID_scsi2Ctrl,
+                       wxT("Enable SCSI2 Mode"));
+       myScsi2Ctrl->SetToolTip(wxT("Enable high-performance mode. May cause problems with SASI/SCSI1 hosts."));
+       fgs->Add(myScsi2Ctrl);
+       Bind(wxEVT_CHECKBOX, &TargetPanel::onInput<wxCommandEvent>, this, ID_scsi2Ctrl);
+
+       myGlitchCtrl =
+               new wxCheckBox(
+                       this,
+                       ID_glitchCtrl,
+                       wxT("Disable glitch filter"));
+       myGlitchCtrl->SetToolTip(wxT("Improve performance at the cost of noise immunity. Only use with short cables."));
+       fgs->Add(myGlitchCtrl);
+       Bind(wxEVT_CHECKBOX, &TargetPanel::onInput<wxCommandEvent>, this, ID_glitchCtrl);
+
        fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SD card start sector")));
        wxWrapSizer* startContainer = new wxWrapSizer();
        myStartSDSectorCtrl =
@@ -304,6 +330,43 @@ TargetPanel::evaluate()
        bool valid = true;
        std::stringstream conv;
 
+       bool enabled = myEnableCtrl->IsChecked();
+       {
+               myScsiIdCtrl->Enable(enabled);
+               myDeviceTypeCtrl->Enable(enabled);
+               myParityCtrl->Enable(enabled);
+               myUnitAttCtrl->Enable(enabled);
+               myScsi2Ctrl->Enable(enabled);
+               myGlitchCtrl->Enable(enabled);
+               myStartSDSectorCtrl->Enable(enabled && !myAutoStartSectorCtrl->IsChecked());
+               myAutoStartSectorCtrl->Enable(enabled);
+               mySectorSizeCtrl->Enable(enabled);
+               myNumSectorCtrl->Enable(enabled);
+               mySizeCtrl->Enable(enabled);
+               mySizeUnitCtrl->Enable(enabled);
+               myVendorCtrl->Enable(enabled);
+               myProductCtrl->Enable(enabled);
+               myRevisionCtrl->Enable(enabled);
+               mySerialCtrl->Enable(enabled);
+       }
+
+       switch (myDeviceTypeCtrl->GetSelection())
+       {
+       case CONFIG_OPTICAL:
+               mySectorSizeCtrl->ChangeValue("2048");
+               mySectorSizeCtrl->Enable(false);
+               break;
+       case CONFIG_FLOPPY_14MB:
+               mySectorSizeCtrl->ChangeValue("512");
+               mySectorSizeCtrl->Enable(false);
+               myNumSectorCtrl->ChangeValue("2880");
+               myNumSectorCtrl->Enable(false);
+               mySizeUnitCtrl->Enable(false);
+               mySizeCtrl->Enable(false);
+               break;
+       };
+       evaluateSize();
+
        if (myAutoStartSectorCtrl->IsChecked())
        {
                std::stringstream ss; ss << myAutoStartSector;
@@ -393,23 +456,6 @@ TargetPanel::evaluate()
                mySerialMsg->SetLabelMarkup("");
        }
 
-       bool enabled = myEnableCtrl->IsChecked();
-       {
-               myScsiIdCtrl->Enable(enabled);
-               myDeviceTypeCtrl->Enable(enabled);
-               myParityCtrl->Enable(enabled);
-               myUnitAttCtrl->Enable(enabled);
-               myStartSDSectorCtrl->Enable(enabled && !myAutoStartSectorCtrl->IsChecked());
-               myAutoStartSectorCtrl->Enable(enabled);
-               mySectorSizeCtrl->Enable(enabled);
-               myNumSectorCtrl->Enable(enabled);
-               mySizeCtrl->Enable(enabled);
-               mySizeUnitCtrl->Enable(enabled);
-               myVendorCtrl->Enable(enabled);
-               myProductCtrl->Enable(enabled);
-               myRevisionCtrl->Enable(enabled);
-               mySerialCtrl->Enable(enabled);
-       }
        return valid || !enabled;
 }
 
@@ -423,49 +469,51 @@ TargetPanel::onInput(EvtType& event)
 void
 TargetPanel::onSizeInput(wxCommandEvent& event)
 {
-       if (event.GetId() == ID_numSectorCtrl)
-       {
-               uint32_t numSectors;
-               std::stringstream conv;
-               conv << myNumSectorCtrl->GetValue();
-               conv >> numSectors;
-
-               conv.str(""); conv.clear();
-
-               if (conv)
-               {
-                       uint64_t bytes =
-                               uint64_t(numSectors) *
-                                       CtrlGetValue<uint16_t>(mySectorSizeCtrl).first;
-
-                       if (bytes >= 1024 * 1024 * 1024)
-                       {
-                               conv << (bytes / (1024.0 * 1024 * 1024));
-                               mySizeUnitCtrl->SetSelection(UNIT_GB);
-                       }
-                       else if (bytes >= 1024 * 1024)
-                       {
-                               conv << (bytes / (1024.0 * 1024));
-                               mySizeUnitCtrl->SetSelection(UNIT_MB);
-                       }
-                       else
-                       {
-                               conv << (bytes / 1024.0);
-                               mySizeUnitCtrl->SetSelection(UNIT_KB);
-                       }
-                       mySizeCtrl->ChangeValue(conv.str());
-               }
-       }
-       else
+       if (event.GetId() != ID_numSectorCtrl)
        {
                std::stringstream ss;
                ss << convertUnitsToSectors().first;
                myNumSectorCtrl->ChangeValue(ss.str());
        }
-
+       evaluateSize();
        onInput(event); // propagate
 }
 
+void
+TargetPanel::evaluateSize()
+{
+       uint32_t numSectors;
+       std::stringstream conv;
+       conv << myNumSectorCtrl->GetValue();
+       conv >> numSectors;
+
+       conv.str(""); conv.clear();
+
+       if (conv)
+       {
+               uint64_t bytes =
+                       uint64_t(numSectors) *
+                               CtrlGetValue<uint16_t>(mySectorSizeCtrl).first;
+
+               if (bytes >= 1024 * 1024 * 1024)
+               {
+                       conv << (bytes / (1024.0 * 1024 * 1024));
+                       mySizeUnitCtrl->SetSelection(UNIT_GB);
+               }
+               else if (bytes >= 1024 * 1024)
+               {
+                       conv << (bytes / (1024.0 * 1024));
+                       mySizeUnitCtrl->SetSelection(UNIT_MB);
+               }
+               else
+               {
+                       conv << (bytes / 1024.0);
+                       mySizeUnitCtrl->SetSelection(UNIT_KB);
+               }
+               mySizeCtrl->ChangeValue(conv.str());
+       }
+}
+
 std::pair<uint32_t, bool>
 TargetPanel::convertUnitsToSectors() const
 {
@@ -522,7 +570,9 @@ TargetPanel::getConfig() const
 
        config.flags =
                (myParityCtrl->IsChecked() ? CONFIG_ENABLE_PARITY : 0) |
-               (myUnitAttCtrl->IsChecked() ? CONFIG_ENABLE_UNIT_ATTENTION : 0);
+               (myUnitAttCtrl->IsChecked() ? CONFIG_ENABLE_UNIT_ATTENTION : 0) |
+               (myScsi2Ctrl->IsChecked() ? CONFIG_ENABLE_SCSI2 : 0) |
+               (myGlitchCtrl->IsChecked() ? CONFIG_DISABLE_GLITCH : 0);
 
        auto startSDSector = CtrlGetValue<uint32_t>(myStartSDSectorCtrl);
        config.sdSectorStart = startSDSector.first;
@@ -556,6 +606,8 @@ TargetPanel::setConfig(const TargetConfig& config)
 
        myParityCtrl->SetValue(config.flags & CONFIG_ENABLE_PARITY);
        myUnitAttCtrl->SetValue(config.flags & CONFIG_ENABLE_UNIT_ATTENTION);
+       myScsi2Ctrl->SetValue(config.flags & CONFIG_ENABLE_SCSI2);
+       myGlitchCtrl->SetValue(config.flags & CONFIG_DISABLE_GLITCH);
 
        {
                std::stringstream ss; ss << config.sdSectorStart;