move keyboard and mouse out of HAL into a standalone ps2.sys driver, implement usb stack with xhci controller discovery, hid keyboard/mouse, and bulk-only mass storage, add pci msi support with capability chain walking and software irq vector allocation (slots 16-23), rewrite user virtual memory as a USER_VA_REGION descriptor arena with per-process ownership tracking and guard page support, replacing the old bump allocator and top-down image region, add MmCreateUserRegion/MmDestroyAllUserRegions so process teardown reclaims all user va in one pass, allocate a pool-backed shadow framebuffer in hal_screen to fix cursor tearing and scroll corruption, reserve ap trampoline page below 1mb in uefi bootloader before boot services exit, rewrite memset/memcpy/memmove/memcmp with __stosq/__movsq intrinsics, promote driver flag literals to macros and add multi-tu STANDALONE_DRIVERS table to build.c, split rtl8139/rtl816x into header+source, rename KbReadScancode to KbReadKey, improve page fault output with MmDebugDescribeAddress and user region dump, fix %p to %016llX throughout.

This commit is contained in:
maksw committed 2026-06-02 00:01:20 +02:00
1 parent b970d7f59c
commit b838f8d83d
130 files changed
+8137 -2932

No files matched your search

+4 -4
View File
@@ -48439,7 +48439,7 @@ void Z_DumpHeap(int lowtag, int hightag)
{
memblock_t* block;
//doom_print("zone size: %i location: %p\n",
//doom_print("zone size: %i location: 0x%016llX\n",
// mainzone->size, mainzone);
doom_print("zone size: ");
doom_print(doom_itoa(mainzone->size, 10));
@@ -48459,7 +48459,7 @@ void Z_DumpHeap(int lowtag, int hightag)
{
if (block->tag >= lowtag && block->tag <= hightag)
{
//doom_print("block:%p size:%7i user:%p tag:%3i\n", block, block->size, block->user, block->tag);
//doom_print("block:0x%016llX size:%7i user:0x%016llX tag:%3i\n", block, block->size, block->user, block->tag);
doom_print("block");
doom_print(doom_ptoa(block));
doom_print(" size:");
@@ -48496,7 +48496,7 @@ void Z_FileDumpHeap(void* f)
{
memblock_t* block;
//fprintf(f, "zone size: %i location: %p\n", mainzone->size, mainzone);
//fprintf(f, "zone size: %i location: 0x%016llX\n", mainzone->size, mainzone);
doom_fprint(f, "zone size: ");
doom_fprint(f, doom_itoa(mainzone->size, 10));
doom_fprint(f, " location: ");
@@ -48505,7 +48505,7 @@ void Z_FileDumpHeap(void* f)
for (block = mainzone->blocklist.next; ; block = block->next)
{
//fprintf(f, "block:%p size:%7i user:%p tag:%3i\n",
//fprintf(f, "block:0x%016llX size:%7i user:0x%016llX tag:%3i\n",
// block, block->size, block->user, block->tag);
doom_fprint(f, "block:");
doom_fprint(f, doom_ptoa(block));
+46 -46
View File
@@ -180,67 +180,67 @@ static char* doom_getenv_wrapper(const char* name)
}
// ---------------------------------------------------------------------------
// Input — Maps Scancode Set 1 values to PureDOOM
// Input — Maps canonical input keys to PureDOOM
// ---------------------------------------------------------------------------
typedef struct { uint8_t scancode; bool extended; doom_key_t key; } KeyMap;
typedef struct { INPUT_KEY inputKey; doom_key_t key; } KeyMap;
static const KeyMap g_keymap[] = {
// Letters
{ 0x11, false, DOOM_KEY_W },
{ 0x1E, false, DOOM_KEY_A },
{ 0x1F, false, DOOM_KEY_S },
{ 0x20, false, DOOM_KEY_D },
{ 0x12, false, DOOM_KEY_E },
{ 0x10, false, DOOM_KEY_Q },
{ 0x15, false, DOOM_KEY_Y },
{ 0x31, false, DOOM_KEY_N },
{ INPUT_KEY_W, DOOM_KEY_W },
{ INPUT_KEY_A, DOOM_KEY_A },
{ INPUT_KEY_S, DOOM_KEY_S },
{ INPUT_KEY_D, DOOM_KEY_D },
{ INPUT_KEY_E, DOOM_KEY_E },
{ INPUT_KEY_Q, DOOM_KEY_Q },
{ INPUT_KEY_Y, DOOM_KEY_Y },
{ INPUT_KEY_N, DOOM_KEY_N },
// Arrow keys
{ 0x48, true, DOOM_KEY_UP_ARROW },
{ 0x50, true, DOOM_KEY_DOWN_ARROW },
{ 0x4B, true, DOOM_KEY_LEFT_ARROW },
{ 0x4D, true, DOOM_KEY_RIGHT_ARROW },
{ INPUT_KEY_UP, DOOM_KEY_UP_ARROW },
{ INPUT_KEY_DOWN, DOOM_KEY_DOWN_ARROW },
{ INPUT_KEY_LEFT, DOOM_KEY_LEFT_ARROW },
{ INPUT_KEY_RIGHT, DOOM_KEY_RIGHT_ARROW },
// Action keys
{ 0x1D, false, DOOM_KEY_CTRL },
{ 0x39, false, DOOM_KEY_SPACE },
{ 0x2A, false, DOOM_KEY_SHIFT },
{ 0x38, false, DOOM_KEY_ALT },
{ INPUT_KEY_LEFT_CTRL, DOOM_KEY_CTRL },
{ INPUT_KEY_SPACE, DOOM_KEY_SPACE },
{ INPUT_KEY_LEFT_SHIFT, DOOM_KEY_SHIFT },
{ INPUT_KEY_LEFT_ALT, DOOM_KEY_ALT },
// Navigation
{ 0x01, false, DOOM_KEY_ESCAPE },
{ 0x1C, false, DOOM_KEY_ENTER },
{ 0x0F, false, DOOM_KEY_TAB },
{ 0x0E, false, DOOM_KEY_BACKSPACE },
{ INPUT_KEY_ESCAPE, DOOM_KEY_ESCAPE },
{ INPUT_KEY_ENTER, DOOM_KEY_ENTER },
{ INPUT_KEY_TAB, DOOM_KEY_TAB },
{ INPUT_KEY_BACKSPACE, DOOM_KEY_BACKSPACE },
// Weapon slots
{ 0x02, false, DOOM_KEY_1 },
{ 0x03, false, DOOM_KEY_2 },
{ 0x04, false, DOOM_KEY_3 },
{ 0x05, false, DOOM_KEY_4 },
{ 0x06, false, DOOM_KEY_5 },
{ 0x07, false, DOOM_KEY_6 },
{ 0x08, false, DOOM_KEY_7 },
{ INPUT_KEY_1, DOOM_KEY_1 },
{ INPUT_KEY_2, DOOM_KEY_2 },
{ INPUT_KEY_3, DOOM_KEY_3 },
{ INPUT_KEY_4, DOOM_KEY_4 },
{ INPUT_KEY_5, DOOM_KEY_5 },
{ INPUT_KEY_6, DOOM_KEY_6 },
{ INPUT_KEY_7, DOOM_KEY_7 },
// Misc
{ 0x0C, false, DOOM_KEY_MINUS },
{ 0x0D, false, DOOM_KEY_EQUALS },
{ 0x33, false, DOOM_KEY_COMMA },
{ 0x34, false, DOOM_KEY_PERIOD },
{ INPUT_KEY_MINUS, DOOM_KEY_MINUS },
{ INPUT_KEY_EQUAL, DOOM_KEY_EQUALS },
{ INPUT_KEY_COMMA, DOOM_KEY_COMMA },
{ INPUT_KEY_PERIOD, DOOM_KEY_PERIOD },
// Function keys
{ 0x3B, false, DOOM_KEY_F1 },
{ 0x3C, false, DOOM_KEY_F2 },
{ 0x3D, false, DOOM_KEY_F3 },
{ 0x3E, false, DOOM_KEY_F4 },
{ 0x3F, false, DOOM_KEY_F5 },
{ 0x40, false, DOOM_KEY_F6 },
{ 0x41, false, DOOM_KEY_F7 },
{ 0x42, false, DOOM_KEY_F8 },
{ 0x43, false, DOOM_KEY_F9 },
{ 0x44, false, DOOM_KEY_F10 },
{ 0x57, false, DOOM_KEY_F11 },
{ 0x58, false, DOOM_KEY_F12 },
{ INPUT_KEY_F1, DOOM_KEY_F1 },
{ INPUT_KEY_F2, DOOM_KEY_F2 },
{ INPUT_KEY_F3, DOOM_KEY_F3 },
{ INPUT_KEY_F4, DOOM_KEY_F4 },
{ INPUT_KEY_F5, DOOM_KEY_F5 },
{ INPUT_KEY_F6, DOOM_KEY_F6 },
{ INPUT_KEY_F7, DOOM_KEY_F7 },
{ INPUT_KEY_F8, DOOM_KEY_F8 },
{ INPUT_KEY_F9, DOOM_KEY_F9 },
{ INPUT_KEY_F10, DOOM_KEY_F10 },
{ INPUT_KEY_F11, DOOM_KEY_F11 },
{ INPUT_KEY_F12, DOOM_KEY_F12 },
};
#define KEYMAP_COUNT (sizeof(g_keymap) / sizeof(g_keymap[0]))
@@ -250,7 +250,7 @@ static bool g_prev_key[KEYMAP_COUNT];
static void poll_input(void)
{
for (int i = 0; i < (int)KEYMAP_COUNT; i++) {
bool cur_down = (SysKbIsKeyDown(g_keymap[i].scancode, g_keymap[i].extended) != 0);
bool cur_down = (SysKbIsKeyDown(g_keymap[i].inputKey) != 0);
bool prev_down = g_prev_key[i];
if (cur_down && !prev_down) doom_key_down(g_keymap[i].key);
+60 -65
View File
@@ -27,29 +27,21 @@
#define COL_CURSOR 0xE0E0E0u
#define COL_CURSORF 0x000000u
#define MOD_LSHIFT (1u << 0)
#define MOD_RSHIFT (1u << 1)
#define MOD_LCTRL (1u << 2)
#define MOD_RCTRL (1u << 3)
#define MOD_CAPS (1u << 6)
#define MOD_SHIFT (MOD_LSHIFT | MOD_RSHIFT)
#define MOD_CTRL (MOD_LCTRL | MOD_RCTRL)
#define SC_ESC 0x01u
#define SC_BACKSPACE 0x0Eu
#define SC_TAB 0x0Fu
#define SC_Q 0x10u
#define SC_S 0x1Fu
#define SC_ENTER 0x1Cu
#define SC_HOME 0x47u
#define SC_UP 0x48u
#define SC_PGUP 0x49u
#define SC_LEFT 0x4Bu
#define SC_RIGHT 0x4Du
#define SC_END 0x4Fu
#define SC_DOWN 0x50u
#define SC_PGDN 0x51u
#define SC_DEL 0x53u
#define EDIT_KEY_ESC INPUT_KEY_ESCAPE
#define EDIT_KEY_BACKSPACE INPUT_KEY_BACKSPACE
#define EDIT_KEY_TAB INPUT_KEY_TAB
#define EDIT_KEY_Q INPUT_KEY_Q
#define EDIT_KEY_S INPUT_KEY_S
#define EDIT_KEY_ENTER INPUT_KEY_ENTER
#define EDIT_KEY_HOME INPUT_KEY_HOME
#define EDIT_KEY_UP INPUT_KEY_UP
#define EDIT_KEY_PGUP INPUT_KEY_PAGE_UP
#define EDIT_KEY_LEFT INPUT_KEY_LEFT
#define EDIT_KEY_RIGHT INPUT_KEY_RIGHT
#define EDIT_KEY_END INPUT_KEY_END
#define EDIT_KEY_DOWN INPUT_KEY_DOWN
#define EDIT_KEY_PGDN INPUT_KEY_PAGE_DOWN
#define EDIT_KEY_DEL INPUT_KEY_DELETE
typedef struct LINE {
int len;
@@ -69,22 +61,6 @@ static bool gQuitArmed = false;
static char gFilename[PATH_MAX2] = "untitled.txt";
static char gMessage[MSG_MAX] = "ready";
static const char gUnshifted[128] = {
0, 0, '1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
'q','w','e','r','t','y','u','i','o','p','[',']','\n', 0, 'a','s',
'd','f','g','h','j','k','l',';','\'','`', 0, '\\','z','x','c','v',
'b','n','m',',','.','/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, '7','8','9','-', '4','5','6','+', '1','2','3','0','.'
};
static const char gShifted[128] = {
0, 0, '!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
'Q','W','E','R','T','Y','U','I','O','P','{','}','\n', 0, 'A','S',
'D','F','G','H','J','K','L',':','"','~', 0, '|','Z','X','C','V',
'B','N','M','<','>','?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, '7','8','9','-', '4','5','6','+', '1','2','3','0','.'
};
static void put_cell(int col, int row, char c, uint32_t fg, uint32_t bg) {
SysScreenPutChar(c ? c : ' ', col * GLYPH_W, row * GLYPH_H, fg, bg);
}
@@ -124,14 +100,33 @@ static void append_u32(char* b, size_t cap, size_t* p, uint32_t v) {
while (n > 0) append_char(b, cap, p, tmp[--n]);
}
static char key_to_char(uint8_t sc, uint32_t mods) {
if (sc >= 128) return 0;
bool shifted = (mods & MOD_SHIFT) != 0;
if (mods & MOD_CAPS) {
char base = gUnshifted[sc];
if (base >= 'a' && base <= 'z') shifted = !shifted;
static char key_to_char(INPUT_KEY key, uint32_t mods) {
if (key >= INPUT_KEY_A && key <= INPUT_KEY_Z) {
bool shifted = (mods & INPUT_MOD_SHIFT) != 0;
bool caps = (mods & INPUT_MOD_CAPS_LOCK) != 0;
char c = (char)('a' + (key - INPUT_KEY_A));
return (shifted ^ caps) ? (char)(c - 'a' + 'A') : c;
}
return shifted ? gShifted[sc] : gUnshifted[sc];
typedef struct { INPUT_KEY key; char normal; char shifted; } PAIR;
static const PAIR map[] = {
{ INPUT_KEY_1, '1', '!' }, { INPUT_KEY_2, '2', '@' },
{ INPUT_KEY_3, '3', '#' }, { INPUT_KEY_4, '4', '$' },
{ INPUT_KEY_5, '5', '%' }, { INPUT_KEY_6, '6', '^' },
{ INPUT_KEY_7, '7', '&' }, { INPUT_KEY_8, '8', '*' },
{ INPUT_KEY_9, '9', '(' }, { INPUT_KEY_0, '0', ')' },
{ INPUT_KEY_MINUS, '-', '_' }, { INPUT_KEY_EQUAL, '=', '+' },
{ INPUT_KEY_LEFT_BRACKET, '[', '{' }, { INPUT_KEY_RIGHT_BRACKET, ']', '}' },
{ INPUT_KEY_BACKSLASH, '\\', '|' }, { INPUT_KEY_SEMICOLON, ';', ':' },
{ INPUT_KEY_APOSTROPHE, '\'', '"' }, { INPUT_KEY_GRAVE, '`', '~' },
{ INPUT_KEY_COMMA, ',', '<' }, { INPUT_KEY_PERIOD, '.', '>' },
{ INPUT_KEY_SLASH, '/', '?' }, { INPUT_KEY_SPACE, ' ', ' ' },
};
bool shifted = (mods & INPUT_MOD_SHIFT) != 0;
for (size_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
if (map[i].key == key) return shifted ? map[i].shifted : map[i].normal;
}
return 0;
}
static void clamp_cursor(void) {
@@ -423,11 +418,11 @@ static void editor_loop(void) {
while (true) {
render();
uint8_t sc = SysKbReadScancode();
INPUT_KEY key = SysKbReadKey();
uint32_t mods = SysKbGetModifiers();
bool ctrl = (mods & MOD_CTRL) != 0;
bool ctrl = (mods & INPUT_MOD_CTRL) != 0;
if (ctrl && sc == SC_Q) {
if (ctrl && key == EDIT_KEY_Q) {
if (gDirty && !gQuitArmed) {
gQuitArmed = true;
msg_set("unsaved changes: press Ctrl+Q again to quit");
@@ -438,38 +433,38 @@ static void editor_loop(void) {
gQuitArmed = false;
if (ctrl && sc == SC_S) { save_file(); continue; }
if (sc == SC_ESC) { msg_set("Ctrl+Q quits, Ctrl+S saves"); continue; }
if (ctrl && key == EDIT_KEY_S) { save_file(); continue; }
if (key == EDIT_KEY_ESC) { msg_set("Ctrl+Q quits, Ctrl+S saves"); continue; }
switch (sc) {
case SC_LEFT: move_left(); break;
case SC_RIGHT: move_right(); break;
case SC_UP: move_up(); break;
case SC_DOWN: move_down(); break;
case SC_HOME: gCx = 0; break;
case SC_END: gCx = gLines[gCy].len; break;
case SC_PGUP: {
switch (key) {
case EDIT_KEY_LEFT: move_left(); break;
case EDIT_KEY_RIGHT: move_right(); break;
case EDIT_KEY_UP: move_up(); break;
case EDIT_KEY_DOWN: move_down(); break;
case EDIT_KEY_HOME: gCx = 0; break;
case EDIT_KEY_END: gCx = gLines[gCy].len; break;
case EDIT_KEY_PGUP: {
int n = gRows - 2;
if (n < 1) n = 1;
gCy -= n;
clamp_cursor();
break;
}
case SC_PGDN: {
case EDIT_KEY_PGDN: {
int n = gRows - 2;
if (n < 1) n = 1;
gCy += n;
clamp_cursor();
break;
}
case SC_BACKSPACE: backspace_at_cursor(); break;
case SC_DEL: delete_at_cursor(); break;
case SC_ENTER: newline_at_cursor(); break;
case SC_TAB:
case EDIT_KEY_BACKSPACE: backspace_at_cursor(); break;
case EDIT_KEY_DEL: delete_at_cursor(); break;
case EDIT_KEY_ENTER: newline_at_cursor(); break;
case EDIT_KEY_TAB:
for (int i = 0; i < 4; i++) insert_char_at_cursor(' ');
break;
default: {
char c = key_to_char(sc, mods);
char c = key_to_char(key, mods);
if (!ctrl && c >= 0x20 && c <= 0x7E) insert_char_at_cursor(c);
break;
}
+1 -1
View File
@@ -173,7 +173,7 @@ typedef struct BINKSND {
// will do it's own threading)
// 2 = No background thread processing at all, but setup
// thread mutexes, so that BinkServiceSound() can be
// call from an external background thread.
// call from an external background thread.
U32 SoundDroppedOut;
U32 sndconvert8; // convert back to 8-bit sound at runtime
+1 -1
View File
@@ -50,7 +50,7 @@ static void PthreadTrampoline(uintptr_t raw) {
uint32_t pid = tr->Pid;
uint32_t tid = SysGetCurrentTid();
// Create the join slot from inside the new thread. KeCreateThread makes the
// Create the join slot from inside the new thread. KeCreateThread makes the
// thread runnable before the creator regains control, so the old design
// raced on tr->Tid and could observe zero/stale memory.
PTHREAD_SLOT* slot = PthreadSlotFind(pid, tid);
+48 -49
View File
@@ -107,7 +107,7 @@ typedef struct _WIN32_FIND_DATAA {
static inline HANDLE KH_TO_HANDLE(uint32_t kh) { return (HANDLE)(uintptr_t)kh; }
static inline uint32_t HANDLE_TO_KH(HANDLE h) { return (uint32_t)(uintptr_t)h; }
// Thread IDs are not kernel handles. Keep Win32 thread pseudo-handles out of
// Thread IDs are not kernel handles. Keep Win32 thread pseudo-handles out of
// the low numeric handle namespace so CloseHandle/WaitForSingleObject cannot
// accidentally operate on an unrelated file/process handle with the same value.
#define WIN32_THREAD_HANDLE_TAG ((uintptr_t)1ULL << 63)
@@ -133,7 +133,7 @@ static void TranslatePath(const char* input, char* output) {
if (!input) { output[0] = '\0'; return; }
if (input[0] != '\0' && input[1] == ':' && (input[2] == '\\' || input[2] == '/')) {
// Translate "C:\" -> "0:/". Native nt-lite paths such as
// Translate "C:\" -> "0:/". Native nt-lite paths such as
// "0:/system/foo.dll" are already drive-indexed and pass through.
char drive = input[0];
if (drive >= 'a' && drive <= 'z') drive -= ('a' - 'A'); // To uppercase
@@ -440,61 +440,60 @@ __declspec(dllexport) size_t VirtualQuery(const void* lpAddress,
// --- Win32 API ---
// Updated GetAsyncKeyState implementation
// GetAsyncKeyState implementation over the canonical input key namespace.
__declspec(dllexport) SHORT GetAsyncKeyState(int vKey) {
static const struct { int vk; uint8_t sc; bool ext; } vk_to_sc[] = {
if (vKey == 0x11) { // VK_CONTROL
return (SysKbIsKeyDown(INPUT_KEY_LEFT_CTRL) || SysKbIsKeyDown(INPUT_KEY_RIGHT_CTRL)) ? (SHORT)0x8000 : 0;
}
if (vKey == 0x10) { // VK_SHIFT
return (SysKbIsKeyDown(INPUT_KEY_LEFT_SHIFT) || SysKbIsKeyDown(INPUT_KEY_RIGHT_SHIFT)) ? (SHORT)0x8000 : 0;
}
if (vKey == 0x12) { // VK_MENU / ALT
return (SysKbIsKeyDown(INPUT_KEY_LEFT_ALT) || SysKbIsKeyDown(INPUT_KEY_RIGHT_ALT)) ? (SHORT)0x8000 : 0;
}
static const struct { int vk; INPUT_KEY key; } vk_to_key[] = {
// Letters
{ 0x41, 0x1E, false }, { 0x42, 0x30, false }, { 0x43, 0x2E, false },
{ 0x44, 0x20, false }, { 0x45, 0x12, false }, { 0x46, 0x21, false },
{ 0x47, 0x22, false }, { 0x48, 0x23, false }, { 0x49, 0x17, false },
{ 0x4A, 0x24, false }, { 0x4B, 0x25, false }, { 0x4C, 0x26, false },
{ 0x4D, 0x32, false }, { 0x4E, 0x31, false }, { 0x4F, 0x18, false },
{ 0x50, 0x19, false }, { 0x51, 0x10, false }, { 0x52, 0x13, false },
{ 0x53, 0x1F, false }, { 0x54, 0x14, false }, { 0x55, 0x16, false },
{ 0x56, 0x2F, false }, { 0x57, 0x11, false }, { 0x58, 0x2D, false },
{ 0x59, 0x15, false }, { 0x5A, 0x2C, false },
{ 0x41, INPUT_KEY_A }, { 0x42, INPUT_KEY_B }, { 0x43, INPUT_KEY_C },
{ 0x44, INPUT_KEY_D }, { 0x45, INPUT_KEY_E }, { 0x46, INPUT_KEY_F },
{ 0x47, INPUT_KEY_G }, { 0x48, INPUT_KEY_H }, { 0x49, INPUT_KEY_I },
{ 0x4A, INPUT_KEY_J }, { 0x4B, INPUT_KEY_K }, { 0x4C, INPUT_KEY_L },
{ 0x4D, INPUT_KEY_M }, { 0x4E, INPUT_KEY_N }, { 0x4F, INPUT_KEY_O },
{ 0x50, INPUT_KEY_P }, { 0x51, INPUT_KEY_Q }, { 0x52, INPUT_KEY_R },
{ 0x53, INPUT_KEY_S }, { 0x54, INPUT_KEY_T }, { 0x55, INPUT_KEY_U },
{ 0x56, INPUT_KEY_V }, { 0x57, INPUT_KEY_W }, { 0x58, INPUT_KEY_X },
{ 0x59, INPUT_KEY_Y }, { 0x5A, INPUT_KEY_Z },
// Numbers
{ 0x31, 0x02, false }, { 0x32, 0x03, false }, { 0x33, 0x04, false },
{ 0x34, 0x05, false }, { 0x35, 0x06, false }, { 0x36, 0x07, false },
{ 0x37, 0x08, false }, { 0x38, 0x09, false }, { 0x39, 0x0A, false },
{ 0x30, 0x0B, false },
{ 0x31, INPUT_KEY_1 }, { 0x32, INPUT_KEY_2 }, { 0x33, INPUT_KEY_3 },
{ 0x34, INPUT_KEY_4 }, { 0x35, INPUT_KEY_5 }, { 0x36, INPUT_KEY_6 },
{ 0x37, INPUT_KEY_7 }, { 0x38, INPUT_KEY_8 }, { 0x39, INPUT_KEY_9 },
{ 0x30, INPUT_KEY_0 },
// Arrows (Extended)
{ 0x26, 0x48, true }, // VK_UP
{ 0x28, 0x50, true }, // VK_DOWN
{ 0x25, 0x4B, true }, // VK_LEFT
{ 0x27, 0x4D, true }, // VK_RIGHT
// Arrows
{ 0x26, INPUT_KEY_UP }, { 0x28, INPUT_KEY_DOWN },
{ 0x25, INPUT_KEY_LEFT }, { 0x27, INPUT_KEY_RIGHT },
// Controls
{ 0x1B, 0x01, false }, // ESC
{ 0x0D, 0x1C, false }, // ENTER
{ 0x20, 0x39, false }, // SPACE
{ 0x11, 0x1D, false }, // CTRL (Generic)
{ 0x10, 0x2A, false }, // SHIFT (Generic)
{ 0x12, 0x38, false }, // ALT (Generic)
{ 0x08, 0x0E, false }, // BACKSPACE
{ 0x09, 0x0F, false }, // TAB
{ 0x1B, INPUT_KEY_ESCAPE }, { 0x0D, INPUT_KEY_ENTER },
{ 0x20, INPUT_KEY_SPACE },
{ 0x08, INPUT_KEY_BACKSPACE }, { 0x09, INPUT_KEY_TAB },
// Function Keys
{ 0x70, 0x3B, false }, { 0x71, 0x3C, false }, { 0x72, 0x3D, false },
{ 0x73, 0x3E, false }, { 0x74, 0x3F, false }, { 0x75, 0x40, false },
{ 0x76, 0x41, false }, { 0x77, 0x42, false }, { 0x78, 0x43, false },
{ 0x79, 0x44, false }, { 0x7A, 0x57, false }, { 0x7B, 0x58, false },
{ 0x70, INPUT_KEY_F1 }, { 0x71, INPUT_KEY_F2 }, { 0x72, INPUT_KEY_F3 },
{ 0x73, INPUT_KEY_F4 }, { 0x74, INPUT_KEY_F5 }, { 0x75, INPUT_KEY_F6 },
{ 0x76, INPUT_KEY_F7 }, { 0x77, INPUT_KEY_F8 }, { 0x78, INPUT_KEY_F9 },
{ 0x79, INPUT_KEY_F10 }, { 0x7A, INPUT_KEY_F11 }, { 0x7B, INPUT_KEY_F12 },
// Symbols
{ 0xBD, 0x0C, false }, // MINUS '-'
{ 0xBB, 0x0D, false }, // EQUALS '='
{ 0xBC, 0x33, false }, // COMMA ','
{ 0xBE, 0x34, false }, // PERIOD '.'
{ 0xBD, INPUT_KEY_MINUS }, { 0xBB, INPUT_KEY_EQUAL },
{ 0xBC, INPUT_KEY_COMMA }, { 0xBE, INPUT_KEY_PERIOD },
};
for (size_t i = 0; i < sizeof(vk_to_sc)/sizeof(vk_to_sc[0]); ++i) {
if (vk_to_sc[i].vk == vKey) {
// Check the hardware state array via our HAL helper
if (SysKbIsKeyDown(vk_to_sc[i].sc, vk_to_sc[i].ext)) {
for (size_t i = 0; i < sizeof(vk_to_key) / sizeof(vk_to_key[0]); ++i) {
if (vk_to_key[i].vk == vKey) {
if (SysKbIsKeyDown(vk_to_key[i].key))
return (SHORT)0x8000;
}
break;
}
}
@@ -668,7 +667,7 @@ __declspec(dllexport) BOOL ReadFile(HANDLE hFile, void* buf, DWORD toRead,
uint32_t s = SysReadFile(HANDLE_TO_KH(hFile), buf, (size_t)toRead, &got);
if (bytesRead) *bytesRead = (DWORD)got;
// Harden callers that accidentally look past *bytesRead. EOF/short reads
// Harden callers that accidentally look past *bytesRead. EOF/short reads
// are legal for files, but consuming stale stack/heap bytes after them makes
// the failure mode look like random game-data corruption.
if (got < (size_t)toRead)
@@ -899,13 +898,13 @@ __declspec(dllexport) HANDLE LoadLibraryA(const char* lpLibFileName) {
}
// Minimal GetProcAddress for code that probes kernel32 functions already present
// in this win32.dll image. Full dynamic DLL loading remains a kernel-loader job.
// in this win32.dll image. Full dynamic DLL loading remains a kernel-loader job.
__declspec(dllexport) BOOL FreeLibrary(HANDLE hLibModule);
__declspec(dllexport) void Sleep(DWORD dwMilliseconds);
__declspec(dllexport) void* GetProcAddress(HANDLE hModule, const char* lpProcName) {
if (hModule != WIN32_HMODULE_WIN32 || !lpProcName) { gLastError = 127; return NULL; }
// Ordinal probes are represented as small integer pointers. Do not treat
// Ordinal probes are represented as small integer pointers. Do not treat
// them as strings while debugging misses.
if ((uintptr_t)lpProcName < 0x10000) {
KiDbgWriteA("GetProcAddress ordinal miss\n");
@@ -1116,7 +1115,7 @@ __declspec(dllexport) BOOL CreateProcessA(
}
uint32_t kh = 0;
// Call the syscall.dll stub. The kernel snapshots the current CWD into
// Call the syscall.dll stub. The kernel snapshots the current CWD into
// the child process, so the temporary lpCurrentDirectory switch can be
// restored immediately after creation.
uint32_t s = K32CreateProcessNative(translatedPath, &kh, cmdline);
@@ -1469,11 +1468,11 @@ __declspec(dllexport) BOOL SetCurrentDirectoryA(const char* lpPathName) {
__declspec(dllexport) DWORD GetCurrentDirectoryA(DWORD nBufferLength, char* lpBuffer) {
if (!lpBuffer || nBufferLength == 0) {
// Return required size (including NUL). Max CWD is 512 bytes + "C:\\".
// Return required size (including NUL). Max CWD is 512 bytes + "C:\\".
return 515;
}
// Kernel returns native "N:/path". Present it as a Win32 drive letter.
// Kernel returns native "N:/path". Present it as a Win32 drive letter.
char raw[512];
uint32_t s = K32GetCwdNative(raw, sizeof(raw), NULL);
if (s != 0) { gLastError = 1; return 0; }
+91 -91
View File
@@ -1,94 +1,94 @@
; syscall_nr.inc
SYS_EXIT_PROCESS EQU 0
SYS_EXIT_THREAD EQU 1
SYS_CREATE_PROCESS EQU 2
SYS_WAIT_FOR_PROCESS EQU 3
SYS_GET_PROCESS_EXIT_CODE EQU 4
SYS_KILL_PROCESS EQU 5
SYS_GET_PROCESS_LIST EQU 6
SYS_GET_PROCESS_PID EQU 7
SYS_CREATE_THREAD EQU 8
SYS_WAIT_THREAD EQU 9
SYS_GET_CURRENT_TID EQU 10
SYS_GET_CURRENT_PID EQU 11
SYS_SET_THREAD_PRIORITY EQU 12
SYS_YIELD EQU 13
SYS_SLEEP EQU 14
SYS_SET_USER_APC_DISPATCHER EQU 15
SYS_APC_RETURN EQU 16
SYS_ALLOC EQU 17
SYS_FREE EQU 18
SYS_REALLOC EQU 19
SYS_CLOSE_HANDLE EQU 20
SYS_MUTEX_CREATE EQU 21
SYS_MUTEX_ACQUIRE EQU 22
SYS_MUTEX_TRY_ACQUIRE EQU 23
SYS_MUTEX_RELEASE EQU 24
SYS_SEM_CREATE EQU 25
SYS_SEM_WAIT EQU 26
SYS_SEM_TRY_WAIT EQU 27
SYS_SEM_SIGNAL EQU 28
SYS_EVENT_CREATE EQU 29
SYS_EVENT_SIGNAL EQU 30
SYS_EVENT_CLEAR EQU 31
SYS_EVENT_WAIT EQU 32
SYS_QUEUE_CREATE EQU 33
SYS_QUEUE_SEND EQU 34
SYS_QUEUE_RECV EQU 35
SYS_PUBLISH_QUEUE EQU 36
SYS_OPEN_NAMED_QUEUE EQU 37
SYS_QUEUE_DUPLICATE EQU 38
SYS_NAMED_QUEUE_OWNER_PID EQU 39
SYS_OPEN_FILE EQU 40
SYS_CREATE_FILE EQU 41
SYS_READ_FILE EQU 42
SYS_WRITE_FILE EQU 43
SYS_READ_FILE_ASYNC EQU 44
SYS_WRITE_FILE_ASYNC EQU 45
SYS_CANCEL_IO EQU 46
SYS_SEEK_FILE EQU 47
SYS_GET_FILE_POS EQU 48
SYS_GET_FILE_SIZE EQU 49
SYS_TRUNCATE_FILE EQU 50
SYS_DELETE_FILE EQU 51
SYS_RENAME_FILE EQU 52
SYS_OPEN_DIR EQU 53
SYS_READ_DIR EQU 54
SYS_CREATE_DIR EQU 55
SYS_REMOVE_DIR EQU 56
SYS_SET_CWD EQU 57
SYS_GET_CWD EQU 58
SYS_WRITE_CONSOLE EQU 59
SYS_SCREEN_BLIT EQU 60
SYS_SCREEN_CLEAR EQU 61
SYS_SCREEN_GET_SIZE EQU 62
SYS_SCREEN_PUT_CHAR EQU 63
SYS_KB_POLL EQU 64
SYS_KB_IS_KEY_DOWN EQU 65
SYS_KB_READ_CHAR EQU 66
SYS_KB_READ_SCANCODE EQU 67
SYS_KB_GET_MODIFIERS EQU 68
SYS_MOUSE_POLL EQU 69
SYS_MOUSE_READ EQU 70
SYS_MOUSE_GET_POS EQU 71
SYS_GET_TICK EQU 72
SYS_DEBUG_PRINT EQU 73
SYS_QUERY_TRAP_FRAME EQU 74
SYS_SOCKET EQU 75
SYS_BIND EQU 76
SYS_LISTEN EQU 77
SYS_ACCEPT EQU 78
SYS_CONNECT EQU 79
SYS_SEND EQU 80
SYS_RECV EQU 81
SYS_SHUTDOWN EQU 82
SYS_SEND_TO EQU 83
SYS_RECV_FROM EQU 84
SYS_RESOLVE_HOST EQU 85
SYS_SET_SOCKET_OPTION EQU 86
SYS_GET_SOCKET_OPTION EQU 87
SYS_POLL EQU 88
SYS_GET_MEMORY_STATUS EQU 89
SYS_EXIT_PROCESS EQU 0
SYS_EXIT_THREAD EQU 1
SYS_CREATE_PROCESS EQU 2
SYS_WAIT_FOR_PROCESS EQU 3
SYS_GET_PROCESS_EXIT_CODE EQU 4
SYS_KILL_PROCESS EQU 5
SYS_GET_PROCESS_LIST EQU 6
SYS_GET_PROCESS_PID EQU 7
SYS_CREATE_THREAD EQU 8
SYS_WAIT_THREAD EQU 9
SYS_GET_CURRENT_TID EQU 10
SYS_GET_CURRENT_PID EQU 11
SYS_SET_THREAD_PRIORITY EQU 12
SYS_YIELD EQU 13
SYS_SLEEP EQU 14
SYS_SET_USER_APC_DISPATCHER EQU 15
SYS_APC_RETURN EQU 16
SYS_ALLOC EQU 17
SYS_FREE EQU 18
SYS_REALLOC EQU 19
SYS_CLOSE_HANDLE EQU 20
SYS_MUTEX_CREATE EQU 21
SYS_MUTEX_ACQUIRE EQU 22
SYS_MUTEX_TRY_ACQUIRE EQU 23
SYS_MUTEX_RELEASE EQU 24
SYS_SEM_CREATE EQU 25
SYS_SEM_WAIT EQU 26
SYS_SEM_TRY_WAIT EQU 27
SYS_SEM_SIGNAL EQU 28
SYS_EVENT_CREATE EQU 29
SYS_EVENT_SIGNAL EQU 30
SYS_EVENT_CLEAR EQU 31
SYS_EVENT_WAIT EQU 32
SYS_QUEUE_CREATE EQU 33
SYS_QUEUE_SEND EQU 34
SYS_QUEUE_RECV EQU 35
SYS_PUBLISH_QUEUE EQU 36
SYS_OPEN_NAMED_QUEUE EQU 37
SYS_QUEUE_DUPLICATE EQU 38
SYS_NAMED_QUEUE_OWNER_PID EQU 39
SYS_OPEN_FILE EQU 40
SYS_CREATE_FILE EQU 41
SYS_READ_FILE EQU 42
SYS_WRITE_FILE EQU 43
SYS_READ_FILE_ASYNC EQU 44
SYS_WRITE_FILE_ASYNC EQU 45
SYS_CANCEL_IO EQU 46
SYS_SEEK_FILE EQU 47
SYS_GET_FILE_POS EQU 48
SYS_GET_FILE_SIZE EQU 49
SYS_TRUNCATE_FILE EQU 50
SYS_DELETE_FILE EQU 51
SYS_RENAME_FILE EQU 52
SYS_OPEN_DIR EQU 53
SYS_READ_DIR EQU 54
SYS_CREATE_DIR EQU 55
SYS_REMOVE_DIR EQU 56
SYS_SET_CWD EQU 57
SYS_GET_CWD EQU 58
SYS_WRITE_CONSOLE EQU 59
SYS_SCREEN_BLIT EQU 60
SYS_SCREEN_CLEAR EQU 61
SYS_SCREEN_GET_SIZE EQU 62
SYS_SCREEN_PUT_CHAR EQU 63
SYS_KB_POLL EQU 64
SYS_KB_IS_KEY_DOWN EQU 65
SYS_KB_READ_CHAR EQU 66
SYS_KB_READ_KEY EQU 67
SYS_KB_GET_MODIFIERS EQU 68
SYS_MOUSE_POLL EQU 69
SYS_MOUSE_READ EQU 70
SYS_MOUSE_GET_POS EQU 71
SYS_GET_TICK EQU 72
SYS_DEBUG_PRINT EQU 73
SYS_QUERY_TRAP_FRAME EQU 74
SYS_SOCKET EQU 75
SYS_BIND EQU 76
SYS_LISTEN EQU 77
SYS_ACCEPT EQU 78
SYS_CONNECT EQU 79
SYS_SEND EQU 80
SYS_RECV EQU 81
SYS_SHUTDOWN EQU 82
SYS_SEND_TO EQU 83
SYS_RECV_FROM EQU 84
SYS_RESOLVE_HOST EQU 85
SYS_SET_SOCKET_OPTION EQU 86
SYS_GET_SOCKET_OPTION EQU 87
SYS_POLL EQU 88
SYS_GET_MEMORY_STATUS EQU 89
SYS_MAX EQU 90
SYS_MAX EQU 90
+3 -3
View File
@@ -83,8 +83,8 @@ SYSCALL_STUB2 ApcReturn, SYS_APC_RETURN
; ---------------------------------------------------------------------------
PUBLIC SysUserApcDispatcher
SysUserApcDispatcher PROC EXPORT
; Kernel enters here with RSP pointing at SYS_USER_APC_FRAME. There is no
; return address because this is an IRET redirection. Preserve RBX because
; Kernel enters here with RSP pointing at SYS_USER_APC_FRAME. There is no
; return address because this is an IRET redirection. Preserve RBX because
; the original user context resumes after SysApcReturn.
push rbx
lea rbx, [rsp + 8] ; original injected RSP = frame pointer
@@ -183,7 +183,7 @@ SYSCALL_STUB6 ScreenPutChar, SYS_SCREEN_PUT_CHAR
SYSCALL_STUB2 KbPoll, SYS_KB_POLL
SYSCALL_STUB2 KbIsKeyDown, SYS_KB_IS_KEY_DOWN
SYSCALL_STUB2 KbReadChar, SYS_KB_READ_CHAR
SYSCALL_STUB2 KbReadScancode, SYS_KB_READ_SCANCODE
SYSCALL_STUB2 KbReadKey, SYS_KB_READ_KEY
SYSCALL_STUB2 KbGetModifiers, SYS_KB_GET_MODIFIERS
SYSCALL_STUB2 MousePoll, SYS_MOUSE_POLL