From 970f9eff3438e0faf63267708e5541784308c216 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sat, 7 Dec 2024 20:14:18 +0700 Subject: [PATCH 01/52] Added a first batch of HDD model names/speeds Adds 10 HDD models' names/speeds other than the generic 86B_HD00. It may not accurate but their models' names\speeds would be closer to the real ones. Also adds the HDD type names to the Connor HDD models. --- src/disk/hdd.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index ea38602d2..bff9aeee8 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -407,18 +407,28 @@ hdd_zones_init(hard_disk_t *hdd) static hdd_preset_t hdd_speed_presets[] = { // clang-format off - { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, - { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, - { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, - { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, - { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, - { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "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 }, - { .name = "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 }, - { .name = "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 }, - // clang-format on + { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, + { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, + { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ESDI] Fujitsu M2263E", .internal_name = "M2263E", .model = "FUJITSU M2263E", .zones = 1, .avg_spt = 16, .heads = 8, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 1 }, + { .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 }, + { .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 }, + { .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 }, + { .name = "[ATA-1] Maxtor 7131AT", .internal_name = "7131AT", .model = "MAXTOR 7131AT", .zones = 2, .avg_spt = 14, .heads = 2, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4, .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 = 15, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 12, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-2] Quantum Bigfoot 1.2AT (BF12A011)", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT_BF12A011", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-4] Quantum Bigfoot TX (TX043A011)", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT_TX043A011", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + // clang-format on }; int From 7c3a54efb83d091e880859323504fc2e10bcfa0e Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sat, 7 Dec 2024 21:19:49 +0700 Subject: [PATCH 02/52] Added the two forgotten HDD models. --- src/disk/hdd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index bff9aeee8..76b5c4c5c 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -428,6 +428,8 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, { .name = "[ATA-4] Quantum Bigfoot TX (TX043A011)", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT_TX043A011", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-4] Quantum Fireball CR (CR43A013)", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, // clang-format on }; From c80a9ecd33edac1ddb4350761ba8cbbba218dca7 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sat, 7 Dec 2024 21:26:29 +0700 Subject: [PATCH 03/52] Fixed the configuration The Fireball is acutally ATA-2, while the SpinPoint is ATA-5 --- src/disk/hdd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 76b5c4c5c..1b2095b9b 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -423,13 +423,13 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[ATA-1] Maxtor 7213AT", .internal_name = "7213AT", .model = "MAXTOR 7213AT", .zones = 4, .avg_spt = 15, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 12, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, { .name = "[ATA-2] Quantum Bigfoot 1.2AT (BF12A011)", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT_BF12A011", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Fireball CR (CR43A013)", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, { .name = "[ATA-4] Quantum Bigfoot TX (TX043A011)", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT_TX043A011", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-4] Quantum Fireball CR (CR43A013)", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, - { .name = "[ATA-4] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, // clang-format on }; From 9a6b1313054f2f05d9fbf40d4016ed07f4d85987 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 01:22:09 +0700 Subject: [PATCH 04/52] Added other 8 HDD models That gives a total of 20 new HDD models to be added to 86Box and is ready to be merged. --- src/disk/hdd.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 1b2095b9b..bff597d1c 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -407,7 +407,7 @@ hdd_zones_init(hard_disk_t *hdd) static hdd_preset_t hdd_speed_presets[] = { // clang-format off - { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, @@ -416,20 +416,28 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[ESDI] Fujitsu M2263E", .internal_name = "M2263E", .model = "FUJITSU M2263E", .zones = 1, .avg_spt = 16, .heads = 8, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 1 }, + { .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "IBM-WDA-L42", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 }, { .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 }, { .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 }, { .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 }, { .name = "[ATA-1] Maxtor 7131AT", .internal_name = "7131AT", .model = "MAXTOR 7131AT", .zones = 2, .avg_spt = 14, .heads = 2, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4, .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 = 15, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .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 = 15, .heads = 4, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "IBM-DBOA-2720", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 12, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, - { .name = "[ATA-2] Quantum Bigfoot 1.2AT (BF12A011)", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT_BF12A011", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 5, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot 1.2AT (BF12A011)", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT_BF12A", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot CY (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[ATA-2] Quantum Fireball CR (CR43A013)", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .avg_spt = 13, .heads = 2, .rpm = 4200, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 16 }, { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, - { .name = "[ATA-4] Quantum Bigfoot TX (TX043A011)", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT_TX043A011", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-4] Quantum Bigfoot TX (TX043A011)", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT_TX043A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 16, .avg_spt = 13, .heads = 6, .rpm = 3811, .full_stroke_ms = 25, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .avg_spt = 9, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, // clang-format on }; From 1edfb0253cfe75f9ae2ad51560a8c92aae0ec510 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 01:26:38 +0700 Subject: [PATCH 05/52] Forgotten model name changes --- src/disk/hdd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index bff597d1c..a07a4358b 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -426,15 +426,15 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "IBM-DBOA-2720", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 12, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 5, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot 1.2AT (BF12A011)", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT_BF12A", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot CY (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-2] Quantum Fireball CR (CR43A013)", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .avg_spt = 13, .heads = 2, .rpm = 4200, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 16 }, { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, - { .name = "[ATA-4] Quantum Bigfoot TX (TX043A011)", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT_TX043A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 16, .avg_spt = 13, .heads = 6, .rpm = 3811, .full_stroke_ms = 25, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .avg_spt = 9, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, From 0e3be4e17ed5fff10757388497ac7c6e1b7cd55c Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 01:29:12 +0700 Subject: [PATCH 06/52] One more change It's now ready to be merged --- src/disk/hdd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index a07a4358b..53bbfddc1 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -426,17 +426,17 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "IBM-DBOA-2720", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 12, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 5, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .avg_spt = 13, .heads = 2, .rpm = 4200, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 16 }, { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, - { .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 16, .avg_spt = 13, .heads = 6, .rpm = 3811, .full_stroke_ms = 25, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 512, .max_multiple = 32 }, - { .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .avg_spt = 9, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, // clang-format on }; From 3a0a3c85d0441ea4ffa0a8b4f7e4192f5317ee63 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 01:41:55 +0700 Subject: [PATCH 07/52] Oops. One forgotten change It's now ready to be merged for the new 4.3 release. --- src/disk/hdd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 53bbfddc1..f21292de9 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -431,19 +431,19 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, - { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .avg_spt = 13, .heads = 2, .rpm = 4200, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .avg_spt = 13, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 16 }, { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, { .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 16, .avg_spt = 13, .heads = 6, .rpm = 3811, .full_stroke_ms = 25, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 512, .max_multiple = 32 }, - { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, - { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .avg_spt = 9, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 8, .avg_spt = 13, .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-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .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 = 8, .avg_spt = 9, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, // clang-format on }; int hdd_preset_get_num(void) -{ +{4 return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t); } From 8436ee078963ed616897aa325eb056bd374b8521 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 01:43:15 +0700 Subject: [PATCH 08/52] Fixed a compile-breaking mistake --- src/disk/hdd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index f21292de9..80187e318 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -443,7 +443,7 @@ static hdd_preset_t hdd_speed_presets[] = { int hdd_preset_get_num(void) -{4 +{ return sizeof(hdd_speed_presets) / sizeof(hdd_preset_t); } From 22fe79209c71698c140301a1edb84558feb66ae9 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 04:00:59 +0700 Subject: [PATCH 09/52] I have forgotten one more change --- src/disk/hdd.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 80187e318..b6344a7a1 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -415,29 +415,29 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ESDI] Fujitsu M2263E", .internal_name = "M2263E", .model = "FUJITSU M2263E", .zones = 1, .avg_spt = 16, .heads = 8, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 1 }, - { .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "IBM-WDA-L42", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 }, + { .name = "[ESDI] Fujitsu M2263E", .internal_name = "M2263E", .model = "FUJITSU M2263E", .zones = 1, .avg_spt = 160, .heads = 8, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 1 }, + { .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "IBM-WDA-L42", .zones = 1, .avg_spt = 85, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 2.5, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 }, { .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 }, { .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 }, { .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 }, - { .name = "[ATA-1] Maxtor 7131AT", .internal_name = "7131AT", .model = "MAXTOR 7131AT", .zones = 2, .avg_spt = 14, .heads = 2, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4, .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 = 15, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .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 = 15, .heads = 4, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 16 }, - { .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "IBM-DBOA-2720", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, - { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 12, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, - { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 5, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 15, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 13, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 11, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, - { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 12, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, - { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 14, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, - { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .avg_spt = 13, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 16 }, - { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1, .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 = 9, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, - { .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 12, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 8, .avg_spt = 13, .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-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .avg_spt = 9, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .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 = 8, .avg_spt = 9, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .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 = 16 }, + { .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 = 16 }, + { .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 }, + { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .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 = 8 }, + { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .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 = 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] 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] 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-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .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] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .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 }, // clang-format on }; From b9de5d5f0fa508406ea6a519036f4d22d05a2a98 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 9 Dec 2024 16:52:21 +0700 Subject: [PATCH 10/52] Added the other 12 HDD models This gives a total for the first batch (or basic set) of 32 HDD model names/speeds to use on 86Box 4.3. It is now ready to be merged. Also changes to some configuration. --- src/disk/hdd.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index b6344a7a1..010e46d1a 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -420,22 +420,33 @@ 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 }, { .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 }, { .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 }, - { .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 = 16 }, + { .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] 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 = 16 }, { .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 = 16 }, { .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 }, { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, - { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, - { .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 = 8 }, - { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 8, .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 = 16 }, + { .name = "[ATA-2] Samsung PLS-31274A", .internal_name = "PLS31274A", .model = "SAMSUNG PLS-31274A", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 45, .track_seek_ms = 4.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .name = "[ATA-2] Samsung Winner-1", .internal_name = "WNR31601A", .model = "SAMSUNG WNR-31601A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 }, + { .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 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] Western Digital Caviar 2850", .internal_name = "AC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 4500, .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 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] 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-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] 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] 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] 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 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 = 8, .rcache_seg_size = 256, .max_multiple = 32 }, { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .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] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .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 }, // clang-format on From b38fb6b72a20ea52967c70e4d0276726965ce782 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 12 Dec 2024 04:42:27 +0700 Subject: [PATCH 11/52] Some changes to the configuration --- src/disk/hdd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 010e46d1a..b0d0495ba 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -437,7 +437,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 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] Western Digital Caviar 2850", .internal_name = "AC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 4500, .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 2850", .internal_name = "WDAC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 4500, .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 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] 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-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 }, @@ -446,7 +446,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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] 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] 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 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 = 8, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Western Digital Caviar 33200", .internal_name = "WDAC33200", .model = "WDC WDAC33200-00LA", .zones = 16, .avg_spt = 110, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .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] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .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 }, // clang-format on From f72657aeb0facb8cfb1e5592acdac3c2ce2cd61b Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 12 Dec 2024 05:37:04 +0700 Subject: [PATCH 12/52] Some model name changes --- src/disk/hdd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index b0d0495ba..d44da0925 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -437,8 +437,8 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 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] Western Digital Caviar 2850", .internal_name = "WDAC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 4500, .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 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-2] Western Digital Caviar 2850", .internal_name = "WDAC2850", .model = "WDC AC2850F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 4500, .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 31200", .internal_name = "WDAC31200", .model = "WDC AC31200F", .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] 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-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 }, @@ -446,7 +446,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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] 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] 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 33200", .internal_name = "WDAC33200", .model = "WDC WDAC33200-00LA", .zones = 16, .avg_spt = 110, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Western Digital Caviar 33200", .internal_name = "WDAC33200", .model = "WDC AC33200LA", .zones = 16, .avg_spt = 110, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .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] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .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 }, // clang-format on From cd4e937291844c09960febe2a56f74497925e176 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Tue, 17 Dec 2024 15:36:51 +0700 Subject: [PATCH 13/52] Added the remaining 9 HDD models Also some changes/fixes to the configuration. --- src/disk/hdd.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index d44da0925..72b8b3a68 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -421,10 +421,15 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 }, { .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 }, { .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] 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 = 16 }, - { .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 = 16 }, + { .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] 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 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] 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 }, { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, @@ -437,8 +442,9 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 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] Western Digital Caviar 2850", .internal_name = "WDAC2850", .model = "WDC AC2850F", .zones = 4, .avg_spt = 115, .heads = 2, .rpm = 4500, .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 31200", .internal_name = "WDAC31200", .model = "WDC AC31200F", .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-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] 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 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] 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-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 }, @@ -446,9 +452,12 @@ static hdd_preset_t hdd_speed_presets[] = { { .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] 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] 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 33200", .internal_name = "WDAC33200", .model = "WDC AC33200LA", .zones = 16, .avg_spt = 110, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, - { .name = "[ATA-5] Samsung SpinPoint V6800", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 2, .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] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 8, .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-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] 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 }, // clang-format on }; From 90be6b1b2f3957c67d007ff3aabde84e32afe5f5 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Wed, 18 Dec 2024 16:22:11 +0700 Subject: [PATCH 14/52] Added the remaining HDD models -Removed the ESDI one since this is a pull request for HDD IDE models' addition -Added notes as well --- src/disk/hdd.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 72b8b3a68..e9d633387 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -415,26 +415,35 @@ static hdd_preset_t hdd_speed_presets[] = { { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ESDI] Fujitsu M2263E", .internal_name = "M2263E", .model = "FUJITSU M2263E", .zones = 1, .avg_spt = 160, .heads = 8, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 1 }, { .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "IBM-WDA-L42", .zones = 1, .avg_spt = 85, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 2.5, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 }, - { .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 }, - { .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 }, - { .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 }, + { .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] 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] 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] 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 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] 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 }, { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, // From Hardcore Windows NT Final Segment by Kugee + { .name = "[ATA-2] Quantum Fireball 640AT", .internal_name = "FB64A341", .model = "QUANTUM FIREBALL 640AT", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3.1, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Quantum Fireball TM1080AT", .internal_name = "TM10A462", .model = "QUANTUM FIREBALL TM1.0A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Quantum Fireball TM1.2AT", .internal_name = "TM12A012", .model = "QUANTUM FIREBALL TM1.2A", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Quantum Fireball ST3.2AT", .internal_name = "ST32A461", .model = "QUANTUM FIREBALL ST3.2A", .zones = 4, .avg_spt = 100, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Fireball EX5.1AT", .internal_name = "EX51A012", .model = "QUANTUM FIREBALL EX5.1A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, { .name = "[ATA-2] Samsung PLS-31274A", .internal_name = "PLS31274A", .model = "SAMSUNG PLS-31274A", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 45, .track_seek_ms = 4.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, { .name = "[ATA-2] Samsung Winner-1", .internal_name = "WNR31601A", .model = "SAMSUNG WNR-31601A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 }, @@ -442,22 +451,33 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 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] 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 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 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-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] 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] 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 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] 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] 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] 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 // clang-format on }; From f11ff443afc75b6f82e96e7dd71da96cf036738d Mon Sep 17 00:00:00 2001 From: rushieda <185547947+rushieda@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:11:46 +0300 Subject: [PATCH 15/52] Add the Compaq ProSignia S316/318 (Intel chipset) --- src/include/86box/machine.h | 1 + src/machine/m_at_socket370.c | 40 +++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 57bc7e533..d46e816ce 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -842,6 +842,7 @@ extern int machine_at_6via90ap_init(const machine_t *); extern int machine_at_s1857_init(const machine_t *); extern int machine_at_p6bap_init(const machine_t *); extern int machine_at_p6bat_init(const machine_t *); +extern int machine_at_prosignias31x_bx_init(const machine_t *); /* m_at_misc.c */ extern int machine_at_vpc2007_init(const machine_t *); diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 6d7b8c710..9be2d45b8 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -74,6 +74,46 @@ machine_at_s370slm_init(const machine_t *model) return ret; } +int +machine_at_prosignias31x_bx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/prosignias31x_bx/p6bxt-ap-092600.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_SOUND, 4, 3, 2, 1); /* assumed */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&winbond_flash_w29c020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */ + hwm_values.temperatures[0] += 2; /* System offset */ + hwm_values.temperatures[1] += 2; /* CPU offset */ + hwm_values.voltages[0] = 3300; /* Vcore and 3.3V are swapped */ + hwm_values.voltages[2] = hwm_get_vcore(); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + int machine_at_s1857_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 99bb44771..26997eb61 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -15130,6 +15130,47 @@ const machine_t machines[] = { /* Slot 1/Socket 370 machines */ /* 440BX */ + /* OEM version of ECS P6BXT-A+ REV 1.3x/2.2x. Has a Winbond W83977EF Super + I/O chip with on-chip KBC with AMIKey-2 KBC firmware.*/ + { + .name = "[i440BX] Compaq ProSignia S316/318 (Intel)", + .internal_name = "prosignias31x_bx", + .type = MACHINE_TYPE_SLOT1_370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .init = machine_at_prosignias31x_bx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1 | CPU_PKG_SOCKET370, + .block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_CYRIX3S), /* Instability issues with PPro, and garbled text in POST with Cyrix */ + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cmi8738_onboard_device, + .net_device = NULL + }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From 36016b6be0e6848349bd9c54ba7ef4dd91f6f392 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Tue, 31 Dec 2024 05:34:50 +0700 Subject: [PATCH 16/52] Update CY4320A model --- src/disk/hdd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index e9d633387..65b731340 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -437,7 +437,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 }, { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, - { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, // From Hardcore Windows NT Final Segment by Kugee + { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, // from Hardcore Windows NT Final Segment by Kugee { .name = "[ATA-2] Quantum Fireball 640AT", .internal_name = "FB64A341", .model = "QUANTUM FIREBALL 640AT", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3.1, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, { .name = "[ATA-2] Quantum Fireball TM1080AT", .internal_name = "TM10A462", .model = "QUANTUM FIREBALL TM1.0A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, { .name = "[ATA-2] Quantum Fireball TM1.2AT", .internal_name = "TM12A012", .model = "QUANTUM FIREBALL TM1.2A", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, From defeb47ca5bd071741edc2b66ad612abf5694aa3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 00:48:50 +0100 Subject: [PATCH 17/52] Switched from raw input to low-level keyboard hook, with -W/--raw to optionally re-enable raw input (needed to debug, so the hook doesn't cause GDB to make system input unusably slow), fixes #4399. --- src/86box.c | 4 + src/device/keyboard.c | 23 +++++- src/include/86box/86box.h | 1 + src/include/86box/keyboard.h | 9 ++- src/qt/qt_main.cpp | 137 ++++++++++++++++++++++++++++++++ src/qt/qt_winrawinputfilter.cpp | 89 +++------------------ src/qt/qt_winrawinputfilter.hpp | 3 - 7 files changed, 180 insertions(+), 86 deletions(-) diff --git a/src/86box.c b/src/86box.c index 5e1f58413..fc698a5ee 100644 --- a/src/86box.c +++ b/src/86box.c @@ -206,6 +206,7 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether also apply when maximized. */ int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus loss */ +int raw_input = 0; /* (C) Use raw input */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are @@ -561,6 +562,7 @@ usage: printf("-S or --settings - show only the settings dialog\n"); #endif printf("-V or --vmname name - overrides the name of the running VM\n"); + printf("-W or --raw - uses raw input (compatibility-only outside Windows)\n"); printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n"); printf("-Y or --donothing - do not show any UI or run the emulation\n"); printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); @@ -636,6 +638,8 @@ usage: dump_missing = 1; } else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) { do_nothing = 1; + } else if (!strcasecmp(argv[c], "--raw") || !strcasecmp(argv[c], "-W")) { + raw_input = 1; } else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) { if ((c + 1) == argc) goto usage; diff --git a/src/device/keyboard.c b/src/device/keyboard.c index ea81e7525..2eff2159b 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -29,7 +29,9 @@ #include "cpu.h" -int keyboard_scan; +uint16_t scancode_map[768] = { 0 }; + +int keyboard_scan; #ifdef _WIN32 /* Windows: F8+F12 */ @@ -386,3 +388,22 @@ keyboard_ismsexit(void) return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) && (recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2])); } + +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +uint16_t +convert_scan_code(uint16_t scan_code) +{ + if ((scan_code & 0xff00) == 0xe000) + scan_code = (scan_code & 0xff) | 0x0100; + + if (scan_code == 0xE11D) + scan_code = 0x0100; + /* E0 00 is sent by some USB keyboards for their special keys, as it is an + invalid scan code (it has no untranslated set 2 equivalent), we mark it + appropriately so it does not get passed through. */ + else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) + scan_code = 0xFFFF; + + return scan_code; +} diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 7d5709d30..fb4a182a0 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -165,6 +165,7 @@ extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */ #endif extern int pit_mode; /* (C) force setting PIT mode */ extern int fm_driver; /* (C) select FM sound driver */ +extern int raw_input; /* (C) Use raw input */ /* Keyboard variables for future key combination redefinition. */ extern uint16_t key_prefix_1_1; diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index f233637ff..225ab3936 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -194,8 +194,10 @@ typedef struct scancode { extern "C" { #endif -extern uint8_t keyboard_mode; -extern int keyboard_scan; +extern uint8_t keyboard_mode; +extern int keyboard_scan; + +extern uint16_t scancode_map[768]; extern void (*keyboard_send)(uint16_t val); extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)); @@ -288,6 +290,9 @@ extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); extern atkbc_dev_t *kbc_at_dev_init(uint8_t inst); +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +extern uint16_t convert_scan_code(uint16_t scan_code); #ifdef __cplusplus } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 3d32a4889..603099e68 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -47,6 +47,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) # include "qt_winmanagerfilter.hpp" # include <86box/win.h> # include +# include #endif extern "C" { @@ -81,6 +82,7 @@ extern QElapsedTimer elapsed_timer; extern MainWindow *main_window; extern "C" { +#include <86box/keyboard.h> #include <86box/timer.h> #include <86box/nvr.h> extern int qt_nvr_save(void); @@ -88,6 +90,122 @@ extern int qt_nvr_save(void); void qt_set_sequence_auto_mnemonic(bool b); +#ifdef Q_OS_WINDOWS +static void +keyboard_getkeymap() +{ + const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + const LPCSTR valueName = "Scancode Map"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; + + /* First, prepare the default scan code map list which is 1:1. + * Remappings will be inserted directly into it. + * 512 bytes so this takes less memory, bit 9 set means E0 + * prefix. + */ + for (j = 0; j < 512; j++) + scancode_map[j] = j; + + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + bufSize = 32768; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { + bufEx2 = (UINT32 *) buf; + scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) { + bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount * 2; j += 2) { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + scancode_unmapped = bufEx[j + 1]; + scancode_mapped = bufEx[j]; + + scancode_unmapped = convert_scan_code(scancode_unmapped); + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Ignore source scan codes with prefixes other than E1 + that are not E1 1D. */ + if (scancode_unmapped != 0xFFFF) + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +static LRESULT CALLBACK +emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; + /* Checks if CTRL was pressed. */ + BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); + uint16_t scancode = lpKdhs->scanCode & 0x00ff; + + if (lpKdhs->flags & LLKHF_EXTENDED) + scancode |= 0x100; + + /* Translate the scan code to 9-bit */ + scancode = convert_scan_code(scancode); + + /* Remap it according to the list from the Registry */ + if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { + // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); + scancode = scancode_map[scancode]; + } + + /* If it's not 0xFFFF, send it to the emulated + keyboard. + 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 + chosen. */ + if ((scancode == 0x11d) && rctrl_is_lalt) + scancode = 0x038; + + /* Normal scan code pass through, pass it through as is if + it's not an invalid scan code. */ + if (scancode != 0xFFFF) + keyboard_input(!(lpKdhs->flags & LLKHF_UP), scancode); + + main_window->checkFullscreenHotkey(); + + if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + return TRUE; + 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))) + return TRUE; + 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))) + return TRUE; + else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + return TRUE; + else if ((lpKdhs->scanCode == 0x51) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) + return TRUE; + else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) + return TRUE; + else + return CallNextHookEx(NULL, nCode, wParam, lParam); +} +#endif + void main_thread_fn() { @@ -165,6 +283,10 @@ main_thread_fn() static std::thread *main_thread; +#ifdef Q_OS_WINDOWS +static HHOOK llhook = NULL; +#endif + int main(int argc, char *argv[]) { @@ -176,6 +298,7 @@ main(int argc, char *argv[]) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif + QApplication app(argc, argv); QLocale::setDefault(QLocale::C); @@ -193,6 +316,13 @@ main(int argc, char *argv[]) #endif elapsed_timer.start(); + for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++) + scancode_map[i] = i; + +#ifdef Q_OS_WINDOWS + keyboard_getkeymap(); +#endif + if (!pc_init(argc, argv)) { return 0; } @@ -340,6 +470,13 @@ main(int argc, char *argv[]) }); } +#ifdef Q_OS_WINDOWS + if (!raw_input) { + llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); + atexit([] () -> void { if (llhook) UnhookWindowsHookEx(llhook); }); + } +#endif + /* Setup raw input */ auto rawInputFilter = WindowsRawInputFilter::Register(main_window); if (rawInputFilter) { diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 66d8ad8e5..4ff515c49 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -64,8 +64,10 @@ WindowsRawInputFilter::Register(MainWindow *window) .hwndTarget = nullptr} }; - if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) - return std::unique_ptr(nullptr); + if (raw_input && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)) + return std::unique_ptr(nullptr); + else if (!raw_input && RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE) + return std::unique_ptr(nullptr); std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); @@ -80,11 +82,6 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window) connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; }); connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; }); } - - for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++) - scancode_map[i] = i; - - keyboard_getkeymap(); } WindowsRawInputFilter::~WindowsRawInputFilter() @@ -100,7 +97,10 @@ WindowsRawInputFilter::~WindowsRawInputFilter() .hwndTarget = NULL} }; - RegisterRawInputDevices(rid, 2, sizeof(rid[0])); + if (raw_input) + RegisterRawInputDevices(rid, 2, sizeof(rid[0])); + else + RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])); } bool @@ -197,7 +197,7 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) /* Remap it according to the list from the Registry */ if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { - pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); + // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); scancode = scancode_map[scancode]; } @@ -221,77 +221,6 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) } } -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -UINT16 -WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) -{ - if ((scan_code & 0xff00) == 0xe000) - scan_code = (scan_code & 0xff) | 0x0100; - - if (scan_code == 0xE11D) - scan_code = 0x0100; - /* E0 00 is sent by some USB keyboards for their special keys, as it is an - invalid scan code (it has no untranslated set 2 equivalent), we mark it - appropriately so it does not get passed through. */ - else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) - scan_code = 0xFFFF; - - return scan_code; -} - -void -WindowsRawInputFilter::keyboard_getkeymap() -{ - const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - const LPCSTR valueName = "Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - UINT32 *bufEx2; - int scMapCount; - UINT16 *bufEx; - int scancode_unmapped; - int scancode_mapped; - - /* First, prepare the default scan code map list which is 1:1. - * Remappings will be inserted directly into it. - * 512 bytes so this takes less memory, bit 9 set means E0 - * prefix. - */ - for (j = 0; j < 512; j++) - scancode_map[j] = j; - - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - bufSize = 32768; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { - if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { - bufEx2 = (UINT32 *) buf; - scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) { - bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount * 2; j += 2) { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - scancode_unmapped = bufEx[j + 1]; - scancode_mapped = bufEx[j]; - - scancode_unmapped = convert_scan_code(scancode_unmapped); - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Ignore source scan codes with prefixes other than E1 - that are not E1 1D. */ - if (scancode_unmapped != 0xFFFF) - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) { diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index f687164ca..411f7841c 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -61,7 +61,6 @@ public: private: MainWindow *window; - uint16_t scancode_map[768]; int buttons = 0; int dx = 0; int dy = 0; @@ -73,8 +72,6 @@ private: void handle_input(HRAWINPUT input); void keyboard_handle(PRAWINPUT raw); void mouse_handle(PRAWINPUT raw); - static UINT16 convert_scan_code(UINT16 scan_code); - void keyboard_getkeymap(); }; #endif From a11712b6513162ebfbdd82a325b5609e6bcd4d00 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 03:27:21 +0100 Subject: [PATCH 18/52] Make the hook only run if it's either captured or full screen. --- src/qt/qt_main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 603099e68..1c4a932c7 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -151,6 +151,9 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); uint16_t scancode = lpKdhs->scanCode & 0x00ff; + if ((nCode < 0) || (nCode != HC_ACTION) || (!mouse_capture && !video_fullscreen)) + return CallNextHookEx(NULL, nCode, wParam, lParam); + if (lpKdhs->flags & LLKHF_EXTENDED) scancode |= 0x100; From 8b05c58fb9072a3bfbbd837ea722f228f355d6d7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 03:59:38 +0100 Subject: [PATCH 19/52] Switched to two hooks, so the emulator doesn't get the input from the entire host OS. --- src/qt/qt_main.cpp | 53 ++++++++++++++++++++++++++--------------- src/qt/qt_mediamenu.cpp | 10 ++++++-- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 1c4a932c7..097d503b7 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -144,16 +144,11 @@ keyboard_getkeymap() } static LRESULT CALLBACK -emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +input_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; - /* Checks if CTRL was pressed. */ - BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); uint16_t scancode = lpKdhs->scanCode & 0x00ff; - if ((nCode < 0) || (nCode != HC_ACTION) || (!mouse_capture && !video_fullscreen)) - return CallNextHookEx(NULL, nCode, wParam, lParam); - if (lpKdhs->flags & LLKHF_EXTENDED) scancode |= 0x100; @@ -184,7 +179,19 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) main_window->checkFullscreenHotkey(); - if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +static LRESULT CALLBACK +emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; + /* Checks if CTRL was pressed. */ + BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); + + 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))) return TRUE; else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) @@ -209,6 +216,11 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) } #endif +#ifdef Q_OS_WINDOWS +static HHOOK llhook = NULL; +static HHOOK llihook = NULL; +#endif + void main_thread_fn() { @@ -286,10 +298,6 @@ main_thread_fn() static std::thread *main_thread; -#ifdef Q_OS_WINDOWS -static HHOOK llhook = NULL; -#endif - int main(int argc, char *argv[]) { @@ -473,18 +481,12 @@ main(int argc, char *argv[]) }); } -#ifdef Q_OS_WINDOWS - if (!raw_input) { - llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); - atexit([] () -> void { if (llhook) UnhookWindowsHookEx(llhook); }); - } -#endif - /* Setup raw input */ auto rawInputFilter = WindowsRawInputFilter::Register(main_window); if (rawInputFilter) { app.installNativeEventFilter(rawInputFilter.get()); - main_window->setSendKeyboardInput(false); + if (raw_input) + main_window->setSendKeyboardInput(false); } #endif @@ -543,6 +545,19 @@ main(int argc, char *argv[]) plat_pause(0); }); +#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); + }); + } +#endif + const auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 1fa5283d2..902ca10d6 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -524,7 +524,8 @@ MediaMenu::cdromMute(int i) void MediaMenu::cdromMount(int i, const QString &filename) { - QByteArray fn = filename.toUtf8().data(); + QByteArray fn = filename.toUtf8().data(); + int was_empty = cdrom_is_empty(i); cdrom_exit(i); @@ -542,9 +543,14 @@ MediaMenu::cdromMount(int i, const QString &filename) cdrom_image_open(&(cdrom[i]), fn.data()); /* Signal media change to the emulated machine. */ - if (cdrom[i].insert) + if (cdrom[i].insert) { cdrom[i].insert(cdrom[i].priv); + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + cdrom[i].insert(cdrom[i].priv); + } + if (strlen(cdrom[i].image_path) > 0) ui_sb_update_icon_state(SB_CDROM | i, 0); else From 686384ce439bd906dd12a1ff914b0ab355c6846f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 04:05:20 +0100 Subject: [PATCH 20/52] Block Ctrl+Alt+PgUp, not Ctrl+Alt+PgDown. --- src/qt/win_cdrom_ioctl.c | 164 +++++++++++++++++++++++++++------------ 1 file changed, 115 insertions(+), 49 deletions(-) diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index ff65046a7..f89ec7412 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -72,12 +72,19 @@ win_cdrom_ioctl_log(const char *fmt, ...) # define win_cdrom_ioctl_log(fmt, ...) #endif +static void +plat_cdrom_close_handle(win_cdrom_ioctl_t *ioctl) +{ + if (ioctl->handle != NULL) + CloseHandle(ioctl->handle); +} + static int plat_cdrom_open(void *local) { win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; - plat_cdrom_close(local); + plat_cdrom_close_handle(local); ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); @@ -107,20 +114,47 @@ plat_cdrom_load(void *local) static int plat_cdrom_read_normal_toc(win_cdrom_ioctl_t *ioctl, uint8_t *toc_buf) { - long size = 0; + long size = 0; + PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL; memset(toc_buf, 0x00, 65536); + + cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536); + if (ioctl->blocks_num != 0) { + memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11); + ioctl->blocks_num = 0; + } + + ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC; + win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format); + ioctl->cur_read_toc_ex.Msf = 1; + ioctl->cur_read_toc_ex.SessionTrack = 0; + plat_cdrom_open(ioctl); - int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc_buf, 65535, (LPDWORD) &size, NULL); + int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535, + cur_full_toc, 65535, (LPDWORD) &size, NULL); plat_cdrom_close(ioctl); -#ifdef ENABLE_WIN_CDROM_IOCTL_LOG win_cdrom_ioctl_log("temp = %i\n", temp); + if (temp != 0) { + int length = ((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) + 2; + memcpy(toc_buf, cur_full_toc, length); + } + + free(cur_full_toc); + +#ifdef ENABLE_WIN_CDROM_IOCTL_LOG PCDROM_TOC toc = (PCDROM_TOC) toc_buf; const int tracks_num = (((toc->Length[0] << 8) | toc->Length[1]) - 2) / 8; - win_cdrom_ioctl_log("%i tracks\n", tracks_num); - for (int i = 0; i < tracks_num; i++) - win_cdrom_ioctl_log("Track %03i: Point %02X\n", i, (int) toc->TrackData[i].TrackNumber); + + win_cdrom_ioctl_log("%i tracks: %02X %02X %02X %02X\n", + tracks_num, toc_buf[0], toc_buf[1], toc_buf[2], toc_buf[3]); + + for (int i = 0; i < tracks_num; i++) { + uint8_t *t = (uint8_t *) &toc->TrackData[i]; + win_cdrom_ioctl_log("Track %03i: %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]); + } #endif return temp; @@ -130,10 +164,10 @@ static void plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl) { long size = 0; - int status; PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL; memset(ioctl->cur_rti, 0x00, 65536); + cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536); if (ioctl->blocks_num != 0) { memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11); @@ -143,11 +177,11 @@ plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl) ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC; win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format); ioctl->cur_read_toc_ex.Msf = 1; - ioctl->cur_read_toc_ex.SessionTrack = 1; + ioctl->cur_read_toc_ex.SessionTrack = 0; plat_cdrom_open(ioctl); - status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535, - cur_full_toc, 65535, (LPDWORD) &size, NULL); + int status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535, + cur_full_toc, 65535, (LPDWORD) &size, NULL); plat_cdrom_close(ioctl); win_cdrom_ioctl_log("status = %i\n", status); @@ -156,15 +190,21 @@ plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl) memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11); } - free(cur_full_toc); - #ifdef ENABLE_WIN_CDROM_IOCTL_LOG - win_cdrom_ioctl_log("%i blocks\n", ioctl->blocks_num); + uint8_t *u = (uint8_t *) cur_full_toc; + + win_cdrom_ioctl_log("%i blocks: %02X %02X %02X %02X\n", + ioctl->blocks_num, u[0], u[1], u[2], u[3]); raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti; - for (int i = 0; i < ioctl->blocks_num; i++) - win_cdrom_ioctl_log("Block %03i: Session %03i, Point %02X\n", i, (int) rti[i].session, (int) rti[i].point); + for (int i = 0; i < ioctl->blocks_num; i++) { + uint8_t *t = (uint8_t *) &rti[i]; + win_cdrom_ioctl_log("Block %03i: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10]); + } #endif + + free(cur_full_toc); } void @@ -206,7 +246,7 @@ plat_cdrom_is_track_audio(void *local, uint32_t sector) win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c, - cur_td->Control, track_addr, sector); + cur_td->Control, cur_addr, sector); if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) && (sector >= cur_addr) && (sector < next_addr)) { @@ -343,9 +383,14 @@ plat_cdrom_ext_medium_changed(void *local) memcpy(toc, new_toc, 65535); if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0) memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path)); - } else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3)) + } else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3)) { /* The TOC has changed. */ + ioctl->toc_valid = 1; + memcpy(toc, new_toc, 65535); + if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0) + memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path)); ret = 1; + } win_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); @@ -458,38 +503,61 @@ plat_cdrom_get_sector_size(void *local, UNUSED(uint32_t sector)) } int -plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector) +plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector) { - win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local; - int status; - long size = 0; - int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + typedef struct SCSI_PASS_THROUGH_DIRECT_BUF { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR SenseBuf[32]; + } SCSI_PASS_THROUGH_DIRECT_BUF; + + win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local; + int sc_offs = (sector == 0xffffffff) ? 0 : 2352; + unsigned long int unused = 0; + int ret; + SCSI_PASS_THROUGH_DIRECT_BUF req; + + memset(&req, 0x00, sizeof(req)); + req.Filler = 0; + req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + req.spt.CdbLength = 12; + req.spt.DataIn = SCSI_IOCTL_DATA_IN; + req.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_BUF, SenseBuf); + req.spt.SenseInfoLength = sizeof(req.SenseBuf); + req.spt.TimeOutValue = 6; + req.spt.DataTransferLength = 2368; + req.spt.DataBuffer = buffer; + + /* Fill in the CDB. */ + req.spt.Cdb[0] = 0xbe; /* READ CD */ + req.spt.Cdb[1] = 0x00; /* DAP = 0, Any Sector Type. */ + req.spt.Cdb[2] = (sector >> 24) & 0xff; + req.spt.Cdb[3] = (sector >> 16) & 0xff; + req.spt.Cdb[4] = (sector >> 8) & 0xff; + req.spt.Cdb[5] = sector & 0xff; /* Starting Logical Block Address. */ + req.spt.Cdb[6] = 0x00; + req.spt.Cdb[7] = 0x00; + req.spt.Cdb[8] = 0x01; /* Transfer Length. */ + /* If sector is FFFFFFFF, only return the subchannel. */ + req.spt.Cdb[9] = (sector == 0xffffffff) ? 0x00 : 0xf8; + req.spt.Cdb[10] = 0x02; + req.spt.Cdb[11] = 0x00; plat_cdrom_open(ioctl); - - if (raw) { - /* Raw */ - win_cdrom_ioctl_log("Raw\n"); - RAW_READ_INFO in; - in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), - buffer, buflen, (LPDWORD) &size, NULL); - } else { - /* Cooked */ - win_cdrom_ioctl_log("Cooked\n"); - int success = 0; - DWORD newPos = SetFilePointer(ioctl->handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); - if (newPos != 0xFFFFFFFF) - success = ReadFile(ioctl->handle, buffer, buflen, (LPDWORD) &size, NULL); - status = (success != 0); - } + ret = DeviceIoControl(ioctl->handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, &req, sizeof(req), &req, sizeof(req), + &unused, NULL); plat_cdrom_close(ioctl); - win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); - return (status > 0) ? (size == buflen) : -1; + /* Construct raw subchannel data from Q only. */ + if (ret && (req.spt.DataTransferLength >= 2368)) + for (int i = 11; i >= 0; i--) + for (int j = 7; j >= 0; j--) + buffer[2352 + (i * 8) + j] = ((buffer[sc_offs + i] >> (7 - j)) & 0x01) << 6; + + win_cdrom_ioctl_log("plat_cdrom_read_scsi_direct: ret = %d, req.spt.DataTransferLength = %lu\n", + ret, req.spt.DataTransferLength); + win_cdrom_ioctl_log("Sense: %08X, %08X\n", req.spt.SenseInfoLength, req.spt.SenseInfoOffset); + return ret && (req.spt.DataTransferLength >= 2368); } void @@ -508,10 +576,8 @@ plat_cdrom_close(void *local) { win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; - if (ioctl->handle != NULL) { - CloseHandle(ioctl->handle); - ioctl->handle = NULL; - } + plat_cdrom_close_handle(ioctl); + ioctl->handle = NULL; } int From f8930ea20784313bd461965045932df8ed94c36b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 04:05:51 +0100 Subject: [PATCH 21/52] Actually commit the correct file and pray God it will compile. --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 097d503b7..2d9d4e095 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -207,7 +207,7 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) return TRUE; - else if ((lpKdhs->scanCode == 0x51) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) + else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) return TRUE; else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) return TRUE; From 8791e5b2270b212532103b3965e394fe97e09ff6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 04:30:42 +0100 Subject: [PATCH 22/52] Make sure the blocked combinations are only blocked from the host, not the guest. --- src/qt/qt_main.cpp | 51 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 2d9d4e095..d18894bf6 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -143,13 +143,10 @@ keyboard_getkeymap() } } -static LRESULT CALLBACK -input_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +static void +kbd_handle(uint16_t scancode, uint16_t flags) { - LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; - uint16_t scancode = lpKdhs->scanCode & 0x00ff; - - if (lpKdhs->flags & LLKHF_EXTENDED) + if (flags & LLKHF_EXTENDED) scancode |= 0x100; /* Translate the scan code to 9-bit */ @@ -175,7 +172,15 @@ input_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) /* Normal scan code pass through, pass it through as is if it's not an invalid scan code. */ if (scancode != 0xFFFF) - keyboard_input(!(lpKdhs->flags & LLKHF_UP), scancode); + 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(); @@ -192,26 +197,34 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 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))) + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + } else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + } else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + } else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + } else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + } else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) + } else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) + } else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) { + kbd_handle(lpKdhs->scanCode & 0x00ff, lpKdhs->flags); return TRUE; - else + } else return CallNextHookEx(NULL, nCode, wParam, lParam); } #endif From 7b6a9181c6beca79c3b4a0109823c5b70289b03e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 04:37:21 +0100 Subject: [PATCH 23/52] Current state of the CD-ROM node - no CUE/BIN overhaul or MDS/MDF support yet, but the rest is already there. --- src/cdrom/cdrom.c | 1151 ++++----- src/cdrom/cdrom_image.c | 41 +- src/cdrom/cdrom_image_backend.c | 396 +++- src/cdrom/cdrom_ioctl.c | 24 +- src/include/86box/cdrom.h | 68 +- src/include/86box/cdrom_image_backend.h | 25 +- src/include/86box/mo.h | 14 +- src/include/86box/plat_cdrom.h | 2 +- src/include/86box/scsi_cdrom.h | 16 +- src/include/86box/scsi_device.h | 36 +- src/include/86box/scsi_disk.h | 13 +- src/include/86box/zip.h | 13 +- src/qt/dummy_cdrom_ioctl.c | 10 +- src/scsi/scsi_cdrom.c | 2834 +++++++++++------------ src/unix/dummy_cdrom_ioctl.c | 10 +- 15 files changed, 2423 insertions(+), 2230 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 0bdcb5fb8..784b84a39 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -443,7 +443,7 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) int ret = 1; if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) { - cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id); + // cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id); if (dev->cd_status == CD_STATUS_PLAYING) dev->seek_pos += (len >> 11); memset(output, 0, len * 2); @@ -452,25 +452,25 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) while (dev->cd_buflen < len) { if (dev->seek_pos < dev->cd_end) { - if (dev->ops->read_sector(dev, CD_READ_AUDIO, (uint8_t *) &(dev->cd_buffer[dev->cd_buflen]), - dev->seek_pos)) { + if (dev->ops->read_sector(dev, (uint8_t *) &(dev->cd_buffer[dev->cd_buflen]), dev->seek_pos)) { cdrom_log("CD-ROM %i: Read LBA %08X successful\n", dev->id, dev->seek_pos); + memcpy(dev->subch_buffer, ((uint8_t *) &(dev->cd_buffer[dev->cd_buflen])) + 2352, 96); dev->seek_pos++; dev->cd_buflen += (RAW_SECTOR_SIZE / 2); ret = 1; } else { cdrom_log("CD-ROM %i: Read LBA %08X failed\n", dev->id, dev->seek_pos); memset(&(dev->cd_buffer[dev->cd_buflen]), 0x00, (BUF_SIZE - dev->cd_buflen) * 2); - dev->cd_status = CD_STATUS_STOPPED; - dev->cd_buflen = len; - ret = 0; + dev->cd_status = CD_STATUS_STOPPED; + dev->cd_buflen = len; + ret = 0; } } else { cdrom_log("CD-ROM %i: Playing completed\n", dev->id); memset(&dev->cd_buffer[dev->cd_buflen], 0x00, (BUF_SIZE - dev->cd_buflen) * 2); - dev->cd_status = CD_STATUS_PLAYING_COMPLETED; - dev->cd_buflen = len; - ret = 0; + dev->cd_status = CD_STATUS_PLAYING_COMPLETED; + dev->cd_buflen = len; + ret = 0; } } @@ -792,18 +792,60 @@ cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume) dev->cd_status = (dev->cd_status & 0xfe) | (resume & 0x01); } +static void +cdrom_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc, int cooked) +{ + uint8_t *scb = dev->subch_buffer; + uint8_t q[16] = { 0 }; + + if ((lba == dev->seek_pos) && (dev->cd_status == CD_STATUS_PLAYING)) { + for (int i = 0; i < 12; i++) + for (int j = 0; j < 8; j++) + q[i] |= ((scb[(i << 3) + j] >> 6) & 0x01) << (7 - j); + + if (cooked) { + uint8_t temp = (q[0] >> 4) | ((q[0] & 0xf) << 4); + q[0] = temp; + + for (int i = 1; i < 10; i++) { + temp = bcd2bin(q[i]); + q[i] = temp; + } + } + + subc->attr = q[0]; + subc->track = q[1]; + subc->index = q[2]; + subc->rel_m = q[3]; + subc->rel_s = q[4]; + subc->rel_f = q[5]; + subc->abs_m = q[7]; + subc->abs_s = q[8]; + subc->abs_f = q[9]; + } else if ((dev->ops != NULL) && (dev->ops->get_subchannel != NULL)) { + dev->ops->get_subchannel(dev, lba, subc); + + if (!cooked) { + uint8_t temp = (q[0] >> 4) | ((q[0] & 0xf) << 4); + q[0] = temp; + + subc->attr = (subc->attr >> 4) | ((subc->attr & 0xf) << 4); + subc->track = bin2bcd(subc->track); + subc->index = bin2bcd(subc->index); + subc->rel_m = bin2bcd(subc->rel_m); + subc->rel_s = bin2bcd(subc->rel_s); + subc->rel_f = bin2bcd(subc->rel_f); + subc->abs_m = bin2bcd(subc->abs_m); + subc->abs_s = bin2bcd(subc->abs_s); + subc->abs_f = bin2bcd(subc->abs_f); + } + } +} + uint8_t -cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) +cdrom_get_current_status(cdrom_t *dev) { uint8_t ret; - subchannel_t subc; - int pos = 1; - int m; - int s; - int f; - uint32_t dat; - - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); if (dev->cd_status == CD_STATUS_DATA_ONLY) ret = 0x15; @@ -816,78 +858,103 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) ret = 0x13; } - cdrom_log("CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, relative at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, ret, dev->seek_pos, dev->cd_end); - - if (b[pos] > 1) { - cdrom_log("B[%i] = %02x, ret = %02x.\n", pos, b[pos], ret); - return ret; - } - - b[pos++] = subc.attr; - b[pos++] = subc.track; - b[pos++] = subc.index; - - if (msf) { - b[pos] = 0; - - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = subc.abs_m; - s = subc.abs_s; - f = subc.abs_f; - msf_to_bcd(&m, &s, &f); - b[pos + 1] = m; - b[pos + 2] = s; - b[pos + 3] = f; - } else { - b[pos + 1] = subc.abs_m; - b[pos + 2] = subc.abs_s; - b[pos + 3] = subc.abs_f; - } - - pos += 4; - - b[pos] = 0; - - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = subc.rel_m; - s = subc.rel_s; - f = subc.rel_f; - msf_to_bcd(&m, &s, &f); - b[pos + 1] = m; - b[pos + 2] = s; - b[pos + 3] = f; - } else { - b[pos + 1] = subc.rel_m; - b[pos + 2] = subc.rel_s; - b[pos + 3] = subc.rel_f; - } - - pos += 4; - } else { - dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - } - return ret; } +void +cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) +{ + subchannel_t subc; + uint32_t dat; + + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 1); + + cdrom_log("CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, " + "relative at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x.\n", + dev->id, subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, + dev->seek_pos, dev->cd_end); + + /* Format code. */ + switch (b[0]) { + /* Mode 0 = Q subchannel mode, first 16 bytes are indentical to mode 1 (current position), + the rest are stuff like ISRC etc., which can be all zeroes. */ + case 0x01: + /* Current position. */ + b[1] = subc.attr; + b[2] = subc.track; + b[3] = subc.index; + + if (msf) { + b[4] = b[8] = 0x00; + + /* NEC CDR-260 speaks BCD. */ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { + /* NEC */ + b[5] = bin2bcd(subc.abs_m); + b[6] = bin2bcd(subc.abs_s); + b[7] = bin2bcd(subc.abs_f); + + b[9] = bin2bcd(subc.rel_m); + b[10] = bin2bcd(subc.rel_s); + b[11] = bin2bcd(subc.rel_f); + } else { + b[5] = subc.abs_m; + b[6] = subc.abs_s; + b[7] = subc.abs_f; + + b[9] = subc.rel_m; + b[10] = subc.rel_s; + b[11] = subc.rel_f; + } + } else { + dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; + b[4] = (dat >> 24) & 0xff; + b[5] = (dat >> 16) & 0xff; + b[6] = (dat >> 8) & 0xff; + b[7] = dat & 0xff; + + dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); + b[8] = (dat >> 24) & 0xff; + b[9] = (dat >> 16) & 0xff; + b[10] = (dat >> 8) & 0xff; + b[11] = dat & 0xff; + } + break; + case 0x02: + /* UPC - TODO: Finding and reporting the actual UPC data. */ + memset(&(b[1]), 0x00, 19); + memset(&(b[5]), 0x30, 13); + /* NEC CDR-260 speaks BCD. */ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) + /* NEC */ + b[19] = bin2bcd(subc.abs_f); + else + b[19] = subc.abs_f; + break; + case 0x03: + /* ISRC - TODO: Finding and reporting the actual ISRC data. */ + memset(&(b[1]), 0x00, 19); + memset(&(b[5]), 0x30, 12); + /* NEC CDR-260 speaks BCD. */ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) + /* NEC */ + b[18] = bin2bcd(subc.abs_f); + else + b[18] = subc.abs_f; + break; + default: + cdrom_log("b[0] = %02X\n", b[0]); + break; + } +} + void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf) { subchannel_t subc; uint32_t dat; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 1); cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x, msf = %x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end, msf); @@ -920,7 +987,7 @@ cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b) uint8_t ret; subchannel_t subc; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 0); if (dev->cd_status == CD_STATUS_DATA_ONLY) ret = 0x05; @@ -934,9 +1001,9 @@ cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b) } b[0] = 0; - b[1] = bin2bcd(subc.abs_m); - b[2] = bin2bcd(subc.abs_s); - b[3] = bin2bcd(subc.abs_f); + b[1] = subc.abs_m; + b[2] = subc.abs_s; + b[3] = subc.abs_f; return ret; } @@ -948,7 +1015,7 @@ cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) subchannel_t subc; uint32_t dat; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 1); if (dev->cd_status == CD_STATUS_DATA_ONLY) ret = 0x05; @@ -982,26 +1049,25 @@ cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b) { subchannel_t subc; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 0); b[0] = subc.attr; - b[1] = bin2bcd(subc.track); - b[2] = bin2bcd(subc.index); - b[3] = bin2bcd(subc.rel_m); - b[4] = bin2bcd(subc.rel_s); - b[5] = bin2bcd(subc.rel_f); - b[6] = bin2bcd(subc.abs_m); - b[7] = bin2bcd(subc.abs_s); - b[8] = bin2bcd(subc.abs_f); + b[1] = subc.track; + b[2] = subc.index; + b[3] = subc.rel_m; + b[4] = subc.rel_s; + b[5] = subc.rel_f; + b[6] = subc.abs_m; + b[7] = subc.abs_s; + b[8] = subc.abs_f; } uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) { uint8_t ret; - subchannel_t subc; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_current_subcodeq(dev, b); if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED) || @@ -1014,100 +1080,166 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) if (dev->ops->track_type(dev, dev->seek_pos) & CD_TRACK_AUDIO) dev->audio_muted_soft = 0; - cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", dev->seek_pos, dev->cd_end, dev->audio_muted_soft); - b[0] = subc.attr; - b[1] = bin2bcd(subc.track); - b[2] = bin2bcd(subc.index); - b[3] = bin2bcd(subc.rel_m); - b[4] = bin2bcd(subc.rel_s); - b[5] = bin2bcd(subc.rel_f); - b[6] = bin2bcd(subc.abs_m); - b[7] = bin2bcd(subc.abs_s); - b[8] = bin2bcd(subc.abs_f); + cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", + dev->seek_pos, dev->cd_end, dev->audio_muted_soft); + return ret; +} + +static void +read_toc_identify_sessions(raw_track_info_t *rti, int num, unsigned char *b) +{ + /* Bytes 2 and 3 = Number of first and last sessions */ + b[2] = 0xff; + b[3] = 0x00; + + for (int i = (num - 1); i >= 0; i--) { + if (rti[i].session < b[2]) + b[2] = rti[i].session; + } + + for (int i = 0; i < num; i++) { + if (rti[i].session > b[3]) + b[3] = rti[i].session; + } +} + +static int +find_track(raw_track_info_t *trti, int num, int first) +{ + int ret = -1; + + if (first) { + for (int i = 0; i < num; i++) + if ((trti[i].point >= 1) && (trti[i].point <= 99)) { + ret = i; + break; + } + } else { + for (int i = (num - 1); i >= 0; i--) + if ((trti[i].point >= 1) && (trti[i].point <= 99)) { + ret = i; + break; + } + } + return ret; } static int -read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf) +find_last_lead_out(raw_track_info_t *trti, int num) { - track_info_t ti; - int i; - int len = 4; - int m; - int s; - int f; - int first_track; - int last_track; - uint32_t temp; + int ret = -1; - cdrom_log("read_toc_normal(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf); + for (int i = (num - 1); i >= 0; i--) + if (trti[i].point == 0xa2) { + ret = i; + break; + } - dev->ops->get_tracks(dev, &first_track, &last_track); + return ret; +} - /* Byte 2 = Number of the first track */ - dev->ops->get_track_info(dev, 1, 0, &ti); - b[2] = ti.number; - cdrom_log(" b[2] = %02X\n", b[2]); +static int +find_specific_track(raw_track_info_t *trti, int num, int track) +{ + int ret = -1; - /* Byte 3 = Number of the last track before the lead-out track */ - dev->ops->get_track_info(dev, last_track, 0, &ti); - b[3] = ti.number; - cdrom_log(" b[3] = %02X\n", b[2]); + if ((track >= 1) && (track <= 99)) { + for (int i = (num - 1); i >= 0; i--) + if (trti[i].point == track) { + ret = i; + break; + } + } - if (start_track == 0x00) - first_track = 0; - else { - first_track = -1; - for (i = 0; i <= last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); - if (ti.number >= start_track) { - first_track = i; + return ret; +} + +static int +read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf, int sony) +{ + uint8_t rti[65536] = { 0 }; + uint8_t prti[65536] = { 0 }; + raw_track_info_t *trti = (raw_track_info_t *) rti; + raw_track_info_t *tprti = (raw_track_info_t *) prti; + int num = 0; + int len = 4; + int s = -1; + + cdrom_log("read_toc_normal(%016" PRIXPTR ", %016" PRIXPTR ", %02X, %i)\n", + (uintptr_t) dev, (uintptr_t) b, start_track, msf, sony); + + dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); + + if (num > 0) { + int j = 0; + for (int i = 0; i < num; i++) { + if ((trti[i].point >= 0x01) && (trti[i].point <= 0x63)) { + tprti[j] = trti[i]; + if ((s == -1) && (tprti[j].point >= start_track)) + s = j; + cdrom_log("Sorted %03i = Unsorted %03i (s = %03i)\n", j, i, s); + j++; + } + } + + /* Bytes 2 and 3 = Number of first and last tracks found before lead out */ + b[2] = tprti[0].point; + b[3] = tprti[j - 1].point; + + for (int i = (num - 1); i >= 0; i--) { + if (trti[i].point == 0xa2) { + tprti[j] = trti[i]; + tprti[j].point = 0xaa; + if ((s == -1) && (tprti[j].point >= start_track)) + s = j; + cdrom_log("Sorted %03i = Unsorted %03i (s = %03i)\n", j, i, s); + j++; break; } } - } - cdrom_log(" first_track = %i, last_track = %i\n", first_track, last_track); - /* No suitable starting track, return with error. */ - if (first_track == -1) { - cdrom_log(" [ERROR] No suitable track found\n"); - return -1; - } + if (s != -1) for (int i = s; i < j; i++) { + uint8_t *c = &(b[len]); - for (i = first_track; i <= last_track; i++) { - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - dev->ops->get_track_info(dev, i + 1, 0, &ti); + if (!sony) + b[len++] = 0; /* Reserved */ + b[len++] = tprti[i].adr_ctl; /* ADR/CTL */ + b[len++] = tprti[i].point; /* Track number */ + if (!sony) + b[len++] = 0; /* Reserved */ - b[len++] = 0; /* reserved */ - b[len++] = ti.attr; - b[len++] = ti.number; /* track number */ - b[len++] = 0; /* reserved */ + if (msf) { + b[len++] = 0; - if (msf) { - b[len++] = 0; - - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[len++] = m; - b[len++] = s; - b[len++] = f; + /* NEC CDR-260 speaks BCD. */ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { + int m = tprti[i].pm; + int s = tprti[i].ps; + int f = tprti[i].pf; + msf_to_bcd(&m, &s, &f); + b[len++] = m; + b[len++] = s; + b[len++] = f; + } else { + b[len++] = tprti[i].pm; + b[len++] = tprti[i].ps; + b[len++] = tprti[i].pf; + } } else { - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; + uint32_t temp = MSFtoLBA(tprti[i].pm, tprti[i].ps, tprti[i].pf) - 150; + + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; } - } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; + + cdrom_log("Track %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]); } - } + } else + b[2] = b[3] = 0; return len; } @@ -1115,229 +1247,89 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m static int read_toc_session(cdrom_t *dev, unsigned char *b, int msf) { - track_info_t ti; - int len = 4; - int m; - int s; - int f; - uint32_t temp; + uint8_t rti[65536] = { 0 }; + raw_track_info_t *t = (raw_track_info_t *) rti; + raw_track_info_t *first = NULL; + int num = 0; + int len = 4; - cdrom_log("read_toc_session(%08X, %08X, %i)\n", dev, b, msf); + dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); /* Bytes 2 and 3 = Number of first and last sessions */ - b[2] = b[3] = 1; + read_toc_identify_sessions((raw_track_info_t *) rti, num, b); - dev->ops->get_track_info(dev, 1, 0, &ti); + cdrom_log("read_toc_session(%016" PRIXPTR ", %016" PRIXPTR ", %i)\n", + (uintptr_t) dev, (uintptr_t) b, msf); - cdrom_log(" tracks(0) = %02X, %02X, %i:%02i.%02i\n", ti.attr, ti.number, ti.m, ti.s, ti.f); - - b[len++] = 0; /* reserved */ - b[len++] = ti.attr; - b[len++] = ti.number; /* track number */ - b[len++] = 0; /* reserved */ - - if (msf) { - b[len++] = 0; - - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[len++] = m; - b[len++] = s; - b[len++] = f; - } else { - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; + if (num != 0) { + for (int i = 0; i < num; i++) if ((t[i].session == b[3]) && (t[i].point >= 0x01) && (t[i].point <= 0x63)) { + first = &(t[i]); + break; } - } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } + if (first != NULL) { + b[len++] = 0x00; + b[len++] = first->adr_ctl; + b[len++] = first->point; + b[len++] = 0x00; - return len; -} + if (msf) { + b[len++] = 0x00; -static int -read_toc_raw(cdrom_t *dev, unsigned char *b) -{ - track_info_t ti; - raw_track_info_t rti[256] = { 0 }; - int num = 0; - int len = 4; - int first_track; - int last_track; + /* NEC CDR-260 speaks BCD. */ + if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ + int m = first->pm; + int s = first->ps; + int f = first->pf; - /* Bytes 2 and 3 = Number of first and last sessions */ - b[2] = b[3] = 1; + msf_to_bcd(&m, &s, &f); - if (dev->ops->get_raw_track_info != NULL) { - cdrom_log("read_toc_raw(%08X, %08X): Raw tracks\n", dev, b); - pclog("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR "): Raw tracks\n", - (uintptr_t) dev, (uintptr_t) b); + b[len++] = m; + b[len++] = s; + b[len++] = f; + } else { + b[len++] = first->pm; + b[len++] = first->ps; + b[len++] = first->pf; + } + } else { + uint32_t temp = MSFtoLBA(first->pm, first->ps, first->pf) - 150; - dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); - - if (num != 0) for (int i = 0; i < num; i++) { - b[len++] = rti[i].session; - b[len++] = rti[i].adr_ctl; - b[len++] = rti[i].tno; - b[len++] = rti[i].point; - b[len++] = rti[i].m; - b[len++] = rti[i].s; - b[len++] = rti[i].f; - b[len++] = rti[i].zero; - b[len++] = rti[i].pm; - b[len++] = rti[i].ps; - b[len++] = rti[i].pf; - } - } else { - cdrom_log("read_toc_raw(%08X, %08X): Cooked tracks\n", dev, b); - pclog("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR "): Cooked tracks\n", - (uintptr_t) dev, (uintptr_t) b); - - dev->ops->get_tracks(dev, &first_track, &last_track); - - dev->ops->get_track_info(dev, 1, 0, &ti); - - b[len++] = 1; /* Session number */ - b[len++] = ti.attr; /* Track ADR and Control */ - b[len++] = 0; /* TNO (always 0) */ - b[len++] = 0xA0; /* Point (for track points - track number) */ - /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = ti.number; /* First track number */ - b[len++] = 0; - b[len++] = 0; - - dev->ops->get_track_info(dev, last_track, 0, &ti); - - b[len++] = 1; /* Session number */ - b[len++] = ti.attr; /* Track ADR and Control */ - b[len++] = 0; /* TNO (always 0) */ - b[len++] = 0xA1; /* Point (for track points - track number) */ - /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = ti.number; /* First track number */ - b[len++] = 0; - b[len++] = 0; - - dev->ops->get_track_info(dev, last_track + 1, 0, &ti); - - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - - b[len++] = 1; /* Session number */ - b[len++] = ti.attr; /* Track ADR and Control */ - b[len++] = 0; /* TNO (always 0) */ - b[len++] = 0xA2; /* Point (for track points - track number) */ - /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = ti.m; /* PM */ - b[len++] = ti.s; /* PS */ - b[len++] = ti.f; /* PF */ - - for (int i = 0; i < last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); - - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - - b[len++] = 1; /* Session number */ - b[len++] = ti.attr; /* Track ADR and Control */ - b[len++] = 0; /* TNO (always 0) */ - b[len++] = ti.number; /* Point (for track points - track number) */ - /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = ti.m; /* PM */ - b[len++] = ti.s; /* PS */ - b[len++] = ti.f; /* PF */ - } - } - - return len; -} - -static int -read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf) -{ - track_info_t ti; - int i; - int len = 4; - int first_track; - int last_track; - uint32_t temp; - - cdrom_log("read_toc_sony(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf); - - dev->ops->get_tracks(dev, &first_track, &last_track); - - /* Byte 2 = Number of the first track */ - dev->ops->get_track_info(dev, 1, 0, &ti); - b[2] = ti.number; - cdrom_log(" b[2] = %02X\n", b[2]); - - /* Byte 3 = Number of the last track before the lead-out track */ - dev->ops->get_track_info(dev, last_track, 0, &ti); - b[3] = ti.number; - cdrom_log(" b[3] = %02X\n", b[2]); - - if (start_track == 0x00) - first_track = 0; - else { - first_track = -1; - for (i = 0; i <= last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); - if (ti.number >= start_track) { - first_track = i; - break; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; } } } - cdrom_log(" first_track = %i, last_track = %i\n", first_track, last_track); - /* No suitable starting track, return with error. */ - if (first_track == -1) { - cdrom_log(" [ERROR] No suitable track found\n"); - return -1; - } + if (len == 4) + memset(&(b[len += 8]), 0x00, 8); - for (i = first_track; i <= last_track; i++) { - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - dev->ops->get_track_info(dev, i + 1, 0, &ti); + return len; +} - b[len++] = ti.number; /* track number */ - b[len++] = ti.attr; +static int +read_toc_raw(cdrom_t *dev, unsigned char *b, unsigned char start_track) +{ + uint8_t rti[65536] = { 0 }; + raw_track_info_t *t = (raw_track_info_t *) rti; + int num = 0; + int len = 4; - if (msf) { - b[len++] = 0; - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; - } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; + /* Bytes 2 and 3 = Number of first and last sessions */ + read_toc_identify_sessions((raw_track_info_t *) rti, num, b); + + cdrom_log("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR ", %02X)\n", + (uintptr_t) dev, (uintptr_t) b, start_track); + + dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); + + if (num != 0) for (int i = 0; i < num; i++) + if (t[i].session >= start_track) { + memcpy(&(b[len]), &(t[i]), 11); + len += 11; } - } + return len; } @@ -1348,13 +1340,13 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra switch (type) { case CD_TOC_NORMAL: - len = read_toc_normal(dev, b, start_track, msf); + len = read_toc_normal(dev, b, start_track, msf, 0); break; case CD_TOC_SESSION: len = read_toc_session(dev, b, msf); break; case CD_TOC_RAW: - len = read_toc_raw(dev, b); + len = read_toc_raw(dev, b, start_track); break; default: cdrom_log("CD-ROM %i: Unknown TOC read type: %i\n", dev->id, type); @@ -1374,7 +1366,7 @@ cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, i { int len; - len = read_toc_sony(dev, b, start_track, msf); + len = read_toc_normal(dev, b, start_track, msf, 1); len = MIN(len, max_len); @@ -1384,29 +1376,50 @@ cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, i return len; } +#ifdef USE_CDROM_MITSUMI /* New API calls for Mitsumi CD-ROM. */ void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf) { - track_info_t ti; - int first_track; - int last_track; + uint8_t rti[65536] = { 0 }; + raw_track_info_t *trti = (raw_track_info_t *) rti; + int num = 0; + int first = -1; + int last = -1; - if (dev != NULL) { - dev->ops->get_tracks(dev, &first_track, &last_track); - buf[0] = 1; - buf[1] = last_track + 1; - dev->ops->get_track_info(dev, 1, 0, &ti); - buf[2] = ti.m; - buf[3] = ti.s; - buf[4] = ti.f; - dev->ops->get_track_info(dev, last_track + 1, 0, &ti); - buf[5] = ti.m; - buf[6] = ti.s; - buf[7] = ti.f; - buf[8] = 0x00; - } else - memset(buf, 0x00, 9); + if (dev != NULL) + dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); + + if (num > 0) { + first = find_track(trti, num, 1); + last = find_track(trti, num, 0); + } + + if (first != -1) { + buf[0] = trti[first].point; + buf[2] = trti[first].pm; + buf[3] = trti[first].ps; + buf[4] = trti[first].pf; + } else { + buf[0] = 0x01; + buf[2] = 0x00; + buf[3] = 0x02; + buf[4] = 0x00; + } + + if (last != -1) { + buf[1] = trti[last].point; + buf[5] = trti[first].pm; + buf[6] = trti[first].ps; + buf[7] = trti[first].pf; + } else { + buf[1] = 0x01; + buf[5] = 0x00; + buf[6] = 0x02; + buf[7] = 0x00; + } + + buf[8] = 0x00; } void @@ -1467,55 +1480,75 @@ cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len) return 1; } +#endif uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type) { - track_info_t ti; - int first_track; - int last_track; - int m = 0; - int s = 0; - int f = 0; - uint32_t temp; + uint8_t rti[65536] = { 0 }; + raw_track_info_t *trti = (raw_track_info_t *) rti; + int num = 0; + int first = -1; + int last = -1; + int t = -1; + uint32_t temp; + uint8_t ret = 1; - dev->ops->get_tracks(dev, &first_track, &last_track); + if (dev != NULL) + dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); + + cdrom_log("Read DISC Info TOC Type = %d, track = %d\n", type, track); - cdrom_log("Read DISC Info TOC Type = %d, track = %d, first_track = %d, last_track = %d.\n", type, track, first_track, last_track); switch (type) { case 0: - b[0] = bin2bcd(first_track); - b[1] = bin2bcd(last_track); - b[2] = 0; - b[3] = 0; - cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 0) at %02i:%02i\n", dev->id, b[0], b[1]); + if (num > 0) { + first = find_track(trti, num, 1); + last = find_track(trti, num, 0); + } + + if ((first == -1) || (last == -1)) + ret = 0; + else { + b[0] = bin2bcd(first); + b[1] = bin2bcd(last); + b[2] = 0x00; + b[3] = 0x00; + + cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 0) at %02i:%02i\n", + dev->id, b[0], b[1]); + } break; case 1: - dev->ops->get_track_info(dev, 0xaa, 0, &ti); - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[0] = m; - b[1] = s; - b[2] = f; - b[3] = 0; - cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 1) at %02i:%02i.%02i, track=%d\n", dev->id, b[0], b[1], b[2], bcd2bin(track)); + if (num > 0) + t = find_last_lead_out(trti, num); + + if (t == -1) + ret = 0; + else { + b[0] = bin2bcd(trti[t].pm); + b[1] = bin2bcd(trti[t].ps); + b[2] = bin2bcd(trti[t].pf); + b[3] = 0x00; + + cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 1) at %02i:%02i.%02i\n", + dev->id, b[0], b[1], b[2]); + } break; case 2: - if (track > bin2bcd(last_track)) - return 0; + if (num > 0) + t = find_specific_track(trti, num, bcd2bin(track)); - dev->ops->get_track_info(dev, bcd2bin(track), 0, &ti); - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[0] = m; - b[1] = s; - b[2] = f; - b[3] = ti.attr; - cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), m, s, f, ti.attr); + if (t == -1) + ret = 0; + else { + b[0] = bin2bcd(trti[t].pm); + b[1] = bin2bcd(trti[t].ps); + b[2] = bin2bcd(trti[t].pf); + b[3] = trti[t].adr_ctl; + + cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at " + "%02i:%02i.%02i, track=%d, attr=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), b[3]); + } break; case 3: /* Undocumented on NEC CD-ROM's, from information based on sr_vendor.c from the Linux kernel */ switch (dev->type) { @@ -1525,22 +1558,36 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in case CDROM_TYPE_NEC_77_106: case CDROM_TYPE_NEC_211_100: case CDROM_TYPE_NEC_464_105: - dev->ops->get_track_info(dev, 1, 0, &ti); - b[0x0e] = 0; - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[0x0f] = temp >> 24; - b[0x10] = temp >> 16; - b[0x11] = temp >> 8; - b[0x12] = temp; + b[0x0e] = 0x00; + + if (num > 0) + first = find_track(trti, num, 1); + + if (first == -1) + ret = 0; + else { + temp = MSFtoLBA(trti[first].pm, trti[first].ps, trti[first].pf) - 150; + b[0x0f] = temp >> 24; + b[0x10] = temp >> 16; + b[0x11] = temp >> 8; + b[0x12] = temp; + } break; default: - dev->ops->get_track_info(dev, 1, 0, &ti); - b[0] = 0; - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[1] = temp >> 24; - b[2] = temp >> 16; - b[3] = temp >> 8; + b[0] = 0x00; /* Audio or CDROM disc. */ + + if (num > 0) + first = find_track(trti, num, 1); + + if (first == -1) + ret = 0; + else { + temp = MSFtoLBA(trti[first].pm, trti[first].ps, trti[first].pf) - 150; + b[0x1] = temp >> 24; + b[0x2] = temp >> 16; + b[0x3] = temp >> 8; + } break; } break; @@ -1548,7 +1595,7 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in break; } - return 1; + return ret; } static int @@ -1595,40 +1642,10 @@ track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode return 1; } -static int -read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len) -{ - uint8_t *bb = rbuf; - const int offset = (!!(mode2 & 0x03)) ? 24 : 16; - - int ret = dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba); - - /* Sync bytes */ - bb[0] = 0; - memset(bb + 1, 0xff, 10); - bb[11] = 0; - bb += 12; - - /* Sector header */ - bb[0] = (msf >> 16) & 0xff; - bb[1] = (msf >> 8) & 0xff; - bb[2] = msf & 0xff; - - bb[3] = 1; /* mode 1 data */ - bb += mode2 ? 12 : 4; - bb += len; - if (mode2 && ((mode2 & 0x03) == 1)) - memset(bb, 0, 280); - else if (!mode2) - memset(bb, 0, 288); - - return ret; -} - static int read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b) { - int ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); + int ret = dev->ops->read_sector(dev, raw_buffer, lba); memcpy(b, raw_buffer, 2352); @@ -1637,15 +1654,9 @@ read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b) return ret; } -static int -read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) +static void +process_mode1(cdrom_t *dev, int cdrom_sector_flags, uint8_t *b) { - int ret; - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048)) - ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048); - else - ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); - cdrom_sector_size = 0; if (cdrom_sector_flags & 0x80) { @@ -1690,18 +1701,28 @@ read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int cdrom_sector_size += 288; b += 288; } +} + +static int +read_data(cdrom_t *dev, uint32_t lba) +{ + return dev->ops->read_sector(dev, raw_buffer, lba); +} + +static int +read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint8_t *b) +{ + int ret = read_data(dev, lba); + + process_mode1(dev, cdrom_sector_flags, b); return ret; } static int -read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) +read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint8_t *b) { - int ret; - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2336)) - ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336); - else - ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); + int ret = dev->ops->read_sector(dev, raw_buffer, lba); cdrom_sector_size = 0; @@ -1741,15 +1762,9 @@ read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t m return ret; } -static int -read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) +static void +process_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint8_t *b) { - int ret; - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048)) - ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048); - else - ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); - cdrom_sector_size = 0; if (cdrom_sector_flags & 0x80) { @@ -1791,18 +1806,22 @@ read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t cdrom_sector_size += 280; b += 280; } +} + +static int +read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint8_t *b) +{ + int ret = read_data(dev, lba); + + process_mode2_xa_form1(dev, cdrom_sector_flags, b); return ret; } static int -read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) +read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint8_t *b) { - int ret; - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2324)) - ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324); - else - ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); + int ret = dev->ops->read_sector(dev, raw_buffer, lba); cdrom_sector_size = 0; @@ -1847,14 +1866,11 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c { uint8_t *b; uint8_t *temp_b; - uint32_t msf; uint32_t lba; - int audio = 0; - int mode2 = 0; - int m; - int s; - int f; - int ret = 0; + int audio = 0; + int mode2 = 0; + int unk = 0; + int ret = 0; if (dev->cd_status == CD_STATUS_EMPTY) return 0; @@ -1864,38 +1880,37 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c *len = 0; if (ismsf) { - m = (sector >> 16) & 0xff; - s = (sector >> 8) & 0xff; - f = sector & 0xff; + int m = (sector >> 16) & 0xff; + int s = (sector >> 8) & 0xff; + int f = sector & 0xff; + lba = MSFtoLBA(m, s, f) - 150; - msf = sector; } else { switch (vendor_type) { case 0x00: lba = sector; - msf = cdrom_lba_to_msf_accurate(sector); break; case 0x40: - m = bcd2bin((sector >> 24) & 0xff); - s = bcd2bin((sector >> 16) & 0xff); - f = bcd2bin((sector >> 8) & 0xff); + int m = bcd2bin((sector >> 24) & 0xff); + int s = bcd2bin((sector >> 16) & 0xff); + int f = bcd2bin((sector >> 8) & 0xff); + lba = MSFtoLBA(m, s, f) - 150; - msf = sector; break; case 0x80: lba = bcd2bin((sector >> 24) & 0xff); - msf = sector; break; /* Never used values but the compiler complains. */ default: - lba = msf = 0; + lba = 0; } } if (dev->ops->track_type) audio = dev->ops->track_type(dev, lba); - mode2 = audio & ~CD_TRACK_AUDIO; + mode2 = audio & CD_TRACK_MODE2; + unk = audio & CD_TRACK_UNK_DATA; audio &= CD_TRACK_AUDIO; memset(raw_buffer, 0, 2448); @@ -1926,55 +1941,67 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c return 0; } - ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode1(dev, cdrom_sector_flags, lba, temp_b); } else if (cdrom_sector_type == 3) { if (audio || !mode2 || (mode2 & 0x03)) { cdrom_log("CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type\n", dev->id); return 0; } - ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, temp_b); } else if (cdrom_sector_type == 4) { if (audio || !mode2 || ((mode2 & 0x03) != 1)) { cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type\n", dev->id); return 0; } - read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + read_mode2_xa_form1(dev, cdrom_sector_flags, lba, temp_b); } else if (cdrom_sector_type == 5) { if (audio || !mode2 || ((mode2 & 0x03) != 2)) { cdrom_log("CD-ROM %i: [XA Mode 2 Form 2] Attempting to read a sector of another type\n", dev->id); return 0; } - ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, temp_b); } else if (cdrom_sector_type == 8) { if (audio) { cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", dev->id); return 0; } - if (mode2 && ((mode2 & 0x03) == 1)) - ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + if (unk) { + /* This is needed to correctly read Mode 2 XA Form 1 sectors over IOCTL. */ + ret = read_data(dev, lba); + + if (raw_buffer[0x000f] == 0x02) { + cdrom_log("CD-ROM %i: [Any Data] Unknown data type determined to be XA Mode 2 Form 1\n", dev->id); + process_mode2_xa_form1(dev, cdrom_sector_flags, temp_b); + } else { + cdrom_log("CD-ROM %i: [Any Data] Unknown data type determined to be Mode 1\n", dev->id); + process_mode1(dev, cdrom_sector_flags, temp_b); + } + } else if (mode2 && ((mode2 & 0x03) == 1)) + ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, temp_b); else if (!mode2) - ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode1(dev, cdrom_sector_flags, lba, temp_b); else { - cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", dev->id); + cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size " + "is not 2048 bytes\n", dev->id); return 0; } } else { if (mode2) { if ((mode2 & 0x03) == 0x01) - ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, temp_b); else if ((mode2 & 0x03) == 0x02) - ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, temp_b); else - ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, temp_b); } else { if (audio) ret = read_audio(dev, lba, temp_b); else - ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); + ret = read_mode1(dev, cdrom_sector_flags, lba, temp_b); } } @@ -2027,7 +2054,6 @@ cdrom_drive_reset(cdrom_t *dev) dev->get_channel = NULL; } -/* Will be removed later. */ #ifdef ENABLE_CDROM_LOG static void cdrom_toc_dump(cdrom_t *dev) @@ -2040,6 +2066,24 @@ cdrom_toc_dump(cdrom_t *dev) fflush(f); fclose(f); pclog("Written TOC of %i bytes to %s\n", len, fn2); + + memset(b, 0x00, 65536); + len = cdrom_read_toc(dev, b, CD_TOC_NORMAL, 0, 0, 65536); + fn2 = "d:\\86boxnew\\toc_cue_cooked.dmp"; + f = fopen(fn2, "wb"); + fwrite(b, 1, len, f); + fflush(f); + fclose(f); + pclog("Written cooked TOC of %i bytes to %s\n", len, fn2); + + memset(b, 0x00, 65536); + len = cdrom_read_toc(dev, b, CD_TOC_SESSION, 0, 0, 65536); + fn2 = "d:\\86boxnew\\toc_cue_session.dmp"; + f = fopen(fn2, "wb"); + fwrite(b, 1, len, f); + fflush(f); + fclose(f); + pclog("Written session TOC of %i bytes to %s\n", len, fn2); } #endif @@ -2084,8 +2128,12 @@ cdrom_hard_reset(void) else cdrom_image_open(dev, dev->image_path); + cdrom_insert(i); + cdrom_insert(i); + #ifdef ENABLE_CDROM_LOG - cdrom_toc_dump(dev); + if (i == 0) + cdrom_toc_dump(dev); #endif } } @@ -2144,9 +2192,24 @@ cdrom_exit(uint8_t id) memset(dev->image_path, 0, sizeof(dev->image_path)); + pclog("cdrom_exit(%i): cdrom_insert(%i)\n", id, id); cdrom_insert(id); } +int +cdrom_is_empty(uint8_t id) +{ + cdrom_t *dev = &cdrom[id]; + int ret = 0; + + /* This entire block should be in cdrom.c/cdrom_eject(dev*) ... */ + if (strlen(dev->image_path) == 0) + /* Switch from empty to empty. Do nothing. */ + ret = 1; + + return ret; +} + /* The mechanics of ejecting a CD-ROM from a drive. */ void cdrom_eject(uint8_t id) @@ -2154,10 +2217,9 @@ cdrom_eject(uint8_t id) cdrom_t *dev = &cdrom[id]; /* This entire block should be in cdrom.c/cdrom_eject(dev*) ... */ - if (strlen(dev->image_path) == 0) { + if (strlen(dev->image_path) == 0) /* Switch from empty to empty. Do nothing. */ return; - } cdrom_exit(id); @@ -2170,7 +2232,8 @@ cdrom_eject(uint8_t id) void cdrom_reload(uint8_t id) { - cdrom_t *dev = &cdrom[id]; + cdrom_t *dev = &cdrom[id]; + int was_empty = cdrom_is_empty(id); if ((strcmp(dev->image_path, dev->prev_image_path) == 0) || (strlen(dev->prev_image_path) == 0) || (strlen(dev->image_path) > 0)) { /* Switch from empty to empty. Do nothing. */ @@ -2206,7 +2269,13 @@ cdrom_reload(uint8_t id) cdrom_toc_dump(dev); #endif + /* Signal media change to the emulated machine. */ + pclog("cdrom_reload(%i): cdrom_insert(%i)\n", id, id); cdrom_insert(id); + + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + cdrom_insert(id); } plat_cdrom_ui_update(id, 1); diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 0ff914795..6e06676f8 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -80,6 +80,12 @@ image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) ti->f = tmsf.fr; } +static void +image_get_raw_track_info(cdrom_t *dev, int *num, raw_track_info_t *rti) +{ + cdi_get_raw_track_info((cd_img_t *) dev->local, num, (uint8_t *) rti); +} + static void image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) { @@ -99,7 +105,8 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) subc->rel_f = rel_pos.fr; cdrom_image_log("image_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); + subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, + subc->rel_m, subc->rel_s, subc->rel_f); } static int @@ -183,24 +190,14 @@ image_sector_size(struct cdrom *dev, uint32_t lba) } static int -image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba) +image_read_sector(struct cdrom *dev, uint8_t *b, uint32_t lba) { cd_img_t *img = (cd_img_t *) dev->local; - switch (type) { - case CD_READ_DATA: - return cdi_read_sector(img, b, 0, lba); - case CD_READ_AUDIO: - return cdi_read_sector(img, b, 1, lba); - case CD_READ_RAW: - if (cdi_get_sector_size(img, lba) == 2352) - return cdi_read_sector(img, b, 1, lba); - else - return cdi_read_sector_sub(img, b, lba); - default: - cdrom_image_log("CD-ROM %i: Unknown CD read type\n", dev->id); - return 0; - } + if (cdi_get_sector_size(img, lba) <= 2352) + return cdi_read_sector(img, b, 1, lba); + else + return cdi_read_sector_sub(img, b, lba); } static int @@ -211,10 +208,8 @@ image_track_type(cdrom_t *dev, uint32_t lba) if (img) { if (image_is_track_audio(dev, lba, 0)) return CD_TRACK_AUDIO; - else { - if (cdi_is_mode2(img, lba)) - return CD_TRACK_MODE2 | cdi_get_mode2_form(img, lba); - } + else if (cdi_is_mode2(img, lba)) + return CD_TRACK_MODE2 | cdi_get_mode2_form(img, lba); } return 0; @@ -245,7 +240,7 @@ image_exit(cdrom_t *dev) static const cdrom_ops_t cdrom_image_ops = { image_get_tracks, image_get_track_info, - NULL, + image_get_raw_track_info, image_get_subchannel, image_is_track_pre, image_sector_size, @@ -303,8 +298,8 @@ cdrom_image_open(cdrom_t *dev, const char *fn) cf = dev->cdrom_capacity % 75; cs = (dev->cdrom_capacity / 75) % 60; cm = (dev->cdrom_capacity / 75) / 60; - pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n", - dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf); + cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n", + dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf); /* Attach this handler to the drive. */ dev->ops = &cdrom_image_ops; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 2578e9e33..3e0fa017a 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -269,9 +269,8 @@ bin_init(const char *filename, int *error) if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { /* tf is freed by bin_close */ bin_close(tf); - } else { + } else free(tf); - } tf = NULL; } @@ -384,7 +383,8 @@ int cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { const track_t *trk = &cdi->tracks[track - 1]; - const int pos = trk->start + 150; + // const int pos = trk->start + 150; + const int pos = trk->indexes[1].start; if ((track < 1) || (track > cdi->tracks_num)) return 0; @@ -406,6 +406,7 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *tra return 0; *start = (uint32_t) trk->start; + // *start = (uint32_t) trk->indexes[1].start - 150ULL; *track_num = trk->track_number; *attr = trk->attr; @@ -413,6 +414,86 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *tra return 1; } +void +cdi_get_raw_track_info(cd_img_t *cdi, int *num, uint8_t *buffer) +{ + TMSF tmsf; + int track_num = 0; + uint8_t attr = 0; + int len = 0; + int first_track; + int last_track; + + cdi_get_audio_tracks(cdi, &first_track, &last_track, &tmsf); + + *num = last_track + 3; + + cdi_get_audio_track_info(cdi, 0, 1, &track_num, &tmsf, &attr); + + buffer[len++] = 1; /* Session number */ + buffer[len++] = attr; /* Track ADR and Control */ + buffer[len++] = 0; /* TNO (always 0) */ + buffer[len++] = 0xA0; /* Point (for track points - track number) */ + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = track_num; /* First track number */ + buffer[len++] = 0; + buffer[len++] = 0; + + cdi_get_audio_track_info(cdi, 0, last_track, &track_num, &tmsf, &attr); + + buffer[len++] = 1; /* Session number */ + buffer[len++] = attr; /* Track ADR and Control */ + buffer[len++] = 0; /* TNO (always 0) */ + buffer[len++] = 0xA1; /* Point (for track points - track number) */ + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = track_num; /* Last track number */ + buffer[len++] = 0; + buffer[len++] = 0; + + cdi_get_audio_track_info(cdi, 0, last_track + 1, &track_num, &tmsf, &attr); + + cdrom_image_backend_log(" tracks(%i) = %02X, %02X, %02i:%02i.%02i\n", last_track, attr, + track_num, tmsf.min, tmsf.sec, tmsf.fr); + + buffer[len++] = 1; /* Session number */ + buffer[len++] = attr; /* Track ADR and Control */ + buffer[len++] = 0; /* TNO (always 0) */ + buffer[len++] = 0xA2; /* Point (for track points - track number) */ + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = tmsf.min; /* PM */ + buffer[len++] = tmsf.sec; /* PS */ + buffer[len++] = tmsf.fr; /* PF */ + + for (int i = 0; i < last_track; i++) { + cdi_get_audio_track_info(cdi, 0, i + 1, &track_num, &tmsf, &attr); + + cdrom_image_backend_log(" tracks(%i) = %02X, %02X, %02i:%02i.%02i\n", i, attr, + track_num, tmsf.min, tmsf.sec, tmsf.fr); + + buffer[len++] = 1; /* Session number */ + buffer[len++] = attr; /* Track ADR and Control */ + buffer[len++] = 0; /* TNO (always 0) */ + buffer[len++] = track_num; /* Point (for track points - track number) */ + /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = 0; + buffer[len++] = tmsf.min; /* PM */ + buffer[len++] = tmsf.sec; /* PS */ + buffer[len++] = tmsf.fr; /* PF */ + } +} + int cdi_get_track(cd_img_t *cdi, uint32_t sector) { @@ -427,10 +508,12 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector) const track_t *next = &cdi->tracks[i + 1]; /* Take into account cue sheets that do not start on sector 0. */ - if ((i == 0) && (sector < cur->start)) + // if ((i == 0) && (sector < cur->start)) + if ((i == 0) && (sector < cur->indexes[0].start)) return cur->number; - if ((cur->start <= sector) && (sector < next->start)) + // if ((cur->start <= sector) && (sector < next->start)) + if ((cur->indexes[0].start <= sector) && (sector < next->indexes[0].start)) return cur->number; } @@ -454,11 +537,32 @@ cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); /* Absolute position should be adjusted by 150, not the relative ones. */ - FRAMES_TO_MSF(sector - trk->start, &rel_pos->min, &rel_pos->sec, &rel_pos->fr); + // FRAMES_TO_MSF(sector - trk->start, &rel_pos->min, &rel_pos->sec, &rel_pos->fr); + /* Relative position is relative Index 1 start - pre-gap values will be negative. */ + FRAMES_TO_MSF((int32_t) (sector + 150 - trk->indexes[1].start), &rel_pos->min, &rel_pos->sec, &rel_pos->fr); return 1; } +static int +cdi_get_sector_index(const track_t *trk, const uint32_t sector) +{ + int ret = 1; + + if ((sector + 150) < trk->indexes[1].start) + ret = 0; + else if ((sector + 150) >= trk->indexes[2].start) + ret = 2; + + return ret; +} + +static __inline int +bin2bcd(int x) +{ + return (x % 10) | ((x / 10) << 4); +} + int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) { @@ -467,9 +571,11 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) int raw_size; int cooked_size; uint64_t offset; - int m = 0; - int s = 0; - int f = 0; + int m = 0; + int s = 0; + int f = 0; + int ret = 0; + uint8_t q[16] = { 0x00 }; if (track < 0) return 0; @@ -478,6 +584,9 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size); + const int index = cdi_get_sector_index(trk, sector); + cdrom_image_backend_log("cdrom_read_sector(%08X): track %02X, index %02X, %016" PRIX64 ", %016" PRIX64 ", %i\n", + sector, track, index, trk->skip, trk->start, trk->sector_size); if (track_is_raw) raw_size = trk->sector_size; @@ -499,26 +608,67 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) else offset = 16ULL; - if (raw && !track_is_raw) { + if (!trk->indexes[index].in_file) { memset(buffer, 0x00, 2448); - const int ret = trk->file->read(trk->file, buffer + offset, seek, length); - if (ret <= 0) - return ret; - /* Construct the rest of the raw sector. */ - memset(buffer + 1, 0xff, 10); - buffer += 12; - FRAMES_TO_MSF(sector + 150, &m, &s, &f); - /* These have to be BCD. */ - buffer[0] = CDROM_BCD(m & 0xff); - buffer[1] = CDROM_BCD(s & 0xff); - buffer[2] = CDROM_BCD(f & 0xff); - /* Data, should reflect the actual sector type. */ - buffer[3] = trk->mode2 ? 2 : 1; - return 1; + if (trk->attr & 0x04) { + /* Construct the rest of the raw sector. */ + memset(buffer + 1, 0xff, 10); + buffer += 12; + FRAMES_TO_MSF(sector + 150, &m, &s, &f); + /* These have to be BCD. */ + buffer[0] = CDROM_BCD(m & 0xff); + buffer[1] = CDROM_BCD(s & 0xff); + buffer[2] = CDROM_BCD(f & 0xff); + /* Data, should reflect the actual sector type. */ + buffer[3] = trk->mode2 ? 2 : 1; + ret = 1; + } + } else if (raw && !track_is_raw) { + memset(buffer, 0x00, 2448); + const int temp = trk->file->read(trk->file, buffer + offset, seek, length); + if (temp <= 0) + return temp; + if (trk->attr & 0x04) { + /* Construct the rest of the raw sector. */ + memset(buffer + 1, 0xff, 10); + buffer += 12; + FRAMES_TO_MSF(sector + 150, &m, &s, &f); + /* These have to be BCD. */ + buffer[0] = CDROM_BCD(m & 0xff); + buffer[1] = CDROM_BCD(s & 0xff); + buffer[2] = CDROM_BCD(f & 0xff); + /* Data, should reflect the actual sector type. */ + buffer[3] = trk->mode2 ? 2 : 1; + ret = 1; + } } else if (!raw && track_is_raw) return trk->file->read(trk->file, buffer, seek + offset, length); - else - return trk->file->read(trk->file, buffer, seek, length); + else { + ret = trk->file->read(trk->file, buffer, seek, length); + if (raw && (raw_size == 2448)) + return ret; + } + + /* Construct Q. */ + q[0] = (trk->attr >> 4) | ((trk->attr & 0xf) << 4); + q[1] = bin2bcd(trk->track_number); + q[2] = 1; /* TODO: Index number. */ + // FRAMES_TO_MSF(sector - trk->start, &m, &s, &f); + FRAMES_TO_MSF((int32_t) (sector + 150 - trk->indexes[1].start), &m, &s, &f); + q[3] = bin2bcd(m); + q[4] = bin2bcd(s); + q[5] = bin2bcd(f); + FRAMES_TO_MSF(sector + 150, &m, &s, &f); + q[7] = bin2bcd(m); + q[8] = bin2bcd(s); + q[9] = bin2bcd(f); + + /* Construct raw subchannel data from Q only. */ + for (int i = 0; i < 12; i++) + for (int j = 0; j < 8; j++) + buffer[2352 + (i << 3) + j] = ((q[i] >> (7 - j)) & 0x01) << 6; + + return ret; } int @@ -700,6 +850,17 @@ cdi_get_iso_track(cd_img_t *cdi, track_t *trk, const char *filename) } trk->length = trk->file->get_length(trk->file) / trk->sector_size; + + trk->indexes[0].in_file = 0; + trk->indexes[0].start = 0; + trk->indexes[0].length = 150; + trk->indexes[1].in_file = 1; + trk->indexes[1].start = 150; + trk->indexes[1].length = trk->length; + trk->indexes[2].in_file = 0; + trk->indexes[2].start = trk->length + 150; + trk->indexes[2].length = 0; + cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk->length, trk->sector_size); return ret; } @@ -721,10 +882,18 @@ cdi_load_iso(cd_img_t *cdi, const char *filename) /* Lead out track. */ trk.number = 2; trk.track_number = 0xAA; - trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */ + // trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */ trk.start = trk.length; - trk.length = 0; trk.file = NULL; + + for (int i = 0; i < 3; i++) { + trk.indexes[i].in_file = 0; + trk.indexes[i].start = trk.length + 150; + trk.indexes[i].length = 0; + } + + trk.length = 0; + cdi_track_push_back(cdi, &trk); } @@ -856,6 +1025,8 @@ cdi_cue_get_flags(track_t *cur, char **line) return 1; } +uint64_t total_pregap = 0ULL; + static int cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t cur_pregap) { @@ -888,6 +1059,23 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u return 1; } + if (prev->indexes[2].length != 0) { + prev->indexes[2].start = cur->indexes[0].start - prev->indexes[2].length; + prev->indexes[1].length = prev->indexes[2].start - prev->indexes[1].start; + cdrom_image_backend_log("Index 2 (%i): %02i:%02i:%02i\n", prev->indexes[2].in_file, + (int) ((prev->indexes[2].start / 75) / 60), (int) ((prev->indexes[2].start / 75) % 60), + (int) (prev->indexes[2].start % 75)); + } else if (prev->indexes[2].in_file) + prev->indexes[2].length = cur->indexes[0].start - prev->indexes[2].start; + else { + prev->indexes[1].length = cur->indexes[0].start - prev->indexes[1].start; + prev->indexes[2].start = prev->indexes[1].start + prev->indexes[1].length; + prev->indexes[2].length = 0; + cdrom_image_backend_log("Index 2 (%i): %02i:%02i:%02i\n", prev->indexes[2].in_file, + (int) ((prev->indexes[2].start / 75) / 60), (int) ((prev->indexes[2].start / 75) % 60), + (int) (prev->indexes[2].start % 75)); + } + /* Current track consumes data from the same file as the previous. */ if (prev->file == cur->file) { cur->start += *shift; @@ -926,10 +1114,10 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) { track_t trk; char pathname[MAX_FILENAME_LENGTH]; - uint64_t shift = 0ULL; - uint64_t prestart = 0ULL; - uint64_t cur_pregap = 0ULL; - uint64_t frame = 0ULL; + uint64_t shift = 0ULL; + uint64_t prestart = 0ULL; + uint64_t cur_pregap = 0ULL; + uint64_t frame = 0ULL; uint64_t index; int iso_file_used = 0; int success; @@ -976,6 +1164,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) /* nuke trailing newline */ } } + cdrom_image_backend_log("line = %s\n", line); (void) cdi_cue_get_keyword(&command, &line); @@ -987,35 +1176,34 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) if (!success) break; + cur_pregap = 0; + prestart = 0; + trk.number = cdi_cue_get_number(&line); + trk.track_number = trk.number; + cdrom_image_backend_log("cdi_load_cue(): Track %02X\n", trk.number); + success = cdi_cue_get_keyword(&type, &line); + + memset(trk.indexes, 0x00, sizeof(trk.indexes)); + + if (!success) + break; + if (iso_file_used) { - /* We don't alter anything of the detected track type with the one specified in the CUE file, except its numbers. */ - cur_pregap = 0; - prestart = 0; + /* + We don't alter anything of the detected track type with + the one specified in the CUE file, except its numbers. + */ + can_add_track = 1; - trk.number = cdi_cue_get_number(&line); - trk.track_number = trk.number; - success = cdi_cue_get_keyword(&type, &line); - if (!success) - break; - can_add_track = 1; - - iso_file_used = 0; + iso_file_used = 0; } else { - trk.start = 0; - trk.skip = 0; - cur_pregap = 0; - prestart = 0; + trk.start = 0; + trk.skip = 0; - trk.number = cdi_cue_get_number(&line); - trk.track_number = trk.number; - success = cdi_cue_get_keyword(&type, &line); - if (!success) - break; + trk.form = 0; + trk.mode2 = 0; - trk.form = 0; - trk.mode2 = 0; - - trk.pre = 0; + trk.pre = 0; if (!strcmp(type, "AUDIO")) { trk.sector_size = RAW_SECTOR_SIZE; @@ -1076,6 +1264,9 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) } else success = 0; + cdrom_image_backend_log("cdi_load_cue(): Format: %i bytes per sector, %02X, %i, %i\n", + trk.sector_size, trk.attr, trk.mode2, trk.form); + can_add_track = 1; } } else if (!strcmp(command, "INDEX")) { @@ -1084,11 +1275,55 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) switch (index) { case 0: - prestart = frame; + prestart = frame; + trk.indexes[0].in_file = 1; + trk.indexes[0].start = prestart + total_pregap; break; case 1: - trk.start = frame; + if (trk.indexes[0].in_file) + trk.indexes[0].length = frame - prestart; + else if (cur_pregap > 0) { + trk.indexes[0].start = frame + total_pregap; + trk.indexes[0].length = cur_pregap; + total_pregap += trk.indexes[0].length; + } else if (trk.number == 1) { + trk.indexes[0].start = 0; + trk.indexes[0].length = 150; + total_pregap += trk.indexes[0].length; + } else { + trk.indexes[0].start = frame + total_pregap; + trk.indexes[0].length = 0; + } + cdrom_image_backend_log("Index 0 (%i): %02i:%02i:%02i\n", trk.indexes[0].in_file, + (int) ((trk.indexes[0].start / 75) / 60), + (int) ((trk.indexes[0].start / 75) % 60), + (int) (trk.indexes[0].start % 75)); + + if (cur_pregap > 0) + trk.start = frame + cur_pregap; + else + trk.start = frame; + trk.indexes[1].start = trk.indexes[0].start + trk.indexes[0].length; + trk.indexes[1].in_file = 1; + cdrom_image_backend_log("Index 1 (%i): %02i:%02i:%02i\n", trk.indexes[1].in_file, + (int) ((trk.indexes[1].start / 75) / 60), + (int) ((trk.indexes[1].start / 75) % 60), + (int) (trk.indexes[1].start % 75)); + break; + + case 2: + trk.indexes[2].in_file = 1; + if (cur_pregap > 0) + trk.indexes[2].start = frame + cur_pregap; + else + trk.indexes[2].start = frame; + trk.indexes[1].length = trk.indexes[2].start - trk.indexes[1].start; + trk.indexes[2].length = 0; + cdrom_image_backend_log("Index 2 (%i): %02i:%02i:%02i\n", trk.indexes[2].in_file, + (int) ((trk.indexes[2].start / 75) / 60), + (int) ((trk.indexes[2].start / 75) % 60), + (int) (trk.indexes[2].start % 75)); break; default: @@ -1163,7 +1398,10 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) } } else if (!strcmp(command, "PREGAP")) success = cdi_cue_get_frame(&cur_pregap, &line); - else if (!strcmp(command, "FLAGS")) + else if (!strcmp(command, "POSTGAP")) { + success = cdi_cue_get_frame(&trk.indexes[2].length, &line); + trk.indexes[2].in_file = 0; + } else if (!strcmp(command, "FLAGS")) success = cdi_cue_get_flags(&trk, &line); else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "ISRC") || !strcmp(command, "PERFORMER") || !strcmp(command, "POSTGAP") || !strcmp(command, "REM") || !strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || !strcmp(command, "")) { /* Ignored commands. */ @@ -1183,18 +1421,58 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) return 0; /* Add last track. */ + cdrom_image_backend_log("LEAD OUT\n"); if (!cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap)) return 0; /* Add lead out track. */ + cdrom_image_backend_log("END OF CUE\n"); trk.number++; + memset(trk.indexes, 0x00, sizeof(trk.indexes)); trk.track_number = 0xAA; + // trk.attr = 0x16; trk.start = 0; trk.length = 0; trk.file = NULL; if (!cdi_add_track(cdi, &trk, &shift, 0, 0)) return 0; + track_t *cur = &cdi->tracks[cdi->tracks_num - 1]; + track_t *prev = &cdi->tracks[cdi->tracks_num - 2]; + + for (int i = 0; i < 3; i++) { + cur->indexes[i].in_file = 0; + cur->indexes[i].start = prev->indexes[1].start + prev->length - 150; + cur->indexes[i].length = 0; + } + + if (prev->indexes[2].length != 0) { + prev->indexes[2].start = cur->indexes[0].start - prev->indexes[2].length; + prev->indexes[1].length = prev->indexes[2].start - prev->indexes[1].start; + } else if (prev->indexes[2].in_file) + prev->indexes[2].length = cur->indexes[0].start - prev->indexes[2].start; + else { + prev->indexes[1].length = cur->indexes[0].start - prev->indexes[1].start; + prev->indexes[2].start = prev->indexes[1].start + prev->indexes[1].length; + prev->indexes[2].length = 0; + } + + for (int i = 0; i < cdi->tracks_num; i++) { + track_t *t = &(cdi->tracks[i]); + for (int j = 0; j < 3; j++) { + track_index_t *ti = &(t->indexes[j]); + cdrom_image_backend_log("Track %02X.%01X (%i): %02i:%02i:%02i-%02i:%02i:%02i\n", + t->track_number, j, + ti->in_file, + (int) ((ti->start / 75) / 60), + (int) ((ti->start / 75) % 60), + (int) (ti->start % 75), + (int) (((ti->start + ti->length - 1) / 75) / 60), + (int) (((ti->start + ti->length - 1) / 75) % 60), + (int) ((ti->start + ti->length - 1) % 75)); + } + } + return 1; } diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index f25988bb9..eccb75fef 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -109,7 +109,8 @@ ioctl_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) subc->rel_f = rel_pos.fr; cdrom_ioctl_log("ioctl_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); + subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, + subc->rel_m, subc->rel_s, subc->rel_f); } static int @@ -157,29 +158,16 @@ ioctl_sector_size(cdrom_t *dev, uint32_t lba) } static int -ioctl_read_sector(cdrom_t *dev, int type, uint8_t *b, uint32_t lba) +ioctl_read_sector(cdrom_t *dev, uint8_t *b, uint32_t lba) { - switch (type) { - case CD_READ_DATA: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n"); - return plat_cdrom_read_sector(dev->local, b, 0, lba); - case CD_READ_AUDIO: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n"); - return plat_cdrom_read_sector(dev->local, b, 1, lba); - case CD_READ_RAW: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n"); - return plat_cdrom_read_sector(dev->local, b, 1, lba); - default: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); - break; - } - return 0; + cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n"); + return plat_cdrom_read_sector(dev->local, b, lba); } static int ioctl_track_type(cdrom_t *dev, uint32_t lba) { - int ret = 0; + int ret = CD_TRACK_UNK_DATA; if (ioctl_is_track_audio(dev, lba, 0)) ret = CD_TRACK_AUDIO; diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 0a28e630d..8fb0bc742 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -28,6 +28,7 @@ #define CD_STATUS_TRANSITION 0x40 #define CD_STATUS_MEDIUM_CHANGED 0x80 +#define CD_TRACK_UNK_DATA 0x10 #define CD_TRACK_AUDIO 0x08 #define CD_TRACK_MODE2 0x04 @@ -85,6 +86,7 @@ enum CDROM_TYPE_TOSHIBA_5302TA_0305, CDROM_TYPE_TOSHIBA_5702B_TA70, CDROM_TYPE_CHINON_CDS431_H42, + CDROM_TYPE_CHINON_CDX435_M62, CDROM_TYPE_DEC_RRD45_0436, CDROM_TYPE_MATSHITA_501_10b, CDROM_TYPE_NEC_25_10a, @@ -93,6 +95,7 @@ enum CDROM_TYPE_NEC_77_106, CDROM_TYPE_NEC_211_100, CDROM_TYPE_NEC_464_105, + CDROM_TYPE_ShinaKen_DM3x1S_104, CDROM_TYPE_SONY_CDU541_10i, CDROM_TYPE_SONY_CDU561_18k, CDROM_TYPE_SONY_CDU76S_100, @@ -101,7 +104,8 @@ enum CDROM_TYPE_PLEXTOR_PX32TS_103, CDROM_TYPE_TEAC_CD50_100, CDROM_TYPE_TEAC_R55S_10R, - CDROM_TYPE_TEXEL_DMXX24_100, + CDROM_TYPE_TEXEL_DM3024_100, + CDROM_TYPE_TEXEL_DM3028_106, CDROM_TYPE_TOSHIBA_XM_3433, CDROM_TYPE_TOSHIBA_XM3201B_3232, CDROM_TYPE_TOSHIBA_XM3301TA_0272, @@ -146,30 +150,33 @@ static const struct { "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE }, { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE }, { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE }, - { "CHINON", "CD-ROM CDS-431", "H42 ", "CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI }, - { "DEC", "RRD45 (C) DEC", "0436", "DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI }, - { "MATSHITA", "CD-ROM CR-501", "1.0b", "MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:25", "1.0a", "NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:38", "1.00", "NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:75", "1.03", "NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:77", "1.06", "NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:211", "1.00", "NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:464", "1.05", "NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, - { "SONY", "CD-ROM CDU-541", "1.0i", "SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, - { "SONY", "CD-ROM CDU-561", "1.8k", "SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI }, - { "SONY", "CD-ROM CDU-76S", "1.00", "SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, - { "PHILIPS", "CDD2600", "1.07", "PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, - { "PIONEER", "CD-ROM DRM-604X", "2403", "PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, - { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, - { "TEAC", "CD 50", "1.00", "TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI }, - { "TEAC", "CD-ROM R55S", "1.0R", "TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI }, - { "TEXEL", "CD-ROM DM-XX24", "1.00", "TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM XM-3201B", "3232", "TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, - { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI }, - { "", "", "", "", "", BUS_TYPE_NONE }, + { "CHINON", "CD-ROM CDS-431", "H42 ", "[SCSI-1] CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI }, + { "CHINON", "CD-ROM CDX-435", "M62 ", "[SCSI-1] CHINON CD-ROM CDX-435 M62", "CHINON_CD-ROM_CDX-435_M62", BUS_TYPE_SCSI }, + { "DEC", "RRD45 (C) DEC", "0436", "[SCSI-1] DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI }, + { "MATSHITA", "CD-ROM CR-501", "1.0b", "[SCSI-1] MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:25", "1.0a", "[SCSI-1] NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:38", "1.00", "[SCSI-2] NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:75", "1.03", "[SCSI-1] NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:77", "1.06", "[SCSI-1] NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:211", "1.00", "[SCSI-2] NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI }, + { "NEC", "CD-ROM DRIVE:464", "1.05", "[SCSI-2] NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, + { "ShinaKen", "CD-ROM DM-3x1S", "1.04", "[SCSI-1] ShinaKen CD-ROM DM-3x1S 1.04", "ShinaKen_CD-ROM_DM-3x1S_1.04", BUS_TYPE_SCSI }, + { "SONY", "CD-ROM CDU-541", "1.0i", "[SCSI-1] SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, + { "SONY", "CD-ROM CDU-561", "1.8k", "[SCSI-2] SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI }, + { "SONY", "CD-ROM CDU-76S", "1.00", "[SCSI-2] SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, + { "PHILIPS", "CDD2600", "1.07", "[SCSI-2] PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, + { "PIONEER", "CD-ROM DRM-604X", "2403", "[SCSI-2] PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, + { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "[SCSI-2] PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, + { "TEAC", "CD 50", "1.00", "[SCSI-2] TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI }, + { "TEAC", "CD-ROM R55S", "1.0R", "[SCSI-2] TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI }, + { "TEXEL", "CD-ROM DM-3024", "1.00", "[SCSI-1] TEXEL CD-ROM DM-3024 1.00", "TEXEL_CD-ROM_DM-3024_1.00", BUS_TYPE_SCSI }, + { "TEXEL", "CD-ROM DM-3028", "1.06", "[SCSI-2] TEXEL CD-ROM DM-3028 1.06", "TEXEL_CD-ROM_DM-3028_1.06", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "[SCSI-2] TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM XM-3201B", "3232", "[SCSI-1] TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "[SCSI-2] TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, + { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "[SCSI-2] TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, + { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "[SCSI-2] TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI }, + { "", "", "", "", "", BUS_TYPE_NONE }, }; /* To shut up the GCC compilers. */ @@ -217,7 +224,7 @@ typedef struct cdrom_ops_t { void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); int (*is_track_pre)(struct cdrom *dev, uint32_t lba); int (*sector_size)(struct cdrom *dev, uint32_t lba); - int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba); + int (*read_sector)(struct cdrom *dev, uint8_t *b, uint32_t lba); int (*track_type)(struct cdrom *dev, uint32_t lba); int (*ext_medium_changed)(struct cdrom *dev); void (*exit)(struct cdrom *dev); @@ -255,6 +262,7 @@ typedef struct cdrom { uint32_t seek_diff; uint32_t cd_end; uint32_t type; + uint32_t sector_size; int cd_buflen; int audio_op; @@ -270,7 +278,9 @@ typedef struct cdrom { uint32_t (*get_volume)(void *p, int channel); uint32_t (*get_channel)(void *p, int channel); - int16_t cd_buffer[BUF_SIZE]; + int16_t cd_buffer[BUF_SIZE]; + + uint8_t subch_buffer[96]; } cdrom_t; extern cdrom_t cdrom[CDROM_NUM]; @@ -296,7 +306,8 @@ extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume); extern uint8_t cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type); extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b); extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf); -extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf); +extern uint8_t cdrom_get_current_status(cdrom_t *dev); +extern void cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf); extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf); extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b); extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); @@ -315,6 +326,7 @@ extern void cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type); extern void cdrom_close_handler(uint8_t id); extern void cdrom_insert(uint8_t id); extern void cdrom_exit(uint8_t id); +extern int cdrom_is_empty(uint8_t id); extern void cdrom_eject(uint8_t id); extern void cdrom_reload(uint8_t id); diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index c6b2d9fc7..2e3aa85b9 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -63,19 +63,16 @@ typedef struct track_file_t { #define BLOCK_NONE ((uint64_t) -1LL) -typedef struct track_block_t { +typedef struct track_index_t { /* Is the current block in the file? If not, return all 0x00's. */ - int type; + int in_file; /* The amount of bytes to skip at the beginning of each sector. */ int skip; /* Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1 to read the pregap of track 1. */ - int64_t start_sector; - int64_t end_sector; - /* Starting and ending offset in the file. */ - uint64_t start_offs; - uint64_t end_offs; -} track_block_t; + uint64_t start; + uint64_t length; +} track_index_t; typedef struct track_t { int pregap_len; /* Pre-gap - not in file. */ @@ -93,7 +90,7 @@ typedef struct track_t { uint64_t start; uint64_t length; uint64_t skip; - track_block_t blocks[256]; + track_index_t indexes[3]; track_file_t *file; } track_t; @@ -108,10 +105,14 @@ extern int cdi_set_device(cd_img_t *cdi, const char *path); extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track); -extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr); -extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr); +extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, + TMSF *start, uint8_t *attr); +extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, + uint32_t *start, uint8_t *attr); +extern void cdi_get_raw_track_info(cd_img_t *cdi, int *num, uint8_t *buffer); extern int cdi_get_track(cd_img_t *cdi, uint32_t sector); -extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); +extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, + uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); extern int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector); extern int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num); extern int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector); diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 5d4b723f3..4ab567aca 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -121,7 +121,6 @@ typedef struct mo_drive_t { uint32_t medium_size; uint32_t base; uint16_t sector_size; - } mo_drive_t; typedef struct mo_t { @@ -139,17 +138,6 @@ typedef struct mo_t { uint8_t current_cdb[16]; uint8_t sense[256]; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif - uint8_t id; uint8_t cur_lun; uint8_t pad0; @@ -172,6 +160,8 @@ typedef struct mo_t { uint32_t packet_len; double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } mo_t; extern mo_t *mo[MO_NUM]; diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h index 06439a652..1e70e014b 100644 --- a/src/include/86box/plat_cdrom.h +++ b/src/include/86box/plat_cdrom.h @@ -59,7 +59,7 @@ extern int plat_cdrom_get_audio_track_info(void *local, int end, int track, extern int plat_cdrom_get_audio_sub(void *local, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); extern int plat_cdrom_get_sector_size(void *local, uint32_t sector); -extern int plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector); +extern int plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector); extern void plat_cdrom_eject(void *local); extern void plat_cdrom_close(void *local); extern int plat_cdrom_set_drive(void *local, const char *drv); diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index dec537429..684a9d589 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -38,17 +38,6 @@ typedef struct scsi_cdrom_t { uint8_t current_cdb[16]; uint8_t sense[256]; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif - uint8_t id; uint8_t cur_lun; uint8_t early; @@ -72,9 +61,12 @@ typedef struct scsi_cdrom_t { double callback; + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); + + int sony_vendor; + mode_sense_pages_t ms_pages_saved_sony; mode_sense_pages_t ms_drive_status_pages_saved; - int sony_vendor; } scsi_cdrom_t; #endif diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index e69d3cc93..3f9f3791b 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -100,43 +100,53 @@ #define GPCMD_WRITE_AND_VERIFY_12 0xae #define GPCMD_VERIFY_12 0xaf #define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 +#define GPCMD_READ_CD_OLD 0xb8 /* Should be equivalent to 0xbe */ #define GPCMD_READ_CD_MSF 0xb9 #define GPCMD_AUDIO_SCAN 0xba #define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc +#define GPCMD_PLAY_CD 0xbc /* At some point, this was READ CD, according to the + ATAPI specification */ #define GPCMD_MECHANISM_STATUS 0xbd #define GPCMD_READ_CD 0xbe #define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */ #define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */ #define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */ -#define GPCMD_UNKNOWN_SONY 0xc0 /* Sony Vendor Unique command */ +#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */ +#define GPCMD_MAGAZINE_EJECT_PIONEER 0xc0 /* Pioneer Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */ #define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */ +#define GPCMD_READ_TOC_PIONEER 0xc1 /* Pioneer Vendor Unique command */ #define GPCMD_PAUSE_RESUME_ALT 0xc2 #define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */ #define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */ #define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */ #define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */ #define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */ #define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */ #define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */ -#define GPCMD_PLAYBACK_STATUS_TOSHIBA 0xc4 /* Sony Vendor Unique command */ +#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */ #define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */ #define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */ #define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */ #define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */ -#define GPCMD_PLAT_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ +#define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */ #define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/ #define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/ #define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /*Matsushita Vendor Unique command */ +#define GPCMD_AUDIO_TRACK_SEARCH_PIONEER 0xc8 /* Pioneer Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /* Matsushita Vendor Unique command */ #define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */ +#define GPCMD_PAUSE_PIONEER 0xca /* Pioneer Vendor Unique command */ #define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */ +#define GPCMD_STOP_PIONEER 0xcb /* Pioneer Vendor Unique command */ +#define GPCMD_PLAYBACK_STATUS_PIONEER 0xcc /* Pioneer Vendor Unique command */ #define GPCMD_SCAN_PIONEER 0xcd /* Should be equivalent to 0xba */ +#define GPCMD_READ_CD_MSF_OLD 0xd5 /* Should be equivalent to 0xb9 */ #define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */ #define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */ #define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */ @@ -145,6 +155,7 @@ #define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */ #define GPCMD_READ_DISC_INFORMATION_NEC 0xde /* NEC Vendor Unique command */ +#define GPCMD_DRIVE_STATUS_PIONEER 0xe0 /* Pioneer Vendor Unique command */ #define GPCMD_PLAY_AUDIO_12_MATSUSHITA 0xe5 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */ @@ -366,17 +377,6 @@ typedef struct scsi_common_s { uint8_t current_cdb[16]; uint8_t sense[256]; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif - uint8_t id; uint8_t cur_lun; uint8_t pad0; @@ -399,6 +399,8 @@ typedef struct scsi_common_s { uint32_t packet_len; double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } scsi_common_t; typedef struct scsi_device_t { diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index eb4dc69a4..8c7e045fb 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -31,17 +31,6 @@ typedef struct scsi_disk_t { uint8_t current_cdb[16]; uint8_t sense[256]; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif - uint8_t id; uint8_t cur_lun; uint8_t pad0; @@ -64,6 +53,8 @@ typedef struct scsi_disk_t { uint32_t packet_len; double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } scsi_disk_t; extern scsi_disk_t *scsi_disk[HDD_NUM]; diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index a4a4c341f..739ba388b 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -85,17 +85,6 @@ typedef struct zip_t { uint8_t current_cdb[16]; uint8_t sense[256]; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif - uint8_t id; uint8_t cur_lun; uint8_t pad0; @@ -118,6 +107,8 @@ typedef struct zip_t { uint32_t packet_len; double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } zip_t; extern zip_t *zip[ZIP_NUM]; diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index bf656177b..8555642e6 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -218,18 +218,14 @@ plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector)) } int -plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector) +plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector) { dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; plat_cdrom_open(ioctl); - if (raw) - /* Raw */ - dummy_cdrom_ioctl_log("Raw\n"); - else - /* Cooked */ - dummy_cdrom_ioctl_log("Cooked\n"); + /* Raw */ + dummy_cdrom_ioctl_log("Raw\n"); plat_cdrom_close(ioctl); diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 103ce3161..fc8f93e51 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -193,8 +193,8 @@ static uint64_t scsi_cdrom_drive_status_page_flags = ((1ULL << 0x01ULL) | (1U static const mode_sense_pages_t scsi_cdrom_drive_status_pages = { {{ 0, 0 }, { 0x01, 0, 2, 0x0f, 0xbf }, /*Drive Status Data Format*/ - { 0x02, 0, 1, 0 }, /*Audio Play Status Format*/ - { 0, 0 }, + { 0x02, 0, 1, 0 }, /*Audio Play Status Format*/ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -564,11 +564,11 @@ scsi_cdrom_get_channel(void *priv, int channel) switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: + ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? + GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE] + [channel ? 10 : 8]; break; default: ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; @@ -589,10 +589,8 @@ scsi_cdrom_get_volume(void *priv, int channel) switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; break; @@ -612,10 +610,8 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t)); memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi, sizeof(mode_sense_pages_t)); @@ -664,10 +660,8 @@ scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev) switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); fp = plat_fopen(nvr_path(file_name), "wb"); if (fp) { @@ -747,10 +741,8 @@ scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page { switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: switch (page_control) { case 0: case 3: @@ -795,14 +787,14 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag page &= 0x3f; if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = 0; /* Number of blocks (0 = all). */ - buf[pos++] = 0; - buf[pos++] = 0; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x800 = 2048 bytes). */ - buf[pos++] = 8; - buf[pos++] = 0; + buf[pos++] = 0x01; /* Density code. */ + buf[pos++] = 0x00; /* Number of blocks (0 = all). */ + buf[pos++] = 0x00; + buf[pos++] = 0x00; + buf[pos++] = 0x00; /* Reserved. */ + buf[pos++] = dev->drv->sector_size >> 16; /* Block length (default: 0x800 = 2048 bytes). */ + buf[pos++] = dev->drv->sector_size >> 8; + buf[pos++] = dev->drv->sector_size; } for (uint8_t i = 0; i < 0x40; i++) { @@ -979,6 +971,10 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) period = cdrom_seek_time(dev->drv); scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us, speed: %" PRIu64 " bytes per second, " + "should be: %" PRIu64 " bytes per second\n", + dev->id, (uint64_t) period, (uint64_t) (1000000.0 / period), + (uint64_t) (176400.0 * (double) dev->drv->cur_speed)); dev->callback += period; fallthrough; case 0x25: @@ -996,11 +992,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) break; case 0xc6 ... 0xc7: switch (dev->drv->type) { - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: + case CDROM_TYPE_TOSHIBA_XM_3433 ... CDROM_TYPE_TOSHIBA_SDM1401_1008: bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; @@ -1008,10 +1000,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case 0xc0: switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; @@ -1020,11 +1010,9 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case 0xc1: switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_PIONEER_DRM604X_2403: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; @@ -1033,11 +1021,9 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case 0xc2 ... 0xc3: switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_PIONEER_DRM604X_2403: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: if (dev->current_cdb[0] == 0xc2) dev->callback += 40.0; /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ @@ -1047,12 +1033,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) } case 0xdd ... 0xde: switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: + case CDROM_TYPE_NEC_25_10a ... CDROM_TYPE_NEC_464_105: /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; @@ -1230,6 +1211,7 @@ scsi_cdrom_bus_master_error(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + scsi_cdrom_log("CD-ROM %i: Bus master error\n", dev->id); scsi_cdrom_buf_free(dev); scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; scsi_cdrom_cmd_error(dev); @@ -1238,6 +1220,7 @@ scsi_cdrom_bus_master_error(scsi_common_t *sc) static void scsi_cdrom_not_ready(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Medium not present\n", dev->id); scsi_cdrom_sense_key = SENSE_NOT_READY; scsi_cdrom_asc = ASC_MEDIUM_NOT_PRESENT; scsi_cdrom_ascq = 0; @@ -1247,6 +1230,7 @@ scsi_cdrom_not_ready(scsi_cdrom_t *dev) static void scsi_cdrom_circ_error(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: CIRC unrecovered error\n", dev->id); scsi_cdrom_sense_key = SENSE_MEDIUM_ERROR; scsi_cdrom_asc = ASC_UNRECOVERED_READ_ERROR; scsi_cdrom_ascq = ASCQ_CIRC_UNRECOVERED_ERROR; @@ -1256,6 +1240,7 @@ scsi_cdrom_circ_error(scsi_cdrom_t *dev) static void scsi_cdrom_invalid_lun(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Invalid LUN\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_LUN; scsi_cdrom_ascq = 0; @@ -1265,6 +1250,7 @@ scsi_cdrom_invalid_lun(scsi_cdrom_t *dev) static void scsi_cdrom_illegal_opcode(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Illegal opcode\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_ILLEGAL_OPCODE; scsi_cdrom_ascq = 0; @@ -1274,6 +1260,7 @@ scsi_cdrom_illegal_opcode(scsi_cdrom_t *dev) static void scsi_cdrom_lba_out_of_range(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: LBA out of range\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_LBA_OUT_OF_RANGE; scsi_cdrom_ascq = 0; @@ -1283,6 +1270,7 @@ scsi_cdrom_lba_out_of_range(scsi_cdrom_t *dev) static void scsi_cdrom_invalid_field(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Invalid field in command packet\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; scsi_cdrom_ascq = 0; @@ -1293,6 +1281,7 @@ scsi_cdrom_invalid_field(scsi_cdrom_t *dev) static void scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Invalid field in parameter list\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; scsi_cdrom_ascq = 0; @@ -1303,6 +1292,7 @@ scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev) static void scsi_cdrom_illegal_mode(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Illegal mode for this track\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; scsi_cdrom_ascq = 0; @@ -1312,6 +1302,7 @@ scsi_cdrom_illegal_mode(scsi_cdrom_t *dev) static void scsi_cdrom_incompatible_format(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Incompatible format\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INCOMPATIBLE_FORMAT; scsi_cdrom_ascq = 2; @@ -1321,6 +1312,7 @@ scsi_cdrom_incompatible_format(scsi_cdrom_t *dev) static void scsi_cdrom_data_phase_error(scsi_cdrom_t *dev) { + scsi_cdrom_log("CD-ROM %i: Data phase error\n", dev->id); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_DATA_PHASE_ERROR; scsi_cdrom_ascq = 0; @@ -1393,15 +1385,20 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch, int ven int type = 0; int flags = 0; - if (dev->current_cdb[0] == GPCMD_READ_CD_MSF) - msf = 1; - - if ((dev->current_cdb[0] == GPCMD_READ_CD_MSF) || (dev->current_cdb[0] == GPCMD_READ_CD)) { - type = (dev->current_cdb[1] >> 2) & 7; - flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); - } else { - type = 8; /* Internal type code indicating both Mode 1 and Mode 2 Form 1 are allowed. */ - flags = 0x10; + switch (dev->current_cdb[0]) { + case GPCMD_READ_CD_MSF_OLD: + case GPCMD_READ_CD_MSF: + msf = 1; + fallthrough; + case GPCMD_READ_CD_OLD: + case GPCMD_READ_CD: + type = (dev->current_cdb[1] >> 2) & 7; + flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); + break; + default: + type = 8; /* Internal type code indicating both Mode 1 and Mode 2 Form 1 are allowed. */ + flags = (dev->drv->sector_size == 2340) ? 0x78 : 0x10; + break; } if (!dev->sector_len) { @@ -1561,7 +1558,7 @@ scsi_cdrom_insert(void *priv) } else if (dev->drv->cd_status & CD_STATUS_TRANSITION) { dev->unit_attention = 1; /* Turn off the medium changed status. */ - dev->drv->cd_status &= ~(CD_STATUS_TRANSITION | CD_STATUS_MEDIUM_CHANGED); + dev->drv->cd_status &= ~CD_STATUS_TRANSITION; scsi_cdrom_log("CD-ROM %i: Media insert\n", dev->id); } else { dev->unit_attention = 0; @@ -1570,6 +1567,25 @@ scsi_cdrom_insert(void *priv) } } +static void +scsi_cdrom_ext_insert(void *priv, int ext_medium_changed) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; + + if ((dev == NULL) || (dev->drv == NULL)) + return; + + if ((dev->drv->ops == NULL) || (ext_medium_changed == -1)) { + dev->unit_attention = 0; + dev->drv->cd_status = CD_STATUS_EMPTY; + scsi_cdrom_log("CD-ROM %i: External media removal\n", dev->id); + } else if (ext_medium_changed == 1) { + dev->unit_attention = 0; + dev->drv->cd_status |= CD_STATUS_TRANSITION; + scsi_cdrom_log("CD-ROM %i: External media transition\n", dev->id); + } +} + static int scsi_command_check_ready(scsi_cdrom_t *dev, uint8_t *cdb) { @@ -1583,11 +1599,9 @@ scsi_command_check_ready(scsi_cdrom_t *dev, uint8_t *cdb) ret = 1; break; case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - if (cdb[0] == 0xC0) + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: + if (cdb[0] == 0xc0) break; ret = 1; break; @@ -1601,7 +1615,7 @@ scsi_command_check_ready(scsi_cdrom_t *dev, uint8_t *cdb) static int scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) { - int ready = 0; + int ready = 0; int ext_medium_changed = 0; if (dev->drv && dev->drv->ops && dev->drv->ops->ext_medium_changed) @@ -1634,6 +1648,9 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) return 0; } + if (ext_medium_changed != 0) + scsi_cdrom_ext_insert((void *) dev, ext_medium_changed); + if ((dev->drv->cd_status == CD_STATUS_PLAYING) || (dev->drv->cd_status == CD_STATUS_PAUSED)) { ready = 1; goto skip_ready_check; @@ -1643,16 +1660,15 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) if ((cdb[0] == GPCMD_TEST_UNIT_READY) || (cdb[0] == GPCMD_REQUEST_SENSE)) ready = 0; else { - scsi_cdrom_insert((void *) dev); + if ((ext_medium_changed != 0) || !(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) { + scsi_cdrom_log("(ext_medium_changed != 0): scsi_cdrom_insert()\n"); + scsi_cdrom_insert((void *) dev); + } ready = (dev->drv->cd_status != CD_STATUS_EMPTY) || (ext_medium_changed == -1); } - } else { - if ((dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) || (ext_medium_changed == 1)) - scsi_cdrom_insert((void *) dev); - - ready = (dev->drv->cd_status != CD_STATUS_EMPTY) || (ext_medium_changed == -1); - } + } else + ready = (dev->drv->cd_status != CD_STATUS_EMPTY); skip_ready_check: /* If the drive is not ready, there is no reason to keep the @@ -1666,7 +1682,7 @@ skip_ready_check: if (dev->unit_attention == 1) { /* Only increment the unit attention phase if the command can not pass through it. */ if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) { - /* scsi_cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); */ + scsi_cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); dev->unit_attention++; scsi_cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); @@ -1675,12 +1691,12 @@ skip_ready_check: } } else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* scsi_cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); */ + scsi_cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); dev->unit_attention = 0; } } - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* + /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* clear the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) scsi_cdrom_sense_clear(dev, cdb[0]); @@ -1760,17 +1776,23 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt dev->unit_attention = 0; } - if (dev->drv->cd_status & CD_STATUS_TRANSITION) + if (dev->drv->cd_status & CD_STATUS_TRANSITION) { + scsi_cdrom_log("CD_STATUS_TRANSITION: scsi_cdrom_insert()\n"); scsi_cdrom_insert((void *) dev); + } } void scsi_cdrom_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int ext_medium_changed = 0; - if (dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) - scsi_cdrom_insert((void *) dev); + if (dev->drv && dev->drv->ops && dev->drv->ops->ext_medium_changed) + ext_medium_changed = dev->drv->ops->ext_medium_changed(dev->drv); + + if (ext_medium_changed != 0) + scsi_cdrom_ext_insert((void *) dev, ext_medium_changed); if ((dev->drv->cd_status == CD_STATUS_EMPTY) && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the @@ -1805,34 +1827,779 @@ scsi_cdrom_stop(scsi_common_t *sc) cdrom_stop(dev->drv); } +static void +scsi_cdrom_set_speed(scsi_cdrom_t *dev, uint8_t *cdb) +{ + dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; + if (dev->drv->cur_speed < 1) + dev->drv->cur_speed = 1; + else if (dev->drv->cur_speed > dev->drv->speed) + dev->drv->cur_speed = dev->drv->speed; + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); +} + +static uint8_t +scsi_cdrom_command_chinon(void *sc, uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + uint8_t cmd_stat = 0x00; + + switch (cdb[0]) { + case GPCMD_UNKNOWN_CHINON: + if (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + } + break; + + case GPCMD_EJECT_CHINON: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_STOP_CHINON: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_dec_sony_texel(void *sc, uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int msf = 0; + int pos = dev->drv->seek_pos; + int ret = 1; + uint8_t cmd_stat = 0x00; + int len; + int max_len; + int alloc_length; + int real_pos; + + switch (cdb[0]) { + case GPCMD_SET_ADDRESS_FORMAT_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->sony_vendor = 1; + dev->drv->sony_msf = cdb[8] & 1; + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_TOC_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + msf = dev->drv->sony_msf; + dev->sony_vendor = 1; + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 65536); + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else { + len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf, max_len); + + if (len == -1) + /* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */ + scsi_cdrom_invalid_field(dev); + else { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCHANNEL_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + dev->sony_vendor = 1; + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + msf = dev->drv->sony_msf; + + scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s), code-q = %02x\n", + dev->id, msf ? "MSF" : "LBA", cdb[2] & 0x40); + + if (cdb[2] & 0x40) { + scsi_cdrom_buf_alloc(dev, 9); + memset(dev->buffer, 0, 9); + len = 9; + cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_HEADER_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + dev->sony_vendor = 1; + + alloc_length = ((cdb[7] << 8) | cdb[8]); + scsi_cdrom_buf_alloc(dev, 4); + + dev->sector_len = 1; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); + dev->buffer[0] = ((real_pos >> 16) & 0xff); + dev->buffer[1] = ((real_pos >> 8) & 0xff); + dev->buffer[2] = real_pos & 0xff; + dev->buffer[3] = 1; /*2048 bytes user data*/ + + len = 4; + len = MIN(len, alloc_length); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + cmd_stat = 0x01; + break; + + case GPCMD_PLAYBACK_STATUS_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + dev->sony_vendor = 1; + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + msf = dev->drv->sony_msf; + + scsi_cdrom_buf_alloc(dev, 18); + + len = 18; + + memset(dev->buffer, 0, 18); + dev->buffer[0] = 0x00; /* Reserved */ + dev->buffer[1] = 0x00; /* Reserved */ + dev->buffer[2] = 0x00; /* Audio Status data length */ + dev->buffer[3] = 0x00; /* Audio Status data length */ + dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, /* Audio status */ + &dev->buffer[6], msf); + dev->buffer[5] = 0x00; + + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); + + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + cmd_stat = 0x01; + break; + + case GPCMD_PAUSE_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->sony_vendor = 1; + cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_TRACK_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->sony_vendor = 1; + + msf = 3; + if ((cdb[5] != 1) || (cdb[8] != 1)) + scsi_cdrom_illegal_mode(dev); + else { + pos = cdb[4]; + + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) + scsi_cdrom_illegal_mode(dev); + else { + /* In this case, len is unused so just pass a fixed value of 1 intead. */ + ret = cdrom_audio_play(dev->drv, pos, 1 /*len*/, msf); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + } + } + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_MSF_SONY: + cdb[0] = GPCMD_PLAY_AUDIO_MSF; + dev->current_cdb[0] = cdb[0]; + dev->sony_vendor = 1; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_MSF. */ + break; + + case GPCMD_PLAY_AUDIO_SONY: + cdb[0] = GPCMD_PLAY_AUDIO_10; + dev->current_cdb[0] = cdb[0]; + dev->sony_vendor = 1; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_10. */ + break; + + case GPCMD_PLAYBACK_CONTROL_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); + dev->sony_vendor = 1; + + len = (cdb[7] << 8) | cdb[8]; + if (len == 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: PlayBack Control Sony All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, 65536); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 1); + } + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_matsushita(void *sc, uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + uint8_t cmd_stat = 0x00; + + switch (cdb[0]) { + case GPCMD_READ_SUBCHANNEL_MATSUSHITA: + cdb[0] = GPCMD_READ_SUBCHANNEL; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_READ_SUBCHANNEL. */ + break; + + case GPCMD_READ_TOC_MATSUSHITA: + cdb[0] = GPCMD_READ_TOC_PMA_ATIP; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_READ_TOC_PMA_ATIP. */ + break; + + case GPCMD_READ_HEADER_MATSUSHITA: + cdb[0] = GPCMD_READ_HEADER; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_READ_HEADER. */ + break; + + case GPCMD_PLAY_AUDIO_MATSUSHITA: + cdb[0] = GPCMD_PLAY_AUDIO_10; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_10. */ + break; + + case GPCMD_PLAY_AUDIO_MSF_MATSUSHITA: + cdb[0] = GPCMD_PLAY_AUDIO_MSF; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_MSF. */ + break; + + case GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA: + cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_TRACK_INDEX. */ + break; + + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA: + cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10. */ + break; + + case GPCMD_PAUSE_RESUME_MATSUSHITA: + cdb[0] = GPCMD_PAUSE_RESUME; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PAUSE_RESUME. */ + break; + + case GPCMD_PLAY_AUDIO_12_MATSUSHITA: + cdb[0] = GPCMD_PLAY_AUDIO_12; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_12. */ + break; + + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA: + cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12; + dev->current_cdb[0] = cdb[0]; + /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12. */ + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_nec(void *sc, uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int pos = dev->drv->seek_pos; + int ret = 1; + uint8_t cmd_stat = 0x00; + int len; + int alloc_length; + + switch (cdb[0]) { + case GPCMD_NO_OPERATION_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_AUDIO_TRACK_SEARCH_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) + scsi_cdrom_illegal_mode(dev); + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_AUDIO_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) + ret = 0; + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + } + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + + cmd_stat = 0x01; + break; + + case GPCMD_STILL_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_SET_STOP_TIME_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_CADDY_EJECT_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 10; + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else if (alloc_length <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_DISC_INFORMATION_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + /* + NEC manual claims 4 bytes but the Linux kernel + (namely sr_vendor.c) actually states otherwise. + */ + scsi_cdrom_buf_alloc(dev, 22); + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else { + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 22; + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else + scsi_cdrom_invalid_field(dev); + } + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_pioneer(void *sc, uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int pos = dev->drv->seek_pos; + int ret = 1; + uint8_t cmd_stat = 0x00; + int len; + int max_len; + int alloc_length; + + switch (cdb[0]) { + case GPCMD_MAGAZINE_EJECT_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_TOC_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 4); + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else { + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 4; + + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else + scsi_cdrom_invalid_field(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCODEQ_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 9; + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + cdrom_get_current_subcodeq(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + cmd_stat = 0x01; + break; + + case GPCMD_AUDIO_TRACK_SEARCH_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) + ret = 0; + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search_pioneer(dev->drv, pos, cdb[1] & 1); + + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + } + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_AUDIO_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) + ret = 0; + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_pioneer(dev->drv, pos); + } + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PAUSE_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_STOP_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PLAYBACK_STATUS_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 6); + + len = 6; + + memset(dev->buffer, 0, 6); + dev->buffer[0] = cdrom_get_audio_status_pioneer(dev->drv, &dev->buffer[1]); /*Audio status*/ + + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); + + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + cmd_stat = 0x01; + break; + + case GPCMD_DRIVE_STATUS_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + len = (cdb[9] | (cdb[8] << 8)); + scsi_cdrom_buf_alloc(dev, 65536); + + if (!(scsi_cdrom_drive_status_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) + scsi_cdrom_invalid_field(dev); + else if (len <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + memset(dev->buffer, 0, len); + alloc_length = len; + + len = scsi_cdrom_drive_status(dev, dev->buffer, 0, cdb[2]); + len = MIN(len, alloc_length); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_log("CD-ROM %i: Reading drive status page: %02X...\n", dev->id, cdb[2]); + + scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); + } + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_toshiba(void *sc, uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int pos = dev->drv->seek_pos; + int ret = 1; + uint8_t cmd_stat = 0x00; + int len; + int alloc_length; + + switch (cdb[0]) { + case GPCMD_NO_OPERATION_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_AUDIO_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) + scsi_cdrom_illegal_mode(dev); + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_STILL_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_SET_STOP_TIME_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_CADDY_EJECT_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 10; + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else if (alloc_length <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_DISC_INFORMATION_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 4); + + if (!dev->drv->ops) + scsi_cdrom_not_ready(dev); + else { + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 4; + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else + scsi_cdrom_invalid_field(dev); + } + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + void scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; - int len; - int max_len; - int used_len; - int alloc_length; - int msf; - int pos = dev->drv->seek_pos; - int size_idx; - int idx = 0; - uint32_t feature; - unsigned preamble_len; - int toc_format; - int block_desc = 0; - int ret; + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int msf = 0; + int pos = dev->drv->seek_pos; + int idx = 0; + int block_desc = 0; + int ret = 1; int format = 0; - int real_pos; int track = 0; char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; int32_t blen = 0; + uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + int len; + int max_len; + int used_len; + int alloc_length; + int size_idx; + uint32_t feature; + unsigned preamble_len; + int toc_format; + int real_pos; int32_t *BufLen; uint8_t *b; - uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == CDROM_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -1875,12 +2642,12 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (scsi_cdrom_pre_execution_check(dev, cdb) == 0) return; -begin: if (cdb[0] != GPCMD_REQUEST_SENSE) { /* Clear the sense stuff as per the spec. */ scsi_cdrom_sense_clear(dev, cdb[0]); } - switch (cdb[0]) { + + if ((dev->ven_cmd == NULL) || (dev->ven_cmd(sc, cdb, BufLen) == 0x00)) switch (cdb[0]) { case GPCMD_TEST_UNIT_READY: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); scsi_cdrom_command_complete(dev); @@ -1914,34 +2681,11 @@ begin: scsi_cdrom_data_command_finish(dev, 18, 18, cdb[4], 0); break; - case 0xDA: /*GPCMD_SPEED_ALT*/ - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_STILL_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, 0x00); - dev->drv->audio_op = 0x01; - scsi_cdrom_command_complete(dev); - if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) - scsi_cdrom_buf_free(dev); - return; - } - fallthrough; case GPCMD_SET_SPEED: - dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; - if (dev->drv->cur_speed < 1) - dev->drv->cur_speed = 1; - else if (dev->drv->cur_speed > dev->drv->speed) - dev->drv->cur_speed = dev->drv->speed; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); + scsi_cdrom_set_speed(dev, cdb); break; - case 0xCD: + case GPCMD_SCAN_PIONEER: case GPCMD_AUDIO_SCAN: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); @@ -1994,110 +2738,22 @@ begin: if (toc_format < 3) { len = cdrom_read_toc(dev->drv, dev->buffer, toc_format, cdb[6], msf, max_len); - if (len == -1) { - /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ + /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ + if (len == -1) scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; + else { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); } - } else { + } else scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - - case 0xC7: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_MSF_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_MSF; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_MSF_SONY*/ - cdb[0] = GPCMD_PLAY_AUDIO_MSF; - dev->current_cdb[0] = cdb[0]; - dev->sony_vendor = 1; - goto begin; - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_READ_DISC_INFORMATION_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 4); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 4; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } break; - case 0xDE: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_DISC_INFORMATION_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 22); /* NEC manual claims 4 bytes, but the Linux kernel (namely sr_vendor.c) actually states otherwise. */ - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 22; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - case GPCMD_READ_CD_OLD: - /* IMPORTANT: Convert the command to new read CD - for pass through purposes. */ - dev->current_cdb[0] = GPCMD_READ_CD; - fallthrough; - case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: + case GPCMD_READ_CD_OLD: + case GPCMD_READ_CD_MSF_OLD: case GPCMD_READ_CD: case GPCMD_READ_CD_MSF: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -2106,139 +2762,117 @@ begin: switch (cdb[0]) { case GPCMD_READ_6: dev->sector_len = cdb[4]; + /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sectors. */ if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - msf = 0; + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | + ((uint32_t) cdb[3]); + scsi_cdrom_log("CD-ROM %i: READ (6): Length: %i, LBA: %i\n", dev->id, dev->sector_len, + dev->sector_pos); break; case GPCMD_READ_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, + scsi_cdrom_log("CD-ROM %i: READ (10): Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - msf = 0; break; case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + scsi_cdrom_log("CD-ROM %i: READ (12): Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - msf = 0; break; + case GPCMD_READ_CD_MSF_OLD: case GPCMD_READ_CD_MSF: - alloc_length = 2856; - dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); - dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - - dev->sector_len -= dev->sector_pos; - dev->sector_len++; - msf = 1; - - if ((cdb[9] & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - scsi_cdrom_invalid_field(dev); - return; - } - - /* If all the flag bits are cleared, then treat it as a non-data command. */ - if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) - dev->sector_len = 0; - else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { - scsi_cdrom_invalid_field(dev); - return; - } - break; + fallthrough; case GPCMD_READ_CD_OLD: case GPCMD_READ_CD: alloc_length = 2856; - dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - msf = 0; + if (msf) { + dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); + dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - if ((cdb[9] & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - scsi_cdrom_invalid_field(dev); - return; + dev->sector_len -= dev->sector_pos; + dev->sector_len++; + } else { + dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; } - /* If all the flag bits are cleared, then treat it as a non-data command. */ - if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) + if (((cdb[9] & 0xf8) == 0x08) || ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00))) { + /* Illegal mode */ + scsi_cdrom_invalid_field(dev); + ret = 0; + } else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) + /* If all the flag bits are cleared, then treat it as a non-data command. */ dev->sector_len = 0; - else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { - scsi_cdrom_invalid_field(dev); - return; - } break; default: break; } - if (!dev->sector_len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - /* scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } + if (ret) { + if (dev->sector_len > 0) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* + If we're reading all blocks in one go for DMA, + why not also for PIO, it should NOT matter + anyway, this step should be identical and only + the way the read dat is transferred to the host + should be different. + */ - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ + dev->packet_len = max_len * alloc_length; + scsi_cdrom_buf_alloc(dev, dev->packet_len); - dev->packet_len = max_len * alloc_length; - scsi_cdrom_buf_alloc(dev, dev->packet_len); + dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); - dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); - - if ((cdb[0] == GPCMD_READ_10) || (cdb[0] == GPCMD_READ_12)) { - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, cdb[9] & 0xc0); - break; - default: + if ((cdb[0] == GPCMD_READ_10) || (cdb[0] == GPCMD_READ_12)) { + switch (dev->drv->type) { + case CDROM_TYPE_NEC_25_10a ... CDROM_TYPE_NEC_464_105: + case CDROM_TYPE_TOSHIBA_XM_3433 ... CDROM_TYPE_TOSHIBA_SDM1401_1008: + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, cdb[9] & 0xc0); + break; + default: + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); + break; + } + } else ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); - break; + + if (ret > 0) { + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + scsi_cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, + alloc_length, 0); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_CDROM | dev->id, 1); + else + ui_sb_update_icon(SB_CDROM | dev->id, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + /* scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); } - } else - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); - - if (ret <= 0) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - scsi_cdrom_buf_free(dev); - return; } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - scsi_cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, - alloc_length, 0); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_CDROM | dev->id, 1); - else - ui_sb_update_icon(SB_CDROM | dev->id, 0); - return; + break; case GPCMD_READ_HEADER: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -2265,7 +2899,7 @@ begin: scsi_cdrom_set_buf_len(dev, BufLen, &len); scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; + break; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: @@ -2286,67 +2920,63 @@ begin: switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: + if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << (uint64_t) (cdb[2] & 0x3f)))) + ret = 0; break; default: - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) + ret = 0; break; } - memset(dev->buffer, 0, len); - alloc_length = len; - /* This determines the media type ID to return - this is - a SCSI/ATAPI-specific thing, so it makes the most sense - to keep this here. - Also, the max_len variable is reused as this command - does otherwise not use it, to avoid having to declare - another variable. */ - if (dev->drv->cd_status == CD_STATUS_EMPTY) - max_len = 70; /* No media inserted. */ - else if (dev->drv->cdrom_capacity > CD_MAX_SECTORS) - max_len = 65; /* DVD. */ - else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) - max_len = 1; /* Data CD. */ - else - max_len = 3; /* Audio or mixed-mode CD. */ + if (ret == 1) { + memset(dev->buffer, 0, len); + alloc_length = len; - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_cdrom_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = len - 1; - dev->buffer[1] = max_len; - if (block_desc) - dev->buffer[3] = 8; - } else { - len = scsi_cdrom_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = (len - 2) >> 8; - dev->buffer[1] = (len - 2) & 255; - dev->buffer[2] = max_len; - if (block_desc) { - dev->buffer[6] = 0; - dev->buffer[7] = 8; + /* This determines the media type ID to return - this is + a SCSI/ATAPI-specific thing, so it makes the most sense + to keep this here. + Also, the max_len variable is reused as this command + does otherwise not use it, to avoid having to declare + another variable. */ + if (dev->drv->cd_status == CD_STATUS_EMPTY) + max_len = 70; /* No media inserted. */ + else if (dev->drv->cdrom_capacity > CD_MAX_SECTORS) + max_len = 65; /* DVD. */ + else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) + max_len = 1; /* Data CD. */ + else + max_len = 3; /* Audio or mixed-mode CD. */ + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = scsi_cdrom_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = len - 1; + dev->buffer[1] = max_len; + if (block_desc) + dev->buffer[3] = 8; + } else { + len = scsi_cdrom_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = (len - 2) >> 8; + dev->buffer[1] = (len - 2) & 255; + dev->buffer[2] = max_len; + if (block_desc) { + dev->buffer[6] = 0; + dev->buffer[7] = 8; + } } - } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + scsi_cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); - return; + scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); + } else + scsi_cdrom_invalid_field(dev); + break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -2366,171 +2996,166 @@ begin: dev->do_page_save = cdb[1] & 1; scsi_cdrom_data_command_finish(dev, len, len, len, 1); - return; + break; case GPCMD_GET_CONFIGURATION: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - /* XXX: could result in alignment problems in some architectures */ + /* XXX: Could result in alignment problems in some architectures */ feature = (cdb[2] << 8) | cdb[3]; max_len = (cdb[7] << 8) | cdb[8]; - /* only feature 0 is supported */ - if ((feature > 3) && (feature != 0x010) && - (feature != 0x1d) && (feature != 0x01e) && - (feature != 0x01f) && (feature != 0x103)) { + /* Only feature 0 is supported */ + if ((feature > 3) && (feature != 0x010) && (feature != 0x1d) && (feature != 0x01e) && + (feature != 0x01f) && (feature != 0x103)) scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + else { + scsi_cdrom_buf_alloc(dev, 65536); + memset(dev->buffer, 0, max_len); - scsi_cdrom_buf_alloc(dev, 65536); - memset(dev->buffer, 0, max_len); + alloc_length = 0; + b = dev->buffer; - alloc_length = 0; - b = dev->buffer; + /* + The number of sectors from the media tells us which profile + to use as current. 0 means there is no media. + */ + if (dev->drv->cd_status != CD_STATUS_EMPTY) { + len = dev->drv->cdrom_capacity; + if (len > CD_MAX_SECTORS) { + b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; + b[7] = MMC_PROFILE_DVD_ROM & 0xff; + ret = 1; + } else { + b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; + b[7] = MMC_PROFILE_CD_ROM & 0xff; + ret = 0; + } + } else + ret = 2; - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (dev->drv->cd_status != CD_STATUS_EMPTY) { - len = dev->drv->cdrom_capacity; - if (len > CD_MAX_SECTORS) { - b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_DVD_ROM & 0xff; - ret = 1; - } else { - b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_CD_ROM & 0xff; - ret = 0; + alloc_length = 8; + b += 8; + + if ((feature == 0) || ((cdb[1] & 3) < 2)) { + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 8; + + alloc_length += 4; + b += 4; + + for (uint8_t i = 0; i < 2; i++) { + b[0] = (profiles[i] >> 8) & 0xff; + b[1] = profiles[i] & 0xff; + + if (ret == i) + b[2] |= 1; + + alloc_length += 4; + b += 4; + } } - } else - ret = 2; + if ((feature == 1) || ((cdb[1] & 3) < 2)) { + b[1] = 1; + b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 8; - alloc_length = 8; - b += 8; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + b[7] = 1; + else + b[7] = 2; + b[8] = 1; - if ((feature == 0) || ((cdb[1] & 3) < 2)) { - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; + alloc_length += 12; + b += 12; + } + if ((feature == 2) || ((cdb[1] & 3) < 2)) { + b[1] = 2; + b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 4; + b[4] = 2; - alloc_length += 4; - b += 4; + alloc_length += 8; + b += 8; + } + if ((feature == 3) || ((cdb[1] & 3) < 2)) { + b[1] = 2; + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 4; + b[4] = 0x0d; - for (uint8_t i = 0; i < 2; i++) { - b[0] = (profiles[i] >> 8) & 0xff; - b[1] = profiles[i] & 0xff; + /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and + early vendor SCSI CD-ROM models) are caddy drives, the later + ones are tray drives. */ + if (dev->drv->bus_type == CDROM_BUS_SCSI) + b[4] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00); + else + b[4] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) || + ((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20); - if (ret == i) - b[2] |= 1; + alloc_length += 8; + b += 8; + } + if ((feature == 0x10) || ((cdb[1] & 3) < 2)) { + b[1] = 0x10; + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 8; + + b[6] = 8; + b[9] = 0x10; + + alloc_length += 12; + b += 12; + } + if ((feature == 0x1d) || ((cdb[1] & 3) < 2)) { + b[1] = 0x1d; + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 0; alloc_length += 4; b += 4; } + if ((feature == 0x1e) || ((cdb[1] & 3) < 2)) { + b[1] = 0x1e; + b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 4; + b[4] = 0; + + alloc_length += 8; + b += 8; + } + if ((feature == 0x1f) || ((cdb[1] & 3) < 2)) { + b[1] = 0x1f; + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 0; + + alloc_length += 4; + b += 4; + } + if ((feature == 0x103) || ((cdb[1] & 3) < 2)) { + b[0] = 1; + b[1] = 3; + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 0; + b[4] = 7; + + b[6] = 1; + + alloc_length += 8; + b += 8; + } + + dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff; + dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff; + dev->buffer[2] = ((alloc_length - 4) >> 8) & 0xff; + dev->buffer[3] = (alloc_length - 4) & 0xff; + + alloc_length = MIN(alloc_length, max_len); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); } - if ((feature == 1) || ((cdb[1] & 3) < 2)) { - b[1] = 1; - b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - b[7] = 1; - else - b[7] = 2; - b[8] = 1; - - alloc_length += 12; - b += 12; - } - if ((feature == 2) || ((cdb[1] & 3) < 2)) { - b[1] = 2; - b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 4; - - b[4] = 2; - - alloc_length += 8; - b += 8; - } - if ((feature == 3) || ((cdb[1] & 3) < 2)) { - b[1] = 2; - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 4; - - b[4] = 0x0d; - /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and - early vendor SCSI CD-ROM models) are caddy drives, the later - ones are tray drives. */ - if (dev->drv->bus_type == CDROM_BUS_SCSI) - b[4] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00); - else - b[4] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) || - ((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20); - - alloc_length += 8; - b += 8; - } - if ((feature == 0x10) || ((cdb[1] & 3) < 2)) { - b[1] = 0x10; - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - b[6] = 8; - b[9] = 0x10; - - alloc_length += 12; - b += 12; - } - if ((feature == 0x1d) || ((cdb[1] & 3) < 2)) { - b[1] = 0x1d; - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 0; - - alloc_length += 4; - b += 4; - } - if ((feature == 0x1e) || ((cdb[1] & 3) < 2)) { - b[1] = 0x1e; - b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 4; - - b[4] = 0; - - alloc_length += 8; - b += 8; - } - if ((feature == 0x1f) || ((cdb[1] & 3) < 2)) { - b[1] = 0x1f; - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 0; - - alloc_length += 4; - b += 4; - } - if ((feature == 0x103) || ((cdb[1] & 3) < 2)) { - b[0] = 1; - b[1] = 3; - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 0; - - b[4] = 7; - b[6] = 1; - - alloc_length += 8; - b += 8; - } - - dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff; - dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff; - dev->buffer[2] = ((alloc_length - 4) >> 8) & 0xff; - dev->buffer[3] = (alloc_length - 4) & 0xff; - - alloc_length = MIN(alloc_length, max_len); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); break; case GPCMD_GET_EVENT_STATUS_NOTIFICATION: @@ -2541,56 +3166,56 @@ begin: gesn_cdb = (void *) cdb; gesn_event_header = (void *) dev->buffer; - /* It is fine by the MMC spec to not support async mode operations. */ - if (!(gesn_cdb->polled & 0x01)) { - /* asynchronous mode */ - /* Only polling is supported, asynchronous mode is not. */ + if (gesn_cdb->polled & 0x01) { + /* + * These are the supported events. + * + * We currently only support requests of the 'media' type. + * Notification class requests and supported event classes are bitmasks, + * but they are built from the same values as the "notification class" + * field. + */ + gesn_event_header->supported_events = 1 << GESN_MEDIA; + + /* + * We use |= below to set the class field; other bits in this byte + * are reserved now but this is useful to do if we have to use the + * reserved fields later. + */ + gesn_event_header->notification_class = 0; + + /* + * Responses to requests are to be based on request priority. The + * notification_class_request_type enum above specifies the + * priority: upper elements are higher prio than lower ones. + */ + if (gesn_cdb->class & (1 << GESN_MEDIA)) { + gesn_event_header->notification_class |= GESN_MEDIA; + + dev->buffer[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ + dev->buffer[5] = 1; /* Power Status (1 = Active) */ + dev->buffer[6] = 0; + dev->buffer[7] = 0; + used_len = 8; + } else { + gesn_event_header->notification_class = 0x80; /* No event available */ + used_len = sizeof(*gesn_event_header); + } + gesn_event_header->len = used_len - sizeof(*gesn_event_header); + + memmove(dev->buffer, gesn_event_header, 4); + + scsi_cdrom_set_buf_len(dev, BufLen, &used_len); + + scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); + } else { + /* + Only polling is supported, asynchronous mode is not. + It is fine by the MMC spec to not support async mode operations. + */ scsi_cdrom_invalid_field(dev); scsi_cdrom_buf_free(dev); - return; } - - /* - * These are the supported events. - * - * We currently only support requests of the 'media' type. - * Notification class requests and supported event classes are bitmasks, - * but they are built from the same values as the "notification class" - * field. - */ - gesn_event_header->supported_events = 1 << GESN_MEDIA; - - /* - * We use |= below to set the class field; other bits in this byte - * are reserved now but this is useful to do if we have to use the - * reserved fields later. - */ - gesn_event_header->notification_class = 0; - - /* - * Responses to requests are to be based on request priority. The - * notification_class_request_type enum above specifies the - * priority: upper elements are higher prio than lower ones. - */ - if (gesn_cdb->class & (1 << GESN_MEDIA)) { - gesn_event_header->notification_class |= GESN_MEDIA; - - dev->buffer[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ - dev->buffer[5] = 1; /* Power Status (1 = Active) */ - dev->buffer[6] = 0; - dev->buffer[7] = 0; - used_len = 8; - } else { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - gesn_event_header->len = used_len - sizeof(*gesn_event_header); - - memmove(dev->buffer, gesn_event_header, 4); - - scsi_cdrom_set_buf_len(dev, BufLen, &used_len); - - scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); break; case GPCMD_READ_DISC_INFORMATION: @@ -2632,213 +3257,36 @@ begin: track |= ((uint32_t) cdb[4]) << 8; track |= (uint32_t) cdb[5]; - if (((cdb[1] & 0x03) != 1) || (track != 1)) { + if (((cdb[1] & 0x03) != 1) || (track != 1)) scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + else { + len = 36; - len = 36; + memset(dev->buffer, 0, 36); + dev->buffer[0] = 0; + dev->buffer[1] = 34; + dev->buffer[2] = 1; /* track number (LSB) */ + dev->buffer[3] = 1; /* session number (LSB) */ + dev->buffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ + dev->buffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | /* not reserved track, not blank, */ + (0 << 6) | (1 << 0); /* not packet writing, not fixed packet, */ + /* data mode 1 */ + dev->buffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, */ + /* next recordable address not valid */ - memset(dev->buffer, 0, 36); - dev->buffer[0] = 0; - dev->buffer[1] = 34; - dev->buffer[2] = 1; /* track number (LSB) */ - dev->buffer[3] = 1; /* session number (LSB) */ - dev->buffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ - dev->buffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ - dev->buffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ + dev->buffer[24] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; /* track size */ + dev->buffer[25] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; /* track size */ + dev->buffer[26] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; /* track size */ + dev->buffer[27] = (dev->drv->cdrom_capacity - 1) & 0xff; /* track size */ - dev->buffer[24] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; /* track size */ - dev->buffer[25] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; /* track size */ - dev->buffer[26] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; /* track size */ - dev->buffer[27] = (dev->drv->cdrom_capacity - 1) & 0xff; /* track size */ + if (len > max_len) { + len = max_len; + dev->buffer[0] = ((max_len - 2) >> 8) & 0xff; + dev->buffer[1] = (max_len - 2) & 0xff; + } - if (len > max_len) { - len = max_len; - dev->buffer[0] = ((max_len - 2) >> 8) & 0xff; - dev->buffer[1] = (max_len - 2) & 0xff; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); - break; - - case 0xC0: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_SET_ADDRESS_FORMAT_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - dev->drv->sony_msf = cdb[8] & 1; - scsi_cdrom_command_complete(dev); - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_MAGAZINE_EJECT_PIONEER*/ - case CDROM_TYPE_CHINON_CDS431_H42: /*GPCMD_EJECT_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xD8: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC1: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_TOC_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - dev->sony_vendor = 1; - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 65536); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf || dev->drv->sony_msf, max_len); - if (len == -1) { - /* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_READ_TOC_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 4); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 4; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_PLAY_AUDIO_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xD9: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_PLAY_AUDIO_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); } break; @@ -2848,10 +3296,10 @@ begin: case GPCMD_PLAY_AUDIO_TRACK_INDEX: case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: - len = 0; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + len = 0; + switch (cdb[0]) { case GPCMD_PLAY_AUDIO_10: msf = 0; @@ -2870,12 +3318,11 @@ begin: break; case GPCMD_PLAY_AUDIO_TRACK_INDEX: msf = 2; - if ((cdb[5] != 1) || (cdb[8] != 1)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = cdb[4]; - len = cdb[7]; + if ((cdb[5] == 1) && (cdb[8] == 1)) { + pos = cdb[4]; + len = cdb[7]; + } else + ret = 0; break; case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: msf = 0x100 | cdb[6]; @@ -2892,12 +3339,10 @@ begin: break; } - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - - ret = cdrom_audio_play(dev->drv, pos, len, msf); + if (ret && (dev->drv->image_path[0] != 0x00) && (dev->drv->cd_status > CD_STATUS_DATA_ONLY)) + ret = cdrom_audio_play(dev->drv, pos, len, msf); + else + ret = 0; if (ret) scsi_cdrom_command_complete(dev); @@ -2921,23 +3366,15 @@ begin: /* scsi_cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", dev->id, cdb[3]); */ scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (max_len <= 0) { + } else if (max_len <= 0) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * CDROM_TIME; scsi_cdrom_set_callback(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (!(cdb[2] & 0x40)) - alloc_length = 4; - else - switch (cdb[3]) { + } else { + if (!(cdb[2] & 0x40)) + alloc_length = 4; + else switch (cdb[3]) { case 0: /* SCSI-2: Q-type subchannel, ATAPI: reserved */ alloc_length = (dev->drv->bus_type == CDROM_BUS_SCSI) ? 48 : 4; @@ -2950,21 +3387,21 @@ begin: break; } - len = alloc_length; + len = alloc_length; - memset(dev->buffer, 0, 24); - pos = 0; - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; /*Audio status*/ - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; /*Subchannel length*/ - /* Mode 0 = Q subchannel mode, first 16 bytes are indentical to mode 1 (current position), - the rest are stuff like ISRC etc., which can be all zeroes. */ - if (cdb[3] <= 3) { - dev->buffer[pos++] = cdb[3]; /*Format code*/ + memset(dev->buffer, 0, 24); + pos = 0x00; + dev->buffer[pos++] = 0x00; + dev->buffer[pos++] = 0x00; /* Audio status */ + dev->buffer[pos++] = 0x00; + dev->buffer[pos++] = 0x00; /* Subchannel length */ + dev->buffer[pos++] = cdb[3]; /* Format code */ if (alloc_length != 4) { - dev->buffer[1] = cdrom_get_current_subchannel(dev->drv, &dev->buffer[4], msf); + dev->buffer[1] = cdrom_get_current_status(dev->drv); + + cdrom_get_current_subchannel(dev->drv, &dev->buffer[4], msf); + dev->buffer[2] = alloc_length - 4; } @@ -2973,140 +3410,25 @@ begin: dev->buffer[1] = 0x11; break; case CD_STATUS_PAUSED: - dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x15 : 0x12; + dev->buffer[1] = ((dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) || + (dev->drv->type == CDROM_TYPE_CHINON_CDX435_M62)) ? 0x15 : 0x12; break; case CD_STATUS_DATA_ONLY: - dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x00 : 0x15; + dev->buffer[1] = ((dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) || + (dev->drv->type == CDROM_TYPE_CHINON_CDX435_M62)) ? 0x00 : 0x15; break; default: - dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x00 : 0x13; + dev->buffer[1] = ((dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) || + (dev->drv->type == CDROM_TYPE_CHINON_CDX435_M62)) ? 0x00 : 0x13; break; } scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[1]); - } - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case 0xC6: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_TRACK_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - - msf = 3; - if ((cdb[5] != 1) || (cdb[8] != 1)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = cdb[4]; - - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - - /* In this case, len is unused so just pass a fixed value of 1 intead. */ - ret = cdrom_audio_play(dev->drv, pos, 1 /*len*/, msf); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - case CDROM_TYPE_CHINON_CDS431_H42: /*GPCMD_STOP_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - len = 10; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); - - memset(dev->buffer, 0, len); - dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xDD: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - len = 10; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); - - memset(dev->buffer, 0, len); - dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; + scsi_cdrom_data_command_finish(dev, len, len, len, 0); } break; @@ -3117,43 +3439,31 @@ begin: scsi_cdrom_buf_alloc(dev, alloc_length); - if ((cdb[7] < 0xc0) && (dev->drv->cdrom_capacity <= CD_MAX_SECTORS)) { + if ((cdb[7] < 0xc0) && (dev->drv->cdrom_capacity <= CD_MAX_SECTORS)) scsi_cdrom_incompatible_format(dev); - scsi_cdrom_buf_free(dev); - return; - } + else { + memset(dev->buffer, 0, alloc_length); - memset(dev->buffer, 0, alloc_length); - - if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { - if (cdb[1] == 0) { - format = cdb[7]; - ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, dev->buffer); - dev->buffer[0] = (ret >> 8); - dev->buffer[1] = (ret & 0xff); - dev->buffer[2] = dev->buffer[3] = 0x00; - if (ret) { - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, - alloc_length, 0); - } else - scsi_cdrom_buf_free(dev); - return; - } - } else { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - break; - - case 0x26: - if (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) { /*GPCMD_UNKNOWN_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - } else { - scsi_cdrom_illegal_opcode(dev); + if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { + if (cdb[1] == 0) { + format = cdb[7]; + ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, dev->buffer); + dev->buffer[0] = (ret >> 8); + dev->buffer[1] = (ret & 0xff); + dev->buffer[2] = dev->buffer[3] = 0x00; + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, + alloc_length, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + } + } else + scsi_cdrom_invalid_field(dev); } break; @@ -3183,80 +3493,6 @@ begin: scsi_cdrom_command_complete(dev); break; - case 0xC4: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_HEADER_MATSUSHITA*/ - cdb[0] = GPCMD_READ_HEADER; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAYBACK_STATUS_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - - scsi_cdrom_buf_alloc(dev, 18); - - len = 18; - - memset(dev->buffer, 0, 18); - dev->buffer[0] = 0x00; /*Reserved*/ - dev->buffer[1] = 0x00; /*Reserved*/ - dev->buffer[2] = 0x00; /*Audio Status data length*/ - dev->buffer[3] = 0x00; /*Audio Status data length*/ - dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf || dev->drv->sony_msf); /*Audio status*/ - dev->buffer[5] = 0x00; - - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); - - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_CADDY_EJECT_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xDC: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_CADDY_EJECT_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - case GPCMD_INQUIRY: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -3331,39 +3567,39 @@ begin: memset(dev->buffer, 0, 8); if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) - dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + dev->buffer[0] = 0x7f; /* No physical device on this LUN */ else - dev->buffer[0] = 5; /*CD-ROM*/ - dev->buffer[1] = 0x80; /*Removable*/ + dev->buffer[0] = 5; /* CD-ROM */ + dev->buffer[1] = 0x80; /* Removable */ if (dev->drv->bus_type == CDROM_BUS_SCSI) { dev->buffer[3] = 0x02; switch (dev->drv->type) { case CDROM_TYPE_CHINON_CDS431_H42: + case CDROM_TYPE_CHINON_CDX435_M62: case CDROM_TYPE_DEC_RRD45_0436: case CDROM_TYPE_MATSHITA_501_10b: + case CDROM_TYPE_ShinaKen_DM3x1S_104: case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEAC_CD50_100: - case CDROM_TYPE_TEAC_R55S_10R: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_TEXEL_DM3024_100: dev->buffer[2] = 0x00; - dev->buffer[3] = 0x01; /*SCSI-1 compliant*/ + dev->buffer[3] = 0x01; /* SCSI-1 compliant */ + break; + case CDROM_TYPE_TEXEL_DM3028_106: + dev->buffer[2] = 0x02; + dev->buffer[3] = 0x01; /* SCSI-2 compliant */ break; case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: case CDROM_TYPE_NEC_75_103: case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - dev->buffer[3] = 0x00; /*SCSI unknown version per NEC manuals*/ + dev->buffer[3] = 0x00; /* SCSI unknown version per NEC manuals */ break; case CDROM_TYPE_TOSHIBA_XM3201B_3232: dev->buffer[2] = 0x01; - dev->buffer[3] = 0x01; /*SCSI-1 compliant*/ + dev->buffer[3] = 0x01; /* SCSI-1 compliant */ break; default: - dev->buffer[2] = 0x02; /*SCSI-2 compliant*/ + dev->buffer[2] = 0x02; /* SCSI-2 compliant */ break; } } else { @@ -3374,12 +3610,12 @@ begin: dev->buffer[4] = 31; if (dev->drv->bus_type == CDROM_BUS_SCSI) { switch (dev->drv->type) { - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-1 (or SCSI-2) CD-ROM drives from 1989-1990*/ - dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ + case CDROM_TYPE_TOSHIBA_XM_3433 ... CDROM_TYPE_TOSHIBA_XM5701TA_3136: + dev->buffer[4] = 91; /* + Always 91 on Toshiba SCSI-1 (or SCSI-2) + CD-ROM drives from 1989-1990 + */ + dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ break; case CDROM_TYPE_PIONEER_DRM604X_2403: dev->buffer[4] = 42; @@ -3388,12 +3624,10 @@ begin: case CDROM_TYPE_NEC_38_103: case CDROM_TYPE_NEC_75_103: case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: break; default: - dev->buffer[6] = 0x01; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ + dev->buffer[6] = 0x01; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ break; } } @@ -3417,10 +3651,7 @@ begin: idx = 47; else { switch (dev->drv->type) { - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: + case CDROM_TYPE_TOSHIBA_XM_3433 ... CDROM_TYPE_TOSHIBA_XM5701TA_3136: idx = 96; break; default: @@ -3439,17 +3670,12 @@ atapi_out: len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_set_buf_len(dev, BufLen, &max_len); scsi_cdrom_log("Inquiry = %d, max = %d, BufLen = %d.\n", len, max_len, *BufLen); scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); break; - case 0x0D: /*GPCMD_NO_OPERATION_TOSHIBA and GPCMD_NO_OPERATION_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - case GPCMD_PREVENT_REMOVAL: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); scsi_cdrom_command_complete(dev); @@ -3462,154 +3688,6 @@ atapi_out: scsi_cdrom_command_complete(dev); break; - case 0xC3: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_TOC_MATSUSHITA*/ - cdb[0] = GPCMD_READ_TOC_PMA_ATIP; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_HEADER_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; - - alloc_length = ((cdb[7] << 8) | cdb[8]); - scsi_cdrom_buf_alloc(dev, 4); - - dev->sector_len = 1; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); - dev->buffer[0] = ((real_pos >> 16) & 0xff); - dev->buffer[1] = ((real_pos >> 8) & 0xff); - dev->buffer[2] = real_pos & 0xff; - dev->buffer[3] = 1; /*2048 bytes user data*/ - - len = 4; - len = MIN(len, alloc_length); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_SET_STOP_TIME_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xDB: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_SET_STOP_TIME_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC2: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_SUBCHANNEL_MATSUSHITA*/ - cdb[0] = GPCMD_READ_SUBCHANNEL; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_SUBCHANNEL_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - - scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s), code-q = %02x\n", dev->id, msf ? "MSF" : "LBA", cdb[2] & 0x40); - - if (cdb[2] & 0x40) { - scsi_cdrom_buf_alloc(dev, 9); - memset(dev->buffer, 0, 9); - len = 9; - cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf || dev->drv->sony_msf); - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - } else { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - } - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_READ_SUBCODEQ_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - len = 9; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); - - memset(dev->buffer, 0, len); - cdrom_get_current_subcodeq(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_STILL_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, 0x00); - dev->drv->audio_op = 0x01; - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - case GPCMD_SEEK_6: case GPCMD_SEEK_10: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); @@ -3625,20 +3703,13 @@ atapi_out: default: break; } + dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos)); + if (cdb[0] == GPCMD_SEEK_10) { switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: + case CDROM_TYPE_NEC_25_10a ... CDROM_TYPE_NEC_464_105: + case CDROM_TYPE_TOSHIBA_XM_3433 ... CDROM_TYPE_TOSHIBA_SDM1401_1008: cdrom_seek(dev->drv, pos, cdb[9] & 0xc0); break; default: @@ -3665,6 +3736,7 @@ atapi_out: dev->buffer[6] = 8; len = 8; + scsi_cdrom_log("CD-ROM Capacity=%x.\n", dev->drv->cdrom_capacity - 1); scsi_cdrom_set_buf_len(dev, BufLen, &len); scsi_cdrom_data_command_finish(dev, len, len, len, 0); @@ -3682,226 +3754,6 @@ atapi_out: scsi_cdrom_command_complete(dev); break; - case 0xC5: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_10; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PAUSE_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC8: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_AUDIO_SONY*/ - cdb[0] = GPCMD_PLAY_AUDIO_10; - dev->current_cdb[0] = cdb[0]; - dev->sony_vendor = 1; - goto begin; - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_AUDIO_TRACK_SEARCH_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search_pioneer(dev->drv, pos, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC9: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAYBACK_CONTROL_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); - dev->sony_vendor = 1; - - len = (cdb[7] << 8) | cdb[8]; - if (!len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: PlayBack Control Sony All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - scsi_cdrom_buf_alloc(dev, 65536); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 1); - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_PLAY_AUDIO_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_pioneer(dev->drv, pos); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xCA: - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_PAUSE_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); - scsi_cdrom_command_complete(dev); - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xCB: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PAUSE_RESUME_MATSUSHITA*/ - cdb[0] = GPCMD_PAUSE_RESUME; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_STOP_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xCC: - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_PLAYBACK_STATUS_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 6); - - len = 6; - - memset(dev->buffer, 0, 6); - dev->buffer[0] = cdrom_get_audio_status_pioneer(dev->drv, &dev->buffer[1]); /*Audio status*/ - - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); - - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xE0: - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_DRIVE_STATUS_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - len = (cdb[9] | (cdb[8] << 8)); - scsi_cdrom_buf_alloc(dev, 65536); - - if (!(scsi_cdrom_drive_status_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (!len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - memset(dev->buffer, 0, len); - alloc_length = len; - - len = scsi_cdrom_drive_status(dev, dev->buffer, 0, cdb[2]); - len = MIN(len, alloc_length); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_log("CD-ROM %i: Reading drive status page: %02X...\n", dev->id, cdb[2]); - - scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); - return; - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xE5: - if (dev->drv->type == CDROM_TYPE_MATSHITA_501_10b) { /*GPCMD_PLAY_AUDIO_12_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_12; - dev->current_cdb[0] = cdb[0]; - goto begin; - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xE9: - if (dev->drv->type == CDROM_TYPE_MATSHITA_501_10b) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12; - dev->current_cdb[0] = cdb[0]; - goto begin; - } - fallthrough; default: scsi_cdrom_illegal_opcode(dev); break; @@ -3959,6 +3811,7 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) block_desc_len = dev->buffer[2]; block_desc_len <<= 8; block_desc_len |= dev->buffer[3]; + scsi_cdrom_log("BlockDescLen (6)=%d, ParamListLen (6)=%d.\n", block_desc_len, param_list_len); } else { block_desc_len = dev->buffer[6]; block_desc_len <<= 8; @@ -3967,8 +3820,21 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) } else block_desc_len = 0; + if (block_desc_len >= 8) { + pos = hdr_len + 5; + + dev->drv->sector_size = (dev->drv->sector_size & 0x0000ffff) | (dev->buffer[pos++] << 16); + dev->drv->sector_size = (dev->drv->sector_size & 0x00ff00ff) | (dev->buffer[pos++] << 8); + dev->drv->sector_size = (dev->drv->sector_size & 0x00ffff00) | (dev->buffer[pos++]); + scsi_cdrom_log("CD-ROM %i: Sector size now %i bytes\n", dev->id, dev->drv->sector_size); + } + pos = hdr_len + block_desc_len; +#ifdef ENABLE_SCSI_CDROM_LOG + for (uint16_t j = 0; j < pos; j++) + scsi_cdrom_log("Buffer Mode Select, pos=%d, data=%02x.\n", j, dev->buffer[j]); +#endif while (1) { if (pos >= param_list_len) { scsi_cdrom_log("CD-ROM %i: Buffer has only block descriptor\n", dev->id); @@ -3982,10 +3848,11 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: + if ((page == 0x08) && (page_len == 0x02)) + dev->drv->sony_msf = dev->buffer[pos] & 0x01; + if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << ((uint64_t) page)))) { scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); error |= 1; @@ -3998,7 +3865,8 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) if (ch) dev->ms_pages_saved_sony.pages[page][i + 2] = val; else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); + scsi_cdrom_log("CD-ROM %i: Unchangeable value on position " + "%02X on page %02X\n", dev->id, i + 2, page); error |= 1; } } @@ -4018,7 +3886,8 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) if (ch) dev->ms_pages_saved.pages[page][i + 2] = val; else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); + scsi_cdrom_log("CD-ROM %i: Unchangeable value on position " + "%02X on page %02X\n", dev->id, i + 2, page); error |= 1; } } @@ -4031,10 +3900,8 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: val = scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][0] & 0x80; break; default: @@ -4060,13 +3927,10 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) case 0xC9: switch (dev->drv->type) { case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - for (i = 0; i < 18; i++) { + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: + for (i = 0; i < 18; i++) dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY][i] = dev->buffer[i]; - } break; default: break; @@ -4303,6 +4167,8 @@ scsi_cdrom_drive_reset(int c) drv->get_channel = scsi_cdrom_get_channel; drv->close = scsi_cdrom_close; + drv->sector_size = 2048; + if (drv->bus_type == CDROM_BUS_SCSI) { valid = 1; @@ -4352,6 +4218,32 @@ scsi_cdrom_drive_reset(int c) scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel); } + switch (dev->drv->type) { + case CDROM_TYPE_CHINON_CDS431_H42: + dev->ven_cmd = scsi_cdrom_command_chinon; + break; + case CDROM_TYPE_DEC_RRD45_0436: + case CDROM_TYPE_ShinaKen_DM3x1S_104 ... CDROM_TYPE_SONY_CDU76S_100: + case CDROM_TYPE_TEXEL_DM3024_100 ... CDROM_TYPE_TEXEL_DM3028_106: + dev->ven_cmd = scsi_cdrom_command_dec_sony_texel; + break; + case CDROM_TYPE_MATSHITA_501_10b: + dev->ven_cmd = scsi_cdrom_command_matsushita; + break; + case CDROM_TYPE_NEC_25_10a ... CDROM_TYPE_NEC_464_105: + dev->ven_cmd = scsi_cdrom_command_nec; + break; + case CDROM_TYPE_PIONEER_DRM604X_2403: + dev->ven_cmd = scsi_cdrom_command_pioneer; + break; + case CDROM_TYPE_TOSHIBA_XM_3433 ... CDROM_TYPE_TOSHIBA_SDM1401_1008: + dev->ven_cmd = scsi_cdrom_command_toshiba; + break; + default: + dev->ven_cmd = NULL; + break; + } + if (valid) scsi_cdrom_init(dev); } diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index bf656177b..8555642e6 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -218,18 +218,14 @@ plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector)) } int -plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector) +plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector) { dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; plat_cdrom_open(ioctl); - if (raw) - /* Raw */ - dummy_cdrom_ioctl_log("Raw\n"); - else - /* Cooked */ - dummy_cdrom_ioctl_log("Cooked\n"); + /* Raw */ + dummy_cdrom_ioctl_log("Raw\n"); plat_cdrom_close(ioctl); From 31875958856c37066b7d32ec904d221c952134ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 04:40:14 +0100 Subject: [PATCH 24/52] Fixed some warnings. --- src/cdrom/cdrom.c | 4 ++++ src/cdrom/cdrom_image.c | 5 ++++- src/cdrom/cdrom_image_backend.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 784b84a39..84a6229bd 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1200,7 +1200,9 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m } if (s != -1) for (int i = s; i < j; i++) { +#ifdef ENABLE_CDROM_LOG uint8_t *c = &(b[len]); +#endif if (!sony) b[len++] = 0; /* Reserved */ @@ -1235,8 +1237,10 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m b[len++] = temp; } +#ifdef ENABLE_CDROM_LOG cdrom_log("Track %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n", i, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]); +#endif } } else b[2] = b[3] = 0; diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 6e06676f8..f74e0d344 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -293,13 +293,16 @@ cdrom_image_open(cdrom_t *dev, const char *fn) dev->seek_pos = 0; dev->cd_buflen = 0; dev->cdrom_capacity = image_get_capacity(dev); - cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); + cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, + ((uint64_t) dev->cdrom_capacity) << 11ULL); +#ifdef ENABLE_CDROM_IMAGE_LOG int cm, cs, cf; cf = dev->cdrom_capacity % 75; cs = (dev->cdrom_capacity / 75) % 60; cm = (dev->cdrom_capacity / 75) / 60; cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf); +#endif /* Attach this handler to the drive. */ dev->ops = &cdrom_image_ops; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 3e0fa017a..fdc4f662f 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -1457,6 +1457,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) prev->indexes[2].length = 0; } +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG for (int i = 0; i < cdi->tracks_num; i++) { track_t *t = &(cdi->tracks[i]); for (int j = 0; j < 3; j++) { @@ -1472,6 +1473,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) (int) ((ti->start + ti->length - 1) % 75)); } } +#endif return 1; } From 8e60cc7bea368ee3dcf46652d15d6de1b6fab690 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 30 Dec 2024 21:47:27 -0500 Subject: [PATCH 25/52] Add Vibra 16CL --- src/include/86box/sound.h | 7 ++- src/sound/snd_sb.c | 126 +++++++++++++++++++++++++------------- src/sound/sound.c | 1 + 3 files changed, 91 insertions(+), 43 deletions(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 2a6347b9c..9029b336d 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -109,6 +109,7 @@ extern void givealbuffer_wt(const void *buf); extern void givealbuffer_cd(const void *buf); #define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base +#define sb_vibra16cl_onboard_relocate_base sb_vibra16s_onboard_relocate_base #define sb_vibra16xv_onboard_relocate_base sb_vibra16s_onboard_relocate_base extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv); @@ -144,12 +145,14 @@ extern const device_t sb_pro_v2_device; extern const device_t sb_pro_mcv_device; extern const device_t sb_pro_compat_device; extern const device_t sb_16_device; +extern const device_t sb_vibra16c_onboard_device; +extern const device_t sb_vibra16c_device; +extern const device_t sb_vibra16cl_onboard_device; +extern const device_t sb_vibra16cl_device; extern const device_t sb_vibra16s_onboard_device; extern const device_t sb_vibra16s_device; extern const device_t sb_vibra16xv_onboard_device; extern const device_t sb_vibra16xv_device; -extern const device_t sb_vibra16c_onboard_device; -extern const device_t sb_vibra16c_device; extern const device_t sb_16_pnp_device; extern const device_t sb_16_pnp_ide_device; extern const device_t sb_16_compat_device; diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 70cc8708b..b71f1557c 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -60,8 +60,9 @@ #define PNP_ROM_SB_16_PNP_NOIDE "roms/sound/creative/CT2941 PnP.BIN" #define PNP_ROM_SB_16_PNP_IDE "roms/sound/creative/CTL0024A.BIN" /* CT2940 */ -#define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" #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_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" @@ -3391,17 +3392,24 @@ sb_16_pnp_init(UNUSED(const device_t *info)) return sb; } +static int +sb_vibra16c_available(void) +{ + return rom_present(PNP_ROM_SB_VIBRA16C); +} + +static int +sb_vibra16cl_available(void) +{ + return rom_present(PNP_ROM_SB_VIBRA16CL); +} + static int sb_vibra16xv_available(void) { return rom_present(PNP_ROM_SB_VIBRA16XV); } -static int -sb_vibra16c_available(void) -{ - return rom_present(PNP_ROM_SB_VIBRA16C); -} static void * sb_vibra16_pnp_init(UNUSED(const device_t *info)) @@ -3437,26 +3445,33 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); switch (info->local) { + case SB_VIBRA16C: /* CTL7001 */ + case SB_VIBRA16CL: /* CTL7002 */ + sb->gameport = gameport_add(&gameport_pnp_device); + break; + case SB_VIBRA16XV: /* CTL7005 */ sb->gameport = gameport_add(&gameport_pnp_1io_device); break; - case SB_VIBRA16C: /* CTL7001/CTL7002 */ default: - sb->gameport = gameport_add(&gameport_pnp_device); break; } const char *pnp_rom_file = NULL; switch (info->local) { - case SB_VIBRA16XV: - pnp_rom_file = PNP_ROM_SB_VIBRA16XV; - break; - case SB_VIBRA16C: pnp_rom_file = PNP_ROM_SB_VIBRA16C; break; + case SB_VIBRA16CL: + pnp_rom_file = PNP_ROM_SB_VIBRA16CL; + break; + + case SB_VIBRA16XV: + pnp_rom_file = PNP_ROM_SB_VIBRA16XV; + break; + default: break; } @@ -3473,8 +3488,9 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) } switch (info->local) { - case SB_VIBRA16XV: case SB_VIBRA16C: + case SB_VIBRA16CL: + case SB_VIBRA16XV: isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_vibra16_pnp_config_changed, NULL, NULL, NULL, sb); break; @@ -5723,6 +5739,62 @@ const device_t sb_16_device = { .config = sb_16_config }; +const device_t sb_vibra16c_onboard_device = { + .name = "Sound Blaster ViBRA 16C (On-Board)", + .internal_name = "sb_vibra16c_onboard", + .flags = DEVICE_ISA | DEVICE_AT, + .local = SB_VIBRA16C, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16c_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16c_device = { + .name = "Sound Blaster ViBRA 16C", + .internal_name = "sb_vibra16c", + .flags = DEVICE_ISA | DEVICE_AT, + .local = SB_VIBRA16C, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16c_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16cl_onboard_device = { + .name = "Sound Blaster ViBRA 16CL (On-Board)", + .internal_name = "sb_vibra16cl_onboard", + .flags = DEVICE_ISA | DEVICE_AT, + .local = SB_VIBRA16CL, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16cl_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16cl_device = { + .name = "Sound Blaster ViBRA 16CL", + .internal_name = "sb_vibra16cl", + .flags = DEVICE_ISA | DEVICE_AT, + .local = SB_VIBRA16CL, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16cl_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + const device_t sb_vibra16s_onboard_device = { .name = "Sound Blaster ViBRA 16S (On-Board)", .internal_name = "sb_vibra16s_onboard", @@ -5779,34 +5851,6 @@ const device_t sb_vibra16xv_device = { .config = sb_16_pnp_config }; -const device_t sb_vibra16c_onboard_device = { - .name = "Sound Blaster ViBRA 16C (On-Board)", - .internal_name = "sb_vibra16c_onboard", - .flags = DEVICE_ISA | DEVICE_AT, - .local = SB_VIBRA16C, - .init = sb_vibra16_pnp_init, - .close = sb_close, - .reset = NULL, - .available = sb_vibra16c_available, - .speed_changed = sb_speed_changed, - .force_redraw = NULL, - .config = sb_16_pnp_config -}; - -const device_t sb_vibra16c_device = { - .name = "Sound Blaster ViBRA 16C", - .internal_name = "sb_vibra16c", - .flags = DEVICE_ISA | DEVICE_AT, - .local = SB_VIBRA16C, - .init = sb_vibra16_pnp_init, - .close = sb_close, - .reset = NULL, - .available = sb_vibra16c_available, - .speed_changed = sb_speed_changed, - .force_redraw = NULL, - .config = sb_16_pnp_config -}; - const device_t sb_16_reply_mca_device = { .name = "Sound Blaster 16 Reply MCA", .internal_name = "sb16_reply_mca", diff --git a/src/sound/sound.c b/src/sound/sound.c index 9b974f022..06f38d125 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -131,6 +131,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_awe64_ide_device }, { &sb_awe64_gold_device }, { &sb_vibra16c_device }, + { &sb_vibra16cl_device }, { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &ssi2001_device }, From 084011bd700efd0027ed38d3d38e1021e884f83a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 04:58:59 +0100 Subject: [PATCH 26/52] cdrom/cdrom.c: Fix some nonsense with labels, fixes compile error on... I think Linux? --- src/cdrom/cdrom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 84a6229bd..ac002ab65 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1894,14 +1894,14 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c case 0x00: lba = sector; break; - case 0x40: + case 0x40: { int m = bcd2bin((sector >> 24) & 0xff); int s = bcd2bin((sector >> 16) & 0xff); int f = bcd2bin((sector >> 8) & 0xff); lba = MSFtoLBA(m, s, f) - 150; break; - case 0x80: + } case 0x80: lba = bcd2bin((sector >> 24) & 0xff); break; /* Never used values but the compiler complains. */ From bc117cf24d9929e4dbaf7f1145e77865f15f8290 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 31 Dec 2024 00:10:56 -0500 Subject: [PATCH 27/52] Add a line which got lost in snd_sb.c --- src/sound/snd_sb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index b71f1557c..df0547fdc 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -50,6 +50,7 @@ #define SB_VIBRA16XV 0 #define SB_VIBRA16C 1 +#define SB_VIBRA16CL 2 #define SB_32_PNP 0 #define SB_AWE32_PNP 1 From 0f61db03eff6b19f52653604d7a0416fd4f8a383 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Dec 2024 07:37:59 +0100 Subject: [PATCH 28/52] qt/win_cdrom_ioctl.c - fix CLang complication. --- src/qt/win_cdrom_ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index f89ec7412..7e3a588c3 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -26,6 +26,7 @@ #include "ntddcdrm.h" #include "ntddscsi.h" #include +#include #include #include #include From 263fea8ed8281f8d6ecae34cf7ffc0f4d8da6092 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Tue, 31 Dec 2024 14:39:24 +0700 Subject: [PATCH 29/52] Added 20 forgotten HDD models Also a few change to the Caviar 2850 --- src/disk/hdd.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 65b731340..4fe21ad12 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -419,16 +419,21 @@ 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 }, @@ -450,10 +455,19 @@ 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", .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 }, @@ -461,12 +475,18 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 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 }, { .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] 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", .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] 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 }, From 7a8a45508eeb3a1f85f08efdc9205977e45e3b78 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Wed, 1 Jan 2025 02:21:52 +0700 Subject: [PATCH 30/52] Some name changes to the MK2101MAN --- src/disk/hdd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 4fe21ad12..3f752cecb 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -460,7 +460,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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] Toshiba MK2101MAN", .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] 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 }, From 78f993c9488d8df6d39de8a45b5abe840658ef62 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Wed, 1 Jan 2025 02:42:08 +0700 Subject: [PATCH 31/52] Added a note on Caviar 21700 --- src/disk/hdd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 3f752cecb..653987e66 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -477,7 +477,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 }, + { .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 }, From 17f9ed66da73c054bdc6e92697d164eb9f7bd35b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 31 Dec 2024 20:43:02 +0100 Subject: [PATCH 32/52] DMA change of the day (December 31st, 2024) Actually add DMA PS/2 (MCA) XFER commands 0x9 (Set DMA Mask), 0xa (Reset DMA mask) and 0xb to addr 0x1a in both r/w parts. --- src/dma.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/dma.c b/src/dma.c index 86c29fe26..4edeb39f8 100644 --- a/src/dma.c +++ b/src/dma.c @@ -665,6 +665,19 @@ dma_ps2_read(uint16_t addr, UNUSED(void *priv)) temp = dma_c->arb_level; break; + case 9: /*Set DMA mask*/ + dma_m |= (1 << dma_ps2.xfr_channel); + break; + + case 0xa: /*Reset DMA mask*/ + dma_m &= ~(1 << dma_ps2.xfr_channel); + break; + + case 0xb: + if (!(dma_m & (1 << dma_ps2.xfr_channel))) + dma_ps2_run(dma_ps2.xfr_channel); + break; + default: fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); } @@ -767,6 +780,19 @@ dma_ps2_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) dma_c->arb_level = val; break; + case 9: /*Set DMA mask*/ + dma_m |= (1 << dma_ps2.xfr_channel); + break; + + case 0xa: /*Reset DMA mask*/ + dma_m &= ~(1 << dma_ps2.xfr_channel); + break; + + case 0xb: + if (!(dma_m & (1 << dma_ps2.xfr_channel))) + dma_ps2_run(dma_ps2.xfr_channel); + break; + default: fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); } From e0daf34629ff5aca65ff92a5acaebcae7183841d Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 31 Dec 2024 21:29:59 +0100 Subject: [PATCH 33/52] SCSI CD-ROM change of the day (December 31st, 2024) Added undocumented 0xC5 NEC SCSI-2 CD-ROM command (most likely a no op command like 0x0D). --- src/include/86box/scsi_device.h | 1 + src/scsi/scsi_cdrom.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 3f9f3791b..6fdac5ebd 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -129,6 +129,7 @@ #define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */ #define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */ #define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */ +#define GPCMD_UNKNOWN_SCSI2_NEC 0xc5 /* NEC Vendor Unique Command */ #define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */ #define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index fc8f93e51..ad7f0d1c0 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2114,7 +2114,7 @@ scsi_cdrom_command_matsushita(void *sc, uint8_t *cdb, int32_t *BufLen) dev->current_cdb[0] = cdb[0]; /* Keep cmd_stat at 0x00, therefore, it's going to process it as GPCMD_PLAY_AUDIO_MSF. */ break; - + case GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA: cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; dev->current_cdb[0] = cdb[0]; @@ -2166,6 +2166,12 @@ scsi_cdrom_command_nec(void *sc, uint8_t *cdb, int32_t *BufLen) cmd_stat = 0x01; break; + case GPCMD_UNKNOWN_SCSI2_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + case GPCMD_AUDIO_TRACK_SEARCH_NEC: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) @@ -2305,7 +2311,7 @@ scsi_cdrom_command_pioneer(void *sc, uint8_t *cdb, int32_t *BufLen) else { ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); len = 4; - + if (ret) { scsi_cdrom_set_buf_len(dev, BufLen, &len); scsi_cdrom_data_command_finish(dev, len, len, len, 0); @@ -2844,7 +2850,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) } } else ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); - + if (ret > 0) { dev->requested_blocks = max_len; dev->packet_len = alloc_length; From e05f9564f6bc4d1df0fa777aafd106b138669fce Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Wed, 1 Jan 2025 12:11:47 +0700 Subject: [PATCH 34/52] Added 20 more models This gives a total of 40 recently-added HDD model names/speeds to use. Also some model name additions for DeskStar 4 and DiamondMax 4320 series. --- src/disk/hdd.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 653987e66..45e6a60ad 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -436,7 +436,9 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 }, @@ -474,6 +476,7 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 }, @@ -481,23 +484,40 @@ static hdd_preset_t hdd_speed_presets[] = { { .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", .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 (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 (91024U3)", .internal_name = "91024U3", .model = "Maxtor 91024U3", .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 (92049U6)", .internal_name = "92049U6", .model = "Maxtor 92049U6", .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] Maxtor DiamondMax Plus 6800 (92732U8)", .internal_name = "92732U8", .model = "Maxtor 92732U8", .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] 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] 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 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 }, // Hitachi 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] 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] Seagate Medalist 4312", .internal_name = "ST34312A", .model = "ST34312A", .zones = 8, .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] 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 }; From 680d23f1f8525c5a4b05138043df0dda572ce8bf Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 2 Jan 2025 01:39:07 +0700 Subject: [PATCH 35/52] Replaced ST34312A with the SV1023D model And also added the model codename to the first SpinPoint V6800 model --- src/disk/hdd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 45e6a60ad..012153f28 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -512,8 +512,8 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 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 }, // Hitachi 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] 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 = 8, .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] 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 }, From 104e83de1b2d6ae54fb7f7145a2db63f9092a53a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 1 Jan 2025 21:20:33 +0100 Subject: [PATCH 36/52] Some changes on the PCSCSI code of the new year (January 1st, 2025) 1. Too many soft resets should not reset the SCSI layer, fixes CD Audio on the 53c90a MCA controller used by guests. 2. Implemented preliminary MDL S/G mode for the PCSCSI side. 3. The underflow DMA function is no longer needed as it now SCSI transfers on the 53c90a MCA controller works properly. 4. Minor corrections to the PCI side (mainly the revision). 5. The DMA 86c01 side of the MCA 53c90a controller is more polished now, should fix some more bugs. --- src/scsi/scsi_pcscsi.c | 232 ++++++++++++++++++++++++----------------- 1 file changed, 136 insertions(+), 96 deletions(-) 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, From 96891e34895a90559919a36f8845bab691cae2f9 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 2 Jan 2025 04:17:45 +0700 Subject: [PATCH 37/52] Added the DiamondMax VL20 model name/speed -Removed the duplicated 91024U3 model (plus head fixes) -Added the secondary manufacturer name for the Travelstar 12GN model (either Hitachi or IBM OEM) --- src/disk/hdd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 012153f28..b861b5e50 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -494,9 +494,8 @@ static hdd_preset_t hdd_speed_presets[] = { { .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 (91024U3)", .internal_name = "91024U3", .model = "Maxtor 91024U3", .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 (92049U6)", .internal_name = "92049U6", .model = "Maxtor 92049U6", .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] Maxtor DiamondMax Plus 6800 (92732U8)", .internal_name = "92732U8", .model = "Maxtor 92732U8", .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 (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 }, @@ -510,8 +509,9 @@ static hdd_preset_t hdd_speed_presets[] = { { .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] 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 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 }, // Hitachi OEM + { .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 }, From ab6756b4003fab8f91c6bed812ce976ca56aed97 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 1 Jan 2025 23:06:19 +0100 Subject: [PATCH 38/52] Some machine changes of the day (January 1st, 2025) 1. Added the Award 430NX-based (Socket 5) ASUS P54NP4 with the right configuration. 2. Based on the pictures of the board, the IDE controller is not built-in in the ASUS P5MP3, but on a riser card, iirc, therefore, make IDE optional. --- src/include/86box/machine.h | 1 + src/machine/m_at_socket4.c | 1 - src/machine/m_at_socket5.c | 30 +++++++++++++++++++++++++ src/machine/machine_table.c | 44 +++++++++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d46e816ce..b5709ea0a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -643,6 +643,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/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 79e46819e..5fb245038 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); 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..8286a07c8 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, @@ -9658,6 +9658,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", From 9b107ebeaeae6f302b65d2ac4101e57f741977d3 Mon Sep 17 00:00:00 2001 From: plant Date: Wed, 1 Jan 2025 15:51:12 -0700 Subject: [PATCH 39/52] Add Micronics M5Pi. This is a Socket 4 430LX machine using the Phoenix Ax86 BIOS. Also adds a single channel version of the W83769F to support it's specific IDE setup. --- src/disk/hdc_ide_w83769f.c | 14 +++++++++++++ src/include/86box/hdc.h | 1 + src/include/86box/machine.h | 1 + src/machine/m_at_socket4.c | 30 ++++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+) 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/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..c369179b9 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 *); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 79e46819e..31e90209f 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -355,6 +355,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/machine_table.c b/src/machine/machine_table.c index 26997eb61..5886145f7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -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 From 3b79448286baf7b9acf4a8f0a24705bbad465fdf Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Jan 2025 02:09:15 +0100 Subject: [PATCH 40/52] Switch back to only one hook (it turns out the second hook was neither needed nor working) and filter keyboard input properly, fixes #5084. --- src/qt/qt_main.cpp | 61 +++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 38 deletions(-) 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); }); From c957266137f6246af47adc605c3282f6e47be25a Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 31 Dec 2024 16:22:44 -0500 Subject: [PATCH 41/52] Add Creative EMU8000 PnP (Goldfinch) --- src/include/86box/snd_sb.h | 8 ++ src/include/86box/sound.h | 1 + src/sound/snd_sb.c | 192 ++++++++++++++++++++++++++++++++++--- src/sound/sound.c | 1 + 4 files changed, 187 insertions(+), 15 deletions(-) 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/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 }, From 0dd26ae058e9f74f0abade0d4fe92cebae7a8932 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 1 Jan 2025 21:48:48 -0500 Subject: [PATCH 42/52] Temporarily disable sonar-scanner --- .github/workflows/cmake_linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 }} From fca5828ed5d198306ceb6cf955c2a67e41e35d1f Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 2 Jan 2025 01:39:23 -0500 Subject: [PATCH 43/52] Fix various omissions in device.c --- src/device.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) 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; From 012a450c9b5f3ded0110232b0cceb2e11ea97990 Mon Sep 17 00:00:00 2001 From: conan7123 Date: Thu, 2 Jan 2025 22:34:18 +0100 Subject: [PATCH 44/52] Add machine Compaq Presario 7100/7200 Series Machine (486) --- src/include/86box/machine.h | 1 + src/machine/m_at_386dx_486.c | 43 ++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c976d15a7..44a55d94f 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -593,6 +593,7 @@ extern int machine_at_pcm5330_init(const machine_t *); extern int machine_at_ecs486_init(const machine_t *); extern int machine_at_hot433a_init(const machine_t *); +extern int machine_at_pl4600c_init(const machine_t *); extern int machine_at_atc1415_init(const machine_t *); extern int machine_at_actionpc2600_init(const machine_t *); extern int machine_at_actiontower8400_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 253f7522a..1c35d7290 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -48,6 +48,7 @@ #include <86box/hwm.h> #include <86box/machine.h> #include <86box/plat_unused.h> +#include <86box/sound.h> int machine_at_acc386_init(const machine_t *model) @@ -1962,6 +1963,48 @@ machine_at_hot433a_init(const machine_t *model) return ret; } +int +machine_at_pl4600c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pl4600c/SST29EE010.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Slot 01 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); /* Slot 02 */ + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */ + pci_register_slot(0x13, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard */ + + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&um8663af_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5430_onboard_pci_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&ess_1688_device); + + if (fdc_current[0] == FDC_INTERNAL){ + fdd_set_turbo(0, 1); + fdd_set_turbo(1, 1); + } + + return ret; +} + int machine_at_atc1415_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ad0844cdc..a414bbd0d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8668,6 +8668,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[UMC 8881] Compaq Presario 7100/7200 Series 486", + .internal_name = "pl4600c", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_pl4600c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_pci_device, + .snd_device = &ess_1688_device, + .net_device = NULL + }, /* Has a VIA VT82C406 KBC+RTC that likely has identical commands to the VT82C42N. */ { .name = "[VIA VT82C496G] DFI G486VPA", From 7ad3b810582c23eb12375c6ce804d263a4b5d8fd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Jan 2025 22:38:10 +0100 Subject: [PATCH 45/52] Rewritten the CD-ROM image handling and Cue sheet parsing, also fixes crashes when using VISO. --- src/cdrom/cdrom_image.c | 83 +- src/cdrom/cdrom_image_backend.c | 1594 +++++++++++------------ src/cdrom/cdrom_image_viso.c | 4 +- src/cdrom/cdrom_ioctl.c | 9 - src/include/86box/cdrom.h | 1 - src/include/86box/cdrom_image_backend.h | 80 +- src/include/86box/plat_cdrom.h | 1 - src/qt/dummy_cdrom_ioctl.c | 17 - src/qt/win_cdrom_ioctl.c | 20 - src/unix/dummy_cdrom_ioctl.c | 17 - 10 files changed, 858 insertions(+), 968 deletions(-) diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index f74e0d344..0c7870902 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -58,26 +58,32 @@ cdrom_image_log(const char *fmt, ...) of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static void -image_get_tracks(cdrom_t *dev, int *first, int *last) -{ - cd_img_t *img = (cd_img_t *) dev->local; - TMSF tmsf; - - cdi_get_audio_tracks(img, first, last, &tmsf); -} - static void image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) { cd_img_t *img = (cd_img_t *) dev->local; - TMSF tmsf; + track_t *ct = NULL; - cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr); + for (int i = 0; i < img->tracks_num; i++) { + ct = &(img->tracks[i]); + if (ct->point == track) + break; + } - ti->m = tmsf.min; - ti->s = tmsf.sec; - ti->f = tmsf.fr; + ti->number = ct->point; + + if (ct == NULL) { + ti->attr = 0x14; + ti->m = 0; + ti->s = 2; + ti->f = 0; + } else { + uint32_t pos = end ? ct->idx[1].start : (ct->idx[1].start + ct->idx[1].length); + ti->attr = ct->attr; + ti->m = (pos / 75) / 60; + ti->s = (pos / 75) % 60; + ti->f = pos % 75; + } } static void @@ -113,24 +119,22 @@ static int image_get_capacity(cdrom_t *dev) { cd_img_t *img = (cd_img_t *) dev->local; - int first_track; - int last_track; - int number; - unsigned char attr; - uint32_t address = 0; uint32_t lb = 0; + track_t *lo = NULL; if (!img) return 0; - cdi_get_audio_tracks_lba(img, &first_track, &last_track, &lb); - - for (int c = 0; c <= last_track; c++) { - cdi_get_audio_track_info_lba(img, 0, c + 1, &number, &address, &attr); - if (address > lb) - lb = address; + for (int i = (img->tracks_num - 1); i >= 0; i--) { + if (img->tracks[i].point == 0xa2) { + lo = &(img->tracks[i]); + break; + } } + if (lo != NULL) + lb = lo->idx[1].start - 1; + return lb; } @@ -138,13 +142,9 @@ static int image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) { cd_img_t *img = (cd_img_t *) dev->local; - uint8_t attr; - TMSF tmsf; int m; int s; int f; - int number; - int track; if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY)) return 0; @@ -156,29 +156,18 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) pos = MSFtoLBA(m, s, f) - 150; } - /* GetTrack requires LBA. */ - track = cdi_get_track(img, pos); - if (track == -1) - return 0; - else { - cdi_get_audio_track_info(img, 0, track, &number, &tmsf, &attr); - return attr == AUDIO_TRACK; - } + return cdi_is_audio(img, pos); } static int image_is_track_pre(cdrom_t *dev, uint32_t lba) { cd_img_t *img = (cd_img_t *) dev->local; - int track; - /* GetTrack requires LBA. */ - track = cdi_get_track(img, lba); + if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY)) + return 0; - if (track != -1) - return cdi_get_audio_track_pre(img, track); - - return 0; + return cdi_is_pre(img, lba); } static int @@ -238,7 +227,6 @@ image_exit(cdrom_t *dev) } static const cdrom_ops_t cdrom_image_ops = { - image_get_tracks, image_get_track_info, image_get_raw_track_info, image_get_subchannel, @@ -270,14 +258,13 @@ cdrom_image_open(cdrom_t *dev, const char *fn) strcpy(dev->image_path, fn); /* Create new instance of the CDROM_Image class. */ - img = (cd_img_t *) malloc(sizeof(cd_img_t)); + img = (cd_img_t *) calloc(1, sizeof(cd_img_t)); /* This guarantees that if ops is not NULL, then neither is the image pointer. */ - if (!img) + if (img == NULL) return image_open_abort(dev); - memset(img, 0, sizeof(cd_img_t)); dev->local = img; /* Open the image. */ diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index fdc4f662f..3c09cb56c 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -6,20 +6,15 @@ * * This file is part of the 86Box distribution. * - * CD-ROM image file handling module, translated to C from - * cdrom_dosbox.cpp. - * - * + * CD-ROM image file handling module. * * Authors: Miran Grca, - * Fred N. van Kempen, - * The DOSBox Team, + * RichardG, * Cacodemon345 * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2002-2020 The DOSBox Team. - * Copyright 2024 Cacodemon345. + * Copyright 2016-2025 Miran Grca. + * Copyright 2016-2025 Miran Grca. + * Copyright 2024-2025 Cacodemon345. */ #define __STDC_FORMAT_MACROS #include @@ -278,285 +273,137 @@ bin_init(const char *filename, int *error) } static track_file_t * -track_file_init(const char *filename, int *error) +track_file_init(const char *filename, int *error, int *is_viso) { + track_file_t *tf; + + *is_viso = 0; + /* Current we only support .BIN files, either combined or one per track. In the future, more is planned. */ - return bin_init(filename, error); -} + tf = bin_init(filename, error); -static void -track_file_close(track_t *trk) -{ - if (trk == NULL) - return; + if (*error) { + if ((tf != NULL) && (tf->close != NULL)) { + tf->close(tf); + tf = NULL; + } - if (trk->file == NULL) - return; + tf = viso_init(filename, error); - if (trk->file->close == NULL) - return; - - trk->file->close(trk->file); - trk->file = NULL; -} - -/* Root functions. */ -static void -cdi_clear_tracks(cd_img_t *cdi) -{ - const track_file_t *last = NULL; - track_t *cur = NULL; - - if ((cdi->tracks == NULL) || (cdi->tracks_num == 0)) - return; - - for (int i = 0; i < cdi->tracks_num; i++) { - cur = &cdi->tracks[i]; - - /* Make sure we do not attempt to close a NULL file. */ - if (cur->file != last) { - last = cur->file; - track_file_close(cur); - } else - cur->file = NULL; + if (!*error) + *is_viso = 1; } - /* Now free the array. */ - free(cdi->tracks); - cdi->tracks = NULL; - - /* Mark that there's no tracks. */ - cdi->tracks_num = 0; + return tf; } -void -cdi_close(cd_img_t *cdi) +static void +index_file_close(track_index_t *idx) { - cdi_clear_tracks(cdi); - free(cdi); -} + if (idx == NULL) + return; -int -cdi_set_device(cd_img_t *cdi, const char *path) -{ - int ret; + if (idx->file == NULL) + return; - if ((ret = cdi_load_cue(cdi, path))) - return ret; + if (idx->file->close == NULL) + return; - if ((ret = cdi_load_iso(cdi, path))) - return ret; - - return 0; -} - -void -cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out) -{ - *st_track = 1; - *end = cdi->tracks_num - 1; - FRAMES_TO_MSF(cdi->tracks[*end].start + 150, &lead_out->min, &lead_out->sec, &lead_out->fr); -} - -void -cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out) -{ - *st_track = 1; - *end = cdi->tracks_num - 1; - *lead_out = cdi->tracks[*end].start; -} - -int -cdi_get_audio_track_pre(cd_img_t *cdi, int track) -{ - const track_t *trk = &cdi->tracks[track - 1]; - - if ((track < 1) || (track > cdi->tracks_num)) - return 0; - - return trk->pre; -} - -/* This replaces both Info and EndInfo, they are specified by a variable. */ -int -cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) -{ - const track_t *trk = &cdi->tracks[track - 1]; - // const int pos = trk->start + 150; - const int pos = trk->indexes[1].start; - - if ((track < 1) || (track > cdi->tracks_num)) - return 0; - - FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr); - - *track_num = trk->track_number; - *attr = trk->attr; - - return 1; -} - -int -cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, uint32_t *start, uint8_t *attr) -{ - const track_t *trk = &cdi->tracks[track - 1]; - - if ((track < 1) || (track > cdi->tracks_num)) - return 0; - - *start = (uint32_t) trk->start; - // *start = (uint32_t) trk->indexes[1].start - 150ULL; - - *track_num = trk->track_number; - *attr = trk->attr; - - return 1; + idx->file->close(idx->file); + idx->file = NULL; } void cdi_get_raw_track_info(cd_img_t *cdi, int *num, uint8_t *buffer) { - TMSF tmsf; - int track_num = 0; - uint8_t attr = 0; - int len = 0; - int first_track; - int last_track; + int len = 0; - cdi_get_audio_tracks(cdi, &first_track, &last_track, &tmsf); + cdrom_image_backend_log("cdi->tracks_num = %i\n", cdi->tracks_num); - *num = last_track + 3; - - cdi_get_audio_track_info(cdi, 0, 1, &track_num, &tmsf, &attr); - - buffer[len++] = 1; /* Session number */ - buffer[len++] = attr; /* Track ADR and Control */ - buffer[len++] = 0; /* TNO (always 0) */ - buffer[len++] = 0xA0; /* Point (for track points - track number) */ - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = track_num; /* First track number */ - buffer[len++] = 0; - buffer[len++] = 0; - - cdi_get_audio_track_info(cdi, 0, last_track, &track_num, &tmsf, &attr); - - buffer[len++] = 1; /* Session number */ - buffer[len++] = attr; /* Track ADR and Control */ - buffer[len++] = 0; /* TNO (always 0) */ - buffer[len++] = 0xA1; /* Point (for track points - track number) */ - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = track_num; /* Last track number */ - buffer[len++] = 0; - buffer[len++] = 0; - - cdi_get_audio_track_info(cdi, 0, last_track + 1, &track_num, &tmsf, &attr); - - cdrom_image_backend_log(" tracks(%i) = %02X, %02X, %02i:%02i.%02i\n", last_track, attr, - track_num, tmsf.min, tmsf.sec, tmsf.fr); - - buffer[len++] = 1; /* Session number */ - buffer[len++] = attr; /* Track ADR and Control */ - buffer[len++] = 0; /* TNO (always 0) */ - buffer[len++] = 0xA2; /* Point (for track points - track number) */ - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = tmsf.min; /* PM */ - buffer[len++] = tmsf.sec; /* PS */ - buffer[len++] = tmsf.fr; /* PF */ - - for (int i = 0; i < last_track; i++) { - cdi_get_audio_track_info(cdi, 0, i + 1, &track_num, &tmsf, &attr); - - cdrom_image_backend_log(" tracks(%i) = %02X, %02X, %02i:%02i.%02i\n", i, attr, - track_num, tmsf.min, tmsf.sec, tmsf.fr); - - buffer[len++] = 1; /* Session number */ - buffer[len++] = attr; /* Track ADR and Control */ - buffer[len++] = 0; /* TNO (always 0) */ - buffer[len++] = track_num; /* Point (for track points - track number) */ - /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = 0; - buffer[len++] = tmsf.min; /* PM */ - buffer[len++] = tmsf.sec; /* PS */ - buffer[len++] = tmsf.fr; /* PF */ + for (int i = 0; i < cdi->tracks_num; i++) { + track_t *ct = &(cdi->tracks[i]); +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG + int old_len = len; +#endif + buffer[len++] = ct->session; /* Session number */ + buffer[len++] = ct->attr; /* Track ADR and Control */ + buffer[len++] = ct->tno; /* TNO (always 0) */ + buffer[len++] = ct->point; /* Point (for track points - track number) */ + for (int j = 0; j < 4; j++) + buffer[len++] = ct->extra[j]; + buffer[len++] = (ct->idx[1].start / 75) / 60; + buffer[len++] = (ct->idx[1].start / 75) % 60; + buffer[len++] = ct->idx[1].start % 75; + cdrom_image_backend_log("%i: %02X %02X %02X %02X %02X %02X %02X\n", i, + buffer[old_len], buffer[old_len + 1], buffer[old_len + 2], buffer[old_len + 3], + buffer[old_len + 8], buffer[old_len + 9], buffer[old_len + 10]); } + + *num = cdi->tracks_num; } -int +static int cdi_get_track(cd_img_t *cdi, uint32_t sector) { - /* There must be at least two tracks - data and lead out. */ - if (cdi->tracks_num < 2) - return -1; + int ret = -1; - /* This has a problem - the code skips the last track, which is - lead out - is that correct? */ - for (int i = 0; i < (cdi->tracks_num - 1); i++) { - const track_t *cur = &cdi->tracks[i]; - const track_t *next = &cdi->tracks[i + 1]; - - /* Take into account cue sheets that do not start on sector 0. */ - // if ((i == 0) && (sector < cur->start)) - if ((i == 0) && (sector < cur->indexes[0].start)) - return cur->number; - - // if ((cur->start <= sector) && (sector < next->start)) - if ((cur->indexes[0].start <= sector) && (sector < next->indexes[0].start)) - return cur->number; + for (int i = 0; i < cdi->tracks_num; i++) { + track_t *ct = &(cdi->tracks[i]); + for (int j = 0; j < 3; j++) { + track_index_t *ci = &(ct->idx[j]); + if (((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) { + ret = i; + break; + } + } } - return -1; + return ret; +} + +static void +cdi_get_track_and_index(cd_img_t *cdi, uint32_t sector, int *track, int *index) +{ + *track = -1; + *index = -1; + + for (int i = 0; i < cdi->tracks_num; i++) { + track_t *ct = &(cdi->tracks[i]); + for (int j = 0; j < 3; j++) { + track_index_t *ci = &(ct->idx[j]); + if (((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) { + *track = i; + *index = j; + break; + } + } + } } /* TODO: See if track start is adjusted by 150 or not. */ int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) { - const int cur_track = cdi_get_track(cdi, sector); + int cur_track = cdi_get_track(cdi, sector); if (cur_track < 1) return 0; *track = (uint8_t) cur_track; - const track_t *trk = &cdi->tracks[*track - 1]; + const track_t *trk = &cdi->tracks[*track]; *attr = trk->attr; *index = 1; + /* Absolute position should be adjusted by 150, not the relative ones. */ FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); - /* Absolute position should be adjusted by 150, not the relative ones. */ - // FRAMES_TO_MSF(sector - trk->start, &rel_pos->min, &rel_pos->sec, &rel_pos->fr); /* Relative position is relative Index 1 start - pre-gap values will be negative. */ - FRAMES_TO_MSF((int32_t) (sector + 150 - trk->indexes[1].start), &rel_pos->min, &rel_pos->sec, &rel_pos->fr); + FRAMES_TO_MSF((int32_t) (sector + 150 - trk->idx[1].start), &rel_pos->min, &rel_pos->sec, &rel_pos->fr); return 1; } -static int -cdi_get_sector_index(const track_t *trk, const uint32_t sector) -{ - int ret = 1; - - if ((sector + 150) < trk->indexes[1].start) - ret = 0; - else if ((sector + 150) >= trk->indexes[2].start) - ret = 2; - - return ret; -} - static __inline int bin2bcd(int x) { @@ -566,34 +413,37 @@ bin2bcd(int x) int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) { - const int track = cdi_get_track(cdi, sector) - 1; - const uint64_t sect = (uint64_t) sector; + const uint64_t sect = (uint64_t) sector; + int m = 0; + int s = 0; + int f = 0; + int ret = 0; + uint64_t offset = 0ULL; + int track; + int index; int raw_size; int cooked_size; - uint64_t offset; - int m = 0; - int s = 0; - int f = 0; - int ret = 0; uint8_t q[16] = { 0x00 }; + cdi_get_track_and_index(cdi, sector, &track, &index); + if (track < 0) return 0; - const track_t *trk = &cdi->tracks[track]; - const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); - - const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size); - const int index = cdi_get_sector_index(trk, sector); + const track_t *trk = &(cdi->tracks[track]); + const track_index_t *idx = &(trk->idx[index]); + const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); + const uint64_t seek = (sect + 150 - idx->start + idx->file_start) * trk->sector_size; + cdrom_image_backend_log("cdrom_read_sector(%08X): track %02X, index %02X, %016" PRIX64 ", %016" PRIX64 ", %i\n", - sector, track, index, trk->skip, trk->start, trk->sector_size); + sector, track, index, trk->start, trk->sector_size); if (track_is_raw) raw_size = trk->sector_size; else raw_size = 2448; - if (trk->mode2 && (trk->form != 1)) { + if ((trk->mode == 2) && (trk->form != 1)) { if (trk->form == 2) cooked_size = (track_is_raw ? 2328 : trk->sector_size); /* Both 2324 + ECC and 2328 variants are valid. */ else @@ -601,14 +451,12 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) } else cooked_size = COOKED_SECTOR_SIZE; - const size_t length = (raw ? raw_size : cooked_size); - - if (trk->mode2 && (trk->form >= 1)) + if ((trk->mode == 2) && (trk->form >= 1)) offset = 24ULL; else offset = 16ULL; - if (!trk->indexes[index].in_file) { + if (idx->type < INDEX_NORMAL) { memset(buffer, 0x00, 2448); if (trk->attr & 0x04) { /* Construct the rest of the raw sector. */ @@ -620,12 +468,13 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) buffer[1] = CDROM_BCD(s & 0xff); buffer[2] = CDROM_BCD(f & 0xff); /* Data, should reflect the actual sector type. */ - buffer[3] = trk->mode2 ? 2 : 1; + buffer[3] = trk->mode; ret = 1; } } else if (raw && !track_is_raw) { memset(buffer, 0x00, 2448); - const int temp = trk->file->read(trk->file, buffer + offset, seek, length); + /* We are doing a raw read but the track is cooked, length should be cooked size. */ + const int temp = idx->file->read(idx->file, buffer + offset, seek, cooked_size); if (temp <= 0) return temp; if (trk->attr & 0x04) { @@ -638,23 +487,29 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) buffer[1] = CDROM_BCD(s & 0xff); buffer[2] = CDROM_BCD(f & 0xff); /* Data, should reflect the actual sector type. */ - buffer[3] = trk->mode2 ? 2 : 1; + buffer[3] = trk->mode; ret = 1; } } else if (!raw && track_is_raw) - return trk->file->read(trk->file, buffer, seek + offset, length); + /* The track is raw but we are doing a cooked read, length should be cooked size. */ + return idx->file->read(idx->file, buffer, seek + offset, cooked_size); else { - ret = trk->file->read(trk->file, buffer, seek, length); + /* The track is raw and we are doing a raw read, length should be raw size. */ + ret = idx->file->read(idx->file, buffer, seek, raw_size); if (raw && (raw_size == 2448)) return ret; } /* Construct Q. */ q[0] = (trk->attr >> 4) | ((trk->attr & 0xf) << 4); - q[1] = bin2bcd(trk->track_number); - q[2] = 1; /* TODO: Index number. */ - // FRAMES_TO_MSF(sector - trk->start, &m, &s, &f); - FRAMES_TO_MSF((int32_t) (sector + 150 - trk->indexes[1].start), &m, &s, &f); + q[1] = bin2bcd(trk->point); + q[2] = index; + if (index == 0) { + /* Pre-gap sector relative frame addresses count from 00:01:74 downwards. */ + FRAMES_TO_MSF((int32_t) (149 - (sector + 150 - idx->start)), &m, &s, &f); + } else { + FRAMES_TO_MSF((int32_t) (sector + 150 - idx->start), &m, &s, &f); + } q[3] = bin2bcd(m); q[4] = bin2bcd(s); q[5] = bin2bcd(f); @@ -671,85 +526,90 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) return ret; } -int -cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num) -{ - int success = 1; - - /* TODO: This fails to account for Mode 2. Shouldn't we have a function - to get sector size? */ - const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - const uint32_t buf_len = num * sector_size; - uint8_t *buf = (uint8_t *) calloc(1, buf_len * sizeof(uint8_t)); - - for (uint32_t i = 0; i < num; i++) { - success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i); - if (success <= 0) - break; - /* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an - audio track. */ - if (raw && (sector < cdi->tracks[0].length) && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[(i * sector_size) + 2068])) - return 0; - } - - memcpy((void *) buffer, buf, buf_len); - free(buf); - buf = NULL; - - return success; -} - /* TODO: Do CUE+BIN images with a sector size of 2448 even exist? */ int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) { - const int track = cdi_get_track(cdi, sector) - 1; + int track; + int index; + + cdi_get_track_and_index(cdi, sector, &track, &index); if (track < 0) return 0; - const track_t *trk = &cdi->tracks[track]; - const uint64_t seek = trk->skip + (((uint64_t) sector - trk->start) * trk->sector_size); - if (trk->sector_size != 2448) + const track_t *trk = &(cdi->tracks[track]); + const track_index_t *idx = &(trk->idx[index]); + + const uint64_t seek = (((uint64_t) sector + 150 - idx->start + idx->file_start) * trk->sector_size); + + if ((idx->type < INDEX_NORMAL) && (trk->sector_size != 2448)) return 0; - return trk->file->read(trk->file, buffer, seek, 2448); + return idx->file->read(idx->file, buffer, seek, 2448); } int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector) { - const int track = cdi_get_track(cdi, sector) - 1; + int track = cdi_get_track(cdi, sector); if (track < 0) return 0; - const track_t *trk = &cdi->tracks[track]; + const track_t *trk = &(cdi->tracks[track]); + return trk->sector_size; } +int +cdi_is_audio(cd_img_t *cdi, uint32_t sector) +{ + int track = cdi_get_track(cdi, sector); + + if (track < 0) + return 0; + + const track_t *trk = &(cdi->tracks[track]); + + return !!(trk->mode == 0); +} + +int +cdi_is_pre(cd_img_t *cdi, uint32_t sector) +{ + int track = cdi_get_track(cdi, sector); + + if (track < 0) + return 0; + + const track_t *trk = &(cdi->tracks[track]); + + return !!(trk->attr & 0x01); +} + int cdi_is_mode2(cd_img_t *cdi, uint32_t sector) { - const int track = cdi_get_track(cdi, sector) - 1; + int track = cdi_get_track(cdi, sector); if (track < 0) return 0; - const track_t *trk = &cdi->tracks[track]; + const track_t *trk = &(cdi->tracks[track]); - return !!(trk->mode2); + return !!(trk->mode == 2); } int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector) { - const int track = cdi_get_track(cdi, sector) - 1; + int track = cdi_get_track(cdi, sector); if (track < 0) return 0; - const track_t *trk = &cdi->tracks[track]; + const track_t *trk = &(cdi->tracks[track]); return trk->form; } @@ -773,133 +633,6 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form) return ((pvd[0] == 1 && !strncmp((char *) (&pvd[1]), "CD001", 5) && pvd[6] == 1) || (pvd[8] == 1 && !strncmp((char *) (&pvd[9]), "CDROM", 5) && pvd[14] == 1)); } -/* This reallocates the array and returns the pointer to the last track. */ -static void -cdi_track_push_back(cd_img_t *cdi, track_t *trk) -{ - /* This has to be done so situations in which realloc would misbehave - can be detected and reported to the user. */ - if ((cdi->tracks != NULL) && (cdi->tracks_num == 0)) - fatal("CD-ROM Image: Non-null tracks array at 0 loaded tracks\n"); - if ((cdi->tracks == NULL) && (cdi->tracks_num != 0)) - fatal("CD-ROM Image: Null tracks array at non-zero loaded tracks\n"); - - cdi->tracks = realloc(cdi->tracks, (cdi->tracks_num + 1) * sizeof(track_t)); - memcpy(&(cdi->tracks[cdi->tracks_num]), trk, sizeof(track_t)); - cdi->tracks_num++; -} - -int -cdi_get_iso_track(cd_img_t *cdi, track_t *trk, const char *filename) -{ - int error = 0; - int ret = 2; - memset(trk, 0, sizeof(track_t)); - - /* Data track (shouldn't there be a lead in track?). */ - trk->file = bin_init(filename, &error); - if (error) { - if ((trk->file != NULL) && (trk->file->close != NULL)) - trk->file->close(trk->file); - ret = 3; - trk->file = viso_init(filename, &error); - if (error) { - if ((trk->file != NULL) && (trk->file->close != NULL)) - trk->file->close(trk->file); - return 0; - } - } - trk->number = 1; - trk->track_number = 1; - trk->attr = DATA_TRACK; - - /* Try to detect ISO type. */ - trk->form = 0; - trk->mode2 = 0; - - if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 0, 0)) - trk->sector_size = RAW_SECTOR_SIZE; - else if (cdi_can_read_pvd(trk->file, 2336, 1, 0)) { - trk->sector_size = 2336; - trk->mode2 = 1; - } else if (cdi_can_read_pvd(trk->file, 2324, 1, 2)) { - trk->sector_size = 2324; - trk->mode2 = 1; - trk->form = 2; - trk->noskip = 1; - } else if (cdi_can_read_pvd(trk->file, 2328, 1, 2)) { - trk->sector_size = 2328; - trk->mode2 = 1; - trk->form = 2; - trk->noskip = 1; - } else if (cdi_can_read_pvd(trk->file, 2336, 1, 1)) { - trk->sector_size = 2336; - trk->mode2 = 1; - trk->form = 1; - trk->skip = 8; - } else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 0)) { - trk->sector_size = RAW_SECTOR_SIZE; - trk->mode2 = 1; - } else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 1)) { - trk->sector_size = RAW_SECTOR_SIZE; - trk->mode2 = 1; - trk->form = 1; - } else { - /* We use 2048 mode 1 as the default. */ - trk->sector_size = COOKED_SECTOR_SIZE; - } - - trk->length = trk->file->get_length(trk->file) / trk->sector_size; - - trk->indexes[0].in_file = 0; - trk->indexes[0].start = 0; - trk->indexes[0].length = 150; - trk->indexes[1].in_file = 1; - trk->indexes[1].start = 150; - trk->indexes[1].length = trk->length; - trk->indexes[2].in_file = 0; - trk->indexes[2].start = trk->length + 150; - trk->indexes[2].length = 0; - - cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk->length, trk->sector_size); - return ret; -} - -int -cdi_load_iso(cd_img_t *cdi, const char *filename) -{ - int ret = 2; - track_t trk = { 0 }; - - cdi->tracks = NULL; - cdi->tracks_num = 0; - - ret = cdi_get_iso_track(cdi, &trk, filename); - - if (ret >= 1) { - cdi_track_push_back(cdi, &trk); - - /* Lead out track. */ - trk.number = 2; - trk.track_number = 0xAA; - // trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */ - trk.start = trk.length; - trk.file = NULL; - - for (int i = 0; i < 3; i++) { - trk.indexes[i].in_file = 0; - trk.indexes[i].start = trk.length + 150; - trk.indexes[i].length = 0; - } - - trk.length = 0; - - cdi_track_push_back(cdi, &trk); - } - - return ret; -} - static int cdi_cue_get_buffer(char *str, char **line, int up) { @@ -1020,120 +753,432 @@ cdi_cue_get_flags(track_t *cur, char **line) if (!success) return 0; - cur->pre = (strstr(temp2, "PRE") != NULL); + if (strstr(temp2, "PRE") != NULL) + cur->attr |= 0x01; + if (strstr(temp2, "DCP") != NULL) + cur->attr |= 0x02; + if (strstr(temp2, "4CH") != NULL) + cur->attr |= 0x08; return 1; } -uint64_t total_pregap = 0ULL; - -static int -cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t cur_pregap) +static track_t * +cdi_insert_track(cd_img_t *cdi, uint8_t session, uint8_t point) { - /* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */ - track_t *prev = NULL; + track_t *ct = NULL; - /* Skip *MUST* be calculated even if prestart is 0. */ - if (prestart > cur->start) - return 0; - /* If prestart is 0, there is no skip. */ - uint64_t skip = (prestart == 0) ? 0 : (cur->start - prestart); - - if ((cdi->tracks != NULL) && (cdi->tracks_num != 0)) - prev = &cdi->tracks[cdi->tracks_num - 1]; - else if ((cdi->tracks == NULL) && (cdi->tracks_num != 0)) { - fatal("NULL cdi->tracks with non-zero cdi->tracks_num\n"); - return 0; - } - - /* First track (track number must be 1). */ - if ((prev == NULL) || (cdi->tracks_num == 0)) { - /* I guess this makes sure the structure is not filled with invalid data. */ - if (cur->number != 1) - return 0; - cur->skip = skip * cur->sector_size; - if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip) - cur->skip += 8; - cur->start += cur_pregap; - cdi_track_push_back(cdi, cur); - return 1; - } - - if (prev->indexes[2].length != 0) { - prev->indexes[2].start = cur->indexes[0].start - prev->indexes[2].length; - prev->indexes[1].length = prev->indexes[2].start - prev->indexes[1].start; - cdrom_image_backend_log("Index 2 (%i): %02i:%02i:%02i\n", prev->indexes[2].in_file, - (int) ((prev->indexes[2].start / 75) / 60), (int) ((prev->indexes[2].start / 75) % 60), - (int) (prev->indexes[2].start % 75)); - } else if (prev->indexes[2].in_file) - prev->indexes[2].length = cur->indexes[0].start - prev->indexes[2].start; - else { - prev->indexes[1].length = cur->indexes[0].start - prev->indexes[1].start; - prev->indexes[2].start = prev->indexes[1].start + prev->indexes[1].length; - prev->indexes[2].length = 0; - cdrom_image_backend_log("Index 2 (%i): %02i:%02i:%02i\n", prev->indexes[2].in_file, - (int) ((prev->indexes[2].start / 75) / 60), (int) ((prev->indexes[2].start / 75) % 60), - (int) (prev->indexes[2].start % 75)); - } - - /* Current track consumes data from the same file as the previous. */ - if (prev->file == cur->file) { - cur->start += *shift; - prev->length = cur->start - prev->start - skip; - cur->skip += prev->skip + (prev->length * prev->sector_size) + (skip * cur->sector_size); - cur->start += cur_pregap; + cdi->tracks_num++; + if (cdi->tracks == NULL) { + cdi->tracks = calloc(1, sizeof(track_t)); + ct = &(cdi->tracks[0]); } else { - const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip); - prev->length = temp / ((uint64_t) prev->sector_size); - if ((temp % prev->sector_size) != 0) - /* Padding. */ - prev->length++; + cdi->tracks = realloc(cdi->tracks, cdi->tracks_num * sizeof(track_t)); + ct = &(cdi->tracks[cdi->tracks_num - 1]); + } + cdrom_image_backend_log("%02X: cdi->tracks[%2i] = %016" PRIX64 "\n", point, cdi->tracks_num - 1, (uint64_t) ct); - cur->start += prev->start + prev->length + cur_pregap; - cur->skip = skip * cur->sector_size; - if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip) - cur->skip += 8; - *shift += prev->start + prev->length; + memset(ct, 0x00, sizeof(track_t)); + + ct->session = session; + ct->point = point; + + for (int i = 0; i < 3; i++) + ct->idx[i].type = (point > 99) ? INDEX_SPECIAL : INDEX_NONE; + + return ct; +} + +static void +cdi_last_3_passes(cd_img_t *cdi) +{ + track_t *ct = NULL; + track_t *lt = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + uint64_t tf_len = 0ULL; + uint64_t cur_pos = 0ULL; + int map[256] = { 0 }; + int lead[3] = { 0 }; + int pos = 0; + int ls = 0; + uint64_t spg[256] = { 0ULL }; + track_t *lo[256] = { 0 }; + + cdrom_image_backend_log("A2 = %016" PRIX64 "\n", (uint64_t) &(cdi->tracks[2])); + + for (int i = 0; i < cdi->tracks_num; i++) { + ct = &(cdi->tracks[i]); + if (((ct->point >= 1) && (ct->point <= 99)) || (ct->point >= 0xb0)) { + if (ct->point == 0xb0) { + /* Point B0h found, add the previous three lead tracks. */ + for (int j = 0; j < 3; j++) { + map[pos] = lead[j]; + pos++; + } + } + + map[pos] = i; + pos++; + } else if ((ct->point >= 0xa0) && (ct->point <= 0xa2)) + lead[ct->point & 0x03] = i; } - /* Error checks. */ - if (cur->number <= 1) - return 0; - if ((prev->number + 1) != cur->number) - return 0; - if (cur->start < (prev->start + prev->length)) + /* The last lead tracks. */ + for (int i = 0; i < 3; i++) { + map[pos] = lead[i]; + pos++; + } +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG + cdrom_image_backend_log("pos = %i, cdi->tracks_num = %i\n", pos, cdi->tracks_num); + for (int i = 0; i < pos; i++) + cdrom_image_backend_log("map[%02i] = %02X\n", i, map[i]); +#endif + + cdrom_image_backend_log("Second pass:\n"); + for (int i = (cdi->tracks_num - 1); i >= 0; i--) { + ct = &(cdi->tracks[map[i]]); + if (ct->idx[1].type != INDEX_SPECIAL) { + for (int j = 2; j >= 0; j--) { + ci = &(ct->idx[j]); + + if ((ci->type >= INDEX_ZERO) && (ci->file != tf)) { + tf = ci->file; + if (tf != NULL) { + tf_len = tf->get_length(tf) / ct->sector_size; + cdrom_image_backend_log(" File length: %016" PRIX64 " sectors\n", tf_len); + } + } + + if (ci->type == INDEX_NONE) { + /* Index was not in the cue sheet, keep its length at zero. */ + ci->file_start = tf_len; + } else if (ci->type == INDEX_NORMAL) { + /* Index was in the cue sheet and is present in the file. */ + ci->file_length = tf_len - ci->file_start; + tf_len -= ci->file_length; + } + + cdrom_image_backend_log(" TRACK %2i (%2i), ATTR %02X, INDEX %i: %2i, file_start = %016" + PRIX64 " (%2i:%02i:%02i), file_length = %016" PRIX64 " (%2i:%02i:%02i)\n", + i, map[i], + ct->attr, + j, ci->type, + ci->file_start, + (int) ((ci->file_start / 75) / 60), + (int) ((ci->file_start / 75) % 60), + (int) (ci->file_start % 75), + ci->file_length, + (int) ((ci->file_length / 75) / 60), + (int) ((ci->file_length / 75) % 60), + (int) (ci->file_length % 75)); + } + } + } + + cdrom_image_backend_log("Third pass:\n"); + for (int i = 0; i < cdi->tracks_num; i++) { + int session_changed = 0; + + ct = &(cdi->tracks[map[i]]); + if (ct->idx[1].type != INDEX_SPECIAL) { + if (ct->session != ls) { + /* The first track of a session always has a pre-gap of at least 0:02:00. */ + ci = &(ct->idx[0]); + if (ci->type == INDEX_NONE) { + ci->type = INDEX_ZERO; + ci->start = 0ULL; + ci->length = 150ULL; + } + + session_changed = 1; + ls = ct->session; + } + + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + + if (ci->type == INDEX_NONE) + /* Index was not in the cue sheet, keep its length at zero. */ + ci->start = cur_pos; + else if (ci->type == INDEX_ZERO) { + /* Index was in the cue sheet and is not present in the file. */ + ci->start = cur_pos; + cur_pos += ci->length; + } else if (ci->type == INDEX_NORMAL) { + /* Index was in the cue sheet and is present in the file. */ + ci->start = cur_pos; + ci->length = ci->file_length; + cur_pos += ci->file_length; + } + + cdrom_image_backend_log(" TRACK %2i (%2i) (%2i), ATTR %02X, MODE %i, INDEX %i: %2i, " + "start = %016" PRIX64 " (%2i:%02i:%02i), length = %016" PRIX64 + " (%2i:%02i:%02i)\n", + i, map[i], + ct->point, ct->attr, + ct->mode, + j, ci->type, + ci->start, + (int) ((ci->start / 75) / 60), + (int) ((ci->start / 75) % 60), + (int) (ci->start % 75), + ci->length, + (int) ((ci->length / 75) / 60), + (int) ((ci->length / 75) % 60), + (int) (ci->length % 75)); + + /* Set the pre-gap of the first track of this session. */ + if (session_changed) + spg[ct->session] = ct->idx[0].start; + } + } + } + + /* Set the lead out starts for all sessions. */ + for (int i = 0; i <= ls; i++) { + lo[i] = NULL; + for (int j = (cdi->tracks_num - 1); j >= 0; j--) { + track_t *jt = &(cdi->tracks[j]); + if ((jt->session == ct->session) && (jt->point >= 1) && (jt->point <= 99)) { + lo[i] = &(cdi->tracks[j]); + break; + } + } + } + + cdrom_image_backend_log("Fourth pass:\n"); + for (int i = 0; i < cdi->tracks_num; i++) { + ct = &(cdi->tracks[i]); + lt = NULL; + switch (ct->point) { + case 0xa0: + for (int j = 0; j < cdi->tracks_num; j++) { + track_t *jt = &(cdi->tracks[j]); + if ((jt->session == ct->session) && (jt->point >= 1) && (jt->point <= 99)) { + lt = &(cdi->tracks[j]); + break; + } + } + if (lt != NULL) { + int disc_type = 0x00; + + ct->attr = lt->attr; + + ct->mode = lt->mode; + ct->form = lt->form; + + if (lt->mode == 2) + disc_type = (lt->form > 0) ? 0x20 : 0x10; + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + ci->type = INDEX_ZERO; + ci->start = (lt->point * 60 * 75) + (disc_type * 75); + ci->length = 0; + } + } + break; + case 0xa1: + for (int j = (cdi->tracks_num - 1); j >= 0; j--) { + track_t *jt = &(cdi->tracks[j]); + if ((jt->session == ct->session) && (jt->point >= 1) && (jt->point <= 99)) { + lt = &(cdi->tracks[j]); + break; + } + } + if (lt != NULL) { + ct->attr = lt->attr; + + ct->mode = lt->mode; + ct->form = lt->form; + + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + ci->type = INDEX_ZERO; + ci->start = (lt->point * 60 * 75); + ci->length = 0; + } + } + break; + case 0xa2: + if (lo[ct->session] != NULL) { + lt = lo[ct->session]; + + ct->attr = lt->attr; + + ct->mode = lt->mode; + ct->form = lt->form; + + if (ct->idx[1].type != INDEX_NORMAL) { + track_index_t *li = &(lt->idx[2]); + + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + ci->type = INDEX_ZERO; + ci->start = li->start + li->length; + ci->length = 0; + } + } + } + break; + case 0xb0: + /* + B0 MSF (*NOT* PMSF) points to the beginning of the pre-gap + of the corresponding session's first track. + */ + ct->extra[0] = (spg[ct->session] / 75) / 60; + ct->extra[1] = (spg[ct->session] / 75) % 60; + ct->extra[2] = spg[ct->session] % 75; + + /* + B0 PMSF points to the start of the lead out track + of the last session. + */ + if (lo[ls] != NULL) { + lt = lo[ls]; + track_index_t *li = &(lt->idx[2]); + + ct->idx[1].start = li->start + li->length; + } + break; + } + +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG + if ((ct->point >= 0xa0) && (ct->point <= 0xa2)) + cdrom_image_backend_log(" TRACK %02X, SESSION %i: start = %016" PRIX64 " (%2i:%02i:%02i)\n", + ct->point, ct->session, + ct->idx[1].start, + (int) ((ct->idx[1].start / 75) / 60), + (int) ((ct->idx[1].start / 75) % 60), + (int) (ct->idx[1].start % 75)); +#endif + } +} + +int +cdi_load_iso(cd_img_t *cdi, const char *filename) +{ + track_t *ct = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + int success; + int error = 1; + int is_viso = 0; + + cdi->tracks = NULL; + success = 1; + + cdrom_image_backend_log("First pass:\n"); + cdi->tracks_num = 0; + + cdi_insert_track(cdi, 1, 0xa0); + cdi_insert_track(cdi, 1, 0xa1); + cdi_insert_track(cdi, 1, 0xa2); + + /* Data track (shouldn't there be a lead in track?). */ + tf = track_file_init(filename, &error, &is_viso); + + if (error) { + cdrom_image_backend_log("ISO: cannot open file '%s'!\n", filename); + + if (tf != NULL) { + tf->close(tf); + tf = NULL; + } + success = 0; + } else if (is_viso) + success = 3; + + if (success) { + ct = cdi_insert_track(cdi, 1, 1); + ci = &(ct->idx[1]); + + ct->form = 0; + ct->mode = 0; + + for (int i = 0; i < 3; i++) + ct->idx[i].type = INDEX_NONE; + + ct->attr = DATA_TRACK; + + /* Try to detect ISO type. */ + ct->mode = 1; + ct->form = 0; + + ci->type = INDEX_NORMAL; + ci->file_start = 0ULL; + + ci->file = tf; + + /* For Mode 2 XA, skip the first 8 bytes in every sector when sector size = 2336. */ + if (cdi_can_read_pvd(ci->file, RAW_SECTOR_SIZE, 0, 0)) + ct->sector_size = RAW_SECTOR_SIZE; + else if (cdi_can_read_pvd(ci->file, 2336, 1, 0)) { + ct->sector_size = 2336; + ct->mode = 2; + } else if (cdi_can_read_pvd(ci->file, 2324, 1, 2)) { + ct->sector_size = 2324; + ct->mode = 2; + ct->form = 2; + } else if (cdi_can_read_pvd(ci->file, 2328, 1, 2)) { + ct->sector_size = 2328; + ct->mode = 2; + ct->form = 2; + } else if (cdi_can_read_pvd(ci->file, 2336, 1, 1)) { + ct->sector_size = 2336; + ct->mode = 2; + ct->form = 1; + ct->skip = 8; + } else if (cdi_can_read_pvd(ci->file, RAW_SECTOR_SIZE, 1, 0)) { + ct->sector_size = RAW_SECTOR_SIZE; + ct->mode = 2; + } else if (cdi_can_read_pvd(ci->file, RAW_SECTOR_SIZE, 1, 1)) { + ct->sector_size = RAW_SECTOR_SIZE; + ct->mode = 2; + ct->form = 1; + } else { + /* We use 2048 mode 1 as the default. */ + ct->sector_size = COOKED_SECTOR_SIZE; + } + + cdrom_image_backend_log("TRACK 1: Mode = %i, Form = %i, Sector size = %08X\n", + ct->mode, ct->form, ct->sector_size); + } + + tf = NULL; + + if (!success) return 0; - cdi_track_push_back(cdi, cur); + cdi_last_3_passes(cdi); - return 1; + return success; } int cdi_load_cue(cd_img_t *cdi, const char *cuefile) { - track_t trk; - char pathname[MAX_FILENAME_LENGTH]; - uint64_t shift = 0ULL; - uint64_t prestart = 0ULL; - uint64_t cur_pregap = 0ULL; - uint64_t frame = 0ULL; - uint64_t index; - int iso_file_used = 0; - int success; - int error; - int can_add_track = 0; - FILE *fp; - char buf[MAX_LINE_LENGTH]; - char *line; - char *command; - char *type; + track_t *ct = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + uint64_t frame = 0ULL; + uint64_t last = 0ULL; + uint8_t session = 1; + int success; + int error; + int is_viso = 0; + int lead[3] = { 0 }; + char pathname[MAX_FILENAME_LENGTH]; + char buf[MAX_LINE_LENGTH]; + FILE *fp; + char *line; + char *command; + char *type; + char temp; cdi->tracks = NULL; cdi->tracks_num = 0; - memset(&trk, 0, sizeof(track_t)); - /* Get a copy of the filename into pathname, we need it later. */ memset(pathname, 0, MAX_FILENAME_LENGTH * sizeof(char)); path_get_dirname(pathname, cuefile); @@ -1145,11 +1190,20 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) success = 0; - for (;;) { + cdrom_image_backend_log("First pass:\n"); + cdi->tracks_num = 0; + + for (int i = 0; i < 3; i++) { + lead[i] = cdi->tracks_num; + (void *) cdi_insert_track(cdi, session, 0xa0 + i); + } + cdrom_image_backend_log("lead[2] = %016" PRIX64 "\n", (uint64_t) &(cdi->tracks[lead[2]])); + + while (1) { line = buf; /* Read a line from the cuesheet file. */ - if (feof(fp) || fgets(buf, sizeof(buf), fp) == NULL || ferror(fp)) + if (feof(fp) || (fgets(buf, sizeof(buf), fp) == NULL) || ferror(fp)) break; /* Do two iterations to make sure to nuke even if it's \r\n or \n\r, @@ -1164,183 +1218,16 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) /* nuke trailing newline */ } } - cdrom_image_backend_log("line = %s\n", line); + cdrom_image_backend_log(" line = %s\n", line); (void) cdi_cue_get_keyword(&command, &line); - if (!strcmp(command, "TRACK")) { - if (can_add_track) - success = cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap); - else - success = 1; - if (!success) - break; - - cur_pregap = 0; - prestart = 0; - trk.number = cdi_cue_get_number(&line); - trk.track_number = trk.number; - cdrom_image_backend_log("cdi_load_cue(): Track %02X\n", trk.number); - success = cdi_cue_get_keyword(&type, &line); - - memset(trk.indexes, 0x00, sizeof(trk.indexes)); - - if (!success) - break; - - if (iso_file_used) { - /* - We don't alter anything of the detected track type with - the one specified in the CUE file, except its numbers. - */ - can_add_track = 1; - - iso_file_used = 0; - } else { - trk.start = 0; - trk.skip = 0; - - trk.form = 0; - trk.mode2 = 0; - - trk.pre = 0; - - if (!strcmp(type, "AUDIO")) { - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = AUDIO_TRACK; - } else if (!strcmp(type, "MODE1/2048")) { - trk.sector_size = COOKED_SECTOR_SIZE; - trk.attr = DATA_TRACK; - } else if (!strcmp(type, "MODE1/2352")) { - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = DATA_TRACK; - } else if (!strcmp(type, "MODE1/2448")) { - trk.sector_size = 2448; - trk.attr = DATA_TRACK; - } else if (!strcmp(type, "MODE2/2048")) { - trk.form = 1; - trk.sector_size = COOKED_SECTOR_SIZE; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2324")) { - trk.form = 2; - trk.sector_size = 2324; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2328")) { - trk.form = 2; - trk.sector_size = 2328; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2336")) { - trk.form = 1; - trk.sector_size = 2336; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2352")) { - /* Assume this is XA Mode 2 Form 1. */ - trk.form = 1; - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2448")) { - /* Assume this is XA Mode 2 Form 1. */ - trk.form = 1; - trk.sector_size = 2448; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "CDG/2448")) { - trk.sector_size = 2448; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "CDI/2336")) { - trk.sector_size = 2336; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "CDI/2352")) { - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else - success = 0; - - cdrom_image_backend_log("cdi_load_cue(): Format: %i bytes per sector, %02X, %i, %i\n", - trk.sector_size, trk.attr, trk.mode2, trk.form); - - can_add_track = 1; - } - } else if (!strcmp(command, "INDEX")) { - index = cdi_cue_get_number(&line); - success = cdi_cue_get_frame(&frame, &line); - - switch (index) { - case 0: - prestart = frame; - trk.indexes[0].in_file = 1; - trk.indexes[0].start = prestart + total_pregap; - break; - - case 1: - if (trk.indexes[0].in_file) - trk.indexes[0].length = frame - prestart; - else if (cur_pregap > 0) { - trk.indexes[0].start = frame + total_pregap; - trk.indexes[0].length = cur_pregap; - total_pregap += trk.indexes[0].length; - } else if (trk.number == 1) { - trk.indexes[0].start = 0; - trk.indexes[0].length = 150; - total_pregap += trk.indexes[0].length; - } else { - trk.indexes[0].start = frame + total_pregap; - trk.indexes[0].length = 0; - } - cdrom_image_backend_log("Index 0 (%i): %02i:%02i:%02i\n", trk.indexes[0].in_file, - (int) ((trk.indexes[0].start / 75) / 60), - (int) ((trk.indexes[0].start / 75) % 60), - (int) (trk.indexes[0].start % 75)); - - if (cur_pregap > 0) - trk.start = frame + cur_pregap; - else - trk.start = frame; - trk.indexes[1].start = trk.indexes[0].start + trk.indexes[0].length; - trk.indexes[1].in_file = 1; - cdrom_image_backend_log("Index 1 (%i): %02i:%02i:%02i\n", trk.indexes[1].in_file, - (int) ((trk.indexes[1].start / 75) / 60), - (int) ((trk.indexes[1].start / 75) % 60), - (int) (trk.indexes[1].start % 75)); - break; - - case 2: - trk.indexes[2].in_file = 1; - if (cur_pregap > 0) - trk.indexes[2].start = frame + cur_pregap; - else - trk.indexes[2].start = frame; - trk.indexes[1].length = trk.indexes[2].start - trk.indexes[1].start; - trk.indexes[2].length = 0; - cdrom_image_backend_log("Index 2 (%i): %02i:%02i:%02i\n", trk.indexes[2].in_file, - (int) ((trk.indexes[2].start / 75) / 60), - (int) ((trk.indexes[2].start / 75) % 60), - (int) (trk.indexes[2].start % 75)); - break; - - default: - /* Ignore other indices. */ - break; - } - } else if (!strcmp(command, "FILE")) { + if (!strcmp(command, "FILE")) { + /* The file for the track. */ char filename[MAX_FILENAME_LENGTH]; char ansi[MAX_FILENAME_LENGTH]; - if (can_add_track) - success = cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap); - else - success = 1; - if (!success) - break; - can_add_track = 0; + tf = NULL; memset(ansi, 0, MAX_FILENAME_LENGTH * sizeof(char)); memset(filename, 0, MAX_FILENAME_LENGTH * sizeof(char)); @@ -1352,61 +1239,177 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) if (!success) break; - trk.file = NULL; error = 1; + is_viso = 0; if (!strcmp(type, "BINARY") || !strcmp(type, "MOTOROLA")) { - int fn_len = 0; - if (!path_abs(ansi)) { + if (!path_abs(ansi)) path_append_filename(filename, pathname, ansi); - } else { + else strcpy(filename, ansi); - } - fn_len = strlen(filename); - if ((tolower((int) filename[fn_len - 1]) == 'o' - && tolower((int) filename[fn_len - 2]) == 's' - && tolower((int) filename[fn_len - 3]) == 'i' - && filename[fn_len - 4] == '.') - || plat_dir_check(filename)) { - error = !cdi_get_iso_track(cdi, &trk, filename); - if (!error) { - iso_file_used = 1; - } - } else - trk.file = track_file_init(filename, &error); + + tf = track_file_init(filename, &error, &is_viso); - if (trk.file) { - trk.file->motorola = !strcmp(type, "MOTOROLA"); - } + if (tf) + tf->motorola = !strcmp(type, "MOTOROLA"); } else if (!strcmp(type, "WAVE") || !strcmp(type, "AIFF") || !strcmp(type, "MP3")) { - if (!path_abs(ansi)) { + if (!path_abs(ansi)) path_append_filename(filename, pathname, ansi); - } else { + else strcpy(filename, ansi); - } - trk.file = audio_init(filename, &error); + tf = audio_init(filename, &error); } if (error) { cdrom_image_backend_log("CUE: cannot open file '%s' in cue sheet!\n", filename); - if (trk.file != NULL) { - trk.file->close(trk.file); - trk.file = NULL; + if (tf != NULL) { + tf->close(tf); + tf = NULL; } success = 0; - } - } else if (!strcmp(command, "PREGAP")) - success = cdi_cue_get_frame(&cur_pregap, &line); - else if (!strcmp(command, "POSTGAP")) { - success = cdi_cue_get_frame(&trk.indexes[2].length, &line); - trk.indexes[2].in_file = 0; + } else if (is_viso) + success = 3; + } else if (!strcmp(command, "TRACK")) { + int t = cdi_cue_get_number(&line); + success = cdi_cue_get_keyword(&type, &line); + + if (!success) + break; + + ct = cdi_insert_track(cdi, session, t); + + cdrom_image_backend_log(" TRACK %i\n", t); + + ct->form = 0; + ct->mode = 0; + + if (!strcmp(type, "AUDIO")) { + ct->sector_size = RAW_SECTOR_SIZE; + ct->attr = AUDIO_TRACK; + } else if (!memcmp(type, "MODE", 4)) { + uint32_t mode; + ct->attr = DATA_TRACK; + sscanf(type, "MODE%" PRIu32 "/%" PRIu32, &mode, &(ct->sector_size)); + ct->mode = mode; + if (ct->mode == 2) switch(ct->sector_size) { + case 2324: case 2328: + ct->form = 2; + break; + case 2048: case 2336: case 2352: case 2448: + ct->form = 1; + break; + } + if ((ct->sector_size == 2336) && (ct->mode == 2) && (ct->form == 1)) + ct->skip = 8; + } else if (!memcmp(type, "CD", 2)) { + ct->attr = DATA_TRACK; + ct->mode = 2; + sscanf(type, "CD%c/%i", &temp, &(ct->sector_size)); + } else + success = 0; + + if (success) + last = ct->sector_size; + } else if (!strcmp(command, "INDEX")) { + int t = cdi_cue_get_number(&line); + ci = &(ct->idx[t]); + + cdrom_image_backend_log(" INDEX %i (1)\n", t); + + ci->type = INDEX_NORMAL; + ci->file = tf; + success = cdi_cue_get_frame(&frame, &line); + ci->file_start = frame; + } else if (!strcmp(command, "PREGAP")) { + ci = &(ct->idx[0]); + cdrom_image_backend_log(" INDEX 0 (0)\n"); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = cdi_cue_get_frame(&frame, &line); + ci->length = frame; + } else if (!strcmp(command, "PAUSE")) { + ci = &(ct->idx[1]); + cdrom_image_backend_log(" INDEX 1 (0)\n"); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = cdi_cue_get_frame(&frame, &line); + ci->length = frame; + } else if (!strcmp(command, "POSTGAP")) { + ci = &(ct->idx[2]); + cdrom_image_backend_log(" INDEX 2 (0)\n"); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = cdi_cue_get_frame(&frame, &line); + ci->length = frame; + } else if (!strcmp(command, "ZERO")) { + ci = &(ct->idx[1]); + cdrom_image_backend_log(" INDEX 1 (0)\n"); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = cdi_cue_get_frame(&frame, &line); + ci->length = frame; } else if (!strcmp(command, "FLAGS")) - success = cdi_cue_get_flags(&trk, &line); - else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "ISRC") || !strcmp(command, "PERFORMER") || !strcmp(command, "POSTGAP") || !strcmp(command, "REM") || !strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || !strcmp(command, "")) { + success = cdi_cue_get_flags(ct, &line); + else if (!strcmp(command, "REM")) { + success = 1; + char *space = strstr(line, " "); + if (space != NULL) { + space++; + if (space < (line + strlen(line))) { + (void) cdi_cue_get_keyword(&command, &space); + if (!strcmp(command, "LEAD-OUT")) { + ct = &(cdi->tracks[lead[2]]); + cdrom_image_backend_log("lead[2] = %016" PRIX64 "\n", (uint64_t) ct); + ct->sector_size = last; + ci = &(ct->idx[1]); + ci->type = INDEX_NORMAL; + ci->file = tf; + success = cdi_cue_get_frame(&frame, &space); + ci->file_start = frame; + + cdrom_image_backend_log(" LEAD-OUT\n"); + } else if (!strcmp(command, "SESSION")) { + session = cdi_cue_get_number(&space); + + if (session > 1) { + ct = cdi_insert_track(cdi, session - 1, 0xb0); + ci = &(ct->idx[1]); + ci->start = (0x40 * 60 * 75) + (0x02 * 75); + + if (session == 2) { + ct->extra[3] = 0x02; + + /* 5F:00:00 on Wembley, C0:00:00 in the spec. And what's in PMSF? */ + ct = cdi_insert_track(cdi, session - 1, 0xc0); + ci = &(ct->idx[1]); + ct->extra[0] = 0x5f; /* Optimum recording power. */ + } else + ct->extra[3] = 0x01; + + for (int i = 0; i < 3; i++) { + lead[i] = cdi->tracks_num; + (void *) cdi_insert_track(cdi, session, 0xa0 + i); + } + cdrom_image_backend_log("lead[2] = %016" PRIX64 "\n", + (uint64_t) &(cdi->tracks[lead[2]])); + } + + cdrom_image_backend_log(" SESSION %i\n", session); + } + } + } + } else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || + !strcmp(command, "ISRC") || !strcmp(command, "PERFORMER") || + !strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || + !strcmp(command, "")) /* Ignored commands. */ success = 1; - } else { + else { cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", command); success = 0; @@ -1416,94 +1419,75 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) break; } + tf = NULL; + fclose(fp); + if (!success) return 0; - /* Add last track. */ - cdrom_image_backend_log("LEAD OUT\n"); - if (!cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap)) - return 0; + cdi_last_3_passes(cdi); - /* Add lead out track. */ - cdrom_image_backend_log("END OF CUE\n"); - trk.number++; - memset(trk.indexes, 0x00, sizeof(trk.indexes)); - trk.track_number = 0xAA; - // trk.attr = 0x16; - trk.start = 0; - trk.length = 0; - trk.file = NULL; - if (!cdi_add_track(cdi, &trk, &shift, 0, 0)) - return 0; + return success; +} - track_t *cur = &cdi->tracks[cdi->tracks_num - 1]; - track_t *prev = &cdi->tracks[cdi->tracks_num - 2]; +/* Root functions. */ +static void +cdi_clear_tracks(cd_img_t *cdi) +{ + track_file_t *last = NULL; + track_t *cur = NULL; + track_index_t *idx = NULL; - for (int i = 0; i < 3; i++) { - cur->indexes[i].in_file = 0; - cur->indexes[i].start = prev->indexes[1].start + prev->length - 150; - cur->indexes[i].length = 0; - } + if ((cdi->tracks == NULL) || (cdi->tracks_num == 0)) + return; - if (prev->indexes[2].length != 0) { - prev->indexes[2].start = cur->indexes[0].start - prev->indexes[2].length; - prev->indexes[1].length = prev->indexes[2].start - prev->indexes[1].start; - } else if (prev->indexes[2].in_file) - prev->indexes[2].length = cur->indexes[0].start - prev->indexes[2].start; - else { - prev->indexes[1].length = cur->indexes[0].start - prev->indexes[1].start; - prev->indexes[2].start = prev->indexes[1].start + prev->indexes[1].length; - prev->indexes[2].length = 0; - } - -#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG for (int i = 0; i < cdi->tracks_num; i++) { - track_t *t = &(cdi->tracks[i]); - for (int j = 0; j < 3; j++) { - track_index_t *ti = &(t->indexes[j]); - cdrom_image_backend_log("Track %02X.%01X (%i): %02i:%02i:%02i-%02i:%02i:%02i\n", - t->track_number, j, - ti->in_file, - (int) ((ti->start / 75) / 60), - (int) ((ti->start / 75) % 60), - (int) (ti->start % 75), - (int) (((ti->start + ti->length - 1) / 75) / 60), - (int) (((ti->start + ti->length - 1) / 75) % 60), - (int) ((ti->start + ti->length - 1) % 75)); + cur = &cdi->tracks[i]; + + if ((cur->point >= 1) && (cur->point <= 99)) for (int j = 0; j < 3; j++) { + idx = &(cur->idx[j]); + + /* Make sure we do not attempt to close a NULL file. */ + if (idx->file != NULL) { + if (idx->file != last) { + last = idx->file; + index_file_close(idx); + } else + idx->file = NULL; + } } } -#endif - return 1; + /* Now free the array. */ + free(cdi->tracks); + cdi->tracks = NULL; + + /* Mark that there's no tracks. */ + cdi->tracks_num = 0; +} + +void +cdi_close(cd_img_t *cdi) +{ + cdi_clear_tracks(cdi); + free(cdi); } int -cdi_has_data_track(cd_img_t *cdi) +cdi_set_device(cd_img_t *cdi, const char *path) { - if ((cdi == NULL) || (cdi->tracks == NULL)) - return 0; + int ret; - /* Data track has attribute 0x14. */ - for (int i = 0; i < cdi->tracks_num; i++) { - if (cdi->tracks[i].attr == DATA_TRACK) - return 1; - } - - return 0; -} - -int -cdi_has_audio_track(cd_img_t *cdi) -{ - if ((cdi == NULL) || (cdi->tracks == NULL)) - return 0; - - /* Audio track has attribute 0x10. */ - for (int i = 0; i < cdi->tracks_num; i++) { - if (cdi->tracks[i].attr == AUDIO_TRACK) - return 1; - } + if ((ret = cdi_load_cue(cdi, path))) + return ret; + + cdi_clear_tracks(cdi); + + if ((ret = cdi_load_iso(cdi, path))) + return ret; + + cdi_close(cdi); return 0; } diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index edca09d91..24f60836d 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -8,9 +8,7 @@ * * Virtual ISO CD-ROM image back-end. * - * - * - * Authors: RichardG + * Authors: RichardG, * * Copyright 2022 RichardG. */ diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index eccb75fef..2bb691f30 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -55,14 +55,6 @@ cdrom_ioctl_log(const char *fmt, ...) of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static void -ioctl_get_tracks(cdrom_t *dev, int *first, int *last) -{ - TMSF tmsf; - - plat_cdrom_get_audio_tracks(dev->local, first, last, &tmsf); -} - static void ioctl_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) { @@ -209,7 +201,6 @@ ioctl_exit(cdrom_t *dev) } static const cdrom_ops_t cdrom_ioctl_ops = { - ioctl_get_tracks, ioctl_get_track_info, ioctl_get_raw_track_info, ioctl_get_subchannel, diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 8fb0bc742..efb45ecfb 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -218,7 +218,6 @@ typedef struct raw_track_info_t { /* Define the various CD-ROM drive operations (ops). */ typedef struct cdrom_ops_t { - void (*get_tracks)(struct cdrom *dev, int *first, int *last); void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti); void (*get_raw_track_info)(struct cdrom *dev, int *num, raw_track_info_t *rti); void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index 2e3aa85b9..64ce88d83 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -6,16 +6,15 @@ * * This file is part of the 86Box distribution. * - * CD-ROM image file handling module header , translated to C - * from cdrom_dosbox.h. + * CD-ROM image file handling module header. * * Authors: Miran Grca, - * Fred N. van Kempen, - * The DOSBox Team, + * RichardG, + * Cacodemon345 * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2002-2020 The DOSBox Team. + * Copyright 2016-2025 Miran Grca. + * Copyright 2016-2025 Miran Grca. + * Copyright 2024-2025 Cacodemon345. */ #ifndef CDROM_IMAGE_BACKEND_H #define CDROM_IMAGE_BACKEND_H @@ -57,72 +56,59 @@ typedef struct track_file_t { int motorola; } track_file_t; -#define BLOCK_EMPTY 0 /* Empty block. */ -#define BLOCK_ZERO 1 /* Block not in the file, return all 0x00's. */ -#define BLOCK_NORMAL 2 /* Block in the file. */ - -#define BLOCK_NONE ((uint64_t) -1LL) +#define INDEX_SPECIAL -2 /* Track A0h onwards. */ +#define INDEX_NONE -1 /* Empty block. */ +#define INDEX_ZERO 0 /* Block not in the file, return all 0x00's. */ +#define INDEX_NORMAL 1 /* Block in the file. */ typedef struct track_index_t { - /* Is the current block in the file? If not, return all 0x00's. */ - int in_file; + /* Is the current block in the file? If not, return all 0x00's. -1 means not yet loaded. */ + int32_t type; /* The amount of bytes to skip at the beginning of each sector. */ - int skip; + int32_t skip; /* Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1 to read the pregap of track 1. */ uint64_t start; uint64_t length; + uint64_t file_start; + uint64_t file_length; + track_file_t *file; } track_index_t; typedef struct track_t { - int pregap_len; /* Pre-gap - not in file. */ - int index0_len; /* Pre-gap - in file. */ - int postgap_len; /* Post-gap - not in file. */ - int blocks_num; /* Number of blocks. */ - int number; - int track_number; - int attr; - int sector_size; - int mode2; - int form; - int pre; - int noskip; /* Do not skip by 8 bytes.*/ - uint64_t start; - uint64_t length; - uint64_t skip; - track_index_t indexes[3]; - track_file_t *file; + uint8_t session; + uint8_t attr; + uint8_t tno; + uint8_t point; + uint8_t extra[4]; + uint8_t mode; + uint8_t form; + uint8_t pad; + uint8_t skip; + uint32_t sector_size; + track_index_t idx[3]; } track_t; typedef struct cd_img_t { - int tracks_num; - track_t *tracks; + int32_t tracks_num; + track_t *tracks; } cd_img_t; /* Binary file functions. */ -extern void cdi_close(cd_img_t *cdi); -extern int cdi_set_device(cd_img_t *cdi, const char *path); -extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); -extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); -extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track); -extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, - TMSF *start, uint8_t *attr); -extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, - uint32_t *start, uint8_t *attr); extern void cdi_get_raw_track_info(cd_img_t *cdi, int *num, uint8_t *buffer); -extern int cdi_get_track(cd_img_t *cdi, uint32_t sector); extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); extern int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector); -extern int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num); extern int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector); extern int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector); +extern int cdi_is_audio(cd_img_t *cdi, uint32_t sector); +extern int cdi_is_pre(cd_img_t *cdi, uint32_t sector); extern int cdi_is_mode2(cd_img_t *cdi, uint32_t sector); extern int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector); extern int cdi_load_iso(cd_img_t *cdi, const char *filename); extern int cdi_load_cue(cd_img_t *cdi, const char *cuefile); -extern int cdi_has_data_track(cd_img_t *cdi); -extern int cdi_has_audio_track(cd_img_t *cdi); +extern void cdi_close(cd_img_t *cdi); +extern int cdi_set_device(cd_img_t *cdi, const char *path); /* Virtual ISO functions. */ extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count); diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h index 1e70e014b..643013a08 100644 --- a/src/include/86box/plat_cdrom.h +++ b/src/include/86box/plat_cdrom.h @@ -53,7 +53,6 @@ extern void plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_i extern int plat_cdrom_is_track_audio(void *local, uint32_t sector); extern int plat_cdrom_is_track_pre(void *local, uint32_t sector); extern uint32_t plat_cdrom_get_last_block(void *local); -extern void plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out); extern int plat_cdrom_get_audio_track_info(void *local, int end, int track, int *track_num, TMSF *start, uint8_t *attr); extern int plat_cdrom_get_audio_sub(void *local, uint32_t sector, uint8_t *attr, uint8_t *track, diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index 8555642e6..4ed0333a7 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local) return ret; } -void -plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out) -{ - dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - - plat_cdrom_read_toc(ioctl); - - *st_track = 1; - *end = 1; - lead_out->min = 0; - lead_out->sec = 0; - lead_out->fr = 2; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", - *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); -} - /* This replaces both Info and EndInfo, they are specified by a variable. */ int plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 7e3a588c3..9d82d68cc 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -398,26 +398,6 @@ plat_cdrom_ext_medium_changed(void *local) return ret; } -void -plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out) -{ - win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; - PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; - - plat_cdrom_read_toc(ioctl); - - PTRACK_DATA ltd = &toc->TrackData[toc->LastTrack]; - - *st_track = 1; - *end = toc->LastTrack; - lead_out->min = ltd->Address[1]; - lead_out->sec = ltd->Address[2]; - lead_out->fr = ltd->Address[3]; - - win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", - *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); -} - /* This replaces both Info and EndInfo, they are specified by a variable. */ int plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index 8555642e6..4ed0333a7 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local) return ret; } -void -plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out) -{ - dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - - plat_cdrom_read_toc(ioctl); - - *st_track = 1; - *end = 1; - lead_out->min = 0; - lead_out->sec = 0; - lead_out->fr = 2; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", - *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); -} - /* This replaces both Info and EndInfo, they are specified by a variable. */ int plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) From 45d952c8cf1e6dde31919e2ca882f8cf4a4166dd Mon Sep 17 00:00:00 2001 From: conan7123 Date: Thu, 2 Jan 2025 22:51:55 +0100 Subject: [PATCH 46/52] Add comment for pl4600c / Compaq Presario 7100 in machine table --- src/machine/machine_table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a414bbd0d..f5a0a9d1c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8668,6 +8668,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Compaq Presario 7100 / 7200 Series, using MiTAC/Trigon PL4600C (486). */ + /* Has a VIA VT82C42N KBC. */ { .name = "[UMC 8881] Compaq Presario 7100/7200 Series 486", .internal_name = "pl4600c", From cc73c0efe4b404af946041b9faf1f2c85afdca07 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 2 Jan 2025 23:49:50 +0100 Subject: [PATCH 47/52] Late day changes (January 2nd, 2025) Actually recognize the Trantor 228 MCA SCSI controller as such (bit 3 of status is for the PS/2 MCA bus type of the 128 controller) --- src/scsi/scsi_t128.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index 3a49f599f..c878bbb91 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -509,6 +509,9 @@ t128_init(const device_t *info) if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; + if (info->flags & DEVICE_MCA) + t128->status |= 0x08; + if (info->local == 0) timer_add(&t128->timer, t128_callback, t128, 0); From 06923a28007550bc8d060399382f513c7ffb850d Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 00:15:28 +0100 Subject: [PATCH 48/52] Switched back to raw input - it appears it *does* work with the hook. --- src/86box.c | 10 ++++--- src/include/86box/86box.h | 2 +- src/qt/qt_main.cpp | 48 +++++++-------------------------- src/qt/qt_winrawinputfilter.cpp | 9 ++----- 4 files changed, 19 insertions(+), 50 deletions(-) diff --git a/src/86box.c b/src/86box.c index fc698a5ee..8fa74fd4b 100644 --- a/src/86box.c +++ b/src/86box.c @@ -206,7 +206,7 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether also apply when maximized. */ int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus loss */ -int raw_input = 0; /* (C) Use raw input */ +int hook_enabled = 1; /* (C) Keyboard hook is enabled */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are @@ -453,6 +453,8 @@ delete_nvr_file(uint8_t flash) fn = NULL; } +extern void device_find_all_descs(void); + /* * Perform initial startup of the PC. * @@ -562,7 +564,7 @@ usage: printf("-S or --settings - show only the settings dialog\n"); #endif printf("-V or --vmname name - overrides the name of the running VM\n"); - printf("-W or --raw - uses raw input (compatibility-only outside Windows)\n"); + printf("-W or --nohook - disables keyboard hook (compatibility-only outside Windows)\n"); printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n"); printf("-Y or --donothing - do not show any UI or run the emulation\n"); printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); @@ -638,8 +640,8 @@ usage: dump_missing = 1; } else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) { do_nothing = 1; - } else if (!strcasecmp(argv[c], "--raw") || !strcasecmp(argv[c], "-W")) { - raw_input = 1; + } else if (!strcasecmp(argv[c], "--nohook") || !strcasecmp(argv[c], "-W")) { + hook_enabled = 0; } else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) { if ((c + 1) == argc) goto usage; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index fb4a182a0..ffa670b7e 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -165,7 +165,7 @@ extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */ #endif extern int pit_mode; /* (C) force setting PIT mode */ extern int fm_driver; /* (C) select FM sound driver */ -extern int raw_input; /* (C) Use raw input */ +extern int hook_enabled; /* (C) Keyboard hook is enabled */ /* Keyboard variables for future key combination redefinition. */ extern uint16_t key_prefix_1_1; diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c602b9ea1..6da0b0285 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -43,6 +43,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) #endif #ifdef Q_OS_WINDOWS +# include "qt_rendererstack.hpp" # include "qt_winrawinputfilter.hpp" # include "qt_winmanagerfilter.hpp" # include <86box/win.h> @@ -143,50 +144,20 @@ keyboard_getkeymap() } } -static void -kbd_handle(uint16_t scancode, uint16_t flags) -{ - if (flags & LLKHF_EXTENDED) - scancode |= 0x100; - - /* Translate the scan code to 9-bit */ - scancode = convert_scan_code(scancode); - - /* Remap it according to the list from the Registry */ - if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { - // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); - scancode = scancode_map[scancode]; - } - - /* If it's not 0xFFFF, send it to the emulated - keyboard. - 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 - chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; - - /* Normal scan code pass through, pass it through as is if - it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(flags & LLKHF_UP), scancode); - - main_window->checkFullscreenHotkey(); -} - static LRESULT CALLBACK emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; /* Checks if CTRL was pressed. */ BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); + BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId())); - if ((GetForegroundWindow() == ((HWND) main_window->winId())) && !(lpKdhs->scanCode & 0xff00)) - kbd_handle(lpKdhs->scanCode, lpKdhs->flags); + if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { + const auto &secondaryRenderer = main_window->renderers[monitor_index]; + is_over_window = is_over_window && (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); + } - if ((nCode < 0) || (nCode != HC_ACTION) || (!mouse_capture && !video_fullscreen)) + if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window) return CallNextHookEx(NULL, nCode, wParam, lParam); else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) @@ -480,7 +451,7 @@ 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; + hook_enabled = 0; } /* Setup raw input */ @@ -547,7 +518,8 @@ main(int argc, char *argv[]) }); #ifdef Q_OS_WINDOWS - if (!raw_input) { + if (hook_enabled) { + /* Yes, low-level hooks *DO* work raw input, at least global ones. */ llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); atexit([] () -> void { if (llhook) diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 4ff515c49..2c11a068a 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -64,9 +64,7 @@ WindowsRawInputFilter::Register(MainWindow *window) .hwndTarget = nullptr} }; - if (raw_input && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)) - return std::unique_ptr(nullptr); - else if (!raw_input && RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE) + if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) return std::unique_ptr(nullptr); std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); @@ -97,10 +95,7 @@ WindowsRawInputFilter::~WindowsRawInputFilter() .hwndTarget = NULL} }; - if (raw_input) - RegisterRawInputDevices(rid, 2, sizeof(rid[0])); - else - RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])); + RegisterRawInputDevices(rid, 2, sizeof(rid[0])); } bool From 509e1e596151d70eb5d52ab0c52a2def83485e05 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 00:27:21 +0100 Subject: [PATCH 49/52] cdrom/cdrom.c that I forgot to commit before. --- src/cdrom/cdrom.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ac002ab65..4b01a109d 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1426,33 +1426,11 @@ cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf) buf[8] = 0x00; } +/* TODO: Actually implement this properly. */ void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode) { - track_info_t ti; - int first_track; - int last_track; - - if (dev != NULL) { - dev->ops->get_tracks(dev, &first_track, &last_track); - dev->ops->get_track_info(dev, *curtoctrk, 0, &ti); - buf[0] = (ti.attr << 4) & 0xf0; - buf[1] = ti.number; - buf[2] = bin2bcd(*curtoctrk + 1); - buf[3] = ti.m; - buf[4] = ti.s; - buf[5] = ti.f; - buf[6] = 0x00; - dev->ops->get_track_info(dev, 1, 0, &ti); - buf[7] = ti.m; - buf[8] = ti.s; - buf[9] = ti.f; - if (*curtoctrk >= (last_track + 1)) - *curtoctrk = 0; - else if (mode) - *curtoctrk = *curtoctrk + 1; - } else - memset(buf, 0x00, 10); + memset(buf, 0x00, 10); } uint8_t From 92e5ed6aaeaad4d665bce1f15d7e42067bc4ae53 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 00:47:35 +0100 Subject: [PATCH 50/52] Keyboard hook: Fixed segmentation fault when non-primary monitors are enabled but none is actually in use. --- src/qt/qt_main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 6da0b0285..20af6a13d 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -154,7 +154,8 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { const auto &secondaryRenderer = main_window->renderers[monitor_index]; - is_over_window = is_over_window && (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); + is_over_window = is_over_window && (secondaryRenderer != nullptr) && + (GetForegroundWindow() == ((HWND) secondaryRenderer->winId())); } if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window) From 370c560c3423d40747bd8051febb17a39bce2197 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jan 2025 01:19:52 +0100 Subject: [PATCH 51/52] Only attempt Cue sheet parsing on files that end in .cue (in any letter case), fixes errors with some .ISO images. --- src/cdrom/cdrom.c | 4 ++-- src/cdrom/cdrom_image_backend.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 4b01a109d..6d993f24a 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -2174,7 +2174,7 @@ cdrom_exit(uint8_t id) memset(dev->image_path, 0, sizeof(dev->image_path)); - pclog("cdrom_exit(%i): cdrom_insert(%i)\n", id, id); + cdrom_log("cdrom_exit(%i): cdrom_insert(%i)\n", id, id); cdrom_insert(id); } @@ -2252,7 +2252,7 @@ cdrom_reload(uint8_t id) #endif /* Signal media change to the emulated machine. */ - pclog("cdrom_reload(%i): cdrom_insert(%i)\n", id, id); + cdrom_log("cdrom_reload(%i): cdrom_insert(%i)\n", id, id); cdrom_insert(id); /* The drive was previously empty, transition directly to UNIT ATTENTION. */ diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 3c09cb56c..9d065a0cb 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -436,7 +436,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) const uint64_t seek = (sect + 150 - idx->start + idx->file_start) * trk->sector_size; cdrom_image_backend_log("cdrom_read_sector(%08X): track %02X, index %02X, %016" PRIX64 ", %016" PRIX64 ", %i\n", - sector, track, index, trk->start, trk->sector_size); + sector, track, index, idx->start, trk->sector_size); if (track_is_raw) raw_size = trk->sector_size; @@ -1477,12 +1477,18 @@ cdi_close(cd_img_t *cdi) int cdi_set_device(cd_img_t *cdi, const char *path) { - int ret; + uintptr_t ext = path + strlen(path) - strrchr(path, '.'); + int ret; - if ((ret = cdi_load_cue(cdi, path))) - return ret; + cdrom_image_backend_log("cdi_set_device(): %" PRIu64 ", %lli, %s\n", + ext, strlen(path), path + strlen(path) - ext + 1); - cdi_clear_tracks(cdi); + if ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE")) { + if ((ret = cdi_load_cue(cdi, path))) + return ret; + + cdi_clear_tracks(cdi); + } if ((ret = cdi_load_iso(cdi, path))) return ret; From 15715bbb79ad1b37cc00281a78c33422564343fd Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 7 Feb 2024 22:30:08 -0500 Subject: [PATCH 52/52] Add Ensoniq ES1370 Co-Authored-By: Cacodemon345 <38420290+Cacodemon345@users.noreply.github.com> --- src/include/86box/snd_akm4531.h | 22 + src/include/86box/sound.h | 1 + src/sound/snd_audiopci.c | 836 ++++++++++++++++++++++++-------- src/sound/sound.c | 1 + 4 files changed, 665 insertions(+), 195 deletions(-) create mode 100644 src/include/86box/snd_akm4531.h diff --git a/src/include/86box/snd_akm4531.h b/src/include/86box/snd_akm4531.h new file mode 100644 index 000000000..96f87b396 --- /dev/null +++ b/src/include/86box/snd_akm4531.h @@ -0,0 +1,22 @@ +/* + * 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. + * + * Ensoniq AudioPCI family emulation. + * + * Authors: Cacodemon345 + * + * Copyright 2024-2025 Cacodemon345. + */ +struct akm4531_t +{ + unsigned char registers[256]; +}; + +typedef struct akm4531_t akm4531_t; + +double akm4531_apply_master_vol(unsigned short sample); \ No newline at end of file diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index e5ae227fd..645d974dd 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -185,6 +185,7 @@ extern const device_t ess_soundpiper_32_mca_device; extern const device_t ess_chipchat_16_mca_device; /* Ensoniq AudioPCI */ +extern const device_t es1370_device; extern const device_t es1371_device; extern const device_t es1371_onboard_device; extern const device_t es1373_device; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 7338a11fc..45b8d4c8c 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -8,15 +8,17 @@ * * Ensoniq AudioPCI family emulation. * - * - * * Authors: Sarah Walker, * RichardG, * Miran Grca, + * Jasmine Iwanek, + * Cacodemon345 * * Copyright 2008-2021 Sarah Walker. * Copyright 2021-2024 RichardG. - * Copyright 2021 Miran Grca. + * Copyright 2021 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. + * Copyright 2024-2025 Cacodemon345. */ #include #include @@ -39,14 +41,15 @@ #include <86box/sound.h> #include <86box/timer.h> #include <86box/plat_unused.h> +#include <86box/snd_akm4531.h> #define N 16 -#define ES1371_NCoef 91 +#define ES137x_NCoef 91 -static float low_fir_es1371_coef[ES1371_NCoef]; +static float low_fir_es137x_coef[ES137x_NCoef]; -typedef struct es1371_t { +typedef struct es137x_t { uint8_t pci_command; uint8_t pci_serr; @@ -111,6 +114,9 @@ typedef struct es1371_t { int16_t out_l; int16_t out_r; + int16_t prev_out_l; + int16_t prev_out_r; + int32_t vol_l; int32_t vol_r; } dac[2], adc; @@ -130,11 +136,35 @@ typedef struct es1371_t { uint8_t pci_slot; int pos; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[WTBUFLEN * 2]; uint32_t type; -} es1371_t; + akm4531_t akm_codec; + + uint32_t calc_sample_rate; + uint32_t calc_sample_rate_synth; + + double interp_factor; + uint32_t interp_step; + + double interp_factor_synth; + uint32_t interp_step_synth; + + uint32_t step_pcm; + uint32_t step_synth; +} es137x_t; + +static const double akm4531_att_2dbstep_5bits[] = { + 25.0, 32.0, 41.0, 51.0, 65.0, 82.0, 103.0, 130.0, + 164.0, 206.0, 260.0, 327.0, 412.0, 519.0, 653.0, 822.0, + 1036.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 +}; + +static double akm4531_gain_2dbstep_5bits[0x20]; + +#define AUDIOPCI_ES1370 0x50001271 #define AUDIOPCI_ES1371 0x13710200 #define AUDIOPCI_ES1373 0x13710400 #define AUDIOPCI_CT5880 0x58800400 @@ -204,8 +234,8 @@ typedef struct es1371_t { #define FORMAT_MONO_16 2 #define FORMAT_STEREO_16 3 -static void es1371_fetch(es1371_t *dev, int dac_nr); -static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl); +static void es137x_fetch(es137x_t *dev, int dac_nr); +static void update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl); #ifdef ENABLE_AUDIOPCI_LOG int audiopci_do_log = ENABLE_AUDIOPCI_LOG; @@ -226,7 +256,7 @@ audiopci_log(const char *fmt, ...) #endif static void -es1371_update_irqs(es1371_t *dev) +es137x_update_irqs(es137x_t *dev) { int irq = 0; @@ -257,63 +287,63 @@ es1371_update_irqs(es1371_t *dev) } static void -es1371_update_tx_irq(es1371_t *dev) +es137x_update_tx_irq(es137x_t *dev) { dev->uart_status &= ~UART_STATUS_TXINT; if (((dev->uart_ctrl & UART_CTRL_TXINTEN) == 0x20) && (dev->uart_status & UART_STATUS_TXRDY)) dev->uart_status |= UART_STATUS_TXINT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); } static void -es1371_set_tx_irq(es1371_t *dev, int set) +es137x_set_tx_irq(es137x_t *dev, int set) { dev->uart_status &= ~UART_STATUS_TXRDY; if (set) dev->uart_status |= UART_STATUS_TXRDY; - es1371_update_tx_irq(dev); + es137x_update_tx_irq(dev); } static void -es1371_update_rx_irq(es1371_t *dev) +es137x_update_rx_irq(es137x_t *dev) { dev->uart_status &= ~UART_STATUS_RXINT; if ((dev->uart_ctrl & UART_CTRL_RXINTEN) && (dev->uart_status & UART_STATUS_RXRDY)) dev->uart_status |= UART_STATUS_RXINT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); } static void -es1371_set_rx_irq(es1371_t *dev, int set) +es137x_set_rx_irq(es137x_t *dev, int set) { dev->uart_status &= ~UART_STATUS_RXRDY; if (set) dev->uart_status |= UART_STATUS_RXRDY; - es1371_update_rx_irq(dev); + es137x_update_rx_irq(dev); } static void -es1371_scan_fifo(es1371_t *dev) +es137x_scan_fifo(es137x_t *dev) { if (dev->read_fifo_pos != dev->write_fifo_pos) { dev->uart_data = dev->uart_fifo[dev->read_fifo_pos]; dev->read_fifo_pos = (dev->read_fifo_pos + 1) & 7; - es1371_set_rx_irq(dev, 1); + es137x_set_rx_irq(dev, 1); } else - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); } static void -es1371_write_fifo(es1371_t *dev, uint8_t val) +es137x_write_fifo(es137x_t *dev, uint8_t val) { if (dev->write_fifo_pos < 8) { dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; @@ -322,27 +352,89 @@ es1371_write_fifo(es1371_t *dev, uint8_t val) } static void -es1371_reset_fifo(es1371_t *dev) +es137x_reset_fifo(es137x_t *dev) { for (uint8_t i = 0; i < 8; i++) dev->uart_fifo[i] = 0x00000000; dev->read_fifo_pos = dev->write_fifo_pos = 0; - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); } static void -es1371_reset(void *priv) +akm4531_reset(es137x_t *dev) { - es1371_t *dev = (es1371_t *) priv; + akm4531_t* codec = &dev->akm_codec; + + memset(codec->registers, 0, sizeof(codec->registers)); + + codec->registers[0] = 0x80; + codec->registers[1] = 0x80; + + for (int i = 0x02; i <= 0x0E; i++) { + codec->registers[i] = 0b10000110; + } + + codec->registers[0xf] = 0x80; + + codec->registers[0x17] = 0x3; + codec->registers[0x16] = 0x3; +} + +static double lerp(double v0, double v1, double t) { + return (1. - t) * v0 + t * v1; +} + +static void +es1370_calc_sample_rate(es137x_t *dev) +{ + if (dev->type != AUDIOPCI_ES1370) + return; + + dev->calc_sample_rate = 1411200 / (((dev->int_ctrl >> 16) & 0x1fff) + 2); + + //pclog("ES1370 calc sample rate %u\n", dev->calc_sample_rate); + + dev->interp_factor = 1.0; + dev->interp_step = 1; + + if (dev->calc_sample_rate >= 44100 || dev->calc_sample_rate < 11025) { + dev->interp_factor = 1.0; + dev->interp_step = 1; + dev->calc_sample_rate = 44100; + } + if (dev->calc_sample_rate == 22050) { + dev->interp_factor = 0.5; + dev->interp_step = 2; + } + if (dev->calc_sample_rate == 11025) { + dev->interp_factor = 0.25; + dev->interp_step = 4; + } + if ((((dev->int_ctrl >> 16) & 0x1fff) + 2) == 256) { + /* 5512.5 Hz */ + dev->interp_factor = 0.125; + dev->interp_step = 8; + dev->calc_sample_rate = 5512; + } + + dev->calc_sample_rate_synth = 44100 / (1 << ((dev->int_ctrl >> 12) & 3)); + dev->interp_factor_synth = 1. / (double)(1 << ((dev->int_ctrl >> 12) & 3)); + dev->interp_step_synth = (1 << ((dev->int_ctrl >> 12) & 3)); +} + +static void +es137x_reset(void *priv) +{ + es137x_t *dev = (es137x_t *) priv; nmi = 0; /* Default subsystem ID. */ dev->subsys_lock = 0x00; - *((uint16_t *) &dev->subsys_id[0]) = 0x1274; - *((uint16_t *) &dev->subsys_id[2]) = 0x1371; + *((uint16_t *) &dev->subsys_id[0]) = (dev->type == AUDIOPCI_ES1370) ? 0x4942 : 0x1274; + *((uint16_t *) &dev->subsys_id[2]) = (dev->type == AUDIOPCI_ES1370) ? 0x4c4c : 0x1371; /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ @@ -352,7 +444,7 @@ es1371_reset(void *priv) Addressable as longword only */ if (dev->type >= AUDIOPCI_CT5880) dev->int_status = 0x52080ec0; - else if (dev->type >= AUDIOPCI_ES1373) + else if (dev->type >= AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) dev->int_status = 0x7f080ec0; else dev->int_status = 0x7ffffec0; @@ -441,17 +533,20 @@ es1371_reset(void *priv) dev->uart_fifo[i] = 0xffff0000; /* Reset the UART TX. */ - es1371_set_tx_irq(dev, 0); + es137x_set_tx_irq(dev, 0); /* Reset the UART (RX) FIFO. */ - es1371_reset_fifo(dev); + es137x_reset_fifo(dev); /* Update interrupts to ensure they're all correctly cleared. */ - es1371_update_irqs(dev); + es137x_update_irqs(dev); + + /* Reset the codec. */ + akm4531_reset(dev); } static uint32_t -es1371_read_frame_reg(es1371_t *dev, int frame, int page) +es137x_read_frame_reg(es137x_t *dev, int frame, int page) { uint32_t ret = 0xffffffff; @@ -559,7 +654,7 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) } static void -es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) +es137x_write_frame_reg(es137x_t *dev, int frame, int page, uint32_t val) { switch (frame) { case 0x30: @@ -666,9 +761,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) } static uint8_t -es1371_inb(uint16_t port, void *priv) +es137x_inb(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint8_t ret = 0xff; switch (port & 0x3f) { @@ -685,7 +780,7 @@ es1371_inb(uint16_t port, void *priv) break; case 0x03: ret = dev->int_ctrl >> 24; - if (dev->type < AUDIOPCI_ES1373) + if (dev->type < AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) ret |= 0xfc; break; @@ -713,7 +808,7 @@ es1371_inb(uint16_t port, void *priv) Addressable as byte only */ case 0x08: ret = dev->uart_data; - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); audiopci_log("[R] UART DATA = %02X\n", ret); break; @@ -758,19 +853,19 @@ es1371_inb(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus & 0xff; break; case 0x1d: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 8; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 16; break; case 0x1f: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 24; break; @@ -790,17 +885,17 @@ es1371_inb(uint16_t port, void *priv) break; default: - audiopci_log("Bad es1371_inb: port=%04x\n", port); + audiopci_log("Bad es137x_inb: port=%04x\n", port); } - audiopci_log("es1371_inb: port=%04x ret=%02x\n", port, ret); + audiopci_log("es137x_inb: port=%04x ret=%02x\n", port, ret); return ret; } static uint16_t -es1371_inw(uint16_t port, void *priv) +es137x_inw(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint16_t ret = 0xffff; switch (port & 0x3e) { @@ -811,7 +906,7 @@ es1371_inw(uint16_t port, void *priv) break; case 0x02: ret = (dev->int_ctrl >> 16) & 0xff0f; - if (dev->type < AUDIOPCI_ES1373) + if (dev->type < AUDIOPCI_ES1373 && dev->type != AUDIOPCI_ES1370) ret |= 0xfc00; break; @@ -836,11 +931,11 @@ es1371_inw(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus & 0xffff; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) ret = dev->spdif_chstatus >> 16; break; @@ -884,36 +979,39 @@ es1371_inw(uint16_t port, void *priv) case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) & 0xffff; + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page) & 0xffff; break; case 0x32: case 0x36: case 0x3a: case 0x3e: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; break; default: break; } - audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret); + audiopci_log("es137x_inw: port=%04x ret=%04x\n", port, ret); return ret; } static uint32_t -es1371_inl(uint16_t port, void *priv) +es137x_inl(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t ret = 0xffffffff; + if (dev->type == AUDIOPCI_ES1370 && (port & 0x3c) == 0x14) + port = 0x10; + switch (port & 0x3c) { /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: ret = dev->int_ctrl & 0xff0fffff; - if (ret < AUDIOPCI_ES1373) + if (ret < AUDIOPCI_ES1373 && ret != AUDIOPCI_ES1370) ret |= 0xfc000000; break; @@ -940,6 +1038,8 @@ es1371_inl(uint16_t port, void *priv) /* CODEC Read Register, Address 14H Addressable as longword only */ case 0x14: + if (dev->type == AUDIOPCI_ES1370) + break; ret = dev->codec_ctrl | CODEC_READY; break; @@ -952,7 +1052,7 @@ es1371_inl(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 || dev->type == AUDIOPCI_ES1370) ret = dev->spdif_chstatus; break; @@ -984,24 +1084,24 @@ es1371_inl(uint16_t port, void *priv) case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page); + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page); break; default: break; } - audiopci_log("es1371_inl: port=%04x ret=%08x\n", port, ret); + audiopci_log("es137x_inl: port=%04x ret=%08x\n", port, ret); return ret; } static void -es1371_outb(uint16_t port, uint8_t val, void *priv) +es137x_outb(uint16_t port, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; - audiopci_log("es1371_outb: port=%04x val=%02x\n", port, val); + audiopci_log("es137x_outb: port=%04x val=%02x\n", port, val); switch (port & 0x3f) { /* Interrupt/Chip Select Control Register, Address 00H @@ -1011,36 +1111,44 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + es137x_fetch(dev, 1); } + //pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; break; case 0x01: dev->int_ctrl = (dev->int_ctrl & 0xffff00ff) | (val << 8); + es1370_calc_sample_rate(dev); break; case 0x02: dev->int_ctrl = (dev->int_ctrl & 0xff00ffff) | (val << 16); + es1370_calc_sample_rate(dev); break; case 0x03: dev->int_ctrl = (dev->int_ctrl & 0x00ffffff) | (val << 24); gameport_remap(dev->gameport, 0x200 | ((val & 0x03) << 3)); + es1370_calc_sample_rate(dev); break; /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only, but PCem implements byte access, which must be for a reason */ case 0x06: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 || dev->type == AUDIOPCI_ES1370) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; case 0x07: - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type >= AUDIOPCI_CT5880 || dev->type == AUDIOPCI_ES1370) dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); break; @@ -1050,7 +1158,7 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) audiopci_log("MIDI data = %02x\n", val); /* TX does not use FIFO. */ midi_raw_out_byte(val); - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); break; /* UART Control Register, Address 09H @@ -1061,15 +1169,15 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) if ((val & 0x03) == 0x03) { /* Reset TX */ - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); /* Software reset */ - es1371_reset_fifo(dev); + es137x_reset_fifo(dev); } else { - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); - es1371_update_tx_irq(dev); - es1371_update_rx_irq(dev); + es137x_update_tx_irq(dev); + es137x_update_rx_irq(dev); } break; @@ -1101,7 +1209,7 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) case 0x1b: old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x00ffffff) | (val << 24); - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1131,21 +1239,21 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; case 0x22: dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); break; default: - audiopci_log("Bad es1371_outb: port=%04x val=%02x\n", port, val); + audiopci_log("Bad es137x_outb: port=%04x val=%02x\n", port, val); } } static void -es1371_outw(uint16_t port, uint16_t val, void *priv) +es137x_outw(uint16_t port, uint16_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; switch (port & 0x3f) { @@ -1156,19 +1264,27 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dev->step_synth = dev->interp_step_synth; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dev->step_pcm = dev->interp_step; + es137x_fetch(dev, 1); } + //pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffff0000) | val; break; case 0x02: dev->int_ctrl = (dev->int_ctrl & 0x0000ffff) | (val << 16); gameport_remap(dev->gameport, 0x200 | ((val & 0x0300) >> 5)); + es1370_calc_sample_rate(dev); break; /* Memory Page Register, Address 0CH @@ -1179,6 +1295,17 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) case 0x0e: break; + /* CODEC Write Register, Address 10H + Addressable as word, longword */ + case 0x10: + if (dev->type != AUDIOPCI_ES1370) + break; + + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; + if ((val >> 8) == 0x16 && !(val & 1)) + akm4531_reset(dev); + break; + /* Legacy Control/Status Register, Address 18H Addressable as byte, word, longword */ case 0x18: @@ -1187,7 +1314,7 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) case 0x1a: old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val << 16); - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1208,7 +1335,7 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; case 0x22: dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); @@ -1238,32 +1365,47 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) } static void -es1371_outl(uint16_t port, uint32_t val, void *priv) +es137x_outl(uint16_t port, uint32_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; - audiopci_log("es1371_outl: port=%04x val=%08x\n", port, val); + audiopci_log("es137x_outl: port=%04x val=%08x\n", port, val); switch (port & 0x3f) { /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: + { + uint8_t dac1start = 0, dac2start = 0; if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dac1start = 1; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dac2start = 1; + es137x_fetch(dev, 1); } + //pclog("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = val; gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); + es1370_calc_sample_rate(dev); + if (dac1start) + dev->step_synth = dev->interp_step_synth; + if (dac2start) + dev->step_pcm = dev->interp_step; break; + } /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ @@ -1271,7 +1413,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) audiopci_log("[W] STATUS = %08X\n", val); if (dev->type >= AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd208ffff) | (val & 0x2df70000); - else if (dev->type >= AUDIOPCI_ES1373) + else if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; @@ -1284,6 +1426,13 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* Sample Rate Converter Interface Register, Address 10H Addressable as longword only */ case 0x10: + if (dev->type == AUDIOPCI_ES1370) + { + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; + if ((val >> 8) == 0x16 && !(val & 1)) + akm4531_reset(dev); + break; + } dev->sr_cir = val & 0xfff8ffff; /*Bits 16 to 18 are undefined*/ if (dev->sr_cir & SRC_RAM_WE) { dev->sr_ram[dev->sr_cir >> 25] = val & 0xffff; @@ -1334,6 +1483,8 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* CODEC Write Register, Address 14H Addressable as longword only */ case 0x14: + if (dev->type == AUDIOPCI_ES1370) + break; if (val & CODEC_READ) { dev->codec_ctrl &= 0x00ff0000; dev->codec_ctrl |= ac97_codec_readw(dev->codec, val >> 16); @@ -1354,7 +1505,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val & 0xffff0000); dev->legacy_ctrl |= LEGACY_INT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1372,7 +1523,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1397,7 +1548,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) case 0x34: case 0x38: case 0x3c: - es1371_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); + es137x_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); break; default: @@ -1406,7 +1557,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) } static void -capture_event(es1371_t *dev, int type, int rw, uint16_t port) +capture_event(es137x_t *dev, int type, int rw, uint16_t port) { dev->legacy_ctrl &= ~(LEGACY_EVENT_MASK | LEGACY_EVENT_ADDR_MASK); dev->legacy_ctrl |= type; @@ -1524,7 +1675,7 @@ capture_read_slave_dma(uint16_t port, void *priv) } static void -update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) +update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl) { if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { @@ -1713,10 +1864,112 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) } } +static uint8_t +es1370_pci_read(int func, int addr, void *priv) +{ + const es137x_t *dev = (es137x_t *) priv; + + if (func > 0) + return 0xff; + + if ((addr > 0x3f) && ((addr < 0xdc) || (addr > 0xe1))) + return 0x00; + + switch (addr) { + case 0x00: /* Vendor ID */ + return 0x74; /* Ensoniq */ + case 0x01: + return 0x12; + + case 0x02: /* Device ID */ + return 0x00; /* ES1370 */ + case 0x03: + return 0x50; + + case 0x04: /* Command TODO */ + return dev->pci_command; + case 0x05: + return dev->pci_serr; + + case 0x06: /* Status TODO */ + return 0x10; /* Supports ACPI */ + case 0x07: + return 0x00; + + case 0x08: /* Class Code & Revision ID */ + return 0x00; /* Revision ID - 0x00 is actual Ensoniq-branded ES1370 */ + case 0x09: + return 0x00; /* Multimedia audio device */ + case 0x0a: + return 0x01; + case 0x0b: + return 0x04; + +// case 0x0c: /* Cache Line Size TODO */ +// case 0x0d: /* Latency Timer TODO */ +// case 0x0e: /* Header Type TODO */ +// case 0x0f: /* BIST TODO */ + + case 0x10: /* Base Address TODO */ + return 0x01 | (dev->base_addr & 0xc0); /* memBaseAddr */ + case 0x11: + return dev->base_addr >> 8; + case 0x12: + return dev->base_addr >> 16; + case 0x13: + return dev->base_addr >> 24; + + case 0x2c: + return 0x42; /* Subsystem vendor ID */ + case 0x2d: + return 0x49; + case 0x2e: + return 0x4c; /* Subsystem product ID */ + case 0x2f: + return 0x4c; + +#if 0 + case 0x34: // TODO + return 0xdc; /* Capabilites pointer */ +#endif + + case 0x3c: + return dev->int_line; + case 0x3d: + return 0x01; /* INTA */ + + case 0x3e: + return 0xc; /* Minimum grant */ + case 0x3f: + return 0x80; /* Maximum latency */ + +#if 0 + case 0xdc: + return 0x01; /* Capabilities identifier */ + case 0xdd: + return 0x00; /* Next item pointer */ + case 0xde: + return 0x31; /* Power management capabilities */ + case 0xdf: + return 0x6c; + + case 0xe0: + return dev->pmcsr & 0xff; + case 0xe1: + return dev->pmcsr >> 8; +#endif + + default: + break; + } + + return 0x00; +} + static uint8_t es1371_pci_read(int func, int addr, void *priv) { - const es1371_t *dev = (es1371_t *) priv; + const es137x_t *dev = (es137x_t *) priv; if (func > 0) return 0xff; @@ -1780,7 +2033,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x80; /* Maximum latency */ case 0x40: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) return dev->subsys_lock; break; @@ -1806,42 +2059,93 @@ es1371_pci_read(int func, int addr, void *priv) } static void -es1371_io_set(es1371_t *dev, int set) +es137x_io_set(es137x_t *dev, int set) { if (dev->pci_command & PCI_COMMAND_IO) { io_handler(set, dev->base_addr, 0x0040, - es1371_inb, es1371_inw, es1371_inl, - es1371_outb, es1371_outw, es1371_outl, dev); + es137x_inb, es137x_inw, es137x_inl, + es137x_outb, es137x_outw, es137x_outl, dev); } } static void -es1371_pci_write(int func, int addr, uint8_t val, void *priv) +es1370_pci_write(int func, int addr, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; if (func) return; switch (addr) { case 0x04: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->pci_command = val & 0x05; - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); break; case 0x05: dev->pci_serr = val & 1; break; case 0x10: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); break; case 0x11: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); + break; + case 0x12: + dev->base_addr = (dev->base_addr & 0xff00ffc0) | (val << 16); + break; + case 0x13: + dev->base_addr = (dev->base_addr & 0x00ffffc0) | (val << 24); + break; + + case 0x3c: + dev->int_line = val; + break; + + case 0xe0: + dev->pmcsr = (dev->pmcsr & 0xff00) | (val & 0x03); + break; + case 0xe1: + dev->pmcsr = (dev->pmcsr & 0x00ff) | ((val & 0x01) << 8); + break; + + default: + break; + } +} + +static void +es1371_pci_write(int func, int addr, uint8_t val, void *priv) +{ + es137x_t *dev = (es137x_t *) priv; + + if (func) + return; + + switch (addr) { + case 0x04: + es137x_io_set(dev, 0); + dev->pci_command = val & 0x05; + es137x_io_set(dev, 1); + break; + case 0x05: + dev->pci_serr = val & 1; + break; + + case 0x10: + es137x_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); + es137x_io_set(dev, 1); + break; + case 0x11: + es137x_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); + es137x_io_set(dev, 1); break; case 0x12: dev->base_addr = (dev->base_addr & 0xff00ffc0) | (val << 16); @@ -1860,7 +2164,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if (dev->type >= AUDIOPCI_ES1373) + if (dev->type >= AUDIOPCI_ES1373 && dev->type < AUDIOPCI_ES1370) dev->subsys_lock = val; break; @@ -1877,7 +2181,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) } static void -es1371_fetch(es1371_t *dev, int dac_nr) +es137x_fetch(es137x_t *dev, int dac_nr) { if (dev->si_cr & (dac_nr ? SI_P2_PAUSE : SI_P1_PAUSE)) return; @@ -1981,8 +2285,8 @@ low_fir_es1371(int dac_nr, int i, float NewSample) read_pos = (pos + 15) & (127 & ~15); n_coef = (16 - pos) & 15; - while (n_coef < ES1371_NCoef) { - out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; + while (n_coef < ES137x_NCoef) { + out += low_fir_es137x_coef[n_coef] * x[dac_nr][i][read_pos]; read_pos = (read_pos + 16) & (127 & ~15); n_coef += 16; } @@ -1997,13 +2301,13 @@ low_fir_es1371(int dac_nr, int i, float NewSample) } static void -es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) +es137x_next_sample_filtered(es137x_t *dev, int dac_nr, int out_idx) { int out_l; int out_r; if ((dev->dac[dac_nr].buffer_pos - dev->dac[dac_nr].buffer_pos_end) >= 0) - es1371_fetch(dev, dac_nr); + es137x_fetch(dev, dac_nr); out_l = dev->dac[dac_nr].buffer_l[dev->dac[dac_nr].buffer_pos & 63]; out_r = dev->dac[dac_nr].buffer_r[dev->dac[dac_nr].buffer_pos & 63]; @@ -2020,21 +2324,35 @@ es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) } static void -es1371_update(es1371_t *dev) +es137x_update(es137x_t *dev) { int32_t l; int32_t r; - l = (dev->dac[0].out_l * dev->dac[0].vol_l) >> 12; - l += ((dev->dac[1].out_l * dev->dac[1].vol_l) >> 12); - r = (dev->dac[0].out_r * dev->dac[0].vol_r) >> 12; - r += ((dev->dac[1].out_r * dev->dac[1].vol_r) >> 12); + if (dev->type == AUDIOPCI_ES1370) { + l = dev->dac[0].out_l * (((dev->akm_codec.registers[0x4] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x4] & 0x1f)]) / 32767.0); + r = dev->dac[0].out_r * (((dev->akm_codec.registers[0x5] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x5] & 0x1f)]) / 32767.0); - l >>= 1; - r >>= 1; + l += dev->dac[1].out_l * (((dev->akm_codec.registers[0x2] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x2] & 0x1f)]) / 32767.0); + r += dev->dac[1].out_r * (((dev->akm_codec.registers[0x3] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x3] & 0x1f)]) / 32767.0); - l = (((l * dev->pcm_vol_l) >> 15) * dev->master_vol_l) >> 15; - r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; + l >>= 1; + r >>= 1; + + l *= (((dev->akm_codec.registers[0x0] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[0x0] & 0x1f) ^ 0x1f]) / 32767.0); + r *= (((dev->akm_codec.registers[0x1] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[0x1] & 0x1f) ^ 0x1f]) / 32767.0); + } else { + l = (dev->dac[0].out_l * dev->dac[0].vol_l) >> 12; + l += ((dev->dac[1].out_l * dev->dac[1].vol_l) >> 12); + r = (dev->dac[0].out_r * dev->dac[0].vol_r) >> 12; + r += ((dev->dac[1].out_r * dev->dac[1].vol_r) >> 12); + + l >>= 1; + r >>= 1; + + l = (((l * dev->pcm_vol_l) >> 15) * dev->master_vol_l) >> 15; + r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; + } if (l < -32768) l = -32768; @@ -2045,16 +2363,16 @@ es1371_update(es1371_t *dev) else if (r > 32767) r = 32767; - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < ((dev->type == AUDIOPCI_ES1370) ? wavetable_pos_global : sound_pos_global); dev->pos++) { dev->buffer[dev->pos * 2] = l; dev->buffer[dev->pos * 2 + 1] = r; } } static void -es1371_poll(void *priv) +es137x_poll(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; int frac; int idx; int samp1_l; @@ -2064,21 +2382,42 @@ es1371_poll(void *priv) timer_advance_u64(&dev->dac[1].timer, dev->dac[1].latch); - es1371_scan_fifo(dev); + es137x_scan_fifo(dev); - es1371_update(dev); + es137x_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) { - /* SRC bypass. */ - if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) - es1371_fetch(dev, 0); + if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) || dev->type == AUDIOPCI_ES1370) { + if (dev->calc_sample_rate_synth != 44100 && dev->type == AUDIOPCI_ES1370) + { + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0 && dev->step_synth >= dev->interp_step_synth) + es137x_fetch(dev, 0); - dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; - dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; - dev->dac[0].buffer_pos++; + if (dev->step_synth >= dev->interp_step_synth) { + dev->step_synth = 0; + } - goto dac0_count; + dev->dac[0].out_l = lerp(dev->dac[0].prev_out_l, dev->dac[0].buffer_l[(dev->dac[0].buffer_pos) & 63], (dev->step_synth + 1) * dev->interp_factor_synth); + dev->dac[0].out_r = lerp(dev->dac[0].prev_out_r, dev->dac[0].buffer_r[(dev->dac[0].buffer_pos) & 63], (dev->step_synth + 1) * dev->interp_factor_synth); + + dev->step_synth++; + if (dev->step_synth >= dev->interp_step_synth) { + dev->dac[0].prev_out_l = dev->dac[0].out_l; + dev->dac[0].prev_out_r = dev->dac[0].out_r; + dev->dac[0].buffer_pos++; + goto dac0_count; + } + } else { + /* SRC bypass. */ + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) + es137x_fetch(dev, 0); + + dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; + dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; + dev->dac[0].buffer_pos++; + + goto dac0_count; + } } else { frac = dev->dac[0].ac & 0x7fff; idx = dev->dac[0].ac >> 15; @@ -2092,14 +2431,14 @@ es1371_poll(void *priv) dev->dac[0].ac += dev->dac[0].vf; dev->dac[0].ac &= ((32 << 15) - 1); if ((dev->dac[0].ac >> (15 + 4)) != dev->dac[0].f_pos) { - es1371_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); + es137x_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; dac0_count: dev->dac[0].curr_samp_ct--; if (dev->dac[0].curr_samp_ct < 0) { dev->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(dev); + es137x_update_irqs(dev); dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; } } @@ -2107,16 +2446,37 @@ dac0_count: } if (dev->int_ctrl & INT_DAC2_EN) { - if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) { - /* SRC bypass. */ - if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) - es1371_fetch(dev, 1); + if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) || dev->type == AUDIOPCI_ES1370) { + if (dev->calc_sample_rate != 44100 && dev->type == AUDIOPCI_ES1370) + { + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0 && dev->step_pcm >= dev->interp_step) + es137x_fetch(dev, 1); - dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; - dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; - dev->dac[1].buffer_pos++; + if (dev->step_pcm >= dev->interp_step) { + dev->step_pcm = 0; + } - goto dac1_count; + dev->dac[1].out_l = lerp(dev->dac[1].prev_out_l, dev->dac[1].buffer_l[(dev->dac[1].buffer_pos) & 63], (dev->step_pcm + 1) * dev->interp_factor); + dev->dac[1].out_r = lerp(dev->dac[1].prev_out_r, dev->dac[1].buffer_r[(dev->dac[1].buffer_pos) & 63], (dev->step_pcm + 1) * dev->interp_factor); + + dev->step_pcm++; + if (dev->step_pcm >= dev->interp_step) { + dev->dac[1].prev_out_l = dev->dac[1].out_l; + dev->dac[1].prev_out_r = dev->dac[1].out_r; + dev->dac[1].buffer_pos++; + goto dac1_count; + } + } else { + /* SRC bypass. */ + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) + es137x_fetch(dev, 1); + + dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; + dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; + dev->dac[1].buffer_pos++; + + goto dac1_count; + } } else { frac = dev->dac[1].ac & 0x7fff; idx = dev->dac[1].ac >> 15; @@ -2130,14 +2490,14 @@ dac0_count: dev->dac[1].ac += dev->dac[1].vf; dev->dac[1].ac &= ((32 << 15) - 1); if ((dev->dac[1].ac >> (15 + 4)) != dev->dac[1].f_pos) { - es1371_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); + es137x_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; dac1_count: dev->dac[1].curr_samp_ct--; if (dev->dac[1].curr_samp_ct < 0) { dev->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; } } @@ -2146,11 +2506,11 @@ dac1_count: } static void -es1371_get_buffer(int32_t *buffer, int len, void *priv) +es137x_get_buffer(int32_t *buffer, int len, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; - es1371_update(dev); + es137x_update(dev); for (int c = 0; c < len * 2; c++) buffer[c] += (dev->buffer[c] / 2); @@ -2158,10 +2518,22 @@ es1371_get_buffer(int32_t *buffer, int len, void *priv) dev->pos = 0; } +static void +es1370_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const es137x_t *dev = (es137x_t *) priv; + double c = 0.0; + double mastervol = ((dev->akm_codec.registers[channel] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[channel] & 0x1f) ^ 0x1f]) / 32767.0; + double cdvol = ((dev->akm_codec.registers[channel + 0x6] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[channel + 0x6] & 0x1f)]) / 32767.0; + + c = *buffer * mastervol * cdvol; + *buffer = c; +} + static void es1371_filter_cd_audio(int channel, double *buffer, void *priv) { - const es1371_t *dev = (es1371_t *) priv; + const es137x_t *dev = (es137x_t *) priv; double c; int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; int master = channel ? dev->master_vol_r : dev->master_vol_l; @@ -2177,49 +2549,49 @@ sinc(double x) } static void -generate_es1371_filter(void) +generate_es137x_filter(void) { /* Cutoff frequency = 1 / 32 */ float fC = 1.0 / 32.0; float gain; int n; - for (n = 0; n < ES1371_NCoef; n++) { + for (n = 0; n < ES137x_NCoef; n++) { /* Blackman window */ - double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (ES1371_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (ES1371_NCoef - 1))); + double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (ES137x_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (ES137x_NCoef - 1))); /* Sinc filter */ - double h = sinc(2.0 * fC * ((double) n - ((double) (ES1371_NCoef - 1) / 2.0))); + double h = sinc(2.0 * fC * ((double) n - ((double) (ES137x_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_es1371_coef[n] = w * h; + low_fir_es137x_coef[n] = w * h; } - low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; + low_fir_es137x_coef[(ES137x_NCoef - 1) / 2] = 1.0; gain = 0.0; - for (n = 0; n < ES1371_NCoef; n++) - gain += low_fir_es1371_coef[n] / (float) N; + for (n = 0; n < ES137x_NCoef; n++) + gain += low_fir_es137x_coef[n] / (float) N; gain /= 0.65; /* Normalise filter, to produce unity gain */ - for (n = 0; n < ES1371_NCoef; n++) - low_fir_es1371_coef[n] /= gain; + for (n = 0; n < ES137x_NCoef; n++) + low_fir_es137x_coef[n] /= gain; } static void -es1371_input_msg(void *priv, uint8_t *msg, uint32_t len) +es137x_input_msg(void *priv, uint8_t *msg, uint32_t len) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; for (uint32_t i = 0; i < len; i++) - es1371_write_fifo(dev, msg[i]); + es137x_write_fifo(dev, msg[i]); } static int -es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) +es137x_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t i = -1; audiopci_log("Abort = %i\n", abort); @@ -2229,7 +2601,7 @@ es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) if (!abort) { for (i = 0; i < len; i++) { - es1371_write_fifo(dev, buffer[i]); + es137x_write_fifo(dev, buffer[i]); if (dev->uart_status & UART_STATUS_RXRDY) break; } @@ -2240,17 +2612,64 @@ es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) return 7 - i; } +static void es137x_speed_changed(void *priv); + +static void * +es1370_init(const device_t *info) +{ + es137x_t *dev = malloc(sizeof(es137x_t)); + memset(dev, 0x00, sizeof(es137x_t)); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); + + wavetable_add_handler(es137x_get_buffer, dev); + sound_set_cd_audio_filter(es1370_filter_cd_audio, dev); + + dev->gameport = gameport_add(&gameport_pnp_device); + gameport_remap(dev->gameport, 0x200); + + pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1370_pci_read, es1370_pci_write, dev, &dev->pci_slot); + + timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); + + generate_es137x_filter(); + + dev->dac[0].vol_l = 1 << 12; + dev->dac[0].vol_r = 1 << 12; + dev->dac[1].vol_l = 1 << 12; + dev->dac[1].vol_r = 1 << 12; + + dev->pcm_vol_l = 1 << 15; + dev->pcm_vol_r = 1 << 15; + dev->master_vol_l = 1 << 15; + dev->master_vol_r = 1 << 15; + + dev->type = AUDIOPCI_ES1370; + + es137x_reset(dev); + + es137x_speed_changed(dev); + + for (int i = 0; i < 0x20; i++) { + double attn = (12.0 - (i * 2.0)); + akm4531_gain_2dbstep_5bits[i] = pow(10, attn / 10.) * 32767.0; + } + + return dev; +} + static void * es1371_init(const device_t *info) { - es1371_t *dev = malloc(sizeof(es1371_t)); - memset(dev, 0x00, sizeof(es1371_t)); + es137x_t *dev = malloc(sizeof(es137x_t)); + memset(dev, 0x00, sizeof(es137x_t)); dev->type = info->local & 0xffffff00; if (device_get_config_int("receive_input")) - midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev); + midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); - sound_add_handler(es1371_get_buffer, dev); + sound_add_handler(es137x_get_buffer, dev); sound_set_cd_audio_filter(es1371_filter_cd_audio, dev); dev->gameport = gameport_add(&gameport_pnp_device); @@ -2258,9 +2677,9 @@ es1371_init(const device_t *info) pci_add_card((info->local & 1) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); - timer_add(&dev->dac[1].timer, es1371_poll, dev, 1); + timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); - generate_es1371_filter(); + generate_es137x_filter(); ac97_codec = &dev->codec; ac97_codec_count = 1; @@ -2269,27 +2688,40 @@ es1371_init(const device_t *info) if (!(info->local & 1)) device_add(ac97_codec_get(device_get_config_int("codec"))); - es1371_reset(dev); + es137x_reset(dev); return dev; } static void -es1371_close(void *priv) +es137x_close(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; free(dev); } static void -es1371_speed_changed(void *priv) +es137x_speed_changed(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; - dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); + dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) (dev->type == AUDIOPCI_ES1370 ? WT_FREQ : SOUND_FREQ))); } +static const device_config_t es1370_config[] = { + // clang-format off + { + .name = "receive_input", + .description = "Receive input (MIDI)", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + static const device_config_t es1371_config[] = { // clang-format off { @@ -2397,16 +2829,30 @@ static const device_config_t es1371_onboard_config[] = { // clang-format on }; +const device_t es1370_device = { + .name = "Ensoniq AudioPCI (ES1370)", + .internal_name = "es1370", + .flags = DEVICE_PCI, + .local = 0, + .init = es1370_init, + .close = es137x_close, + .reset = es137x_reset, + { .available = NULL }, + .speed_changed = es137x_speed_changed, + .force_redraw = NULL, + .config = es1370_config +}; + const device_t es1371_device = { .name = "Ensoniq AudioPCI (ES1371)", .internal_name = "es1371", .flags = DEVICE_PCI, .local = AUDIOPCI_ES1371, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_config }; @@ -2417,10 +2863,10 @@ const device_t es1371_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1371 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; @@ -2431,10 +2877,10 @@ const device_t es1373_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1373, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1373_config }; @@ -2445,10 +2891,10 @@ const device_t es1373_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1373 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; @@ -2459,10 +2905,10 @@ const device_t ct5880_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_CT5880, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = ct5880_config }; @@ -2473,10 +2919,10 @@ const device_t ct5880_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_CT5880 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, + .close = es137x_close, + .reset = es137x_reset, .available = NULL, - .speed_changed = es1371_speed_changed, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; diff --git a/src/sound/sound.c b/src/sound/sound.c index b1762eaff..28cb96629 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -153,6 +153,7 @@ static const SOUND_CARD sound_cards[] = { { &ess_soundpiper_32_mca_device }, { &cmi8338_device }, { &cmi8738_device }, + { &es1370_device }, { &es1371_device }, { &es1373_device }, { &ct5880_device },