Merge branch 'master' of [email protected]:acess2
authorJohn Hodge <[email protected]>
Tue, 11 May 2010 02:15:47 +0000 (10:15 +0800)
committerJohn Hodge <[email protected]>
Tue, 11 May 2010 02:15:47 +0000 (10:15 +0800)
98 files changed:
COPYING [new file with mode: 0644]
Kernel/Doxyfile.api
Kernel/Makefile
Kernel/Makefile.BuildNum
Kernel/adt.c [new file with mode: 0644]
Kernel/arch/x86/Makefile
Kernel/arch/x86/desctab.asm
Kernel/arch/x86/errors.c
Kernel/arch/x86/kpanic.c [new file with mode: 0644]
Kernel/arch/x86/link.ld
Kernel/arch/x86/main.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.asm [new file with mode: 0644]
Kernel/arch/x86/proc.c
Kernel/arch/x86/start.asm
Kernel/arch/x86/time.c
Kernel/arch/x86/vm8086.c
Kernel/debug.c
Kernel/drv/kb.c
Kernel/drv/vga.c
Kernel/drv/vterm.c
Kernel/drvutil.c
Kernel/include/acess.h
Kernel/include/adt.h [new file with mode: 0644]
Kernel/include/apidoc_mainpage.h
Kernel/include/errno.h
Kernel/include/fs_devfs.h
Kernel/include/syscalls.h
Kernel/include/syscalls.inc.asm
Kernel/include/threads.h
Kernel/include/tpl_drv_disk.h
Kernel/include/tpl_drv_video.h
Kernel/include/vfs_ext.h
Kernel/lib.c
Kernel/logging.c
Kernel/modules.c
Kernel/syscalls.c
Kernel/syscalls.lst
Kernel/system.c
Kernel/threads.c
Kernel/vfs/io.c
Kernel/vfs/open.c
Makefile.cfg
Modules/Display/BochsGA/bochsvbe.c
Modules/Display/VESA/main.c
Modules/Filesystems/FAT/fat.c
Modules/Filesystems/InitRD/Makefile
Modules/Filesystems/InitRD/files.lst
Modules/IPStack/ipv4.c
Modules/IPStack/ipv6.c
Modules/IPStack/tcp.c
Modules/IPStack/tcp.h
Modules/Storage/ATA/main.c
Usermode/Applications/Makefile.tpl
Usermode/Applications/axwin2_src/Shell_src/main.c
Usermode/Applications/axwin2_src/WM/Makefile
Usermode/Applications/axwin2_src/WM/common.h
Usermode/Applications/axwin2_src/WM/decorator.c [new file with mode: 0644]
Usermode/Applications/axwin2_src/WM/interface.c [new file with mode: 0644]
Usermode/Applications/axwin2_src/WM/main.c
Usermode/Applications/axwin2_src/WM/messages.c
Usermode/Applications/axwin2_src/WM/video.c
Usermode/Applications/axwin2_src/WM/wm.c [new file with mode: 0644]
Usermode/Applications/axwin2_src/WM/wm.h
Usermode/Applications/login_src/main.c
Usermode/Applications/ls_src/main.c
Usermode/Applications/testserver_src/Makefile [new file with mode: 0644]
Usermode/Applications/testserver_src/main.c [new file with mode: 0644]
Usermode/Libraries/Makefile.cfg
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/acess.ld_src/Makefile
Usermode/Libraries/crt0.o_src/Makefile
Usermode/Libraries/ld-acess.so_src/common.h
Usermode/Libraries/ld-acess.so_src/helpers.asm
Usermode/Libraries/ld-acess.so_src/loadlib.c
Usermode/Libraries/ld-acess.so_src/main.c
Usermode/Libraries/libacess.so_src/Makefile
Usermode/Libraries/libacess.so_src/core.asm
Usermode/Libraries/libacess.so_src/vfs.asm
Usermode/Libraries/libaxwin2.so_src/Makefile
Usermode/Libraries/libaxwin2.so_src/common.h
Usermode/Libraries/libaxwin2.so_src/main.c
Usermode/Libraries/libaxwin2.so_src/messages.c
Usermode/Libraries/libaxwin2.so_src/windows.c
Usermode/Libraries/libc.so_src/Makefile
Usermode/Libraries/libc.so_src/fileIO.c
Usermode/Libraries/libc.so_src/heap.c
Usermode/Libraries/libc.so_src/stub.c
Usermode/Libraries/libgcc.so_src/libgcc.c
Usermode/include/acess/sys.h
Usermode/include/axwin/axwin.h
Usermode/include/axwin/messages.h
Usermode/include/stdio.h
Usermode/include/stdlib.h
Usermode/include/string.h [deleted file]
Usermode/include/strings.h [new file with mode: 0644]
Usermode/include/sys/sys.h
Usermode/include/sys/types.h

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..81c67f0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,21 @@
+ Copyright (c) 2009 John Hodge (thePowersGang)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not
+    claim that you wrote the original software. If you use this software
+    in a product, an acknowledgment in the product documentation would be
+    appreciated but is not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+    misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source
+    distribution.
+
index d445416..5b02591 100644 (file)
@@ -570,11 +570,15 @@ INPUT                  = include/apidoc_mainpage.h \
                          include/binary.h \
                          include/modules.h \
                          include/vfs.h include/vfs_ext.h \
-                                                include/fs_devfs.h \
+                                                include/fs_devfs.h include/fs_sysfs.h \
                          include/iocache.h \
                          include/apidoc/arch_x86.h \
                          include/tpl_drv_common.h \
-                         include/tpl_drv_video.h
+                         include/tpl_drv_video.h \
+                         include/tpl_drv_terminal.h \
+                         include/tpl_drv_disk.h \
+                         include/tpl_drv_keyboard.h \
+                         include/tpl_drv_network.h
 
 # This tag can be used to specify the character encoding of the source files 
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
index 5e6fafb..fa8ff2a 100644 (file)
@@ -25,8 +25,9 @@ ifeq ($(DEBUG_BUILD),yes)
        CFLAGS += -g
 endif
 
-OBJ = $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
-OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o threads.o drvutil.o logging.o
+OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
+OBJ += heap.o drvutil.o logging.o debug.o lib.o adt.o
+OBJ += messages.o modules.o syscalls.o system.o threads.o
 OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
 OBJ += drv/vterm.o drv/proc.o drv/fifo.o drv/iocache.o drv/dma.o drv/pci.o drv/kb.o drv/vga.o
 OBJ += binary.o bin/elf.o bin/pe.o
index dc8d809..334be63 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1822
+BUILD_NUM = 2145
diff --git a/Kernel/adt.c b/Kernel/adt.c
new file mode 100644 (file)
index 0000000..7a23834
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ */
+#include <acess.h>
+#include <adt.h>
+
+// === CODE ===
+// --- Ring Buffers ---
+tRingBuffer *RingBuffer_Create(size_t Space)
+{
+       tRingBuffer     *ret = malloc(sizeof(tRingBuffer)+Space);
+       ret->Start = 0;
+       ret->Length = 0;
+       ret->Space = Space;
+       return ret;
+}
+
+size_t RingBuffer_Read(void *Dest, tRingBuffer *Buffer, size_t Length)
+{
+       if(Length > Buffer->Length)     Length = Buffer->Length;
+       
+       if( Buffer->Start + Length > Buffer->Space )
+       {
+                int    endData = Buffer->Space - Buffer->Start;
+               memcpy(Dest, &Buffer->Data[Buffer->Start], endData);
+               memcpy(Dest + endData, &Buffer->Data, Length - endData);
+       }
+       else
+       {
+               memcpy(Dest, &Buffer->Data[Buffer->Start], Length);
+       }
+       Buffer->Length -= Length;
+       return Length;
+}
+
+size_t RingBuffer_Write(tRingBuffer *Buffer, void *Source, size_t Length)
+{
+       size_t  bufEnd = Buffer->Start + Buffer->Length;
+       size_t  endSpace = Buffer->Space - bufEnd;
+       
+       // Force to bounds
+       if(Length > Buffer->Space - Buffer->Length)
+               Length = Buffer->Space - Buffer->Length;
+       
+       if(endSpace < Length)
+       {
+               memcpy( &Buffer->Data[bufEnd], Source, endSpace );
+               memcpy( Buffer->Data, Source + endSpace, Length - endSpace );
+               Buffer->Length = Length - endSpace;
+       }
+       else
+       {
+               memcpy( &Buffer->Data[bufEnd], Source, Length );
+               Buffer->Length += Length;
+       }
+       
+       return Length;
+}
index 708c8dc..0c44288 100644 (file)
@@ -31,5 +31,5 @@ endif
 
 A_OBJ  = start.ao main.o lib.o desctab.ao errors.o irq.o
 A_OBJ += mm_phys.o mm_virt.o
-A_OBJ += proc.o time.o vm8086.o
-#A_OBJ += gdb_stub.o
+A_OBJ += proc.o proc.ao time.o vm8086.o
+A_OBJ += kpanic.o
index 43bd8e4..27b7bb1 100644 (file)
@@ -190,6 +190,7 @@ DEF_SYSCALL 0xAC    ; Acess System Call
 ; IRQs
 ; - Timer
 [global Isr240]
+[extern SchedulerBase]
 Isr240:
        push 0
        jmp SchedulerBase
@@ -281,40 +282,3 @@ IRQCommon:
        popa
        add esp, 8      ; Error Code and ID
        iret
-
-; --------------
-; Task Scheduler
-; --------------
-[extern Proc_Scheduler]
-SchedulerBase:
-       pusha
-       push ds
-       push es
-       push fs
-       push gs
-       
-       mov ax, 0x10
-       mov ds, ax
-       mov es, ax
-       mov fs, ax
-       mov gs, ax
-       
-       mov eax, [esp+12*4]     ; CPU Number
-       push eax        ; Pus as argument
-       
-       call Proc_Scheduler
-       
-       add esp, 4      ; Remove Argument
-       
-       pop gs
-       pop fs
-       pop es
-       pop ds
-
-       mov dx, 0x20
-       mov al, 0x20
-       out dx, al              ; ACK IRQ
-       popa
-       add esp, 4      ; CPU ID
-       ; No Error code / int num
-       iret
index 31c385f..d1d9cb7 100644 (file)
@@ -12,7 +12,8 @@
 // === IMPORTS ===
 extern void    MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs);
 extern void    VM8086_GPF(tRegs *Regs);
-extern void Threads_Dump();
+extern void Threads_Dump(void);
+extern void    Threads_Fault(int Num);
 
 // === PROTOTYPES ===
 void   Error_Backtrace(Uint eip, Uint ebp);
@@ -66,11 +67,34 @@ void ErrorHandler(tRegs *Regs)
                return ;
        }
        
+       // Check if it's a user mode fault
+       if( Regs->eip < KERNEL_BASE || (Regs->cs & 3) == 3 ) {
+               Log_Warning("Arch", "User Fault -  %s, Code: 0x%x",
+                       csaERROR_NAMES[Regs->int_num], Regs->err_code);
+               Log_Warning("Arch", "at CS:EIP %04x:%08x",
+                       Regs->cs, Regs->eip);
+               switch( Regs->int_num )
+               {
+               // Division by Zero
+               case  0:        Threads_Fault(FAULT_DIV0);      break;
+               // Invalid opcode
+               case  6:        Threads_Fault(FAULT_OPCODE);    break;
+               // GPF
+               case 13:        Threads_Fault(FAULT_ACCESS);    break;
+               // Floating Point Exception
+               case 16:        Threads_Fault(FAULT_FLOAT);     break;
+               
+               default:        Threads_Fault(FAULT_MISC);      break;
+               }
+               return ;
+       }
+       
+       Debug_KernelPanic();
        Warning("CPU Error %i - %s, Code: 0x%x",
                Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
        Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
        if(Regs->cs == 0x08)
-               Warning(" SS:ESP = 0x0010:%08x", 0x10, (Uint)Regs+sizeof(tRegs));
+               Warning(" SS:ESP = 0x0010:%08x", (Uint)Regs+sizeof(tRegs));
        else
                Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
        Warning(" EFLAGS = 0x%08x", Regs->eflags);
diff --git a/Kernel/arch/x86/kpanic.c b/Kernel/arch/x86/kpanic.c
new file mode 100644 (file)
index 0000000..798c513
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Acess 2 Kernel
+ * By John Hodge (thePowersGang)
+ * - x86 Kernel Panic Handler
+ */
+
+#include <acess.h>
+
+#define        FB      ((Uint16 *)(KERNEL_BASE|0xB8000))
+#define BGC    0x4F00  // White on Red
+//#define BGC  0xC000  // Black on Bright Red
+//#define BGC  0x1F00  // White on Blue (BSOD!)
+
+ int   giKP_Pos = 0;
+
+const struct {
+       Uint16  IdxPort;
+       Uint16  DatPort;
+       Uint8   Index;
+       Uint8   Value;
+}      caRegValues[] = {
+       //{0x3C0, 0x3C0, 0x10, 0x0C},   // Mode Control (Blink Enabled)
+       {0x3C0, 0x3C0, 0x10, 0x04},     // Mode Control (Blink Disabled)
+       {0x3C0, 0x3C0, 0x11, 0x00},     // Overscan Register
+       {0x3C0, 0x3C0, 0x12, 0x0F},     // Color Plane Enable
+       {0x3C0, 0x3C0, 0x13, 0x08},     // Horizontal Panning
+       {0x3C0, 0x3C0, 0x14, 0x00},     // Color Select
+       {0    , 0x3C2, 0   , 0x67},     // Miscellaneous Output Register
+       {0x3C4, 0x3C5, 0x01, 0x00},     // Clock Mode Register
+       {0x3C4, 0x3C5, 0x03, 0x00},     // Character select
+       {0x3C4, 0x3C5, 0x04, 0x07},     // Memory Mode Register
+       {0x3CE, 0x3CF, 0x05, 0x10},     // Mode Register
+       {0x3CE, 0x3CF, 0x06, 0x0E},     // Miscellaneous Register
+       {0x3D4, 0x3D5, 0x00, 0x5F},     // Horizontal Total
+       {0x3D4, 0x3D5, 0x01, 0x4F},     // Horizontal Display Enable End
+       {0x3D4, 0x3D5, 0x02, 0x50},     // Horizontal Blank Start
+       {0x3D4, 0x3D5, 0x03, 0x82},     // Horizontal Blank End
+       {0x3D4, 0x3D5, 0x04, 0x55},     // Horizontal Retrace Start
+       {0x3D4, 0x3D5, 0x05, 0x81},     // Horizontal Retrace End
+       {0x3D4, 0x3D5, 0x06, 0xBF},     // Vertical Total
+       {0x3D4, 0x3D5, 0x07, 0x1F},     // Overflow Register
+       {0x3D4, 0x3D5, 0x08, 0x00},     // Preset row scan
+       {0x3D4, 0x3D5, 0x09, 0x4F},     // Maximum Scan Line
+       {0x3D4, 0x3D5, 0x10, 0x9C},     // Vertical Retrace Start
+       {0x3D4, 0x3D5, 0x11, 0x8E},     // Vertical Retrace End
+       {0x3D4, 0x3D5, 0x12, 0x8F},     // Vertical Display Enable End
+       {0x3D4, 0x3D5, 0x13, 0x28},     // Logical Width
+       {0x3D4, 0x3D5, 0x14, 0x1F},     // Underline Location
+       {0x3D4, 0x3D5, 0x15, 0x96},     // Vertical Blank Start
+       {0x3D4, 0x3D5, 0x16, 0xB9},     // Vertical Blank End
+       {0x3D4, 0x3D5, 0x17, 0xA3}      // CRTC Mode Control
+};
+#define        NUM_REGVALUES   (sizeof(caRegValues)/sizeof(caRegValues[0]))
+
+/**
+ * \brief Sets the screen mode for a kernel panic
+ */
+void KernelPanic_SetMode()
+{
+        int    i;
+       
+       // This function is called by Panic(), but MM_PageFault and the
+       // CPU exception handers also call it, so let's not clear the screen
+       // twice
+       if( giKP_Pos )  return ;
+       
+       // Restore VGA 0xB8000 text mode
+       #if 1
+       for( i = 0; i < NUM_REGVALUES; i++ )
+       {
+               // Reset Flip-Flop
+               if( caRegValues[i].IdxPort == 0x3C0 )   inb(0x3DA);
+               
+               if( caRegValues[i].IdxPort )
+                       outb(caRegValues[i].IdxPort, caRegValues[i].Index);
+               outb(caRegValues[i].DatPort, caRegValues[i].Value);
+       }
+       
+       inb(0x3DA);
+       outb(0x3C0, 0x20);
+       #endif
+       
+       // Clear Screen
+       for( i = 0; i < 80*25; i++ )
+       {
+               FB[i] = BGC;
+       }
+}
+
+void KernelPanic_PutChar(char Ch)
+{
+       if( giKP_Pos > 80*25 )  return ;
+       switch(Ch)
+       {
+       case '\t':
+               do {
+                       FB[giKP_Pos] &= 0xFF00;
+                       FB[giKP_Pos++] |= ' ';
+               } while(giKP_Pos & 7);
+               break;
+       
+       case '\n':
+               giKP_Pos += 80;
+       case '\r':
+               giKP_Pos -= giKP_Pos % 80;
+               break;
+       
+       default:
+               if(' ' <= Ch && Ch < 0x7F)
+               {
+                       FB[giKP_Pos] &= 0xFF00;
+                       FB[giKP_Pos] |= Ch;
+               }
+               giKP_Pos ++;
+               break;
+       }
+}
index 2fe1764..75b712f 100644 (file)
@@ -24,6 +24,7 @@ SECTIONS {
                _UsertextBase = .;
                *(.usertext)
        }
+       _UsertextEnd = .;
        
        .rodata ALIGN(0x1000): AT(ADDR(.rodata) - 0xC0000000) {
                *(.initpd)
index fa3cb45..2dca563 100644 (file)
@@ -23,11 +23,20 @@ extern int  Time_Setup(void);
 extern Uint    Proc_Clone(Uint *Err, Uint Flags);
 extern void    Threads_Sleep(void);
 extern void    Threads_Exit(void);
+// --- Core ---
+extern void    System_Init(char *Commandline);
 
-extern int     Modules_LoadBuiltins(void);
+// === PROTOTYPES ===
+void   Arch_LoadBootModules(void);
 
 // === GLOBALS ===
 char   *gsBootCmdLine = NULL;
+struct {
+       void    *Base;
+       Uint    Size;
+       char    *ArgString;
+}      *gaArch_BootModules;
+ int   giArch_NumBootModules = 0;
 
 // === CODE ===
 int kmain(Uint MbMagic, void *MbInfoPtr)
@@ -81,35 +90,44 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        // Load Virtual Filesystem
        VFS_Init();
        
-       // Initialise builtin modules
-       Log_Log("Arch", "Initialising builtin modules...");
-       Modules_LoadBuiltins();
-       
-       Log_Log("Arch", "Loading %i Modules...", mbInfo->ModuleCount);
-       
        // Load initial modules
        mods = (void*)( mbInfo->Modules + KERNEL_BASE );
+       giArch_NumBootModules = mbInfo->ModuleCount;
+       gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) );
        for( i = 0; i < mbInfo->ModuleCount; i ++ )
        {
                // Adjust into higher half
-               mods[i].Start += KERNEL_BASE;
-               mods[i].End += KERNEL_BASE;
+               mods[i].Start  += KERNEL_BASE;
+               mods[i].End    += KERNEL_BASE;
                mods[i].String += KERNEL_BASE;
                
-               Log_Log("Arch", "Loading '%s'", mods[i].String);
-               
-               if( !Module_LoadMem( (void *)mods[i].Start, mods[i].End-mods[i].Start, (char *)mods[i].String ) )
-               {
-                       Log_Warning("Arch", "Unable to load module\n");
-               }
+               gaArch_BootModules[i].Base = (void *)mods[i].Start;
+               gaArch_BootModules[i].Size = mods[i].End - mods[i].Start;
+               gaArch_BootModules[i].ArgString = (char *)mods[i].String;
        }
        
        // Pass on to Independent Loader
        Log_Log("Arch", "Starting system");
-       System_Init( gsBootCmdLine );
+       System_Init(gsBootCmdLine);
        
        // Sleep forever (sleeping beauty)
        for(;;)
                Threads_Sleep();
        return 0;
 }
+
+void Arch_LoadBootModules(void)
+{
+        int    i;
+       for( i = 0; i < giArch_NumBootModules; i ++ )
+       {
+               Log_Log("Arch", "Loading '%s'", gaArch_BootModules[i].ArgString);
+               
+               if( !Module_LoadMem( gaArch_BootModules[i].Base, gaArch_BootModules[i].Size, gaArch_BootModules[i].ArgString ) )
+               {
+                       Log_Warning("Arch", "Unable to load module\n");
+               }
+       }
+       Log_Log("Arch", "Boot modules loaded");
+       free( gaArch_BootModules );
+}
index cf77b87..9c93334 100644 (file)
@@ -66,6 +66,7 @@ typedef Uint32        tTabEnt;
 #endif
 
 // === IMPORTS ===
+extern void    _UsertextEnd, _UsertextBase;
 extern Uint32  gaInitPageDir[1024];
 extern Uint32  gaInitPageTable[1024];
 extern void    Threads_SegFault(tVAddr Addr);
@@ -153,6 +154,12 @@ void MM_InstallVirtual()
                memset( &gaPageTable[i*1024], 0, 0x1000 );
        }
        #endif
+       
+       // Unset kernel on the User Text pages
+       for( i = ((tVAddr)&_UsertextEnd-(tVAddr)&_UsertextBase+0xFFF)/4096; i--; ) {
+               Log("MM_SetFlags( 0x%08x, 0, MM_PFLAG_KERNEL)", (tVAddr)&_UsertextBase + i*4096);
+               MM_SetFlags( (tVAddr)&_UsertextBase + i*4096, 0, MM_PFLAG_KERNEL );
+       }
 }
 
 /**
@@ -214,6 +221,8 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
                return ;
        }
        
+       Debug_KernelPanic();
+       
        // -- Check Error Code --
        if(ErrorCode & 8)
                Warning("Reserved Bits Trashed!");
@@ -779,15 +788,25 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
        // Read-Only
        if( Mask & MM_PFLAG_RO )
        {
-               if( Flags & MM_PFLAG_RO )       *ent &= ~PF_WRITE;
-               else    *ent |= PF_WRITE;
+               if( Flags & MM_PFLAG_RO ) {
+                       *ent &= ~PF_WRITE;
+               }
+               else {
+                       gaPageDir[VAddr >> 22] |= PF_WRITE;
+                       *ent |= PF_WRITE;
+               }
        }
        
        // Kernel
        if( Mask & MM_PFLAG_KERNEL )
        {
-               if( Flags & MM_PFLAG_KERNEL )   *ent &= ~PF_USER;
-               else    *ent |= PF_USER;
+               if( Flags & MM_PFLAG_KERNEL ) {
+                       *ent &= ~PF_USER;
+               }
+               else {
+                       gaPageDir[VAddr >> 22] |= PF_USER;
+                       *ent |= PF_USER;
+               }
        }
        
        // Copy-On-Write
@@ -802,6 +821,9 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
                        *ent |= PF_WRITE;
                }
        }
+       
+       //Log("MM_SetFlags: *ent = 0x%08x, gaPageDir[%i] = 0x%08x",
+       //      *ent, VAddr >> 22, gaPageDir[VAddr >> 22]);
 }
 
 /**
@@ -1002,17 +1024,21 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
 void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
 {
         int    i, j;
+       
+       //Log_Debug("VirtMem", "MM_UnmapHWPages: (VAddr=0x%08x, Number=%i)", VAddr, Number);
+       
        // Sanity Check
-       if(VAddr < HW_MAP_ADDR || VAddr-Number*0x1000 > HW_MAP_MAX)     return;
+       if(VAddr < HW_MAP_ADDR || VAddr+Number*0x1000 > HW_MAP_MAX)     return;
        
        i = VAddr >> 12;
        
        LOCK( &gilTempMappings );       // Temp and HW share a directory, so they share a lock
        
+       
        for( j = 0; j < Number; j++ )
        {
-               MM_DerefPhys( gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] );
-               gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] = 0;
+               MM_DerefPhys( gaPageTable[ i + j ] & ~0xFFF );
+               gaPageTable[ i + j ] = 0;
        }
        
        RELEASE( &gilTempMappings );
diff --git a/Kernel/arch/x86/proc.asm b/Kernel/arch/x86/proc.asm
new file mode 100644 (file)
index 0000000..b1843c7
--- /dev/null
@@ -0,0 +1,126 @@
+; AcessOS Microkernel Version
+; Start.asm
+
+[bits 32]
+
+KERNEL_BASE    equ 0xC0000000
+
+KSTACK_USERSTATE_SIZE  equ     (4+8+1+5)*4     ; SRegs, GPRegs, CPU, IRET
+
+[section .text]
+; --------------
+; Task Scheduler
+; --------------
+[extern Proc_Scheduler]
+[global SchedulerBase]
+SchedulerBase:
+       pusha
+       push ds
+       push es
+       push fs
+       push gs
+       
+       mov ax, 0x10
+       mov ds, ax
+       mov es, ax
+       mov fs, ax
+       mov gs, ax
+       
+       mov eax, [esp+12*4]     ; CPU Number
+       push eax        ; Pus as argument
+       
+       call Proc_Scheduler
+       
+       add esp, 4      ; Remove Argument
+       
+       pop gs
+       pop fs
+       pop es
+       pop ds
+
+       mov dx, 0x20
+       mov al, 0x20
+       out dx, al              ; ACK IRQ
+       popa
+       add esp, 4      ; CPU ID
+       ; No Error code / int num
+       iret
+
+[extern Proc_Clone]
+[extern Threads_Exit]
+[global SpawnTask]
+SpawnTask:
+       ; Call Proc_Clone with Flags=0
+       xor eax, eax
+       push eax
+       push eax
+       call Proc_Clone
+       add esp, 8      ; Remove arguments from stack
+       
+       test eax, eax
+       jnz .parent
+       
+       ; In child, so now set up stack frame
+       mov ebx, [esp+4]        ; Child Function
+       mov edx, [esp+8]        ; Argument
+       ; Child
+       push edx        ; Argument
+       call ebx        ; Function
+       call Threads_Exit       ; Kill Thread
+       
+.parent:
+       ret
+
+;
+; Calls a user fault handler
+;
+[global Proc_AlterUserReturnAddr]
+[extern Proc_GetCurThread]
+Proc_AlterUserReturnAddr:
+       ; EBP is the handler to use
+       
+       call Proc_GetCurThread
+       xchg bx, bx
+       
+       ; EAX is the current thread
+       mov ebx, eax
+       mov eax, [ebx+40]       ; Get Kernel Stack
+       sub eax, KSTACK_USERSTATE_SIZE  
+       
+       ;
+       ; NOTE: This can cause corruption if the signal happens while the user
+       ;       has called a kernel operation.
+       ; Good thing this can only be called on a user fault.
+       ;
+       
+       ; Get and alter User SP
+       mov ecx, [eax+KSTACK_USERSTATE_SIZE-12]
+       mov edx, [ebx+60]       ; Get Signal Number
+       mov [ecx-4], edx
+       mov [ecx-8], DWORD User_Syscall_RetAndExit
+       sub ecx, 8
+       
+       ; Restore Segment Registers
+       mov ax, 0x23
+       mov ds, ax
+       mov es, ax
+       mov fs, ax
+       mov gs, ax
+       
+       push 0x23       ; SS
+       push ecx        ; ESP
+       push 0x202      ; EFLAGS (IP and Rsvd)
+       push 0x1B       ; CS
+       push ebp        ; EIP
+       
+       iret
+
+
+[section .usertext]
+User_Syscall_RetAndExit:
+       push eax
+       call User_Syscall_Exit
+User_Syscall_Exit:
+       xor eax, eax
+       mov ebx, [esp+4]
+       int 0xAC
index 3b5ceb2..e988416 100644 (file)
@@ -39,6 +39,7 @@ extern tThread        *Threads_GetNextToRun(int CPU);
 extern void    Threads_Dump();
 extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
 extern void    Isr8(); // Double Fault
+extern void    Proc_AlterUserReturnAddr();
 
 // === PROTOTYPES ===
 void   ArchThreads_Init();
@@ -51,6 +52,7 @@ tThread       *Proc_GetCurThread();
 void   Proc_ChangeStack();
  int   Proc_Clone(Uint *Err, Uint Flags);
 void   Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP);
+void   Proc_CallFaultHandler(tThread *Thread);
 void   Proc_Scheduler();
 
 // === GLOBALS ===
@@ -693,6 +695,18 @@ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs)
        return 0;
 }
 
+/**
+ * \brief Calls a signal handler in user mode
+ * \note Used for signals
+ */
+void Proc_CallFaultHandler(tThread *Thread)
+{
+       // Rewinds the stack and calls the user function
+       // Never returns
+       __asm__ __volatile__ ("mov %0, %%ebp;\n\tcall Proc_AlterUserReturnAddr" :: "r"(Thread->FaultHandler));
+       for(;;);
+}
+
 /**
  * \fn void Proc_Scheduler(int CPU)
  * \brief Swap current thread and clears dead threads
@@ -779,6 +793,14 @@ void Proc_Scheduler(int CPU)
        #else
                __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3));
        #endif
+       
+       #if 0
+       if(thread->SavedState.ESP > 0xC0000000
+       && thread->SavedState.ESP < thread->KernelStack-0x2000) {
+               Log_Warning("Proc", "Possible bad ESP %p (PID %i)", thread->SavedState.ESP);
+       }
+       #endif
+       
        // Switch threads
        __asm__ __volatile__ (
                "mov %1, %%esp\n\t"     // Restore ESP
index d9a1e50..b98a016 100644 (file)
@@ -168,31 +168,6 @@ CallWithArgArray:
        pop ebp\r
        ret\r
 \r
-[extern Proc_Clone]\r
-[extern Threads_Exit]\r
-[global SpawnTask]\r
-SpawnTask:\r
-       ; Call Proc_Clone with Flags=0\r
-       xor eax, eax\r
-       push eax
-       push eax\r
-       call Proc_Clone\r
-       add esp, 8      ; Remove arguments from stack\r
-       \r
-       test eax, eax\r
-       jnz .parent\r
-       \r
-       ; In child, so now set up stack frame\r
-       mov ebx, [esp+4]        ; Child Function\r
-       mov edx, [esp+8]        ; Argument\r
-       ; Child\r
-       push edx        ; Argument\r
-       call ebx        ; Function\r
-       call Threads_Exit       ; Kill Thread\r
-       \r
-.parent:\r
-       ret\r
-\r
 [section .initpd]\r
 [global gaInitPageDir]\r
 [global gaInitPageTable]\r
index 5f7d592..cdf2370 100644 (file)
@@ -8,8 +8,9 @@
 // === MACROS ===
 #define        NUM_TIMERS      8
 #define        TIMER_QUANTUM   100
-#define TIMER_RATE     13      // (Max: 15, Min: 2) - 15 = 1Hz, 13 = 4Hz, 10 = 1024Hz
-#define TIMER_FREQ     (32768>>TIMER_RATE)     //Hz
+// 2^(15-rate), 15: 1HZ, 5: 1024Hz, 2: 8192Hz
+#define TIMER_RATE     12      // (Max: 15, Min: 2) - 15 = 1Hz, 13 = 4Hz, 12 = 8Hz, 11 = 16Hz 10 = 32Hz, 2
+#define TIMER_FREQ     (0x8000>>TIMER_RATE)    //Hz
 #define MS_PER_TICK_WHOLE      (1000/(TIMER_FREQ))
 #define MS_PER_TICK_FRACT      ((Uint64)(1000*TIMER_FREQ-((Uint64)MS_PER_TICK_WHOLE)*0x80000000/TIMER_FREQ))
 
index 8ef7453..1816eac 100644 (file)
 #define VM8086_STACK_OFS       0x0AFE
 enum eVM8086_Opcodes
 {
-       VM8086_OP_PUSHF = 0x9C,
-       VM8086_OP_POPF  = 0x9D,
-       VM8086_OP_INT_I = 0xCD,
-       VM8086_OP_IRET  = 0xCF,
-       VM8086_OP_IN_AD = 0xEC,
-       VM8086_OP_IN_ADX= 0xED
+       VM8086_OP_PUSHF   = 0x9C,
+       VM8086_OP_POPF    = 0x9D,
+       VM8086_OP_INT_I   = 0xCD,
+       VM8086_OP_IRET    = 0xCF,
+       VM8086_OP_IN_AD   = 0xEC,
+       VM8086_OP_IN_ADX  = 0xED,
+       VM8086_OP_OUT_AD  = 0xEE,
+       VM8086_OP_OUT_ADX = 0xEF
 };
 #define VM8086_PAGES_PER_INST  4
 
@@ -45,13 +47,16 @@ MODULE_DEFINE(0, 0x100, VM8086, VM8086_Install, NULL, NULL);
 tSpinlock      glVM8086_Process;
 tPID   gVM8086_WorkerPID;
 tTID   gVM8086_CallingThread;
-tVM8086        * volatile gpVM8086_State;
+tVM8086        * volatile gpVM8086_State = (void*)-1;  // Set to -1 to avoid race conditions
 
 // === FUNCTIONS ===
 int VM8086_Install(char **Arguments)
 {
        tPID    pid;    
        
+       // Lock to avoid race conditions
+       LOCK( &glVM8086_Process );
+       
        // Create BIOS Call process
        pid = Proc_Clone(NULL, CLONE_VM);
        if(pid == -1)
@@ -139,6 +144,11 @@ void VM8086_GPF(tRegs *Regs)
        if(Regs->eip == VM8086_MAGIC_IP && Regs->cs == VM8086_MAGIC_CS
        && Threads_GetPID() == gVM8086_WorkerPID)
        {
+               if( gpVM8086_State == (void*)-1 ) {
+                       Log_Log("VM8086", "Worker thread ready and waiting");
+                       RELEASE( &glVM8086_Process );   // Release lock obtained in VM8086_Install
+                       gpVM8086_State = NULL;
+               }
                if( gpVM8086_State ) {
                        gpVM8086_State->AX = Regs->eax; gpVM8086_State->CX = Regs->ecx;
                        gpVM8086_State->DX = Regs->edx; gpVM8086_State->BX = Regs->ebx;
@@ -176,7 +186,7 @@ void VM8086_GPF(tRegs *Regs)
                return ;
        }
        
-       opcode = *(Uint8*)( KERNEL_BASE + (Regs->cs*16) + (Regs->eip) );
+       opcode = *(Uint8*)( (Regs->cs*16) + (Regs->eip) );
        Regs->eip ++;
        switch(opcode)
        {
@@ -237,13 +247,13 @@ void VM8086_GPF(tRegs *Regs)
                #endif
                break;
                
-       case 0xEE:      //OUT DX, AL
+       case VM8086_OP_OUT_AD:  //OUT DX, AL
                outb(Regs->edx&0xFFFF, Regs->eax&0xFF);
                #if TRACE_EMU
                Log_Debug("VM8086", "Emulated OUT DX, AL (*0x%04x = 0x%02x)\n", Regs->edx&0xFFFF, Regs->eax&0xFF);
                #endif
                break;
-       case 0xEF:      //OUT DX, AX
+       case VM8086_OP_OUT_ADX: //OUT DX, AX
                outw(Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #if TRACE_EMU
                Log_Debug("VM8086", "Emulated OUT DX, AX (*0x%04x = 0x%04x)\n", Regs->edx&0xFFFF, Regs->eax&0xFFFF);
@@ -257,8 +267,31 @@ void VM8086_GPF(tRegs *Regs)
                break;
        
        case 0x66:
-               Log_Warning("VM8086", "Code at %04x:%04x attempted to use an operand override, ignored",
-                       Regs->cs, Regs->eip);
+               opcode = *(Uint8*)( (Regs->cs*16) + (Regs->eip&0xFFFF));
+               switch( opcode )
+               {
+               case VM8086_OP_IN_ADX:  //IN AX, DX
+                       Regs->eax = ind(Regs->edx&0xFFFF);
+                       #if TRACE_EMU
+                       Log_Debug("VM8086", "Emulated IN EAX, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+                       #endif
+                       break;
+               case VM8086_OP_OUT_ADX: //OUT DX, AX
+                       outd(Regs->edx&0xFFFF, Regs->eax);
+                       #if TRACE_EMU
+                       Log_Debug("VM8086", "Emulated OUT DX, EAX (*0x%04x = 0x%08x)\n", Regs->edx&0xFFFF, Regs->eax);
+                       #endif
+                       break;
+               default:
+                       Log_Error("VM8086", "Error - Unknown opcode 66 %02x caused a GPF at %04x:%04x",
+                               Regs->cs, Regs->eip,
+                               opcode
+                               );
+                       // Force an end to the call
+                       Regs->cs = VM8086_MAGIC_CS;
+                       Regs->eip = VM8086_MAGIC_IP;
+                       break;
+               }
                break;
        
        default:
index 4b3aeb7..b9e5cdc 100644 (file)
@@ -9,15 +9,28 @@
 #define DEBUG_TO_SERIAL        1
 #define        SERIAL_PORT     0x3F8
 #define        GDB_SERIAL_PORT 0x2F8
+#define DEBUG_USE_VSNPRINTF    1
+#define        DEBUG_MAX_LINE_LEN      256
 
 // === IMPORTS ===
-extern void Threads_Dump();
+extern void Threads_Dump(void);
+extern void    KernelPanic_SetMode(void);
+extern void    KernelPanic_PutChar(char Ch);
+
+// === PROTOTYPES ===
+ int   putDebugChar(char ch);
+ int   getDebugChar();
+static void    Debug_Putchar(char ch);
+static void    Debug_Puts(char *Str);
+void   Debug_Fmt(const char *format, va_list args);
 
 // === GLOBALS ===
  int   gDebug_Level = 0;
  int   giDebug_KTerm = -1;
  int   gbDebug_SerialSetup = 0;
  int   gbGDB_SerialSetup = 0;
+ int   gbDebug_IsKPanic = 0;
+volatile int   gbInPutChar = 0;
 
 // === CODE ===
 int putDebugChar(char ch)
@@ -54,9 +67,10 @@ int getDebugChar()
 
 static void Debug_Putchar(char ch)
 {
-       if(giDebug_KTerm != -1)
-               VFS_Write(giDebug_KTerm, 1, &ch);
-
+       #if DEBUG_TO_E9
+       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
+       #endif
+       
        #if DEBUG_TO_SERIAL
        if(!gbDebug_SerialSetup) {
                outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
@@ -71,19 +85,71 @@ static void Debug_Putchar(char ch)
        while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
        outb(SERIAL_PORT, ch);
        #endif
-
-       #if DEBUG_TO_E9
-       __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
-       #endif
+       
+       if( !gbDebug_IsKPanic )
+       {
+               if(gbInPutChar) return ;
+               gbInPutChar = 1;
+               if(giDebug_KTerm != -1)
+                       VFS_Write(giDebug_KTerm, 1, &ch);
+               gbInPutChar = 0;
+       }
+       else
+               KernelPanic_PutChar(ch);
 }
 
 static void Debug_Puts(char *Str)
 {
-       while(*Str)     Debug_Putchar(*Str++);
+        int    len = 0;
+       while( *Str )
+       {
+               #if DEBUG_TO_E9
+               __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a" ((Uint8)*Str) );
+               #endif
+               
+               #if DEBUG_TO_SERIAL
+               if(!gbDebug_SerialSetup) {
+                       outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+                       outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+                       outb(SERIAL_PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
+                       outb(SERIAL_PORT + 1, 0x00);    //                  (hi byte)
+                       outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+                       outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+                       outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+                       gbDebug_SerialSetup = 1;
+               }
+               while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
+               outb(SERIAL_PORT, *Str);
+               #endif
+               
+               if( gbDebug_IsKPanic )
+                       KernelPanic_PutChar(*Str);
+               len ++;
+               Str ++;
+       }
+       
+       Str -= len;
+       
+       if( !gbDebug_IsKPanic && giDebug_KTerm != -1)
+       {
+               if(gbInPutChar) return ;
+               gbInPutChar = 1;
+               VFS_Write(giDebug_KTerm, len, Str);
+               gbInPutChar = 0;
+       }
 }
 
-void Debug_Fmt(const char *format, va_list *args)
+void Debug_Fmt(const char *format, va_list args)
 {
+       #if DEBUG_USE_VSNPRINTF
+       char    buf[DEBUG_MAX_LINE_LEN];
+        int    len;
+       len = vsnprintf(buf, DEBUG_MAX_LINE_LEN-1, format, args);
+       //if( len < DEBUG_MAX_LINE )
+               // do something
+       Debug_Puts(buf);
+       return ;
+       #else
        char    c, pad = ' ';
         int    minSize = 0, len;
        char    tmpBuf[34];     // For Integers
@@ -217,6 +283,13 @@ void Debug_Fmt(const char *format, va_list *args)
                        break;
                }
     }
+    #endif
+}
+
+void Debug_KernelPanic()
+{
+       gbDebug_IsKPanic = 1;
+       KernelPanic_SetMode();
 }
 
 /**
@@ -228,7 +301,7 @@ void LogF(char *Fmt, ...)
 
        va_start(args, Fmt);
 
-       Debug_Fmt(Fmt, &args);
+       Debug_Fmt(Fmt, args);
 
        va_end(args);
 }
@@ -241,7 +314,7 @@ void Log(char *Fmt, ...)
 
        Debug_Puts("Log: ");
        va_start(args, Fmt);
-       Debug_Fmt(Fmt, &args);
+       Debug_Fmt(Fmt, args);
        va_end(args);
        Debug_Putchar('\n');
 }
@@ -250,16 +323,19 @@ void Warning(char *Fmt, ...)
        va_list args;
        Debug_Puts("Warning: ");
        va_start(args, Fmt);
-       Debug_Fmt(Fmt, &args);
+       Debug_Fmt(Fmt, args);
        va_end(args);
        Debug_Putchar('\n');
 }
 void Panic(char *Fmt, ...)
 {
        va_list args;
+       
+       Debug_KernelPanic();
+       
        Debug_Puts("Panic: ");
        va_start(args, Fmt);
-       Debug_Fmt(Fmt, &args);
+       Debug_Fmt(Fmt, args);
        va_end(args);
        Debug_Putchar('\n');
 
@@ -272,10 +348,16 @@ void Panic(char *Fmt, ...)
 
 void Debug_SetKTerminal(char *File)
 {
-       if(giDebug_KTerm != -1)
-               VFS_Close(giDebug_KTerm);
-       giDebug_KTerm = VFS_Open(File, VFS_OPENFLAG_WRITE);
-       Log_Log("Debug", "Opened '%s' as 0x%x", File, giDebug_KTerm);
+        int    tmp;
+       if(giDebug_KTerm != -1) {
+               tmp = giDebug_KTerm;
+               giDebug_KTerm = -1;
+               VFS_Close(tmp);
+       }
+       tmp = VFS_Open(File, VFS_OPENFLAG_WRITE);
+       Log_Log("Debug", "Opened '%s' as 0x%x", File, tmp);
+       giDebug_KTerm = tmp;
+       Log_Log("Debug", "Returning to %p", __builtin_return_address(0));
 }
 
 void Debug_Enter(char *FuncName, char *ArgTypes, ...)
@@ -301,15 +383,15 @@ void Debug_Enter(char *FuncName, char *ArgTypes, ...)
                if(pos != -1)   ArgTypes[pos] = ' ';
                switch(*ArgTypes)
                {
-               case 'p':       Debug_Fmt("%p", &args); break;
-               case 's':       Debug_Fmt("'%s'", &args);       break;
-               case 'i':       Debug_Fmt("%i", &args); break;
-               case 'u':       Debug_Fmt("%u", &args); break;
-               case 'x':       Debug_Fmt("0x%x", &args);       break;
-               case 'b':       Debug_Fmt("0b%b", &args);       break;
+               case 'p':       Debug_Fmt("%p", args);  break;
+               case 's':       Debug_Fmt("'%s'", args);        break;
+               case 'i':       Debug_Fmt("%i", args);  break;
+               case 'u':       Debug_Fmt("%u", args);  break;
+               case 'x':       Debug_Fmt("0x%x", args);        break;
+               case 'b':       Debug_Fmt("0b%b", args);        break;
                // Extended (64-Bit)
-               case 'X':       Debug_Fmt("0x%llx", &args);     break;
-               case 'B':       Debug_Fmt("0b%llb", &args);     break;
+               case 'X':       Debug_Fmt("0x%llx", args);      break;
+               case 'B':       Debug_Fmt("0b%llb", args);      break;
                }
                if(pos != -1) {
                        Debug_Putchar(',');     Debug_Putchar(' ');
@@ -333,7 +415,7 @@ void Debug_Log(char *FuncName, char *Fmt, ...)
        while(i--)      Debug_Putchar(' ');
 
        Debug_Puts(FuncName);   Debug_Puts(": ");
-       Debug_Fmt(Fmt, &args);
+       Debug_Fmt(Fmt, args);
 
        va_end(args);
        Debug_Putchar('\n');
@@ -365,13 +447,13 @@ void Debug_Leave(char *FuncName, char RetType, ...)
        switch(RetType)
        {
        case 'n':       Debug_Puts("NULL");     break;
-       case 'p':       Debug_Fmt("%p", &args); break;
-       case 's':       Debug_Fmt("'%s'", &args);       break;
-       case 'i':       Debug_Fmt("%i", &args); break;
-       case 'u':       Debug_Fmt("%u", &args); break;
-       case 'x':       Debug_Fmt("0x%x", &args);       break;
+       case 'p':       Debug_Fmt("%p", args);  break;
+       case 's':       Debug_Fmt("'%s'", args);        break;
+       case 'i':       Debug_Fmt("%i", args);  break;
+       case 'u':       Debug_Fmt("%u", args);  break;
+       case 'x':       Debug_Fmt("0x%x", args);        break;
        // Extended (64-Bit)
-       case 'X':       Debug_Fmt("0x%llx", &args);     break;
+       case 'X':       Debug_Fmt("0x%llx", args);      break;
        }
        Debug_Putchar('\n');
 
index 6577882..5e07840 100644 (file)
@@ -183,6 +183,7 @@ void KB_IRQHandler()
        {
                switch(ch)
                {
+               case 'q':       *((int*)1) = 0; break;
                case 'd':       __asm__ __volatile__ ("xchg %bx, %bx"); break;
                case 'p':       Threads_Dump(); break;
                }
index b0c9662..700eae9 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Acess2 VGA Controller Driver
  */
+#define DEBUG  0
 #include <acess.h>
 #include <fs_devfs.h>
 #include <tpl_drv_video.h>
index cf4efc7..d010625 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Acess2 Virtual Terminal Driver
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <acess.h>
 #include <fs_devfs.h>
 #include <modules.h>
 #define        NUM_VTS 8
 #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       "BochsGA"
-//#define DEFAULT_OUTPUT       "Vesa"
+#define DEFAULT_OUTPUT "Vesa"
 #define DEFAULT_INPUT  "PS2Keyboard"
-#define        DEFAULT_WIDTH   80
-#define        DEFAULT_HEIGHT  25
+#define        DEFAULT_WIDTH   640
+#define        DEFAULT_HEIGHT  480
+#define DEFAULT_SCROLLBACK     2       // 2 Screens of text + current screen
+#define        TEXTTERM_WIDTH  (BOOT_WIDTH/8)
+#define        TEXTTERM_HEIGHT (BOOT_WIDTH/16)
 #define        DEFAULT_COLOUR  (VT_COL_BLACK|(0xAAA<<16))
 
 #define        VT_FLAG_HIDECSR 0x01
@@ -63,22 +64,29 @@ extern void Debug_SetKTerminal(char *File);
 
 // === PROTOTYPES ===
  int   VT_Install(char **Arguments);
+void   VT_InitOutput(void);
+void   VT_InitInput(void);
 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_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data);
+void   VT_SetResolution(int Width, int Height);
+void   VT_SetMode(int Mode);
 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);
 void   VT_int_PutChar(tVTerm *Term, Uint32 Ch);
+void   VT_int_ScrollFramebuffer( tVTerm *Term );
 void   VT_int_UpdateScreen( tVTerm *Term, int UpdateAll );
 void   VT_int_ChangeMode(tVTerm *Term, int NewMode);
 
 // === CONSTANTS ===
 const Uint16   caVT100Colours[] = {
+               // Black, Red, Green, Yellow, Blue, Purple, Cyan, Gray
+               // Same again, but bright
                VT_COL_BLACK, 0x700, 0x070, 0x770, 0x007, 0x707, 0x077, 0xAAA,
                VT_COL_GREY, 0xF00, 0x0F0, 0xFF0, 0x00F, 0xF0F, 0x0FF, VT_COL_WHITE
        };
@@ -100,10 +108,11 @@ tDevFS_Driver     gVT_DrvInfo = {
 // --- Terminals ---
 tVTerm gVT_Terminals[NUM_VTS];
  int   giVT_CurrentTerminal = 0;
+tVTerm *gpVT_CurTerm = &gVT_Terminals[0];
 // --- Video State ---
-short  giVT_RealWidth; //!< Real Width
-short  giVT_RealHeight;        //!< Real Height
- int   gbVT_TextMode = 1;
+short  giVT_RealWidth  = DEFAULT_WIDTH;        //!< Screen Width
+short  giVT_RealHeight = DEFAULT_HEIGHT;       //!< Screen Height
+ int   giVT_Scrollback = DEFAULT_SCROLLBACK;
 // --- Driver Handles ---
 char   *gsVT_OutputDevice = NULL;
 char   *gsVT_InputDevice = NULL;
@@ -121,37 +130,35 @@ char      *gsVT_InputDevice = NULL;
  */
 int VT_Install(char **Arguments)
 {
-       char    **args = Arguments;
-       char    *arg;
         int    i;
        
        // Scan Arguments
        if(Arguments)
        {
+               char    **args = Arguments;
+               char    *arg, *opt, *val;
                for( ; (arg = *args); args++ )
                {
-                       if(arg[0] != '-')       continue;
+                       Log_Debug("VTerm", "Argument '%s'", arg);
+                       opt = arg;
+                       val = arg + strpos(arg, '=');   *val++ = '\0';
                        
-                       switch(arg[1])
-                       {
-                       // Set output device
-                       case 'o':
-                               if(args[1] ==  NULL)    break;
+                       if( strcmp(opt, "Video") == 0 ) {
                                if(gsVT_OutputDevice)   free(gsVT_OutputDevice);
-                               gsVT_OutputDevice = malloc(strlen(args[1])+1);
-                               strcpy(gsVT_OutputDevice, args[1]);
-                               args ++;
-                               break;
-                       
-                       // Set input device
-                       case 'i':
-                               if(args[1] == NULL)     break;
+                               gsVT_OutputDevice = strdup(val);
+                       }
+                       else if( strcmp(opt, "Input") == 0 ) {
                                if(gsVT_InputDevice)    free(gsVT_InputDevice);
-                               gsVT_InputDevice = malloc(strlen(args[1])+1);
-                               strcpy(gsVT_InputDevice, args[1]);
-                               args ++;
-                               break;
-                       
+                               gsVT_InputDevice = strdup(val);
+                       }
+                       else if( strcmp(opt, "Width") == 0 ) {
+                               giVT_RealWidth = atoi( val );
+                       }
+                       else if( strcmp(opt, "Height") == 0 ) {
+                               giVT_RealHeight = atoi( val );
+                       }
+                       else if( strcmp(opt, "Scrollback") == 0 ) {
+                               giVT_Scrollback = atoi( val );
                        }
                }
        }
@@ -168,13 +175,16 @@ int VT_Install(char **Arguments)
        {
                gVT_Terminals[i].Mode = TERM_MODE_TEXT;
                gVT_Terminals[i].Flags = 0;
-               gVT_Terminals[i].Width = DEFAULT_WIDTH;
-               gVT_Terminals[i].Height = DEFAULT_HEIGHT;
+               gVT_Terminals[i].Width = giVT_RealWidth/giVT_CharWidth;
+               gVT_Terminals[i].Height = giVT_RealHeight/giVT_CharHeight;
                gVT_Terminals[i].CurColour = DEFAULT_COLOUR;
                gVT_Terminals[i].WritePos = 0;
                gVT_Terminals[i].ViewPos = 0;
                
-               gVT_Terminals[i].Buffer = calloc( DEFAULT_WIDTH*DEFAULT_HEIGHT*VT_SCROLLBACK, sizeof(tVT_Char) );
+               gVT_Terminals[i].Buffer = calloc(
+                       gVT_Terminals[i].Width*gVT_Terminals[i].Height*(giVT_Scrollback+1),
+                       sizeof(tVT_Char)
+                       );
                
                gVT_Terminals[i].Name[0] = '0'+i;
                gVT_Terminals[i].Name[1] = '\0';
@@ -190,9 +200,13 @@ int VT_Install(char **Arguments)
        // Add to DevFS
        DevFS_AddDevice( &gVT_DrvInfo );
        
+       VT_InitOutput();
+       VT_InitInput();
+       
        // Set kernel output to VT0
        Debug_SetKTerminal("/Devices/VTerm/0");
        
+       Log_Log("VTerm", "Returning %i", MODULE_ERR_OK);
        return MODULE_ERR_OK;
 }
 
@@ -203,7 +217,13 @@ int VT_Install(char **Arguments)
 void VT_InitOutput()
 {
        giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE);
+       if(giVT_InputDevHandle == -1) {
+               Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice);
+               return ;
+       }
+       VT_SetResolution(giVT_RealWidth, giVT_RealHeight);
        VT_SetTerminal( 0 );
+       VT_SetMode( VIDEO_BUFFMT_TEXT );
 }
 
 /**
@@ -236,7 +256,7 @@ tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name)
 {
         int    num;
        
-       //ENTER("pNode sName", Node, Name);
+       ENTER("pNode sName", Node, Name);
        
        // Open the input and output files if needed
        if(giVT_OutputDevHandle == -2)  VT_InitOutput();
@@ -254,7 +274,7 @@ tVFS_Node *VT_FindDir(tVFS_Node *Node, char *Name)
                return NULL;
        }
        // Return node
-       //LEAVE('p', &gVT_Terminals[num].Node);
+       LEAVE('p', &gVT_Terminals[num].Node);
        return &gVT_Terminals[num].Node;
 }
 
@@ -320,8 +340,8 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                }
                break;
        
-       case TERM_MODE_FB:
-       //case TERM_MODE_:
+       //case TERM_MODE_FB:
+       default:
                while(pos < Length)
                {
                        while(term->InputRead == term->InputWrite)      Threads_Yield();
@@ -342,8 +362,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
        tVTerm  *term = &gVT_Terminals[ Node->Inode ];
-       
-       //ENTER("pNode XOffset XLength pBuffer",  Node, Offset, Length, Buffer);
+        int    size;
        
        // Write
        switch( term->Mode )
@@ -352,30 +371,57 @@ Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                VT_int_PutString(term, Buffer, Length);
                break;
        case TERM_MODE_FB:
-               if( giVT_RealWidth > term->Width || giVT_RealHeight > term->Height )
+               size = term->Width*term->Height*4;
+               if( Offset > size ) {
+                       Log_Notice("VTerm", "VT_Write: Offset (0x%llx) > FBSize (0x%x)",
+                               Offset, size);
+                       return 0;
+               }
+               
+               if( Offset + Length > size ) {
+                       Log_Notice("VTerm", "VT_Write: Offset+Length (0x%llx) > FBSize (0x%x)",
+                               Offset+Length, size);
+                       Length = size - Offset;
+               }
+               
+               memcpy( (void*)((Uint)term->Buffer + (Uint)Offset), Buffer, Length );
+               
+               if( Node->Inode == giVT_CurrentTerminal )
                {
-                       #if 0
-                        int    x, y, h;
-                       x = Offset/4;   y = x / term->Width;    x %= term->Width;
-                       w = Length/4+x; h = w / term->Width;    w %= term->Width;
-                       while(h--)
+                       if( giVT_RealWidth > term->Width || giVT_RealHeight > term->Height )
                        {
-                               VFS_WriteAt( giVT_OutputDevHandle,
-                                       (x+y*term->RealWidth)*4,
-                                       term->Width * 4,
-                                       Buffer
-                                       );
-                               Buffer = (void*)( (Uint)Buffer + term->Width*term->Height*4 );
+                                int    x, y, w, h;
+                               x = Offset/4;   y = x / term->Width;    x %= term->Width;
+                               w = Length/4+x; h = w / term->Width;    w %= term->Width;
+                               // Center
+                               x += (giVT_RealWidth - term->Width) / 2;
+                               y += (giVT_RealHeight - term->Height) / 2;
+                               while(h--)
+                               {
+                                       VFS_WriteAt( giVT_OutputDevHandle,
+                                               (x + y * giVT_RealWidth)*4,
+                                               term->Width * 4,
+                                               Buffer
+                                               );
+                                       Buffer = (void*)( (Uint)Buffer + term->Width*4 );
+                                       y ++;
+                               }
+                               return 0;
+                       }
+                       else {
+                               return VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer );
                        }
-                       #endif
-                       return 0;
                }
-               else {
-                       return VFS_WriteAt( giVT_OutputDevHandle, Offset, Length, Buffer );
+       
+       case TERM_MODE_2DACCEL:
+       //case TERM_MODE_3DACCEL:
+               if( Node->Inode == giVT_CurrentTerminal )
+               {
+                       VFS_Write( giVT_OutputDevHandle, Length, Buffer );
                }
+               break;
        }
        
-       //LEAVE('i', 0);
        return 0;
 }
 
@@ -390,11 +436,14 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        ENTER("pNode iId pData", Node, Id, Data);
        
        if(Id >= DRV_IOCTL_LOOKUP) {
+               // Only root can fiddle with graphics modes
+               // TODO: Remove this and replace with user ownership
                if( Threads_GetUID() != 0 )     return -1;
        }
        
        switch(Id)
        {
+       // --- Core Defined
        case DRV_IOCTL_TYPE:
                LEAVE('i', DRV_TYPE_TERMINAL);
                return DRV_TYPE_TERMINAL;
@@ -413,11 +462,18 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        case TERM_IOCTL_MODETYPE:
                if(Data != NULL)
                {
+                       if( CheckMem(Data, sizeof(int)) == 0 ) {
+                               LEAVE('i', -1);
+                               return -1;
+                       }
+                       Log_Log("VTerm", "VTerm %i mode set to %i", (int)Node->Inode, *iData);
+                       
+                       // Update mode if needed
                        if(term->Mode != *iData)
                                VT_int_ChangeMode(term, *iData);
                        
                        // Update the screen dimensions
-                       if(giVT_CurrentTerminal == Node->Inode)
+                       if(Node->Inode == giVT_CurrentTerminal)
                                VT_SetTerminal( giVT_CurrentTerminal );
                }
                LEAVE('i', term->Mode);
@@ -425,19 +481,33 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        
        // Get/set the terminal width
        case TERM_IOCTL_WIDTH:
-               if(Data != NULL)        term->Width = *iData;
+               if(Data != NULL) {
+                       if( CheckMem(Data, sizeof(int)) == 0 ) {
+                               LEAVE('i', -1);
+                               return -1;
+                       }
+                       term->Width = *iData;
+               }
                Log("VT_Terminal_IOCtl - RETURN term->Width = %i", term->Width);
                LEAVE('i', term->Width);
                return term->Width;
        
        // Get/set the terminal height
        case TERM_IOCTL_HEIGHT:
-               if(Data != NULL)        term->Height = *iData;
+               if(Data != NULL) {
+                       if( CheckMem(Data, sizeof(int)) == 0 ) {
+                               LEAVE('i', -1);
+                               return -1;
+                       }
+                       term->Height = *iData;
+               }
                Log("VT_Terminal_IOCtl - RETURN term->Height = %i", term->Height);
                LEAVE('i', term->Height);
                return term->Height;
        
        case TERM_IOCTL_FORCESHOW:
+               Log_Log("VTerm", "Thread %i forced VTerm %i to be shown",
+                       Threads_GetTID(), (int)Node->Inode);
                VT_SetTerminal( Node->Inode );
                LEAVE('i', 1);
                return 1;
@@ -446,10 +516,11 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        return -1;
 }
 
-void VT_SetResolution(int IsTextMode, int Width, int Height)
+void VT_SetResolution(int Width, int Height)
 {
        tVideo_IOCtl_Mode       mode = {0};
         int    tmp;
+        int    i;
        
        // Create the video mode
        mode.width = Width;
@@ -460,17 +531,41 @@ void VT_SetResolution(int IsTextMode, int Width, int Height)
        // Set video mode
        VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_FINDMODE, &mode );
        tmp = mode.id;
-       giVT_RealWidth = mode.width;
-       giVT_RealHeight = mode.height;
+       if( Width != mode.width || Height != mode.height )
+       {
+               Log_Warning("VTerm",
+                       "Selected resolution (%ix%i is not supported) by the device, using (%ix%i)",
+                       giVT_RealWidth, giVT_RealHeight,
+                       mode.width, mode.height
+                       );
+       }
        VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp );
        
-       
-       
-       if(IsTextMode)
-               tmp = VIDEO_BUFFMT_TEXT;
-       else
-               tmp = VIDEO_BUFFMT_FRAMEBUFFER;
-       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp );
+       // Resize text terminals if needed
+       if( giVT_RealWidth != mode.width || giVT_RealHeight != mode.height )
+       {
+                int    newBufSize = (giVT_RealWidth/giVT_CharWidth)
+                                       *(giVT_RealHeight/giVT_CharHeight)
+                                       *(giVT_Scrollback+1);
+               //tVT_Char      *tmp;
+               // Resize the text terminals
+               giVT_RealWidth = mode.width;
+               giVT_RealHeight = mode.height;
+               for( i = 0; i < NUM_VTS; i ++ )
+               {
+                       if( gVT_Terminals[i].Mode != TERM_MODE_TEXT )   continue;
+                       
+                       gVT_Terminals[i].Text = realloc(
+                               gVT_Terminals[i].Text,
+                               newBufSize*sizeof(tVT_Char)
+                               );
+               }
+       }
+}
+
+void VT_SetMode(int Mode)
+{
+       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &Mode );
 }
 
 /**
@@ -482,6 +577,21 @@ void VT_SetTerminal(int ID)
        // Update current terminal ID
        Log_Log("VTerm", "Changed terminal from %i to %i", giVT_CurrentTerminal, ID);
        giVT_CurrentTerminal = ID;
+       gpVT_CurTerm = &gVT_Terminals[ID];
+       
+       // Update cursor
+       if( gpVT_CurTerm->Mode == TERM_MODE_TEXT && !(gpVT_CurTerm->Flags & VT_FLAG_HIDECSR) )
+       {
+               tVideo_IOCtl_Pos        pos;
+               pos.x = gpVT_CurTerm->WritePos % gpVT_CurTerm->Width;
+               pos.y = gpVT_CurTerm->WritePos / gpVT_CurTerm->Width;
+               VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos);
+       }
+       
+       if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
+               VT_SetMode( VIDEO_BUFFMT_TEXT );
+       else
+               VT_SetMode( VIDEO_BUFFMT_FRAMEBUFFER );
        
        // Update the screen
        VT_int_UpdateScreen( &gVT_Terminals[ ID ], 1 );
@@ -562,8 +672,16 @@ void VT_KBCallBack(Uint32 Codepoint)
                case KEY_F11:   VT_SetTerminal(10);     return;
                case KEY_F12:   VT_SetTerminal(11);     return;
                case KEY_PGUP:
+                       if( gpVT_CurTerm->ViewPos > gpVT_CurTerm->Width )
+                               gpVT_CurTerm->ViewPos -= gpVT_CurTerm->Width;
+                       else
+                               gpVT_CurTerm->ViewPos = 0;
                        return;
                case KEY_PGDOWN:
+                       if( gpVT_CurTerm->ViewPos < gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback-1) )
+                               gpVT_CurTerm->ViewPos += gpVT_CurTerm->Width;
+                       else
+                               gpVT_CurTerm->ViewPos = gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback-1);
                        return;
                }
        }
@@ -648,41 +766,6 @@ void VT_KBCallBack(Uint32 Codepoint)
        }
 }
 
-/**
- * \fn void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
- * \brief Print a string to the Virtual Terminal
- */
-void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
-{
-       Uint32  val;
-        int    i;
-       for( i = 0; i < Count; i++ )
-       {
-               if( Buffer[i] == 0x1B ) // Escape Sequence
-               {
-                       i ++;
-                       i += VT_int_ParseEscape(Term, (char*)&Buffer[i]);
-                       continue;
-               }
-               
-               if( Buffer[i] < 128 )   // Plain ASCII
-                       VT_int_PutChar(Term, Buffer[i]);
-               else {  // UTF-8
-                       i += ReadUTF8(&Buffer[i], &val);
-                       VT_int_PutChar(Term, val);
-               }
-       }
-       
-       // Update cursor
-       if( !(Term->Flags & VT_FLAG_HIDECSR) )
-       {
-               tVideo_IOCtl_Pos        pos;
-               pos.x = Term->WritePos % Term->Width;
-               pos.y = Term->WritePos / Term->Width;
-               VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos);
-       }
-}
-
 /**
  * \fn void VT_int_ClearLine(tVTerm *Term, int Num)
  * \brief Clears a line in a virtual terminal
@@ -708,28 +791,36 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
        char    c;
         int    argc = 0, j = 1;
         int    tmp;
-        int    args[4] = {0,0,0,0};
+        int    args[6] = {0,0,0,0};
        
-       switch(Buffer[0]) {
+       switch(Buffer[0])
+       {
        //Large Code
        case '[':
                // Get Arguments
-               c = Buffer[1];
-               do {
-                       while('0' <= c && c <= '9') {
-                               args[argc] *= 10;
-                               args[argc] += c-'0';
-                               c = Buffer[++j];
-                       }
-                       if( j != 1 )    argc ++;
-               } while(c == ';');
+               c = Buffer[j++];
+               if( '0' <= c && c <= '9' )
+               {
+                       do {
+                               while('0' <= c && c <= '9') {
+                                       args[argc] *= 10;
+                                       args[argc] += c-'0';
+                                       c = Buffer[j++];
+                               }
+                               argc ++;
+                       } while(c == ';');
+               }
                
+               /*
                // Get string (what does this do?)
                if(c == '"') {
-                       c = Buffer[++j];
+                       c = Buffer[j++];
                        while(c != '"')
-                               c = Buffer[++j];
+                               c = Buffer[j++];
                }
+               */
+               
+               //Log_Debug("VTerm", "argc = %i", argc);
                
                // Get Command
                if(     ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
@@ -765,7 +856,7 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                {
                                case 2:
                                        {
-                                        int    i = Term->Height * VT_SCROLLBACK;
+                                        int    i = Term->Height * (giVT_Scrollback + 1);
                                        while( i-- )    VT_int_ClearLine(Term, i);
                                        Term->WritePos = 0;
                                        Term->ViewPos = 0;
@@ -800,15 +891,55 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                        }
                                }
                                break;
+                       default:
+                               Log_Warning("VTerm", "Unknown control sequence");
+                               break;
                        }
                }
                break;
                
-       default:
-               break;
+       default:        break;
+       }
+       
+       //Log_Debug("VTerm", "j = %i, Buffer = '%s'", j, Buffer);
+       return j;
+}
+
+/**
+ * \fn void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
+ * \brief Print a string to the Virtual Terminal
+ */
+void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
+{
+       Uint32  val;
+        int    i;
+       for( i = 0; i < Count; i++ )
+       {
+               if( Buffer[i] == 0x1B ) // Escape Sequence
+               {
+                       i ++;
+                       i += VT_int_ParseEscape(Term, (char*)&Buffer[i]) - 1;
+                       continue;
+               }
+               
+               if( Buffer[i] < 128 )   // Plain ASCII
+                       VT_int_PutChar(Term, Buffer[i]);
+               else {  // UTF-8
+                       i += ReadUTF8(&Buffer[i], &val);
+                       VT_int_PutChar(Term, val);
+               }
        }
+       // Update Screen
+       VT_int_UpdateScreen( Term, 0 );
        
-       return j + 1;
+       // Update cursor
+       if( Term == gpVT_CurTerm && !(Term->Flags & VT_FLAG_HIDECSR) )
+       {
+               tVideo_IOCtl_Pos        pos;
+               pos.x = Term->WritePos % Term->Width;
+               pos.y = Term->WritePos / Term->Width;
+               VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSOR, &pos);
+       }
 }
 
 /**
@@ -825,6 +956,7 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
        {
        case '\0':      return; // Ignore NULL byte
        case '\n':
+               VT_int_UpdateScreen( Term, 0 ); // Update the line before newlining
                Term->WritePos += Term->Width;
        case '\r':
                Term->WritePos -= Term->WritePos % Term->Width;
@@ -866,27 +998,27 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                Term->WritePos ++;
                break;
        }
-               
        
        // Move Screen
-       if(Term->WritePos >= Term->Width*Term->Height*VT_SCROLLBACK)
+       if(Term->WritePos >= Term->Width*Term->Height*(giVT_Scrollback+1))
        {
                 int    base, i;
                Term->WritePos -= Term->Width;
+               VT_int_UpdateScreen( Term, 0 );
                
                // Update view position
-               base = Term->Width*Term->Height*(VT_SCROLLBACK-1);
+               base = Term->Width*Term->Height*(giVT_Scrollback-1);
                if(Term->ViewPos < base)        Term->ViewPos += Term->Width;
                if(Term->ViewPos > base)        Term->ViewPos = base;
                
                // Scroll terminal cache
-               base = Term->Width*(Term->Height*VT_SCROLLBACK-1);
+               base = Term->Width*(Term->Height*(giVT_Scrollback+1)-1);
                
                // Scroll Back
                memcpy(
                        Term->Text,
                        &Term->Text[Term->Width],
-                       Term->Width*(Term->Height-1)*VT_SCROLLBACK*sizeof(tVT_Char)
+                       (Term->Width*Term->Height*(giVT_Scrollback+1)-Term->Width)*sizeof(tVT_Char)
                        );
                
                // Clear last row
@@ -896,19 +1028,59 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
                        Term->Text[ base + i ].Colour = Term->CurColour;
                }
                
-               VT_int_UpdateScreen( Term, 1 );
+               //LOG("Scrolled buffer");
+               VT_int_ScrollFramebuffer( Term );
+               VT_int_UpdateScreen( Term, 0 );
        }
-       else if(Term->WritePos > Term->Width*Term->Height+Term->ViewPos)
+       else if(Term->WritePos >= Term->ViewPos + Term->Width*Term->Height)
        {
+               //LOG("Scrolled screen");
+               Term->WritePos -= Term->Width;
+               VT_int_UpdateScreen( Term, 0 );
+               Term->WritePos += Term->Width;
+               
                Term->ViewPos += Term->Width;
-               VT_int_UpdateScreen( Term, 1 );
-       }
-       else
+               VT_int_ScrollFramebuffer( Term );
                VT_int_UpdateScreen( Term, 0 );
+       }
        
        //LEAVE('-');
 }
 
+/**
+ * \fn void VT_int_ScrollFramebuffer( tVTerm *Term )
+ * \note Scrolls the framebuffer by 1 text line
+ */
+void VT_int_ScrollFramebuffer( tVTerm *Term )
+{
+        int    tmp;
+       struct {
+               Uint8   Op;
+               Uint16  DstX, DstY;
+               Uint16  SrcX, SrcY;
+               Uint16  W, H;
+       } PACKED        buf;
+       // Only update if this is the current terminal
+       if( Term != gpVT_CurTerm )      return;
+       
+       // This should only be called in text mode
+       
+       tmp = VIDEO_BUFFMT_2DSTREAM;
+       VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
+       
+       buf.Op = VIDEO_2DOP_BLIT;
+       buf.DstX = 0;   buf.DstY = 0;
+       buf.SrcX = 0;   buf.SrcY = giVT_CharHeight;
+       buf.W = Term->Width * giVT_CharWidth;
+       buf.H = (Term->Height-1) * giVT_CharHeight;
+       
+       VFS_WriteAt(giVT_OutputDevHandle, 0, 1+12, &buf);
+       
+       // Restore old mode
+       tmp = VIDEO_BUFFMT_TEXT;
+       VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp);
+}
+
 /**
  * \fn void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
  * \brief Updates the video framebuffer
@@ -916,55 +1088,42 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
 void VT_int_UpdateScreen( tVTerm *Term, int UpdateAll )
 {
        // Only update if this is the current terminal
-       if( Term != &gVT_Terminals[giVT_CurrentTerminal] )      return;
+       if( Term != gpVT_CurTerm )      return;
        
-       if( Term->Mode == TERM_MODE_TEXT )
+       switch( Term->Mode )
        {
-               if(gbVT_TextMode)
-               {
-                       if(UpdateAll) {
-                               VFS_WriteAt(
-                                       giVT_OutputDevHandle,
-                                       0,
-                                       Term->Width*Term->Height*sizeof(tVT_Char),
-                                       &Term->Text[Term->ViewPos]
-                                       );
-                       } else {
-                                int    pos = Term->WritePos - Term->WritePos % Term->Width;
-                               VFS_WriteAt(
-                                       giVT_OutputDevHandle,
-                                       (pos - Term->ViewPos)*sizeof(tVT_Char),
-                                       Term->Width*sizeof(tVT_Char),
-                                       &Term->Text[pos]
-                                       );
-                       }
-               }
-               else
-               {
-                       //TODO: Do VT Rendered Text
-                       #if 0
-                       if( UpdateAll ) {
-                               VT_RenderText(0, Term->Width*Term->Height, &Term->Text[Term->ViewPos]);
-                       }
-                       else {
-                                int    pos = Term->WritePos - Term->WritePos % Term->Width;
-                               VT_RenderText(
-                                       pos - Term->ViewPos,
-                                       Term->Width,
-                                       &Term->Text[pos]
-                                       );
-                       }
-                       #endif
+       case TERM_MODE_TEXT:
+               if(UpdateAll) {
+                       //LOG("UpdateAll = 1");
+                       //LOG("VFS_WriteAt(0x%x, 0, %i*sizeof(tVT_Char), &Term->Text[%i])",
+                       //      giVT_OutputDevHandle, Term->Width*Term->Height, Term->ViewPos);
+                       VFS_WriteAt(
+                               giVT_OutputDevHandle,
+                               0,
+                               Term->Width*Term->Height*sizeof(tVT_Char),
+                               &Term->Text[Term->ViewPos]
+                               );
+               } else {
+                        int    pos = Term->WritePos - Term->WritePos % Term->Width;
+                       //LOG("UpdateAll = 0");
+                       //LOG("VFS_WriteAt(0x%x, %i*sizeof(tVT_Char), %i*sizeof(tVT_Char), &Term->Text[%i])",
+                       //      giVT_OutputDevHandle, (pos - Term->ViewPos), Term->Width, pos);
+                       VFS_WriteAt(
+                               giVT_OutputDevHandle,
+                               (pos - Term->ViewPos)*sizeof(tVT_Char),
+                               Term->Width*sizeof(tVT_Char),
+                               &Term->Text[pos]
+                               );
                }
-       }
-       else
-       {
+               break;
+       case TERM_MODE_FB:
                VFS_WriteAt(
                        giVT_OutputDevHandle,
                        0,
                        Term->Width*Term->Height*sizeof(Uint32),
-                       &Term->Buffer
+                       Term->Buffer
                        );
+               break;
        }
 }
 
@@ -977,14 +1136,19 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode)
        switch(NewMode)
        {
        case TERM_MODE_TEXT:
+               Log_Log("VTerm", "Set VT %p to text mode", Term);
                free(Term->Buffer);
-               Term->Text = calloc( Term->Width*Term->Height*VT_SCROLLBACK, sizeof(tVT_Char) );
+               Term->Text = calloc( Term->Width*Term->Height*(giVT_Scrollback+1), sizeof(tVT_Char) );
                break;
        case TERM_MODE_FB:
+               Log_Log("VTerm", "Set VT %p to framebuffer mode (%ix%i)", Term,
+                       Term->Width, Term->Height);
                free(Term->Text);
                Term->Buffer = calloc( Term->Width*Term->Height, sizeof(Uint32) );
+               Log_Debug("VTerm", "Term->Buffer = %p", Term->Buffer);
                break;
-       //case TERM_MODE_OPENGL:
+       //case TERM_MODE_2DACCEL:
+       //case TERM_MODE_3DACCEL:
        //      return;
        }
        
@@ -1006,7 +1170,7 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode)
 Uint8  *VT_Font_GetChar(Uint32 Codepoint);
 
 // === GLOBALS ===
-int    giVT_CharWidth = FONT_WIDTH+1;
+int    giVT_CharWidth = FONT_WIDTH;
 int    giVT_CharHeight = FONT_HEIGHT;
 
 // === CODE ===
index 12f21cd..99d02f6 100644 (file)
@@ -5,8 +5,82 @@
 #define DEBUG  0
 #include <acess.h>
 #include <tpl_drv_disk.h>
+#include <tpl_drv_video.h>
 
 // === CODE ===
+// --- Video Driver Helpers ---
+Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
+       tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers)
+{
+       Uint8   *stream = Buffer;
+        int    rem = Length;
+        int    op;
+       while( rem )
+       {
+               rem --;
+               op = *stream++;
+               
+               if(op > NUM_VIDEO_2DOPS) {
+                       Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Unknown"
+                               " operation %i", op);
+               }
+               
+               if(op*4 > SizeofHandlers) {
+                       Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver does"
+                               " not support op %i", op);
+                       return Length-rem;
+               }
+               
+               switch(op)
+               {
+               case VIDEO_2DOP_NOP:    break;
+               
+               case VIDEO_2DOP_FILL:
+                       if(rem < 12)    return Length-rem;
+                       
+                       if(!Handlers->Fill) {
+                               Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
+                                       " does not support VIDEO_2DOP_FILL");
+                               return Length-rem;
+                       }
+                       
+                       Handlers->Fill(
+                               Ent,
+                               *(Uint16*)(&stream[0]), *(Uint16*)(&stream[2]),
+                               *(Uint16*)(&stream[4]), *(Uint16*)(&stream[6]),
+                               *(Uint32*)(&stream[8])
+                               );
+                       
+                       rem -= 12;
+                       stream += 12;
+                       break;
+               
+               case VIDEO_2DOP_BLIT:
+                       if(rem < 12)    return Length-rem;
+                       
+                       if(!Handlers->Blit) {
+                               Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver"
+                                       " does not support VIDEO_2DOP_BLIT");
+                               return Length-rem;
+                       }
+                       
+                       Handlers->Blit(
+                               Ent,
+                               *(Uint16*)(&stream[0]), *(Uint16*)(&stream[2]),
+                               *(Uint16*)(&stream[4]), *(Uint16*)(&stream[6]),
+                               *(Uint16*)(&stream[8]), *(Uint16*)(&stream[10])
+                               );
+                       
+                       rem -= 12;
+                       stream += 12;
+                       break;
+               
+               }
+       }
+       return 0;
+}
+
+// --- Disk Driver Helpers ---
 Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
        tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
 {
index 963cb9c..8e62578 100644 (file)
@@ -95,9 +95,6 @@ typedef struct sKernelSymbol {
  */
 
 // === FUNCTIONS ===
-// --- Core ---
-extern void    System_Init(char *ArgString);
-
 // --- IRQs ---
 extern int     IRQ_AddHandler(int Num, void (*Callback)(int));
 
@@ -115,11 +112,12 @@ extern void       Log_Debug(char *Ident, char *Message, ...);
  * \name Debugging and Errors
  * \{
  */
-extern void    Panic(char *Msg, ...);
-extern void    Warning(char *Msg, ...);
-extern void    Log(char *Fmt, ...);
-extern void    LogV(char *Fmt, va_list Args);
-extern void    LogF(char *Fmt, ...);
+extern void    Debug_KernelPanic();    //!< Initiate a kernel panic
+extern void    Panic(char *Msg, ...);  //!< Print a panic message (initiates a kernel panic)
+extern void    Warning(char *Msg, ...);        //!< Print a warning message
+extern void    LogF(char *Fmt, ...);   //!< Print a log message without a trailing newline
+extern void    Log(char *Fmt, ...);    //!< Print a log message
+extern void    LogV(char *Fmt, va_list Args);  //!< va_list Log message
 extern void    Debug_Enter(char *FuncName, char *ArgTypes, ...);
 extern void    Debug_Log(char *FuncName, char *Fmt, ...);
 extern void    Debug_Leave(char *FuncName, char RetType, ...);
@@ -314,6 +312,7 @@ extern int  strcmp(const char *__str1, const char *__str2);
 extern int     strncmp(const char *Str1, const char *Str2, size_t num);
 extern int     strucmp(const char *Str1, const char *Str2);
 extern char    *strdup(const char *Str);
+extern char    **str_split(const char *__str, char __ch);
 extern int     strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
 extern void    itoa(char *buf, Uint num, int base, int minLength, char pad);
@@ -399,5 +398,6 @@ extern int  DivUp(int num, int dem);
 
 #include <binary_ext.h>
 #include <vfs_ext.h>
+#include <adt.h>
 
 #endif
diff --git a/Kernel/include/adt.h b/Kernel/include/adt.h
new file mode 100644 (file)
index 0000000..17f2387
--- /dev/null
@@ -0,0 +1,47 @@
+/* 
+ * Acess2
+ * - Abstract Data Types
+ */
+#ifndef _ADT_H_
+#define _ADT_H_
+
+/**
+ * \name Ring Buffers
+ * \{
+ */
+typedef struct sRingBuffer
+{
+       size_t  Start;  //!< Start of data in ring buffer
+       size_t  Length; //!< Number of data bytes in buffer
+       size_t  Space;  //!< Allocated space in buffer
+       char    Data[]; //!< Buffer
+}      tRingBuffer;
+
+/**
+ * \brief Create a ring buffer \a Space bytes large
+ * \param Space        Ammount of space to allocate within the buffer
+ * \return Pointer to the buffer structure
+ */
+extern tRingBuffer     *RingBuffer_Create(size_t Space);
+/**
+ * \brief Read at most \a Length bytes from the buffer
+ * \param Dest Destinaton buffer
+ * \param Buffer       Source ring buffer
+ * \param Length       Requested number of bytes
+ * \return Number of bytes read
+ */
+extern size_t  RingBuffer_Read(void *Dest, tRingBuffer *Buffer, size_t Length);
+/**
+ * \brief Write at most \a Length bytes to the buffer
+ * \param Buffer       Destination ring buffer
+ * \param Source       Source buffer
+ * \param Length       Provided number of bytes
+ * \return Number of bytes written
+ */
+extern size_t  RingBuffer_Write(tRingBuffer *Buffer, void *Source, size_t Length);
+/**
+ * \}
+ */
+
+
+#endif
index 29a6c00..ca6a5da 100644 (file)
@@ -42,7 +42,7 @@
  * VFS node. This node is used to provide the user access to the
  * driver's functions via IOCtl calls and Reading or Writing to the driver
  * file. Drivers are also able to expose a readonly buffer by using
- * \ref fs_proc.h ProcDev, usually to provide state information or device
+ * \ref fs_sysfs.h "ProcDev", usually to provide state information or device
  * capabilities for the the user.
  * 
  * The device driver interfaces are all based on the core specifcation
  * framebuffer (this may not be the true framebuffer, to allow for double-buffering)
  * to the user. See the full documentation in tpl_drv_video.h for the
  * complete specifcation.
+ * 
+ * \subsection drv_disk Disk/Storage Devices
+ * Storage devices present themselves as a linear collection of bytes.
+ * Reads and writes to the device need not be aligned to the stated block
+ * size, but it is suggested that users of a storage device file align
+ * their accesses to block boundaries.
+ * The functions DrvUtil_ReadBlock and DrvUtil_WriteBlock are provided
+ * to storage drivers to assist in handling non-alinged reads and writes.
+ * 
+ * \see tpl_drv_common.h Common Spec.
+ * \see tpl_drv_video.h Video Device Spec.
+ * \see tpl_drv_keyboard.h Keyboard Device Spec.
+ * \see tpl_drv_disk.h Disk/Storage Device Spec.
+ * \see tpl_drv_network.h Network Device Spec.
+ * \see tpl_drv_terminal.h Virtual Terminal Spec.
  */
index 0b796c0..f5b2360 100644 (file)
@@ -14,7 +14,12 @@ enum eErrorNums
        EACCES,
        ENOTFOUND,
        EREADONLY,
-       ENOTIMPL
+       ENOTIMPL,
+       ENOENT,
+       ENFILE,
+       ENOTDIR,
+       
+       NUM_ERRS
 };
 
 #endif
index f75a7ff..5589f4f 100644 (file)
@@ -20,7 +20,7 @@ typedef struct sDevFS_Driver
 
 // === FUNCTIONS ===
 /**
- * \fn int DevFS_AddDevice(tDevFS_Driver *Dev)
+ * \fn int DevFS_AddDevice(tDevFS_Driver *Device)
  * \brief Registers a device in the Device Filesystem
  * \param Device       Pointer to a persistant structure that represents the driver
  * \return Boolean success
index 2c44d2c..0007dc1 100644 (file)
@@ -9,7 +9,7 @@ enum eSyscalls {
        SYS_EXIT,       // 0 - Kill this thread
        SYS_CLONE,      // 1 - Create a new thread
        SYS_KILL,       // 2 - Send a signal
-       SYS_SIGNAL,     // 3 - Set signal Handler
+       SYS_SETFAULTHANDLER,    // 3 - Set signal Handler
        SYS_YIELD,      // 4 - Yield remainder of timestamp
        SYS_SLEEP,      // 5 - Sleep until messaged or signaled
        SYS_WAIT,       // 6 - Wait for a time or a message
@@ -47,22 +47,23 @@ enum eSyscalls {
        SYS_WRITE,      // 68 - Write to an open file
        SYS_IOCTL,      // 69 - Perform an IOCtl Call
        SYS_READDIR,    // 70 - Read from an open directory
-       SYS_MKDIR,      // 71 - Create a new directory
-       SYS_SYMLINK,    // 72 - Create a symbolic link
-       SYS_GETACL,     // 73 - Get an ACL Value
-       SYS_SETACL,     // 74 - Set an ACL Value
-       SYS_FINFO,      // 75 - Get file information
-       SYS_SEEK,       // 76 - Seek to a new position in the file
-       SYS_TELL,       // 77 - Return the current file position
-       SYS_CHDIR,      // 78 - Change current directory
-       SYS_GETCWD,     // 79 - Get current directory
-       SYS_MOUNT,      // 80 - Mount a filesystem
+       SYS_OPENCHILD,  // 71 - Open a child entry in a directory
+       SYS_MKDIR,      // 72 - Create a new directory
+       SYS_SYMLINK,    // 73 - Create a symbolic link
+       SYS_GETACL,     // 74 - Get an ACL Value
+       SYS_SETACL,     // 75 - Set an ACL Value
+       SYS_FINFO,      // 76 - Get file information
+       SYS_SEEK,       // 77 - Seek to a new position in the file
+       SYS_TELL,       // 78 - Return the current file position
+       SYS_CHDIR,      // 79 - Change current directory
+       SYS_GETCWD,     // 80 - Get current directory
+       SYS_MOUNT,      // 81 - Mount a filesystem
        NUM_SYSCALLS,
        SYS_DEBUG = 0x100       // 0x100 - Print a debug string
 };
 
 static const char *cSYSCALL_NAMES[] = {
-       "SYS_EXIT","SYS_CLONE","SYS_KILL","SYS_SIGNAL","SYS_YIELD","SYS_SLEEP",
+       "SYS_EXIT","SYS_CLONE","SYS_KILL","SYS_SETFAULTHANDLER","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_LOADMOD","","","",
@@ -73,8 +74,8 @@ static const char *cSYSCALL_NAMES[] = {
        "","","","","","",
        "","","","","","",
        "","","","","SYS_OPEN","SYS_REOPEN",
-       "SYS_CLOSE","SYS_READ","SYS_WRITE","SYS_IOCTL","SYS_READDIR","SYS_MKDIR",
-       "SYS_SYMLINK","SYS_GETACL","SYS_SETACL","SYS_FINFO","SYS_SEEK","SYS_TELL",
-       "SYS_CHDIR","SYS_GETCWD","SYS_MOUNT",""
+       "SYS_CLOSE","SYS_READ","SYS_WRITE","SYS_IOCTL","SYS_READDIR","SYS_OPENCHILD",
+       "SYS_MKDIR","SYS_SYMLINK","SYS_GETACL","SYS_SETACL","SYS_FINFO","SYS_SEEK",
+       "SYS_TELL","SYS_CHDIR","SYS_GETCWD","SYS_MOUNT",""
 };
 #endif
index 178ecbd..bd59af8 100644 (file)
@@ -5,7 +5,7 @@
 %define SYS_EXIT       0       ; Kill this thread
 %define SYS_CLONE      1       ; Create a new thread
 %define SYS_KILL       2       ; Send a signal
-%define SYS_SIGNAL     3       ; Set signal Handler
+%define SYS_SETFAULTHANDLER    3       ; Set signal Handler
 %define SYS_YIELD      4       ; Yield remainder of timestamp
 %define SYS_SLEEP      5       ; Sleep until messaged or signaled
 %define SYS_WAIT       6       ; Wait for a time or a message
 %define SYS_WRITE      68      ; Write to an open file
 %define SYS_IOCTL      69      ; Perform an IOCtl Call
 %define SYS_READDIR    70      ; Read from an open directory
-%define SYS_MKDIR      71      ; Create a new directory
-%define SYS_SYMLINK    72      ; Create a symbolic link
-%define SYS_GETACL     73      ; Get an ACL Value
-%define SYS_SETACL     74      ; Set an ACL Value
-%define SYS_FINFO      75      ; Get file information
-%define SYS_SEEK       76      ; Seek to a new position in the file
-%define SYS_TELL       77      ; Return the current file position
-%define SYS_CHDIR      78      ; Change current directory
-%define SYS_GETCWD     79      ; Get current directory
-%define SYS_MOUNT      80      ; Mount a filesystem
+%define SYS_OPENCHILD  71      ; Open a child entry in a directory
+%define SYS_MKDIR      72      ; Create a new directory
+%define SYS_SYMLINK    73      ; Create a symbolic link
+%define SYS_GETACL     74      ; Get an ACL Value
+%define SYS_SETACL     75      ; Set an ACL Value
+%define SYS_FINFO      76      ; Get file information
+%define SYS_SEEK       77      ; Seek to a new position in the file
+%define SYS_TELL       78      ; Return the current file position
+%define SYS_CHDIR      79      ; Change current directory
+%define SYS_GETCWD     80      ; Get current directory
+%define SYS_MOUNT      81      ; Mount a filesystem
index b55fe0e..2b066d9 100644 (file)
@@ -17,11 +17,13 @@ typedef struct sMessage
 typedef struct sThread
 {
        // --- threads.c's
+       //  0
        struct sThread  *Next;  //!< Next thread in list
        tSpinlock       IsLocked;       //!< Thread's spinlock
        volatile int    Status;         //!< Thread Status
         int    RetStatus;      //!< Return Status
        
+       // 16
        Uint    TID;    //!< Thread ID
        Uint    TGID;   //!< Thread Group (Process)
        Uint    PTID;   //!< Parent Thread ID
@@ -29,19 +31,22 @@ typedef struct sThread
        char    *ThreadName;    //!< Name of thread
        
        // --- arch/proc.c's responsibility
+       // 40
        //! Kernel Stack Base
        tVAddr  KernelStack;
        
+       // 44 (x86)
        //! Memory Manager State
        tMemoryState    MemState;
        
+       // 48 (x86)
        //! State on task switch
        tTaskState      SavedState;
        
        // --- threads.c's
-        int    CurSignal;      //!< Signal currently being handled (0 for none)
-       tVAddr  SignalHandlers[NSIG];   //!< Signal Handler List
-       tTaskState      SignalState;    //!< Saved state for signal handler
+       // 60
+        int    CurFaultNum;    //!< Current fault number, 0: none
+       tVAddr  FaultHandler;   //!< Fault Handler
        
        tMsg * volatile Messages;       //!< Message Queue
        tMsg    *LastMessage;   //!< Last Message (speeds up insertion)
@@ -62,6 +67,16 @@ enum {
        THREAD_STAT_DEAD
 };
 
+enum eFaultNumbers
+{
+       FAULT_MISC,
+       FAULT_PAGE,
+       FAULT_ACCESS,
+       FAULT_DIV0,
+       FAULT_OPCODE,
+       FAULT_FLOAT
+};
+
 // === FUNCTIONS ===
 extern tThread *Proc_GetCurThread();
 extern tThread *Threads_GetThread(Uint TID);
index d459ace..47efb04 100644 (file)
@@ -3,6 +3,10 @@
  * \brief Disk Driver Interface Definitions\r
  * \author John Hodge (thePowersGang)\r
  * \r
+ * \section Nomeclature\r
+ * All addreses are 64-bit counts of bytes from the logical beginning of\r
+ * the disk unless explicitly stated.\r
+ * \r
  * \section dirs VFS Layout\r
  * Disk drivers have a flexible directory layout. The root directory can\r
  * contain subdirectories, with the only conditions being that all nodes\r
@@ -33,13 +37,109 @@ enum eTplDisk_IOCtl {
         * \brief Get the block size\r
         * \return Size of a hardware block for this device\r
         */\r
-       DISK_IOCTL_GETBLOCKSIZE = 4\r
+       DISK_IOCTL_GETBLOCKSIZE = 4,\r
+       \r
+       /**\r
+        * ioctl(..., tTplDisk_CacheRegion *RegionInfo)\r
+        * \brief Sets the cache importantce and protocol for a section of\r
+        *        memory.\r
+        * \param RegionInfo    Pointer to a region information structure\r
+        * \return Boolean failure\r
+        */\r
+       DISK_IOCTL_SETCACHEREGION,\r
+       \r
+       /**\r
+        * ioctl(..., Uint64 *Info[2])\r
+        * \brief Asks the driver to precache a region of disk.\r
+        * \param Region        64-bit Address and Size pair describing the area to cache\r
+        * \return Number of blocks cached\r
+        */\r
+       DISK_IOCTL_PRECACHE,\r
+       \r
+       /**\r
+        * ioclt(..., Uint64 *Region[2])\r
+        * \brief Asks to driver to flush the region back to disk\r
+        * \param Region        64-bit Address and Size pair describing the area to flush\r
+        * \note If Region[0] == -1 then the entire disk's cache is flushed\r
+        * \return Number of blocks flushed (or 0 for entire disk)\r
+        */\r
+       DISK_IOCTL_FLUSH\r
+};\r
+\r
+/**\r
+ * \brief Describes the cache parameters of a region on the disk\r
+ */\r
+typedef struct sTplDisk_CacheRegion\r
+{\r
+       Uint64  Base;   //!< Base of cache region\r
+       Uint64  Length; //!< Size of cache region\r
+       /**\r
+        * \brief Cache Protocol & Flags\r
+        * \r
+        * The low 4 bits denot the cache protocol to be used by the\r
+        * region (see ::eTplDisk_CacheProtocols for a list).\r
+        * The high 4 bits denote flags to apply to the cache (see\r
+        * ::eTplDisk_CacheFlags)\r
+        */\r
+       Uint8   Flags;\r
+       Uint8   Priority;       //!< Lower is a higher proritory\r
+       /**\r
+        * \brief Maximum size of cache, in blocks\r
+        * \note If CacheSize is zero, the implemenation defined limit is used\r
+        */\r
+       Uint16  CacheSize;\r
+}      tTplDisk_CacheRegion;\r
+\r
+/**\r
+ * \brief Cache protocols to use\r
+ */\r
+enum eTplDisk_CacheProtocols\r
+{\r
+       /**\r
+        * \brief Don't cache the region\r
+        */\r
+       \r
+       DISK_CACHEPROTO_DONTCACHE,\r
+       /**\r
+        * \brief Most recently used blocks cached\r
+        * \note This is the default action for undefined regions\r
+        */\r
+       DISK_CACHEPROTO_RECENTLYUSED,\r
+       /**\r
+        * \brief Cache the entire region in memory\r
+        * \r
+        * This is a faster version of setting Length to CacheSize*BlockSize\r
+        */\r
+       DISK_CACHEPROTO_FULLCACHE,\r
+       \r
+       /**\r
+        * \brief Cache only on demand\r
+        * \r
+        * Only cache when the ::DISK_IOCTL_PRECACHE IOCtl is used\r
+        */\r
+       DISK_CACHEPROTO_EXPLICIT\r
+};\r
+\r
+/**\r
+ * \brief Flags for the cache\r
+ */\r
+enum eTplDisk_CacheFlags\r
+{\r
+       /**\r
+        * \brief Write all changes to the region straight back to media\r
+        */\r
+       DISK_CACHEFLAG_WRITETHROUGH = 0x10\r
 };\r
 \r
 /**\r
  * \brief IOCtl name strings\r
  */\r
-#define        DRV_DISK_IOCTLNAMES     "get_block_size"\r
+#define        DRV_DISK_IOCTLNAMES     "get_block_size","set_cache_region","set_precache"\r
+\r
+/**\r
+ * \name Disk Driver Utilities\r
+ * \{\r
+ */\r
 \r
 /**\r
  * \brief Callback function type used by DrvUtil_ReadBlock and DrvUtil_WriteBlock\r
@@ -77,4 +177,8 @@ extern Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, void *Buffer,
        tDrvUtil_Callback ReadBlocks, tDrvUtil_Callback WriteBlocks,\r
        Uint64 BlockSize, Uint Argument);\r
 \r
+/**\r
+ * \}\r
+ */\r
+\r
 #endif\r
index ebbe98f..1c00c5e 100644 (file)
@@ -15,8 +15,6 @@
  * Writes to the driver's file while in component colour modes\r
  * must correspond to a change of the contents of the screen. The framebuffer\r
  * must start at offset 0 in the file.\r
- * In pallete colour modes the LFB is preceded by a 1024 byte pallete (allowing\r
- * room for 256 entries of 32-bits each)\r
  * Reading from the screen must either return zero, or read from the\r
  * framebuffer.\r
  * \r
@@ -125,11 +123,85 @@ typedef struct sVideo_IOCtl_Mode
  */\r
 enum eTplVideo_BufFormats\r
 {\r
+       /**\r
+        * \brief Text Mode\r
+        * \r
+        * The device file presents itself as an array of ::tVT_Char\r
+        * each describing a character cell on the screen.\r
+        * These cells are each \a giVT_CharWidth pixels wide and\r
+        * \a giVT_CharHeight high.\r
+        */\r
        VIDEO_BUFFMT_TEXT,\r
+       /**\r
+        * \brief Framebuffer Mode\r
+        * \r
+        * The device file presents as an array of 32-bpp pixels describing\r
+        * the entire screen. The format of a single pixel is in xRGB format\r
+        * (top 8 bits ignored, next 8 bits red, next 8 bits green and\r
+        * the bottom 8 bits blue)\r
+        */\r
        VIDEO_BUFFMT_FRAMEBUFFER,\r
+       /**\r
+        * \brief 2D Accelerated Mode\r
+        * \r
+        * The device file acts as a character device, accepting a stream of\r
+        * commands described in eTplVideo_2DCommands when written to.\r
+        */\r
+       VIDEO_BUFFMT_2DSTREAM,\r
+       /**\r
+        * \brief 3D Accelerated Mode\r
+        * \r
+        * The device file acts as a character device, accepting a stream of\r
+        * commands described in eTplVideo_3DCommands when written to.\r
+        */\r
        VIDEO_BUFFMT_3DSTREAM\r
 };\r
 \r
+/**\r
+ * \brief 2D Accellerated Video Commands\r
+ * \r
+ * Commands passed in the command stream for ::VIDEO_BUFFMT_2DSTREAM\r
+ */\r
+enum eTplVideo_2DCommands\r
+{\r
+       /**\r
+        * \brief No Operation\r
+        */\r
+       VIDEO_2DOP_NOP,\r
+       /**\r
+        * \brief Fill a region\r
+        * \param X     Uint16 - Leftmost pixels of the region\r
+        * \param Y     Uint16 - Topmost pixels of the region\r
+        * \param W     Uint16 - Width of the region\r
+        * \param H     Uint16 - Height of the region\r
+        * \param Colour        Uint32 - Value to fill with\r
+        */\r
+       VIDEO_2DOP_FILL,\r
+       /**\r
+        * \brief Copy a region from one part of the framebuffer to another\r
+        * \param DestX Uint16 - Leftmost pixels of the destination\r
+        * \param DestY Uint16 - Topmost pixels of the destination\r
+        * \param SrcX  Uint16 - Leftmost pixels of the source\r
+        * \param SrcY  Uint16 - Topmost pixels of the source\r
+        * \param Width Uint16 - Width of the region\r
+        * \param Height        Uint16 - Height of the region\r
+        */\r
+       VIDEO_2DOP_BLIT,\r
+\r
+\r
+       /**\r
+        * \brief Copy a region from video memory to the framebuffer\r
+        */\r
+       VIDEO_2DOP_BLITBUF,\r
+\r
+       /**\r
+        * \brief Copy and scale a region from video memory to the framebuffer\r
+        */\r
+       VIDEO_2DOP_BLITSCALEBUF,\r
+\r
+       NUM_VIDEO_2DOPS\r
+};\r
+\r
 /**\r
  * \brief Describes a position in the video framebuffer\r
  */\r
@@ -192,4 +264,49 @@ extern void        VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC
  */\r
 extern Uint32  VT_Colour12to24(Uint16 Col12);\r
 \r
+/**\r
+ * \brief Handlers for eTplVideo_2DCommands\r
+ */\r
+typedef struct sDrvUtil_Video_2DHandlers\r
+{\r
+       /**\r
+        * \brief No Operation, Ignored\r
+        * \see VIDEO_2DOP_NOP\r
+        */\r
+       void    *Nop;\r
+       /**\r
+        * \brief Fill a buffer region\r
+        * \param X     Lefthand edge\r
+        * \param Y     Top edge\r
+        * \param W     Width\r
+        * \param H     Height\r
+        * \param Colour        Colour to fill with\r
+        * \see VIDEO_2DOP_FILL\r
+        */\r
+       void    (*Fill)(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);\r
+       /**\r
+        * \brief Fill a buffer region\r
+        * \param DestX Lefthand edge of destination\r
+        * \param DestY Top edge of destination\r
+        * \param SrcX  Lefthand edge of source\r
+        * \param SrcY  Top edge of source\r
+        * \param W     Width\r
+        * \param H     Height\r
+        * \see VIDEO_2DOP_BLIT\r
+        */\r
+       void    (*Blit)(void *Ent, Uint16 DestX, Uint16 DestY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);\r
+}      tDrvUtil_Video_2DHandlers;\r
+\r
+/**\r
+ * \brief Handle a 2D operation stream for a driver\r
+ * \param Ent  Value to pass to handlers\r
+ * \param Buffer       Stream buffer\r
+ * \param Length       Length of stream\r
+ * \param Handlers     Handlers to use for the stream\r
+ * \param SizeofHandlers       Size of \a tDrvUtil_Video_2DHandlers according\r
+ *        to the driver. Used as version control and error avoidence.\r
+ */\r
+extern Uint64  DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,\r
+       tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers);\r
+\r
 #endif\r
index e2f0344..c9d5110 100644 (file)
@@ -266,5 +266,15 @@ extern int VFS_Symlink(char *Name, char *Link);
  * \return Boolean Success
  */
 extern int     VFS_ReadDir(int FD, char *Dest);
+/**
+ * \brief Opens a file via an open directory
+ * \note The file to open must be a direct child of the parent
+ * \param Errno        Error number
+ * \param FD   Parent Directory
+ * \param Name Child name
+ * \param Mode Open mode
+ * \return File handle (same as returned from VFS_Open)
+ */
+extern int     VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode);
 
 #endif
index cfbae0f..116dce6 100644 (file)
@@ -28,10 +28,11 @@ char        *strncpy(char *__str1, const char *__str2, size_t max);
  int   strcmp(const char *str1, const char *str2);
  int   strncmp(const char *str1, const char *str2, size_t num);
 char   *strdup(const char *Str);
- int   DivUp(int num, int dem);
+char   **str_split(const char *__str, char __ch);
  int   strpos8(const char *str, Uint32 Search);
  int   ReadUTF8(Uint8 *str, Uint32 *Val);
  int   WriteUTF8(Uint8 *str, Uint32 Val);
+ int   DivUp(int num, int dem);
 Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year);
 Uint   rand(void);
  int   CheckString(char *String);
@@ -54,8 +55,9 @@ EXPORT(strncpy);
 EXPORT(strcmp);
 EXPORT(strncmp);
 EXPORT(strdup);
-EXPORT(DivUp);
+EXPORT(str_split);
 EXPORT(strpos8);
+EXPORT(DivUp);
 EXPORT(ReadUTF8);
 EXPORT(WriteUTF8);
 EXPORT(timestamp);
@@ -181,14 +183,14 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad)
 int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
 {
        char    c, pad = ' ';
-        int    minSize = 0;
+        int    minSize = 0, len;
        char    tmpBuf[34];     // For Integers
        char    *p = NULL;
         int    isLongLong = 0;
        Uint64  val;
        size_t  pos = 0;
        // Flags
-       // int  bPadLeft = 0;
+        int    bPadLeft = 0;
        
        //Log("vsnprintf: (__s=%p, __maxlen=%i, __format='%s', ...)", __s, __maxlen, __format);
        
@@ -214,7 +216,12 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                
                // Get Argument
                val = va_arg(args, Uint);
-               //Log("val = %x", val);
+               
+               // - Padding Side Flag
+               if(c == '+') {
+                       bPadLeft = 1;
+                       c = *__format++;
+               }
                
                // - Padding
                if(c == '0') {
@@ -225,8 +232,12 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                        pad = ' ';
                
                // - Minimum length
-               minSize = 1;
-               if('1' <= c && c <= '9')
+               if(c == '*') {
+                       minSize = val;
+                       val = va_arg(args, Uint);
+                       c = *__format++;
+               }
+               else if('1' <= c && c <= '9')
                {
                        minSize = 0;
                        while('0' <= c && c <= '9')
@@ -236,6 +247,8 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                                c = *__format++;
                        }
                }
+               else
+                       minSize = 1;
                
                // - Default, Long or LongLong?
                isLongLong = 0;
@@ -285,14 +298,17 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                case 's':
                        p = (char*)(Uint)val;
                printString:
-                       //Log("p = '%s'", p);
                        if(!p)          p = "(null)";
+                       len = strlen(p);
+                       if( !bPadLeft ) while(len++ < minSize)  PUTCH(pad);
                        while(*p)       PUTCH(*p++);
+                       if( bPadLeft )  while(len++ < minSize)  PUTCH(pad);
                        break;
                
                case 'C':       // Non-Null Terminated Character Array
                        p = (char*)(Uint)val;
                        if(!p)  goto printString;
+                       //while(minSize--)      PUTCH(*p++);
                        while(minSize--)        PUTCH(*p++);
                        break;
                
@@ -444,6 +460,47 @@ char *strdup(const char *Str)
        return ret;
 }
 
+/**
+ * \brief Split a string using the passed character
+ * \return NULL terminated array of strings on the heap
+ * \param __str        String to split
+ * \param __ch Character to split by
+ */
+char **str_split(const char *__str, char __ch)
+{
+        int    i, j;
+        int    len = 1;
+       char    **ret;
+       char    *start;
+       
+       for( i = 0; __str[i]; i++ )
+       {
+               if(__str[i] == __ch)
+                       len ++;
+       }
+       
+       ret = malloc( sizeof(char*)*(len+1) + (i + 1) );
+       if( !ret )      return NULL;
+       
+       j = 1;
+       start = (char *)&ret[len+1];
+       ret[0] = start;
+       for( i = 0; __str[i]; i++ )
+       {
+               if(__str[i] == __ch) {
+                       *start++ = '\0';
+                       ret[j++] = start;
+               }
+               else {
+                       *start++ = __str[i]; 
+               }
+       }
+       *start = '\0';
+       ret[j] = NULL;
+       
+       return ret;
+}
+
 /**
  * \fn int DivUp(int num, int dem)
  * \brief Divide two numbers, rounding up
index 6eac233..747094d 100644 (file)
@@ -21,7 +21,11 @@ enum eLogLevels
        LOG_LEVEL_DEBUG,
        NUM_LOG_LEVELS
 };
-const char     *csaLevelCodes[] = {"k","p","f","e","w","n","l","d"};
+const char     *csaLevelColours[] = {
+               "\x1B[35m", "\x1B[34m", "\x1B[36m", "\x1B[31m",
+               "\x1B[33m", "\x1B[32m", "\x1B[0m", "\x1B[0m"
+               };
+const char     *csaLevelCodes[] =  {"k","p","f","e","w","n","l","d"};
 
 // === TYPES ===
 typedef struct sLogEntry
@@ -29,9 +33,9 @@ typedef struct sLogEntry
        struct sLogEntry        *Next;
        struct sLogEntry        *LevelNext;
        Sint64  Time;
-       char    Ident[8];
         int    Level;
         int    Length;
+       char    Ident[9];
        char    Data[];
 }      tLogEntry;
 typedef struct sLogList
@@ -50,10 +54,8 @@ void Log_Warning(char *Ident, char *Message, ...);
 void   Log_Notice(char *Ident, char *Message, ...);
 void   Log_Log(char *Ident, char *Message, ...);
 void   Log_Debug(char *Ident, char *Message, ...);
-//static Uint64        Log_Int_GetIdent(const char *Str);
 
 // === EXPORTS ===
-EXPORT(Log_KernelPanic);
 EXPORT(Log_Panic);
 EXPORT(Log_Error);
 EXPORT(Log_Warning);
@@ -83,7 +85,7 @@ void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
        
        ent = malloc(sizeof(tLogEntry)+len+1);
        ent->Time = now();
-       strncpy(ent->Ident, Ident, 7);
+       strncpy(ent->Ident, Ident, 8);
        ent->Level = Level;
        ent->Length = len;
        vsnprintf( ent->Data, 256, Format, Args );
@@ -118,7 +120,8 @@ void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
  */
 void Log_Int_PrintMessage(tLogEntry *Entry)
 {
-       LogF("%018lli%s [%+8s] %s\n",
+       LogF("%s%018lli%s [%+8s] %s\x1B[0m\n",
+               csaLevelColours[Entry->Level],
                Entry->Time,
                csaLevelCodes[Entry->Level],
                Entry->Ident,
index eb742d4..41fb514 100644 (file)
@@ -10,7 +10,9 @@
 #define        USE_UDI 0
 
 // === PROTOTYPES ===
- int   Modules_LoadBuiltins(void);
+ int   Module_int_Initialise(tModule *Module, char *ArgString);
+void   Modules_LoadBuiltins(void);
+void   Modules_SetBuiltinParams(char *Name, char *ArgString);
  int   Module_RegisterLoader(tModuleLoader *Loader);
  int   Module_LoadMem(void *Buffer, Uint Length, char *ArgString);
  int   Module_LoadFile(char *Path, char *ArgString);
@@ -34,6 +36,7 @@ tSpinlock     glModuleSpinlock;
 tModule        *gLoadedModules = NULL;
 tModuleLoader  *gModule_Loaders = NULL;
 tModule        *gLoadingModules = NULL;
+char   **gasBuiltinModuleArgs;
 
 // === CODE ===
 /**
@@ -45,11 +48,12 @@ tModule     *gLoadingModules = NULL;
  * \retval 0   Returned on success
  * \retval >0  Error code form the module's initialisation function
  */
-int Module_int_Initialise(tModule *Module)
+int Module_int_Initialise(tModule *Module, char *ArgString)
 {
         int    i, j;
         int    ret;
        char    **deps;
+       char    **args;
        tModule *mod;
        
        ENTER("pModule", Module);
@@ -100,7 +104,10 @@ int Module_int_Initialise(tModule *Module)
                }
                
                // Dependency is not loaded, so load it
-               ret = Module_int_Initialise( &gKernelModules[i] );
+               ret = Module_int_Initialise(
+                       &gKernelModules[i],
+                       gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL
+                       );
                if( ret )
                {
                        // The only "ok" error is NOTNEEDED
@@ -116,7 +123,15 @@ int Module_int_Initialise(tModule *Module)
                Module->Version >> 8, Module->Version & 0xFF
                );
        
-       ret = Module->Init(NULL);
+       if( ArgString )
+               args = str_split( ArgString, ',' );
+       else
+               args = NULL;
+       
+       ret = Module->Init(args);
+       
+       if(args)        free(args);
+       
        if( ret != MODULE_ERR_OK ) {
                switch(ret)
                {
@@ -136,6 +151,7 @@ int Module_int_Initialise(tModule *Module)
                LEAVE_RET('i', ret);
                return ret;
        }
+       LOG("ret = %i", ret);
        
        // Remove from loading list
        gLoadingModules = gLoadingModules->Next;
@@ -152,7 +168,7 @@ int Module_int_Initialise(tModule *Module)
 /**
  * \brief Initialises builtin modules
  */
-int Modules_LoadBuiltins()
+void Modules_LoadBuiltins()
 {
         int    i;
        
@@ -162,10 +178,37 @@ int Modules_LoadBuiltins()
        
        for( i = 0; i < giNumBuiltinModules; i++ )
        {
-               Module_int_Initialise( &gKernelModules[i] );
+               Module_int_Initialise(
+                       &gKernelModules[i],
+                       (gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL)
+                       );
        }
        
-       return 0;
+       if( gasBuiltinModuleArgs != NULL )
+               free(gasBuiltinModuleArgs);
+}
+
+/**
+ * \brief Sets the parameters for a builtin module
+ */
+void Modules_SetBuiltinParams(char *Name, char *ArgString)
+{
+        int    i;
+       if( gasBuiltinModuleArgs == NULL ) {
+               giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
+               giNumBuiltinModules /= sizeof(tModule);
+               gasBuiltinModuleArgs = calloc( giNumBuiltinModules, sizeof(char*) );
+       }
+       
+       for( i = 0; i < giNumBuiltinModules; i ++ )
+       {
+               if(strcmp( gKernelModules[i].Name, Name ) == 0) {
+                       gasBuiltinModuleArgs[i] = ArgString;
+                       return ;
+               }
+       }
+       
+       Log_Warning("Modules", "Unknown builtin kernel module '%s'", Name);
 }
 
 /**
@@ -257,7 +300,7 @@ int Module_LoadFile(char *Path, char *ArgString)
        }
        
        #if 1
-       if( Module_int_Initialise( info ) )
+       if( Module_int_Initialise( info, ArgString ) )
        {
                Binary_Unload(base);
                return 0;
index cafe7c2..9e7d35f 100644 (file)
@@ -32,6 +32,7 @@ extern tUID   Threads_GetUID();
 extern int     Threads_SetUID(Uint *errno, tUID ID);
 extern tGID    Threads_GetGID();
 extern int     Threads_SetGID(Uint *errno, tGID ID);
+extern int     Threads_SetFaultHandler(Uint Handler);
 
 // === PROTOTYPES ===
  int   Syscall_ValidString(Uint Addr);
@@ -60,6 +61,11 @@ void SyscallHandler(tSyscallRegs *Regs)
        // -- Yield current timeslice
        case SYS_YIELD: Threads_Yield();        break;
        
+       // -- Set Error Handler
+       case SYS_SETFAULTHANDLER:
+               Threads_SetFaultHandler(Regs->Arg1);
+               break;
+       
        // -- Clone the current thread
        case SYS_CLONE:
                // Call clone system call
@@ -192,7 +198,11 @@ void SyscallHandler(tSyscallRegs *Regs)
                break;
        
        case SYS_SEEK:
+               #if BITS == 64
                ret = VFS_Seek( Regs->Arg1, Regs->Arg2, Regs->Arg3 );
+               #else
+               ret = VFS_Seek( Regs->Arg1, Regs->Arg2|(((Uint64)Regs->Arg3)<<32), Regs->Arg4 );
+               #endif
                break;
                
        case SYS_TELL:
@@ -235,6 +245,16 @@ void SyscallHandler(tSyscallRegs *Regs)
                ret = VFS_ReadDir( Regs->Arg1, (void*)Regs->Arg2 );
                break;
        
+       // Open a file that is a entry in an open directory
+       case SYS_OPENCHILD:
+               if( !Syscall_ValidString(Regs->Arg2) ) {
+                       err = -EINVAL;
+                       ret = -1;
+                       break;
+               }
+               ret = VFS_OpenChild( &err, Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3);
+               break;
+       
        // Change Directory
        case SYS_CHDIR:
                if( !Syscall_ValidString(Regs->Arg1) ) {
index a83f5d6..dde278c 100644 (file)
@@ -3,7 +3,7 @@
 SYS_EXIT       Kill this thread
 SYS_CLONE      Create a new thread
 SYS_KILL       Send a signal
-SYS_SIGNAL     Set signal Handler
+SYS_SETFAULTHANDLER    Set signal Handler
 SYS_YIELD      Yield remainder of timestamp
 SYS_SLEEP      Sleep until messaged or signaled
 SYS_WAIT       Wait for a time or a message
@@ -48,6 +48,7 @@ SYS_READ      Read from an open file
 SYS_WRITE      Write to an open file
 SYS_IOCTL      Perform an IOCtl Call
 SYS_READDIR    Read from an open directory
+SYS_OPENCHILD  Open a child entry in a directory
 SYS_MKDIR      Create a new directory
 SYS_SYMLINK    Create a symbolic link
 SYS_GETACL     Get an ACL Value
index 546b2d8..7c5ff32 100644 (file)
@@ -32,31 +32,32 @@ typedef struct
 }      tConfigCommand;
 
 // === IMPORTS ===
+extern void    Arch_LoadBootModules();
 extern int     Modules_LoadBuiltins();
-//extern int   PCI_Install();
-extern void    DMA_Install();
+extern void    Modules_SetBuiltinParams(char *Name, char *ArgString);
 extern void    Debug_SetKTerminal(char *File);
-extern void    StartupPrint(char *Str);
 
 // === PROTOTYPES ===
-void   System_Init(char *ArgString);
+void   System_Init(char *Commandline);
 void   System_ParseCommandLine(char *ArgString);
+void   System_ExecuteCommandLine(void);
 void   System_ParseVFS(char *Arg);
+void   System_ParseModuleArgs(char *Arg);
 void   System_ParseSetting(char *Arg);
-void   System_ExecuteScript();
+void   System_ExecuteScript(void);
 tConfigFile    *System_Int_ParseFile(char *File);
 
 // === CONSTANTS ===
 const tConfigCommand   caConfigCommands[] = {
-       {"module", 1,2, 0, Module_LoadFile, {(Uint)"",0}},      // Load a module from a file
-       {"spawn", 1,1, 0, Proc_Spawn, {0}},             // Spawn a process
+       {"module",  1,2, 00, Module_LoadFile, {(Uint)"",0}},    // Load a module from a file
+       {"spawn",   1,1, 00, Proc_Spawn, {0}},          // Spawn a process
        // --- VFS ---
-       {"mount", 3,4, 0, VFS_Mount, {(Uint)"",0}},             // Mount a device
-       {"symlink", 2,2, 0, VFS_Symlink, {0}},  // Create a Symbolic Link
-       {"mkdir", 1,1, 0, VFS_MkDir, {0}},              // Create a Directory
-       {"open", 1,2, 0, VFS_Open, {VFS_OPENFLAG_READ,0}},      // Open a file
-       {"close", 1,1, 0x1, VFS_Close, {0}},    // Close an open file
-       {"ioctl", 3,3, 0x3, VFS_IOCtl, {0}},    // Call an IOCtl
+       {"mount",   3,4, 00, VFS_Mount, {(Uint)"",0}},          // Mount a device
+       {"symlink", 2,2, 00, VFS_Symlink, {0}}, // Create a Symbolic Link
+       {"mkdir",   1,1, 00, VFS_MkDir, {0}},           // Create a Directory
+       {"open",    1,2, 00, VFS_Open,  {VFS_OPENFLAG_READ,0}}, // Open a file
+       {"close",   1,1, 01, VFS_Close, {0}},   // Close an open file
+       {"ioctl",   3,3, 03, VFS_IOCtl, {0}},   // Call an IOCtl
        
        {"", 0,0, 0, NULL, {0}}
 };
@@ -64,13 +65,21 @@ const tConfigCommand        caConfigCommands[] = {
 
 // === GLOBALS ===
 char   *gsConfigScript = "/Acess/Conf/BootConf.cfg";
+char   *argv[32];
+ int   argc;
 
 // === CODE ===
-void System_Init(char *ArgString)
+void System_Init(char *CommandLine)
 {
+       // Parse Kernel's Command Line
+       System_ParseCommandLine(CommandLine);
        
-       // - Parse Kernel's Command Line
-       System_ParseCommandLine(ArgString);
+       // Initialise modules
+       Log_Log("Config", "Initialising builtin modules...");
+       Modules_LoadBuiltins();
+       Arch_LoadBootModules();
+       
+       System_ExecuteCommandLine();
        
        // - Execute the Config Script
        Log_Log("Config", "Executing config script...");
@@ -87,8 +96,6 @@ void System_Init(char *ArgString)
  */
 void System_ParseCommandLine(char *ArgString)
 {
-       char    *argv[32];
-        int    argc;
         int    i;
        char    *str;
        
@@ -103,13 +110,13 @@ void System_ParseCommandLine(char *ArgString)
                // Check for the end of the string
                if(*str == '\0') {      argc--; break;} 
                argv[argc] = str;
-               while(*str && *str != ' ')
-               {
-                       /*if(*str == '"') {
-                               while(*str && !(*str == '"' && str[-1] != '\\'))
-                                       str ++;
-                       }*/
-                       str++;
+               if(*str == '"') {
+                       while(*str && !(*str == '"' && str[-1] != '\\'))
+                               str ++;
+               }
+               else {
+                       while(*str && *str != ' ')
+                               str++;
                }
                if(*str == '\0')        break;  // Check for EOS
                *str = '\0';    // Cap off argument string
@@ -118,13 +125,44 @@ void System_ParseCommandLine(char *ArgString)
        if(argc < 32)
                argc ++;        // Count last argument
        
-       // --- Parse Arguments ---
+       // --- Parse Arguments (Pass 1) ---
        for( i = 1; i < argc; i++ )
        {
-               if( argv[i][0] == '/' )
-                       System_ParseVFS( argv[i] );
-               else
+               switch(argv[i][0])
+               {
+               // --- VFS ---
+               // Ignored on this pass
+               case '/':
+                       break;
+               
+               // --- Module Paramaters ---
+               // -VTerm:Width=640,Height=480,Scrollback=2
+               case '-':
+                       System_ParseModuleArgs( argv[i] );
+                       break;
+               // --- Config Options ---
+               // SCRIPT=/Acess/Conf/BootConf.cfg
+               default:
                        System_ParseSetting( argv[i] );
+                       break;
+               }
+       }
+}
+
+void System_ExecuteCommandLine(void)
+{
+        int    i;
+       for( i = 1; i < argc; i++ )
+       {
+               switch(argv[i][0])
+               {
+               // --- VFS ---
+               // Mount    /System=ext2:/Devices/ATA/A1
+               // Symlink  /Acess=/System/Acess2
+               case '/':
+                       System_ParseVFS( argv[i] );
+                       break;
+               }
        }
 }
 
@@ -180,6 +218,37 @@ void System_ParseVFS(char *Arg)
        }
 }
 
+/**
+ * \biref Parse a module argument string
+ */
+void System_ParseModuleArgs(char *Arg)
+{
+       char    *name, *args;
+        int    i;
+       
+       // Remove '-'   
+       name = Arg + 1;
+       
+       // Find the start of the args
+       i = strpos(name, ':');
+       if( i == -1 ) {
+               Log_Warning("Config", "Module spec with no arguments");
+               #if 1
+               return ;
+               #else
+               i = strlen(name);
+               args = name + i;
+               #endif
+       }
+       else {
+               name[i] = '\0';
+               args = name + i + 1;
+       }
+       
+       Log_Log("Config", "Setting boot parameters for '%s' to '%s'", name, args);
+       Modules_SetBuiltinParams(name, args);
+}
+
 /**
  * \fn void System_ParseSetting(char *Arg)
  */
@@ -220,8 +289,9 @@ void System_ParseSetting(char *Arg)
 
 /**
  * \fn void System_ExecuteScript()
+ * \brief Reads and parses the boot configuration script
  */
-void System_ExecuteScript()
+void System_ExecuteScript(void)
 {
         int    fp;
         int    fLen = 0;
@@ -242,10 +312,11 @@ void System_ExecuteScript()
                return;
        }
        
-       // Read into memory buffer
+       // Get length
        VFS_Seek(fp, 0, SEEK_END);
        fLen = VFS_Tell(fp);
        VFS_Seek(fp, 0, SEEK_SET);
+       // Read into memory buffer
        fData = malloc(fLen+1);
        VFS_Read(fp, fLen, fData);
        fData[fLen] = '\0';
@@ -419,6 +490,8 @@ void System_ExecuteScript()
                }
                free( file->Lines[i].Parts );
        }
+       
+       // Free data
        free( file );
        free( fData );
 }
index 96a38da..c62f726 100644 (file)
@@ -22,6 +22,7 @@ extern void   ArchThreads_Init();
 extern void    Proc_Start();
 extern tThread *Proc_GetCurThread();
 extern int     Proc_Clone(Uint *Err, Uint Flags);
+extern void    Proc_CallFaultHandler(tThread *Thread);
 
 // === PROTOTYPES ===
 void   Threads_Init();
@@ -62,7 +63,7 @@ tThread       gThreadZero = {
        {0},    // Saved State
        {0},    // VM State
        
-       0, {0}, {0},    // Signal State
+       0, 0,   // Current Fault, Fault Handler
        
        NULL, NULL,     // Messages, Last Message
        DEFAULT_QUANTUM, DEFAULT_QUANTUM,       // Quantum, Remaining
@@ -201,12 +202,8 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        new->NumTickets = cur->NumTickets;
        
        // Set Signal Handlers
-       new->CurSignal = 0;
-       if(Flags & CLONE_VM)
-               memset(new->SignalHandlers, 0, sizeof(new->SignalHandlers));
-       else
-               memcpy(new->SignalHandlers, cur->SignalHandlers, sizeof(new->SignalHandlers));
-       memset(&new->SignalState, 0, sizeof(tTaskState));
+       new->CurFaultNum = 0;
+       new->FaultHandler = cur->FaultHandler;
        
        for( i = 0; i < NUM_CFG_ENTRIES; i ++ )
        {
@@ -269,10 +266,11 @@ int Threads_WaitTID(int TID, int *status)
                 int    initStatus = t->Status;
                 int    ret;
                
-               if(initStatus != THREAD_STAT_ZOMBIE)
+               if(initStatus != THREAD_STAT_ZOMBIE) {
                        while(t->Status == initStatus) {
                                Threads_Yield();
                        }
+               }
                
                ret = t->RetStatus;
                switch(t->Status)
@@ -566,57 +564,52 @@ void Threads_AddActive(tThread *Thread)
        RELEASE( &giThreadListLock );
 }
 
-#if 0
 /**
- * \fn void Threads_SetSignalHandler(int Num, void *Handler)
+ * \fn void Threads_SetFaultHandler(Uint Handler)
  * \brief Sets the signal handler for a signal
  */
-void Threads_SetSignalHandler(int Num, void *Handler)
-{
-       if(Num < 0 || Num >= NSIG)      return;
-       
-       gCurrentThread->SignalHandlers[Num] = Handler;
+void Threads_SetFaultHandler(Uint Handler)
+{      
+       Log_Log("Threads", "Threads_SetFaultHandler: Handler = %p", Handler);
+       Proc_GetCurThread()->FaultHandler = Handler;
 }
 
 /**
- * \fn void Threads_SendSignal(int TID, int Num)
- * \brief Send a signal to a thread
+ * \fn void Threads_Fault(int Num)
+ * \brief Calls a fault handler
  */
-void Threads_SendSignal(int TID, int Num)
+void Threads_Fault(int Num)
 {
-       tThread *thread = Proc_GetThread(TID);
-       void    *handler;
+       tThread *thread = Proc_GetCurThread();
+       
+       Log_Log("Threads", "Threads_Fault: thread = %p", thread);
        
        if(!thread)     return ;
        
-       handler = thread->SignalHandlers[Num];
+       Log_Log("Threads", "Threads_Fault: thread->FaultHandler = %p", thread->FaultHandler);
        
-       // Panic?
-       if(handler == SIG_ERR) {
-               Proc_Kill(TID);
+       switch(thread->FaultHandler)
+       {
+       case 0: // Panic?
+               Threads_Kill(thread, -1);
+               HALT();
                return ;
-       }
-       // Dump Core?
-       if(handler == -2) {
-               Proc_Kill(TID);
+       case 1: // Dump Core?
+               Threads_Kill(thread, -1);
+               HALT();
                return ;
        }
-       // Ignore?
-       if(handler == -2)       return;
-       
-       // Check the type and handle if the thread is already in a signal
-       if(thread->CurSignal != 0) {
-               if(Num < _SIGTYPE_FATAL)
-                       Proc_Kill(TID);
-               } else {
-                       while(thread->CurSignal != 0)
-                               Proc_Yield();
-               }
+       
+       // Double Fault? Oh, F**k
+       if(thread->CurFaultNum != 0) {
+               Threads_Kill(thread, -1);       // For now, just kill
+               HALT();
        }
        
-       //TODO: 
+       thread->CurFaultNum = Num;
+       
+       Proc_CallFaultHandler(thread);
 }
-#endif
 
 // --- Process Structure Access Functions ---
 tPID Threads_GetPID()
@@ -747,9 +740,9 @@ tThread *Threads_GetNextToRun(int CPU)
  */
 void Threads_SegFault(tVAddr Addr)
 {
-       //Threads_SendSignal( Proc_GetCurThread()->TID, SIGSEGV );
        Warning("Thread #%i committed a segfault at address %p", Proc_GetCurThread()->TID, Addr);
-       Threads_Exit( 0, -1 );
+       Threads_Fault( 1 );
+       //Threads_Exit( 0, -1 );
 }
 
 // === EXPORTS ===
index 8ff15f5..f2d47ce 100644 (file)
@@ -103,7 +103,7 @@ Uint64 VFS_Write(int FD, Uint64 Length, void *Buffer)
 
 /**
  * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
- * \brief Write data to a file at a given offset (atomic)
+ * \brief Write data to a file at a given offset
  */
 Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
 {
@@ -150,6 +150,9 @@ int VFS_Seek(int FD, Sint64 Offset, int Whence)
        h = VFS_GetHandle(FD);
        if(!h)  return -1;
        
+       //Log_Debug("VFS", "VFS_Seek: (fd=0x%x, Offset=0x%llx, Whence=%i)",
+       //      FD, Offset, Whence);
+       
        // Set relative to current position
        if(Whence == 0) {
                h->Position += Offset;
index ac47683..d5e940e 100644 (file)
@@ -535,6 +535,107 @@ int VFS_Open(char *Path, Uint Mode)
        return -1;
 }
 
+
+/**
+ * \brief Open a file from an open directory
+ */
+int VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode)
+{
+       tVFS_Handle     *h;
+       tVFS_Node       *node;
+        int    i;
+       
+       // Get handle
+       h = VFS_GetHandle(FD);
+       if(h == NULL) {
+               Log_Warning("VFS", "VFS_OpenChild - Invalid file handle 0x%x", FD);
+               if(Errno)       *Errno = EINVAL;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Check for directory
+       if( !(h->Node->Flags & VFS_FFLAG_DIRECTORY) ) {
+               Log_Warning("VFS", "VFS_OpenChild - Passed handle is not a directory", FD);
+               if(Errno)       *Errno = ENOTDIR;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Find Child
+       node = h->Node->FindDir(h->Node, Name);
+       if(!node) {
+               if(Errno)       *Errno = ENOENT;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       i = 0;
+       i |= (Mode & VFS_OPENFLAG_EXEC) ? VFS_PERM_EXECUTE : 0;
+       i |= (Mode & VFS_OPENFLAG_READ) ? VFS_PERM_READ : 0;
+       i |= (Mode & VFS_OPENFLAG_WRITE) ? VFS_PERM_WRITE : 0;
+       
+       // Permissions Check
+       if( !VFS_CheckACL(node, i) ) {
+               if(node->Close) node->Close( node );
+               Log_Notice("VFS", "VFS_OpenChild - Permissions Failed");
+               if(Errno)       *Errno = EACCES;
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Check for a user open
+       if(Mode & VFS_OPENFLAG_USER)
+       {
+               // Allocate Buffer
+               if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 )
+               {
+                       Uint    addr, size;
+                       size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle);
+                       for(addr = 0; addr < size; addr += 0x1000)
+                               MM_Allocate( (Uint)gaUserHandles + addr );
+                       memset( gaUserHandles, 0, size );
+               }
+               // Get a handle
+               for(i=0;i<CFGINT(CFG_VFS_MAXFILES);i++)
+               {
+                       if(gaUserHandles[i].Node)       continue;
+                       gaUserHandles[i].Node = node;
+                       gaUserHandles[i].Position = 0;
+                       gaUserHandles[i].Mode = Mode;
+                       LEAVE('i', i);
+                       return i;
+               }
+       }
+       else
+       {
+               // Allocate space if not already
+               if( MM_GetPhysAddr( (Uint)gaKernelHandles ) == 0 )
+               {
+                       Uint    addr, size;
+                       size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
+                       for(addr = 0; addr < size; addr += 0x1000)
+                               MM_Allocate( (Uint)gaKernelHandles + addr );
+                       memset( gaKernelHandles, 0, size );
+               }
+               // Get a handle
+               for(i=0;i<MAX_KERNEL_FILES;i++)
+               {
+                       if(gaKernelHandles[i].Node)     continue;
+                       gaKernelHandles[i].Node = node;
+                       gaKernelHandles[i].Position = 0;
+                       gaKernelHandles[i].Mode = Mode;
+                       LEAVE('x', i|VFS_KERNEL_FLAG);
+                       return i|VFS_KERNEL_FLAG;
+               }
+       }
+       
+       Log_Error("VFS", "VFS_OpenChild - Out of handles");
+       if(Errno)       *Errno = ENFILE;
+       LEAVE('i', -1);
+       return -1;
+}
+
 /**
  * \fn void VFS_Close(int FD)
  * \brief Closes an open file handle
@@ -546,7 +647,7 @@ void VFS_Close(int FD)
        // Get handle
        h = VFS_GetHandle(FD);
        if(h == NULL) {
-               Warning("Invalid file handle passed to VFS_Close, 0x%x\n", FD);
+               Log_Warning("VFS", "Invalid file handle passed to VFS_Close, 0x%x\n", FD);
                return;
        }
        
@@ -658,6 +759,8 @@ tVFS_Handle *VFS_GetHandle(int FD)
 {
        tVFS_Handle     *h;
        
+       //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
+       
        if(FD < 0)      return NULL;
        
        if(FD & VFS_KERNEL_FLAG) {
@@ -670,6 +773,7 @@ tVFS_Handle *VFS_GetHandle(int FD)
        }
        
        if(h->Node == NULL)     return NULL;
+       //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
        return h;
 }
 
index ecf32ac..991a98d 100644 (file)
@@ -29,7 +29,7 @@ DRIVERS =
 MODULES  = Storage/ATA Storage/FDD
 MODULES += Network/NE2000
 MODULES += Display/VESA
-#MODULES += Display/BochsGA
+MODULES += Display/BochsGA
 MODULES += Filesystems/Ext2
 MODULES += Filesystems/FAT
 MODULES += IPStack
index 8f73ccb..3c8309e 100644 (file)
@@ -78,12 +78,11 @@ tDevFS_Driver       gBGA_DriverStruct = {
  int   giBGA_BufferFormat = 0;\r
 tVideo_IOCtl_Pos       gBGA_CursorPos = {-1,-1};\r
 Uint   *gBGA_Framebuffer;\r
-tBGA_Mode      gpBGA_CurrentMode;\r
+const tBGA_Mode        *gpBGA_CurrentMode;\r
 const tBGA_Mode        gBGA_Modes[] = {\r
-       {},\r
-       {640,480,32, 0, 640*480*4},\r
-       {800,600,32, 0, 800*600*4},\r
-       {1024,768,32, 0, 1024*768*4}\r
+       {640,480,32, 640*480*4},\r
+       {800,600,32, 800*600*4},\r
+       {1024,768,32, 1024*768*4}\r
 };\r
 #define        BGA_MODE_COUNT  (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0]))\r
 \r
@@ -111,7 +110,7 @@ int BGA_Install(char **Arguments)
        }\r
        \r
        // Map Framebuffer to hardware address\r
-       gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768);  // 768 pages (3Mb)\r
+       gBGA_Framebuffer = (void *) MM_MapHWPages(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768); // 768 pages (3Mb)\r
        \r
        return MODULE_ERR_OK;\r
 }\r
@@ -122,7 +121,7 @@ int BGA_Install(char **Arguments)
 void BGA_Uninstall()\r
 {\r
        DevFS_DelDevice( &gBGA_DriverStruct );\r
-       MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
+       MM_UnmapHWPages( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
 }\r
 \r
 /**\r
@@ -153,8 +152,8 @@ Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *Buffer)
        \r
        // Check Mode\r
        if(giBGA_CurrentMode == -1) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
+               Log_Notice("BGA", "Setting video mode to #0 (640x480x32)");\r
+               BGA_int_UpdateMode(0);  // Mode Zero is 640x480\r
        }\r
        \r
        // Text Mode\r
@@ -163,41 +162,39 @@ Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *Buffer)
        case VIDEO_BUFFMT_TEXT:\r
                {\r
                tVT_Char        *chars = Buffer;\r
-                int    pitch = gpBGA_CurrentMode->width * giVT_CharWidth;\r
-                int    x, y;\r
+                int    x, y;   // Characters/Rows\r
+                int    widthInChars = gpBGA_CurrentMode->width/giVT_CharWidth;\r
                Uint32  *dest;\r
                \r
                off /= sizeof(tVT_Char);\r
-               dest = (void*)gBGA_Framebuffer;\r
-               x = (off % gpBGA_CurrentMode->width) * giVT_CharWidth;\r
-               y = (off / gpBGA_CurrentMode->width) * giVT_CharHeight;\r
+               len /= sizeof(tVT_Char);\r
+               \r
+               x = (off % widthInChars);\r
+               y = (off / widthInChars);\r
                \r
                // Sanity Check\r
-               if(y > gpBGA_CurrentMode->height) {\r
+               if(y > gpBGA_CurrentMode->height / giVT_CharHeight) {\r
                        LEAVE('i', 0);\r
                        return 0;\r
                }\r
                \r
-               dest += y * pitch;\r
-               dest += x * giVT_CharWidth;\r
-               len /= sizeof(tVT_Char);\r
+               dest = (Uint32 *)gBGA_Framebuffer;\r
+               dest += y * gpBGA_CurrentMode->width * giVT_CharHeight;\r
                while(len--)\r
                {\r
                        VT_Font_Render(\r
                                chars->Ch,\r
-                               dest, pitch,\r
+                               dest + x*giVT_CharWidth, gpBGA_CurrentMode->width,\r
                                VT_Colour12to24(chars->BGCol),\r
                                VT_Colour12to24(chars->FGCol)\r
                                );\r
                        \r
-                       dest += giVT_CharWidth;\r
-                       \r
                        chars ++;\r
-                       x += giVT_CharWidth;\r
-                       if( x >= pitch ) {\r
+                       x ++;\r
+                       if( x >= widthInChars ) {\r
                                x = 0;\r
-                               y += giVT_CharHeight;\r
-                               dest += pitch*(giVT_CharHeight-1);\r
+                               y ++;   // Why am I keeping track of this?\r
+                               dest += gpBGA_CurrentMode->width*giVT_CharHeight;\r
                        }\r
                }\r
                }\r
@@ -344,15 +341,9 @@ int BGA_int_UpdateMode(int id)
        // Sanity Check\r
        if(id < 0 || id >= BGA_MODE_COUNT)      return -1;\r
        \r
-       // Check if it is a text mode\r
-       if( gBGA_Modes[id].flags & MODEFLAG_TEXT )\r
-               BGA_int_SetMode(\r
-                       gBGA_Modes[id].width*giVT_CharWidth,\r
-                       gBGA_Modes[id].height*giVT_CharHeight);\r
-       else    // Graphics?\r
-               BGA_int_SetMode(\r
-                       gBGA_Modes[id].width,\r
-                       gBGA_Modes[id].height);\r
+       BGA_int_SetMode(\r
+               gBGA_Modes[id].width,\r
+               gBGA_Modes[id].height);\r
        \r
        giBGA_CurrentMode = id;\r
        gpBGA_CurrentMode = &gBGA_Modes[id];\r
@@ -379,10 +370,6 @@ int BGA_int_FindMode(tVideo_IOCtl_Mode *info)
                LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp);\r
                #endif\r
                \r
-               // Check if this mode is the same type as what we want\r
-               if( !(gBGA_Modes[i].flags & MODEFLAG_TEXT) != !(info->flags & VIDEO_FLAG_TEXT) )\r
-                       continue;\r
-               \r
                // Ooh! A perfect match\r
                if(gBGA_Modes[i].width == info->width\r
                && gBGA_Modes[i].height == info->height\r
@@ -417,10 +404,6 @@ int BGA_int_FindMode(tVideo_IOCtl_Mode *info)
        info->height = gBGA_Modes[best].height;\r
        info->bpp = gBGA_Modes[best].bpp;\r
        \r
-       info->flags = 0;\r
-       if(gBGA_Modes[best].flags & MODEFLAG_TEXT)\r
-               info->flags |= VIDEO_FLAG_TEXT;\r
-       \r
        return best;\r
 }\r
 \r
@@ -441,10 +424,6 @@ int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)
        info->height = gBGA_Modes[info->id].height;\r
        info->bpp = gBGA_Modes[info->id].bpp;\r
        \r
-       info->flags = 0;\r
-       if(gBGA_Modes[info->id].flags & MODEFLAG_TEXT)\r
-               info->flags |= VIDEO_FLAG_TEXT;\r
-       \r
        return 1;\r
 }\r
 \r
index e87ca05..43b7147 100644 (file)
@@ -2,7 +2,7 @@
  * AcessOS 1\r
  * Video BIOS Extensions (Vesa) Driver\r
  */\r
-#define DEBUG  1\r
+#define DEBUG  0\r
 #define VERSION        0x100\r
 \r
 #include <acess.h>\r
@@ -15,6 +15,7 @@
 \r
 // === CONSTANTS ===\r
 #define        FLAG_LFB        0x1\r
+#define VESA_DEFAULT_FRAMEBUFFER       (KERNEL_BASE|0xA0000)\r
 \r
 // === PROTOTYPES ===\r
  int   Vesa_Install(char **Arguments);\r
@@ -24,6 +25,9 @@ Uint64        Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
  int   Vesa_Int_SetMode(int Mode);\r
  int   Vesa_Int_FindMode(tVideo_IOCtl_Mode *data);\r
  int   Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data);\r
+// --- 2D Acceleration Functions --\r
+void   Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);\r
+void   Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);\r
 \r
 // === GLOBALS ===\r
 MODULE_DEFINE(0, VERSION, Vesa, Vesa_Install, NULL, "PCI", "VM8086", NULL);\r
@@ -37,13 +41,18 @@ tDevFS_Driver       gVesa_DriverStruct = {
 };\r
 tSpinlock      glVesa_Lock;\r
 tVM8086        *gpVesa_BiosState;\r
- int   giVesaCurrentMode = -1;\r
+ int   giVesaCurrentMode = 0;\r
  int   giVesaCurrentFormat = VIDEO_BUFFMT_TEXT;\r
  int   giVesaDriverId = -1;\r
-char   *gVesaFramebuffer = (void*)0xC00A0000;\r
+char   *gpVesa_Framebuffer = (void*)VESA_DEFAULT_FRAMEBUFFER;\r
 tVesa_Mode     *gVesa_Modes;\r
  int   giVesaModeCount = 0;\r
  int   giVesaPageCount = 0;\r
+tDrvUtil_Video_2DHandlers      gVesa_2DFunctions = {\r
+       NULL,\r
+       Vesa_2D_Fill,\r
+       Vesa_2D_Blit\r
+};\r
 \r
 //CODE\r
 int Vesa_Install(char **Arguments)\r
@@ -67,11 +76,11 @@ int Vesa_Install(char **Arguments)
        // Call Interrupt\r
        VM8086_Int(gpVesa_BiosState, 0x10);\r
        if(gpVesa_BiosState->AX != 0x004F) {\r
-               Log_Warning("Vesa", "Vesa_Install - VESA/VBE Unsupported (AX = 0x%x)\n", gpVesa_BiosState->AX);\r
+               Log_Warning("VESA", "Vesa_Install - VESA/VBE Unsupported (AX = 0x%x)", gpVesa_BiosState->AX);\r
                return MODULE_ERR_NOTNEEDED;\r
        }\r
        \r
-       Log_Debug("Vesa", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs);\r
+       Log_Debug("VESA", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs);\r
        modes = (Uint16 *) VM8086_GetPointer(gpVesa_BiosState, info->VideoModes.seg, info->VideoModes.ofs);\r
        \r
        // Read Modes\r
@@ -109,12 +118,13 @@ int Vesa_Install(char **Arguments)
                        gVesa_Modes[i].fbSize = 0;\r
                }\r
                \r
+               gVesa_Modes[i].pitch = modeinfo->pitch;\r
                gVesa_Modes[i].width = modeinfo->Xres;\r
                gVesa_Modes[i].height = modeinfo->Yres;\r
                gVesa_Modes[i].bpp = modeinfo->bpp;\r
                \r
                #if DEBUG\r
-               Log_Log("Vesa", "0x%x - %ix%ix%i",\r
+               Log_Log("VESA", "0x%x - %ix%ix%i",\r
                        gVesa_Modes[i].code, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);\r
                #endif\r
        }\r
@@ -132,7 +142,7 @@ int Vesa_Install(char **Arguments)
 Uint64 Vesa_Read(tVFS_Node *Node, Uint64 off, Uint64 len, void *buffer)\r
 {\r
        #if DEBUG >= 2\r
-       LogF("Vesa_Read: () - NULL\n");\r
+       Log("Vesa_Read: () - NULL\n");\r
        #endif\r
        return 0;\r
 }\r
@@ -152,43 +162,45 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        // Default Text mode\r
        if( giVesaCurrentMode == 0 )\r
        {\r
-               Uint8   *fb = (Uint8 *)(KERNEL_BASE|0xB8000);\r
-               Uint32  *buf = Buffer;\r
+               Uint16  *fb = (Uint16*)(KERNEL_BASE|0xB8000);\r
+               tVT_Char        *chars = Buffer;\r
                 int    rem;\r
                \r
+               Length /= sizeof(tVT_Char);\r
+               Offset /= sizeof(tVT_Char);\r
+               \r
                if( giVesaCurrentFormat != VIDEO_BUFFMT_TEXT ) {\r
                        Log_Warning("VESA", "Vesa_Write - Mode 0 is not framebuffer");\r
                        LEAVE('i', -1);\r
                        return -1;\r
                }\r
                \r
-               if( Offset + Length > 25*80*8 ) {\r
+               if( Offset + Length > 25*80 ) {\r
                        Log_Warning("VESA", "Vesa_Write - Framebuffer Overflow");\r
                        LEAVE('i', 0);\r
                        return 0;\r
                }\r
                \r
                fb += 2*Offset;\r
-               for(rem = Length / sizeof(tVT_Char); rem --; fb += 2)\r
+               LOG("fb = %p", fb);\r
+               for(rem = Length; rem --; fb ++, chars++)\r
                {\r
-                       if( *buf < 0x80 )\r
-                               *fb = *buf & 0x7F;\r
+                       if( chars->Ch < 0x80 )\r
+                               *fb = chars->Ch & 0x7F;\r
                        else\r
                                *fb = 0x00;\r
-                       buf ++;\r
                        \r
-                       fb[1] = 0;\r
-                       fb[1] |= (*buf & 0x888) == 0x888 ? 0x8 : 0;\r
-                       fb[1] |= (*buf & 0x700) > 0x300 ? 0x4 : 0;\r
-                       fb[1] |= (*buf & 0x070) > 0x030 ? 0x2 : 0;\r
-                       fb[1] |= (*buf & 0x007) > 0x003 ? 0x1 : 0;\r
-                       fb[1] |= (*buf & 0x888000) == 0x888000 ? 0x80 : 0;\r
-                       fb[1] |= (*buf & 0x700000) > 0x300000 ? 0x40 : 0;\r
-                       fb[1] |= (*buf & 0x070000) > 0x030000 ? 0x20 : 0;\r
-                       fb[1] |= (*buf & 0x007000) > 0x003000 ? 0x10 : 0;\r
-                       buf ++;\r
+                       *fb |= (chars->FGCol & 0x888) == 0x888 ? 0x8 : 0;\r
+                       *fb |= (chars->FGCol & 0x700) > 0x300 ? 0x4 : 0;\r
+                       *fb |= (chars->FGCol & 0x070) > 0x030 ? 0x2 : 0;\r
+                       *fb |= (chars->FGCol & 0x007) > 0x003 ? 0x1 : 0;\r
+                       *fb |= (chars->BGCol & 0x888) == 0x888 ? 0x80 : 0;\r
+                       *fb |= (chars->BGCol & 0x700) > 0x300 ? 0x40 : 0;\r
+                       *fb |= (chars->BGCol & 0x070) > 0x030 ? 0x20 : 0;\r
+                       *fb |= (chars->BGCol & 0x007) > 0x003 ? 0x10 : 0;\r
+                       //LOG("%08x (%03x,%03x) = %04x",\r
+                       //      chars->Ch, chars->BGCol, chars->FGCol, *fb);\r
                }\r
-               Length /= sizeof(tVT_Char);\r
                Length *= sizeof(tVT_Char);\r
                LEAVE('X', Length);\r
                return Length;\r
@@ -206,51 +218,69 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        case VIDEO_BUFFMT_TEXT:\r
                {\r
                tVT_Char        *chars = Buffer;\r
-                int    pitch = gVesa_Modes[giVesaCurrentMode].width * giVT_CharWidth;\r
+                int    pitch = gVesa_Modes[giVesaCurrentMode].width;\r
+                int    widthInChars = gVesa_Modes[giVesaCurrentMode].width/giVT_CharWidth;\r
+                int    heightInChars = gVesa_Modes[giVesaCurrentMode].height/giVT_CharHeight;\r
                 int    x, y;\r
-               Uint32  *dest;\r
-                int    rem;\r
+               Uint32  *dest = (void*)gpVesa_Framebuffer;\r
+                int    i;\r
                \r
+               Length /= sizeof(tVT_Char);\r
                Offset /= sizeof(tVT_Char);\r
-               dest = (void*)gVesaFramebuffer;\r
-               x = (Offset % gVesa_Modes[giVesaCurrentMode].width) * giVT_CharWidth;\r
-               y = (Offset / gVesa_Modes[giVesaCurrentMode].width) * giVT_CharHeight;\r
+               \r
+               LOG("gVesa_Modes[%i].width = %i", giVesaCurrentMode, gVesa_Modes[giVesaCurrentMode].width);\r
+               x = Offset % widthInChars;\r
+               y = Offset / widthInChars;\r
+               LOG("(x,y) = (%i,%i) = [%i,%i]", x, y, x * giVT_CharWidth, y * giVT_CharHeight * pitch);\r
+               LOG("(w,h) = (%i,%i) = [%i,%i]",\r
+                       (int)(Length % widthInChars),\r
+                       (int)(Length / widthInChars),\r
+                       (int)((Length % widthInChars) * giVT_CharWidth),\r
+                       (int)((Length / widthInChars) * giVT_CharHeight * pitch)\r
+                       );\r
                \r
                // Sanity Check\r
-               if(y > gVesa_Modes[giVesaCurrentMode].height) {\r
+               if(y > heightInChars) {\r
                        LEAVE('i', 0);\r
                        return 0;\r
                }\r
                \r
-               dest += y * pitch;\r
+               if( Offset + Length > heightInChars*widthInChars ) {\r
+                       Log_Debug("VESA", "%i + %i > %i*%i (%i)",\r
+                               (int)Offset, (int)Length, heightInChars, widthInChars, heightInChars*widthInChars);\r
+                       Length = heightInChars*widthInChars - Offset;\r
+                       Log_Notice("VESA", "Clipping write size to %i characters", (int)Length);\r
+               }\r
+               \r
+               dest += y * giVT_CharHeight * pitch;\r
                dest += x * giVT_CharWidth;\r
-               for( rem = Length / sizeof(tVT_Char); rem--; )\r
+               \r
+               LOG("dest = %p", dest);\r
+               \r
+               for( i = 0; i < Length; i++ )\r
                {\r
                        VT_Font_Render(\r
                                chars->Ch,\r
-                               dest, pitch,\r
+                               dest + x*giVT_CharWidth, pitch,\r
                                VT_Colour12to24(chars->BGCol),\r
                                VT_Colour12to24(chars->FGCol)\r
                                );\r
                        \r
-                       dest += giVT_CharWidth;\r
-                       \r
                        chars ++;\r
-                       x += giVT_CharWidth;\r
-                       if( x >= pitch ) {\r
+                       x ++;\r
+                       if( x >= widthInChars ) {\r
                                x = 0;\r
-                               y += giVT_CharHeight;\r
-                               dest += pitch*(giVT_CharHeight-1);\r
+                               y ++;\r
+                               dest += pitch*giVT_CharHeight;\r
                        }\r
                }\r
-               Length /= sizeof(tVT_Char);\r
                Length *= sizeof(tVT_Char);\r
                }\r
                break;\r
        \r
        case VIDEO_BUFFMT_FRAMEBUFFER:\r
                {\r
-               Uint8   *destBuf = (Uint8*) ((Uint)gVesaFramebuffer + (Uint)Offset);\r
+               Uint8   *destBuf = (Uint8*) ((Uint)gpVesa_Framebuffer + (Uint)Offset);\r
                \r
                if(gVesa_Modes[giVesaCurrentMode].fbSize < Offset+Length)\r
                {\r
@@ -269,6 +299,14 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                LOG("BGA Framebuffer updated");\r
                }\r
                break;\r
+       \r
+       case VIDEO_BUFFMT_2DSTREAM:\r
+               Length = DrvUtil_Video_2DStream(\r
+                       NULL,   // Single framebuffer, so Ent is unused\r
+                       Buffer, Length, &gVesa_2DFunctions, sizeof(gVesa_2DFunctions)\r
+                       );\r
+               break;\r
+       \r
        default:\r
                LEAVE('i', -1);\r
                return -1;\r
@@ -285,6 +323,7 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)\r
 {\r
         int    ret;\r
+       //Log_Debug("VESA", "Vesa_Ioctl: (Node=%p, ID=%i, Data=%p)", Node, ID, Data);\r
        switch(ID)\r
        {\r
        case DRV_IOCTL_TYPE:    return DRV_TYPE_VIDEO;\r
@@ -302,9 +341,15 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)
        \r
        case VIDEO_IOCTL_SETBUFFORMAT:\r
                ret = giVesaCurrentFormat;\r
-               if(Data)        giVesaCurrentFormat = *(int*)Data;\r
+               if(Data) {\r
+                       //Log_Log("VESA", "Buffer mode to %i", *(int*)Data);\r
+                       giVesaCurrentFormat = *(int*)Data;\r
+               }\r
                return ret;\r
        \r
+       case VIDEO_IOCTL_SETCURSOR:     // Set cursor position\r
+               return 0;\r
+       \r
        case VIDEO_IOCTL_REQLFB:        // Request Linear Framebuffer\r
                return 0;\r
        }\r
@@ -312,10 +357,8 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)
 }\r
 \r
 int Vesa_Int_SetMode(int mode)\r
-{      \r
-       #if DEBUG\r
-       LogF("Vesa_Int_SetMode: (mode=%i)\n", mode);\r
-       #endif\r
+{\r
+       Log_Log("VESA", "Setting mode to %i", mode);\r
        \r
        // Sanity Check values\r
        if(mode < 0 || mode > giVesaModeCount)  return -1;\r
@@ -336,12 +379,13 @@ int Vesa_Int_SetMode(int mode)
        VM8086_Int(gpVesa_BiosState, 0x10);\r
        \r
        // Map Framebuffer\r
-       MM_UnmapHWPages((tVAddr)gVesaFramebuffer, giVesaPageCount);\r
+       if( (tVAddr)gpVesa_Framebuffer != VESA_DEFAULT_FRAMEBUFFER )\r
+               MM_UnmapHWPages((tVAddr)gpVesa_Framebuffer, giVesaPageCount);\r
        giVesaPageCount = (gVesa_Modes[mode].fbSize + 0xFFF) >> 12;\r
-       gVesaFramebuffer = (void*)MM_MapHWPages(gVesa_Modes[mode].framebuffer, giVesaPageCount);\r
+       gpVesa_Framebuffer = (void*)MM_MapHWPages(gVesa_Modes[mode].framebuffer, giVesaPageCount);\r
        \r
-       LogF("Vesa", "Framebuffer (Phys) = 0x%x", gVesa_Modes[mode].framebuffer);\r
-       LogF("Vesa", "Framebuffer (Virt) = 0x%x", gVesaFramebuffer);\r
+       Log_Log("VESA", "Framebuffer (Phys) = 0x%x", gVesa_Modes[mode].framebuffer);\r
+       Log_Log("VESA", "Framebuffer (Virt) = 0x%x", gpVesa_Framebuffer);\r
        \r
        // Record Mode Set\r
        giVesaCurrentMode = mode;\r
@@ -401,3 +445,58 @@ int Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data)
        data->bpp = gVesa_Modes[data->id].bpp;\r
        return 1;\r
 }\r
+\r
+// ------------------------\r
+// --- 2D Accelleration ---\r
+// ------------------------\r
+void Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)\r
+{\r
+        int    scrnwidth = gVesa_Modes[giVesaCurrentMode].width;\r
+       Uint32  *buf = (Uint32*)gpVesa_Framebuffer + Y*scrnwidth + X;\r
+       while( H -- ) {\r
+               memsetd(buf, Colour, W);\r
+               buf += scrnwidth;\r
+       }\r
+}\r
+\r
+void Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)\r
+{\r
+        int    scrnwidth = gVesa_Modes[giVesaCurrentMode].width;\r
+        int    dst = DstY*scrnwidth + DstX;\r
+        int    src = SrcY*scrnwidth + SrcX;\r
+        int    tmp;\r
+       \r
+       //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",\r
+       //      Ent, DstX, DstY, SrcX, SrcY, W, H);\r
+       \r
+       if(SrcX + W > scrnwidth)\r
+               W = scrnwidth - SrcX;\r
+       if(DstX + W > scrnwidth)\r
+               W = scrnwidth - DstX;\r
+       if(SrcY + H > gVesa_Modes[giVesaCurrentMode].height)\r
+               H = gVesa_Modes[giVesaCurrentMode].height - SrcY;\r
+       if(DstY + H > gVesa_Modes[giVesaCurrentMode].height)\r
+               H = gVesa_Modes[giVesaCurrentMode].height - DstY;\r
+       \r
+       if( dst > src ) {\r
+               // Reverse copy\r
+               dst += H*scrnwidth;\r
+               src += H*scrnwidth;\r
+               while( H -- ) {\r
+                       dst -= scrnwidth;\r
+                       src -= scrnwidth;\r
+                       tmp = W;\r
+                       for( tmp = W; tmp --; ) {\r
+                               *((Uint32*)gpVesa_Framebuffer + dst + tmp) = *((Uint32*)gpVesa_Framebuffer + src + tmp);\r
+                       }\r
+               }\r
+       }\r
+       else {\r
+               // Normal copy is OK\r
+               while( H -- ) {\r
+                       memcpyd((Uint32*)gpVesa_Framebuffer + dst, (Uint32*)gpVesa_Framebuffer + src, W);\r
+                       dst += scrnwidth;\r
+                       src += scrnwidth;\r
+               }\r
+       }\r
+}\r
index 3ec2a5f..93911de 100644 (file)
@@ -3,7 +3,7 @@
  * FAT12/16/32 Driver Version (Incl LFN)\r
  * \r
  * NOTE: This driver will only support _reading_ long file names, not\r
- * writing. I don't even know why i'm adding write-support. FAT sucks.\r
+ * writing. I don't even know why I'm adding write-support. FAT sucks.\r
  * \r
  * Known Bugs:\r
  * - LFN Is buggy in FAT_ReadDir\r
  * \todo Implement changing of the parent directory when a file is written to\r
  * \todo Implement file creation / deletion\r
  */\r
-#define DEBUG  1\r
+#define DEBUG  0\r
 #define VERBOSE        1\r
 \r
 #define CACHE_FAT      1       //!< Caches the FAT in memory\r
-#define USE_LFN                0       //!< Enables the use of Long File Names\r
+#define USE_LFN                1       //!< Enables the use of Long File Names\r
 #define        SUPPORT_WRITE   0\r
 \r
 #include <acess.h>\r
@@ -328,6 +328,8 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu
                if(Cluster)     *Cluster = cluster;\r
        }\r
        \r
+       LOG("cluster = %08x", cluster);\r
+       \r
        // Bounds Checking (Used to spot corruption)\r
        if(cluster > disk->ClusterCount + 2)\r
        {\r
@@ -976,6 +978,7 @@ int FAT_int_ReadDirSector(tVFS_Node *Node, int Sector, fat_filetable *Buffer)
                return 1;\r
        }\r
        \r
+       LOG("addr = 0x%llx", addr);\r
        // Read Sector\r
        if(VFS_ReadAt(disk->fileHandle, addr, 512, Buffer) != 512)\r
        {\r
@@ -1106,6 +1109,7 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        \r
        if(FAT_int_ReadDirSector(Node, ID/16, fileinfo))\r
        {\r
+               LOG("End of chain, end of dir");\r
                LEAVE('n');\r
                return NULL;\r
        }\r
@@ -1113,9 +1117,7 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        // Offset in sector\r
        a = ID % 16;\r
 \r
-       LOG("a = %i", a);\r
-       \r
-       LOG("name[0] = 0x%x", (Uint8)fileinfo[a].name[0]);\r
+       LOG("fileinfo[%i].name[0] = 0x%x", a, (Uint8)fileinfo[a].name[0]);\r
        \r
        // Check if this is the last entry\r
        if( fileinfo[a].name[0] == '\0' ) {\r
@@ -1128,8 +1130,13 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        // Check for empty entry\r
        if( (Uint8)fileinfo[a].name[0] == 0xE5 ) {\r
                LOG("Empty Entry");\r
+               #if 0   // Stop on empty entry?\r
+               LEAVE('n');\r
+               return NULL;    // Stop\r
+               #else\r
                LEAVE('p', VFS_SKIP);\r
                return VFS_SKIP;        // Skip\r
+               #endif\r
        }\r
        \r
        #if USE_LFN\r
@@ -1258,6 +1265,8 @@ tVFS_Node *FAT_FindDir(tVFS_Node *Node, char *Name)
                {\r
                        // Remove LFN if it does not apply\r
                        if(lfnId != i)  lfn[0] = '\0';\r
+               #else\r
+               if(fileinfo[i&0xF].attrib == ATTR_LFN)  continue;\r
                #endif\r
                        // Get Real Filename\r
                        FAT_int_ProperFilename(tmpName, fileinfo[i&0xF].name);\r
index 2c78bf1..00542d7 100644 (file)
@@ -2,6 +2,7 @@
 #
 
 OBJ = main.o files.o
+EXTRA = files.c
 NAME = InitRD
 
 -include ../Makefile.tpl
index 7ebee22..6aa6670 100644 (file)
@@ -11,7 +11,7 @@ Dir "Bin" {
 Dir "Libs" {
        File "ld-acess.so" "../../../Usermode/Libraries/ld-acess.so"
        File "libacess.so" "../../../Usermode/Libraries/libacess.so"
-       File "libc.so.1" "../../../Usermode/Libraries/libc.so.1"
+       File "libc.so.1" "../../../Usermode/Libraries/libc.so"
        File "libgcc.so" "../../../Usermode/Libraries/libgcc.so"
 }
 Dir "Conf" {
index ae1c123..a1b9178 100644 (file)
@@ -103,9 +103,10 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
         int    dataLength;
        if(Length < sizeof(tIPv4Header))        return;
        
+       #if 0
        //Log_Log("IPv4", "Version = %i", hdr->Version);
-       Log_Log("IPv4", "HeaderLength = %i", hdr->HeaderLength);
-       Log_Log("IPv4", "DiffServices = %i", hdr->DiffServices);
+       //Log_Log("IPv4", "HeaderLength = %i", hdr->HeaderLength);
+       //Log_Log("IPv4", "DiffServices = %i", hdr->DiffServices);
        Log_Log("IPv4", "TotalLength = %i", ntohs(hdr->TotalLength) );
        //Log_Log("IPv4", "Identifcation = %i", ntohs(hdr->Identifcation) );
        //Log_Log("IPv4", "TTL = %i", hdr->TTL );
@@ -116,7 +117,8 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
        Log_Log("IPv4", "Destination = %i.%i.%i.%i",
                hdr->Destination.B[0], hdr->Destination.B[1],
                hdr->Destination.B[2], hdr->Destination.B[3] );
-       
+       #endif  
+
        // Check that the version IS IPv4
        if(hdr->Version != 4) {
                Log_Log("IPv4", "hdr->Version(%i) != 4", hdr->Version);
index b709dfa..7ae927a 100644 (file)
@@ -38,14 +38,14 @@ void IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Bu
                return;
        
        Log("[IPv6 ] hdr = {");
-       Log("[IPv6 ]  .Version = %i", (hdr->Head >> (20+8)) & 0xF );
-       Log("[IPv6 ]  .TrafficClass = %i", (hdr->Head >> (20)) & 0xFF );
-       Log("[IPv6 ]  .FlowLabel = %i", hdr->Head & 0xFFFFF );
+       Log("[IPv6 ]  .Version       = %i", (hdr->Head >> (20+8)) & 0xF );
+       Log("[IPv6 ]  .TrafficClass  = %i", (hdr->Head >> (20)) & 0xFF );
+       Log("[IPv6 ]  .FlowLabel     = %i", hdr->Head & 0xFFFFF );
        Log("[IPv6 ]  .PayloadLength = 0x%04x", ntohs(hdr->PayloadLength) );
-       Log("[IPv6 ]  .NextHeader = 0x%02x", hdr->NextHeader );
-       Log("[IPv6 ]  .HopLimit = 0x%02x", hdr->HopLimit );
-       Log("[IPv6 ]  .Source = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source );
-       Log("[IPv6 ]  .Destination = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination );
+       Log("[IPv6 ]  .NextHeader    = 0x%02x", hdr->NextHeader );
+       Log("[IPv6 ]  .HopLimit      = 0x%02x", hdr->HopLimit );
+       Log("[IPv6 ]  .Source        = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source );
+       Log("[IPv6 ]  .Destination   = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination );
        Log("[IPv6 ] }");
        
 }
index e7cded3..90f3dc9 100644 (file)
@@ -2,6 +2,7 @@
  * Acess2 IP Stack
  * - TCP Handling
  */
+#define DEBUG  1
 #include "ipstack.h"
 #include "ipv4.h"
 #include "tcp.h"
@@ -9,6 +10,10 @@
 #define TCP_MIN_DYNPORT        0xC000
 #define TCP_MAX_HALFOPEN       1024    // Should be enough
 
+#define TCP_MAX_PACKET_SIZE    1024
+#define TCP_WINDOW_SIZE        0x2000
+#define TCP_RECIEVE_BUFFER_SIZE        0x4000
+
 // === PROTOTYPES ===
 void   TCP_Initialise();
 void   TCP_StartConnection(tTCPConnection *Conn);
@@ -59,28 +64,6 @@ void TCP_Initialise()
        IPv4_RegisterCallback(IP4PROT_TCP, TCP_GetPacket);
 }
 
-/**
- * \brief Open a connection to another host using TCP
- * \param Conn Connection structure
- */
-void TCP_StartConnection(tTCPConnection *Conn)
-{
-       tTCPHeader      hdr;
-
-       hdr.SourcePort = Conn->LocalPort;
-       hdr.DestPort = Conn->RemotePort;
-       Conn->NextSequenceSend = rand();
-       hdr.SequenceNumber = Conn->NextSequenceSend;
-       hdr.DataOffset = (sizeof(tTCPHeader)/4) << 4;
-       hdr.Flags = TCP_FLAG_SYN;
-       hdr.WindowSize = 0xFFFF;        // Max
-       hdr.Checksum = 0;       // TODO
-       hdr.UrgentPointer = 0;
-       
-       TCP_SendPacket( Conn, sizeof(tTCPHeader), &hdr );
-       return ;
-}
-
 /**
  * \brief Sends a packet from the specified connection, calculating the checksums
  * \param Conn Connection
@@ -123,6 +106,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
 
        Log_Log("TCP", "SourcePort = %i, DestPort = %i",
                ntohs(hdr->SourcePort), ntohs(hdr->DestPort));
+/*
        Log_Log("TCP", "SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber));
        Log_Log("TCP", "AcknowlegementNumber = 0x%x", ntohl(hdr->AcknowlegementNumber));
        Log_Log("TCP", "DataOffset = %i", hdr->DataOffset >> 4);
@@ -139,6 +123,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
        Log_Log("TCP", "WindowSize = %i", htons(hdr->WindowSize));
        Log_Log("TCP", "Checksum = 0x%x", htons(hdr->Checksum));
        Log_Log("TCP", "UrgentPointer = 0x%x", htons(hdr->UrgentPointer));
+*/
 
        if( Length > (hdr->DataOffset >> 4)*4 )
        {
@@ -208,12 +193,15 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        case 6: conn->RemoteIP.v6 = *(tIPv6*)Address;   break;
                        }
                        
+                       conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE );
+                       
                        conn->NextSequenceRcv = ntohl( hdr->SequenceNumber ) + 1;
                        conn->NextSequenceSend = rand();
                        
                        // Create node
                        conn->Node.NumACLs = 1;
                        conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
+                       conn->Node.ImplPtr = conn;
                        conn->Node.ImplInt = srv->NextID ++;
                        conn->Node.Read = TCP_Client_Read;
                        conn->Node.Write = TCP_Client_Write;
@@ -243,7 +231,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        hdr->SourcePort = htons(srv->Port);
                        hdr->DataOffset = (sizeof(tTCPHeader)/4) << 4;
                        TCP_SendPacket( conn, sizeof(tTCPHeader), hdr );
-
+                       conn->NextSequenceSend ++;
                        return ;
                }
        }
@@ -284,9 +272,25 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
        tTCPStoredPacket        *pkt;
         int    dataLen;
        
-       Connection->State = TCP_ST_OPEN;
        if(Header->Flags & TCP_FLAG_SYN) {
-               Connection->NextSequenceRcv = Header->SequenceNumber + 1;
+               Connection->NextSequenceRcv = ntohl(Header->SequenceNumber) + 1;
+       }
+       
+       if( Connection->State == TCP_ST_SYN_SENT )
+       {
+               if( (Header->Flags & (TCP_FLAG_SYN|TCP_FLAG_ACK)) == (TCP_FLAG_SYN|TCP_FLAG_ACK) ) {
+                       
+                       Header->DestPort = Header->SourcePort;
+                       Header->SourcePort = htons(Connection->LocalPort);
+                       Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+                       Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+                       Header->WindowSize = htons(TCP_WINDOW_SIZE);
+                       Header->Flags = TCP_FLAG_ACK;
+                       Header->DataOffset = (sizeof(tTCPHeader)/4) << 4;
+                       Log_Log("TCP", "ACKing SYN-ACK");
+                       TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+                       Connection->State = TCP_ST_OPEN;
+               }
        }
        
        // Get length of data
@@ -298,7 +302,28 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                Log_Log("TCP", "Conn %p, Packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
        }
        
-       if(dataLen == 0)        return ;
+       // TODO: Check what to do here
+       if(Header->Flags & TCP_FLAG_FIN) {
+               if( Connection->State == TCP_ST_FIN_SENT ) {
+                       Connection->State = TCP_ST_FINISHED;
+                       return ;
+               }
+               else {
+                       Connection->State = TCP_ST_FINISHED;
+                       Header->DestPort = Header->SourcePort;
+                       Header->SourcePort = htons(Connection->LocalPort);
+                       Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+                       Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+                       Header->Flags = TCP_FLAG_ACK;
+                       TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+                       return ;
+               }
+       }
+       
+       if(dataLen == 0) {
+               Log_Log("TCP", "Empty Packet");
+               return ;
+       }
        
        // NOTES:
        // Flags
@@ -313,6 +338,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
        memcpy(pkt->Data, (Uint8*)Header + (Header->DataOffset>>4)*4, dataLen);
        
        // Is this packet the next expected packet?
+       // TODO: Fix this to check if the packet is in the window.
        if( pkt->Sequence != Connection->NextSequenceRcv )
        {
                tTCPStoredPacket        *tmp, *prev = NULL;
@@ -339,22 +365,26 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
        {
                // Ooh, Goodie! Add it to the recieved list
                TCP_INT_AppendRecieved(Connection, pkt);
-               if(dataLen)
-                       Connection->NextSequenceRcv += dataLen;
-               else
-                       Connection->NextSequenceRcv += 1;
+               free(pkt);
+               Log_Log("TCP", "0x%08x += %i", Connection->NextSequenceRcv, dataLen);
+               Connection->NextSequenceRcv += dataLen;
                
                // TODO: This should be moved out of the watcher thread,
                // so that a single lost packet on one connection doesn't cause
                // all connections on the interface to lag.
                TCP_INT_UpdateRecievedFromFuture(Connection);
        
-               // TODO: Check ACK code validity
-               Header->AcknowlegementNumber = ntohl(pkt->Sequence) + dataLen;
-               Header->SequenceNumber = ntohl(Connection->NextSequenceSend);
-               Header->Flags &= TCP_FLAG_SYN;
-               Header->Flags = TCP_FLAG_ACK;
+               // ACK Packet
+               Header->DestPort = Header->SourcePort;
+               Header->SourcePort = htons(Connection->LocalPort);
+               Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+               Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+               Header->WindowSize = htons(TCP_WINDOW_SIZE);
+               Header->Flags &= TCP_FLAG_SYN;  // Eliminate all flags save for SYN
+               Header->Flags |= TCP_FLAG_ACK;  // Add ACK
+               Log_Log("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
                TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+               //Connection->NextSequenceSend ++;
        }
 }
 
@@ -366,16 +396,17 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
 void TCP_INT_AppendRecieved(tTCPConnection *Connection, tTCPStoredPacket *Pkt)
 {
        LOCK( &Connection->lRecievedPackets );
-       if(Connection->RecievedPackets)
+       if(Connection->RecievedBuffer->Length + Pkt->Length > Connection->RecievedBuffer->Space )
        {
-               Connection->RecievedPacketsTail->Next = Pkt;
-               Connection->RecievedPacketsTail = Pkt;
-       }
-       else
-       {
-               Connection->RecievedPackets = Pkt;
-               Connection->RecievedPacketsTail = Pkt;
+               Log_Error("TCP", "Buffer filled, packet dropped (%s)",
+               //      TCP_INT_DumpConnection(Connection)
+                       ""
+                       );
+               return ;
        }
+       
+       RingBuffer_Write( Connection->RecievedBuffer, Pkt->Data, Pkt->Length );
+       
        RELEASE( &Connection->lRecievedPackets );
 }
 
@@ -416,7 +447,8 @@ void TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection)
                
                // Looks like we found one
                TCP_INT_AppendRecieved(Connection, pkt);
-               Connection->NextSequenceRcv ++;
+               Connection->NextSequenceRcv += pkt->Length;
+               free(pkt);
        }
 }
 
@@ -484,8 +516,6 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface)
        
        srv = malloc( sizeof(tTCPListener) );
 
-       Log_Debug("TCP", "srv = %p", srv);
-
        if( srv == NULL ) {
                Log_Warning("TCP", "malloc failed for listener (%i) bytes", sizeof(tTCPListener));
                return NULL;
@@ -495,6 +525,8 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface)
        srv->Port = 0;
        srv->NextID = 0;
        srv->Connections = NULL;
+       srv->ConnectionsTail = NULL;
+       srv->NewConnections = NULL;
        srv->Next = NULL;
        srv->Node.Flags = VFS_FFLAG_DIRECTORY;
        srv->Node.Size = -1;
@@ -525,6 +557,8 @@ char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
        tTCPListener    *srv = Node->ImplPtr;
        tTCPConnection  *conn;
        char    *ret;
+       
+       ENTER("pNode iPos", Node, Pos);
 
        Log_Log("TCP", "Thread %i waiting for a connection", Threads_GetTID());
        for(;;)
@@ -538,15 +572,21 @@ char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
        
 
        // Increment the new list (the current connection is still on the 
-       // normal list
+       // normal list)
        conn = srv->NewConnections;
        srv->NewConnections = conn->Next;
        
+       LOG("conn = %p", conn);
+       LOG("srv->Connections = %p", srv->Connections);
+       LOG("srv->NewConnections = %p", srv->NewConnections);
+       LOG("srv->ConnectionsTail = %p", srv->ConnectionsTail);
+       
        RELEASE( &srv->lConnections );
 
        ret = malloc(9);
-       itoa(ret, Node->ImplInt, 16, 8, '0');
-       Log("TCP_Server_ReadDir: RETURN '%s'", ret);
+       itoa(ret, conn->Node.ImplInt, 16, 8, '0');
+       Log_Log("TCP", "Thread %i got '%s'", Threads_GetTID(), ret);
+       LEAVE('s', ret);
        return ret;
 }
 
@@ -562,21 +602,40 @@ tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name)
        char    tmp[9];
         int    id = atoi(Name);
        
+       ENTER("pNode sName", Node, Name);
+       
        // Sanity Check
        itoa(tmp, id, 16, 8, '0');
-       if(strcmp(tmp, Name) != 0)      return NULL;
+       if(strcmp(tmp, Name) != 0) {
+               LOG("'%s' != '%s' (%08x)", Name, tmp, id);
+               LEAVE('n');
+               return NULL;
+       }
+       
+       Log_Debug("TCP", "srv->Connections = %p", srv->Connections);
+       Log_Debug("TCP", "srv->NewConnections = %p", srv->NewConnections);
+       Log_Debug("TCP", "srv->ConnectionsTail = %p", srv->ConnectionsTail);
        
        // Search
        LOCK( &srv->lConnections );
        for(conn = srv->Connections;
-               conn && conn->Node.ImplInt != id;
-               conn = conn->Next);
+               conn;
+               conn = conn->Next)
+       {
+               LOG("conn->Node.ImplInt = %i", conn->Node.ImplInt);
+               if(conn->Node.ImplInt == id)    break;
+       }
        RELEASE( &srv->lConnections );
        
        // If not found, ret NULL
-       if(!conn)       return NULL;
+       if(!conn) {
+               LOG("Connection %i not found", id);
+               LEAVE('n');
+               return NULL;
+       }
        
        // Return node
+       LEAVE('p', &conn->Node);
        return &conn->Node;
 }
 
@@ -636,8 +695,8 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
 
        conn->State = TCP_ST_CLOSED;
        conn->Interface = Interface;
-       conn->LocalPort = 0;
-       conn->RemotePort = 0;
+       conn->LocalPort = -1;
+       conn->RemotePort = -1;
        memset( &conn->RemoteIP, 0, sizeof(conn->RemoteIP) );
 
        conn->Node.ImplPtr = conn;
@@ -648,6 +707,8 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
        conn->Node.IOCtl = TCP_Client_IOCtl;
        conn->Node.Close = TCP_Client_Close;
 
+       conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE );
+
        LOCK(&glTCP_OutbountCons);
        conn->Next = gTCP_OutbountCons;
        gTCP_OutbountCons = conn;
@@ -664,46 +725,123 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
 Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
        tTCPConnection  *conn = Node->ImplPtr;
-       tTCPStoredPacket        *pkt;
+       char    *destbuf = Buffer;
+       size_t  len;
        
-       Log("TCP_Client_Read: (Length=%i)", Length);
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       LOG("conn = %p", conn);
+       LOG("conn->State = %i", conn->State);
        
        // Check if connection is open
-       if( conn->State != TCP_ST_OPEN )        return 0;
+       while( conn->State == TCP_ST_HALFOPEN || conn->State == TCP_ST_SYN_SENT )
+               Threads_Yield();
+       if( conn->State != TCP_ST_OPEN ) {
+               LEAVE('i', 0);
+               return 0;
+       }
        
        // Poll packets
        for(;;)
-       {               
+       {
                // Lock list and check if there is a packet
                LOCK( &conn->lRecievedPackets );
-               if( conn->RecievedPackets == NULL ) {
+               if( conn->RecievedBuffer->Length == 0 ) {
                        // If not, release the lock, yield and try again
                        RELEASE( &conn->lRecievedPackets );
                        Threads_Yield();
                        continue;
                }
                
-               // Get packet pointer
-               pkt = conn->RecievedPackets;
-               conn->RecievedPackets = pkt->Next;
+               // Attempt to read all `Length` bytes
+               len = RingBuffer_Read( destbuf, conn->RecievedBuffer, Length );
+               
                // Release the lock (we don't need it any more)
                RELEASE( &conn->lRecievedPackets );
-               
-               Log("TCP_Client_Read: pkt->Length = %i", pkt->Length);
-               
-               // Copy Data
-               if(Length > pkt->Length)        Length = pkt->Length;
-               memcpy(Buffer, pkt->Data, Length);
-               
-               // Free packet and return
-               free(pkt);
-               return Length;
+       
+               LEAVE('i', len);
+               return len;
        }
 }
 
+/**
+ * \brief Send a data packet on a connection
+ */
+void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, void *Data)
+{
+       char    buf[sizeof(tTCPHeader)+Length];
+       tTCPHeader      *packet = (void*)buf;
+       
+       packet->SourcePort = htons(Connection->LocalPort);
+       packet->DestPort = htons(Connection->RemotePort);
+       packet->DataOffset = (sizeof(tTCPHeader)/4)*16;
+       packet->WindowSize = TCP_WINDOW_SIZE;
+       
+       packet->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+       packet->SequenceNumber = htonl(Connection->NextSequenceSend);
+       packet->Flags = TCP_FLAG_PSH|TCP_FLAG_ACK;      // Hey, ACK if you can!
+       
+       memcpy(packet->Options, Data, Length);
+       
+       TCP_SendPacket( Connection, sizeof(tTCPHeader)+Length, packet );
+       
+       Connection->NextSequenceSend += Length;
+}
+
+/**
+ * \brief Send some bytes on a connection
+ */
 Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
-       return 0;
+       tTCPConnection  *conn = Node->ImplPtr;
+       size_t  rem = Length;
+       
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       
+       // Check if connection is open
+       while( conn->State == TCP_ST_HALFOPEN || conn->State == TCP_ST_SYN_SENT )
+               Threads_Yield();
+       if( conn->State != TCP_ST_OPEN ) {
+               LEAVE('i', 0);
+               return 0;
+       }
+       
+       while( rem > TCP_MAX_PACKET_SIZE )
+       {
+               TCP_INT_SendDataPacket(conn, TCP_MAX_PACKET_SIZE, Buffer);
+               Buffer += TCP_MAX_PACKET_SIZE;
+       }
+       
+       TCP_INT_SendDataPacket(conn, rem, Buffer);
+       
+       LEAVE('i', Length);
+       return Length;
+}
+
+/**
+ * \brief Open a connection to another host using TCP
+ * \param Conn Connection structure
+ */
+void TCP_StartConnection(tTCPConnection *Conn)
+{
+       tTCPHeader      hdr;
+
+       Conn->State = TCP_ST_SYN_SENT;
+
+       hdr.SourcePort = htons(Conn->LocalPort);
+       hdr.DestPort = htons(Conn->RemotePort);
+       Conn->NextSequenceSend = rand();
+       hdr.SequenceNumber = htonl(Conn->NextSequenceSend);
+       hdr.DataOffset = (sizeof(tTCPHeader)/4) << 4;
+       hdr.Flags = TCP_FLAG_SYN;
+       hdr.WindowSize = htons(TCP_WINDOW_SIZE);        // Max
+       hdr.Checksum = 0;       // TODO
+       hdr.UrgentPointer = 0;
+       
+       TCP_SendPacket( Conn, sizeof(tTCPHeader), &hdr );
+       
+       Conn->NextSequenceSend ++;
+       Conn->State = TCP_ST_SYN_SENT;
+       return ;
 }
 
 /**
@@ -752,7 +890,7 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
                return 0;
 
        case 7: // Connect
-               if(conn->LocalPort == -1)
+               if(conn->LocalPort == 0xFFFF)
                        conn->LocalPort = TCP_GetUnusedPort();
                if(conn->RemotePort == -1)
                        return 0;
@@ -766,5 +904,23 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
 
 void TCP_Client_Close(tVFS_Node *Node)
 {
-       free(Node->ImplPtr);
+       tTCPConnection  *conn = Node->ImplPtr;
+       tTCPHeader      packet;
+       
+       packet.SourcePort = htons(conn->LocalPort);
+       packet.DestPort = htons(conn->RemotePort);
+       packet.DataOffset = (sizeof(tTCPHeader)/4)*16;
+       packet.WindowSize = TCP_WINDOW_SIZE;
+       
+       packet.AcknowlegementNumber = 0;
+       packet.SequenceNumber = htonl(conn->NextSequenceSend);
+       packet.Flags = TCP_FLAG_FIN;
+       
+       conn->State = TCP_ST_FIN_SENT;
+       
+       TCP_SendPacket( conn, sizeof(tTCPHeader), &packet );
+       
+       while( conn->State == TCP_ST_FIN_SENT ) Threads_Yield();
+       
+       free(conn);
 }
index c2ca893..492e035 100644 (file)
@@ -90,8 +90,8 @@ struct sTCPConnection
        tInterface      *Interface;     //!< Listening Interface
        tVFS_Node       Node;   //!< Node
        
-        int    NextSequenceSend;       //!< Next sequence value for outbound packets
-        int    NextSequenceRcv;        //!< Next expected sequence value for inbound
+       Uint32  NextSequenceSend;       //!< Next sequence value for outbound packets
+       Uint32  NextSequenceRcv;        //!< Next expected sequence value for inbound
        
        /**
         * \brief Non-ACKed packets
@@ -106,12 +106,11 @@ struct sTCPConnection
        
        /**
         * \brief Unread Packets
-        * \note Double ended list (fifo)
+        * \note Ring buffer
         * \{
         */
        tSpinlock       lRecievedPackets;
-       tTCPStoredPacket        *RecievedPackets;       //!< Unread Packets
-       tTCPStoredPacket        *RecievedPacketsTail;   //!< Unread Packets (End of list)
+       tRingBuffer     *RecievedBuffer;
        /**
         * \}
         */
@@ -137,8 +136,11 @@ struct sTCPConnection
 enum eTCPConnectionState
 {
        TCP_ST_CLOSED,
+       TCP_ST_SYN_SENT,
        TCP_ST_HALFOPEN,
-       TCP_ST_OPEN
+       TCP_ST_OPEN,
+       TCP_ST_FIN_SENT,
+       TCP_ST_FINISHED
 };
 
 #endif
index 3ba921d..dac5a2a 100644 (file)
@@ -140,7 +140,8 @@ int ATA_SetupIO()
        LOG("ent = %i", ent);
        gATA_BusMasterBase = PCI_GetBAR4( ent );
        if( gATA_BusMasterBase == 0 ) {
-               Warning("It seems that there is no Bus Master Controller on this machine. Get one");
+               Log_Warning("ATA", "It seems that there is no Bus Master Controller on this machine. Get one");
+               // TODO: Use PIO mode instead
                LEAVE('i', MODULE_ERR_NOTNEEDED);
                return MODULE_ERR_NOTNEEDED;
        }
index d18e52e..8aad269 100644 (file)
@@ -2,9 +2,11 @@
 #
 #
 
-CFLAGS  += -Wall -fno-builtin -fno-stack-protector
+CFLAGS  += -Wall -fno-builtin -fno-stack-protector -g
 LDFLAGS += 
 
+DEPFILES := $(OBJ:%.o=%.d)
+
 .PHONY : all clean install
 
 all: $(BIN)
@@ -17,9 +19,12 @@ install: $(BIN)
 
 $(BIN): $(OBJ)
        @echo --- $(LD) -o $@
-       @$(LD) $(LDFLAGS) -o $@ $(OBJ) -Map Map.txt
-       @objdump -d $(BIN) > $(BIN).dsm
+       @$(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map Map.txt
+       @objdump -d -S $(BIN) > $(BIN).dsm
 
 $(OBJ): %.o: %.c
        @echo --- GCC -o $@
-       @$(CC) $(CFLAGS) $(CPPFLAGS) -c $? -o $@
+       @$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
+       @$(CC) -M -MT $@ $(CPPFLAGS) $< -o $*.d
+
+-include $(DEPFILES)
index b357dea..7c903ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Acess2 GUI Shell
+ * Acess2 GUI Test App
  * - By John Hodge (thePowersGang)
  */
 #include <axwin/axwin.h>
@@ -13,9 +13,11 @@ tAxWin_Handle        ghMenubarWindow;
 
 // === CODE ===
 int main(int argc, char *argv[])
-{      
+{
+       AxWin_Register("Terminal");
+       
        // Create Window
-       ghMenubarWindow = AxWin_CreateWindow(0, 0, -1, -1, WINFLAG_NOBORDER, Menubar_HandleMessage);
+       //ghMenubarWindow = AxWin_CreateWindow(0, 0, -1, -1, WINFLAG_NOBORDER, Menubar_HandleMessage);
        
        AxWin_MessageLoop();
        
index 7fa1000..02ed977 100644 (file)
@@ -4,8 +4,10 @@
 
 CPPFLAGS += -I../include
 
-DIR = Apps/AxWin/1.0
-BIN = ../AxWinWM
-OBJ = main.o helpers.o commandline.o video.o messages.o
+DIR := Apps/AxWin/1.0
+BIN := ../AxWinWM
+OBJ := main.o helpers.o commandline.o video.o
+OBJ += messages.o interface.o wm.o decorator.o
+OBJ += image.o
 
 -include ../../Makefile.tpl
index 13379fa..eb21f3c 100644 (file)
@@ -10,6 +10,8 @@
 #include <stdint.h>
 
 #include "wm.h"
+#include "image.h"
+//#include "font.h"
 
 // === GLOBALS ===
 extern char    *gsTerminalDevice;
@@ -24,5 +26,11 @@ extern int   giMouseFD;
 
 // === Functions ===
 extern void    memset32(void *ptr, uint32_t val, size_t count);
-
+// --- Video ---
+extern void    Video_Update(void);
+extern void    Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
+extern void    Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
+extern void    Video_DrawText(short X, short Y, short W, short H, void *Font, int Point, uint32_t Color, char *Text);
+// --- Debug Hack ---
+extern void    _SysDebug(const char *Format, ...);
 #endif
diff --git a/Usermode/Applications/axwin2_src/WM/decorator.c b/Usermode/Applications/axwin2_src/WM/decorator.c
new file mode 100644 (file)
index 0000000..601f953
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Acess GUI (AxWin) Version 2
+ * By John Hodge (thePowersGang)
+ * 
+ * Widget Decorator
+ */
+#include "common.h"
+#include "wm.h"
+
+#define BOX_BGCOLOUR    0xC0C0C0
+#define BOX_BORDER      0xA0A0A0
+#define BUTTON_BGCOLOUR 0xD0D0D0
+#define BUTTON_BORDER   0xF0F0F0
+#define        TEXT_COLOUR     0x000000
+
+// === CODE ===
+void Decorator_RenderWidget(tElement *Element)
+{
+       _SysDebug("Decorator_RenderWidget: (Element={Type:%i,(%i,%i) %ix%i})",
+               Element->Type,
+               Element->CachedX, Element->CachedY,
+               Element->CachedW, Element->CachedH
+               );
+       
+       switch(Element->Type)
+       {
+       case ELETYPE_NONE:
+       case ELETYPE_BOX:       break;
+       
+       case ELETYPE_TABBAR:    // TODO: Moar
+       case ELETYPE_TOOLBAR:
+               Video_DrawRect(
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW, Element->CachedH,
+                       BOX_BORDER
+                       );
+               Video_FillRect(
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BOX_BGCOLOUR
+                       );
+               break;
+       
+       case ELETYPE_SPACER:
+               Video_FillRect(
+                       Element->CachedX+3, Element->CachedY+3,
+                       Element->CachedW-6, Element->CachedH-6,
+                       BOX_BORDER
+                       );
+               break;
+       
+       case ELETYPE_BUTTON:
+               Video_FillRect(
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BUTTON_BORDER
+                       );
+               Video_DrawRect(
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW-1, Element->CachedH-1,
+                       BUTTON_BORDER
+                       );
+               break;
+       
+       case ELETYPE_TEXT:
+               Video_DrawText(
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       NULL,
+                       10,
+                       TEXT_COLOUR,
+                       Element->Text
+                       );
+               break;
+       }
+}
diff --git a/Usermode/Applications/axwin2_src/WM/interface.c b/Usermode/Applications/axwin2_src/WM/interface.c
new file mode 100644 (file)
index 0000000..52030f3
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Acess GUI (AxWin) Version 2
+ * By John Hodge (thePowersGang)
+ */
+#include "common.h"
+
+// === GLOBALS ==
+ int   giInterface_Width = 0;
+tElement       *gpInterface_Sidebar;
+tElement       *gpInterface_MainArea;
+tElement       *gpInterface_HeaderBar;
+tElement       *gpInterface_TabBar;
+tElement       *gpInterface_TabContent;
+
+// === CODE ===
+void Interface_Init(void)
+{
+       tElement        *area;
+       tElement        *btn, *text;
+       
+       giInterface_Width = giScreenWidth/16;
+       
+       WM_SetFlags(NULL, 0);
+       
+       // -- Create Sidebar --
+       gpInterface_Sidebar = WM_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL);
+       WM_SetSize( gpInterface_Sidebar, giInterface_Width );
+       
+       // --- Top segment ---
+       area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL);
+       // ---- Menu Button ----
+       btn = WM_CreateElement(area, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH);
+       WM_SetSize(btn, giInterface_Width);
+       //text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE);
+       //WM_SetText(text, "asset://LogoSmall.sif");
+       text = WM_CreateElement(btn, ELETYPE_TEXT, 0);
+       WM_SetText(text, "Acess");
+       
+       // ---- Plain <hr/> style spacer ----
+       WM_CreateElement(area, ELETYPE_SPACER, 0);
+       
+       // Windows Go Here
+       
+       // --- Bottom Segment ---
+       area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL|ELEFLAG_ALIGN_END);
+       
+       // ---- Plain <hr/> style spacer ----
+       WM_CreateElement(area, ELETYPE_SPACER, 0);
+       
+       // ---- Version String ----
+       text = WM_CreateElement(area, ELETYPE_TEXT, ELEFLAG_WRAP);
+       WM_SetText(text, "AxWin 1.0");
+       
+       // -- Create Main Area and regions within --
+       gpInterface_MainArea = WM_CreateElement(NULL, ELETYPE_BOX, ELEFLAG_VERTICAL);
+       gpInterface_HeaderBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0);
+       gpInterface_TabBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_TABBAR, 0);
+       gpInterface_TabContent = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0);
+}
+
+void Interface_Update(void)
+{
+       giInterface_Width = giScreenWidth/16;
+       WM_SetSize( gpInterface_Sidebar, giInterface_Width );
+}
+
+void Interface_Render(void)
+{
+       
+       Video_FillRect(
+               0, 0,
+               giInterface_Width, giScreenHeight,
+               0xDDDDDD);
+       
+       Video_Update();
+}
index 7d26b39..7b42562 100644 (file)
@@ -7,7 +7,10 @@
 
 // === IMPORTS ===
 extern void    ParseCommandline(int argc, char *argv[]);
-extern void    Video_Setup();
+extern void    Video_Setup(void);
+extern void    WM_Update(void);
+extern void    Messages_PollIPC(void);
+extern void    Interface_Init(void);
 
 // === GLOBALS ===
 char   *gsTerminalDevice = NULL;
@@ -30,10 +33,13 @@ int main(int argc, char *argv[])
        ParseCommandline(argc, argv);
        
        if( gsTerminalDevice == NULL ) {
-               gsTerminalDevice = "/Devices/VTerm/7";
+               gsTerminalDevice = "/Devices/VTerm/6";
        }
        
        Video_Setup();
+       Interface_Init();
+       
+       WM_Update();
        
        // Main Loop
        for(;;)
index 0147e5f..92137f0 100644 (file)
@@ -60,10 +60,16 @@ void Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, in
 {
        switch(Msg->ID)
        {
+       #if 0
        case MSG_SREQ_PING:
-               Msg->ID = MSG_SRSP_PONG;
-               Respond(ID, sizeof(Msg->ID), Msg);
+               Msg->ID = MSG_SRSP_VERSION;
+               Msg->Size = 2;
+               Msg->Data[0] = 0;
+               Msg->Data[1] = 1;
+               *(uint16_t*)&Msg->Data[2] = -1;
+               Messages_RespondIPC(ID, sizeof(Msg->ID), Msg);
                break;
+       #endif
        default:
                fprintf(stderr, "WARNING: Unknown message %i from %i (%p)\n", Msg->ID, ID, Respond);
                _SysDebug("WARNING: Unknown message %i from %i (%p)\n", Msg->ID, ID, Respond);
index 00dbe16..d17e0e5 100644 (file)
@@ -7,13 +7,14 @@
 #include <acess/devices/terminal.h>
 
 // === PROTOTYPES ===
-void   Video_Setup();
-void   Video_Update();
+void   Video_Setup(void);
+void   Video_Update(void);
+void   Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
 
 // === GLOBALS ===
 
 // === CODE ===
-void Video_Setup()
+void Video_Setup(void)
 {
         int    tmpInt;
        
@@ -58,8 +59,42 @@ void Video_Setup()
        Video_Update();
 }
 
-void Video_Update()
+void Video_Update(void)
 {
-       seek(giTerminalFD, 0, SEEK_SET);
+       //seek(giTerminalFD, 0, SEEK_SET);
+       seek(giTerminalFD, 0, 1);
        write(giTerminalFD, giScreenWidth*giScreenHeight*4, gpScreenBuffer);
 }
+
+void Video_FillRect(short X, short Y, short W, short H, uint32_t Color)
+{
+       uint32_t        *buf = gpScreenBuffer + Y*giScreenWidth + X;
+       
+       _SysDebug("Video_FillRect: (X=%i, Y=%i, W=%i, H=%i, Color=%08x)",
+               X, Y, W, H, Color);
+       
+       if(W < 0 || X < 0 || X >= giScreenWidth)        return ;
+       if(X + W > giScreenWidth)       W = giScreenWidth - X;
+       
+       if(H < 0 || Y < 0 || Y >= giScreenHeight)       return ;
+       if(Y + H > giScreenHeight)      H = giScreenHeight - Y;
+       
+       while( H -- )
+       {
+               memset32( buf, Color, W );
+               buf += giScreenWidth;
+       }
+}
+
+void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color)
+{      
+       Video_FillRect(X, Y, W, 1, Color);
+       Video_FillRect(X, Y+H-1, W, 1, Color);
+       Video_FillRect(X, Y, 1, H, Color);
+       Video_FillRect(X+W-1, Y, 1, H, Color);
+}
+
+void Video_DrawText(short X, short Y, short W, short H, void *Font, int Point, uint32_t Color, char *Text)
+{
+       // TODO!
+}
diff --git a/Usermode/Applications/axwin2_src/WM/wm.c b/Usermode/Applications/axwin2_src/WM/wm.c
new file mode 100644 (file)
index 0000000..a8fc96d
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Acess GUI (AxWin) Version 2
+ * By John Hodge (thePowersGang)
+ * 
+ * Window Manager and Widget Control
+ */
+#include "common.h"
+#include <stdlib.h>
+#include <strings.h>
+#include "wm.h"
+
+// === IMPORTS ===
+extern void    Decorator_RenderWidget(tElement *Element);
+
+// === PROTOTYPES ===
+tElement       *WM_CreateElement(tElement *Parent, int Type, int Flags);
+void   WM_UpdateMinDims(tElement *Element);
+void   WM_SetFlags(tElement *Element, int Flags);
+void   WM_SetSize(tElement *Element, int Size);
+void   WM_SetText(tElement *Element, char *Text);
+void   WM_UpdateDimensions(tElement *Element, int Pass);
+void   WM_UpdatePosition(tElement *Element);
+void   WM_RenderWidget(tElement *Element);
+void   WM_Update(void);
+
+// === GLOBALS ===
+tElement       gWM_RootElement;
+struct {
+       void    (*Init)(tElement *This);
+       void    (*UpdateFlags)(tElement *This);
+       void    (*UpdateSize)(tElement *This);
+       void    (*UpdateText)(tElement *This);
+}      gaWM_WidgetTypes[MAX_ELETYPES] = {
+       {NULL, NULL, NULL, NULL},       // NULL
+       {NULL, NULL, NULL, NULL}        // Box
+};
+
+// === CODE ===
+// --- Widget Creation and Control ---
+tElement *WM_CreateElement(tElement *Parent, int Type, int Flags)
+{
+       tElement        *ret;
+       
+       ret = calloc(sizeof(tElement), 1);
+       if(!ret)        return NULL;
+       
+       // Prepare
+       ret->Type = Type;
+       if(Parent == NULL)      Parent = &gWM_RootElement;
+       ret->Parent = Parent;
+       ret->Flags = Flags;
+       
+       // Append to parent's list
+       ret->NextSibling = Parent->LastChild;
+       Parent->LastChild = ret;
+       if(!Parent->FirstChild) Parent->FirstChild = ret;
+       
+       ret->PaddingL = 2;
+       ret->PaddingR = 2;
+       ret->PaddingT = 2;
+       ret->PaddingB = 2;
+       
+       if( gaWM_WidgetTypes[Type].Init )
+               gaWM_WidgetTypes[Type].Init(ret);
+       
+       WM_UpdateMinDims(ret->Parent);
+       
+       return ret;
+}
+
+/**
+ * \brief Alter an element's flags 
+ */
+void WM_SetFlags(tElement *Element, int Flags)
+{
+       // Permissions are handled in the message handler
+       if(!Element) {
+               gWM_RootElement.Flags = Flags;
+               return ;
+       }
+       
+       Element->Flags = Flags;
+       return ;
+}
+
+void WM_SetSize(tElement *Element, int Size)
+{
+       if(!Element)    return ;
+       Element->FixedWith = Size;
+       return ;
+}
+
+void WM_SetText(tElement *Element, char *Text)
+{
+       if(!Element)    return ;
+       if(Element->Text)       free(Element->Text);
+       Element->Text = strdup(Text);
+       
+       switch(Element->Type)
+       {
+       case ELETYPE_IMAGE:
+               if(Element->Data)       free(Element->Data);
+               Element->Data = Image_Load( Element->Text );
+               if(!Element->Data) {
+                       Element->Flags &= ~ELEFLAG_FIXEDSIZE;
+                       return ;
+               }
+               
+               //Element->Flags |= ELEFLAG_FIXEDSIZE;
+               Element->CachedW = ((tImage*)Element->Data)->Width;
+               Element->CachedH = ((tImage*)Element->Data)->Height;
+               
+               if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
+                       Element->MinCross = ((tImage*)Element->Data)->Width;
+                       Element->MinWith = ((tImage*)Element->Data)->Height;
+               }
+               else {
+                       Element->MinWith = ((tImage*)Element->Data)->Width;
+                       Element->MinCross = ((tImage*)Element->Data)->Height;
+               }
+               break;
+       }
+       
+       return ;
+}
+
+// --- Pre-Rendering ---
+/**
+ * \brief Updates the dimensions of an element
+ * 
+ * The dimensions of an element are calculated from the parent's
+ * cross dimension (the side at right angles to the alignment) sans some
+ * padding.
+ */
+void WM_UpdateDimensions(tElement *Element, int Pass)
+{
+       tElement        *child;
+        int    nChildren = 0;
+        int    nFixed = 0;
+        int    maxCross = 0;
+        int    fixedSize = 0;
+        int    fullCross, dynWith;
+       
+       _SysDebug("%p -> Flags = 0x%x", Element, Element->Flags);
+       _SysDebug("%p ->CachedH = %i, ->PaddingT = %i, ->PaddingB = %i",
+               Element, Element->CachedH, Element->PaddingT, Element->PaddingB
+               );
+       _SysDebug("%p ->CachedW = %i, ->PaddingL = %i, ->PaddingR = %i",
+               Element, Element->CachedW, Element->PaddingL, Element->PaddingR
+               );
+       
+       // Pass 1
+       for( child = Element->FirstChild; child; child = child->NextSibling )
+       {
+               if( child->Flags & ELEFLAG_ABSOLUTEPOS )
+                       continue ;
+               
+               _SysDebug("%p,%p ->FixedWith = %i", Element, child, child->FixedWith);
+               if( child->FixedWith )
+               {
+                       nFixed ++;
+                       fixedSize += child->FixedWith;
+               }
+               
+               if( child->FixedCross && maxCross < child->FixedCross )
+                       maxCross = child->FixedCross;
+               if( child->MinCross && maxCross < child->MinCross )
+                       maxCross = child->MinCross;
+               nChildren ++;
+       }
+       
+       _SysDebug("%p - nChildren = %i, nFixed = %i", Element, nChildren, nFixed);
+       if( nChildren > nFixed ) {
+               if( Element->Flags & ELEFLAG_VERTICAL )
+                       dynWith = Element->CachedH - Element->PaddingT
+                               - Element->PaddingB;
+               else
+                       dynWith = Element->CachedW - Element->PaddingL
+                               - Element->PaddingR;
+               dynWith -= fixedSize;
+               if( dynWith < 0 )       return ;
+               dynWith /= nChildren - nFixed;
+               _SysDebug("%p - dynWith = %i", Element, dynWith);
+       }
+       
+       if( Element->Flags & ELEFLAG_VERTICAL )
+               fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR;
+       else
+               fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB;
+       
+       _SysDebug("%p - fullCross = %i", Element, fullCross);
+       
+       // Pass 2 - Set sizes and recurse
+       for( child = Element->FirstChild; child; child = child->NextSibling )
+       {
+                int    cross, with;
+               
+               _SysDebug("%p,%p ->MinCross = %i", Element, child, child->MinCross);
+
+               
+               // --- Cross Size ---
+               if( child->FixedCross )
+                       cross = child->FixedCross;
+               // Expand to fill?
+               // TODO: Extra flag so options are (Expand, Equal, Wrap)
+               else if( child->Flags & ELEFLAG_NOEXPAND )
+                       cross = child->MinCross;
+               else
+                       cross = fullCross;
+               _SysDebug("%p,%p - cross = %i", Element, child, cross);
+               if( Element->Flags & ELEFLAG_VERTICAL )
+                       child->CachedW = cross;
+               else
+                       child->CachedH = cross;
+               
+               // --- With Size ---
+               if( child->FixedWith)
+                       with = child->FixedWith;
+               else if( child->Flags & ELEFLAG_NOSTRETCH )
+                       with = child->MinWith;
+               else
+                       with = dynWith;
+               _SysDebug("%p,%p - with = %i", Element, child, with);
+               if( Element->Flags & ELEFLAG_VERTICAL )
+                       child->CachedH = with;
+               else
+                       child->CachedW = with;
+               
+               WM_UpdateDimensions(child, 0);
+       }
+}
+
+/**
+ * \brief Updates the position of an element
+ * 
+ * The parent element sets the positions of its children
+ */
+void WM_UpdatePosition(tElement *Element)
+{
+       tElement        *child;
+        int    x, y;
+       
+       if( Element->Flags & ELEFLAG_NORENDER ) return ;
+       
+       _SysDebug("Element=%p{PaddingL:%i, PaddingT:%i}",
+               Element, Element->PaddingL, Element->PaddingT);
+       
+       // Initialise
+       x = Element->CachedX + Element->PaddingL;
+       y = Element->CachedY + Element->PaddingT;
+       
+       // Update each child
+       for(child = Element->FirstChild; child; child = child->NextSibling)
+       {
+               child->CachedX = x;
+               child->CachedY = y;
+               
+               // Set Alignment
+               if( Element->Flags & ELEFLAG_ALIGN_CENTER ) {
+                       if(Element->Flags & ELEFLAG_VERTICAL )
+                               child->CachedX += Element->CachedW/2 - child->CachedW/2;
+                       else
+                               child->CachedY += Element->CachedH/2 - child->CachedH/2;
+               }
+               else if( Element->Flags & ELEFLAG_ALIGN_END ) {
+                       if(Element->Flags & ELEFLAG_VERTICAL )
+                               child->CachedX += Element->CachedW - child->CachedW;
+                       else
+                               child->CachedY += Element->CachedH - child->CachedH;
+               }
+               
+               // Update child's children positions
+               WM_UpdatePosition(child);
+               
+               // Increment
+               if(Element->Flags & ELEFLAG_VERTICAL ) {
+                       y += child->CachedH + Element->GapSize;
+               }
+               else {
+                       x += child->CachedW + Element->GapSize;
+               }
+       }
+       
+       _SysDebug("Element %p (%i,%i)",
+                Element, Element->CachedX, Element->CachedY
+               );
+}
+
+
+/**
+ * \brief Update the minimum dimensions of the element
+ * \note Called after a child's minimum dimensions have changed
+ */
+void WM_UpdateMinDims(tElement *Element)
+{
+       tElement        *child;
+       
+       if(!Element)    return;
+       
+       Element->MinCross = 0;
+       Element->MinWith = 0;
+       
+       for(child = Element->FirstChild; child; child = child->NextSibling)
+       {
+               if( Element->Parent &&
+                       (Element->Flags & ELEFLAG_VERTICAL) == (Element->Parent->Flags & ELEFLAG_VERTICAL)
+                       )
+               {
+                       if(child->FixedCross)
+                               Element->MinCross += child->FixedCross;
+                       else
+                               Element->MinCross += child->MinCross;
+                       if(child->FixedWith)
+                               Element->MinWith += child->FixedWith;
+                       else
+                               Element->MinWith += child->MinWith;
+               }
+               else
+               {
+                       if(child->FixedCross)
+                               Element->MinWith += child->FixedCross;
+                       else
+                               Element->MinWith += child->MinCross;
+                       if(child->FixedWith)
+                               Element->MinCross += child->FixedWith;
+                       else
+                               Element->MinCross += child->MinWith;
+               }
+       }
+       
+       // Recurse upwards
+       WM_UpdateMinDims(Element->Parent);
+}
+
+// --- Render ---
+void WM_RenderWidget(tElement *Element)
+{
+       tElement        *child;
+       
+       if( Element->Flags & ELEFLAG_NORENDER ) return ;
+       if( Element->Flags & ELEFLAG_INVISIBLE )        return ;
+       
+       Decorator_RenderWidget(Element);
+       
+       for(child = Element->FirstChild; child; child = child->NextSibling)
+       {
+               WM_RenderWidget(child);
+       }
+}
+
+void WM_Update(void)
+{
+       gWM_RootElement.CachedX = 0;    gWM_RootElement.CachedY = 0;
+       gWM_RootElement.CachedW = giScreenWidth;
+       gWM_RootElement.CachedH = giScreenHeight;
+       gWM_RootElement.Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
+       
+       WM_UpdateDimensions( &gWM_RootElement, 0 );
+       WM_UpdatePosition( &gWM_RootElement );
+       WM_RenderWidget( &gWM_RootElement );
+       
+       Video_Update();
+}
index e7b6bee..96d488d 100644 (file)
@@ -4,18 +4,43 @@
 
 typedef struct sElement
 {
+        int    Type;
+       
+       struct sElement *Parent;
+       struct sElement *FirstChild;
+       struct sElement *LastChild;
        struct sElement *NextSibling;
        
-       short   CachedX;
-       short   CachedY;
-       short   CachedW;
-       short   CachedH;
+       short   PaddingL, PaddingR;
+       short   PaddingT, PaddingB;
+       short   GapSize;
        
-       struct sElement *FirstChild;
+       short   FixedWith;      // Fixed Long Size attribute (height)
+       short   FixedCross;     // Fixed Cross Size attribute (width)
+       
+       char    *Text;
+       
+       // -- Attributes maitained by the element code
+       // Not touched by the user
+       short   MinWith;        // Minimum long size
+       short   MinCross;       // Minimum cross size
+       void    *Data;
+       
+       uint32_t        Flags;
+       
+       // -- Render Cache
+       short   CachedX, CachedY;
+       short   CachedW, CachedH;
 }      tElement;
 
 typedef struct sTab
 {
+        int    Type;   // Should be zero, allows a tab to be the parent of an element
+       
+       struct sElement *Parent;
+       struct sElement *FirstChild;
+       struct sElement *LastChild;
+       
        char    *Name;
        
        tElement        *RootElement;
@@ -31,4 +56,88 @@ typedef struct sApplication
        char    Name[];
 }      tApplication;
 
+// === CONSTANTS ===
+enum eElementFlags
+{
+       /**
+        * \brief Rendered
+        * 
+        * If set, the element will be ignored in calculating sizes and
+        * rendering.
+        */
+       ELEFLAG_NORENDER    = 0x001,
+       /**
+        * \brief Element visibility
+        * 
+        * If set, the element is not drawn.
+        */
+       ELEFLAG_INVISIBLE   = 0x002,
+       
+       /**
+        * \brief Position an element absulutely
+        */
+       ELEFLAG_ABSOLUTEPOS = 0x004,
+       
+       /**
+        * \brief Fixed size element
+        */
+       ELEFLAG_FIXEDSIZE   = 0x008,
+       
+       /**
+        * \brief Element "orientation"
+        */
+       ELEFLAG_VERTICAL    = 0x010,//  ELEFLAG_HORIZONTAL  = 0x000,
+       /**
+        * \brief Action for text that overflows
+        */
+       ELEFLAG_WRAP        = 0x020,//  ELEFLAG_NOWRAP      = 0x000,
+       /**
+        * \brief Cross size action
+        * 
+        * If this flag is set, the element will only be as large (across
+        * its parent) as is needed to encase the contents of the element.
+        * Otherwise, the element will expand to fill all avaliable space.
+        */
+       ELEFLAG_NOEXPAND    = 0x040,
+       
+       ELEFLAG_NOSTRETCH   = 0x080,
+       
+       /**
+        * \brief Center alignment
+        */
+       ELEFLAG_ALIGN_CENTER= 0x100,
+       /**
+        * \brief Right/Bottom alignment
+        */
+       ELEFLAG_ALIGN_END = 0x200
+};
+
+/**
+ */
+enum eElementTypes
+{
+       ELETYPE_NONE,
+       
+       ELETYPE_BOX,    //!< Content box
+       ELETYPE_TABBAR, //!< Tab Bar
+       ELETYPE_TOOLBAR,        //!< Tool Bar
+       
+       ELETYPE_BUTTON, //!< Push Button
+       ELETYPE_TEXT,   //!< Text
+       ELETYPE_IMAGE,  //!< Image
+       
+       ELETYPE_SPACER, //!< Visual Spacer
+       
+       MAX_ELETYPES    = 0x100
+};
+
+// === FUNCTIONS ===
+/**
+ * \brief Create a new element as a child of \a Parent
+ */
+extern tElement        *WM_CreateElement(tElement *Parent, int Type, int Flags);
+extern void    WM_SetFlags(tElement *Element, int Flags);
+extern void    WM_SetSize(tElement *Element, int Size);
+extern void    WM_SetText(tElement *Element, char *Text);
+
 #endif
index 2866dbd..456974f 100644 (file)
@@ -87,6 +87,7 @@ char *GetUsername()
        while( (ch = fgetc(stdin)) != -1 && ch != '\n' )
        {
                if(ch == '\b') {
+                       if( pos <= 0 )  continue;
                        pos --;
                        ret[pos] = '\0';
                }
@@ -122,6 +123,7 @@ char *GetPassword()
        while( (ch = fgetc(stdin)) != -1 && ch != '\n' )
        {
                if(ch == '\b') {
+                       if( pos <= 0 )  continue;
                        pos --;
                        ret[pos] = '\0';
                }
index 297f5f9..db51613 100644 (file)
@@ -294,7 +294,7 @@ void DisplayFile(char *Filename)
                        else if(size < (uint64_t)2048*1024*1024*1024) { // < 2 TiB
                                printf("%4i GiB ", size>>30);
                        }
-                       else {  // Greater than 2 TiB
+                       else {  // Greater than 2 TiB (if your files are larger than this, you are Doing It Wrong [TM])
                                printf("%4i TiB ", size>>40);
                        }
                } else {
diff --git a/Usermode/Applications/testserver_src/Makefile b/Usermode/Applications/testserver_src/Makefile
new file mode 100644 (file)
index 0000000..5b6d255
--- /dev/null
@@ -0,0 +1,9 @@
+# Project: testsrv
+
+-include ../Makefile.cfg
+
+OBJ = main.o
+BIN = ../testsrv
+
+-include ../Makefile.tpl
+
diff --git a/Usermode/Applications/testserver_src/main.c b/Usermode/Applications/testserver_src/main.c
new file mode 100644 (file)
index 0000000..0b787dd
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Acess2 Test Server
+ */
+#include <acess/sys.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/**
+ * \fn int main(int argc, char *argv[])
+ * \brief Entrypoint
+ */
+int main(int argc, char *argv[])
+{
+        int    srv = -1;
+        int    con = -1;
+        int    len;
+       uint16_t        port;
+       char    buf[8+1];
+       uint8_t data[4096];     // Packet Data
+        
+       srv = open("/Devices/ip/1/tcps", OPENFLAG_READ|OPENFLAG_EXEC);
+       if(srv == -1) {
+               fprintf(stderr, "Unable top open TCP server '/Devices/ip/1/tcps'\n");
+               return -1;
+       }
+       port = 80;      ioctl(srv, 4, &port);   // Set Port
+       
+       for(;;)
+       {
+               readdir( srv, buf );
+               printf("Connection '/Devices/ip/1/tcps/%s'\n", buf);
+               con = _SysOpenChild(srv, buf, OPENFLAG_READ|OPENFLAG_WRITE);
+               if(con == -1) {
+                       fprintf(stderr, "Wtf! Why didn't this open?\n");
+                       return 1;
+               }
+               
+               len = read(con, 4096, data);
+               if( len == -1 ) {
+                       printf("Connection closed\n");
+                       close(con);
+                       continue;
+               }
+               if( len != 0 )
+               {
+                       printf("Packet Data: (%i bytes)\n", len);
+                       printf("%s\n", data);
+                       printf("--- EOP ---\n");
+               }
+               
+               #define RET_STR "HTTP/1.1 200 OK\r\n"\
+                       "Content-Type: text/plain\r\n"\
+                       "Content-Length: 92\r\n"\
+                       "\r\n"\
+                       "<html><head><title>Acess2 Web Server</title></head><body><h1>Hello World!</h1></body></html>\r\n"
+               
+               write(con, sizeof(RET_STR), RET_STR);
+               
+               close(con);
+       }
+       
+       return 0;
+}
index abd8c81..78e39fb 100644 (file)
@@ -7,5 +7,5 @@ MAKEDEP  = $(CC) -M
 
 ASFLAGS  = -felf
 CPPFLAGS = -I$(ACESSDIR)/Usermode/include/
-CFLAGS   = -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS)
-LDFLAGS  = -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain -x -L.. -lacess
+CFLAGS   = -g -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS)
+LDFLAGS  = -g -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain -x -L.. -lacess
index 709aaac..b501b7d 100644 (file)
@@ -6,13 +6,14 @@
 all: $(BIN)
 
 clean:
-       $(RM) $(BIN) $(OBJ)
+       $(RM) $(BIN) $(OBJ) $(BIN).dsm
 
 install: $(BIN)
        $(xCP) $(BIN) $(DISTROOT)/Libs/
 
 $(BIN): $(OBJ)
        $(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
+       @$(OBJDUMP) -d -S $(BIN) > $(BIN).dsm
 
 %.o: %.c
        $(CC) $(CFLAGS) -o $@ -c $<
index 82a7dd2..405ec20 100644 (file)
@@ -3,12 +3,14 @@
 
 BIN = ../acess.ld
 
+.PHONY: all clean install
+
 all: ../acess.ld
 
 clean:
        $(RM) ../acess.ld
 
-install:
+install: ../acess.ld
 
 ../acess.ld:   acess.ld.h
        cpp -nostdinc -U i386 -P -C $< -o $@ -DACESSDIR=$(ACESSDIR)
index f191556..d15f271 100644 (file)
@@ -6,11 +6,11 @@
 
 ASFLAGS = -felf
 
-.PHONY: all clean
+.PHONY: all clean install
 
 all: ../crt0.o
 
-install:
+install: ../crt0.o
 
 clean:
        $(RM) ../crt0.o
index bc2efbd..81913d5 100644 (file)
 \r
 #include <stdarg.h>\r
 \r
+// === CONSTANTS ===\r
+#define        MAX_LOADED_LIBRARIES    64\r
+#define        MAX_STRINGS_BYTES       4096\r
+#define        SYSTEM_LIB_DIR  "/Acess/Libs/"\r
+\r
 // === Types ===\r
 typedef unsigned int   Uint;\r
 typedef unsigned char  Uint8;\r
@@ -19,6 +24,14 @@ typedef unsigned long        Uint32;
 typedef signed char            Sint8;\r
 typedef signed short   Sint16;\r
 typedef signed long            Sint32;\r
+\r
+typedef struct {\r
+       Uint    Base;\r
+       char    *Name;\r
+}      tLoadedLib;\r
+\r
+// === GLOBALS ===\r
+extern tLoadedLib      gLoadedLibraries[MAX_LOADED_LIBRARIES];\r
 
 // === Main ===
 extern int     DoRelocate( Uint base, char **envp, char *Filename );
@@ -42,6 +55,7 @@ extern void   SysDebug(char *fmt, ...);       //!< Now implemented in main.c
 extern void    SysDebugV(char *fmt, ...);\r
 extern Uint    SysLoadBin(char *path, Uint *entry);\r
 extern Uint    SysUnloadBin(Uint Base);\r
+extern void    SysSetFaultHandler(int (*Hanlder)(int));\r
 extern int     open(char *filename, int flags);\r
 extern void    close(int fd);\r
 
index 3797333..49b9bd8 100644 (file)
@@ -9,6 +9,7 @@
 [global _SysExit]\r
 [global _SysLoadBin]\r
 [global _SysUnloadBin]\r
+[global _SysSetFaultHandler]\r
 [global _open]\r
 [global _close]\r
 \r
@@ -77,3 +78,11 @@ _close:
        int 0xAC\r
        pop ebx\r
        ret\r
+\r
+_SysSetFaultHandler:\r
+       push ebx\r
+       mov eax, SYS_SETFAULTHANDLER\r
+       mov ebx, [esp+0x8]      ; File Descriptor\r
+       int 0xAC\r
+       pop ebx\r
+       ret\r
index 5cfa26e..e0b3b25 100644 (file)
 # define DEBUGS(v...)  \r
 #endif\r
 \r
-// === CONSTANTS ===\r
-#define        MAX_LOADED_LIBRARIES    64\r
-#define        MAX_STRINGS_BYTES       4096\r
-#define        SYSTEM_LIB_DIR  "/Acess/Libs/"\r
-\r
 // === PROTOTYPES ===\r
 Uint   IsFileLoaded(char *file);
  int   GetSymbolFromBase(Uint base, char *name, Uint *ret);\r
 \r
-// === GLOABLS ===\r
-struct {\r
-       Uint    Base;\r
+// === CONSTANTS ===\r
+const struct {\r
+       Uint    Value;\r
        char    *Name;\r
-}      gLoadedLibraries[MAX_LOADED_LIBRARIES];\r
+}      caLocalExports[] = {\r
+       {gLoadedLibraries, "gLoadedLibraries"}\r
+};\r
+\r
+// === GLOABLS ===\r
+tLoadedLib     gLoadedLibraries[MAX_LOADED_LIBRARIES];\r
 char   gsLoadedStrings[MAX_STRINGS_BYTES];\r
 char   *gsNextAvailString = gsLoadedStrings;\r
 //tLoadLib     *gpLoadedLibraries = NULL;\r
@@ -200,6 +200,12 @@ Uint GetSymbol(char *name)
 {\r
         int    i;
        Uint    ret;\r
+       for(i=0;i<sizeof(caLocalExports)/sizeof(caLocalExports[0]);i++)\r
+       {\r
+               if( strcmp(caLocalExports[i].Name, name) == 0 )\r
+                       return caLocalExports[i].Value;\r
+       }\r
+       \r
        for(i=0;i<sizeof(gLoadedLibraries)/sizeof(gLoadedLibraries[0]);i++)\r
        {\r
                if(gLoadedLibraries[i].Base == 0)       break;\r
index dc5d4d3..678dc9a 100644 (file)
@@ -22,9 +22,6 @@ extern void   gLinkedBase;
 int SoMain(Uint base, int arg1)\r
 {\r
         int    ret;\r
-       \r
-       //SysDebug("SoMain: base = 0x%x", base);\r
-       //SysDebug("SoMain: arg1 = 0x%x", arg1);\r
         \r
        // - Assume that the file pointer will be less than 4096\r
        if(base < 0x1000) {\r
index 9acb5eb..a6267f2 100644 (file)
@@ -25,6 +25,6 @@ $(BIN): $(OBJ)
        @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
        @$(STRIP) $(BIN)
        
-%.ao: %.asm syscalls.inc.asm
+%.ao: %.asm syscalls.inc.asm ../../../Kernel/include/syscalls.inc.asm
        @echo $(AS) -o $@
        @$(AS) $(ASFLAGS) -o $@ $<
index ef5b123..e097d8c 100644 (file)
@@ -18,7 +18,6 @@ SoMain:
 SYSCALL1       _exit, SYS_EXIT
 SYSCALL2       clone, SYS_CLONE
 SYSCALL2       kill, SYS_KILL
-SYSCALL2       signal, SYS_SIGNAL
 SYSCALL0       yield, SYS_YIELD
 SYSCALL0       sleep, SYS_SLEEP
 SYSCALL1       wait, SYS_WAIT
@@ -44,5 +43,6 @@ SYSCALL3      SysSpawn, SYS_SPAWN
 SYSCALL3       execve, SYS_EXECVE
 SYSCALL2       SysLoadBin, SYS_LOADBIN
 
+SYSCALL1       _SysSetFaultHandler, SYS_SETFAULTHANDLER
 
 SYSCALL6       _SysDebug, 0x100
index deb9751..44bce6b 100644 (file)
@@ -20,3 +20,5 @@ SYSCALL2      _SysGetACL, SYS_GETACL  ; int, void*
 SYSCALL1       chdir, SYS_CHDIR        ; char*
 SYSCALL3       ioctl, SYS_IOCTL        ; int, int, void*
 SYSCALL4       _SysMount, SYS_MOUNT    ; char*, char*, char*, char*
+
+SYSCALL3       _SysOpenChild, SYS_OPENCHILD
index 5529140..2ce02e4 100644 (file)
@@ -7,7 +7,7 @@ CPPFLAGS +=
 CFLAGS   += -Wall
 LDFLAGS  += -lc -soname libaxwin2.so
 
-OBJ = main.o messages.o windows.o
+OBJ = main.o messages.o
 BIN = ../libaxwin2.so
 
 include ../Makefile.tpl
index 28d2839..f0a7ea1 100644 (file)
@@ -22,5 +22,6 @@ enum eAxWin_Modes
 
 // === Variables ===
 extern int     giAxWin_Mode;
+extern int     giAxWin_PID;
 
 #endif
index 1a12561..1dfcf9b 100644 (file)
@@ -7,12 +7,74 @@
  * main.c - Library Initialisation
  */
 #include "common.h"
+#include <string.h>
 
 // === GLOBALS ===
  int   giAxWin_Mode = 0;
+ int   giAxWin_PID = 0;
 
 // === CODE ===
 int SoMain()
 {
        return 0;
 }
+
+int AxWin_Register(const char *Name)
+{
+       tAxWin_Message  req;
+       tAxWin_Message  *msg;
+       tAxWin_RetMsg   *ret;
+        int    len = strlen(Name);
+       
+       req.ID = MSG_SREQ_REGISTER;
+       req.Size = 1 + (len+1)/4;
+       strcpy(req.Data, Name);
+       
+       AxWin_SendMessage(&req);
+       
+       for(;;)
+       {
+               msg = AxWin_WaitForMessage();
+               
+               if(msg->ID == MSG_SREQ_ADDTAB)
+               {
+                       ret = (void*) &msg->Data[0];
+                       if( ret->ReqID == MSG_SREQ_REGISTER )
+                               break;
+               }
+               
+               AxWin_HandleMessage(msg);
+               free(msg);
+       }
+       
+       return !!ret->Bool;
+}
+
+tAxWin_Handle AxWin_AddTab(const char *Title)
+{
+       tAxWin_Message  req;
+       tAxWin_Message  *msg;
+       tAxWin_RetMsg   *ret;
+        int    len = strlen(Title);
+       
+       req.ID = MSG_SREQ_ADDTAB;
+       req.Size = 1 + (len+1)/4;
+       strcpy(req.Data, Title);
+       
+       for(;;)
+       {
+               msg = AxWin_WaitForMessage();
+               
+               if(msg->ID == MSG_SRSP_RETURN)
+               {
+                       ret = (void*) &msg->Data[0];
+                       if( ret->ReqID == MSG_SREQ_ADDTAB )
+                               break;
+               }
+               
+               AxWin_HandleMessage(msg);
+               free(msg);
+       }
+       
+       return (tAxWin_Handle) ret->Handle;
+}
index d0fc5da..7b43bda 100644 (file)
 tAxWin_Message *AxWin_WaitForMessage();
  int   AxWin_HandleMessage(tAxWin_Message *Message);
 
+// ===  ===
+
 // === CODE ===
+int AxWin_SendMessage(tAxWin_Message *Message)
+{
+       switch(giAxWin_Mode)
+       {
+       case AXWIN_MODE_IPC:
+               SysSendMessage(giAxWin_PID, Message->Size*4, Message);
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
 /**
  * \brief Loop forever, checking and waiting for messages
  */
index a37bfbb..efb418b 100644 (file)
@@ -13,11 +13,11 @@ struct sAxWin_Window
 {
        struct sAxWin_Window    *Next;
        uint32_t        WmHandle;
-       tAxWin_MessageCallback  Callback;
+       tAxWin_MessageCallback  *Callback;
 };
 
 // === PROTOTYPES ===
-tAxWin_Handle  AxWin_CreateWindow(
+tAxWin_Window  *AxWin_CreateWindow(
        int16_t X, int16_t Y, int16_t W, int16_t H,
        uint32_t Flags, tAxWin_MessageCallback *Callback
        );
@@ -27,7 +27,7 @@ tAxWin_Handle AxWin_CreateWindow(
 tAxWin_Window  *gProcessWindows;
 
 // === CODE ===
-tAxWin_Handle  AxWin_CreateWindow(
+tAxWin_Window  *AxWin_CreateWindow(
        int16_t X, int16_t Y,
        int16_t W, int16_t H,
        uint32_t Flags, tAxWin_MessageCallback *Callback)
index 1e3fc46..a12ff45 100644 (file)
@@ -6,22 +6,22 @@
 CPPFLAGS += \r
 CFLAGS   += \r
 ASFLAGS  +=\r
-LDFLAGS  += -soname libc.so.1 -Map map.txt -lgcc\r
+LDFLAGS  += -soname libc.so -Map map.txt -lgcc\r
 \r
 OBJ = stub.o heap.o stdlib.o env.o fileIO.o string.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
 # signals.o\r
-BIN = ../libc.so.1\r
+BIN = ../libc.so\r
 \r
 .PHONY:        all clean install\r
 \r
 all: $(BIN)\r
 \r
 clean:\r
-       $(RM) $(BIN) ../libc.so $(OBJ) $(DEPFILES) libc.so.1.dsm libc.so.1.dmp map.txt\r
+       $(RM) $(BIN) $(OBJ) $(DEPFILES) libc.so.dsm libc.so.dmp map.txt\r
 \r
 install: $(BIN)\r
-       $(xCP) ../libc.so.1 $(DISTROOT)/Libs/\r
+       $(xCP) $(BIN) $(DISTROOT)/Libs/\r
 \r
 # Core C Library\r
 $(BIN): $(OBJ)\r
@@ -29,7 +29,6 @@ $(BIN): $(OBJ)
        @$(LD) $(LDFLAGS) $(OBJ) -o $@\r
        @$(OBJDUMP) -d $@ > libc.so.1.dsm\r
        @$(OBJDUMP) -x -r -R $@ > libc.so.1.dmp\r
-       cp ../libc.so.1 ../libc.so\r
 \r
 # C Runtime 0\r
 ../crt0.o: crt0.asm\r
index 5fdac4c..1b1d3f3 100644 (file)
@@ -17,7 +17,7 @@
 #define        _stdout 1\r
 \r
 // === PROTOTYPES ===\r
-EXPORT void    itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned);\r
+EXPORT void    itoa(char *buf, uint64_t num, uint base, int minLength, char pad, int bSigned);\r
 struct sFILE   *get_file_struct();\r
 \r
 // === GLOBALS ===\r
@@ -150,20 +150,28 @@ EXPORT int vfprintf(FILE *fp, const char *format, va_list args)
 {\r
        va_list tmpList = args;\r
         int    size;\r
-       char    *buf;\r
+       char    sbuf[1024];\r
+       char    *buf = sbuf;\r
         \r
        if(!fp || !format)      return -1;\r
        \r
-       size = vsprintf(NULL, (char*)format, tmpList);\r
+       size = vsnprintf(sbuf, 1024, (char*)format, tmpList);\r
        \r
-       buf = (char*)malloc(size+1);\r
-       buf[size] = '\0';\r
+       if( size >= 1024 )\r
+       {\r
+               buf = (char*)malloc(size+1);\r
+               if(!buf) {\r
+                       write(_stdout, 31, "vfprintf ERROR: malloc() failed");\r
+                       return 0;\r
+               }\r
+               buf[size] = '\0';\r
        \r
-       // Print\r
-       vsprintf(buf, (char*)format, args);\r
+               // Print\r
+               vsnprintf(buf, size+1, (char*)format, args);\r
+       }\r
        \r
        // Write to stream\r
-       write(fp->FD, size+1, buf);\r
+       write(fp->FD, size, buf);\r
        \r
        // Free buffer\r
        free(buf);\r
@@ -271,17 +279,22 @@ EXPORT int        puts(const char *str)
        return len;\r
 }\r
 \r
+EXPORT int vsprintf(char * __s, const char *__format, va_list __args)\r
+{\r
+       return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
+}\r
+\r
 //sprintfv\r
 /**\r
- \fn EXPORT void vsprintf(char *buf, const char *format, va_list args)\r
+ \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
  \brief Prints a formatted string to a buffer\r
  \param buf    Pointer - Destination Buffer\r
  \param format String - Format String\r
  \param args   VarArgs List - Arguments\r
 */\r
-EXPORT int vsprintf(char *buf, const char *format, va_list args)\r
+EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args)\r
 {\r
-       char    tmp[33];\r
+       char    tmp[65];\r
         int    c, minSize;\r
         int    pos = 0;\r
        char    *p;\r
@@ -295,7 +308,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
        {\r
                // Non-control character\r
                if (c != '%') {\r
-                       if(buf) buf[pos] = c;\r
+                       if(buf && pos < __maxlen)       buf[pos] = c;\r
                        pos ++;\r
                        continue;\r
                }\r
@@ -303,7 +316,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                // Control Character\r
                c = *format++;\r
                if(c == '%') {  // Literal %\r
-                       if(buf) buf[pos] = '%';\r
+                       if(buf && pos < __maxlen)       buf[pos] = '%';\r
                        pos ++;\r
                        continue;\r
                }\r
@@ -358,12 +371,15 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                \r
                // Pointer\r
                case 'p':\r
-                       if(buf) {\r
+                       if(buf && pos+2 < __maxlen) {\r
                                buf[pos] = '*';\r
                                buf[pos+1] = '0';\r
                                buf[pos+2] = 'x';\r
                        }\r
                        pos += 3;\r
+                       arg = va_arg(args, uint32_t);\r
+                       itoa(tmp, arg, 16, minSize, pad, 0);\r
+                       goto sprintf_puts;\r
                        // Fall through to hex\r
                // Unsigned Hexadecimal\r
                case 'x':\r
@@ -392,9 +408,11 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                        p = (void*)(intptr_t)arg;\r
                sprintf_puts:\r
                        if(!p)  p = "(null)";\r
+                       //_SysDebug("vsnprintf: p = '%s'", p);\r
                        if(buf) {\r
                                while(*p) {\r
-                                       buf[pos++] = *p++;\r
+                                       if(pos < __maxlen)      buf[pos] = *p;\r
+                                       pos ++; p ++;\r
                                }\r
                        }\r
                        else {\r
@@ -407,12 +425,14 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                // Unknown, just treat it as a character\r
                default:\r
                        arg = va_arg(args, uint32_t);\r
-                       if(buf) buf[pos] = arg;\r
+                       if(buf && pos < __maxlen)       buf[pos] = arg;\r
                        pos ++;\r
                        break;\r
                }\r
     }\r
-       if(buf) buf[pos] = '\0';\r
+       if(buf && pos < __maxlen)       buf[pos] = '\0';\r
+       \r
+       //_SysDebug("vsnprintf: buf = '%s'", buf);\r
        \r
        return pos;\r
 }\r
@@ -422,13 +442,13 @@ const char cUCDIGITS[] = "0123456789ABCDEF";
  * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned)\r
  * \brief Convert an integer into a character string\r
  */\r
-EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned)\r
+EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned)\r
 {\r
-       char    tmpBuf[32];\r
+       char    tmpBuf[64];\r
         int    pos=0, i;\r
 \r
        if(!buf)        return;\r
-       if(base > 16) {\r
+       if(base > 16 || base < 2) {\r
                buf[0] = 0;\r
                return;\r
        }\r
@@ -441,13 +461,13 @@ EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int
                bSigned = 0;\r
        \r
        while(num > base-1) {\r
-               tmpBuf[pos] = cUCDIGITS[ num % base ];\r
-               num = (long) num / base;                // Shift {number} right 1 digit\r
-               pos++;\r
+               tmpBuf[pos++] = cUCDIGITS[ num % base ];\r
+               num = (uint64_t) num / (uint64_t)base;          // Shift {number} right 1 digit\r
        }\r
 \r
        tmpBuf[pos++] = cUCDIGITS[ num % base ];                // Last digit of {number}\r
        if(bSigned)     tmpBuf[pos++] = '-';    // Append sign symbol if needed\r
+       \r
        i = 0;\r
        minLength -= pos;\r
        while(minLength-- > 0)  buf[i++] = pad;\r
@@ -463,22 +483,29 @@ EXPORT int printf(const char *format, ...)
 {\r
        #if 1\r
         int    size;\r
-       char    *buf;\r
+       char    sbuf[1024];\r
+       char    *buf = sbuf;\r
        va_list args;\r
        \r
        // Get final size\r
        va_start(args, format);\r
-       size = vsprintf(NULL, (char*)format, args);\r
+       size = vsnprintf(sbuf, 1024, (char*)format, args);\r
        va_end(args);\r
        \r
-       // Allocate buffer\r
-       buf = (char*)malloc(size+1);\r
-       buf[size] = '\0';\r
+       if( size >= 1024 ) {\r
+               // Allocate buffer\r
+               buf = (char*)malloc(size+1);\r
+               if(buf) {\r
+                       write(_stdout, 29, "PRINTF ERROR: malloc() failed");\r
+                       return 0;\r
+               }\r
+               buf[size] = '\0';\r
        \r
-       // Fill Buffer\r
-       va_start(args, format);\r
-       vsprintf(buf, (char*)format, args);\r
-       va_end(args);\r
+               // Fill Buffer\r
+               va_start(args, format);\r
+               vsnprintf(buf, size+1, (char*)format, args);\r
+               va_end(args);\r
+       }\r
        \r
        // Send to stdout\r
        write(_stdout, size+1, buf);\r
index 499d24c..d049070 100644 (file)
@@ -4,6 +4,7 @@ heap.c - Heap Manager
 */\r
 #include <acess/sys.h>\r
 #include <stdlib.h>\r
+#include <string.h>\r
 #include "lib.h"\r
 \r
 // === Constants ===\r
@@ -14,7 +15,7 @@ heap.c - Heap Manager
 \r
 typedef unsigned int Uint;\r
 \r
-//Typedefs\r
+// === TYPES ===\r
 typedef struct {\r
        Uint    magic;\r
        Uint    size;\r
@@ -24,12 +25,13 @@ typedef struct {
        Uint    magic;\r
 }      heap_foot;\r
 \r
-//Globals\r
-void   *_heap_start = NULL;\r
-void   *_heap_end = NULL;\r
+// === LOCAL VARIABLES ===\r
+static void    *_heap_start = NULL;\r
+static void    *_heap_end = NULL;\r
 \r
-//Prototypes\r
-EXPORT void    *malloc(Uint bytes);\r
+// === PROTOTYPES ===\r
+EXPORT void    *malloc(size_t bytes);\r
+EXPORT void    *calloc(size_t bytes, size_t count);\r
 EXPORT void    free(void *mem);\r
 EXPORT void    *realloc(void *mem, Uint bytes);\r
 EXPORT void    *sbrk(int increment);\r
@@ -133,6 +135,20 @@ EXPORT void *malloc(size_t bytes)
        return (void*)(bestMatchAddr+sizeof(heap_head));\r
 }\r
 \r
+/**\r
+ * \fn EXPORT void *calloc(size_t bytes, size_t count)\r
+ * \brief Allocate and zero a block of memory\r
+ * \param __nmemb      Number of memeber elements\r
+ * \param __size       Size of one element\r
+ */\r
+EXPORT void *calloc(size_t __nmemb, size_t __size)\r
+{\r
+       void    *ret = malloc(__size*__nmemb);\r
+       if(!ret)        return NULL;\r
+       memset(ret, 0, __size*__nmemb);\r
+       return ret;\r
+}\r
+\r
 /**\r
  \fn EXPORT void free(void *mem)\r
  \brief Free previously allocated memory\r
index 9f629ba..d1ee56e 100644 (file)
@@ -3,13 +3,25 @@
  */\r
 #include "stdio_int.h"\r
 #include "lib.h"\r
+#include <stdio.h>\r
+#include <sys/sys.h>\r
 \r
 #define USE_CPUID      0\r
 \r
+// === TYPES ===\r
+typedef struct {\r
+       intptr_t        Base;\r
+       char    *Name;\r
+}      tLoadedLib;\r
+\r
 // === PROTOTYPES ===\r
 #if USE_CPUID\r
 static void    cpuid(uint32_t Num, uint32_t *EAX, uint32_t *EBX, uint32_t *EDX, uint32_t *ECX);\r
 #endif\r
+ int   ErrorHandler(int Fault);\r
+\r
+// === IMPORTS ===\r
+extern tLoadedLib      gLoadedLibraries[64];\r
 \r
 // === GLOBALS ===\r
 extern char **_envp;\r
@@ -53,9 +65,25 @@ int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp)
        }\r
        #endif\r
        \r
+       // Set Error handler\r
+       _SysSetFaultHandler(ErrorHandler);\r
+       \r
        return 1;\r
 }\r
 \r
+int ErrorHandler(int Fault)\r
+{\r
+        int    i;\r
+       fprintf(stderr, "ErrorHandler: (Fault = %i)\n", Fault);\r
+       fprintf(stderr, "Loaded Libraries:\n");\r
+       for( i = 0; i < 64; i ++ )\r
+       {\r
+               //if(gLoadedLibraries[i].Base == 0)     continue;\r
+       //      fprintf(stderr, "%02i: %p  %s\n", i, gLoadedLibraries[i].Base, gLoadedLibraries[i].Name);\r
+       }\r
+       fprintf(stderr, "\n");\r
+       return -1;\r
+}\r
 \r
 #if USE_CPUID\r
 /**\r
index 3b0f212..6e7fb08 100644 (file)
@@ -25,14 +25,58 @@ void __stack_chk_fail()
  */
 uint64_t __udivdi3(uint64_t Num, uint64_t Den)
 {
+       #if 0
        uint64_t        ret = 0;
        if(Den == 0)    // Call Div by Zero Error
                __asm__ __volatile__ ("int $0");
+       
+       if(Den == 1)    return Num;
+       if(Den == 2)    return Num >> 1;
+       if(Den == 4)    return Num >> 2;
+       if(Den == 8)    return Num >> 3;
+       if(Den == 16)   return Num >> 4;
+       if(Den == 32)   return Num >> 5;
+       if(Den == 64)   return Num >> 6;
+       if(Den == 128)  return Num >> 7;
+       if(Den == 256)  return Num >> 8;
+       
        while(Num > Den) {
                ret ++;
                Num -= Den;
        }
        return ret;
+       #else
+       uint64_t        P[64], q, n;
+        int    i;
+       
+       if(Den == 0)    __asm__ __volatile__ ("int $0x0");
+       // Common speedups
+       if(Den == 1)    return Num;
+       if(Den == 2)    return Num >> 1;
+       if(Den == 16)   return Num >> 4;
+       
+       
+       // Non-restoring division, from wikipedia
+       // http://en.wikipedia.org/wiki/Division_(digital)
+       P[0] = Num;
+       for( i = 0; i < 64; i ++ )
+       {
+               if( P[i] >= 0 ) {
+                       q |= (uint64_t)1 << (63-i);
+                       P[i+1] = 2*P[i] - Den;
+               }
+               else {
+                       //q |= 0 << (63-i);
+                       P[i+1] = 2*P[i] + Den;
+               }
+       }
+       
+       n = ~q;
+       n = -n;
+       q += n;
+       
+       return q;
+       #endif
 }
 
 /**
@@ -41,9 +85,28 @@ uint64_t __udivdi3(uint64_t Num, uint64_t Den)
  */
 uint64_t __umoddi3(uint64_t Num, uint64_t Den)
 {
-       if(Den == 0)    // Call Div by Zero Error
-               __asm__ __volatile__ ("int $0");
-       while(Num >= Den)
-               Num -= Den;
+       #if 0
+       if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
+       
+       if(Den == 1)    return 0;
+       if(Den == 2)    return Num & 0x01;
+       if(Den == 4)    return Num & 0x03;
+       if(Den == 8)    return Num & 0x07;
+       if(Den == 16)   return Num & 0x0F;
+       if(Den == 32)   return Num & 0x1F;
+       if(Den == 64)   return Num & 0x3F;
+       if(Den == 128)  return Num & 0x3F;
+       if(Den == 256)  return Num & 0x7F;
+       
+       while(Num >= Den)       Num -= Den;
+       
        return Num;
+       #else
+       if(Den == 0)    __asm__ __volatile__ ("int $0");        // Call Div by Zero Error
+       // Speedups for common operations
+       if(Den == 1)    return 0;
+       if(Den == 2)    return Num & 0x01;
+       if(Den == 16)   return Num & 0x0F;
+       return Num - __udivdi3(Num, Den) * Den;
+       #endif
 }
index c034b77..368524a 100644 (file)
@@ -1,10 +1,11 @@
 /*
  * Acess2 System Interface Header
  */
-#ifndef _SYS_SYS_H_
-#define _SYS_SYS_H_
+#ifndef _ACESS_SYS_H_
+#define _ACESS_SYS_H_
 
 #include <stdint.h>
+#include <sys/types.h>
 
 // === CONSTANTS ===
 #ifndef NULL
@@ -27,8 +28,6 @@
 #define FILEFLAG_SYMLINK       0x20
 
 // === TYPES ===
-typedef uint   pid_t;
-
 struct s_sysACL {
        union {
                struct {
@@ -62,7 +61,7 @@ typedef struct s_sysACL       t_sysACL;
 extern int     _errno;
 
 // === FUNCTIONS ===
-extern void    _SysDebug(char *str, ...);
+extern void    _SysDebug(const char *format, ...);
 // --- Proc ---
 extern void    _exit(int status)       __attribute__((noreturn));
 extern void    sleep();
@@ -73,6 +72,7 @@ extern int    clone(int flags, void *stack);
 extern int     execve(char *path, char **argv, char **envp);
 extern int     gettid();
 extern int     getpid();
+extern int     _SysSetFaultHandler(int (*Handler)(int));
 
 // --- Permissions ---
 extern int     getuid();
@@ -87,11 +87,12 @@ extern int  reopen(int fd, const char *path, int flags);
 extern void    close(int fd);
 extern uint    read(int fd, uint length, void *buffer);
 extern uint    write(int fd, uint length, void *buffer);
-extern int     seek(int fd, uint64_t offset, int whence);
+extern int     seek(int fd, int64_t offset, int whence);
 extern uint64_t        tell(int fd);
 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     _SysOpenChild(int fd, char *name, int flags);
 extern int     _SysGetACL(int fd, t_sysACL *dest);
 extern int     _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options);
 
index ee160b8..cacf1d8 100644 (file)
@@ -7,11 +7,14 @@
 #define _AXWIN_AXWIN_H
 
 // === Core Types ===
-typedef unsigned int   tAxWin_Handle;
+typedef void   *tAxWin_Handle;
 
 // === Messaging ===
 #include "messages.h"
 extern int     AxWin_MessageLoop();
+extern int     AxWin_SendMessage(tAxWin_Message *Message);
+extern tAxWin_Message  *AxWin_WaitForMessage(void);
+extern int     AxWin_HandleMessage(tAxWin_Message *Message);
 
 // === Window Control ===
 /**
@@ -30,7 +33,7 @@ typedef int   tAxWin_MessageCallback(tAxWin_Message *);
 /**
  * \}
  */
-extern tAxWin_Window   AxWin_CreateWindow(
+extern tAxWin_Window   *AxWin_CreateWindow(
                int16_t X, int16_t Y, int16_t W, int16_t H,
                uint32_t Flags, tAxWin_MessageCallback *Callback);
 
index b27583e..4d53ab5 100644 (file)
@@ -9,6 +9,13 @@
 #include <stdint.h>
 
 typedef struct sAxWin_Message  tAxWin_Message;
+typedef struct sAxWin_RetMsg   tAxWin_RetMsg;
+
+// Higherarchy:
+// - HANDLE
+//  + ELEMENT
+//   > DIALOG
+//   > TAB
 
 /**
  * \brief Message IDs
@@ -20,11 +27,11 @@ enum eAxWin_Messages
        // - Windows
        MSG_SREQ_REGISTER,      // bool (char[] Name) - Registers this PID with the Window Manager
        
-       MSG_SREQ_ADDTAB,        // ELEMENT (char[] Name) - Adds a tab to the window
+       MSG_SREQ_ADDTAB,        // TAB (char[] Name) - Adds a tab to the window
        MSG_SREQ_DELTAB,        // void (TAB Tab)       - Closes a tab
        
-       MSG_SREQ_NEWDIALOG,     // ELEMENT (ELEMENT Parent, char[] Name)        - Creates a dialog
-       MSG_SREQ_DELDIALOG,     // void (ELEMENT Dialog)        - Closes a dialog
+       MSG_SREQ_NEWDIALOG,     // DIALOG (TAB Parent, char[] Name)     - Creates a dialog
+       MSG_SREQ_DELDIALOG,     // void (DIALOG Dialog) - Closes a dialog
        
        MSG_SREQ_SETNAME,       // void (ELEMENT Element, char[] Name)
        MSG_SREQ_GETNAME,       // char[] (ELEMENT Element)
@@ -43,6 +50,7 @@ enum eAxWin_Messages
        MSG_SREQ_SETFONT,       MSG_SREQ_PUTTEXT,
        
        // Server Responses
+       MSG_SRSP_VERSION,
        MSG_SRSP_RETURN,        // {int RequestID, void[] Return Value} - Returns a value from a server request
        
        NUM_MSG
@@ -72,7 +80,7 @@ struct sAxWin_SReq_NewWindow
  * \brief Server Response - Pong
  * \see eAxWin_Messages.MSG_SRSP_PONG
  */
-struct sAxWin_SRsp_Pong
+struct sAxWin_SRsp_Version
 {
        uint8_t Major;
        uint8_t Minor;
@@ -98,14 +106,18 @@ struct sAxWin_Message
 {
        uint16_t        ID;
        uint16_t        Size;   //!< Size in DWORDS
+       char    Data[];
+};
+
+struct sAxWin_RetMsg
+{
+       uint16_t        ReqID;
+       uint16_t        Rsvd;
        union
        {
-               struct sAxWin_SReq_Ping SReq_Pong;
-               struct sAxWin_SReq_NewWindow    SReq_NewWindow;
-               
-               // Server Responses
-               struct sAxWin_SRsp_Pong SRsp_Pong;
-               struct sAxWin_SRsp_NewWindow    SRsp_Window;
+                uint8_t        Bool;
+               uint32_t        Handle;
+                int    Integer;
        };
 };
 
index 985f058..1223fe8 100644 (file)
@@ -16,6 +16,7 @@ typedef struct sFILE  FILE;
 \r
 // --- Standard IO ---\r
 extern int     printf(const char *format, ...);\r
+extern int     vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args);\r
 extern int     vsprintf(char *buf, const char *format, va_list args);\r
 extern int     sprintf(char *buf, const char *format, ...);\r
 \r
index 50cedb3..baf12c3 100644 (file)
@@ -19,7 +19,7 @@
 #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 void    _exit(int code) __attribute__((noreturn));      //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
@@ -29,8 +29,9 @@ extern char   *getenv(const char *name);
 \r
 // --- Heap ---\r
 extern void free(void *mem);\r
-extern void *malloc(unsigned int bytes);\r
-extern void *realloc(void *oldPos, unsigned int bytes);\r
+extern void *malloc(size_t bytes);\r
+extern void *calloc(size_t __nmemb, size_t __size);\r
+extern void *realloc(void *__ptr, size_t __size);\r
 extern int     IsHeap(void *ptr);\r
 \r
 #ifndef SEEK_CUR\r
diff --git a/Usermode/include/string.h b/Usermode/include/string.h
deleted file mode 100644 (file)
index 1e72197..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * AcessOS LibC
- * string.h
- */
-#ifndef __STRING_H
-#define __STRING_H
-
-#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
diff --git a/Usermode/include/strings.h b/Usermode/include/strings.h
new file mode 100644 (file)
index 0000000..1e72197
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * AcessOS LibC
+ * string.h
+ */
+#ifndef __STRING_H
+#define __STRING_H
+
+#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
index 7ddf583..d9e7ada 100644 (file)
@@ -1,6 +1,8 @@
 /*\r
  Syscall Definitions\r
 */\r
+#ifndef _SYS_SYS_H_\r
+#define _SYS_SYS_H_\r
 \r
 #include <sys/types.h>\r
 \r
@@ -25,7 +27,7 @@ extern int    close(int fp);
 extern int     read(int fp, int len, void *buf);\r
 extern int     write(int fp, int len, void *buf);\r
 extern int     tell(int fp);\r
-extern void seek(int fp, int dist, int flag);\r
+extern void seek(int fp, int64_t dist, int flag);\r
 extern int     fstat(int fp, t_fstat *st);\r
 extern int     ioctl(int fp, int call, void *arg);\r
 extern int     readdir(int fp, char *file);\r
@@ -36,3 +38,5 @@ extern int    getpid();       // Get Process ID
 extern int     sendmsg(int dest, unsigned int *Data);\r
 extern int     pollmsg(int *src, unsigned int *Data);\r
 extern int     getmsg(int *src, unsigned int *Data);\r
+\r
+#endif\r
index 03ee846..2fad39f 100644 (file)
@@ -1,6 +1,8 @@
-
+/*
+ */
 #ifndef _SYS_TYPES_H
 #define _SYS_TYPES_H
+#include <stdint.h>
 
 typedef struct {
        int             st_dev;         //dev_t
@@ -25,4 +27,9 @@ typedef struct {
 #define                S_IFSOCK        0140000 /* socket */
 #define                S_IFIFO 0010000 /* fifo */
 
+
+typedef uint32_t       pid_t;
+typedef uint32_t       tid_t;
+typedef  int64_t       time_t;
+
 #endif

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