From 2afa0e7503f8e551c115c34dab7f9c93893499df Mon Sep 17 00:00:00 2001 From: Domppari Date: Fri, 19 Dec 2025 21:56:23 +0200 Subject: [PATCH] FDD Support for detecting if in BIOS POST test mode or normal operations mode. Used to change FDD audio samples for the drive to match real HW BIOS FDD POST test sounds. --- src/floppy/fdc.c | 6 ++++ src/floppy/fdd.c | 70 ++++++++++++++++++++++++++++++++--------- src/floppy/fdd_audio.c | 4 +-- src/include/86box/fdd.h | 12 +++++++ 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index c1bf04618..de0549ca4 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -784,6 +784,9 @@ fdc_sis(fdc_t *fdc) static void fdc_soft_reset(fdc_t *fdc) { + /* Reset boot status to POST on controller soft reset */ + fdd_boot_status_reset(); + if (fdc->power_down) { timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); fdc->interrupt = -5; @@ -2403,6 +2406,9 @@ fdc_reset(void *priv) fdc_t *fdc = (fdc_t *) priv; + /* Reset boot status to POST on controller reset */ + fdd_boot_status_reset(); + default_rwc = (fdc->flags & FDC_FLAG_START_RWC_1) ? 1 : 0; fdc->enable_3f1 = 1; diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 30be0979a..fbf5c1cd1 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -101,6 +101,9 @@ typedef struct fdd_pending_op_t { static fdd_pending_op_t fdd_pending[FDD_NUM]; +/* BIOS boot status tracking */ +static bios_boot_status_t bios_boot_status = BIOS_BOOT_POST; + char floppyfns[FDD_NUM][512]; char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; @@ -212,9 +215,9 @@ int fdd_do_log = ENABLE_FDD_LOG; static void fdd_log(const char *fmt, ...) { - va_list ap, ap_copy; + va_list ap; char timebuf[32]; - char fullbuf[1056]; // 32 + 1024 bytes for timestamp + message + char fullbuf[1056]; /* 32 + 1024 bytes for timestamp + message */ if (fdd_do_log) { uint32_t ticks = plat_get_ticks(); @@ -224,27 +227,58 @@ fdd_log(const char *fmt, ...) snprintf(timebuf, sizeof(timebuf), "[%07u.%03u] ", seconds, milliseconds); va_start(ap, fmt); - va_copy(ap_copy, ap); - strcpy(fullbuf, timebuf); - vsnprintf(fullbuf + strlen(timebuf), sizeof(fullbuf) - strlen(timebuf), fmt, ap_copy); - - va_end(ap_copy); + vsnprintf(fullbuf + strlen(timebuf), sizeof(fullbuf) - strlen(timebuf), fmt, ap); va_end(ap); - va_start(ap, fmt); - va_end(ap); - - char *msg = fullbuf; - va_start(ap, fmt); - pclog_ex("%s", (va_list) &msg); - va_end(ap); + pclog("%s", fullbuf); } } #else # define fdd_log(fmt, ...) #endif +/* + * BIOS boot status functions + * + * These functions track whether the system is in BIOS POST (Power-On Self Test) + * or has transitioned to normal operation. The POST state is set on: + * - System hard reset (fdd_reset) + * - FDC soft reset (fdd_boot_status_reset) + * + * POST is considered complete when the first floppy read operation occurs, + * indicating that BIOS has finished POST and is attempting to boot. + */ +bios_boot_status_t +fdd_get_boot_status(void) +{ + return bios_boot_status; +} + +void +fdd_set_boot_status(bios_boot_status_t status) +{ + if (bios_boot_status != status) { + fdd_log("BIOS boot status changed: %s -> %s\n", + bios_boot_status == BIOS_BOOT_POST ? "POST" : "NORMAL", + status == BIOS_BOOT_POST ? "POST" : "NORMAL"); + bios_boot_status = status; + } +} + +void +fdd_boot_status_reset(void) +{ + fdd_log("BIOS boot status reset to POST\n"); + bios_boot_status = BIOS_BOOT_POST; +} + +int +fdd_is_post_complete(void) +{ + return (bios_boot_status == BIOS_BOOT_NORMAL); +} + void fdd_set_audio_profile(int drive, int profile) { @@ -778,6 +812,9 @@ fdd_get_bitcell_period(int rate) void fdd_reset(void) { + /* Reset boot status to POST on system reset */ + fdd_boot_status_reset(); + for (uint8_t i = 0; i < FDD_NUM; i++) { drives[i].id = i; timer_add(&(fdd_poll_time[i]), fdd_poll, &drives[i], 0); @@ -789,6 +826,11 @@ fdd_readsector(int drive, int sector, int track, int side, int density, int sect { fdd_log("fdd_readsector(%d, %d, %d, %d, %d, %d)\n", drive, sector, track, side, density, sector_size); + /* First floppy read operation marks POST as complete */ + if (bios_boot_status == BIOS_BOOT_POST) { + fdd_set_boot_status(BIOS_BOOT_NORMAL); + } + if (fdd_seek_in_progress[drive]) { fdd_log("Seek in progress on drive %d, deferring READ (trk=%d->%d, side=%d, sec=%d)\n", drive, fdd[drive].track, track, side, sector); diff --git a/src/floppy/fdd_audio.c b/src/floppy/fdd_audio.c index 9bd9aeea6..1657db924 100644 --- a/src/floppy/fdd_audio.c +++ b/src/floppy/fdd_audio.c @@ -92,14 +92,14 @@ extern int fdd_get_audio_profile(int drive); static int16_t *load_wav(const char *filename, int *sample_count); # ifdef ENABLE_FDD_LOG -int fdc_do_log = ENABLE_FDD_LOG; +static int fdd_audio_do_log = ENABLE_FDD_LOG; static void fdd_log(const char *fmt, ...) { va_list ap; - if (fdc_do_log) { + if (fdd_audio_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index a173279a4..2ac46d651 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -26,6 +26,12 @@ #define SEEK_RECALIBRATE -999 #define DEFAULT_SEEK_TIME_MS 10.0 +/* BIOS boot status - used to detect POST vs normal operation */ +typedef enum bios_boot_status_t { + BIOS_BOOT_POST = 0, /* System is in POST (Power-On Self Test) */ + BIOS_BOOT_NORMAL /* POST complete, normal operation */ +} bios_boot_status_t; + #ifdef __cplusplus extern "C" { #endif @@ -118,6 +124,12 @@ extern int fdd_hole(int drive); extern void fdd_stop(int drive); extern void fdd_do_writeback(int drive); +/* BIOS boot status functions */ +extern bios_boot_status_t fdd_get_boot_status(void); +extern void fdd_set_boot_status(bios_boot_status_t status); +extern void fdd_boot_status_reset(void); +extern int fdd_is_post_complete(void); + extern int motorspin; extern uint64_t motoron[FDD_NUM];