![]() Of course, soon after that, I found a post saying that you can just bind Ctrl+ScrollLock instead, since QBasic also accepts that. Figures. I hacked the emulator's keyboard hardware code to also send Ctrl down/up codes, and sure enough, QBasic finally broke out of run mode. ![]() ![]() Not only that, but it won't accept it as such unless it also sees the Ctrl key down, which is why I couldn't get it to work with Pause as the host key. It turns out that while QBasic hooks the BIOS Ctrl+Break callback to block it in edit mode, it run mode it takes over the IRQ1 interrupt vector and monitors the raw scan codes for Ctrl+Break. Surprisingly, WinDbg has a limited ability to debug 16-bit code - disassembly's a bit wonky, but breakpoints do work - so I was able to debug the IRQ1 handler under NTVDM on a machine running 32-bit XP. None of that was working either, so I had to figure out how QBasic handles Ctrl+Break. That meant the next likely missing part was the BIOS handling, which involves setting a break flag, pushing a break code into the keyboard buffer, and calling a break interrupt vector. As I said earlier, it was easy enough to send down the right set of scancodes, but that wasn't working. The next step, then, was to figure out how to push Ctrl+Break through. There wasn't a straightforward fix for this, and I didn't really have the intention to rewrite the input path in both DOSBox and SDL, so I decided to just bypass it and try to get the Pause key to send Ctrl+Break into the emulation. Apparently, one of the undocumented gotchas for DirectInput is that you might not get Ctrl+Break events, ever. I'd never encountered this because I use window messages for keyboard input in my own programs. An example is dynamic vertex/index buffers in Direct3D9, which seem easy, until you find out that occasionally on mode switches Lock() hands back an invalid pointer while still returning D3D_OK. uh oh.ĭirectX, like most Windows APIs, has a lot of unwritten lore that still isn't really documented after a decade, basic stuff that you need to know but end up learning the hard way. Let's see, no WM_KEYDOWN handler, which means it's probably using DirectInput, so let's set a breakpoint on the DirectInput code. Luckily, I built the SDL library in Debug configuration from source, so I can debug into it. In fact, no keyboard events are arriving at all when I press Ctrl+Break. That was easily fixed, but I noticed that Ctrl+Break was never arriving from the UI, either. Okay, we probably just need to check for the analogous SDL constant for VK_CANCEL, which appears to be SDLK_BREAK. Sure enough, when I dug into the keyboard emulation code, it was always sending the scan codes for the pause key. Therefore, somewhere along the line, it's likely that this difference wasn't being emulated. This anomaly is often reflected in higher level APIs, and in Win32, this manifests as your window handler getting a WM_KEYDOWN message with VK_CANCEL instead of VK_PAUSE. One of them is Pause, which magically turns to Break when Ctrl is also pressed. (I'm actually not a fan of the "fix it yourself it's open source" mentality, and I don't have any good memories of 16-bit real mode x86, but scuttle four Colonization games in a row and I will launch the debugger.) Now, I already had a suspicion as to what was causing this: there's an anomaly in the PC keyboard where certain scan codes change depending on modifier keys. I'd had luck doing this previously, when I tracked down the bug where the keyboard would suddenly stop working if you pressed Ctrl+Esc. I finally got annoyed enough about this to try to diagnose it myself. ![]() Unfortunately, one of the old programs I occasionally run is QBasic, and there's a long standing problem where Ctrl+Break doesn't work in QBasic under DOSBox. Therefore, I've been making greater use of DOSBox in the few cases where I need to run such programs, since it integrates a little better than virtualization. While this is usually attributed to Microsoft cleaning legacy house, it's also due to a hardware limitation: the original x86-64 specification prohibited VM86 mode under long mode. One of the problems with switching to a 64-bit version of Windows is that you can't run 16-bit DOS programs, due to the removal of NTVDM. ¶Why Ctrl+Break doesn't work with QBasic in DOSBox
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |