From 6ad7dd1797d06efe23bff975dba4819f09fd94e9 Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Thu, 27 Aug 2015 13:09:09 -0700 Subject: [PATCH] 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. --- src/hardware/keyboard.cpp | 12 ------------ src/ints/bios.cpp | 20 +++++++++++++++++--- vs2015/.vs/dosbox-x/v14/.suo | Bin 178176 -> 178176 bytes 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/hardware/keyboard.cpp b/src/hardware/keyboard.cpp index 7ec8cf29b..a05f0cb3a 100644 --- a/src/hardware/keyboard.cpp +++ b/src/hardware/keyboard.cpp @@ -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); } -// 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) { keyb.p60changed=false; keyb.auxchanged=false; diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index a7a9a1510..95c88373e 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -1894,7 +1894,16 @@ static void BIOS_HostTimeSync() { // TODO: make option 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) { /* 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 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. */ - if (enable_bios_timer_synchronize_keyboard_leds) - KEYBOARD_BIOS_CheckLEDs_From_DataArea((mem_readb(BIOS_KEYBOARD_STATE) >> 4) & 7); + if (enable_bios_timer_synchronize_keyboard_leds) { + 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 static bool check = false; diff --git a/vs2015/.vs/dosbox-x/v14/.suo b/vs2015/.vs/dosbox-x/v14/.suo index a6d0fe9e7f6e7d2557f474be85a5443a07859d98..d1bc42444bc7d3815bac657288c47c6e336327c3 100644 GIT binary patch delta 232 zcmZqpz}4`9Yk~nI!$d=APDTa>25unUIz90yqwvOp35*j9I3_XWunC9?zGr^8xrk{Q zqYMvF!7d>F4+Jxy^j{!549K2r!tzA`Bmn}MKmitzpao~j<~gh>LX*UFL~Z~DZUgaj zAWj2fkiy9hQd1cJPQEIZF6s*udJV)BV_YQD zuxSP((`Lqb|0|a%FfuKZVhoxl!Pvpry}eU{v7B*P9;4UfgCWA3g)h8iT(*nx9{?i& BQSkr( delta 207 zcmZqpz}4`9Yk~nI(?mmQPG$xM1}-4JGClDqqwvOp35*j9I3_XWupBsatZs7w+XTi* zEE1AlKoz@y_&*TLfYP2o`tM{zj^CUtKvpIY^G`Nqb>`%T%KJ`kWEExs>DWAjHA83; zpVDTf1NRswi5W1ynrtW*KY4 r*ui*vd*>>~3dZe>QjGrtCm#$E-Yk6KE#tC0Mz3WOj7-aRG5!Mpe``$C