diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml
index 73ae94969..83672974f 100644
--- a/.github/workflows/cmake_linux.yml
+++ b/.github/workflows/cmake_linux.yml
@@ -106,7 +106,7 @@ jobs:
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
-# if: 0
+ if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/src/device.c b/src/device.c
index 2f5a3cdad..9a904f550 100644
--- a/src/device.c
+++ b/src/device.c
@@ -493,14 +493,26 @@ device_get_name(const device_t *dev, int bus, char *name)
sbus = (dev->flags & DEVICE_AT) ? "ISA16" : "ISA";
else if (dev->flags & DEVICE_CBUS)
sbus = "C-BUS";
+ else if (dev->flags & DEVICE_PCMCIA)
+ sbus = "PCMCIA";
else if (dev->flags & DEVICE_MCA)
sbus = "MCA";
+ else if (dev->flags & DEVICE_HIL)
+ sbus = "HP HIL";
else if (dev->flags & DEVICE_EISA)
sbus = "EISA";
+ else if (dev->flags & DEVICE_AT32)
+ sbus = "AT/32";
+ else if (dev->flags & DEVICE_OLB)
+ sbus = "OLB";
else if (dev->flags & DEVICE_VLB)
sbus = "VLB";
else if (dev->flags & DEVICE_PCI)
sbus = "PCI";
+ else if (dev->flags & DEVICE_CARDBUS)
+ sbus = "CARDBUS";
+ else if (dev->flags & DEVICE_USB)
+ sbus = "USB";
else if (dev->flags & DEVICE_AGP)
sbus = "AGP";
else if (dev->flags & DEVICE_AC97)
@@ -767,13 +779,16 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC))
return 0;
+ if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS))
+ return 0;
+
if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA))
return 0;
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS))
return 0;
- if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA))
+ if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_ISA))
return 0;
if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA))
@@ -785,6 +800,9 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA))
return 0;
+ if ((device->flags & DEVICE_AT32) && !machine_has_bus(m, MACHINE_BUS_AT32))
+ return 0;
+
if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB))
return 0;
@@ -794,7 +812,7 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI))
return 0;
- if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS))
+ if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_PCI))
return 0;
if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB))
@@ -803,9 +821,6 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP))
return 0;
- if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS))
- return 0;
-
if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97))
return 0;
diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c
index c2b053814..608d7a8a7 100644
--- a/src/disk/hdc_ide_w83769f.c
+++ b/src/disk/hdc_ide_w83769f.c
@@ -458,3 +458,17 @@ const device_t ide_w83769f_pci_34_device = {
.config = NULL
};
+const device_t ide_w83769f_pci_single_channel_device = {
+ .name = "Winbond W83769F PCI (Single Channel)",
+ .internal_name = "ide_w83769f_pci_single_channel",
+ .flags = DEVICE_PCI,
+ .local = 0x200b4,
+ .init = w83769f_init,
+ .close = w83769f_close,
+ .reset = w83769f_reset,
+ { .available = NULL },
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
diff --git a/src/disk/hdd.c b/src/disk/hdd.c
index 65b731340..b861b5e50 100644
--- a/src/disk/hdd.c
+++ b/src/disk/hdd.c
@@ -419,19 +419,26 @@ static hdd_preset_t hdd_speed_presets[] = {
{ .name = "[ATA-1] Conner CP3024", .internal_name = "CP3024", .model = "Conner Peripherals 20MB - CP3024", .zones = 1, .avg_spt = 33, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
{ .name = "[ATA-1] Conner CP3044", .internal_name = "CP3044", .model = "Conner Peripherals 40MB - CP3044", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
{ .name = "[ATA-1] Conner CP3104", .internal_name = "CP3104", .model = "Conner Peripherals 104MB - CP3104", .zones = 1, .avg_spt = 33, .heads = 8, .rpm = 3500, .full_stroke_ms = 45, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
+ { .name = "[ATA-1] HP Kittyhawk", .internal_name = "C3014A", .model = "HP C3014A", .zones = 6, .avg_spt = 180, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[ATA-1] IBM H3256-A3", .internal_name = "H3256A3", .model = "IBM-H3256-A3", .zones = 1, .avg_spt = 140, .heads = 2, .rpm = 3600, .full_stroke_ms = 32, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 8 },
{ .name = "[ATA-1] IBM H3342-A4", .internal_name = "H3342A4", .model = "IBM-H3342-A4", .zones = 1, .avg_spt = 140, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 8 },
+ { .name = "[ATA-1] Kalok KL343", .internal_name = "KL343", .model = "KALOK KL-343", .zones = 1, .avg_spt = 280, .heads = 6, .rpm = 3600, .full_stroke_ms = 50, .track_seek_ms = 2, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 },
+ { .name = "[ATA-1] Kalok KL3100", .internal_name = "KL3100", .model = "KALOK KL-3100", .zones = 1, .avg_spt = 200, .heads = 6, .rpm = 3662, .full_stroke_ms = 50, .track_seek_ms = 2, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7060AT", .internal_name = "7060AT", .model = "Maxtor 7060AT", .zones = 1, .avg_spt = 162, .heads = 2, .rpm = 3524, .full_stroke_ms = 30, .track_seek_ms = 3.6, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7131AT", .internal_name = "7131AT", .model = "Maxtor 7131AT", .zones = 2, .avg_spt = 154, .heads = 2, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4.5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7213AT", .internal_name = "7213AT", .model = "Maxtor 7213AT", .zones = 4, .avg_spt = 155, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6.5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7245AT", .internal_name = "7245AT", .model = "Maxtor 7245AT", .zones = 4, .avg_spt = 149, .heads = 4, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4.4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Quantum ProDrive LPS 105", .internal_name = "LPS105AT", .model = "QUANTUM PRODRIVE 105", .zones = 1, .avg_spt = 170, .heads = 2, .rpm = 3662, .full_stroke_ms = 45, .track_seek_ms = 5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Quantum ProDrive LPS 120AT", .internal_name = "GM12A012", .model = "QUANTUM PRODRIVE 120AT", .zones = 1, .avg_spt = 150, .heads = 2, .rpm = 3605, .full_stroke_ms = 45, .track_seek_ms = 4, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
+ { .name = "[ATA-1] Seagate ST3243A", .internal_name = "ST3243A", .model = "ST3243A", .zones = 1, .avg_spt = 140, .heads = 4, .rpm = 3811, .full_stroke_ms = 32, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 140", .internal_name = "WDAC140", .model = "WDC WDAC140-50", .zones = 4, .avg_spt = 170, .heads = 2, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 8, .rcache_seg_size = 8, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 280", .internal_name = "WDAC280", .model = "WDC WDAC280-00", .zones = 4, .avg_spt = 170, .heads = 4, .rpm = 3595, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 8, .rcache_seg_size = 32, .max_multiple = 8 },
+ { .name = "[ATA-1] Western Digital Caviar 1210", .internal_name = "WDAC1210", .model = "WDC WDAC1210-21F", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 3314, .full_stroke_ms = 33, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 2120", .internal_name = "WDAC2120", .model = "WDC WDAC2120-00M", .zones = 4, .avg_spt = 140, .heads = 2, .rpm = 3605, .full_stroke_ms = 28, .track_seek_ms = 2.8, .rcache_num_seg = 8, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "IBM-DBOA-2720", .zones = 2, .avg_spt = 135, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 },
- { .name = "[ATA-2] IBM DeskStar 4", .internal_name = "DCAA34330", .model = "IBM-DCAA-34330", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
+ { .name = "[ATA-2] IBM DeskStar 4 (DCAA-32880)", .internal_name = "DCAA32880", .model = "IBM-DCAA-32880", .zones = 8, .avg_spt = 85, .heads = 2, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
+ { .name = "[ATA-2] IBM DeskStar 4 (DCAA-33610)", .internal_name = "DCAA33610", .model = "IBM-DCAA-33610", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
+ { .name = "[ATA-2] IBM DeskStar 4 (DCAA-34330)", .internal_name = "DCAA34330", .model = "IBM-DCAA-34330", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
{ .name = "[ATA-2] Maxtor 7540AV", .internal_name = "7540AV", .model = "Maxtor 7540AV", .zones = 2, .avg_spt = 120, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 4.3, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-2] Maxtor 7546AT", .internal_name = "7546AT", .model = "Maxtor 7546AT", .zones = 2, .avg_spt = 100, .heads = 4, .rpm = 4500, .full_stroke_ms = 28, .track_seek_ms = 2.3, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 },
{ .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 120, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3.7, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 },
@@ -450,34 +457,67 @@ static hdd_preset_t hdd_speed_presets[] = {
{ .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 140, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 },
{ .name = "[ATA-2] Seagate Medalist 210xe", .internal_name = "ST3250A", .model = "ST3250A", .zones = 4, .avg_spt = 148, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 4.1, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 3.4, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 8 },
+ { .name = "[ATA-2] Seagate Medalist 545xe", .internal_name = "ST3660A", .model = "ST3660A", .zones = 4, .avg_spt = 130, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
+ { .name = "[ATA-2] Seagate Medalist 640xe", .internal_name = "ST3630A", .model = "ST3630A", .zones = 4, .avg_spt = 130, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.5, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
+ { .name = "[ATA-2] Seagate Medalist 850xe", .internal_name = "ST3850A", .model = "ST3850A", .zones = 8, .avg_spt = 150, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.8, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 1270SL", .internal_name = "ST51270A", .model = "ST51270A", .zones = 8, .avg_spt = 105, .heads = 3, .rpm = 5736, .full_stroke_ms = 25, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Seagate Medalist 3240", .internal_name = "ST33240A", .model = "ST33240A", .zones = 16, .avg_spt = 125, .heads = 8, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
- { .name = "[ATA-2] Western Digital Caviar 2850", .internal_name = "WDAC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
+ { .name = "[ATA-2] Toshiba MK2101MAN (HDD2616)", .internal_name = "HDD2616", .model = "TOSHIBA MK2101MAN", .zones = 8, .avg_spt = 130, .heads = 10, .rpm = 4200, .full_stroke_ms = 36, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 },
+ { .name = "[ATA-2] Western Digital Caviar 2540", .internal_name = "WDAC2540", .model = "WDC WDAC2540-00H", .zones = 4, .avg_spt = 250, .heads = 2, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
+ { .name = "[ATA-2] Western Digital Caviar 2850", .internal_name = "WDAC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 230, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 11000", .internal_name = "WDAC11000", .model = "WDC WDAC11000-00H", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
+ { .name = "[ATA-2] Western Digital Caviar 21200", .internal_name = "WDAC21200", .model = "WDC WDAC21200-00H", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 5200, .full_stroke_ms = 39, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
+ { .name = "[ATA-2] Western Digital Caviar 21600", .internal_name = "WDAC21600", .model = "WDC WDAC21600-00H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
+ { .name = "[ATA-2] Western Digital Caviar 22000", .internal_name = "AC22000", .model = "WDC AC22000-32LA", .zones = 8, .avg_spt = 130, .heads = 3, .rpm = 5200, .full_stroke_ms = 33, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
+ { .name = "[ATA-2] Western Digital Caviar 22100", .internal_name = "WDAC22100", .model = "WDC WDAC22100-18H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Western Digital Caviar 31200", .internal_name = "WDAC31200", .model = "WDC WDAC31200-00F", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3017AT", .internal_name = "MPA3017AT", .model = "FUJITSU MPA3017AT", .zones = 5, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3026AT", .internal_name = "MPA3026AT", .model = "FUJITSU MPA3026AT", .zones = 8, .avg_spt = 95, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3035AT", .internal_name = "MPA3035AT", .model = "FUJITSU MPA3035AT", .zones = 11, .avg_spt = 95, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3043AT", .internal_name = "MPA3043AT", .model = "FUJITSU MPA3043AT", .zones = 15, .avg_spt = 95, .heads = 5, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3052AT", .internal_name = "MPA3052AT", .model = "FUJITSU MPA3052AT", .zones = 16, .avg_spt = 95, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
+ { .name = "[ATA-3] Samsung Voyager 6", .internal_name = "SV0844A", .model = "SAMSUNG SV0844A", .zones = 8, .avg_spt = 105, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-3] Samsung Winner 5X", .internal_name = "WU33205A", .model = "SAMSUNG WU33205A", .zones = 16, .avg_spt = 100, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
+ { .name = "[ATA-3] Seagate Medalist 1720", .internal_name = "ST31720A", .model = "ST31720A", .zones = 4, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 2, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 },
+ { .name = "[ATA-3] Seagate Medalist 2132", .internal_name = "ST32132A", .model = "ST32132A", .zones = 8, .avg_spt = 125, .heads = 6, .rpm = 4500, .full_stroke_ms = 30, .track_seek_ms = 2.3, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 16 },
+ { .name = "[ATA-3] Western Digital Caviar 21700", .internal_name = "WDAC21700", .model = "WDC WDAC21700-40H", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5200, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, // Apple Computer OEM only, not retail version
{ .name = "[ATA-4] Fujitsu MPB3021AT", .internal_name = "MPB3021AT", .model = "FUJITSU MPB3021AT", .zones = 7, .avg_spt = 100, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 16 },
{ .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-4] Fujitsu MPD3064AT", .internal_name = "MPD3064AT", .model = "FUJITSU MPD3064AT", .zones = 7, .avg_spt = 95, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
+ { .name = "[ATA-4] Fujitsu MPD3084AT", .internal_name = "MPD3084AT", .model = "FUJITSU MPD3084AT", .zones = 7, .avg_spt = 95, .heads = 4, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 16 },
+ { .name = "[ATA-4] Fujitsu MPE3064AT", .internal_name = "MPE3064AT", .model = "FUJITSU MPE3064AT", .zones = 7, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 2160", .internal_name = "86480D6", .model = "Maxtor 86480D6", .zones = 8, .avg_spt = 97, .heads = 4, .rpm = 5200, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 2880", .internal_name = "90432D3", .model = "Maxtor 90432D3", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax 3400", .internal_name = "90644D3", .model = "Maxtor 90644D3", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax 4320 (90432D2)", .internal_name = "90432D2", .model = "Maxtor 90432D2", .zones = 16, .avg_spt = 90, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax 4320 (90845D4)", .internal_name = "90845D4", .model = "Maxtor 90845D4", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (90683U2)", .internal_name = "90683U2", .model = "Maxtor 90683U2", .zones = 16, .avg_spt = 90, .heads = 2, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (91024U3)", .internal_name = "91024U3", .model = "Maxtor 91024U3", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (91366U4)", .internal_name = "91366U4", .model = "Maxtor 91366U4", .zones = 16, .avg_spt = 90, .heads = 4, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (92049U6)", .internal_name = "92049U6", .model = "Maxtor 92049U6", .zones = 16, .avg_spt = 90, .heads = 6, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (92732U8)", .internal_name = "92732U8", .model = "Maxtor 92732U8", .zones = 16, .avg_spt = 90, .heads = 8, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
+ { .name = "[ATA-4] Seagate Medalist 2122", .internal_name = "ST32122A", .model = "ST32122A", .zones = 16, .avg_spt = 115, .heads = 2, .rpm = 4500, .full_stroke_ms = 23, .track_seek_ms = 3.8, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 3321", .internal_name = "ST33221A", .model = "ST33221A", .zones = 16, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1.7, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 4321", .internal_name = "ST34321A", .model = "ST34321A", .zones = 16, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 6531", .internal_name = "ST36531A", .model = "ST36531A", .zones = 16, .avg_spt = 115, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1.7, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
+ { .name = "[ATA-4] Seagate Medalist 8420", .internal_name = "ST38420A", .model = "ST38420A", .zones = 16, .avg_spt = 90, .heads = 2, .rpm = 5400, .full_stroke_ms = 16, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 8, .avg_spt = 130, .heads = 6, .rpm = 4200, .full_stroke_ms = 25, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Western Digital Caviar 14300", .internal_name = "AC14300", .model = "WDC AC14300-00RT", .zones = 16, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 5.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-4] Western Digital Caviar 23200", .internal_name = "AC23200", .model = "WDC AC23200-00LB", .zones = 16, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Western Digital Caviar 26400", .internal_name = "AC26400", .model = "WDC AC26400-00RN", .zones = 16, .avg_spt = 95, .heads = 5, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Western Digital Caviar 33200", .internal_name = "AC33200", .model = "WDC AC33200-00LA", .zones = 16, .avg_spt = 110, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
- { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 8, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
- { .name = "[ATA-5] Seagate Medalist 4312", .internal_name = "ST34312A", .model = "ST34312A", .zones = 16, .avg_spt = 86, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
- { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 16, .avg_spt = 95, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, // Hard disk entry removed from The Retro Web
+ { .name = "[ATA-5] IBM Travelstar 6GN", .internal_name = "DARA206000", .model = "IBM-DARA-206000", .zones = 12, .avg_spt = 92, .heads = 2, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] IBM Travelstar 9GN", .internal_name = "DARA209000", .model = "IBM-DARA-209000", .zones = 12, .avg_spt = 92, .heads = 3, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] IBM/Hitachi Travelstar 12GN", .internal_name = "DARA212000", .model = "IBM-DARA-212000", .zones = 12, .avg_spt = 92, .heads = 4, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, // Either Hitachi or IBM OEM
+ { .name = "[ATA-5] Maxtor DiamondMax VL 17", .internal_name = "90871U2", .model = "Maxtor 90871U2", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
+ { .name = "[ATA-5] Maxtor DiamondMax VL 20", .internal_name = "91021U2", .model = "Maxtor 91021U2", .zones = 16, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 8, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] Samsung SpinPoint V6800 (SV1023D)", .internal_name = "SV1023D", .model = "SAMSUNG SV1023D", .zones = 8, .avg_spt = 95, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] Seagate U8 - 4.3gb", .internal_name = "ST34313A", .model = "ST34313A", .zones = 16, .avg_spt = 89, .heads = 1, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] Seagate U8 - 8.4gb", .internal_name = "ST38410A", .model = "ST38410A", .zones = 16, .avg_spt = 89, .heads = 2, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 16, .avg_spt = 95, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
+ { .name = "[ATA-5] Western Digital Expert", .internal_name = "WD135BA", .model = "WDC WD135BA-60AK", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 1920, .max_multiple = 32 },
// clang-format on
};
diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h
index 48235bb1e..a3b667e2e 100644
--- a/src/include/86box/hdc.h
+++ b/src/include/86box/hdc.h
@@ -89,6 +89,7 @@ extern const device_t ide_w83769f_vlb_device; /* Winbond W8376
extern const device_t ide_w83769f_vlb_34_device; /* Winbond W83769F VLB (Port 34h) */
extern const device_t ide_w83769f_pci_device; /* Winbond W83769F PCI */
extern const device_t ide_w83769f_pci_34_device; /* Winbond W83769F PCI (Port 34h) */
+extern const device_t ide_w83769f_pci_single_channel_device; /* Winbond W83769F PCI (Only primary channel) */
extern const device_t ide_ter_device;
extern const device_t ide_ter_pnp_device;
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index d46e816ce..c976d15a7 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -631,6 +631,7 @@ extern int machine_at_valuepointp60_init(const machine_t *);
extern int machine_at_revenge_init(const machine_t *);
extern int machine_at_586is_init(const machine_t *);
extern int machine_at_pb520r_init(const machine_t *);
+extern int machine_at_m5pi_init(const machine_t *);
extern int machine_at_excalibur_init(const machine_t *);
@@ -643,6 +644,7 @@ extern int machine_at_p5sp4_init(const machine_t *);
extern int machine_at_plato_init(const machine_t *);
extern int machine_at_dellplato_init(const machine_t *);
extern int machine_at_ambradp90_init(const machine_t *);
+extern int machine_at_p54np4_init(const machine_t *);
extern int machine_at_586ip_init(const machine_t *);
extern int machine_at_tek932_init(const machine_t *);
diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h
index 33467cf25..a85f1515c 100644
--- a/src/include/86box/snd_sb.h
+++ b/src/include/86box/snd_sb.h
@@ -11,9 +11,11 @@
* Authors: Sarah Walker,
* Miran Grca,
* TheCollector1995,
+ * Jasmine Iwanek,
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
+ * Copyright 2024-2025 Jasmine Iwanek.
*/
#ifndef SOUND_SND_SB_H
@@ -196,6 +198,12 @@ typedef struct sb_t {
void (*opl_mix)(void*, double*, double*);
} sb_t;
+typedef struct goldfinch_t {
+ emu8k_t emu8k;
+
+ uint8_t pnp_rom[512];
+} goldfinch_t;
+
extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv);
extern uint8_t sb_ct1345_mixer_read(uint16_t addr, void *priv);
extern void sb_ct1345_mixer_reset(sb_t *sb);
diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h
index 9029b336d..e5ae227fd 100644
--- a/src/include/86box/sound.h
+++ b/src/include/86box/sound.h
@@ -158,6 +158,7 @@ extern const device_t sb_16_pnp_ide_device;
extern const device_t sb_16_compat_device;
extern const device_t sb_16_compat_nompu_device;
extern const device_t sb_16_reply_mca_device;
+extern const device_t sb_goldfinch_device;
extern const device_t sb_32_pnp_device;
extern const device_t sb_awe32_device;
extern const device_t sb_awe32_pnp_device;
diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c
index 79e46819e..c3213f1ac 100644
--- a/src/machine/m_at_socket4.c
+++ b/src/machine/m_at_socket4.c
@@ -126,7 +126,6 @@ machine_at_p5mp3_init(const machine_t *model)
return ret;
machine_at_common_init(model);
- device_add(&ide_pci_device);
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -355,6 +354,36 @@ machine_at_pb520r_init(const machine_t *model)
return ret;
}
+int
+machine_at_m5pi_init(const machine_t *model)
+{
+ int ret;
+
+ ret = bios_load_linear_inverted("roms/machines/m5pi/M5PI10R.BIN",
+ 0x000e0000, 131072, 0);
+
+ if (bios_only || !ret)
+ return ret;
+
+ machine_at_common_init(model);
+
+ pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
+ pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
+ pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
+ pci_register_slot(0x0f, PCI_CARD_NORMAL, 1, 2, 3, 4);
+ pci_register_slot(0x0c, PCI_CARD_NORMAL, 2, 3, 4, 1);
+ pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2);
+ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
+ device_add(&i430lx_device);
+ device_add(&sio_zb_device);
+ device_add(&keyboard_ps2_phoenix_device);
+ device_add(&ide_w83769f_pci_single_channel_device);
+ device_add(&fdc37c665_ide_sec_device);
+ device_add(&intel_flash_bxt_ami_device);
+
+ return ret;
+}
+
int
machine_at_excalibur_init(const machine_t *model)
{
diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c
index a5ab30c42..b6e82301b 100644
--- a/src/machine/m_at_socket5.c
+++ b/src/machine/m_at_socket5.c
@@ -97,6 +97,36 @@ machine_at_ambradp90_init(const machine_t *model)
return ret;
}
+int
+machine_at_p54np4_init(const machine_t *model)
+{
+ int ret;
+
+ ret = bios_load_linear("roms/machines/p54np4/asus-642accdebcb75833703472.bin",
+ 0x000e0000, 131072, 0);
+
+ if (bios_only || !ret)
+ return ret;
+
+ machine_at_common_init(model);
+
+ pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
+ pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
+ pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */
+ pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */
+ pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */
+ pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */
+ pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */
+ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
+ device_add(&i430nx_device);
+ device_add(&keyboard_ps2_ami_pci_device);
+ device_add(&fdc37c665_ide_pri_device);
+ device_add(&ncr53c810_onboard_pci_device);
+ device_add(&intel_flash_bxt_device);
+
+ return ret;
+}
+
int
machine_at_586ip_init(const machine_t *model)
{
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 26997eb61..ad0844cdc 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -4348,9 +4348,9 @@ const machine_t machines[] = {
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0,
-
+
},
- .bus_flags = MACHINE_PS2,
+ .bus_flags = MACHINE_PS2,
.flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/
.ram = {
.min = 2048,
@@ -9366,6 +9366,46 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
+ /* The M5Pi appears to have a Phoenix MultiKey KBC firmware according to photos. */
+ {
+ .name = "[i430LX] Micronics M5Pi",
+ .internal_name = "m5pi",
+ .type = MACHINE_TYPE_SOCKET4,
+ .chipset = MACHINE_CHIPSET_INTEL_430LX,
+ .init = machine_at_m5pi_init,
+ .p1_handler = NULL,
+ .gpio_handler = NULL,
+ .available_flag = MACHINE_AVAILABLE,
+ .gpio_acpi_handler = NULL,
+ .cpu = {
+ .package = CPU_PKG_SOCKET4,
+ .block = CPU_BLOCK_NONE,
+ .min_bus = 60000000,
+ .max_bus = 66666667,
+ .min_voltage = 5000,
+ .max_voltage = 5000,
+ .min_multi = MACHINE_MULTIPLIER_FIXED,
+ .max_multi = MACHINE_MULTIPLIER_FIXED
+ },
+ .bus_flags = MACHINE_PCI,
+ .flags = MACHINE_IDE_DUAL | MACHINE_APM,
+ .ram = {
+ .min = 2048,
+ .max = 131072,
+ .step = 2048
+ },
+ .nvrmask = 127,
+ .kbc_device = NULL,
+ .kbc_p1 = 0xff,
+ .gpio = 0xffffffff,
+ .gpio_acpi = 0xffffffff,
+ .device = NULL,
+ .fdc_device = NULL,
+ .sio_device = NULL,
+ .vid_device = NULL,
+ .snd_device = NULL,
+ .net_device = NULL
+ },
/* OPTi 596/597 */
/* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the
@@ -9658,6 +9698,46 @@ const machine_t machines[] = {
.net_device = NULL
},
/* Has AMI 'H' KBC firmware. */
+ {
+ .name = "[i430NX] ASUS PCI/I-P54NP4",
+ .internal_name = "p54np4",
+ .type = MACHINE_TYPE_SOCKET5,
+ .chipset = MACHINE_CHIPSET_INTEL_430NX,
+ .init = machine_at_p54np4_init,
+ .p1_handler = NULL,
+ .gpio_handler = NULL,
+ .available_flag = MACHINE_AVAILABLE,
+ .gpio_acpi_handler = NULL,
+ .cpu = {
+ .package = CPU_PKG_SOCKET5_7,
+ .block = CPU_BLOCK_NONE,
+ .min_bus = 60000000,
+ .max_bus = 66666667,
+ .min_voltage = 3520,
+ .max_voltage = 3520,
+ .min_multi = 1.5,
+ .max_multi = 1.5
+ },
+ .bus_flags = MACHINE_PS2_PCI,
+ .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM,
+ .ram = {
+ .min = 2048,
+ .max = 524288,
+ .step = 2048
+ },
+ .nvrmask = 127,
+ .kbc_device = NULL,
+ .kbc_p1 = 0xff,
+ .gpio = 0xffffffff,
+ .gpio_acpi = 0xffffffff,
+ .device = NULL,
+ .fdc_device = NULL,
+ .sio_device = NULL,
+ .vid_device = NULL,
+ .snd_device = NULL,
+ .net_device = NULL
+ },
+ /* Has AMI 'H' KBC firmware. */
{
.name = "[i430NX] Gigabyte GA-586IP",
.internal_name = "586ip",
diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp
index d18894bf6..c602b9ea1 100644
--- a/src/qt/qt_main.cpp
+++ b/src/qt/qt_main.cpp
@@ -163,8 +163,7 @@ kbd_handle(uint16_t scancode, uint16_t flags)
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
-
- /* Translate right CTRL to left ALT if the user has so
+ /* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11d) && rctrl_is_lalt)
scancode = 0x038;
@@ -173,18 +172,8 @@ kbd_handle(uint16_t scancode, uint16_t flags)
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!(flags & LLKHF_UP), scancode);
-}
-
-static LRESULT CALLBACK
-input_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
-{
- LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam;
-
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
main_window->checkFullscreenHotkey();
-
- return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static LRESULT CALLBACK
@@ -194,44 +183,38 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
/* Checks if CTRL was pressed. */
BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);
+ if ((GetForegroundWindow() == ((HWND) main_window->winId())) && !(lpKdhs->scanCode & 0xff00))
+ kbd_handle(lpKdhs->scanCode, lpKdhs->flags);
+
if ((nCode < 0) || (nCode != HC_ACTION) || (!mouse_capture && !video_fullscreen))
return CallNextHookEx(NULL, nCode, wParam, lParam);
else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
- !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
return TRUE;
- } else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
return TRUE;
- } else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
- !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
+ !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
return TRUE;
- } else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
return TRUE;
- } else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
- !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
+ !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
return TRUE;
- } else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
- !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
+ !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
return TRUE;
- } else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP))
return TRUE;
- } else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) {
- kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags);
+ else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED))
return TRUE;
- } else
+ else
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
#endif
#ifdef Q_OS_WINDOWS
static HHOOK llhook = NULL;
-static HHOOK llihook = NULL;
#endif
void
@@ -494,12 +477,17 @@ main(int argc, char *argv[])
});
}
+ /* Force raw input if a debugger is present. */
+ if (IsDebuggerPresent()) {
+ pclog("WARNING: Debugged detected, forcing raw input\n");
+ raw_input = 1;
+ }
+
/* Setup raw input */
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
if (rawInputFilter) {
app.installNativeEventFilter(rawInputFilter.get());
- if (raw_input)
- main_window->setSendKeyboardInput(false);
+ main_window->setSendKeyboardInput(false);
}
#endif
@@ -561,10 +549,7 @@ main(int argc, char *argv[])
#ifdef Q_OS_WINDOWS
if (!raw_input) {
llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0);
- llihook = SetWindowsHookEx(WH_KEYBOARD_LL, input_LowLevelKeyboardProc, NULL, GetCurrentThreadId());
atexit([] () -> void {
- if (llihook)
- UnhookWindowsHookEx(llihook);
if (llhook)
UnhookWindowsHookEx(llhook);
});
diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c
index be50d9a89..9aa5f391f 100644
--- a/src/scsi/scsi_pcscsi.c
+++ b/src/scsi/scsi_pcscsi.c
@@ -114,6 +114,7 @@
#define INTR_FC 0x08
#define INTR_BS 0x10
#define INTR_DC 0x20
+#define INTR_ILL 0x40
#define INTR_RST 0x80
#define SEQ_0 0x0
@@ -174,12 +175,11 @@ typedef struct esp_t {
uint8_t bus;
uint8_t id, lun;
Fifo8 cmdfifo;
- uint32_t do_cmd;
uint8_t cmdfifo_cdb_offset;
int data_ready;
- int32_t xfer_counter;
- int dma_enabled;
+ int32_t xfer_counter;
+ int dma_enabled;
uint32_t buffer_pos;
uint32_t dma_regs[8];
@@ -198,6 +198,7 @@ typedef struct esp_t {
struct {
uint8_t mode;
uint8_t status;
+ int interrupt;
int pos;
} dma_86c01;
@@ -239,7 +240,7 @@ static void esp_dma_ti_check(esp_t *dev);
static void esp_nodma_ti_dataout(esp_t *dev);
static void esp_pci_soft_reset(esp_t *dev);
static void esp_pci_hard_reset(esp_t *dev);
-static void handle_ti(void *priv);
+static void handle_ti(esp_t *dev);
static int
esp_cdb_length(uint8_t *buf)
@@ -253,7 +254,7 @@ esp_cdb_length(uint8_t *buf)
break;
case 1:
case 2:
- case 6:
+ case 6: /*Vendor unique*/
cdb_len = 10;
break;
case 4:
@@ -292,9 +293,11 @@ esp_irq(esp_t *dev, int level)
if (dev->mca) {
if (level) {
picintlevel(1 << dev->irq, &dev->irq_state);
+ dev->dma_86c01.mode |= 0x40;
esp_log("Raising IRQ...\n");
} else {
picintclevel(1 << dev->irq, &dev->irq_state);
+ dev->dma_86c01.mode &= ~0x40;
esp_log("Lowering IRQ...\n");
}
} else {
@@ -307,8 +310,8 @@ esp_irq(esp_t *dev, int level)
* DMA_STAT_DONE and the ESP IRQ arriving which is visible to the
* guest that can cause confusion e.g. Linux
*/
- if ((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x3 &&
- dev->dma_regs[DMA_WBC] == 0)
+ if (((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x03) &&
+ (dev->dma_regs[DMA_WBC] == 0))
dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
} else
dev->dma_regs[DMA_STAT] &= ~DMA_STAT_SCSIINT;
@@ -383,7 +386,7 @@ esp_get_tc(esp_t *dev)
{
uint32_t dmalen;
- dmalen = dev->rregs[ESP_TCLO];
+ dmalen = dev->rregs[ESP_TCLO] & 0xff;
dmalen |= dev->rregs[ESP_TCMID] << 8;
dmalen |= dev->rregs[ESP_TCHI] << 16;
@@ -395,10 +398,11 @@ esp_set_tc(esp_t *dev, uint32_t dmalen)
{
uint32_t old_tc = esp_get_tc(dev);
- dev->rregs[ESP_TCLO] = dmalen;
+ dev->rregs[ESP_TCLO] = dmalen & 0xff;
dev->rregs[ESP_TCMID] = dmalen >> 8;
dev->rregs[ESP_TCHI] = dmalen >> 16;
+ esp_log("OLDTC=%d, DMALEN=%d.\n", old_tc, dmalen);
if (old_tc && !dmalen)
dev->rregs[ESP_RSTAT] |= STAT_TC;
}
@@ -408,10 +412,11 @@ esp_get_stc(esp_t *dev)
{
uint32_t dmalen;
- dmalen = dev->wregs[ESP_TCLO];
- dmalen |= dev->wregs[ESP_TCMID] << 8;
- dmalen |= dev->wregs[ESP_TCHI] << 16;
+ dmalen = dev->wregs[ESP_TCLO] & 0xff;
+ dmalen |= (dev->wregs[ESP_TCMID] << 8);
+ dmalen |= (dev->wregs[ESP_TCHI] << 16);
+ esp_log("STCW=%d.\n", dmalen);
return dmalen;
}
@@ -459,25 +464,25 @@ esp_transfer_data(esp_t *dev)
dev->rregs[ESP_RSEQ] = SEQ_CD;
break;
- case CMD_SELATNS:
- case (CMD_SELATNS | CMD_DMA):
- /*
- * Initial incoming data xfer is complete so raise command
- * completion interrupt
- */
- dev->rregs[ESP_RINTR] |= INTR_BS;
- dev->rregs[ESP_RSEQ] = SEQ_MO;
- break;
+ case CMD_SELATNS:
+ case (CMD_SELATNS | CMD_DMA):
+ /*
+ * Initial incoming data xfer is complete so raise command
+ * completion interrupt
+ */
+ dev->rregs[ESP_RINTR] |= INTR_BS;
+ dev->rregs[ESP_RSEQ] = SEQ_MO;
+ break;
- case CMD_TI:
- case (CMD_TI | CMD_DMA):
- /*
- * Bus service interrupt raised because of initial change to
- * DATA phase
- */
- dev->rregs[ESP_CMD] = 0;
- dev->rregs[ESP_RINTR] |= INTR_BS;
- break;
+ case CMD_TI:
+ case (CMD_TI | CMD_DMA):
+ /*
+ * Bus service interrupt raised because of initial change to
+ * DATA phase
+ */
+ dev->rregs[ESP_CMD] = 0;
+ dev->rregs[ESP_RINTR] |= INTR_BS;
+ break;
}
esp_raise_irq(dev);
@@ -621,16 +626,12 @@ esp_hard_reset(esp_t *dev)
{
memset(dev->rregs, 0, ESP_REGS);
memset(dev->wregs, 0, ESP_REGS);
- dev->tchi_written = 0;
dev->ti_size = 0;
fifo8_reset(&dev->fifo);
fifo8_reset(&dev->cmdfifo);
dev->dma = 0;
- dev->do_cmd = 0;
dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7;
esp_log("ESP Reset\n");
- for (uint8_t i = 0; i < 16; i++)
- scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_stop(&dev->timer);
}
@@ -681,7 +682,7 @@ esp_do_dma(esp_t *dev)
len = esp_get_tc(dev);
- switch (esp_get_phase(dev)) {
+ switch (esp_get_phase(dev)) {
case STAT_MO:
len = MIN(len, fifo8_num_free(&dev->cmdfifo));
if (dev->mca) {
@@ -787,7 +788,6 @@ esp_do_dma(esp_t *dev)
esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, len, WRITE_TO_DEVICE);
esp_set_tc(dev, esp_get_tc(dev) - len);
-
dev->buffer_pos += len;
dev->xfer_counter -= len;
dev->ti_size += len;
@@ -827,6 +827,7 @@ esp_do_dma(esp_t *dev)
/* Defer until data is available. */
return;
}
+
if (len > dev->xfer_counter)
len = dev->xfer_counter;
@@ -861,14 +862,6 @@ esp_do_dma(esp_t *dev)
break;
}
- if ((dev->xfer_counter <= 0) && !dev->ti_size && esp_get_tc(dev)) {
- /* If the guest underflows TC then terminate SCSI request */
- esp_log("ESP SCSI Read finished (underflow).\n");
- scsi_device_command_phase1(sd);
- esp_command_complete(dev, sd->status);
- return;
- }
-
if ((dev->xfer_counter <= 0) && (fifo8_num_used(&dev->fifo) < 2)) {
/* Defer until the scsi layer has completed */
if (dev->ti_size <= 0) {
@@ -1241,10 +1234,8 @@ handle_pad(esp_t *dev)
}
static void
-handle_ti(void *priv)
+handle_ti(esp_t *dev)
{
- esp_t *dev = (esp_t *) priv;
-
if (dev->dma) {
esp_log("ESP Handle TI, do data, minlen = %i\n", esp_get_tc(dev));
esp_do_dma(dev);
@@ -1329,8 +1320,6 @@ esp_callback(void *priv)
handle_pad(dev);
}
}
-
- esp_log("ESP DMA activated = %d, CMD activated = %d, CMD = %02x\n", dev->dma_enabled, dev->do_cmd, (dev->rregs[ESP_CMD] & CMD_CMD));
}
static uint32_t
@@ -1353,13 +1342,15 @@ esp_reg_read(esp_t *dev, uint32_t saddr)
esp_lower_irq(dev);
esp_log("ESP RINTR read old val = %02x\n", ret);
break;
- case ESP_TCHI:
- /* Return the unique id if the value has never been written */
- if (!dev->tchi_written && !dev->mca) {
- esp_log("ESP TCHI read id 0x12\n");
- ret = TCHI_AM53C974;
- } else
- ret = dev->rregs[saddr];
+ case ESP_TCHI: /* Return the unique id if the value has never been written */
+ if (dev->mca) {
+ ret = dev->rregs[ESP_TCHI];
+ } else {
+ if (dev->rregs[ESP_CFG2] & 0x40)
+ ret = TCHI_AM53C974;
+ else
+ ret = dev->rregs[ESP_TCHI];
+ }
break;
case ESP_RFLAGS:
ret = fifo8_num_used(&dev->fifo);
@@ -1376,14 +1367,11 @@ static void
esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
{
esp_log("Write reg %02x = %02x\n", saddr, val);
-
switch (saddr) {
case ESP_TCHI:
- dev->tchi_written = 1;
- fallthrough;
case ESP_TCLO:
case ESP_TCMID:
- esp_log("Transfer count regs %02x = %i\n", saddr, val);
+ esp_log("ESP TCW reg%02x = %02x.\n", saddr, val);
dev->rregs[ESP_RSTAT] &= ~STAT_TC;
break;
case ESP_FIFO:
@@ -1393,14 +1381,18 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
esp_do_nodma(dev);
break;
case ESP_CMD:
- dev->rregs[saddr] = val;
+ dev->rregs[ESP_CMD] = val;
if (val & CMD_DMA) {
dev->dma = 1;
/* Reload DMA counter. */
esp_set_tc(dev, esp_get_stc(dev));
- if (!esp_get_stc(dev))
- esp_set_tc(dev, 0x10000);
+ if (!esp_get_stc(dev)) {
+ if (dev->rregs[ESP_CFG2] & 0x40)
+ esp_set_tc(dev, 0x1000000);
+ else
+ esp_set_tc(dev, 0x10000);
+ }
} else {
dev->dma = 0;
esp_log("ESP Command not for DMA\n");
@@ -1481,6 +1473,8 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
}
break;
case ESP_WBUSID:
+ esp_log("ESP BUS ID=%d.\n", val & BUSID_DID);
+ break;
case ESP_WSEL:
case ESP_WSYNTP:
case ESP_WSYNO:
@@ -1505,6 +1499,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
static void
esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir)
{
+ uint32_t sg_pos = 0;
uint32_t addr;
int expected_dir;
@@ -1513,31 +1508,58 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir)
else
expected_dir = WRITE_TO_DEVICE;
- esp_log("ESP DMA WBC = %d, addr = %06x, expected direction = %d, dir = %i\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir, dir);
-
if (dir != expected_dir) {
esp_log("ESP unexpected direction\n");
return;
}
- addr = dev->dma_regs[DMA_WAC];
- if (dev->dma_regs[DMA_WBC] < len)
- len = dev->dma_regs[DMA_WBC];
+ if (dev->dma_regs[DMA_CMD] & DMA_CMD_MDL) {
+ if (dev->dma_regs[DMA_STC]) {
+ if (dev->dma_regs[DMA_WBC] > len)
+ dev->dma_regs[DMA_WBC] = len;
- if (expected_dir)
- dma_bm_write(addr, buf, len, 4);
- else
- dma_bm_read(addr, buf, len, 4);
+ esp_log("WAC MDL=%08x, STC=%d, ID=%d.\n", dev->dma_regs[DMA_WAC] | (dev->dma_regs[DMA_WMAC] & 0xff000), dev->dma_regs[DMA_STC], dev->id);
+ for (uint32_t i = 0; i < len; i++) {
+ addr = dev->dma_regs[DMA_WAC];
- esp_log("DMA: Address = %08X, Length = %08X (%02X %02X %02X %02X -> %02X %02X %02X %02X)\n", dev->dma_regs[DMA_SPA], len,
- ram[dev->dma_regs[DMA_SPA]], ram[dev->dma_regs[DMA_SPA] + 1], ram[dev->dma_regs[DMA_SPA] + 2], ram[dev->dma_regs[DMA_SPA] + 3],
- buf[0], buf[1], buf[2], buf[3]);
+ if (expected_dir)
+ dma_bm_write(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4);
+ else
+ dma_bm_read(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4);
- /* update status registers */
- dev->dma_regs[DMA_WBC] -= len;
- dev->dma_regs[DMA_WAC] += len;
- if (dev->dma_regs[DMA_WBC] == 0)
- dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
+ sg_pos++;
+ dev->dma_regs[DMA_WBC]--;
+ dev->dma_regs[DMA_WAC]++;
+
+ if (dev->dma_regs[DMA_WAC] & 0x1000) {
+ dev->dma_regs[DMA_WAC] = 0;
+ dev->dma_regs[DMA_WMAC] += 0x1000;
+ }
+
+ if (dev->dma_regs[DMA_WBC] <= 0) {
+ dev->dma_regs[DMA_WBC] = 0;
+ dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
+ }
+ }
+ }
+ } else {
+ if (dev->dma_regs[DMA_WBC] < len)
+ len = dev->dma_regs[DMA_WBC];
+
+ addr = dev->dma_regs[DMA_WAC];
+
+ if (expected_dir)
+ dma_bm_write(addr, buf, len, 4);
+ else
+ dma_bm_read(addr, buf, len, 4);
+
+ /* update status registers */
+ dev->dma_regs[DMA_WBC] -= len;
+ dev->dma_regs[DMA_WAC] += len;
+
+ if (dev->dma_regs[DMA_WBC] == 0)
+ dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
+ }
}
static uint32_t
@@ -1566,7 +1588,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
switch (saddr) {
case DMA_CMD:
- dev->dma_regs[saddr] = val;
+ dev->dma_regs[DMA_CMD] = val;
esp_log("ESP PCI DMA Write CMD = %02x\n", val & DMA_CMD_MASK);
switch (val & DMA_CMD_MASK) {
case 0: /*IDLE*/
@@ -1580,21 +1602,32 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]);
break;
case 3: /*START*/
+ dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA];
+ dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA] & 0xfffffffc;
+ if (!dev->dma_regs[DMA_STC])
+ dev->dma_regs[DMA_STC] = 0x1000000;
+
dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC];
- dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA];
- dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA];
dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN);
esp_dma_enable(dev, 1);
- esp_log("PCI DMA enable\n");
+ esp_log("PCI DMA enable, MDL bit=%02x, SPA=%08x, SMDLA=%08x, STC=%d, ID=%d, SCSICMD=%02x.\n", val & DMA_CMD_MDL, dev->dma_regs[DMA_SPA], dev->dma_regs[DMA_SMDLA], dev->dma_regs[DMA_STC], dev->id, dev->cmdfifo.data[1]);
break;
default: /* can't happen */
abort();
+ break;
}
break;
case DMA_STC:
+ dev->dma_regs[DMA_STC] = val;
+ esp_log("DMASTC PCI write=%08x.\n", val);
+ break;
case DMA_SPA:
+ dev->dma_regs[DMA_SPA] = val;
+ esp_log("DMASPA PCI write=%08x.\n", val);
+ break;
case DMA_SMDLA:
- dev->dma_regs[saddr] = val;
+ dev->dma_regs[DMA_SMDLA] = val;
+ esp_log("DMASMDLA PCI write=%08x.\n", val);
break;
case DMA_STAT:
if (dev->sbac & SBAC_STATUS) {
@@ -1629,7 +1662,7 @@ esp_pci_hard_reset(esp_t *dev)
dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT
| DMA_STAT_DONE | DMA_STAT_ABORT
| DMA_STAT_ERROR);
- dev->dma_regs[DMA_WMAC] = 0xfffffffd;
+ dev->dma_regs[DMA_WMAC] = 0xfffffffc;
}
static uint32_t
@@ -1680,7 +1713,7 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size)
current = dev->wregs[addr >> 2];
} else if (addr < 0x60) {
current = dev->dma_regs[(addr - 0x40) >> 2];
- } else if (addr < 0x74) {
+ } else if (addr == 0x70) {
current = dev->sbac;
}
@@ -2008,7 +2041,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv)
case 0x07:
return esp_pci_regs[0x07] | 0x02;
case 0x08:
- return 0; /*Revision ID*/
+ return 0x10; /*Revision ID*/
case 0x09:
return 0; /*Programming interface*/
case 0x0A:
@@ -2018,7 +2051,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv)
case 0x0E:
return 0; /*Header type */
case 0x10:
- return (esp_pci_bar[0].addr_regs[0] & 0x80) | 0x01; /*I/O space*/
+ return esp_pci_bar[0].addr_regs[0] | 0x01; /*I/O space*/
case 0x11:
return esp_pci_bar[0].addr_regs[1];
case 0x12:
@@ -2082,7 +2115,7 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
switch (addr) {
case 0x04:
- valxor = (val & 3) ^ esp_pci_regs[addr];
+ valxor = (val & 0x01) ^ esp_pci_regs[addr];
if (valxor & PCI_COMMAND_IO) {
esp_io_remove(dev, dev->PCIBase, 0x80);
if ((val & PCI_COMMAND_IO) && (dev->PCIBase != 0))
@@ -2215,6 +2248,8 @@ dc390_init(UNUSED(const device_t *info))
}
esp_pci_hard_reset(dev);
+ for (uint8_t i = 0; i < 16; i++)
+ scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_add(&dev->timer, esp_callback, dev, 0);
@@ -2240,12 +2275,12 @@ ncr53c9x_in(uint16_t port, void *priv)
break;
case 0x0c:
- if (dev->rregs[ESP_RSTAT] & STAT_INT)
+ if (dev->dma_86c01.mode & 0x40)
dev->dma_86c01.status |= 0x01;
else
dev->dma_86c01.status &= ~0x01;
- if ((dev->dma_86c01.mode & 0x40) || dev->dma_enabled)
+ if (dev->dma_enabled)
dev->dma_86c01.status |= 0x02;
else
dev->dma_86c01.status &= ~0x02;
@@ -2258,7 +2293,7 @@ ncr53c9x_in(uint16_t port, void *priv)
}
}
- esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x.\n\n", CS, cpu_state.pc, port, ret);
+ esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x, local = %d.\n\n", CS, cpu_state.pc, port, ret, dev->local);
return ret;
}
@@ -2282,7 +2317,7 @@ ncr53c9x_out(uint16_t port, uint16_t val, void *priv)
port &= 0x1f;
- esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val);
+ esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x.\n\n", CS, cpu_state.pc, port, val);
if (port >= 0x10)
esp_reg_write(dev, port - 0x10, val);
@@ -2360,6 +2395,8 @@ ncr53c9x_mca_write(int port, uint8_t val, void *priv)
ncr53c9x_outb, ncr53c9x_outw, NULL, dev);
esp_hard_reset(dev);
+ for (uint8_t i = 0; i < 8; i++)
+ scsi_device_reset(&scsi_devices[dev->bus][i]);
}
/* Say hello. */
@@ -2377,7 +2414,7 @@ ncr53c9x_mca_feedb(void *priv)
}
static void *
-ncr53c9x_mca_init(UNUSED(const device_t *info))
+ncr53c9x_mca_init(const device_t *info)
{
esp_t *dev;
@@ -2387,6 +2424,7 @@ ncr53c9x_mca_init(UNUSED(const device_t *info))
dev->bus = scsi_get_bus();
dev->mca = 1;
+ dev->local = info->local;
fifo8_create(&dev->fifo, ESP_FIFO_SZ);
fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ);
@@ -2396,6 +2434,8 @@ ncr53c9x_mca_init(UNUSED(const device_t *info))
mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev);
esp_hard_reset(dev);
+ for (uint8_t i = 0; i < 8; i++)
+ scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_add(&dev->timer, esp_callback, dev, 0);
@@ -2446,7 +2486,7 @@ const device_t dc390_pci_device = {
};
const device_t am53c974_pci_device = {
- .name = "AMD 53c974 PCI",
+ .name = "AMD 53c974A PCI",
.internal_name = "am53c974",
.flags = DEVICE_PCI,
.local = 1,
diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c
index df0547fdc..8ac27882b 100644
--- a/src/sound/snd_sb.c
+++ b/src/sound/snd_sb.c
@@ -1,23 +1,21 @@
/*
- * 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.
+ * 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.
*
- * This file is part of the 86Box distribution.
+ * This file is part of the 86Box distribution.
*
- * Sound Blaster emulation.
+ * Sound Blaster emulation.
*
+ * Authors: Sarah Walker,
+ * Miran Grca,
+ * TheCollector1995,
+ * Jasmine Iwanek,
*
- *
- * Authors: Sarah Walker,
- * Miran Grca,
- * TheCollector1995,
- * Jasmine Iwanek,
- *
- * Copyright 2008-2020 Sarah Walker.
- * Copyright 2016-2020 Miran Grca.
- * Copyright 2024 Jasmine Iwanek.
+ * Copyright 2008-2020 Sarah Walker.
+ * Copyright 2016-2020 Miran Grca.
+ * Copyright 2024-2025 Jasmine Iwanek.
*/
#include
#include
@@ -64,6 +62,7 @@
#define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN"
#define PNP_ROM_SB_VIBRA16CL "roms/sound/creative/CT4100 PnP.BIN"
#define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN"
+#define PNP_ROM_SB_GOLDFINCH "roms/sound/creative/CT1920 PnP.BIN"
#define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN"
#define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN"
#define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN"
@@ -509,6 +508,28 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv)
sb->opl.reset_buffer(sb->opl.priv);
}
+// TODO: Goldfinch
+static void
+sb_get_wavetable_buffer_goldfinch(int32_t *buffer, const int len, void *priv)
+{
+ goldfinch_t *goldfinch = (goldfinch_t *) priv;
+
+ emu8k_update(&goldfinch->emu8k);
+
+ for (int c = 0; c < len * 2; c += 2) {
+ double out_l = 0.0;
+ double out_r = 0.0;
+
+ out_l += ((double) goldfinch->emu8k.buffer[c]);
+ out_r += ((double) goldfinch->emu8k.buffer[c + 1]);
+
+ buffer[c] += (int32_t) out_l;
+ buffer[c + 1] += (int32_t) out_r;
+ }
+
+ goldfinch->emu8k.pos = 0;
+}
+
static void
sb_get_wavetable_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv)
{
@@ -2217,6 +2238,21 @@ sb_vibra16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config,
}
}
+static void
+goldfinch_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv)
+{
+ goldfinch_t *goldfinch = (goldfinch_t *) priv;
+
+ switch (ld) {
+ default:
+ break;
+
+ case 0: /* WaveTable */
+ emu8k_change_addr(&goldfinch->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
+ break;
+ }
+}
+
static void
sb_awe32_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv)
{
@@ -3550,6 +3586,12 @@ sb_awe32_available(void)
return rom_present(EMU8K_ROM_PATH);
}
+static int
+sb_goldfinch_available(void)
+{
+ return sb_awe32_available() && rom_present(PNP_ROM_SB_GOLDFINCH);
+}
+
static int
sb_32_pnp_available(void)
{
@@ -3659,6 +3701,54 @@ sb_awe32_init(UNUSED(const device_t *info))
return sb;
}
+static void *
+sb_goldfinch_init(const device_t *info)
+{
+ goldfinch_t *goldfinch = malloc(sizeof(goldfinch_t));
+ int onboard_ram = device_get_config_int("onboard_ram");
+
+ memset(goldfinch, 0x00, sizeof(goldfinch_t));
+
+ wavetable_add_handler(sb_get_wavetable_buffer_goldfinch, goldfinch);
+
+ emu8k_init(&goldfinch->emu8k, 0, onboard_ram);
+
+ const char *pnp_rom_file = NULL;
+ switch (info->local) {
+ case 0:
+ pnp_rom_file = PNP_ROM_SB_GOLDFINCH;
+ break;
+
+ default:
+ break;
+ }
+
+ uint8_t *pnp_rom = NULL;
+ if (pnp_rom_file) {
+ FILE *fp = rom_fopen(pnp_rom_file, "rb");
+ uint16_t pnp_rom_len = 256;
+ if (fp) {
+ if (fread(goldfinch->pnp_rom, 1, pnp_rom_len, fp) == pnp_rom_len)
+ pnp_rom = goldfinch->pnp_rom;
+ fclose(fp);
+ }
+ }
+
+ switch (info->local) {
+ case 0:
+ isapnp_add_card(pnp_rom, sizeof(goldfinch->pnp_rom), goldfinch_pnp_config_changed,
+ NULL, NULL, NULL, goldfinch);
+ break;
+
+ default:
+ break;
+ }
+
+ emu8k_change_addr(&goldfinch->emu8k, 0);
+
+ return goldfinch;
+}
+
static void *
sb_awe32_pnp_init(const device_t *info)
{
@@ -4054,6 +4144,16 @@ sb_close(void *priv)
free(sb);
}
+static void
+sb_goldfinch_close(void *priv)
+{
+ goldfinch_t *goldfinch = (goldfinch_t *) priv;
+
+ emu8k_close(&goldfinch->emu8k);
+
+ free(goldfinch);
+}
+
static void
sb_awe32_close(void *priv)
{
@@ -4765,6 +4865,54 @@ static const device_config_t sb_16_pnp_config[] = {
{ .name = "", .description = "", .type = CONFIG_END }
};
+static const device_config_t sb_goldfinch_config[] = {
+ {
+ .name = "onboard_ram",
+ .description = "Memory size",
+ .type = CONFIG_SELECTION,
+ .default_string = "",
+ .default_int = 0,
+ .file_filter = "",
+ .spinner = { 0 },
+ .selection = {
+ {
+ .description = "None",
+ .value = 0
+ },
+ {
+ .description = "512 KB",
+ .value = 512
+ },
+ {
+ .description = "1 MB",
+ .value = 1024
+ },
+ {
+ .description = "2 MB",
+ .value = 2048
+ },
+ {
+ .description = "4 MB",
+ .value = 4096
+ },
+ {
+ .description = "8 MB",
+ .value = 8192
+ },
+ {
+ .description = "16 MB",
+ .value = 16384
+ },
+ {
+ .description = "28 MB",
+ .value = 28672
+ },
+ { .description = "" }
+ }
+ },
+ { .name = "", .description = "", .type = CONFIG_END }
+};
+
static const device_config_t sb_32_pnp_config[] = {
{
.name = "onboard_ram",
@@ -5922,6 +6070,20 @@ const device_t sb_16_compat_nompu_device = {
.config = NULL
};
+const device_t sb_goldfinch_device = {
+ .name = "Creative EMU8000 PnP (Goldfinch)",
+ .internal_name = "sb_goldfinch",
+ .flags = DEVICE_ISA | DEVICE_AT,
+ .local = 0,
+ .init = sb_goldfinch_init,
+ .close = sb_goldfinch_close,
+ .reset = NULL,
+ .available = sb_goldfinch_available,
+ .speed_changed = NULL,
+ .force_redraw = NULL,
+ .config = sb_goldfinch_config
+};
+
const device_t sb_32_pnp_device = {
.name = "Sound Blaster 32 PnP",
.internal_name = "sb32_pnp",
diff --git a/src/sound/sound.c b/src/sound/sound.c
index 06f38d125..b1762eaff 100644
--- a/src/sound/sound.c
+++ b/src/sound/sound.c
@@ -123,6 +123,7 @@ static const SOUND_CARD sound_cards[] = {
{ &sb_16_device },
{ &sb_16_pnp_device },
{ &sb_16_pnp_ide_device },
+ { &sb_goldfinch_device },
{ &sb_32_pnp_device },
{ &sb_awe32_device },
{ &sb_awe32_pnp_device },