\r
KERNEL_SRC = ../../Kernel/\r
\r
-KERNEL_OBJ := logging.o adt.o lib.o\r
+KERNEL_OBJ := logging.o adt.o lib.o drvutil.o\r
KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o vfs/nodecache.o vfs/mount.o vfs/memfile.o\r
KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o\r
KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o\r
\r
-OBJ := main.o helpers.o threads.o video.o keyboard.o mouse.o nativefs.o vfs_handle.o\r
+OBJ := main.o helpers.o threads.o syscalls.o\r
+OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o\r
OBJ += $(addprefix $(KERNEL_SRC),$(KERNEL_OBJ))\r
\r
OBJ := $(addsuffix .$(PLATFORM),$(OBJ))\r
\r
CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/\r
-CFLAGS += -Wall\r
-LDFLAGS += -lSDL -lSDLmain\r
+CFLAGS += -Wall -g\r
+LDFLAGS += -lSDL -lSDLmain -g\r
\r
ifeq ($(PLATFORM),win)\r
BIN := ../AcessKernel.exe\r
// Ignored, kernel debug goes to stdout
}
-void *Heap_Allocate(int Count, const char *File, int Line)
+void *Heap_Allocate(const char *File, int Line, int ByteCount)
{
- return malloc(Count);
+ return malloc(ByteCount);
}
tPAddr MM_GetPhysAddr(tVAddr VAddr)
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
-
+#undef CLONE_VM
#define _MODULE_NAME_ "NativeKernel"
#define BITS (sizeof(intptr_t)*8)
#define _HEAP_H_
// NOP (stdlib.h defines the heap functions)
+// Heap_Allocate is used in _strdup
+extern void *Heap_Allocate(const char *File, int Line, int ByteCount);
#endif
+/*
+ * Acess2 Native Kernel
+ *
+ * Keyboard Driver
+ */
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include <tpl_drv_common.h>
+#include <tpl_drv_keyboard.h>
+#include "ui.h"
+
+// === PROTOTYPES ===
+ int NativeKeyboard_Install(char **Arguments);
+ int NativeKeyboard_IOCtl(tVFS_Node *Node, int Id, void *Data);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, 0x0100, NativeKeyboard, NativeKeyboard_Install, NULL, NULL);
+tDevFS_Driver gKB_DevInfo = {
+ NULL, "NativeKeyboard",
+ {
+ .NumACLs = 0,
+ .Size = 0,
+ .IOCtl = NativeKeyboard_IOCtl
+ }
+};
+
+// === CODE ===
+/**
+ * \brief Install the keyboard driver
+ */
+int NativeKeyboard_Install(char **Arguments)
+{
+ DevFS_AddDevice( &gKB_DevInfo );
+ return MODULE_ERR_OK;
+}
+
+static const char * const csaIOCTL_NAMES[] = {
+ DRV_IOCTLNAMES,
+ DRV_KEYBAORD_IOCTLNAMES,
+ NULL
+};
+
+/**
+ * \fn int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief Calls an IOCtl Command
+ */
+int NativeKeyboard_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+ switch(Id)
+ {
+ BASE_IOCTLS(DRV_TYPE_KEYBOARD, "NativeKeyboard", 0x10000, csaIOCTL_NAMES);
+
+ // Sets the Keyboard Callback
+ case KB_IOCTL_SETCALLBACK:
+ // Sanity Check
+ if(Threads_GetUID() != 0)
+ return 0;
+ // Can only be set once
+ if(gUI_KeyboardCallback != NULL) return 0;
+ // Set Callback
+ gUI_KeyboardCallback = Data;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
*/
#include <stdio.h>
#include <stdlib.h>
-#include <SDL/SDL.h>
+// === IMPORTS ===
+extern int UI_Initialise(int Width, int Height);
+extern int VFS_Init(void);
+extern int Video_Install(char **Arguments);
+extern int NativeKeyboard_Install(char **Arguments);
+extern int VT_Install(char **Arguments);
+
+// === CODE ===
int main(int argc, char *argv[])
{
+ // Parse command line settings
+
+ // Start UI subsystem
+ UI_Initialise(640, 480);
+
+ // Initialise VFS
+ VFS_Init();
+ // - Start IO Drivers
+ Video_Install(NULL);
+ NativeKeyboard_Install(NULL);
+ // - Start VTerm
+ {
+ char *args[] = {
+ "Video=NativeVideo",
+ "Input=NativeKeyboard",
+ NULL
+ };
+ VT_Install(args);
+ }
+
+ // Start syscall server
+ for( ;; )
+ {
+ UI_Redraw();
+ }
+
return 0;
}
+void AcessNative_Exit(void)
+{
+ // TODO: Close client applications too
+ exit(0);
+}
--- /dev/null
+/*
+ * Acess2 Native Kernel
+ * - Acess kernel emulation on another OS using SDL and UDP
+ *
+ * Syscall Server
+ */
+#include <acess.h>
+#include "../syscalls.h"
+
+// === TYPES ===
+typedef int (*tSyscallHandler)(const char *Format, void *Args);
+
+// === MACROS ===
+#define SYSCALL3(_name, _call, _fmtstr, _t1, _t2, _t3) int _name(const char *fmt,void*args){\
+ _t1 a1;_t2 a2;_t3 a3;\
+ if(strcmp(fmt,_fmtstr)!=0)return 0;\
+ a1 = *(_t1*)args;args+=sizeof(_t1);\
+ a2 = *(_t2*)args;args+=sizeof(_t2);\
+ a3 = *(_t3*)args;args+=sizeof(_t3);\
+ return _call(a1,a2,a3);\
+}
+
+#define SYSCALL2(_name, _call, _fmtstr, _t1, _t2) int _name(const char *fmt,void*args){\
+ _t1 a1;_t2 a2;\
+ if(strcmp(fmt,_fmtstr)!=0)return 0;\
+ a1 = *(_t1*)args;args+=sizeof(_t1);\
+ a2 = *(_t2*)args;args+=sizeof(_t2);\
+ return _call(a1,a2);\
+}
+
+#define SYSCALL1V(_name, _call, _fmtstr, _t1) int _name(const char *fmt, void*args){\
+ _t1 a1;\
+ if(strcmp(fmt,_fmtstr)!=0)return 0;\
+ a1 = *(_t1*)args;args+=sizeof(_t1);\
+ _call(a1);\
+ return 0;\
+}
+
+// === CODE ===
+int Syscall_Null(const char *Format, void *Args)
+{
+ return 0;
+}
+
+SYSCALL2(Syscall_Open, VFS_Open, "di", const char *, int);
+SYSCALL1V(Syscall_Close, VFS_Close, "i", int);
+SYSCALL3(Syscall_Read, VFS_Read, "iid", int, int, void *);
+SYSCALL3(Syscall_Write, VFS_Write, "iid", int, int, const void *);
+
+
+const tSyscallHandler caSyscalls[] = {
+ Syscall_Null,
+ Syscall_Open,
+ Syscall_Close,
+ Syscall_Read,
+ Syscall_Write
+};
+const int ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]);
+/**
+ * \brief Recieve a syscall structure from the server code
+ */
+tRequestHeader *SyscallRecieve(tRequestHeader *Request)
+{
+ char formatString[Request->NParams+1];
+ char *inData = (char*)&Request->Params[Request->NParams+Request->NReturn];
+ int argListLen = 0;
+ int i, retVal;
+
+ if( Request->CallID > ciNumSyscalls ) {
+ return NULL;
+ }
+
+ // Get size of argument list
+ for( i = 0; i < Request->NParams; i ++ )
+ {
+ switch(Request->Params[i].Type)
+ {
+ case ARG_TYPE_VOID:
+ formatString[i] = '-';
+ break;
+ case ARG_TYPE_INT32:
+ formatString[i] = 'i';
+ argListLen += sizeof(Uint32);
+ break;
+ case ARG_TYPE_INT64:
+ formatString[i] = 'I';
+ argListLen += sizeof(Uint64);
+ break;
+ case ARG_TYPE_DATA:
+ formatString[i] = 'd';
+ argListLen += sizeof(void*);
+ break;
+ default:
+ return NULL; // ERROR!
+ }
+ }
+
+ {
+ char argListData[argListLen];
+ argListLen = 0;
+ // Build argument list
+ for( i = 0; i < Request->NParams; i ++ )
+ {
+ switch(Request->Params[i].Type)
+ {
+ case ARG_TYPE_VOID:
+ break;
+ case ARG_TYPE_INT32:
+ *(Uint32*)&argListData[argListLen] = *(Uint32*)inData;
+ argListLen += sizeof(Uint32);
+ inData += sizeof(Uint32);
+ break;
+ case ARG_TYPE_INT64:
+ *(Uint64*)&argListData[argListLen] = *(Uint64*)inData;
+ argListLen += sizeof(Uint64);
+ inData += sizeof(Uint64);
+ break;
+ case ARG_TYPE_DATA:
+ case ARG_TYPE_STRING:
+ *(void**)&argListData[argListLen] = *(void**)inData;
+ argListLen += sizeof(void*);
+ inData += sizeof(void*);
+ break;
+ }
+ }
+
+ retVal = caSyscalls[Request->CallID](formatString, argListData);
+ }
+
+ return NULL;
+}
} tThread;
// === GLOBALS ===
-tThread *gpThreads;
-__thread tThread *gpCurrentThread;
+tThread gThread_Zero = {
+ State: 1,
+ ThreadName: "ThreadZero"
+};
+tThread *gpThreads = &gThread_Zero;
+__thread tThread *gpCurrentThread = &gThread_Zero;
// === CODE ===
tThread *Threads_GetThread(int TID)
Uint *Threads_GetCfgPtr(int Index)
{
+ if( Index < 0 || Index >= NUM_CFG_ENTRIES )
+ return NULL;
+ if( !gpCurrentThread )
+ return NULL;
return &gpCurrentThread->Config[Index];
}
--- /dev/null
+/*
+ * Acess2
+ * AcessNative Kernel
+ *
+ * ui.h - User Interface common header
+ */
+#ifndef _UI_H_
+#define _UI_H_
+
+extern const int giUI_Width;
+extern const int giUI_Height;
+extern const int giUI_Pitch;
+extern const Uint32 * const gUI_Framebuffer;
+
+extern void UI_SetWindowDims(int Width, int Height);
+extern void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap);
+extern void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H);
+extern void UI_FillBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 Value);
+extern void UI_Redraw(void);
+
+typedef void (*tUI_KeybardCallback)(Uint32 Key);
+extern tUI_KeybardCallback gUI_KeyboardCallback;
+
+#endif
--- /dev/null
+/*
+ * Acess2 Native Kernel
+ *
+ * SDL User Interface
+ */
+#include <SDL/SDL.h>
+#define const
+#include "ui.h"
+#undef const
+#include <tpl_drv_keyboard.h>
+
+// === IMPORTS ===
+extern void AcessNative_Exit(void);
+
+// === PROTOTYPES ===
+ int UI_Initialise(int MaxWidth, int MaxHeight);
+ int UI_MainThread(void *Unused);
+void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap);
+void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H);
+void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value);
+void UI_Redraw(void);
+
+// === GLOBALS ===
+SDL_Surface *gScreen;
+SDL_Thread *gInputThread;
+ int giUI_Width = 0;
+ int giUI_Height = 0;
+ int giUI_Pitch = 0;
+tUI_KeybardCallback gUI_KeyboardCallback;
+Uint32 gUI_Keymap[2][SDLK_LAST]; // Upper/Lower case
+
+// === FUNCTIONS ===
+int UI_Initialise(int MaxWidth, int MaxHeight)
+{
+ // Changed when the video mode is set
+ giUI_Width = MaxWidth;
+ giUI_Height = MaxHeight;
+
+ // Start main thread
+ gInputThread = SDL_CreateThread(UI_MainThread, NULL);
+
+ return 0;
+}
+
+Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode)
+{
+ Uint8 *keystate = SDL_GetKeyState(NULL);
+ int shiftState = 0;
+ Uint32 ret = 0;
+
+ if( keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT] )
+ shiftState = 1;
+
+ // Fast return
+ if( gUI_Keymap[shiftState][Sym] )
+ return gUI_Keymap[shiftState][Sym];
+
+ // How nice of you, a unicode value
+ if( Unicode )
+ {
+ ret = Unicode;
+ }
+ // Ok, we need to do work :(
+ else
+ {
+ switch(Sym)
+ {
+ case SDLK_UP: ret = KEY_UP; break;
+ case SDLK_DOWN: ret = KEY_DOWN; break;
+ case SDLK_LEFT: ret = KEY_LEFT; break;
+ case SDLK_RIGHT:ret = KEY_RIGHT;break;
+ case SDLK_CAPSLOCK: ret = KEY_CAPSLOCK; break;
+ case SDLK_F1: ret = KEY_F1; break;
+ case SDLK_F2: ret = KEY_F2; break;
+ case SDLK_F3: ret = KEY_F3; break;
+ case SDLK_F4: ret = KEY_F4; break;
+ case SDLK_F5: ret = KEY_F5; break;
+ case SDLK_F6: ret = KEY_F6; break;
+ case SDLK_F7: ret = KEY_F7; break;
+ case SDLK_F8: ret = KEY_F8; break;
+ case SDLK_F9: ret = KEY_F9; break;
+ case SDLK_F10: ret = KEY_F10; break;
+ case SDLK_F11: ret = KEY_F11; break;
+ case SDLK_F12: ret = KEY_F12; break;
+ default:
+ printf("Unhandled key code %i\n", Sym);
+ break;
+ }
+ }
+
+ gUI_Keymap[shiftState][Sym] = ret;
+ return ret;
+}
+
+int UI_MainThread(void *Unused)
+{
+ SDL_Event event;
+ Uint32 acess_sym;
+
+ SDL_Init(SDL_INIT_VIDEO);
+
+ // Set up video
+ gScreen = SDL_SetVideoMode(giUI_Width, giUI_Height, 32, 0);
+ if( !gScreen ) {
+ fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", giUI_Width, giUI_Height, SDL_GetError());
+ SDL_Quit();
+ exit(2);
+ }
+ SDL_WM_SetCaption("Acess2", "Acess2");
+
+ giUI_Width = gScreen->w;
+ giUI_Height = gScreen->h;
+ giUI_Pitch = gScreen->pitch;
+
+ SDL_EnableUNICODE(1);
+
+ for( ;; )
+ {
+ while(SDL_PollEvent(&event))
+ {
+ switch(event.type)
+ {
+ case SDL_QUIT:
+ AcessNative_Exit();
+ return 0;
+
+ case SDL_KEYDOWN:
+ acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
+ event.key.keysym.unicode);
+
+ if( gUI_KeyboardCallback )
+ gUI_KeyboardCallback(acess_sym);
+ break;
+
+ case SDL_KEYUP:
+ acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
+ event.key.keysym.unicode);
+
+ //if( gUI_KeyboardCallback )
+ // gUI_KeyboardCallback(0x80000000|acess_sym);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap)
+{
+ SDL_Surface *tmp;
+ SDL_Rect dstRect;
+
+ tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4,
+ 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
+ SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE);
+
+ dstRect.x = DstX; dstRect.y = DstY;
+
+ SDL_BlitSurface(tmp, NULL, gScreen, &dstRect);
+
+ SDL_FreeSurface(tmp);
+}
+
+void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H)
+{
+ SDL_Rect srcRect;
+ SDL_Rect dstRect;
+
+ srcRect.x = SrcX; srcRect.y = SrcY;
+ srcRect.w = W; srcRect.h = H;
+ dstRect.x = DstX; dstRect.y = DstY;
+
+ SDL_BlitSurface(gScreen, &srcRect, gScreen, &dstRect);
+}
+
+void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value)
+{
+ SDL_Rect dstRect;
+
+ dstRect.x = X; dstRect.y = Y;
+ dstRect.w = W; dstRect.h = H;
+
+ SDL_FillRect(gScreen, &dstRect, Value);
+}
+
+void UI_Redraw(void)
+{
+ // No-Op, we're not using double buffering
+}
+/*
+ * Acess2 Native Kernel
+ *
+ * Video Driver
+ */
+#define VERSION ((0<<8)|10)
+#include <acess.h>
+#include <vfs.h>
+#include <fs_devfs.h>
+#include <modules.h>
+#include <tpl_drv_video.h>
+#include "ui.h"
+
+// === PROTOTYPES ===
+ int Video_Install(char **Arguments);
+Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+ int Video_IOCtl(tVFS_Node *Node, int ID, void *Data);
+// --- 2D Acceleration Functions --
+void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
+void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);
+
+// === GLOBALS ===
+//MODULE_DEFINE(0, VERSION, NativeVideo, Video_Install, NULL, NULL);
+tDevFS_Driver gVideo_DriverStruct = {
+ NULL, "NativeVideo",
+ {
+ .Read = Video_Read,
+ .Write = Video_Write,
+ .IOCtl = Video_IOCtl
+ }
+};
+ int giVideo_DriverID;
+ int giVideo_CurrentFormat;
+// --- 2D Video Stream Handlers ---
+tDrvUtil_Video_2DHandlers gVideo_2DFunctions = {
+ NULL,
+ Video_2D_Fill,
+ Video_2D_Blit
+};
+
+// === CODE ===
+int Video_Install(char **Arguments)
+{
+ // Install Device
+ giVideo_DriverID = DevFS_AddDevice( &gVideo_DriverStruct );
+ if(giVideo_DriverID == -1)
+ return MODULE_ERR_MISC;
+
+ return MODULE_ERR_OK;
+}
+
+/**
+ * \brief Read from framebuffer (unimplemented)
+ */
+Uint64 Video_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+ return 0;
+}
+
+/**
+ * \brief Write to the framebuffer
+ */
+Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+ int i;
+ ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+
+ if(Buffer == NULL) {
+ LEAVE('i', 0);
+ return 0;
+ }
+ // Text Mode
+ switch( giVideo_CurrentFormat )
+ {
+ case VIDEO_BUFFMT_TEXT:
+ {
+ tVT_Char *chars = Buffer;
+ // int pitch = giUI_Pitch;
+ int widthInChars = giUI_Width/giVT_CharWidth;
+ int heightInChars = giUI_Height/giVT_CharHeight;
+ int x, y;
+ Uint32 tmpBuf[giVT_CharHeight*giVT_CharWidth];
+
+ Length /= sizeof(tVT_Char);
+ Offset /= sizeof(tVT_Char);
+
+ x = Offset % widthInChars;
+ y = Offset / widthInChars;
+
+ // Sanity Check
+ if( Offset > (Uint64)(heightInChars*widthInChars) ) {
+ LEAVE('i', 0);
+ return 0;
+ }
+ if(y >= heightInChars) {
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ // Clip to screen size
+ if( (int)Offset + (int)Length > heightInChars*widthInChars ) {
+ Log_Debug("Video", "%i + %i > %i*%i (%i)",
+ (int)Offset, (int)Length, heightInChars, widthInChars, heightInChars*widthInChars);
+ Length = heightInChars*widthInChars - Offset;
+ Log_Notice("Video", "Clipping write size to %i characters", (int)Length);
+ }
+
+ // Print characters
+ for( i = 0; i < (int)Length; i++ )
+ {
+ VT_Font_Render(
+ chars->Ch,
+ //dest + x*giVT_CharWidth, pitch,
+ tmpBuf, giVT_CharWidth,
+ VT_Colour12to24(chars->BGCol),
+ VT_Colour12to24(chars->FGCol)
+ );
+ UI_BlitBitmap(
+ x*giVT_CharWidth, y*giVT_CharHeight,
+ giVT_CharWidth, giVT_CharHeight,
+ tmpBuf
+ );
+
+ chars ++;
+ x ++;
+ if( x >= widthInChars ) {
+ x = 0;
+ y ++;
+ //dest += pitch*giVT_CharHeight;
+ }
+ }
+ Length *= sizeof(tVT_Char);
+ }
+ break;
+
+ case VIDEO_BUFFMT_FRAMEBUFFER:
+ {
+ int startX, startY;
+
+ if(giUI_Pitch*giUI_Height < Offset+Length)
+ {
+ Log_Warning("Video", "Video_Write - Framebuffer Overflow");
+ LEAVE('i', 0);
+ return 0;
+ }
+
+ LOG("buffer = %p", Buffer);
+ LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length);
+
+ startX = Offset % giUI_Width;
+ startY = Offset / giUI_Width;
+
+ if( Length + startX < giUI_Width )
+ {
+ // Single line
+ UI_BlitBitmap(
+ startX, startY,
+ Length, 1,
+ Buffer);
+ }
+ else
+ {
+ // First scanline (partial or full)
+ UI_BlitBitmap(
+ startX, startY,
+ giUI_Width - startX, 1,
+ Buffer);
+
+ Length -= giUI_Width - startX;
+ Buffer += giUI_Width - startX;
+
+ // Middle Scanlines
+ for( i = 0; i < Length / giUI_Height; i ++ )
+ {
+ UI_BlitBitmap(
+ 0, startY + i,
+ giUI_Width, 1,
+ Buffer);
+ Buffer += giUI_Width;
+ }
+
+ // Final scanline (partial)
+ if( Length % giUI_Height )
+ {
+ UI_BlitBitmap(
+ 0, startY + i,
+ Length % giUI_Height, 1,
+ Buffer);
+ }
+ }
+ }
+ break;
+
+ case VIDEO_BUFFMT_2DSTREAM:
+ Length = DrvUtil_Video_2DStream(
+ NULL, // Single framebuffer, so Ent is unused
+ Buffer, Length, &gVideo_2DFunctions, sizeof(gVideo_2DFunctions)
+ );
+ break;
+
+ default:
+ LEAVE('i', -1);
+ return -1;
+ }
+
+ // Tell the UI to blit
+ UI_Redraw();
+
+ LEAVE('X', Length);
+ return Length;
+}
+
+const char * const csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
+/**
+ * \brief Handle messages to the device
+ */
+int Video_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+ int ret;
+ tVideo_IOCtl_Mode *mode = Data;
+ switch(ID)
+ {
+ BASE_IOCTLS(DRV_TYPE_VIDEO, "NativeVideo", VERSION, csaVIDEO_IOCTLS);
+
+ // Video mode control
+ // - We cheat, and only have one mode
+ case VIDEO_IOCTL_GETSETMODE:
+ return 0;
+ case VIDEO_IOCTL_FINDMODE:
+ case VIDEO_IOCTL_MODEINFO:
+ mode->id = 0;
+ mode->width = giUI_Width;
+ mode->height = giUI_Height;
+ mode->bpp = 32;
+ mode->flags = 0;
+ return 0;
+
+ // Buffer mode
+ case VIDEO_IOCTL_SETBUFFORMAT:
+ ret = giVideo_CurrentFormat;
+ if(Data) {
+ giVideo_CurrentFormat = *(int*)Data;
+ }
+ return ret;
+
+ #if 0
+ case VIDEO_IOCTL_SETCURSOR: // Set cursor position
+ #if !BLINKING_CURSOR
+ if(giVesaCursorX > 0)
+ Vesa_FlipCursor(Node);
+ #endif
+ giVesaCursorX = ((tVideo_IOCtl_Pos*)Data)->x;
+ giVesaCursorY = ((tVideo_IOCtl_Pos*)Data)->y;
+ //Log_Debug("VESA", "Cursor position (%i,%i)", giVesaCursorX, giVesaCursorY);
+ if(
+ giVesaCursorX < 0 || giVesaCursorY < 0
+ || giVesaCursorX >= gpVesaCurMode->width/giVT_CharWidth
+ || giVesaCursorY >= gpVesaCurMode->height/giVT_CharHeight)
+ {
+ #if BLINKING_CURSOR
+ if(giVesaCursorTimer != -1) {
+ Time_RemoveTimer(giVesaCursorTimer);
+ giVesaCursorTimer = -1;
+ }
+ #endif
+ giVesaCursorX = -1;
+ giVesaCursorY = -1;
+ }
+ else {
+ #if BLINKING_CURSOR
+ // Log_Debug("VESA", "Updating timer %i?", giVesaCursorTimer);
+ if(giVesaCursorTimer == -1)
+ giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Node);
+ #else
+ Vesa_FlipCursor(Node);
+ #endif
+ }
+ //Log_Debug("VESA", "Cursor position (%i,%i) Timer %i", giVesaCursorX, giVesaCursorY, giVesaCursorTimer);
+ return 0;
+ #endif
+
+ case VIDEO_IOCTL_REQLFB: // Request Linear Framebuffer
+ return 0;
+ }
+ return 0;
+}
+
+// --- 2D Acceleration Functions --
+void Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)
+{
+ UI_FillBitmap(X, Y, W, H, Colour);
+}
+
+void Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)
+{
+ UI_BlitFramebuffer(DstX, DstY, SrcX, SrcY, W, H);
+}
fread(&dword, 1, 4, fp);
fseek(fp, 0, SEEK_SET);
- printf("dword = %08x\n", dword);
if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
fmt = &gElf_FormatDef;
int i;
tBinary *bin;
- printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n",
- SymbolName, Value);
+ //printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n",
+ // SymbolName, Value);
// Search builtins
// - Placed first to override smartarses that define their own versions
for(bin = gLoadedBinaries; bin; bin = bin->Next)
{
if( !bin->Ready ) continue;
- printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
+ //printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
return 1;
}
- printf("Binary_GetSymbol: RETURN 0, not found\n");
+ //printf("Binary_GetSymbol: RETURN 0, not found\n");
return 0;
}
Elf32_Phdr *phtab;\r
int i, j;\r
int iPageCount;\r
- uint32_t max, base = -1;\r
+ uint32_t max, base;\r
uint32_t addr;\r
uint32_t baseDiff = 0;\r
\r
//ret->Interpreter = NULL;\r
\r
// Prescan for base and size\r
+ max = 0;\r
+ base = 0xFFFFFFFF;\r
for( i = 0; i < hdr.phentcount; i ++)\r
{\r
if( phtab[i].Type != PT_LOAD )\r
addr = phtab[i].VAddr + baseDiff;\r
\r
if( AllocateMemory( addr, phtab[i].MemSize ) ) {\r
+ fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n",\r
+ addr, phtab[i].MemSize);\r
+ free( phtab );\r
return NULL;\r
}\r
\r
printf("base = %p\n", base);
if( !base ) return 127;
+ printf("==============================\n");
+ for(i = 0; i < appArgc; i ++)
+ printf("\"%s\" ", appArgv[i]);
+ printf("\n");
__asm__ __volatile__ (
"push %0;\n\t"
"push %1;\n\t"
#else
uintptr_t base, ofs, size;
uintptr_t end = -1;
- const int PAGE_SIZE = 0x1000;
+ static const int PAGE_SIZE = 0x1000;
size = (ByteCount + PAGE_SIZE - 1) / PAGE_SIZE;
size *= PAGE_SIZE;
}
#endif
+ // Open TCP Connection
+ gSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Open UDP Connection
- gSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ //gSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (gSocket == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
client.sin_port = htons(0);
client.sin_addr.s_addr = htonl(0x7F00001);
+ if( connect(gSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0 )
+ {
+ fprintf(stderr, "Cannot connect to server (localhost:%i)\n", SERVER_PORT);
+ perror("_InitSyscalls");
+ #if __WIN32__
+ closesocket(gSocket);
+ WSACleanup();
+ #else
+ close(gSocket);
+ #endif
+ exit(0);
+ }
+
+ #if 0
// Bind
if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
{
#endif
exit(0);
}
+ #endif
+
return 0;
}
int requestLen;
int i;
+ if( gSocket == INVALID_SOCKET )
+ {
+ _InitSyscalls();
+ }
+
// See ../syscalls.h for details of request format
requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue);
case 'i': value->Type = ARG_TYPE_INT32; break;
case 'I': value->Type = ARG_TYPE_INT64; break;
case 'd': value->Type = ARG_TYPE_DATA; break;
+ case 's': value->Type = ARG_TYPE_DATA; break;
default:
+ fprintf(stderr, __FILE__" SendRequest: Unknown output type '%c'\n",
+ Output[i]->Type);
return -1;
}
value->Length = Output[i]->Length;
memcpy(data, Output[i]->Data, Output[i]->Length);
+ value ++;
data += Output[i]->Length;
}
case 'I': value->Type = ARG_TYPE_INT64; break;
case 'd': value->Type = ARG_TYPE_DATA; break;
default:
+ fprintf(stderr, " SendRequest: Unknown input type '%c'\n",
+ Input[i]->Type);
return -1;
}
value->Length = Input[i]->Length;
+ value ++;
+ }
+ #if 0
+ printf("value = %p\n", value);
+ {
+ for(i=0;i<requestLen;i++)
+ {
+ printf("%02x ", ((uint8_t*)request)[i]);
+ if( i % 16 == 15 ) printf("\n");
+ }
+ printf("\n");
}
+ #endif
// Send it off
- send(gSocket, request, requestLen, 0);
+ if( send(gSocket, request, requestLen, 0) != requestLen ) {
+ fprintf(stderr, "SendRequest: send() failed\n");
+ perror("SendRequest - send");
+ free( request );
+ return -1;
+ }
// Wait for a response
- recv(gSocket, request, requestLen, 0);
+ requestLen = recv(gSocket, request, requestLen, 0);
+ if( requestLen < 0 ) {
+ fprintf(stderr, "SendRequest: revc() failed\n");
+ perror("SendRequest - recv");
+ free( request );
+ return -1;
+ }
// Parse response out
+ if( request->NParams != NumInput ) {
+ fprintf(stderr, "SendRequest: Unexpected number of values retured (%i, exp %i)\n",
+ request->NParams, NumInput
+ );
+ free( request );
+ return -1;
+ }
+
+ // Free memory
+ free( request );
return 0;
}
#include <stdarg.h>
#include <string.h>
#include "request.h"
+#include "../syscalls.h"
// === Types ===
* ?d: Bi-directional buffer (Preceded by valid size), buffer contents
* are returned
*/
-int _Syscall(const char *ArgTypes, ...)
+void _Syscall(int SyscallID, const char *ArgTypes, ...)
{
va_list args;
- int outCount = 0;
- int inCount = 0;
+ int outCount;
+ int inCount;
const char *str;
-
tOutValue **output;
tInValue **input;
// Get data size
va_start(args, ArgTypes);
str = ArgTypes;
+ outCount = 0;
+ inCount = 0;
while(*str)
{
int dir;
str = ReadEntry(NULL, NULL, &dir, str, args);
- if( !str ) break;
+ if( !str ) {
+ fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
+ exit(127);
+ }
// Out!
if( dir & 1 ) outCount ++;
output = malloc( outCount*sizeof(tOutValue*) );
input = malloc( inCount*sizeof(tInValue*) );
- // - re-zero so they can be used as indicies
- outCount = 0;
- inCount = 0;
-
// Fill `output` and `input`
va_start(args, ArgTypes);
str = ArgTypes;
+ // - re-zero so they can be used as indicies
+ outCount = 0;
+ inCount = 0;
while(*str)
{
tOutValue *outParam;
va_end(args);
// Send syscall request
-
+ if( SendRequest(SyscallID, outCount, output, inCount, input) ) {
+ fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
+ exit(127);
+ }
// Clean up
while(outCount--) free(output[outCount]);
free(output);
while(inCount--) free(input[inCount]);
free(input);
-
- return 0;
}
// --- VFS Calls
int open(const char *Path, int Flags) {
- return _Syscall(">s >i", Path, Flags);
+ int ret = 0;
+ _Syscall(SYS_OPEN, "<i >s >i", &ret, Path, Flags);
+ return ret;
}
void close(int FD) {
- _Syscall(">i", FD);
+ _Syscall(SYS_CLOSE, ">i", FD);
}
size_t read(int FD, size_t Bytes, void *Dest) {
- return _Syscall(">i >i <d", FD, Bytes, Bytes, Dest);
+ int ret = 0;
+ _Syscall(SYS_READ, "<i >i >i <d", &ret, FD, Bytes, Bytes, Dest);
+ return ret;
}
size_t write(int FD, size_t Bytes, void *Src) {
- return _Syscall(">i >i >d", FD, Bytes, Bytes, Src);
+ int ret = 0;
+ _Syscall(SYS_WRITE, "<i >i >i >d", &ret, FD, Bytes, Bytes, Src);
+ return ret;
}
int seek(int FD, int64_t Ofs, int Dir) {
- return _Syscall(">i >I >i", FD, Ofs, Dir);
+ int ret = 0;
+ _Syscall(SYS_SEEK, "<i >i >I >i", &ret, FD, Ofs, Dir);
+ return ret;
}
uint64_t tell(int FD) {
uint64_t ret;
- _Syscall("<I >i", &ret, FD);
+ _Syscall(SYS_TELL, "<I >i", &ret, FD);
return ret;
}
int ioctl(int fd, int id, void *data) {
+ int ret = 0;
// NOTE: 1024 byte size is a hack
- return _Syscall(">i >i ?d", fd, id, 1024, data);
+ _Syscall(SYS_IOCTL, "<i >i >i ?d", &ret, fd, id, 1024, data);
+ return ret;
}
int finfo(int fd, t_sysFInfo *info, int maxacls) {
- return _Syscall(">i <d >i", fd, maxacls*sizeof(t_sysFInfo), info, maxacls);
+ int ret = 0;
+ _Syscall(SYS_FINFO, "<i >i <d >i",
+ &ret, fd,
+ sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
+ maxacls);
+ return ret;
}
int readdir(int fd, char *dest) {
- return _Syscall(">i <s", fd, dest);
+ int ret = 0;
+ _Syscall(SYS_READDIR, "<i >i <d", &ret, fd, 256, dest);
+ return ret;
}
int _SysOpenChild(int fd, char *name, int flags) {
- return _Syscall(">i >s >i", fd, name, flags);
+ int ret = 0;
+ _Syscall(SYS_OPENCHILD, "<i >i >s >i", &ret, fd, name, flags);
+ return ret;
}
int _SysGetACL(int fd, t_sysACL *dest) {
- return _Syscall(">i <d", fd, sizeof(t_sysACL), dest);
+ int ret = 0;
+ _Syscall(SYS_GETACL, "<i >i <d", &ret, fd, sizeof(t_sysACL), dest);
+ return ret;
}
int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
- return _Syscall(">s >s >s >s", Device, Directory, Type, Options);
+ int ret = 0;
+ _Syscall(SYS_MOUNT, "<i >s >s >s >s", &ret, Device, Directory, Type, Options);
+ return ret;
}
enum eSyscalls {
SYS_NULL,
- SYS_OPEN
+ SYS_OPEN,
+ SYS_CLOSE,
+ SYS_READ,
+ SYS_WRITE,
+ SYS_SEEK,
+ SYS_TELL,
+ SYS_IOCTL,
+ SYS_FINFO,
+ SYS_READDIR,
+ SYS_OPENCHILD,
+ SYS_GETACL,
+ SYS_MOUNT,
+ N_SYSCALLS
};
enum eArgumentTypes {
ARG_TYPE_VOID,
ARG_TYPE_INT32,
ARG_TYPE_INT64,
+ ARG_TYPE_STRING,
ARG_TYPE_DATA
};
#include <acess.h>
#include <threads.h>
+#define TRACE_LOCKS 1
+
extern int GetCPUNum(void);
// === CODE ===
__ASM__("cli");
Lock->IF = IF;
#endif
+
+ #if TRACE_LOCKS
+ Log_Log("LOCK", "%p locked by %p\n", Lock, __builtin_return_address(0));
+ #endif
}
/**
* \brief Release a short lock
*/
void SHORTREL(struct sShortSpinlock *Lock)
{
+ #if TRACE_LOCKS
+ Log_Log("LOCK", "%p released by %p\n", Lock, __builtin_return_address(0));
+ #endif
+
#if STACKED_LOCKS
if( Lock->Depth ) {
Lock->Depth --;
// Scan Arguments
if(Arguments)
{
- char **args = Arguments;
- char *arg, *opt, *val;
- for( ; (arg = *args); args++ )
+ char **args;
+ const char *arg;
+ for(args = Arguments; (arg = *args); args++ )
{
+ char data[strlen(arg)+1];
+ char *opt = data;
+ char *val;
+
+ val = strchr(arg, '=');
+ strcpy(data, arg);
+ if( val ) {
+ data[ val - arg ] = '\0';
+ val ++;
+ }
Log_Debug("VTerm", "Argument '%s'", arg);
- opt = arg;
- val = arg + strpos(arg, '='); *val++ = '\0';
if( strcmp(opt, "Video") == 0 ) {
gsVT_OutputDevice = val;
gVT_Terminals[i].CurColour = DEFAULT_COLOUR;
gVT_Terminals[i].WritePos = 0;
gVT_Terminals[i].ViewPos = 0;
+ gVT_Terminals[i].ReadingThread = -1;
// Initialise
VT_int_ChangeMode( &gVT_Terminals[i],
void VT_InitOutput()
{
giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE);
- if(giVT_InputDevHandle == -1) {
+ if(giVT_OutputDevHandle == -1) {
Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice);
return ;
}
void VT_InitInput()
{
giVT_InputDevHandle = VFS_Open(gsVT_InputDevice, VFS_OPENFLAG_READ);
- if(giVT_InputDevHandle == -1) return ;
+ if(giVT_InputDevHandle == -1) {
+ Log_Warning("VTerm", "Can't open the input device '%s'", gsVT_InputDevice);
+ return ;
+ }
VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack);
}
KB_IOCTL_SETCALLBACK\r
};\r
\r
+#define DRV_KEYBAORD_IOCTLNAMES "getset_repeat_rate", "getset_repeat_delay", "set_callback"\r
+\r
/**\r
* \brief Callback type for KB_IOCTL_SETCALLBACK\r
* \param Key Unicode character code for the pressed key (with bit 31\r
*/\r
VIDEO_IOCTL_REQLFB\r
};\r
+#define DRV_VIDEO_IOCTLNAMES "getset_mode", "find+mode", "mode_info", "set_buf_format", "set_cursor", "request_framebuffer"\r
\r
/**\r
* \brief Mode Structure used in IOCtl Calls\r
srv->ConnectionsTail = conn;
if(!srv->NewConnections)
srv->NewConnections = conn;
- SHORTLOCK(&srv->lConnections);
+ SHORTREL(&srv->lConnections);
// Send the SYN ACK
hdr->Flags |= TCP_FLAG_ACK;
[global _start]
[global start]
[extern main]
+[extern _exit]
_start:
start:
call main
- mov eax, ebx ; Set Argument 1 to Return Value
- xor eax, eax ; Set EAX to SYS_EXIT (0)
- int 0xAC
+ push eax
+ call _exit
jmp $ ; This should never be reached