mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-16 05:27:22 +08:00
bugfix: keyboard led synchronization now compares against LEDs bitmask,
and only updates then, just like a real BIOS. this fixes LED flickering when running code that directly communicates with the controller.
This commit is contained in:
@@ -302,18 +302,6 @@ void KEYBOARD_SetLEDs(Bit8u bits) {
|
|||||||
LOG(LOG_KEYBOARD,LOG_DEBUG)("Keyboard LEDs: SCR=%u NUM=%u CAPS=%u",bits&1,(bits>>1)&1,(bits>>2)&1);
|
LOG(LOG_KEYBOARD,LOG_DEBUG)("Keyboard LEDs: SCR=%u NUM=%u CAPS=%u",bits&1,(bits>>1)&1,(bits>>2)&1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// believe it or not most BIOSes will also periodically check the BIOS data area
|
|
||||||
// and send updated keyboard LED state from it if it changes, from within IRQ 0 (INT 8h).
|
|
||||||
// This is not documented anywhere I know, but it's been my experience with DOS
|
|
||||||
// programming and Windows 3.1/9x keyboard handling seems to rely on it.
|
|
||||||
void KEYBOARD_BIOS_CheckLEDs_From_DataArea(Bitu bits) {
|
|
||||||
if ((bits & 7) != (keyb.led_state & 7)) {
|
|
||||||
keyb.led_state = bits;
|
|
||||||
UpdateKeyboardLEDState(bits);
|
|
||||||
LOG(LOG_KEYBOARD, LOG_DEBUG)("Keyboard LEDs (from BIOS data area update): SCR=%u NUM=%u CAPS=%u", bits & 1, (bits >> 1) & 1, (bits >> 2) & 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bitu read_p60(Bitu port,Bitu iolen) {
|
static Bitu read_p60(Bitu port,Bitu iolen) {
|
||||||
keyb.p60changed=false;
|
keyb.p60changed=false;
|
||||||
keyb.auxchanged=false;
|
keyb.auxchanged=false;
|
||||||
|
@@ -1894,7 +1894,16 @@ static void BIOS_HostTimeSync() {
|
|||||||
// TODO: make option
|
// TODO: make option
|
||||||
bool enable_bios_timer_synchronize_keyboard_leds = true;
|
bool enable_bios_timer_synchronize_keyboard_leds = true;
|
||||||
|
|
||||||
void KEYBOARD_BIOS_CheckLEDs_From_DataArea(Bitu x);
|
void KEYBOARD_SetLEDs(Bit8u bits);
|
||||||
|
|
||||||
|
void BIOS_KEYBOARD_SetLEDs(Bitu state) {
|
||||||
|
Bitu x = mem_readb(BIOS_KEYBOARD_LEDS);
|
||||||
|
|
||||||
|
x &= ~7;
|
||||||
|
x |= (state & 7);
|
||||||
|
mem_writeb(BIOS_KEYBOARD_LEDS,x);
|
||||||
|
KEYBOARD_SetLEDs(state);
|
||||||
|
}
|
||||||
|
|
||||||
static Bitu INT8_Handler(void) {
|
static Bitu INT8_Handler(void) {
|
||||||
/* Increase the bios tick counter */
|
/* Increase the bios tick counter */
|
||||||
@@ -1913,8 +1922,13 @@ static Bitu INT8_Handler(void) {
|
|||||||
it when handling the keyboard from it's own driver. Their driver does
|
it when handling the keyboard from it's own driver. Their driver does
|
||||||
hook the keyboard and handles keyboard I/O by itself, but it still
|
hook the keyboard and handles keyboard I/O by itself, but it still
|
||||||
allows the BIOS to do the keyboard magic from IRQ 0 (INT 8h). Yech. */
|
allows the BIOS to do the keyboard magic from IRQ 0 (INT 8h). Yech. */
|
||||||
if (enable_bios_timer_synchronize_keyboard_leds)
|
if (enable_bios_timer_synchronize_keyboard_leds) {
|
||||||
KEYBOARD_BIOS_CheckLEDs_From_DataArea((mem_readb(BIOS_KEYBOARD_STATE) >> 4) & 7);
|
Bitu should_be = (mem_readb(BIOS_KEYBOARD_STATE) >> 4) & 7;
|
||||||
|
Bitu led_state = (mem_readb(BIOS_KEYBOARD_LEDS) & 7);
|
||||||
|
|
||||||
|
if (should_be != led_state)
|
||||||
|
BIOS_KEYBOARD_SetLEDs(should_be);
|
||||||
|
}
|
||||||
|
|
||||||
#if DOSBOX_CLOCKSYNC
|
#if DOSBOX_CLOCKSYNC
|
||||||
static bool check = false;
|
static bool check = false;
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user