fix the return value of LdrLoadImage, make use of __declspec(dllexport), speed up blitting, add dummy TEB, redesign the syscall interface, fix stack alignent so movaps doesn't crash, implement a shitload of win32, implement a simple shell, add bink as video.exe 😎, minor kmain.c cleanup, HAL now supports power-off events, implemented \b in hal_screen.c, fix many deadlocks, add wait for exit event for processes, completely new error codes, small readme changes.
This commit is contained in:
1 parent
c13dd99150
commit
7f4052f41c
33 files changed
+6396
-735
No files matched your search
+159
-29
@@ -1,47 +1,177 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
void BitBlt(int x, int y, int w, int h, const uint32_t* pixels);
|
||||
void* HeapAlloc(void* heap, unsigned long flags, size_t size);
|
||||
int HeapFree(void* heap, unsigned long flags, void* mem);
|
||||
// ---------------------------------------------------------------------------
|
||||
// Win32 imports
|
||||
// ---------------------------------------------------------------------------
|
||||
_Noreturn void ExitProcess(unsigned int code);
|
||||
_Noreturn void ExitThread(unsigned long code);
|
||||
void OutputDebugStringA(const char* s);
|
||||
|
||||
int main() {
|
||||
OutputDebugStringA("Hello from the shell!\n");
|
||||
int width = 300;
|
||||
int height = 300;
|
||||
typedef void* HANDLE;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE)0)
|
||||
#define INFINITE 0xFFFFFFFFUL
|
||||
#define STD_INPUT_HANDLE ((DWORD)-10)
|
||||
|
||||
// Allocate space for uint32_t (4 bytes per pixel)
|
||||
uint32_t* image = (uint32_t *)HeapAlloc(NULL, 0, width * height * sizeof(uint32_t));
|
||||
|
||||
int tileSize = 8;
|
||||
HANDLE GetStdHandle(DWORD nStdHandle);
|
||||
BOOL ReadConsoleA(HANDLE hConsoleInput, void* lpBuffer,
|
||||
DWORD nNumberOfCharsToRead, DWORD* lpNumberOfCharsRead,
|
||||
void* pInputControl);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
uint32_t color1 = 0xFFFFFFFF; // White
|
||||
uint32_t color2 = 0xFF000000; // Black
|
||||
typedef struct {
|
||||
DWORD cb;
|
||||
char* lpReserved;
|
||||
char* lpDesktop;
|
||||
char* lpTitle;
|
||||
DWORD dwX, dwY, dwXSize, dwYSize;
|
||||
DWORD dwXCountChars, dwYCountChars;
|
||||
DWORD dwFillAttribute, dwFlags;
|
||||
unsigned short wShowWindow, cbReserved2;
|
||||
unsigned char* lpReserved2;
|
||||
HANDLE hStdInput, hStdOutput, hStdError;
|
||||
} STARTUPINFOA;
|
||||
|
||||
int tileX = x / tileSize;
|
||||
int tileY = y / tileSize;
|
||||
typedef struct {
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
DWORD dwProcessId;
|
||||
DWORD dwThreadId;
|
||||
} PROCESS_INFORMATION;
|
||||
|
||||
if ((tileX + tileY) % 2 == 0) {
|
||||
image[y * width + x] = color1;
|
||||
} else {
|
||||
image[y * width + x] = color2;
|
||||
}
|
||||
BOOL CreateProcessA(const char* lpApp, char* lpCmdLine,
|
||||
void* lpPA, void* lpTA, BOOL bInherit,
|
||||
DWORD dwFlags, void* lpEnv, const char* lpDir,
|
||||
STARTUPINFOA* lpSI, PROCESS_INFORMATION* lpPI);
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMs);
|
||||
BOOL GetExitCodeProcess(HANDLE hProcess, DWORD* lpExitCode);
|
||||
BOOL CloseHandle(HANDLE hObject);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
static void print(const char* s) {
|
||||
OutputDebugStringA(s);
|
||||
}
|
||||
|
||||
static void printUInt(uint32_t n) {
|
||||
char buf[12];
|
||||
int i = 0;
|
||||
if (n == 0) { print("0"); return; }
|
||||
while (n > 0) { buf[i++] = (char)('0' + n % 10); n /= 10; }
|
||||
char rev[12];
|
||||
int j = 0;
|
||||
while (i > 0) rev[j++] = buf[--i];
|
||||
rev[j] = '\0';
|
||||
print(rev);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Line editor
|
||||
// Reads one character at a time via ReadConsoleA, echoes it, handles
|
||||
// backspace, returns on Enter.
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MAX_CMD 256
|
||||
|
||||
static void readLine(HANDLE hIn, char* buf, int len) {
|
||||
int pos = 0;
|
||||
while (1) {
|
||||
char c;
|
||||
DWORD nRead;
|
||||
ReadConsoleA(hIn, &c, 1, &nRead, 0);
|
||||
if (!nRead) continue;
|
||||
|
||||
if (c == '\r' || c == '\n') {
|
||||
print("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((c == '\b' || c == 127) && pos > 0) {
|
||||
pos--;
|
||||
print("\b \b");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c < 0x20 || c == 127)
|
||||
continue;
|
||||
|
||||
if (pos < len - 1) {
|
||||
buf[pos++] = c;
|
||||
char echo[2] = { c, '\0' };
|
||||
print(echo);
|
||||
}
|
||||
}
|
||||
buf[pos] = '\0';
|
||||
}
|
||||
|
||||
// Pass the 32-bit buffer directly to BitBlt
|
||||
BitBlt(600, 400, width, height, image);
|
||||
// ---------------------------------------------------------------------------
|
||||
// Trim leading/trailing spaces in-place; returns pointer into buf.
|
||||
// ---------------------------------------------------------------------------
|
||||
static char* trim(char* s) {
|
||||
while (*s == ' ') s++;
|
||||
int len = (int)strlen(s);
|
||||
while (len > 0 && s[len - 1] == ' ') len--;
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
// for (size_t i = 0; i < 1000000000; i++) {
|
||||
// // burn!
|
||||
// }
|
||||
// ---------------------------------------------------------------------------
|
||||
// Run one command. Returns 1 if the shell should exit.
|
||||
// ---------------------------------------------------------------------------
|
||||
static int runCommand(const char* cmd) {
|
||||
if (!cmd || *cmd == '\0')
|
||||
return 0;
|
||||
|
||||
OutputDebugStringA("Goodbye from the shell!\n");
|
||||
if (strcmp(cmd, "exit") == 0)
|
||||
return 1;
|
||||
|
||||
STARTUPINFOA si;
|
||||
PROCESS_INFORMATION pi;
|
||||
unsigned char* p = (unsigned char*)&si;
|
||||
for (size_t i = 0; i < sizeof(si); i++) p[i] = 0;
|
||||
si.cb = (DWORD)sizeof(si);
|
||||
|
||||
if (!CreateProcessA(cmd, 0, 0, 0, 0, 0, 0, 0, &si, &pi)) {
|
||||
print("shell: could not launch '");
|
||||
print(cmd);
|
||||
print("'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
DWORD exitCode = 0;
|
||||
GetExitCodeProcess(pi.hProcess, &exitCode);
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
if (exitCode != 0) {
|
||||
print("shell: '");
|
||||
print(cmd);
|
||||
print("' exited with code ");
|
||||
printUInt(exitCode);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Entry point
|
||||
// ---------------------------------------------------------------------------
|
||||
int main() {
|
||||
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
char lineBuf[MAX_CMD];
|
||||
|
||||
print("shell: ready\n");
|
||||
|
||||
while (1) {
|
||||
print("> ");
|
||||
readLine(hIn, lineBuf, MAX_CMD);
|
||||
if (runCommand(trim(lineBuf)))
|
||||
break;
|
||||
}
|
||||
|
||||
print("shell: goodbye\n");
|
||||
ExitProcess(0);
|
||||
}
|
||||
Reference in new issue
Block a user