implement proper IRQL, DPCs, kernel and user APCs, alertable waits, async file I/O with cancellation, trap frames, selftests, a real driver/device model, native async FAT32, VFAT dotfile fixes, syscall ABI cleanup, async_apc and async_cancel tests, POSIX multi-volume paths, and pimp the readme.
This commit is contained in:
1 parent
f5fd7bdd75
commit
529f816166
75 files changed
+9969
-5675
No files matched your search
+46
-2
@@ -17,6 +17,17 @@ static uint8_t gBuf[KBD_BUF_SIZE];
|
||||
static volatile int gHead = 0;
|
||||
static volatile int gTail = 0;
|
||||
|
||||
// -- Deferred callback queue ---------------------------------------------------
|
||||
// The hard IRQ path updates the key state and stores completed make codes.
|
||||
// Optional client callbacks are delivered later from the kernel-queued DPC,
|
||||
// never directly from DIRQL/ISR context.
|
||||
#define KBD_DPC_BUF_SIZE 128u
|
||||
#define KBD_DPC_BUF_MASK (KBD_DPC_BUF_SIZE - 1u)
|
||||
|
||||
static uint8_t gDpcBuf[KBD_DPC_BUF_SIZE];
|
||||
static volatile int gDpcHead = 0;
|
||||
static volatile int gDpcTail = 0;
|
||||
|
||||
// -- Live Key State (for GetAsyncKeyState) ------------------------------------
|
||||
// These arrays track whether a key is currently held down.
|
||||
static volatile uint8_t gKeyState[128]; // Standard scan codes
|
||||
@@ -62,6 +73,21 @@ static const char gShifted[128] = {
|
||||
0, 0, 0, 0, 0, '7','8','9','-', '4','5','6','+', '1','2','3','0','.'
|
||||
};
|
||||
|
||||
// -- Deferred callback delivery ------------------------------------------------
|
||||
static void KbdDpc(void) {
|
||||
for (;;) {
|
||||
if (gDpcHead == gDpcTail)
|
||||
break;
|
||||
|
||||
uint8_t make = gDpcBuf[gDpcHead];
|
||||
gDpcHead = (gDpcHead + 1) & (int)KBD_DPC_BUF_MASK;
|
||||
|
||||
void (*cb)(uint8_t) = (void (*)(uint8_t))gCallback;
|
||||
if (cb)
|
||||
cb(make);
|
||||
}
|
||||
}
|
||||
|
||||
// -- ISR: The Engine -----------------------------------------------------------
|
||||
void KbdIsr(void) {
|
||||
uint8_t sc = __inbyte(PS2_DATA);
|
||||
@@ -108,8 +134,15 @@ void KbdIsr(void) {
|
||||
gTail = next;
|
||||
}
|
||||
|
||||
void (*cb)(uint8_t) = (void (*)(uint8_t))gCallback;
|
||||
if (cb) cb(make);
|
||||
// Queue optional callback delivery to the DPC path. Keep a separate
|
||||
// callback queue so the public ReadScancode ring remains independent.
|
||||
if (gCallback) {
|
||||
int dpcNext = (gDpcTail + 1) & (int)KBD_DPC_BUF_MASK;
|
||||
if (dpcNext != gDpcHead) {
|
||||
gDpcBuf[gDpcTail] = make;
|
||||
gDpcTail = dpcNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +179,14 @@ static char KbdReadChar(void) {
|
||||
return shifted ? gShifted[make] : gUnshifted[make];
|
||||
}
|
||||
|
||||
static uint32_t KbdGetModifiers(void) {
|
||||
return gModifiers;
|
||||
}
|
||||
|
||||
static void KbdSetCallback(void (*cb)(uint8_t scancode)) {
|
||||
gCallback = cb;
|
||||
}
|
||||
|
||||
void HalKeyboardInitialize(HAL_KEYBOARD *out) {
|
||||
while (__inbyte(PS2_STAT) & 2);
|
||||
__outbyte(PS2_CMD, 0xA8);
|
||||
@@ -154,7 +195,10 @@ void HalKeyboardInitialize(HAL_KEYBOARD *out) {
|
||||
out->Poll = KbdPoll;
|
||||
out->ReadScancode = KbdReadScancode;
|
||||
out->ReadChar = KbdReadChar;
|
||||
out->GetModifiers = KbdGetModifiers;
|
||||
out->SetCallback = KbdSetCallback;
|
||||
out->IsKeyDown = KbdIsKeyDown;
|
||||
out->Isr = KbdIsr;
|
||||
out->Dpc = KbdDpc;
|
||||
out->IrqNumber = 1;
|
||||
}
|
||||
Reference in new issue
Block a user