Lockup with Ctrl-Shift + Chars
Mar 14, 2023 18:07:06 GMT 1
Post by whathim on Mar 14, 2023 18:07:06 GMT 1
Jos
I’ve come across an issue that occurred in my PowerBasic editor program but I’ve extracted the code to a small test program and it’s repeatable.
The test program simply consists of a ChildLoop that is called from a ParentLoop. The program monitors the keyboard shift status and when it sees Ctrl-Shift it remains in the ChildLoop otherwise it remains in ParentLoop.
The issue manifests when running in vDos under Windows 10. There are two scenarios, the second of which is the more serious.
Scenario 1:
1. Press and hold Ctrl-Shift so that the program remains in ChildLoop.
2. With the shift keys still held, press Esc. This, of course, activates Windows Task Manager.
3. Release the Ctrl-Shift keys. The program remains in ChildLoop.
4. Restore focus to Vdos by clicking its task bar (or by minimising Task Manager).
5. The program remains in ChildLoop even though Ctrl-Shift has been released. Pressing a key (any key will do) causes the program to exit ChildLoop as it should.
Scenario 2:
1. Press and hold Ctrl-Shift so that the program remains in ChildLoop.
2. With the shift keys still held, press and hold a character key, for example “A”.
3. After a short time, the program locks and the vDos window goes grey.
4. Pressing keys at random has no effect and Task Manger says vDos is not responding.
5. No way out but to “End task” from Task Manager.
I might add that in Scenario 2, just pressing a character key several times (i.e. no auto-repeat) eventually gives the same lock up (of the order of 30 keypresses).
When I try the program in NTVDM under Windows XP, the issue doesn’t manifest.
Scenario 1:
In steps 4 and 5 above, when I restore focus to the NTVDM window, the program immediately exits ChildLoop, as it should. I do not have to press a key to cause exit.
Scenario 2:
As above, I press and hold Ctrl-Shift and then simultaneously hold a character key, like “A”. No lockup occurs. However, the keyboard buffer starts beeping indicating it is full. Perhaps this is a clue to what is going on.
Keith
I’ve come across an issue that occurred in my PowerBasic editor program but I’ve extracted the code to a small test program and it’s repeatable.
The test program simply consists of a ChildLoop that is called from a ParentLoop. The program monitors the keyboard shift status and when it sees Ctrl-Shift it remains in the ChildLoop otherwise it remains in ParentLoop.
The issue manifests when running in vDos under Windows 10. There are two scenarios, the second of which is the more serious.
Scenario 1:
1. Press and hold Ctrl-Shift so that the program remains in ChildLoop.
2. With the shift keys still held, press Esc. This, of course, activates Windows Task Manager.
3. Release the Ctrl-Shift keys. The program remains in ChildLoop.
4. Restore focus to Vdos by clicking its task bar (or by minimising Task Manager).
5. The program remains in ChildLoop even though Ctrl-Shift has been released. Pressing a key (any key will do) causes the program to exit ChildLoop as it should.
Scenario 2:
1. Press and hold Ctrl-Shift so that the program remains in ChildLoop.
2. With the shift keys still held, press and hold a character key, for example “A”.
3. After a short time, the program locks and the vDos window goes grey.
4. Pressing keys at random has no effect and Task Manger says vDos is not responding.
5. No way out but to “End task” from Task Manager.
I might add that in Scenario 2, just pressing a character key several times (i.e. no auto-repeat) eventually gives the same lock up (of the order of 30 keypresses).
When I try the program in NTVDM under Windows XP, the issue doesn’t manifest.
Scenario 1:
In steps 4 and 5 above, when I restore focus to the NTVDM window, the program immediately exits ChildLoop, as it should. I do not have to press a key to cause exit.
Scenario 2:
As above, I press and hold Ctrl-Shift and then simultaneously hold a character key, like “A”. No lockup occurs. However, the keyboard buffer starts beeping indicating it is full. Perhaps this is a clue to what is going on.
Keith
insert code here' TEST01 -------------------------------------------- Keith Waters
'
' Run program and follow on-screen instructions.
'
%Key.Enter = 13
' -------------------------------------------------------------------
'SUB GetKey (ky$)
' ky$ returned key press {out}
'
' Waits for a key-press. Extended characters are returned intact.
'
SUB GetKey (k$)
DO UNTIL GotKey(k$)
LOOP
END SUB
' --------------------------------------------------------
' Reads a character from the keyboard buffer and returns true if one was
' indeed retrieved.
'
FUNCTION GotKey (k$) AS INTEGER
k$ = INKEY$
FUNCTION = ISTRUE(LEN(k$))
END FUNCTION
' --------------------------------------------------------------
' Shift status values
'
%Status.RightShift = &B0000001 'Decimal 1
%Status.LeftShift = &B0000010 'Decimal 2
%Status.CtrlKey = &B0000100 'Decimal 4
%Status.AltKey = &B0001000 'Decimal 8
%Status.ScrollLock = &B0010000 'Decimal 16
%Status.NumLock = &B0100000 'Decimal 32
%Status.CapsLock = &B1000000 'Decimal 64
' NOTE: The above shift status values were confirmed through experiment and
' are documented in Appendix A of the PB3 Reference Guide.
'
' ----------------------------------------------------------
' Returns true if the shift status of the keyboard includes the specified
' shift-status mask.
FUNCTION ShiftKey% (BYVAL mask%) PRIVATE
DEF SEG = &H40
ShiftKey% = ( (PEEK(&H17) AND mask%) = mask% )
DEF SEG
END FUNCTION
' EXAMPLE: ShiftKey% (%Status.LeftShift OR %Status.CtrlKey) returns true if
' the keyboard left-Shift and Ctrl keys are down. Note that another
' shift-status (e.g. NumLock) might be down simultaneously.
'
' -------------------------------------------------------
SUB ChildLoop ()
LOCAL n%
DO WHILE ShiftKey%(%Status.CtrlKey OR %Status.LeftShift)
LOCATE 10, 10
PRINT "Child Loop:" + STR$(n%)
IF n% > 32000 THEN n% = 0
INCR n%
LOOP
LOCATE 10, 10
PRINT " "
END SUB
' -----------------------------------------
SUB ParentLoop ()
LOCAL k$
CLS
LOCATE 6, 10
PRINT "Hold down Ctrl-Shift to activate child loop."
LOCATE 8, 10
PRINT "Press Enter to exit program."
DO
CALL GotKey(k$)
IF ASCII(k$) = %Key.Enter THEN EXIT LOOP
CALL ChildLoop ()
LOOP
LOCATE 12, 10
PRINT "Program exited."
END SUB
' -------------------------------------------------
CALL ParentLoop()
' =================================================================