Files
86Box/src/qt/qt_settingsmachine.cpp

310 lines
10 KiB
C++
Raw Normal View History

2022-02-07 15:00:02 +06:00
/*
2023-01-06 15:36:05 -05:00
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86Box distribution.
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Machine selection and configuration UI module.
2022-02-07 15:00:02 +06:00
*
*
*
2023-01-06 15:36:05 -05:00
* Authors: Joakim L. Gilje <jgilje@jgilje.net>
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Copyright 2021 Joakim L. Gilje
2022-02-07 15:00:02 +06:00
*/
2021-11-25 10:20:56 +01:00
#include "qt_settingsmachine.hpp"
#include "ui_qt_settingsmachine.h"
#include <QDebug>
#include <QDialog>
#include <QFrame>
#include <QVBoxLayout>
#include <QDialogButtonBox>
2021-12-16 12:53:04 +01:00
#include <algorithm>
2021-11-25 10:20:56 +01:00
extern "C" {
#include "../cpu/cpu.h"
#include <86box/86box.h>
#include <86box/config.h>
#include <86box/device.h>
#include <86box/machine.h>
}
// from nvr.h, which we can't import into CPP code
2022-11-19 08:49:04 -05:00
#define TIME_SYNC_DISABLED 0
#define TIME_SYNC_ENABLED 1
#define TIME_SYNC_UTC 2
2021-11-25 10:20:56 +01:00
#include "qt_deviceconfig.hpp"
#include "qt_models_common.hpp"
2022-11-19 08:49:04 -05:00
SettingsMachine::SettingsMachine(QWidget *parent)
: QWidget(parent)
, ui(new Ui::SettingsMachine)
2021-11-25 10:20:56 +01:00
{
ui->setupUi(this);
switch (time_sync) {
2022-11-19 08:49:04 -05:00
case TIME_SYNC_ENABLED:
ui->radioButtonLocalTime->setChecked(true);
break;
case TIME_SYNC_ENABLED | TIME_SYNC_UTC:
ui->radioButtonUTC->setChecked(true);
break;
case TIME_SYNC_DISABLED:
default:
ui->radioButtonDisabled->setChecked(true);
break;
2021-11-25 10:20:56 +01:00
}
2022-11-19 08:49:04 -05:00
auto *waitStatesModel = ui->comboBoxWaitStates->model();
2021-11-25 10:20:56 +01:00
waitStatesModel->insertRows(0, 9);
auto idx = waitStatesModel->index(0, 0);
waitStatesModel->setData(idx, tr("Default"), Qt::DisplayRole);
2021-11-25 10:20:56 +01:00
waitStatesModel->setData(idx, 0, Qt::UserRole);
for (int i = 0; i < 8; ++i) {
2022-11-19 08:49:04 -05:00
idx = waitStatesModel->index(i + 1, 0);
2022-01-08 16:39:51 +06:00
waitStatesModel->setData(idx, QString::asprintf(tr("%i Wait state(s)").toUtf8().constData(), i), Qt::DisplayRole);
2022-11-19 08:49:04 -05:00
waitStatesModel->setData(idx, i + 1, Qt::UserRole);
2021-11-25 10:20:56 +01:00
}
2022-11-19 08:49:04 -05:00
int selectedMachineType = 0;
auto *machineTypesModel = ui->comboBoxMachineType->model();
for (int i = 1; i < MACHINE_TYPE_MAX; ++i) {
int j = 0;
while (machine_get_internal_name_ex(j) != nullptr) {
if (machine_available(j) && (machine_get_type(j) == i)) {
int row = Models::AddEntry(machineTypesModel, machine_types[i].name, machine_types[i].id);
if (machine_types[i].id == machine_get_type(machine)) {
selectedMachineType = row;
}
break;
}
j++;
2021-11-25 10:20:56 +01:00
}
}
ui->comboBoxMachineType->setCurrentIndex(-1);
2021-11-25 10:20:56 +01:00
ui->comboBoxMachineType->setCurrentIndex(selectedMachineType);
}
2022-11-19 08:49:04 -05:00
SettingsMachine::~SettingsMachine()
{
2021-11-25 10:20:56 +01:00
delete ui;
}
2022-11-19 08:49:04 -05:00
void
SettingsMachine::save()
{
machine = ui->comboBoxMachine->currentData().toInt();
cpu_f = const_cast<cpu_family_t *>(&cpu_families[ui->comboBoxCPU->currentData().toInt()]);
cpu = ui->comboBoxSpeed->currentData().toInt();
fpu_type = ui->comboBoxFPU->currentData().toInt();
2021-11-25 10:20:56 +01:00
cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0;
int64_t temp_mem_size;
if (machine_get_ram_granularity(machine) < 1024) {
temp_mem_size = ui->spinBoxRAM->value();
2021-11-25 10:20:56 +01:00
} else {
temp_mem_size = ui->spinBoxRAM->value() * 1024;
2021-11-25 10:20:56 +01:00
}
temp_mem_size &= ~(machine_get_ram_granularity(machine) - 1);
if (temp_mem_size < machine_get_min_ram(machine)) {
temp_mem_size = machine_get_min_ram(machine);
} else if (temp_mem_size > machine_get_max_ram(machine)) {
temp_mem_size = machine_get_max_ram(machine);
}
mem_size = static_cast<uint32_t>(temp_mem_size);
2021-11-25 10:20:56 +01:00
if (ui->comboBoxWaitStates->isEnabled()) {
cpu_waitstates = ui->comboBoxWaitStates->currentData().toInt();
} else {
cpu_waitstates = 0;
}
time_sync = 0;
if (ui->radioButtonLocalTime->isChecked()) {
time_sync = TIME_SYNC_ENABLED;
}
if (ui->radioButtonUTC->isChecked()) {
time_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC;
}
}
2022-11-19 08:49:04 -05:00
void
SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index)
{
if (index < 0) {
return;
}
2022-11-19 08:49:04 -05:00
auto *model = ui->comboBoxMachine->model();
int removeRows = model->rowCount();
2021-11-25 10:20:56 +01:00
int selectedMachineRow = 0;
for (int i = 0; i < machine_count(); ++i) {
if ((machine_get_type(i) == ui->comboBoxMachineType->currentData().toInt()) && machine_available(i)) {
2021-11-25 10:20:56 +01:00
int row = Models::AddEntry(model, machines[i].name, i);
if (i == machine) {
selectedMachineRow = row - removeRows;
}
}
}
model->removeRows(0, removeRows);
ui->comboBoxMachine->setCurrentIndex(-1);
ui->comboBoxMachine->setCurrentIndex(selectedMachineRow);
}
2022-11-19 08:49:04 -05:00
void
SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index)
{
2021-11-25 10:20:56 +01:00
// win_settings_machine_recalc_machine
if (index < 0) {
return;
}
2022-11-19 08:49:04 -05:00
int machineId = ui->comboBoxMachine->currentData().toInt();
const auto *device = machine_getdevice(machineId);
2021-11-25 10:20:56 +01:00
ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr));
2022-11-19 08:49:04 -05:00
auto *modelCpu = ui->comboBoxCPU->model();
int removeRows = modelCpu->rowCount();
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
int i = 0;
int eligibleRows = 0;
2021-11-25 10:20:56 +01:00
int selectedCpuFamilyRow = 0;
while (cpu_families[i].package != 0) {
if (cpu_family_is_eligible(&cpu_families[i], machineId)) {
Models::AddEntry(modelCpu, QString("%1 %2").arg(cpu_families[i].manufacturer, cpu_families[i].name), i);
if (&cpu_families[i] == cpu_f) {
selectedCpuFamilyRow = eligibleRows;
}
++eligibleRows;
}
++i;
}
modelCpu->removeRows(0, removeRows);
ui->comboBoxCPU->setEnabled(eligibleRows > 1);
ui->comboBoxCPU->setCurrentIndex(-1);
ui->comboBoxCPU->setCurrentIndex(selectedCpuFamilyRow);
2021-12-16 13:52:37 +01:00
int divisor;
if ((machine_get_ram_granularity(machineId) < 1024)) {
divisor = 1;
ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "KB").prepend(' '));
2021-11-25 10:20:56 +01:00
} else {
2021-12-16 13:52:37 +01:00
divisor = 1024;
ui->spinBoxRAM->setSuffix(QCoreApplication::translate("", "MB").prepend(' '));
2021-11-25 10:20:56 +01:00
}
2021-12-16 13:52:37 +01:00
ui->spinBoxRAM->setMinimum(machine_get_min_ram(machineId) / divisor);
ui->spinBoxRAM->setMaximum(machine_get_max_ram(machineId) / divisor);
ui->spinBoxRAM->setSingleStep(machine_get_ram_granularity(machineId) / divisor);
ui->spinBoxRAM->setValue(mem_size / divisor);
ui->spinBoxRAM->setEnabled(machine_get_min_ram(machineId) != machine_get_max_ram(machineId));
2021-11-25 10:20:56 +01:00
emit currentMachineChanged(machineId);
}
2022-11-19 08:49:04 -05:00
void
SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index)
{
2021-11-25 10:20:56 +01:00
if (index < 0) {
return;
}
2022-11-19 08:49:04 -05:00
int machineId = ui->comboBoxMachine->currentData().toInt();
int cpuFamilyId = ui->comboBoxCPU->currentData().toInt();
const auto *cpuFamily = &cpu_families[cpuFamilyId];
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
auto *modelSpeed = ui->comboBoxSpeed->model();
int removeRows = modelSpeed->rowCount();
2021-11-25 10:20:56 +01:00
// win_settings_machine_recalc_cpu_m
2022-11-19 08:49:04 -05:00
int i = 0;
int eligibleRows = 0;
2021-11-25 10:20:56 +01:00
int selectedSpeedRow = 0;
while (cpuFamily->cpus[i].cpu_type != 0) {
if (cpu_is_eligible(cpuFamily, i, machineId)) {
Models::AddEntry(modelSpeed, QString("%1").arg(cpuFamily->cpus[i].name), i);
if (cpu == i) {
selectedSpeedRow = eligibleRows;
}
++eligibleRows;
}
++i;
}
modelSpeed->removeRows(0, removeRows);
ui->comboBoxSpeed->setEnabled(eligibleRows > 1);
ui->comboBoxSpeed->setCurrentIndex(-1);
ui->comboBoxSpeed->setCurrentIndex(selectedSpeedRow);
}
2022-11-19 08:49:04 -05:00
void
SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index)
{
2021-11-25 10:20:56 +01:00
if (index < 0) {
return;
}
// win_settings_machine_recalc_cpu
2022-11-19 08:49:04 -05:00
int cpuFamilyId = ui->comboBoxCPU->currentData().toInt();
const auto *cpuFamily = &cpu_families[cpuFamilyId];
int cpuId = ui->comboBoxSpeed->currentData().toInt();
uint cpuType = cpuFamily->cpus[cpuId].cpu_type;
2021-11-25 10:20:56 +01:00
if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) {
ui->comboBoxWaitStates->setEnabled(true);
ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates);
} else {
ui->comboBoxWaitStates->setCurrentIndex(0);
ui->comboBoxWaitStates->setEnabled(false);
}
#ifdef USE_DYNAREC
uint8_t flags = cpuFamily->cpus[cpuId].cpu_flags;
2022-11-19 08:49:04 -05:00
if (!(flags & CPU_SUPPORTS_DYNAREC)) {
2021-11-25 10:20:56 +01:00
ui->checkBoxDynamicRecompiler->setChecked(false);
ui->checkBoxDynamicRecompiler->setEnabled(false);
} else if (flags & CPU_REQUIRES_DYNAREC) {
ui->checkBoxDynamicRecompiler->setChecked(true);
ui->checkBoxDynamicRecompiler->setEnabled(false);
} else {
ui->checkBoxDynamicRecompiler->setChecked(cpu_use_dynarec);
ui->checkBoxDynamicRecompiler->setEnabled(true);
}
#endif
// win_settings_machine_recalc_fpu
2022-11-19 08:49:04 -05:00
auto *modelFpu = ui->comboBoxFPU->model();
int removeRows = modelFpu->rowCount();
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
int i = 0;
2021-11-25 10:20:56 +01:00
int selectedFpuRow = 0;
2022-11-19 08:49:04 -05:00
for (const char *fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) {
2021-11-25 10:20:56 +01:00
auto fpuType = fpu_get_type_from_index(cpuFamily, cpuId, i);
Models::AddEntry(modelFpu, QString("%1").arg(fpuName), fpuType);
if (fpu_type == fpuType) {
selectedFpuRow = i;
}
}
modelFpu->removeRows(0, removeRows);
ui->comboBoxFPU->setEnabled(modelFpu->rowCount() > 1);
ui->comboBoxFPU->setCurrentIndex(-1);
ui->comboBoxFPU->setCurrentIndex(selectedFpuRow);
}
2022-11-19 08:49:04 -05:00
void
SettingsMachine::on_pushButtonConfigure_clicked()
{
2021-11-25 10:20:56 +01:00
// deviceconfig_inst_open
2022-11-19 08:49:04 -05:00
int machineId = ui->comboBoxMachine->currentData().toInt();
const auto *device = machine_getdevice(machineId);
DeviceConfig::ConfigureDevice(device, 0, qobject_cast<Settings *>(Settings::settings));
2021-11-25 10:20:56 +01:00
}