Sitelet https://github.com/86Box/86Box/pull/7888
Skip to content

softpower: Fix the power-off delay spinner range overflowing int16_t - #7888

Merged
OBattler merged 1 commit into
86Box:masterfrom
MaxFreedomPollard:softpower-delay-spinner-range
Sep 7, 2026
Merged

OBattler merged 1 commit into
86Box:masterfrom
MaxFreedomPollard:softpower-delay-spinner-range

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Contributor

Summary

Opening the configuration dialog for the PC Convertible Soft Power Card silently resets its power-off delay to 0 ms.

device_config_spinner_t holds min, max and step as int16_t (src/include/86box/device.h:140-144). The "delay" spinner in src/device/softpower.c:169 sets .max = 60000, which does not fit and truncates to -5536, below its .min of 0. src/qt/qt_deviceconfig.cpp:327-328 calls setMaximum() and then setMinimum() with those values, and Qt pulls the other end of the range along on each call, so the QSpinBox ends up ranged [0, 0]. The dialog therefore displays 0, sees that it differs from the stored 2000, and writes delay = 0 back to the config. softpower_write() then arms power_off_timer with a zero delay and the machine loses power before the suspend NMI handler runs, which is the window the card exists to provide.

This caps the maximum at 30000 ms. It fits int16_t, it is a multiple of the 100 ms step so the spinner arrows land on it, and it is fifteen times the delay of the real power supply.

clang warns about the truncation by default today:

src/device/softpower.c:169:21: warning: implicit conversion from 'int' to 'int16_t' (aka 'short') changes value from 60000 to -5536 [-Wconstant-conversion]
  169 |             .max  = 60000,
      |                     ^~~~~

I checked the change two ways. cc -fsyntax-only -Wall -Wextra on src/device/softpower.c emits the warning above before the change and is clean after it. And a standalone program that reuses the device_config_spinner_t definition and the range adjustment Qt applies prints:

before: min=0 max=-5536 step=100 -> spin box range [0,0], delay 2000 ms becomes 0 ms
after : min=0 max=30000 step=100 -> spin box range [0,30000], delay 2000 ms becomes 2000 ms

It is the only spinner in the tree that does not fit the field; the next largest is 15872 in src/device/isamem.c.

Checklist

  • I have tested my changes locally and validated that the functionality works as intended

References

IBM PC Convertible Technical Reference Volume 1 (6280655), cited by the card's own header comment for the Power System Control register at hex 07F and the roughly two second delay before power is removed: http://bitsavers.org/pdf/ibm/pc/convertable/6280655_PC_Convertable_Technical_Reference_Volume_1_Feb86.pdf

IBM PC Convertible Technical Reference Volume 2 (55X8817), the BIOS listing containing the SYS_POWER_OFF and SUSPEND handlers that run in that window: http://bitsavers.org/pdf/ibm/pc/convertable/55X8817_PC_Convertable_Technical_Reference_Volume_2_Feb86.pdf

device_config_spinner_t stores min, max and step as int16_t
(src/include/86box/device.h:140-144), so the "delay" spinner's
.max = 60000 in src/device/softpower.c:169 truncates to -5536, below
the .min of 0. qt_deviceconfig.cpp:327-331 calls setMaximum() and then
setMinimum() with those values, which collapses the QSpinBox range to
[0, 0], so opening the card's configuration dialog clamps the delay to
0 and writes it back to the config.

With the delay at 0, softpower_write() arms power_off_timer with a zero
delay, and the system powers off before the suspend NMI handler runs.
That defeats the point of the card: the IBM PC Convertible Technical
Reference Vol. 1 (6280655), "Power System Control (Hex 07F)", describes
the power supply removing power roughly two seconds after REQ_POFF so
the SUSPEND handler can save system state.

Cap the maximum at 30000 ms, which fits int16_t, is a multiple of the
100 ms step, and is fifteen times the delay of the reference hardware.
This also clears the -Wconstant-conversion warning clang emits for the
file by default.
@OBattler
OBattler merged commit bcc792e into 86Box:master Sep 7, 2026
44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants