Fixes to Libc, Doxygen Comments and VTerm layout
authorJohn Hodge <[email protected]>
Mon, 26 Oct 2009 04:54:31 +0000 (12:54 +0800)
committerJohn Hodge <[email protected]>
Mon, 26 Oct 2009 04:54:31 +0000 (12:54 +0800)
- Fixed Libc so that zlib could compile against it (still some bugs to get rid of)
- Fixed doxygen commenting
- Fixed a bug in the Makefile (used %* instead of $*)
- Changed the structure of the VTerm driver to facilitate kernel modesetting properly

37 files changed:
Kernel/Makefile
Kernel/arch/x86/lib.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.c
Kernel/arch/x86/time.c
Kernel/debug.c
Kernel/drv/kb.c
Kernel/drv/kb_kbdus.h
Kernel/drv/vterm.c
Kernel/include/modules.h
Kernel/include/syscalls.h
Kernel/include/syscalls.inc.asm
Kernel/include/tpl_drv_keyboard.h
Kernel/include/tpl_drv_video.h
Kernel/lib.c
Kernel/messages.c
Kernel/proc.c [deleted file]
Kernel/system.c
Kernel/threads.c
Kernel/vfs.c [deleted file]
Kernel/vfs/fs/devfs.c
Kernel/vfs/fs/ext2.c
Kernel/vfs/fs/fat.c
Kernel/vfs/fs/fs_ext2.h
Makefile.cfg
Modules/BochsVBE/bochsvbe.c
Modules/Makefile.tpl
Modules/NE2000/Makefile
Usermode/Applications/CLIShell_src/main.c
Usermode/Applications/init_src/main.c
Usermode/Applications/login_src/main.c
Usermode/Libraries/libc.so_src/fileIO.c
Usermode/Libraries/libc.so_src/string.c
Usermode/include/acess/sys.h
Usermode/include/stdio.h
Usermode/include/stdlib.h
Usermode/include/string.h

index 45d2f02..c538da5 100644 (file)
@@ -24,7 +24,7 @@ OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
 OBJ += drv/fifo.o drv/dma.o drv/pci.o drv/vterm.o drv/vga.o drv/kb.o
 OBJ += $(addprefix drv/, $(addsuffix .o,$(DRIVERS)))
 OBJ := $(addsuffix .$(ARCH), $(OBJ))
-MODS += $(addprefix ../Modules/, $(addsuffix .o.$(ARCH),$(MODULES)))
+MODS += $(addprefix ../Modules/, $(addsuffix .xo.$(ARCH),$(MODULES)))
 BIN = ../Acess2.$(ARCH).bin
 
 DEPFILES  = $(filter %.o.$(ARCH),$(OBJ))
@@ -61,6 +61,9 @@ $(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile
        @$(MAKEDEP) $(CPPFLAGS) -MT $@ -o $*.d.$(ARCH) $<
 #      endif
 
+%.xo.$(ARCH):
+       @make -C $* all
+
 include/syscalls.h:    syscalls.lst Makefile
        php GenSyscalls.php
 
index 7e79c71..8b86145 100644 (file)
@@ -86,7 +86,8 @@ int memcmp(const void *m1, const void *m2, Uint Num)
 }
 
 /**
- * \fn void *memcpy(void *Dest, void *Src, Uint Num)
+ * \fn void *memcpy(void *Dest, const void *Src, Uint Num)
+ * \brief Copy \a Num bytes from \a Src to \a Dest
  */
 void *memcpy(void *Dest, const void *Src, Uint Num)
 {
@@ -102,7 +103,8 @@ void *memcpy(void *Dest, const void *Src, Uint Num)
        return Dest;
 }
 /**
- * \fn void *memcpyd(void *Dest, void *Src, Uint Num)
+ * \fn void *memcpyd(void *Dest, const void *Src, Uint Num)
+ * \brief Copy \a Num DWORDs from \a Src to \a Dest
  */
 void *memcpyd(void *Dest, const void *Src, Uint Num)
 {
index f5b8959..d7d1d81 100644 (file)
@@ -174,7 +174,7 @@ void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs)
 }
 
 /**
- * \fn void MM_DumpTables(Uint Start, Uint End)
+ * \fn void MM_DumpTables(tVAddr Start, tVAddr End)
  * \brief Dumps the layout of the page tables
  */
 void MM_DumpTables(tVAddr Start, tVAddr End)
index 5132f82..5301401 100644 (file)
@@ -386,7 +386,7 @@ Uint Proc_MakeUserStack()
 
 
 /**
- * \fn void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, char **ArgV, char **EnvP, int DataSize)
+ * \fn void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize)
  * \brief Starts a user task
  */
 void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize)
@@ -457,6 +457,8 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **
  * \fn int Proc_Demote(Uint *Err, int Dest, tRegs *Regs)
  * \brief Demotes a process to a lower permission level
  * \param Err  Pointer to user's errno
+ * \param Dest New Permission Level
+ * \param Regs Pointer to user's register structure
  */
 int Proc_Demote(Uint *Err, int Dest, tRegs *Regs)
 {
index 79ea4d0..cfe2f03 100644 (file)
@@ -87,10 +87,10 @@ void Time_Interrupt()
        inb(0x71);      // Just throw away contents.
 }
 
+#if 0
 /**
  * \fn void Time_TimerThread()
  */
-#if 0
 void Time_TimerThread()
 {
        Sint64  next;
index 99a236e..72621cc 100644 (file)
@@ -5,16 +5,21 @@
 #include <common.h>
 #include <stdarg.h>
 
-// === MACROS ===
-#define E9(ch) __asm__ __volatile__ ("outb %%al, $0xe9"::"a"(((Uint8)ch)))
-
 // === IMPORTS ===
 extern void Threads_Dump();
 
 // === GLOBALS ===
  int   gDebug_Level = 0;
+ int   giDebug_KTerm = -1;
 
 // === CODE ===
+static void E9(char ch)
+{
+       if(giDebug_KTerm != -1)
+               VFS_Write(giDebug_KTerm, 1, &ch);
+       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
+}
+
 static void E9_Str(char *Str)
 {
        while(*Str)     E9(*Str++);
@@ -190,6 +195,13 @@ void Panic(char *Fmt, ...)
        for(;;) __asm__ __volatile__ ("hlt");
 }
 
+void Debug_SetKTerminal(char *File)
+{
+       if(giDebug_KTerm != -1)
+               VFS_Close(giDebug_KTerm);
+       giDebug_KTerm = VFS_Open(File, VFS_OPENFLAG_WRITE);
+}
+
 void Debug_Enter(char *FuncName, char *ArgTypes, ...)
 {
        va_list args;
index d6124e7..608b058 100644 (file)
@@ -29,8 +29,8 @@ tDevFS_Driver gKB_DevInfo = {
        NULL, "PS2Keyboard",
        {
        .NumACLs = 0,
-       .Size = -1,
-       .Read = KB_Read,
+       .Size = 0,
+       //.Read = KB_Read,
        .IOCtl = KB_IOCtl
        }
 };
@@ -122,8 +122,8 @@ void KB_IRQHandler()
                if( !gbaKB_States[KEY_LSHIFT] && !gbaKB_States[KEY_RSHIFT] )
                        gbKB_ShiftState = 0;
                
-               KB_AddBuffer(KEY_KEYUP);
-               KB_AddBuffer(ch);
+               if(ch != 0 && gKB_Callback)
+                       gKB_Callback( ch & 0x80000000 );
                
                return;
        }
@@ -140,7 +140,7 @@ void KB_IRQHandler()
        }
 
        // Ignore Non-Printable Characters
-       if(ch == 0 || ch & 0x80)                return;
+       if(ch == 0)             return;
        
        // --- Check for Kernel Magic Combos
        if(gbaKB_States[KEY_LCTRL] && gbaKB_States[KEY_LALT])
@@ -157,6 +157,7 @@ void KB_IRQHandler()
        {
                switch(ch)
                {
+               case 0: break;
                case '`':       ch = '~';       break;
                case '1':       ch = '!';       break;
                case '2':       ch = '@';       break;
@@ -185,48 +186,7 @@ void KB_IRQHandler()
                }
        }
        
-       if(gKB_Callback)        gKB_Callback(ch);
-}
-
-/**
- * \fn void KB_AddBuffer(char ch)
- * \brief Add to the keyboard ring buffer
- */
-void KB_AddBuffer(char ch)
-{
-       // Add to buffer
-       gaKB_Buffer[ giKB_InsertPoint++ ] = ch;
-       // - Wrap
-       if( giKB_InsertPoint == KB_BUFFER_SIZE )        giKB_InsertPoint = 0;
-       // - Force increment read pointer
-       if( giKB_InsertPoint == giKB_ReadPoint )        giKB_ReadPoint ++;
-}
-
-/**
- * \fn Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest)
- * \brief Read from the ring buffer
- * \param Node Unused
- * \param Offset       Unused (Character Device)
- * \param Length       Number of bytes to read
- * \param Dest Destination
- */
-Uint64 KB_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Dest)
-{
-        int    pos = 0;
-       char    *dstbuf = Dest;
-       
-       if(giKB_InUse)  return -1;
-       giKB_InUse = 1;
-       
-       while(giKB_ReadPoint != giKB_InsertPoint && pos < Length)
-       {
-               dstbuf[pos++] = gaKB_Buffer[ giKB_ReadPoint++ ];
-               if( giKB_ReadPoint == KB_BUFFER_SIZE )  giKB_InsertPoint = 0;
-       }
-       
-       giKB_InUse = 0;
-       
-       return Length;
+       if(gKB_Callback && ch != 0)     gKB_Callback(ch);
 }
 
 /**
index 94e515a..4010bbe 100644 (file)
@@ -46,6 +46,7 @@ Uint8 gpKBDUS2[256] = {
 /*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
 /*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
 };\r
+// - 0xE1 Prefixed\r
 Uint8  gpKBDUS3[256] = {\r
 //     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\r
 /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-F\r
index 0f5cf8c..f8a649a 100644 (file)
@@ -6,40 +6,48 @@
 #include <modules.h>
 #include <tpl_drv_video.h>
 #include <tpl_drv_keyboard.h>
+#include <tpl_drv_terminal.h>
+#include <errno.h>
 
 // === CONSTANTS ===
+#define VERSION        ((0<<8)|(50))
+
 #define        NUM_VTS 4
-#define MAX_INPUT_CHARS        64
-#define VT_SCROLLBACK  1       // 4 Screens of text
-#define DEFAULT_OUTPUT "/Devices/VGA"
-#define DEFAULT_INPUT  "/Devices/PS2Keyboard"
+#define MAX_INPUT_CHARS32      64
+#define MAX_INPUT_CHARS8       (MAX_INPUT_CHARS32*4)
+#define VT_SCROLLBACK  1       // 2 Screens of text
+#define DEFAULT_OUTPUT "VGA"
+//#define DEFAULT_OUTPUT       "/Devices/BochsGA"
+#define DEFAULT_INPUT  "PS2Keyboard"
 #define        DEFAULT_WIDTH   80
 #define        DEFAULT_HEIGHT  25
 #define        DEFAULT_COLOUR  (VT_COL_BLACK|(0xAAA<<16))
 
 #define        VT_FLAG_HIDECSR 0x01
 
-enum eVT_Modes {
-       VT_MODE_TEXT8,  // UTF-8 Text Mode (VT100 Emulation)
-       VT_MODE_TEXT32, // UTF-32 Text Mode (Acess Native)
-       VT_MODE_8BPP,   // 256 Colour Mode
-       VT_MODE_16BPP,  // 16 bit Colour Mode
-       VT_MODE_24BPP,  // 24 bit Colour Mode
-       VT_MODE_32BPP,  // 32 bit Colour Mode
-       NUM_VT_MODES
+enum eVT_InModes {
+       VT_INMODE_TEXT8,        // UTF-8 Text Mode (VT100 Emulation)
+       VT_INMODE_TEXT32,       // UTF-32 Text Mode (Acess Native)
+       NUM_VT_INMODES
 };
 
 // === TYPES ===
 typedef struct {
-        int    Mode;
-        int    Flags;
-        int    Width, Height;
-        int    ViewPos, WritePos;
-       Uint32  CurColour;
-       char    Name[2];
-        int    InputRead;
-        int    InputWrite;
-       Uint32  InputBuffer[MAX_INPUT_CHARS];
+        int    Mode;   //!< Current Mode (see ::eTplTerminal_Modes)
+        int    Flags;  //!< Flags (see VT_FLAG_*)
+       short   Width;  //!< Virtual Width
+       short   Height; //!< Virtual Height
+       short   RealWidth;      //!< Real Width
+       short   RealHeight;     //!< Real Height
+       
+        int    ViewPos;        //!< View Buffer Offset (Text Only)
+        int    WritePos;       //!< Write Buffer Offset (Text Only)
+       Uint32  CurColour;      //!< Current Text Colour
+       char    Name[2];        //!< Name of the terminal
+       
+        int    InputRead;      //!< Input buffer read position
+        int    InputWrite;     //!< Input buffer write position
+       char    InputBuffer[MAX_INPUT_CHARS8];
        union {
                tVT_Char        *Text;
                Uint32          *Buffer;
@@ -51,9 +59,11 @@ typedef struct {
  int   VT_Install(char **Arguments);
 char   *VT_ReadDir(tVFS_Node *Node, int Pos);
 tVFS_Node      *VT_FindDir(tVFS_Node *Node, char *Name);
+ int   VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data);
 Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
 Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
- int   VT_IOCtl(tVFS_Node *Node, int Id, void *Data);
+ int   VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data);
+void   VT_SetTerminal(int ID);
 void   VT_KBCallBack(Uint32 Codepoint);
 void   VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count);
  int   VT_int_ParseEscape(tVTerm *Term, char *Buffer);
@@ -67,7 +77,7 @@ const Uint16  caVT100Colours[] = {
        };
 
 // === GLOBALS ===
-MODULE_DEFINE(0, 0x0032, VTerm, VT_Install, NULL, NULL);
+MODULE_DEFINE(0, VERSION, VTerm, VT_Install, NULL, DEFAULT_OUTPUT, DEFAULT_INPUT, NULL);
 tDevFS_Driver  gVT_DrvInfo = {
        NULL, "VTerm",
        {
@@ -76,15 +86,22 @@ tDevFS_Driver       gVT_DrvInfo = {
        .Inode = -1,
        .NumACLs = 0,
        .ReadDir = VT_ReadDir,
-       .FindDir = VT_FindDir
+       .FindDir = VT_FindDir,
+       .IOCtl = VT_Root_IOCtl
        }
 };
+// --- Terminals ---
 tVTerm gVT_Terminals[NUM_VTS];
+ int   giVT_CurrentTerminal = 0;
+// --- Driver Handles ---
 char   *gsVT_OutputDevice = NULL;
 char   *gsVT_InputDevice = NULL;
  int   giVT_OutputDevHandle = -2;
  int   giVT_InputDevHandle = -2;
- int   giVT_CurrentTerminal = 0;
+// --- Key States --- (Used for VT Switching/Magic Combos)
+ int   gbVT_CtrlDown = 0;
+ int   gbVT_AltDown = 0;
+ int   gbVT_SysrqDown = 0;
 
 // === CODE ===
 /**
@@ -129,8 +146,8 @@ int VT_Install(char **Arguments)
        }
        
        // Apply Defaults
-       if(!gsVT_OutputDevice)  gsVT_OutputDevice = DEFAULT_OUTPUT;
-       if(!gsVT_InputDevice)   gsVT_InputDevice = DEFAULT_INPUT;
+       if(!gsVT_OutputDevice)  gsVT_OutputDevice = "/Devices/"DEFAULT_OUTPUT;
+       if(!gsVT_InputDevice)   gsVT_InputDevice = "/Devices/"DEFAULT_INPUT;
        
        LOG("Using '%s' as output", gsVT_OutputDevice);
        LOG("Using '%s' as input", gsVT_InputDevice);
@@ -138,7 +155,7 @@ int VT_Install(char **Arguments)
        // Create Nodes
        for( i = 0; i < NUM_VTS; i++ )
        {
-               gVT_Terminals[i].Mode = VT_MODE_TEXT8;
+               gVT_Terminals[i].Mode = TERM_MODE_TEXT;
                gVT_Terminals[i].Flags = 0;
                gVT_Terminals[i].Width = DEFAULT_WIDTH;
                gVT_Terminals[i].Height = DEFAULT_HEIGHT;
@@ -152,11 +169,12 @@ int VT_Install(char **Arguments)
                gVT_Terminals[i].Name[0] = '0'+i;
                gVT_Terminals[i].Name[1] = '\0';
                gVT_Terminals[i].Node.Inode = i;
+               gVT_Terminals[i].Node.ImplPtr = &gVT_Terminals[i];
                gVT_Terminals[i].Node.NumACLs = 0;      // Only root can open virtual terminals
                
                gVT_Terminals[i].Node.Read = VT_Read;
                gVT_Terminals[i].Node.Write = VT_Write;
-               gVT_Terminals[i].Node.IOCtl = VT_IOCtl;
+               gVT_Terminals[i].Node.IOCtl = VT_Terminal_IOCtl;
        }
        
        // Add to DevFS
@@ -173,6 +191,7 @@ void VT_InitOutput()
 {
        giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE);
        LOG("giVT_OutputDevHandle = %x\n", giVT_OutputDevHandle);
+       VT_SetTerminal( 0 );
 }
 
 /**
@@ -228,6 +247,44 @@ tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name)
        return &gVT_Terminals[num].Node;
 }
 
+/**
+ * \fn int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief Control the VTerm Driver
+ */
+int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+        int    len;
+       switch(Id)
+       {
+       case DRV_IOCTL_TYPE:    return DRV_TYPE_MISC;
+       case DRV_IOCTL_IDENT:   memcpy(Data, "VT\0\0", 4);      return 0;
+       case DRV_IOCTL_VERSION: return VERSION;
+       case DRV_IOCTL_LOOKUP:  return 0;
+       
+       case 4: // Get Video Driver
+               if(Data)        strcpy(Data, gsVT_OutputDevice);
+               return strlen(gsVT_OutputDevice);
+       
+       case 5: // Set Video Driver
+               if(!Data)       return -EINVAL;
+               if(Threads_GetUID() != 0)       return -EACCES;
+               
+               len = strlen(Data);
+               
+               free(gsVT_OutputDevice);
+               
+               gsVT_OutputDevice = malloc(len+1);
+               strcpy(gsVT_OutputDevice, Data);
+               
+               VFS_Close(giVT_OutputDevHandle);
+               giVT_OutputDevHandle = -1;
+               
+               VT_InitOutput();
+               return 1;
+       }
+       return 0;
+}
+
 /**
  * \fn Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
  * \brief Read from a virtual terminal
@@ -240,29 +297,29 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        // Check current mode
        switch(term->Mode)
        {
-       case VT_MODE_TEXT8:
+       case TERM_MODE_TEXT:
                while(pos < Length)
                {
                        while(term->InputRead == term->InputWrite)      Threads_Yield();
-                       while(term->InputRead != term->InputWrite)
-                       {
-                               pos += WriteUTF8(Buffer+pos, term->InputBuffer[term->InputRead]);
-                               term->InputRead ++;
-                               term->InputRead %= MAX_INPUT_CHARS;
-                       }
+                       
+                       ((char*)Buffer)[pos] = term->InputBuffer[term->InputRead];
+                       pos ++;
+                       term->InputRead ++;
+                       term->InputRead %= MAX_INPUT_CHARS8;
                }
                break;
        
-       case VT_MODE_TEXT32:
+       case TERM_MODE_FB:
+       case TERM_MODE_OPENGL:
                while(pos < Length)
                {
                        while(term->InputRead == term->InputWrite)      Threads_Yield();
                        while(term->InputRead != term->InputWrite)
                        {
-                               ((Uint32*)Buffer)[pos] = term->InputBuffer[term->InputRead];
+                               ((Uint32*)Buffer)[pos] = ((Uint32*)term->InputBuffer)[term->InputRead];
                                pos ++;
                                term->InputRead ++;
-                               term->InputRead %= MAX_INPUT_CHARS;
+                               term->InputRead %= MAX_INPUT_CHARS32;
                        }
                }
                break;
@@ -283,12 +340,9 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        // Write
        switch( term->Mode )
        {
-       case VT_MODE_TEXT8:
+       case TERM_MODE_TEXT:
                VT_int_PutString(term, Buffer, Length);
                break;
-       case VT_MODE_TEXT32:
-               //VT_int_PutString32(term, Buffer, Length);
-               break;
        }
        
        //LEAVE('i', 0);
@@ -296,14 +350,78 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 }
 
 /**
- * \fn int VT_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \fn int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
  * \brief Call an IO Control on a virtual terminal
  */
-int VT_IOCtl(tVFS_Node *Node, int Id, void *Data)
+int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
 {
+        int    *iData = Data;
+       tVTerm  *term = Node->ImplPtr;
+       switch(Id)
+       {
+       case DRV_IOCTL_TYPE:    return DRV_TYPE_TERMINAL;
+       case DRV_IOCTL_IDENT:   memcpy(Data, "VT\0\0", 4);      return 0;
+       case DRV_IOCTL_VERSION: return VERSION;
+       case DRV_IOCTL_LOOKUP:  return 0;
+       
+       // Get/Set the mode (and apply any changes)
+       case TERM_IOCTL_MODETYPE:
+               if(Data == NULL)        return term->Mode;
+               term->Mode = *iData;
+               // Update the screen dimensions
+               if(giVT_CurrentTerminal == Node->Inode)
+                       VT_SetTerminal( giVT_CurrentTerminal );
+               break;
+       
+       // Get/set the terminal width
+       case TERM_IOCTL_WIDTH:
+               if(Data == NULL)        return term->Width;
+               term->Width = *iData;
+               break;
+       
+       // Get/set the terminal height
+       case TERM_IOCTL_HEIGHT:
+               if(Data == NULL)        return term->Height;
+               term->Height = *iData;
+               break;
+       
+       default:
+               return -1;
+       }
        return 0;
 }
 
+/**
+ * \fn void VT_SetTerminal(int ID)
+ * \brief Set the current terminal
+ */
+void VT_SetTerminal(int ID)
+{
+       tVideo_IOCtl_Mode       mode = {0};
+        int    modeNum;
+       
+       // Create the video mode
+       mode.width = gVT_Terminals[ ID ].Width;
+       mode.height = gVT_Terminals[ ID ].Height;
+       // - Text Mode
+       if(gVT_Terminals[ ID ].Mode == TERM_MODE_TEXT) {
+               mode.bpp = 12;
+               mode.flags = VIDEO_FLAG_TEXT;
+       }
+       // - Framebuffer or 3D
+       else {
+               mode.bpp = 32;
+               mode.flags = 0;
+       }
+       
+       // Set video mode
+       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_FINDMODE, &mode );
+       modeNum = mode.id;
+       gVT_Terminals[ ID ].RealWidth = mode.width;
+       gVT_Terminals[ ID ].RealHeight = mode.height;
+       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETMODE, &modeNum );
+}
+
 /**
  * \fn void VT_KBCallBack(Uint32 Codepoint)
  * \brief Called on keyboard interrupt
@@ -312,12 +430,113 @@ void VT_KBCallBack(Uint32 Codepoint)
 {
        tVTerm  *term = &gVT_Terminals[giVT_CurrentTerminal];
        
-       term->InputBuffer[ term->InputWrite ] = Codepoint;
-       term->InputWrite ++;
-       term->InputWrite %= MAX_INPUT_CHARS;
-       if(term->InputRead == term->InputWrite) {
-               term->InputRead ++;
-               term->InputRead %= MAX_INPUT_CHARS;
+       // How the hell did we get a Codepoint of zero?
+       if(Codepoint == 0)      return;
+       
+       // Key Up
+       if( Codepoint & 0x80000000 )
+       {
+               Codepoint &= 0x7FFFFFFF;
+               switch(Codepoint)
+               {
+               case KEY_LALT:
+               case KEY_RALT:
+                       gbVT_AltDown = 0;
+                       break;
+               case KEY_LCTRL:
+               case KEY_RCTRL:
+                       gbVT_CtrlDown = 0;
+                       break;
+               }
+               return;
+       }
+       
+       switch(Codepoint)
+       {
+       case KEY_LALT:
+       case KEY_RALT:
+               gbVT_AltDown = 1;
+               break;
+       case KEY_LCTRL:
+       case KEY_RCTRL:
+               gbVT_CtrlDown = 1;
+               break;
+       
+       default:
+               if(!gbVT_AltDown || !gbVT_CtrlDown)
+                       break;
+               switch(Codepoint)
+               {
+               case KEY_F1:
+                       giVT_CurrentTerminal = 0;
+                       break;
+               case KEY_F2:
+                       giVT_CurrentTerminal = 0;
+                       break;
+               case KEY_F3:
+                       giVT_CurrentTerminal = 0;
+                       break;
+               case KEY_F4:
+                       giVT_CurrentTerminal = 0;
+                       break;
+               }
+               return;
+       }
+       
+       // Encode key
+       if(term->Mode == TERM_MODE_TEXT)
+       {
+               Uint8   buf[6] = {0};
+                int    len;
+               
+               // Ignore Modifer Keys
+               if(Codepoint > KEY_MODIFIERS)   return;
+               
+               // Get UTF-8/ANSI Encoding
+               switch(Codepoint)
+               {
+               case KEY_LEFT:
+                       buf[0] = '\x1B';        buf[1] = '[';
+                       buf[2] = 'D';   len = 3;
+                       break;
+               case KEY_RIGHT:
+                       buf[0] = '\x1B';        buf[1] = '[';
+                       buf[2] = 'C';   len = 3;
+                       break;
+               default:
+                       len = WriteUTF8( buf, Codepoint );
+                       //Log("Codepoint = 0x%x", Codepoint);
+                       break;
+               }
+               
+               //Log("len = %i, buf = %s", len, buf);
+               
+               // Write
+               if( MAX_INPUT_CHARS8 - term->InputWrite >= len )
+                       memcpy( &term->InputBuffer[term->InputWrite], buf, len );
+               else {
+                       memcpy( &term->InputBuffer[term->InputWrite], buf, MAX_INPUT_CHARS8 - term->InputWrite );
+                       memcpy( &term->InputBuffer[0], buf, len - (MAX_INPUT_CHARS8 - term->InputWrite) );
+               }
+               // Roll the buffer over
+               term->InputWrite += len;
+               term->InputWrite %= MAX_INPUT_CHARS8;
+               if( (term->InputWrite - term->InputRead + MAX_INPUT_CHARS8)%MAX_INPUT_CHARS8 < len ) {
+                       term->InputRead = term->InputWrite + 1;
+                       term->InputRead %= MAX_INPUT_CHARS8;
+               }
+               
+       }
+       else
+       {
+               // Encode the raw UTF-32 Key
+               ((Uint32*)term->InputBuffer)[ term->InputWrite ] = Codepoint;
+               term->InputWrite ++;
+               term->InputWrite %= MAX_INPUT_CHARS32;
+               if(term->InputRead == term->InputWrite) {
+                       term->InputRead ++;
+                       term->InputRead %= MAX_INPUT_CHARS32;
+               }
        }
 }
 
@@ -380,6 +599,7 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
 {
        char    c;
         int    argc = 0, j = 1;
+        int    tmp;
         int    args[4] = {0,0,0,0};
        
        switch(Buffer[0]) {
@@ -393,7 +613,7 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                args[argc] += c-'0';
                                c = Buffer[++j];
                        }
-                       argc ++;
+                       if( j != 1 )    argc ++;
                } while(c == ';');
                
                // Get string (what does this do?)
@@ -406,8 +626,32 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                // Get Command
                if(     ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
                {
-                       switch(c) {
-                       //Clear By Line
+                       switch(c)
+                       {
+                       // Left
+                       case 'D':
+                               if(argc == 1)   tmp = args[0];
+                               else    tmp = 1;
+                               
+                               if( Term->WritePos-(tmp-1) % Term->Width == 0 )
+                                       Term->WritePos -= Term->WritePos % Term->Width;
+                               else
+                                       Term->WritePos -= tmp;
+                               Log("Left by %i", tmp);
+                               break;
+                       
+                       // Right
+                       case 'C':
+                               if(argc == 1)   tmp = args[0];
+                               else    tmp = 1;
+                               if( (Term->WritePos + tmp) % Term->Width == 0 ) {
+                                       Term->WritePos -= Term->WritePos % Term->Width;
+                                       Term->WritePos += Term->Width - 1;
+                               } else
+                                       Term->WritePos += tmp;
+                               break;
+                       
+                       // Clear By Line
                        case 'J':
                                // Clear Screen
                                switch(args[0])
index bf3171b..68c797b 100644 (file)
@@ -17,9 +17,9 @@
 # error "Unknown architecture when determining MODULE_ARCH_ID ('" #ARCH "')"
 #endif
 
-#define MODULE_DEFINE(_flags,_ver,_ident,_entry,_deps...)      char *_DriverDeps_##_ident[]={_deps};\
+#define MODULE_DEFINE(_flags,_ver,_ident,_entry,_deinit,_deps...)      char *_DriverDeps_##_ident[]={_deps};\
        tModule __attribute__ ((section ("KMODULES"),unused)) _DriverInfo_##_ident=\
-       {MODULE_MAGIC,MODULE_ARCH_ID,_flags,_ver,NULL,#_ident,_entry,_DriverDeps_##_ident}
+       {MODULE_MAGIC,MODULE_ARCH_ID,_flags,_ver,NULL,#_ident,_entry,_deinit,_DriverDeps_##_ident}
 
 typedef struct sModule {
        Uint32  Magic;
@@ -29,6 +29,7 @@ typedef struct sModule {
        struct sModule  *Next;
        char    *Name;
         int    (*Init)(char **Arguments);
+       void    (*Deinit)();
        char    **Dependencies; // NULL Terminated List
 } __attribute__((packed)) tModule;
 
index a615c37..2c44d2c 100644 (file)
@@ -26,6 +26,7 @@ enum eSyscalls {
        SYS_EXECVE,     // 17 - Replace the current process
        SYS_LOADBIN,    // 18 - Load a binary into the current address space
        SYS_UNLOADBIN,  // 19 - Unload a loaded binary
+       SYS_LOADMOD,    // 20 - Load a module into the kernel
 
        SYS_GETPHYS = 32,       // 32 - Get the physical address of a page
        SYS_MAP,        // 33 -         Map a physical address
@@ -64,7 +65,7 @@ static const char *cSYSCALL_NAMES[] = {
        "SYS_EXIT","SYS_CLONE","SYS_KILL","SYS_SIGNAL","SYS_YIELD","SYS_SLEEP",
        "SYS_WAIT","SYS_WAITTID","SYS_SETNAME","SYS_GETNAME","SYS_GETTID","SYS_GETPID",
        "SYS_SETPRI","SYS_SENDMSG","SYS_GETMSG","SYS_GETTIME","SYS_SPAWN","SYS_EXECVE",
-       "SYS_LOADBIN","SYS_UNLOADBIN","","","","",
+       "SYS_LOADBIN","SYS_UNLOADBIN","SYS_LOADMOD","","","",
        "","","","","","",
        "","","SYS_GETPHYS","SYS_MAP","SYS_ALLOCATE","SYS_UNMAP",
        "SYS_PREALLOC","SYS_SETFLAGS","SYS_SHAREWITH","SYS_GETUID","SYS_GETGID","SYS_SETUID",
index 9f3973a..178ecbd 100644 (file)
@@ -22,6 +22,7 @@
 %define SYS_EXECVE     17      ; Replace the current process
 %define SYS_LOADBIN    18      ; Load a binary into the current address space
 %define SYS_UNLOADBIN  19      ; Unload a loaded binary
+%define SYS_LOADMOD    20      ; Load a module into the kernel
 
 %define SYS_GETPHYS    32      ; Get the physical address of a page
 %define SYS_MAP        33      ;       Map a physical address
index 9d3e5dc..77f8295 100644 (file)
@@ -27,9 +27,7 @@ enum {
        KEY_ESC = 0x1B,\r
        \r
        KEY_NP_MASK = 0x80,     //End of ASCII Range\r
-       KEY_LCTRL, KEY_RCTRL,\r
-       KEY_LALT, KEY_RALT,\r
-       KEY_LSHIFT, KEY_RSHIFT,\r
+       \r
        KEY_CAPSLOCK,\r
        KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,\r
        KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, \r
@@ -43,6 +41,12 @@ enum {
        KEY_KPEND, KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL,\r
        KEY_WIN, KEY_MENU,\r
        \r
+       // Modifiers\r
+       KEY_MODIFIERS = 0xC0,\r
+       KEY_LCTRL, KEY_RCTRL,\r
+       KEY_LALT, KEY_RALT,\r
+       KEY_LSHIFT, KEY_RSHIFT,\r
+       \r
        KEY_KEYUP = 0xFF\r
 };\r
 \r
index 51f6ea9..b84a97e 100644 (file)
@@ -54,16 +54,21 @@ struct sVideo_IOCtl_Mode {
        Uint8   bpp;    //!< Bits per Pixel\r
        Uint8   flags;  //!< Mode Flags\r
 };\r
-#define VIDEO_FLAG_TEXT        0x1     //!< Text Mode\r
+typedef struct sVideo_IOCtl_Mode       tVideo_IOCtl_Mode;      //!< Mode Type\r
+/**\r
+ * \brief Text Mode Flag\r
+ * \note A text mode should have the ::sVideo_IOCtl_Mode.bpp set to 12\r
+ */\r
+#define VIDEO_FLAG_TEXT        0x1\r
 #define VIDEO_FLAG_SLOW        0x2     //!< Non-accelerated mode\r
+\r
+typedef struct sVideo_IOCtl_Pos        tVideo_IOCtl_Pos;       //!< Position Type\r
 /**\r
  */\r
 struct sVideo_IOCtl_Pos {\r
-       Sint16  x;\r
-       Sint16  y;\r
+       Sint16  x;      //!< X Coordinate\r
+       Sint16  y;      //!< Y Coordinate\r
 };\r
-typedef struct sVideo_IOCtl_Mode       tVideo_IOCtl_Mode;      //!< Mode Type\r
-typedef struct sVideo_IOCtl_Pos        tVideo_IOCtl_Pos;       //!< Mode Type\r
 \r
 /**\r
  * \struct sVT_Char\r
index d3fff54..5bed4ca 100644 (file)
@@ -171,7 +171,7 @@ int DivUp(int num, int dem)
 }
 
 /**
- * \fn int strpos8(char *str, Uint32 search)
+ * \fn int strpos8(const char *str, Uint32 search)
  * \brief Search a string for a UTF-8 character
  */
 int strpos8(const char *str, Uint32 Search)
index 93cf6ca..057f997 100644 (file)
@@ -12,6 +12,8 @@
  * \brief Send an IPC message
  * \param Err  Pointer to the errno variable
  * \param Dest Destination Thread
+ * \param Length       Length of the message
+ * \param Data Message data
  */
 int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
 {
@@ -63,6 +65,9 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data)
 /**
  * \fn int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
  * \brief Gets a message
+ * \param Err  Pointer to \a errno
+ * \param Source       Where to put the source TID
+ * \param Buffer       Buffer to place the message data (set to NULL to just get message length)
  */
 int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer)
 {
diff --git a/Kernel/proc.c b/Kernel/proc.c
deleted file mode 100644 (file)
index e5d9f8f..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * AcessOS Microkernel Version
- * proc.c
- */
-#include <common.h>
-#include <proc.h>
-#include <mm_virt.h>
-#include <errno.h>
-#include <mp.h>
-
-// === CONSTANTS ===
-#define        RANDOM_SEED     0xACE55051
-#define        SWITCH_MAGIC    0xFFFACE55      // There is no code in this area
-#define        DEFAULT_QUANTUM 10
-#define        DEFAULT_TICKETS 5
-#define MAX_TICKETS            10
-#define TIMER_DIVISOR  11931   //~100Hz
-
-// === MACROS ===
-#define TIMER_BASE     1193182 //Hz
-#define MS_PER_TICK_WHOLE      (1000*(TIMER_DIVISOR)/(TIMER_BASE))
-#define MS_PER_TICK_FRACT      ((Uint64)(1000*TIMER_DIVISOR-((Uint64)MS_PER_TICK_WHOLE)*TIMER_BASE)*(0x80000000/TIMER_BASE))
-
-// === IMPORTS ===
-extern Uint    GetEIP();       // start.asm
-extern Uint32  gaInitPageDir[1024];    // start.asm
-extern void    Kernel_Stack_Top;
-
-// === PROTOTYPES ===
-void   Proc_Start();
-static tThread *Proc_int_GetPrevThread(tThread **List, tThread *Thread);
-void   Proc_Scheduler();
-Uint   rand();
-
-// === GLOBALS ===
-// -- Core Thread --
-tThread        gThreadZero = {
-       NULL, 0,        // Next, Lock
-       THREAD_STAT_ACTIVE,     // Status
-       0, 0,   // TID, TGID
-       0, 0,   // UID, GID
-       "ThreadZero",   // Name
-       0, 0, 0,        // ESP, EBP, EIP (Set on switch)
-       (Uint)&gaInitPageDir-KERNEL_BASE,       // CR3
-       (Uint)&Kernel_Stack_Top,        // Kernel Stack (Unused as it it PL0)
-       NULL, NULL,     // Messages, Last Message
-       DEFAULT_QUANTUM, DEFAULT_QUANTUM,       // Quantum, Remaining
-       DEFAULT_TICKETS
-       };
-// -- Processes --
-// --- Locks ---
- int   giThreadListLock = 0;   ///\note NEVER use a heap function while locked
-// --- Current State ---
-tThread        *gCurrentThread = NULL;
- int   giNumActiveThreads = 0;
- int   giTotalTickets = 0;
-Uint   giNextTID = 1;
-// --- Thread Lists ---
-tThread        *gActiveThreads = NULL;         // Currently Running Threads
-tThread        *gSleepingThreads = NULL;       // Sleeping Threads
-tThread        *gDeleteThreads = NULL;         // Threads to delete
-// --- Timekeeping ---
-Uint64 giTicks = 0;
-Uint64 giTimestamp = 0;
-Uint64 giPartMiliseconds = 0;
-// --- Multiprocessing ---
- int   giNumCPUs = 1;
-tMPInfo        *gMPTable = NULL;
-tTSS   *gTSSs = NULL;
-tTSS   gTSS0 = {0};
-
-// === CODE ===
-/**
- * \fn void Proc_Start()
- * \brief Starts the process scheduler
- */
-void Proc_Start()
-{
-       Uint    pos;
-       // -- Initialise Multiprocessing
-       // Find MP Floating Table
-       // - EBDA
-       for(pos = KERNEL_BASE|0x9FC00; pos < (KERNEL_BASE|0xA0000); pos += 16) {
-               if( *(Uint*)(pos) == MPTABLE_IDENT ) {
-                       if(ByteSum( (void*)pos, sizeof(tMPInfo) ) != 0) continue;
-                       gMPTable = (void*)pos;
-                       break;
-               }
-       }
-       // - Last KiB
-       if(!gMPTable) {
-               
-       }
-       // - BIOS ROM
-       if(!gMPTable) {
-               for(pos = KERNEL_BASE|0xF0000; pos < (KERNEL_BASE|0x100000); pos += 16) {
-                       if( *(Uint*)(pos) == MPTABLE_IDENT ) {
-                               if(ByteSum( (void*)pos, sizeof(tMPInfo) ) != 0) continue;
-                               gMPTable = (void*)pos;
-                               break;
-                       }
-               }
-       }
-       
-       // If the MP Table Exists, parse it
-       if(gMPTable)
-       {
-               Panic("Uh oh... MP Table Parsing is unimplemented\n");
-       } else {
-               giNumCPUs = 1;
-               gTSSs = &gTSS0;
-       }
-       
-       // Initialise TSS
-       for(pos=0;pos<giNumCPUs;pos++)
-       {
-               gTSSs[pos].SS0 = 0x10;
-               gTSSs[pos].ESP0 = 0;    // Set properly by scheduler
-               gGDT[9+pos].LimitLow = sizeof(tTSS);
-               gGDT[9+pos].LimitHi = 0;
-               gGDT[9+pos].Access = 0x89;      // Type
-               gGDT[9+pos].Flags = 0x4;
-               gGDT[9+pos].BaseLow = (Uint)&gTSSs[pos] & 0xFFFF;
-               gGDT[9+pos].BaseMid = (Uint)&gTSSs[pos] >> 16;
-               gGDT[9+pos].BaseHi = (Uint)&gTSSs[pos] >> 24;
-       }
-       for(pos=0;pos<giNumCPUs;pos++) {
-               __asm__ __volatile__ ("ltr %%ax"::"a"(0x48+pos*8));
-       }
-       
-       // Set timer frequency
-       outb(0x43, 0x34);       // Set Channel 0, Low/High, Rate Generator
-       outb(0x40, TIMER_DIVISOR&0xFF); // Low Byte of Divisor
-       outb(0x40, (TIMER_DIVISOR>>8)&0xFF);    // High Byte
-       
-       // Clear timestamp
-       giTimestamp = 0;
-       giPartMiliseconds = 0;
-       giTicks = 0;
-       
-       // Create Initial Task
-       gActiveThreads = &gThreadZero;
-       gCurrentThread = &gThreadZero;
-       giTotalTickets = gThreadZero.NumTickets;
-       giNumActiveThreads = 1;
-       
-       // Create Idle Task
-       if(Proc_Clone(0, 0) == 0)
-       {
-               gCurrentThread->ThreadName = "Idle Thread";
-               Proc_SetTickets(0);     // Never called randomly
-               gCurrentThread->Quantum = 1;    // 1 slice quantum
-               for(;;) __asm__ __volatile__ ("hlt");   // Just yeilds
-       }
-       
-       // Start Interrupts (and hence scheduler)
-       __asm__ __volatile__("sti");
-}
-
-/**
- * \fn int Proc_Clone(Uint *Err, Uint Flags)
- * \brief Clone the current process
- */
-int Proc_Clone(Uint *Err, Uint Flags)
-{
-       tThread *newThread;
-       Uint    eip, esp, ebp;
-       
-       __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
-       __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
-       
-       // Create new thread structure
-       newThread = malloc( sizeof(tThread) );
-       if(!newThread) {
-               Warning("Proc_Clone - Out of memory when creating thread\n");
-               *Err = -ENOMEM;
-               return -1;
-       }
-       // Base new thread on old
-       memcpy(newThread, gCurrentThread, sizeof(tThread));
-       // Initialise Memory Space (New Addr space or kernel stack)
-       if(Flags & CLONE_VM) {
-               newThread->TGID = newThread->TID;
-               newThread->CR3 = MM_Clone();
-       } else {
-               Uint    tmpEbp, oldEsp = esp;
-
-               // Create new KStack
-               newThread->KernelStack = MM_NewKStack();
-               // Check for errors
-               if(newThread->KernelStack == 0) {
-                       free(newThread);
-                       return -1;
-               }
-
-               // Get ESP as a used size
-               esp = gCurrentThread->KernelStack - esp;
-               // Copy used stack
-               memcpy( (void*)(newThread->KernelStack - esp), (void*)(gCurrentThread->KernelStack - esp), esp );
-               // Get ESP as an offset in the new stack
-               esp = newThread->KernelStack - esp;
-               // Adjust EBP
-               ebp = newThread->KernelStack - (gCurrentThread->KernelStack - ebp);
-
-               // Repair EBPs & Stack Addresses
-               #if 0
-               tmpEbp = ebp;
-               while(oldEsp < *(Uint*)tmpEbp && *(Uint*)tmpEbp < gCurrentThread->KernelStack)
-               {
-                       *(Uint*)tmpEbp += newThread->KernelStack - gCurrentThread->KernelStack;
-                       tmpEbp = *(Uint*)tmpEbp;
-               }
-               #else   // Catches arguments also, but may trash stack-address-like values
-               for(tmpEbp = esp; tmpEbp < newThread->KernelStack; tmpEbp += 4)
-               {
-                       if(oldEsp < *(Uint*)tmpEbp && *(Uint*)tmpEbp < gCurrentThread->KernelStack)
-                               *(Uint*)tmpEbp += newThread->KernelStack - gCurrentThread->KernelStack;
-               }
-               #endif
-       }
-
-       // Set Pointer, Spinlock and TID
-       newThread->Next = NULL;
-       newThread->IsLocked = 0;
-       newThread->TID = giNextTID++;
-
-       // Clear message list (messages are not inherited)
-       newThread->Messages = NULL;
-       newThread->LastMessage = NULL;
-       
-       // Set remaining (sheduler expects remaining to be correct)
-       newThread->Remaining = newThread->Quantum;
-       
-       // Save core machine state
-       newThread->ESP = esp;
-       newThread->EBP = ebp;
-       eip = GetEIP();
-       if(eip == SWITCH_MAGIC) {
-               outb(0x20, 0x20);       // ACK Timer and return as child
-               return 0;
-       }
-       
-       // Set EIP as parent
-       newThread->EIP = eip;
-       
-       //Log(" Proc_Clone: giTimestamp = %i.%07i", (Uint)giTimestamp, (Uint)giPartMiliseconds/214);
-       
-       // Lock list and add to active
-       LOCK( &giThreadListLock );
-       newThread->Next = gActiveThreads;
-       gActiveThreads = newThread;
-       giNumActiveThreads ++;
-       giTotalTickets += newThread->NumTickets;
-       RELEASE( &giThreadListLock );
-       
-       return newThread->TID;
-}
-
-/**
- * \fn void Proc_Exit()
- * \brief Kill the current process
- */
-void Proc_Exit()
-{
-       tThread *thread;
-       tMsg    *msg;
-       
-       ///\note Double lock is needed due to overlap of locks
-       
-       // Lock thread (stop us recieving messages)
-       LOCK( &gCurrentThread->IsLocked );
-       
-       // Lock thread list
-       LOCK( &giThreadListLock );
-       
-       // Get previous thread on list
-       thread = Proc_int_GetPrevThread( &gActiveThreads, gCurrentThread );
-       if(!thread) {
-               Warning("Proc_Exit - Current thread is not on the active queue");
-               return;
-       }
-       
-       // Clear Message Queue
-       while( gCurrentThread->Messages )
-       {
-               msg = gCurrentThread->Messages->Next;
-               free( gCurrentThread->Messages );
-               gCurrentThread->Messages = msg;
-       }
-       
-       gCurrentThread->Remaining = 0;  // Clear Remaining Quantum
-       gCurrentThread->Quantum = 0;    // Clear Quantum to indicate dead thread
-       thread->Next = gCurrentThread->Next;    // Remove from active
-       
-       // Add to delete queue
-       if(gDeleteThreads) {
-               gCurrentThread->Next = gDeleteThreads;
-               gDeleteThreads = gCurrentThread;
-       } else {
-               gCurrentThread->Next = NULL;
-               gDeleteThreads = gCurrentThread;
-       }
-       
-       giNumActiveThreads --;
-       giTotalTickets -= gCurrentThread->NumTickets;
-       
-       // Mark thread as sleeping
-       gCurrentThread->Status = THREAD_STAT_DEAD;
-       
-       // Release spinlocks
-       RELEASE( &gCurrentThread->IsLocked );   // Released first so that it IS released
-       RELEASE( &giThreadListLock );
-       __asm__ __volatile__ ("hlt");
-}
-
-/**
- * \fn void Proc_Yield()
- * \brief Yield remainder of timeslice
- */
-void Proc_Yield()
-{
-       gCurrentThread->Quantum = 0;
-       __asm__ __volatile__ ("hlt");
-}
-
-/**
- * \fn void Proc_Sleep()
- * \brief Take the current process off the run queue
- */
-void Proc_Sleep()
-{
-       tThread *thread;
-       
-       //Log("Proc_Sleep: %i going to sleep", gCurrentThread->TID);
-       
-       // Acquire Spinlock
-       LOCK( &giThreadListLock );
-       
-       // Get thread before current thread
-       thread = Proc_int_GetPrevThread( &gActiveThreads, gCurrentThread );
-       if(!thread) {
-               Warning("Proc_Sleep - Current thread is not on the active queue");
-               return;
-       }
-       
-       // Don't sleep if there is a message waiting
-       if( gCurrentThread->Messages ) {
-               RELEASE( &giThreadListLock );
-               return;
-       }
-       
-       // Unset remaining timeslices (force a task switch on timer fire)
-       gCurrentThread->Remaining = 0;
-       
-       // Remove from active list
-       thread->Next = gCurrentThread->Next;
-       
-       // Add to Sleeping List (at the top)
-       gCurrentThread->Next = gSleepingThreads;
-       gSleepingThreads = gCurrentThread;
-       
-       // Reduce the active count & ticket count
-       giNumActiveThreads --;
-       giTotalTickets -= gCurrentThread->NumTickets;
-       
-       // Mark thread as sleeping
-       gCurrentThread->Status = THREAD_STAT_SLEEPING;
-       
-       // Release Spinlock
-       RELEASE( &giThreadListLock );
-       
-       __asm__ __volatile__ ("hlt");
-}
-
-/**
- * \fn void Thread_Wake( tThread *Thread )
- * \brief Wakes a sleeping/waiting thread up
- */
-void Thread_Wake(tThread *Thread)
-{
-       tThread *prev;
-       switch(Thread->Status)
-       {
-       case THREAD_STAT_ACTIVE:        break;
-       case THREAD_STAT_SLEEPING:
-               LOCK( &giThreadListLock );
-               prev = Proc_int_GetPrevThread(&gSleepingThreads, Thread);
-               prev->Next = Thread->Next;      // Remove from sleeping queue
-               Thread->Next = gActiveThreads;  // Add to active queue
-               gActiveThreads = Thread;
-               Thread->Status = THREAD_STAT_ACTIVE;
-               RELEASE( &giThreadListLock );
-               break;
-       case THREAD_STAT_WAITING:
-               Warning("Thread_Wake - Waiting threads are not currently supported");
-               break;
-       case THREAD_STAT_DEAD:
-               Warning("Thread_Wake - Attempt to wake dead thread (%i)", Thread->TID);
-               break;
-       default:
-               Warning("Thread_Wake - Unknown process status (%i)\n", Thread->Status);
-               break;
-       }
-}
-
-/**
- * \fn int Proc_Demote(Uint *Err, int Dest, tRegs *Regs)
- * \brief Demotes a process to a lower permission level
- * \param Err  Pointer to user's errno
- */
-int Proc_Demote(Uint *Err, int Dest, tRegs *Regs)
-{
-        int    cpl = Regs->cs & 3;
-       // Sanity Check
-       if(Dest > 3 || Dest < 0) {
-               *Err = -EINVAL;
-               return -1;
-       }
-       
-       // Permission Check
-       if(cpl > Dest) {
-               *Err = -EACCES;
-               return -1;
-       }
-       
-       // Change the Segment Registers
-       Regs->cs = (((Dest+1)<<4) | Dest) - 8;
-       Regs->ss = ((Dest+1)<<4) | Dest;
-       // Check if the GP Segs are GDT, then change them
-       if(!(Regs->ds & 4))     Regs->ds = ((Dest+1)<<4) | Dest;
-       if(!(Regs->es & 4))     Regs->es = ((Dest+1)<<4) | Dest;
-       if(!(Regs->fs & 4))     Regs->fs = ((Dest+1)<<4) | Dest;
-       if(!(Regs->gs & 4))     Regs->gs = ((Dest+1)<<4) | Dest;
-       
-       return 0;
-}
-
-/**
- * \fn void Proc_SetTickets(int Num)
- * \brief Sets the 'priority' of a task
- */
-void Proc_SetTickets(int Num)
-{
-       if(Num < 0)     return;
-       if(Num > MAX_TICKETS)   Num = MAX_TICKETS;
-       
-       Log("Proc_SetTickets: (Num=%i)", Num);
-       Log(" Proc_SetTickets: giTotalTickets = %i", giTotalTickets);
-       LOCK( &giThreadListLock );
-       giTotalTickets -= gCurrentThread->NumTickets;
-       gCurrentThread->NumTickets = Num;
-       giTotalTickets += Num;
-       RELEASE( &giThreadListLock );
-       Log(" Proc_SetTickets: giTotalTickets = %i", giTotalTickets);
-       Log("Proc_SetTickets: RETURN", giTotalTickets);
-}
-
-/**
- * \fn tThread *Proc_GetThread(Uint TID)
- * \brief Gets a thread given its TID
- */
-tThread *Proc_GetThread(Uint TID)
-{
-       tThread *thread;
-       
-       // Search Active List
-       for(thread = gActiveThreads;
-               thread;
-               thread = thread->Next)
-       {
-               if(thread->TID == TID)
-                       return thread;
-       }
-       
-       // Search Sleeping List
-       for(thread = gSleepingThreads;
-               thread;
-               thread = thread->Next)
-       {
-               if(thread->TID == TID)
-                       return thread;
-       }
-       
-       return NULL;
-}
-
-/**
- * \fn static tThread *Proc_int_GetPrevThread(tThread *List, tThread *Thread)
- * \brief Gets the previous entry in a thead linked list
- */
-static tThread *Proc_int_GetPrevThread(tThread **List, tThread *Thread)
-{
-       tThread *ret;
-       // First Entry
-       if(*List == Thread) {
-               return (tThread*)List;
-       } else {
-               for(ret = *List;
-                       ret->Next && ret->Next != Thread;
-                       ret = ret->Next
-                       );
-               // Error if the thread is not on the list
-               if(!ret->Next || ret->Next != Thread) {
-                       return NULL;
-               }
-       }
-       return ret;
-}
-
-/**
- * \fn void Proc_DumpThreads()
- */
-void Proc_DumpThreads()
-{
-       tThread *thread;
-       
-       Log("Active Threads:");
-       for(thread=gActiveThreads;thread;thread=thread->Next)
-       {
-               Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName);
-               Log("  %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum);
-               Log("  CR3 0x%x, KStack 0x%x", thread->CR3, thread->KernelStack);
-       }
-       Log("Sleeping Threads:");
-       for(thread=gSleepingThreads;thread;thread=thread->Next)
-       {
-               Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName);
-               Log("  %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum);
-               Log("  CR3 0x%x, KStack 0x%x", thread->CR3, thread->KernelStack);
-       }
-}
-
-/**
- * \fn void Proc_Scheduler(int CPU)
- * \brief Swap current task
- */
-void Proc_Scheduler(int CPU)
-{
-       Uint    esp, ebp, eip;
-       Uint    number, ticket;
-       tThread *thread;
-       
-       // Increment Timestamps
-       giTicks ++;
-       giTimestamp += MS_PER_TICK_WHOLE;
-       giPartMiliseconds += MS_PER_TICK_FRACT;
-       if(giPartMiliseconds > 0x80000000) {
-               giTimestamp ++;
-               giPartMiliseconds -= 0x80000000;
-       }
-       
-       // If the spinlock is set, let it complete
-       if(giThreadListLock)    return;
-       
-       // Clear Delete Queue
-       while(gDeleteThreads)
-       {
-               thread = gDeleteThreads->Next;
-               if(gDeleteThreads->IsLocked) {  // Only free if structure is unused
-                       gDeleteThreads->Status = THREAD_STAT_NULL;
-                       free( gDeleteThreads );
-               }
-               gDeleteThreads = thread;
-       }
-       
-       // Check if there is any tasks running
-       if(giNumActiveThreads == 0) {
-               Log("No Active threads, sleeping\n");
-               __asm__ __volatile__ ("hlt");
-               return;
-       }
-       
-       // Reduce remaining quantum
-       if(gCurrentThread->Remaining--) return;
-       // Reset quantum for next call
-       gCurrentThread->Remaining = gCurrentThread->Quantum;
-       
-       // Get machine state
-       __asm__ __volatile__ ("mov %%esp, %0":"=r"(esp));
-       __asm__ __volatile__ ("mov %%ebp, %0":"=r"(ebp));
-       eip = GetEIP();
-       if(eip == SWITCH_MAGIC) return; // Check if a switch happened
-       
-       // Save machine state
-       gCurrentThread->ESP = esp;
-       gCurrentThread->EBP = ebp;
-       gCurrentThread->EIP = eip;
-       
-       // Special case: 1 thread
-       if(giNumActiveThreads == 1)
-       {
-               // Check if a switch is needed (NumActive can be 1 after a sleep)
-               if(gActiveThreads == gCurrentThread)    return;
-               // Switch processes
-               gCurrentThread = gActiveThreads;
-               goto performSwitch;
-       }
-       
-       // Get the ticket number
-       ticket = number = rand() % giTotalTickets;
-       
-       //Log(" Proc_Scheduler: number = 0x%x\n", number);
-       
-       // Find the next thread
-       for(thread=gActiveThreads;thread;thread=thread->Next)
-       {
-               if(thread->NumTickets > number) break;
-               number -= thread->NumTickets;
-       }
-       
-       // Error Check
-       if(thread == NULL)
-       {
-               number = 0;
-               for(thread=gActiveThreads;thread;thread=thread->Next)
-                       number += thread->NumTickets;
-               Panic("Bookeeping Failed - giTotalTicketCount (%i) != true count (%i)",
-                       giTotalTickets, number);
-       }
-       
-       // Set current thread
-       gCurrentThread = thread;
-       
-       // Update Kernel Stack pointer
-       gTSSs[CPU].ESP0 = thread->KernelStack;
-       
-performSwitch:
-       // Set address space
-       MM_SetCR3( gCurrentThread->CR3 );
-       // Switch threads
-       __asm__ __volatile__ (
-               "mov %1, %%esp\n\t"
-               "mov %2, %%ebp\n\t"
-               "jmp *%3" : :
-               "a"(SWITCH_MAGIC), "b"(gCurrentThread->ESP),
-               "d"(gCurrentThread->EBP), "c"(gCurrentThread->EIP));
-       for(;;);        // Shouldn't reach here
-}
-
-/**
- * \fn Uint rand()
- * \brief Pseudo random number generator
- * \note Unknown effectiveness (made up on the spot)
- */
-Uint rand()
-{
-       static Uint     randomState = RANDOM_SEED;
-       Uint    ret = randomState;
-        int    roll = randomState & 31;
-       randomState = (randomState << roll) | (randomState >> (32-roll));
-       randomState ^= 0x9A3C5E78;
-       return ret;
-}
index 4dc92c8..27c3502 100644 (file)
@@ -9,6 +9,7 @@
 extern int     Modules_LoadBuiltins();
 extern int     PCI_Install();
 extern void    DMA_Install();
+extern void    Debug_SetKTerminal(char *File);
 
 // === PROTOTYPES ===
 void   System_Init(char *ArgString);
@@ -29,6 +30,9 @@ void System_Init(char *ArgString)
        DMA_Install();
        Modules_LoadBuiltins();
        
+       // Set the debug to be echoed to the terminal
+       Debug_SetKTerminal("/Devices/vterm/0");
+       
        // - Parse Kernel's Command Line
        System_ParseCommandLine(ArgString);
        
index 3be9789..00fc050 100644 (file)
@@ -335,7 +335,7 @@ void Threads_AddToDelete(tThread *Thread)
 }
 
 /**
- * \fn tThread *Threads_int_GetPrev(tThread *List, tThread *Thread)
+ * \fn tThread *Threads_int_GetPrev(tThread **List, tThread *Thread)
  * \brief Gets the previous entry in a thead linked list
  */
 tThread *Threads_int_GetPrev(tThread **List, tThread *Thread)
@@ -373,7 +373,8 @@ void Threads_Exit(int TID, int Status)
 /**
  * \fn void Threads_Kill(tThread *Thread, int Status)
  * \brief Kill a thread
- * \param TID  Thread ID (0 for current)
+ * \param Thread       Thread to kill
+ * \param Status       Status code to return to the parent
  */
 void Threads_Kill(tThread *Thread, int Status)
 {
diff --git a/Kernel/vfs.c b/Kernel/vfs.c
deleted file mode 100644 (file)
index c1d6eef..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Acess 2
- * binary.c
- * - Binary File Loader
- */
-#include <common.h>
-#include <vfs.h>
-
-// === GLOBALS ===
-
-
-// === CODE ===
index 6ead47e..90770a7 100644 (file)
@@ -43,7 +43,7 @@ int DevFS_AddDevice(tDevFS_Driver *Dev)
 /**
  * \fn tVFS_Node *DevFS_InitDevice(char *Device, char **Options)
  * \brief Initialise the DevFS and detect double-mounting, or just do nothing
- * \stub
+ * \note STUB
  */
 tVFS_Node *DevFS_InitDevice(char *Device, char **Options)
 {
index 8ee26af..be50e6c 100644 (file)
@@ -69,7 +69,7 @@ int Ext2_Install(char **Arguments)
 }\r
 \r
 /**\r
- \fn tVFS_Node *Ext2_initDevice(char *Device, char **Options)\r
+ \fn tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
  \brief Initializes a device to be read by by the driver\r
  \param Device String - Device to read from\r
  \param Options        NULL Terminated array of option strings\r
@@ -336,7 +336,7 @@ addBlocks:
 }\r
 \r
 /**\r
- * \fn void Ext2_CloseFile(vfs_node *Node)\r
+ * \fn void Ext2_CloseFile(tVFS_Node *Node)\r
  * \brief Close a file (Remove it from the cache)\r
  */\r
 void Ext2_CloseFile(tVFS_Node *Node)\r
@@ -487,11 +487,11 @@ int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
 \r
 \r
 /**\r
\fn int Ext2_int_GetInode(vfs_node *Node, tExt2_Inode *Inode)\r
- \brief Gets the inode descriptor for a node\r
\param node   node to get the Inode of\r
\param inode  Destination\r
-*/\r
* \fn int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
\brief Gets the inode descriptor for a node\r
* \param Node node to get the Inode of\r
* \param Inode        Destination\r
+ */\r
 int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
 {\r
        return Ext2_int_ReadInode(Node->ImplPtr, Node->Inode, Inode);\r
index 7c5eefc..5712da9 100644 (file)
@@ -36,7 +36,7 @@ tVFS_Node     *FAT_FindDir(tVFS_Node *dirNode, char *file);
 void   FAT_CloseFile(tVFS_Node *node);\r
 \r
 // === SEMI-GLOBALS ===\r
-MODULE_DEFINE(0, 0x51 /*v0.80*/, FAT32, FAT_Install, NULL);\r
+MODULE_DEFINE(0, 0x51 /*v0.80*/, FAT32, FAT_Install, NULL, NULL);\r
 tFAT_VolInfo   gFAT_Disks[8];\r
  int   giFAT_PartCount = 0;\r
 #if CACHE_FAT\r
index 0041116..f7c9ae1 100644 (file)
@@ -1,8 +1,8 @@
 /**\r
- Acess Version 1\r
\file fs_ext2_int.h\r
- \brief EXT2 Filesystem Driver\r
-*/\r
+ * Acess2\r
* \file fs_ext2.h\r
\brief EXT2 Filesystem Driver\r
+ */\r
 \r
 /**\r
  \name Inode Flag Values\r
 \r
 #define EXT2_NAME_LEN 255      //!< Maximum Name Length\r
 \r
-//STRUCTURES\r
+// === TYPEDEFS ===\r
+typedef struct ext2_inode_s                    tExt2_Inode;    //!< Inode Type\r
+typedef struct ext2_super_block_s      tExt2_SuperBlock;       //!< Superblock Type\r
+typedef struct ext2_group_desc_s       tExt2_Group;    //!< Group Descriptor Type\r
+typedef struct ext2_dir_entry_s                tExt2_DirEnt;   //!< Directory Entry Type\r
+\r
+// === STRUCTURES ===\r
 /**\r
- \struct ext2_super_block_s\r
- \brief EXT2 Superblock Structure\r
-*/\r
+ * \brief EXT2 Superblock Structure\r
+ */\r
 struct ext2_super_block_s {\r
        Uint32  s_inodes_count;         //!< Inodes count\r
        Uint32  s_blocks_count;         //!< Blocks count\r
@@ -70,9 +75,9 @@ struct ext2_super_block_s {
 };\r
 \r
 /**\r
- \struct ext2_inode_s\r
- \brief EXT2 Inode Definition\r
-*/\r
\struct ext2_inode_s\r
\brief EXT2 Inode Definition\r
+ */\r
 struct ext2_inode_s {\r
        Uint16 i_mode;  //!< File mode\r
        Uint16 i_uid;   //!< Owner Uid\r
@@ -120,9 +125,9 @@ struct ext2_inode_s {
 };\r
 \r
 /**\r
- \struct ext2_group_desc_s\r
- \brief EXT2 Group Descriptor\r
-*/\r
\struct ext2_group_desc_s\r
\brief EXT2 Group Descriptor\r
+ */\r
 struct ext2_group_desc_s {\r
        Uint32  bg_block_bitmap;        //!< Blocks bitmap block\r
        Uint32  bg_inode_bitmap;        //!< Inodes bitmap block\r
@@ -135,10 +140,9 @@ struct ext2_group_desc_s {
 };\r
 \r
 /**\r
- \struct ext2_dir_entry\r
- \brief EXT2 Directory Entry\r
- \note The name may take up less than 255 characters\r
-*/\r
+ * \brief EXT2 Directory Entry\r
+ * \note The name may take up less than 255 characters\r
+ */\r
 struct ext2_dir_entry_s {\r
        Uint32  inode;          //!< Inode number\r
        Uint16  rec_len;        //!< Directory entry length\r
@@ -146,9 +150,3 @@ struct ext2_dir_entry_s {
        Uint8   type;           //!< File Type\r
        char    name[];         //!< File name\r
 };\r
-\r
-//TYPEDEFS\r
-typedef struct ext2_inode_s                    tExt2_Inode;    //!< Inode Type\r
-typedef struct ext2_super_block_s      tExt2_SuperBlock;       //!< Superblock Type\r
-typedef struct ext2_group_desc_s       tExt2_Group;    //!< Group Descriptor Type\r
-typedef struct ext2_dir_entry_s                tExt2_DirEnt;   //!< Directory Entry Type\r
index f6f0061..1752497 100644 (file)
@@ -16,7 +16,7 @@ ARCHDIR = x86
 
 FILESYSTEMS = fat ext2
 DRIVERS = ata_x86 fdd
-MODULES = ne2000
+MODULES = NE2000 BochsVBE
 
 DISTROOT = /mnt/AcessHDD/Acess2
 ACESSDIR = /home/hodgeja/Projects/Acess2
index a55e702..2fe0110 100644 (file)
@@ -85,8 +85,8 @@ tDevFS_Driver gBGA_DriverStruct = {
 Uint   *gBGA_Framebuffer;\r
 t_bga_mode     gBGA_Modes[] = {\r
        {},\r
-       { 80,25, 32, MODEFLAG_TEXT, 80*25*8},   // 640 x 480\r
-       {100,37, 32, MODEFLAG_TEXT, 100*37*8},  // 800 x 600\r
+       { 80,25, 12, MODEFLAG_TEXT, 80*25*8},   // 640 x 480\r
+       {100,37, 12, MODEFLAG_TEXT, 100*37*8},  // 800 x 600\r
        {640,480,8, 0, 640*480},\r
        {640,480,32, 0, 640*480*4},\r
        {800,600,8, 0, 800*600},\r
@@ -176,8 +176,10 @@ Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)
                tVT_Char        *chars = buffer;\r
                 int    pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth;\r
                Uint32  *dest;\r
+               off /= sizeof(tVT_Char);\r
                dest = (void*)gBGA_Framebuffer;\r
-               dest += off * giVT_CharWidth;\r
+               dest += (off / gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharHeight * pitch;\r
+               dest += (off % gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharWidth;\r
                len /= sizeof(tVT_Char);\r
                while(len--)\r
                {\r
@@ -400,9 +402,9 @@ int BGA_int_FindMode(tVideo_IOCtl_Mode *info)
 int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
 {\r
        // Sanity Check\r
-       if( !MM_IsUser( (Uint)info, sizeof(tVideo_IOCtl_Mode) ) ) {\r
-               return -EINVAL;\r
-       }\r
+       //if( !MM_IsUser( (Uint)info, sizeof(tVideo_IOCtl_Mode) ) ) {\r
+       //      return -EINVAL;\r
+       //}\r
        \r
        if(info->id < 0 || info->id >= BGA_MODE_COUNT)  return -1;\r
        \r
index 6d22b4c..4174344 100644 (file)
@@ -9,21 +9,27 @@ CFLAGS = -Wall -Werror $(CPPFLAGS)
 
 OBJ := $(addsuffix .$(ARCH),$(OBJ))
 BIN = ../$(NAME).kmd.$(ARCH)
+KOBJ = ../$(NAME).xo.$(ARCH)
+
+DEPFILES  = $(filter %.o.$(ARCH),$(OBJ))
+DEPFILES := $(DEPFILES:%.o.$(ARCH)=%.d.$(ARCH))
 
 .PHONY: all clean
 
 all: $(BIN)
 
 clean:
-       $(RM) $(BIN) $(OBJ)
+       $(RM) $(BIN) $(KOBJ) $(OBJ) $(DEPFILES)
 
 $(BIN): $(OBJ)
        @echo --- $(LD) -o $@
        @$(LD) -T ../link.ld -shared -o $@ $(OBJ)
        @echo --- $(LD) -o ../$(NAME).o.$(ARCH)
-       @$(CC) -Wl,-r -nostdlib -o ../$(NAME).o.$(ARCH) $(OBJ)
+       @$(CC) -Wl,-r -nostdlib -o $(KOBJ) $(OBJ)
 
 %.o.$(ARCH): %.c Makefile ../Makefile.tpl ../../Makefile.cfg 
        @echo --- $(CC) -o $@
        @$(CC) $(CFLAGS) -o $@ -c $<
-       @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d $<
+       @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(ARCH) $<
+
+-include $(DEPFILES)
index f6f3485..7e74022 100644 (file)
@@ -2,6 +2,6 @@
 #
 
 OBJ = ne2000.o
-NAME = ne2000
+NAME = NE2000
 
 -include ../Makefile.tpl
index d6c40d6..836c6f5 100644 (file)
@@ -135,7 +135,9 @@ char *ReadCommandLine(int *Length)
        char    *ret;\r
         int    len, pos, space = 1023;\r
        char    ch;\r
-       // int  scrollbackPos = giLastCommand;\r
+       #if 1\r
+        int    scrollbackPos = giLastCommand;\r
+       #endif\r
         \r
        // Preset Variables\r
        ret = malloc( space+1 );\r
@@ -145,8 +147,13 @@ char *ReadCommandLine(int *Length)
        // Read In Command Line\r
        do {\r
                read(_stdin, 1, &ch);   // Read Character from stdin (read is a blocking call)\r
+               \r
+               if(ch == '\n')  break;\r
+               \r
+               switch(ch)\r
+               {\r
                // Control characters\r
-               if(ch == '\x1B') {\r
+               case '\x1B':\r
                        read(_stdin, 1, &ch);   // Read control character\r
                        switch(ch)\r
                        {\r
@@ -158,23 +165,32 @@ char *ReadCommandLine(int *Length)
                                {\r
                                #if 0\r
                                case 'A':       // Up\r
-                                       if( scrollbackPos > 0 ) break;\r
-                                       \r
-                                       free(ret);\r
-                                       ret = strdup( gasCommandHistory[--scrollbackPos] );\r
-                                       \r
-                                       len = strlen(ret);\r
-                                       while(pos--)    write(_stdout, 3, "\x1B[D");\r
-                                       while(pos++ < len)      write(_stdout, 3, "\x1B[C");\r
+                                       {\r
+                                                int    oldLen = len;\r
+                                               if( scrollbackPos > 0 ) break;\r
+                                               \r
+                                               free(ret);\r
+                                               ret = strdup( gasCommandHistory[--scrollbackPos] );\r
+                                               \r
+                                               len = strlen(ret);\r
+                                               while(pos--)    write(_stdout, 3, "\x1B[D");\r
+                                               write(_stdout, len, ret);       pos = len;\r
+                                               while(pos++ < oldLen)   write(_stdout, 1, " ");\r
+                                       }\r
                                        break;\r
                                case 'B':       // Down\r
-                                       if( scrollbackPos < giLastCommand-1 )   break;\r
-                                       free(ret);\r
-                                       ret = strdup( gasCommandHistory[++scrollbackPos] );\r
-                                       \r
-                                       len = strlen(ret);\r
-                                       while(pos--)    write(_stdout, 3, "\x1B[D");\r
-                                       while(pos++ < len)      write(_stdout, 3, "\x1B[C");\r
+                                       {\r
+                                                int    oldLen = len;\r
+                                               if( scrollbackPos < giLastCommand-1 )   break;\r
+                                               \r
+                                               free(ret);\r
+                                               ret = strdup( gasCommandHistory[++scrollbackPos] );\r
+                                               \r
+                                               len = strlen(ret);\r
+                                               while(pos--)    write(_stdout, 3, "\x1B[D");\r
+                                               write(_stdout, len, ret);       pos = len;\r
+                                               while(pos++ < oldLen)   write(_stdout, 1, " ");\r
+                                       }\r
                                        break;\r
                                #endif\r
                                case 'D':       // Left\r
@@ -183,49 +199,74 @@ char *ReadCommandLine(int *Length)
                                        write(_stdout, 3, "\x1B[D");\r
                                        break;\r
                                case 'C':       // Right\r
-                                       if(pos == len-1)        break;\r
+                                       if(pos == len)  break;\r
                                        pos++;\r
                                        write(_stdout, 3, "\x1B[C");\r
                                        break;\r
                                }\r
                        }\r
-                       continue;\r
-               }\r
+                       break;\r
+               \r
                // Backspace\r
-               if(ch == '\b') {\r
-                       if(len <= 0)            continue;       // Protect against underflows\r
+               case '\b':\r
+                       if(len <= 0)            break;  // Protect against underflows\r
+                       write(_stdout, 1, &ch);\r
                        if(pos == len) {        // Simple case of end of string\r
-                               len --; pos--;\r
-                       } else {\r
+                               len --;\r
+                               pos--;\r
+                       }\r
+                       else {\r
+                               char    buf[7] = "\x1B[000D";\r
+                               buf[2] += ((len-pos+1)/100) % 10;\r
+                               buf[3] += ((len-pos+1)/10) % 10;\r
+                               buf[4] += (len-pos+1) % 10;\r
+                               write(_stdout, len-pos, &ret[pos]);     // Move Text\r
+                               ch = ' ';       write(_stdout, 1, &ch); ch = '\b';      // Clear deleted character\r
+                               write(_stdout, 7, buf); // Update Cursor\r
+                               // Alter Buffer\r
                                memmove(&ret[pos-1], &ret[pos], len-pos);\r
                                pos --;\r
                                len --;\r
                        }\r
-                       write(_stdout, 1, &ch);\r
-                       continue;\r
-               }\r
+                       break;\r
+               \r
                // Tab\r
-               if(ch == '\t') {\r
+               case '\t':\r
                        //TODO: Implement Tab-Completion\r
                        //Currently just ignore tabs\r
-                       continue;\r
-               }\r
+                       break;\r
                \r
-               // Expand Buffer\r
-               if(len > space) {\r
-                       space += 256;\r
-                       ret = realloc(ret, space+1);\r
-                       if(!ret)        return NULL;\r
+               default:                \r
+                       // Expand Buffer\r
+                       if(len+1 > space) {\r
+                               space += 256;\r
+                               ret = realloc(ret, space+1);\r
+                               if(!ret)        return NULL;\r
+                       }\r
+                       \r
+                       // Editing inside the buffer\r
+                       if(pos != len) {\r
+                               char    buf[7] = "\x1B[000D";\r
+                               buf[2] += ((len-pos)/100) % 10;\r
+                               buf[3] += ((len-pos)/10) % 10;\r
+                               buf[4] += (len-pos) % 10;\r
+                               write(_stdout, 1, &ch); // Print new character\r
+                               write(_stdout, len-pos, &ret[pos]);     // Move Text\r
+                               write(_stdout, 7, buf); // Update Cursor\r
+                               memmove( &ret[pos+1], &ret[pos], len-pos );\r
+                       }\r
+                       else {\r
+                               write(_stdout, 1, &ch);\r
+                       }\r
+                       ret[pos++] = ch;\r
+                       len ++;\r
+                       break;\r
                }\r
-               \r
-               write(_stdout, 1, &ch);\r
-               ret[pos++] = ch;\r
-               len ++;\r
        } while(ch != '\n');\r
        \r
-       // Remove newline\r
-       pos --;\r
-       ret[pos] = '\0';\r
+       // Cap String\r
+       ret[len] = '\0';\r
+       printf("\n");\r
        \r
        // Return length\r
        if(Length)      *Length = len;\r
index 8787f39..3473eb5 100644 (file)
@@ -5,28 +5,35 @@
 
 // === CONSTANTS ===
 #define NULL   ((void*)0)
+#define NUM_TERMS      4
 #define        DEFAULT_TERMINAL        "/Devices/VTerm/0"
 #define DEFAULT_SHELL  "/Acess/SBin/login"
 
 // === CODE ===
 /**
  * \fn int main(int argc, char *argv[])
+ * \brief Entrypoint
  */
 int main(int argc, char *argv[])
 {
         int    tid;
-       open(DEFAULT_TERMINAL, OPENFLAG_READ);  // Stdin
-       open(DEFAULT_TERMINAL, OPENFLAG_WRITE); // Stdout
-       open(DEFAULT_TERMINAL, OPENFLAG_WRITE); // Stderr
+       // int  i;
+       char    termpath[sizeof(DEFAULT_TERMINAL)+1] = DEFAULT_TERMINAL;
        
-       write(1, 13, "Hello, World!");
-       
-       tid = clone(CLONE_VM, 0);
-       if(tid == 0)
-       {
-               execve(DEFAULT_SHELL, NULL, NULL);
-               for(;;) __asm__ __volatile__("hlt");
-       }
+       //for( i = 0; i < NUM_TERMS; i++ )
+       //{
+               //termpath[ sizeof(DEFAULT_TERMINAL)-1 ] = '0' + i;
+               open(termpath, OPENFLAG_READ);  // Stdin
+               open(termpath, OPENFLAG_WRITE); // Stdout
+               open(termpath, OPENFLAG_WRITE); // Stderr
+               
+               tid = clone(CLONE_VM, 0);
+               if(tid == 0)
+               {
+                       execve(DEFAULT_SHELL, NULL, NULL);
+                       for(;;) __asm__ __volatile__("hlt");
+               }
+       //}
        
        for(;;) sleep();
        
index 248e13b..391d5bc 100644 (file)
@@ -22,11 +22,19 @@ int main(int argc, char *argv[])
        {
                printf("\x1B[2J");      // Clear Screen
                // Validate User
-               do {
-                       if(uid == -1)   printf("\n");
+               for(;;)
+               {
                        sUsername = GetUsername();
                        sPassword = GetPassword();
-               } while( (uid = ValidateUser(sUsername, sPassword)) == -1 );
+                       if( (uid = ValidateUser(sUsername, sPassword)) == -1 )
+                       {
+                               printf("\nInvalid username or password for '%s'\n", sUsername);
+                               free(sUsername);
+                               free(sPassword);
+                       }
+                       else
+                               break;
+               }
                printf("\n");
                
                // Create child process
@@ -67,7 +75,7 @@ int main(int argc, char *argv[])
  */
 char *GetUsername()
 {
-       char    ret[BUFLEN];
+       char    ret[BUFLEN] = {0};
         int    pos = 0;
        char    ch;
        
index 1645cde..5fdac4c 100644 (file)
@@ -29,9 +29,9 @@ struct sFILE  *stderr;        // Standard Error
 \r
 // === CODE ===\r
 /**\r
- * \fn FILE *freopen(FILE *fp, char *file, char *mode)\r
+ * \fn FILE *freopen(char *file, char *mode, FILE *fp)\r
  */\r
-EXPORT FILE *freopen(FILE *fp, char *file, char *mode)\r
+EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp)\r
 {\r
         int    openFlags = 0;\r
         int    i;\r
@@ -98,12 +98,12 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode)
        return fp;\r
 }\r
 /**\r
- \fn FILE *fopen(char *file, char *mode)\r
+ \fn FILE *fopen(const char *file, const char *mode)\r
  \brief Opens a file and returns the pointer\r
  \param file   String - Filename to open\r
  \param mode   Mode to open in\r
 */\r
-EXPORT FILE *fopen(char *file, char *mode)\r
+EXPORT FILE *fopen(const char *file, const char *mode)\r
 {\r
        FILE    *retFile;\r
        \r
@@ -113,7 +113,7 @@ EXPORT FILE *fopen(char *file, char *mode)
        // Create Return Structure\r
        retFile = get_file_struct();\r
        \r
-       return freopen(retFile, file, mode);\r
+       return freopen(file, mode, retFile);\r
 }\r
 \r
 EXPORT void fclose(FILE *fp)\r
index 07c2017..98692b2 100644 (file)
@@ -34,6 +34,35 @@ EXPORT char *strcpy(char *dst, const char *src)
        return _dst;
 }
 
+/**
+ * \fn EXPORT char *strncpy(char *dst, const char *src)
+ * \brief Copy at most \a num characters from \a src to \a dst
+ * \return \a dst
+ */
+EXPORT char *strncpy(char *dst, const char *src, size_t num)
+{
+       char *to = dst;
+       while(*src && num--)    *to++ = *src++;
+       *to = '\0';
+       return dst;
+}
+
+/**
+ * \fn EXPORT char *strcat(char *dst, const char *src)
+ * \brief Append a string onto another
+ */
+EXPORT char *strcat(char *dst, const char *src)
+{
+       char    *to = dst;
+       // Find the end
+       while(*to)      to++;
+       // Copy
+       while(*src)     *to++ = *src++;
+       // End string
+       *to = '\0';
+       return dst;
+}
+
 /**
  * \fn EXPORT int strlen(const char *str)
  * \brief Get the length of a string
@@ -72,6 +101,52 @@ EXPORT char *strdup(const char *str)
        return ret;
 }
 
+/**
+ * \fn EXPORT char *strchr(char *str, int character)
+ * \brief Locate a character in a string
+ */
+EXPORT char *strchr(char *str, int character)
+{
+       while(*str)
+       {
+               if(*str == character)   return str;
+       }
+       return NULL;
+}
+
+/**
+ * \fn EXPORT char *strrchr(char *str, int character)
+ * \brief Locate the last occurance of a character in a string
+ */
+EXPORT char *strrchr(char *str, int character)
+{
+        int    i;
+       i = strlen(str)-1;
+       while(i--)
+       {
+               if(str[i] == character) return &str[i];
+       }
+       return NULL;
+}
+
+/**
+ * \fn EXPORT char *strstr(char *str1, const char *str2)
+ * \brief Search a \a str1 for the first occurance of \a str2
+ */
+EXPORT char *strstr(char *str1, const char *str2)
+{
+       const char      *test = str2;
+       
+       while(*str1)
+       {
+               if(*test == '\0')       return str1;
+               if(*str1 == *test)      test++;
+               else    test = str2;
+               str1 ++;
+       }
+       return NULL;
+}
+
 // --- Memory ---
 /**
  * \fn EXPORT void *memset(void *dest, int val, size_t num)
@@ -111,3 +186,40 @@ EXPORT void *memmove(void *dest, const void *src, size_t count)
        for(;count--;) *dp++ = *sp++;
     return dest;
 }
+
+/**
+ * \fn EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
+ * \brief Compare two regions of memory
+ * \param mem1 Region 1
+ * \param mem2 Region 2
+ * \param count        Number of bytes to check
+ */
+EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
+{
+       while(count--)
+       {
+               if( *(unsigned char*)mem1 != *(unsigned char*)mem2 )
+                       return *(unsigned char*)mem1 - *(unsigned char*)mem2;
+               mem1 ++;
+               mem2 ++;
+       }
+       return 0;
+}
+
+/**
+ * \fn EXPORT void *memchr(void *ptr, int value, size_t num)
+ * \brief Locates the first occurence of \a value starting at \a ptr
+ * \param ptr  Starting memory location
+ * \param value        Value to find
+ * \param num  Size of memory area to check
+ */
+EXPORT void *memchr(void *ptr, int value, size_t num)
+{
+       while(num--)
+       {
+               if( *(unsigned char*)ptr == (unsigned char)value )
+                       return ptr;
+               ptr ++;
+       }
+       return NULL;
+}
index d1e39af..a1bdbbb 100644 (file)
@@ -71,9 +71,9 @@ extern void   setuid(int id);
 extern void    setgid(int id);
 
 // --- VFS ---
-extern int     chdir(char *dir);
-extern int     open(char *path, int flags);
-extern int     reopen(int fd, char *path, int flags);
+extern int     chdir(const char *dir);
+extern int     open(const char *path, int flags);
+extern int     reopen(int fd, const char *path, int flags);
 extern void    close(int fd);
 extern uint64_t        read(int fd, uint64_t length, void *buffer);
 extern uint64_t        write(int fd, uint64_t length, void *buffer);
@@ -83,7 +83,7 @@ extern int    ioctl(int fd, int id, void *data);
 extern int     finfo(int fd, t_sysFInfo *info, int maxacls);
 extern int     readdir(int fd, char *dest);
 extern int     _SysGetACL(int fd, t_sysACL *dest);
-extern int     _SysMount(char *Device, char *Directory, char *Type, char *Options);
+extern int     _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options);
 
 // --- IPC ---
 extern int     SysSendMessage(int dest, int length, void *Data);
index 26d9c68..985f058 100644 (file)
@@ -7,15 +7,21 @@
 \r
 #include <stdlib.h>\r
 #include <stdarg.h>\r
-
+\r
+// === Types ===
 typedef struct sFILE   FILE;
 \r
+// === CONSTANTS ===\r
+#define EOF    (-1)\r
+\r
+// --- Standard IO ---\r
 extern int     printf(const char *format, ...);\r
 extern int     vsprintf(char *buf, const char *format, va_list args);\r
-extern int     sprintf(char *buf, const char *format, ...);
+extern int     sprintf(char *buf, const char *format, ...);\r
 \r
-extern FILE    *fopen(char *file, char *mode);\r
-extern FILE    *freopen(FILE *fp, char *file, char *mode);
+extern FILE    *fopen(const char *file, const char *mode);\r
+extern FILE    *freopen(const char *file, const char *mode, FILE *fp);\r
+extern FILE    *fdopen(int fd, const char *modes);
 extern void fclose(FILE *fp);\r
 extern void fflush(FILE *fp);\r
 extern long int        ftell(FILE *fp);\r
index 9dd720e..50cedb3 100644 (file)
@@ -1,23 +1,17 @@
 /*\r
-AcessOS LibC\r
-\r
-stdlib.h\r
-*/\r
+ * AcessOS LibC\r
+ * stdlib.h\r
+ */\r
 #ifndef __STDLIB_H\r
 #define __STDLIB_H\r
 \r
+#include <stddef.h>\r
 #include <stdarg.h>\r
 #include <sys/types.h>\r
 \r
-#ifndef NULL\r
-# define NULL  ((void*)0)\r
-#endif\r
-\r
 #define EXIT_FAILURE   1\r
 #define EXIT_SUCCESS   0\r
 \r
-typedef unsigned int   size_t;\r
-\r
 // --- Spinlock Macros ---\r
 #define DEFLOCK(_name) static int _spinlock_##_name=0;\r
 //#define LOCK(_name)  __asm__ __volatile__("jmp ._tst;\n\t._lp:call yield;\n\t._tst:lock btsl $1,(%0);\n\tjc ._lp"::"D"(&_spinlock_##_name))\r
@@ -25,6 +19,7 @@ typedef unsigned int  size_t;
 #define UNLOCK(_name) __asm__ __volatile__("lock andl $0, (%0)"::"D"(&_spinlock_##_name))\r
 \r
 // --- StdLib ---\r
+extern void    _exit(int code);        //NOTE: Also defined in acess/sys.h\r
 extern int     atoi(const char *ptr);\r
 extern void    exit(int status) __attribute__((noreturn));\r
 extern void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));\r
index beeff60..1e72197 100644 (file)
@@ -5,19 +5,25 @@
 #ifndef __STRING_H
 #define __STRING_H
 
-#include <stdlib.h>
-
-// Memory
-extern void *memset(void *dest, int val, size_t count);
-extern void *memcpy(void *dest, const void *src, size_t count);
-extern void *memmove(void *dest, const void *src, size_t count);
-extern int     memcmp(const void *mem1, const void *mem2, size_t count);
+#include <stddef.h>
 
 // Strings
 extern int     strlen(const char *string);
 extern int     strcmp(const char *str1, const char *str2);
 extern int     strncmp(const char *str1, const char *str2, size_t len);
 extern char    *strcpy(char *dst, const char *src);
+extern char    *strncpy(char *dst, const char *src, size_t num);
+extern char    *strcat(char *dst, const char *src);
 extern char    *strdup(const char *src);
+extern char    *strchr(char *str, int character);
+extern char    *strrchr(char *str, int character);
+extern char    *strstr(char *str1, const char *str2);
+
+// Memory
+extern void *memset(void *dest, int val, size_t count);
+extern void *memcpy(void *dest, const void *src, size_t count);
+extern void *memmove(void *dest, const void *src, size_t count);
+extern int     memcmp(const void *mem1, const void *mem2, size_t count);
+extern void    *memchr(void *ptr, int value, size_t num);
 
 #endif

UCC git Repository :: git.ucc.asn.au