From f98dc1f79469dca98c6ff666ce6a5ba0fe280ad7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 18 Apr 2020 14:43:46 -0300 Subject: [PATCH] Sync floppy drive types to CMOS on coreboot machines --- src/floppy/fdd.c | 7 ++++++ src/include/86box/fdd.h | 1 + src/nvr_at.c | 49 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 791c82abd..a2a5342af 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -407,6 +407,13 @@ fdd_is_dd(int drive) } +int +fdd_is_hd(int drive) +{ + return drive_types[fdd[drive].type].flags & FLAG_HOLE1; +} + + int fdd_is_ed(int drive) { diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index b486b617d..ccd420924 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -43,6 +43,7 @@ extern int fdd_can_read_medium(int drive); extern int fdd_doublestep_40(int drive); extern int fdd_is_525(int drive); extern int fdd_is_dd(int drive); +extern int fdd_is_hd(int drive); extern int fdd_is_ed(int drive); extern int fdd_is_double_sided(int drive); extern void fdd_set_head(int drive, int head); diff --git a/src/nvr_at.c b/src/nvr_at.c index d95a6d7c0..403fc62f7 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -237,6 +237,7 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/nvr.h> +#include <86box/fdd.h> /* RTC registers and bit definitions. */ @@ -279,6 +280,8 @@ # define REGC_UF 0x10 #define RTC_REGD 13 # define REGD_VRT 0x80 +#define RTC_FDD_TYPES 0x10 +#define RTC_INST_EQUIP 0x14 #define RTC_CENTURY_AT 0x32 /* century register for AT etc */ #define RTC_CENTURY_PS 0x37 /* century register for PS/1 PS/2 */ #define RTC_ALDAY 0x7D /* VIA VT82C586B - alarm day */ @@ -753,7 +756,7 @@ nvr_reset(nvr_t *nvr) static void nvr_start(nvr_t *nvr) { - int i; + int i, fdd; local_t *local = (local_t *) nvr->data; struct tm tm; @@ -768,6 +771,50 @@ nvr_start(nvr_t *nvr) nvr->regs[0x0e] = 0xff; /* If load failed or it loaded an uninitialized NVR, mark everything as bad. */ + if (machines[machine].flags & MACHINE_COREBOOT) { + /* Sync floppy drive types on coreboot machines, as SeaBIOS lacks a setup + utility and just leaves these untouched. */ + + nvr->regs[RTC_FDD_TYPES] = 0x00; + nvr->regs[RTC_INST_EQUIP] |= 0xc0; + + for (i = 0; i <= 1; i++) { + fdd = fdd_get_type(i); + if (fdd) { + if (fdd_is_525(i)) { + if (fdd_is_hd(i)) + fdd = 2; + else if (fdd_doublestep_40(i)) + fdd = 3; + else + fdd = 1; + } else { + if (fdd_is_hd(i)) + fdd = 4; + else if (fdd_is_double_sided(i)) + fdd = 3; + else + fdd = 1; + } + + nvr->regs[RTC_FDD_TYPES] |= (fdd << ((1 - i) * 4)); + nvr->regs[RTC_INST_EQUIP] &= 0x3f; /* At least one drive installed. */ + } + } + + if ((nvr->regs[RTC_FDD_TYPES] >> 4) && (nvr->regs[RTC_FDD_TYPES] & 0xf)) + nvr->regs[RTC_INST_EQUIP] |= 0x40; /* Two drives installed. */ + + /* Re-compute CMOS checksum. SeaBIOS also doesn't care about the checksum, + but Windows does. */ + uint16_t checksum = 0; + for (i = 0x10; i <= 0x2d; i++) { + checksum += nvr->regs[i]; + } + nvr->regs[0x2e] = checksum >> 8; + nvr->regs[0x2f] = checksum; + } + /* Initialize the internal and chip times. */ if (time_sync & TIME_SYNC_ENABLED) { /* Use the internal clock's time. */