From 589ce208181e956724334c50e13100e318a21811 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Sun, 2 Feb 2020 13:37:26 +0100 Subject: [PATCH] Shell : scroll, new keyboard layout, history --- include/io/cursor.h | 2 + include/io/keyb.h | 26 +++-- include/io/vga.h | 4 + include/ke/proc.h | 10 +- include/kernel.h | 2 +- include/lib/list.h | 30 ++++-- include/sh/shell.h | 2 - kaleid/kernel/init/init.c | 1 + kaleid/kernel/io/cursor.c | 9 ++ kaleid/kernel/io/keyb.c | 34 ++++-- kaleid/kernel/io/scan.c | 85 ++++++++++++--- kaleid/kernel/io/vga.c | 13 ++- kaleid/kernel/ps/sched.c | 112 +++++++++----------- kaleid/kernel/sh/shell.c | 204 ++++++++++++++++++++++++++++++------ kaleid/kernel/sh/testcmds.c | 9 ++ kaleid/libbuf/bgetc.c | 5 +- kaleid/libbuf/bputc.c | 27 +---- 17 files changed, 402 insertions(+), 173 deletions(-) diff --git a/include/io/cursor.h b/include/io/cursor.h index 5222910..72494b0 100644 --- a/include/io/cursor.h +++ b/include/io/cursor.h @@ -34,6 +34,8 @@ void IoEnableCursor(void); void IoDisableCursor(void); void IoUpdateCursor(int, int); +int IoGetCursorX(void); +int IoGetCursorY(void); //----------------------------------------------------------------------------// diff --git a/include/io/keyb.h b/include/io/keyb.h index 0ae4151..b5802f5 100644 --- a/include/io/keyb.h +++ b/include/io/keyb.h @@ -36,17 +36,25 @@ void IoChangeCodePage(char *); //----------------------------------------------------------------------------// -#define KEY_ESC 27 -#define KEY_BS 8 -#define KEY_BEL 7 +#define K_BACKSPACE 8 +#define K_BELL 7 -#define KEY_DC1 17 // Arrow Up -#define KEY_DC2 18 // Arrow Down -#define KEY_DC3 19 // Arrow Left -#define KEY_DC4 20 // Arrow Right +#define K_ARRW_UP 17 +#define K_ARRW_DOWN 18 +#define K_ARRW_LEFT 19 +#define K_ARRW_RIGHT 20 -#define KEY_DC5 17 // Page Up -#define KEY_DC6 18 // Page Down +#define K_PAGE_UP 21 +#define K_PAGE_DOWN 22 + +#define K_INSERT 23 + +#define K_HOME 24 +#define K_END 25 + +#define K_ESCAPE 27 + +#define K_DEL 127 //----------------------------------------------------------------------------// diff --git a/include/io/vga.h b/include/io/vga.h index 11d7c50..9736124 100644 --- a/include/io/vga.h +++ b/include/io/vga.h @@ -65,6 +65,10 @@ void IoScrollDown(void); void IoChangeTermColor(int, int); + +int IoGetCursorOffset(void); +void IoSetCursorOffset(int); + error_t IoInitVGABuffer(void); //----------------------------------------------------------------------------// diff --git a/include/ke/proc.h b/include/ke/proc.h index c10e4ac..e7b4364 100644 --- a/include/ke/proc.h +++ b/include/ke/proc.h @@ -26,6 +26,10 @@ #include #endif +#ifndef _LIB_LIST_H +#include +#endif + #ifndef _KALKERN_PROC_H #define _KALKERN_PROC_H @@ -44,6 +48,9 @@ enum ProcState_t // struct Process_t { + // Scheduler internals + ListNode_t schedNode; + // Identifier int pid; @@ -67,9 +74,6 @@ struct Process_t // Default time-slice ulong defTimeSlice; - - // Scheduler internals - ListNode_t *schedNode; }; //----------------------------------------------------------------------------// diff --git a/include/kernel.h b/include/kernel.h index d7aa537..8000b3d 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -211,7 +211,7 @@ noreturn void KeStartPanic(const char *, ...); while(_vga<(volatile ushort*)(0xB8000+(80*25*2))) \ *_vga++=(c|(0xf<<8)); \ asm volatile("cli\nhlt"); \ -}while(0) +}while(1) #define BUG() XBUG('B') #define BUGON(x) if(x)BUG() diff --git a/include/lib/list.h b/include/lib/list.h index 95042a4..dda6e77 100644 --- a/include/lib/list.h +++ b/include/lib/list.h @@ -57,8 +57,8 @@ struct ListNode_t // // Create a list head with an extern lock // -static inline ListHead_t -*ExCreateListHead(Lock_t *lock) +static inline +ListHead_t *ExCreateListHead() { ListHead_t *head = malloc(sizeof(ListHead_t)); @@ -70,11 +70,24 @@ static inline ListHead_t return head; } +static inline +ListNode_t *ExCreateNode() +{ + ListNode_t *node = malloc(sizeof(ListNode_t)); + + if (node == NULL) return NULL; + + node->prev = node->next = NULL; + node->head = NULL; + + return node; +} + // // Prepend node at beginning of list // -static inline ListHead_t -*ExPrependNode(ListHead_t *head, ListNode_t *node) +static inline +ListHead_t *ExPrependNode(ListHead_t *head, ListNode_t *node) { assert(head && node); @@ -101,8 +114,8 @@ static inline ListHead_t // // Append node at end of list // -static inline ListHead_t -*ExAppendNode(ListHead_t *head, ListNode_t *node) +static inline +ListHead_t *ExAppendNode(ListHead_t *head, ListNode_t *node) { assert(head && node); @@ -182,6 +195,9 @@ static inline ListHead_t static inline ListHead_t *ExRemoveNode(ListHead_t *head, ListNode_t *node) { + assert(head); + assert(node); + assert(head->length > 0); assert(head && node && head->length > 0 && node->head == head); if (head->length == 1) { @@ -221,6 +237,8 @@ ExDestroyListHead(ListHead_t *head) free(head); } +#define ExGetNodeData(list, type) ((type)list) + //------------------------------------------// #ifdef __cplusplus diff --git a/include/sh/shell.h b/include/sh/shell.h index 2766086..e9cd8b0 100644 --- a/include/sh/shell.h +++ b/include/sh/shell.h @@ -31,8 +31,6 @@ //----------------------------------------------------------------------------// -#define CMDBUFSIZE 256 - typedef struct Command_t Command_t; struct Command_t diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 09e3cbc..58d4935 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/kaleid/kernel/io/cursor.c b/kaleid/kernel/io/cursor.c index 24a8693..5095d36 100644 --- a/kaleid/kernel/io/cursor.c +++ b/kaleid/kernel/io/cursor.c @@ -25,6 +25,8 @@ #include #include +static int _curX = 0, _curY = 0; + void IoEnableCursor(void) { IoWriteByteOnPort(0x3D4, 0xA); @@ -42,6 +44,9 @@ void IoDisableCursor(void) void IoUpdateCursor(int x, int y) { + _curX = x; + _curY = y; + const ushort pos = y * BtVideoInfo.framebufferWidth + x; IoWriteByteOnPort(0x3D4, 0x0F); @@ -49,3 +54,7 @@ void IoUpdateCursor(int x, int y) IoWriteByteOnPort(0x3D4, 0x0E); IoWriteByteOnPort(0x3D5, ((pos >> 8) & 0xFF)); } + +int IoGetCursorX(void) { return _curX; } +int IoGetCursorY(void) { return _curY; } + diff --git a/kaleid/kernel/io/keyb.c b/kaleid/kernel/io/keyb.c index bdf9f0c..c66e8d8 100644 --- a/kaleid/kernel/io/keyb.c +++ b/kaleid/kernel/io/keyb.c @@ -32,7 +32,10 @@ #define FLAGS(code) (table[2*(code)+1]) static bool capsLockActive = 0; + +static bool e0received = 0; static bool altPressed = 0; +static bool altGrPressed = 0; static bool shiftPressed = 0; static bool controlPressed = 0; @@ -40,11 +43,18 @@ static void KeybPrint(uchar _code) { uint code = (uint)_code; - const uint *table = - (altPressed ? LeftAltScanCodes - : (controlPressed ? LeftControlScanCodes - : (shiftPressed ? LeftShiftScanCodes - : RegularScanCodes))); + const uint *table; + + if (!e0received) { + table = (altPressed ? LeftAltScanCodes + : (controlPressed ? LeftControlScanCodes + : (shiftPressed ? LeftShiftScanCodes + : (altGrPressed ? AltGrScanCodes + : RegularScanCodes)))); + } else { + table = E0ScanCodes; + e0received = 0; + } if ((capsLockActive && (FLAGS(code) & CAPSLOCK)) && !(altPressed || controlPressed)) { @@ -58,8 +68,14 @@ static void KeybPrint(uchar _code) if (!ch) { switch (code) { - case 0x38: altPressed = 1; break; - case 0xB8: altPressed = 0; break; + case 0xE0: e0received = 1; break; + + case 0x38: if (table == E0ScanCodes) altGrPressed = 1; + else altPressed = 1; + break; + case 0xB8: if (table == E0ScanCodes) altGrPressed = 0; + else altPressed = 0; + break; case 0x36: case 0x2A: shiftPressed = 1; break; case 0xB6: case 0xAA: shiftPressed = 0; break; @@ -73,10 +89,6 @@ static void KeybPrint(uchar _code) } bputc(BStdIn, ch); - if (code && (FLAGS(code) & INVISIBLE) == 0) { - bputc(BStdOut, table[2 * code]); - BStdOut->flusher(BStdOut); - } } static void KeybHandler(ISRFrame_t *regs) diff --git a/kaleid/kernel/io/scan.c b/kaleid/kernel/io/scan.c index 89d61a9..ed28c4d 100644 --- a/kaleid/kernel/io/scan.c +++ b/kaleid/kernel/io/scan.c @@ -22,8 +22,6 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// -#define WANT_AZERTY 1 - #define NONE 0 #define INVISIBLE 1 #define CAPSLOCK 2 @@ -35,7 +33,7 @@ const uint RegularScanCodes[2 * 256] = { ENTRY (0x00, 0, INVISIBLE|INVALID), - ENTRY (0x01, KEY_ESC, INVISIBLE), + ENTRY (0x01, K_ESCAPE, INVISIBLE), ENTRY (0x02, '&', NONE), ENTRY (0x03, 'e', NONE), @@ -49,7 +47,7 @@ const uint RegularScanCodes[2 * 256] = ENTRY (0x0B, 'a', NONE), ENTRY (0x0C, ')', NONE), ENTRY (0x0D, '=', NONE), - ENTRY (0x0E, KEY_BS, NONE), // Backspace + ENTRY (0x0E, '\b', NONE), ENTRY (0x0F, '\t', NONE), ENTRY (0x10, 'a', CAPSLOCK), @@ -96,17 +94,32 @@ const uint RegularScanCodes[2 * 256] = ENTRY (0x35, '!', CAPSLOCK), ENTRY (0x39, ' ', NONE), - - ENTRY (0x48, KEY_DC1, INVISIBLE), // UP arrow - ENTRY (0x4B, KEY_DC3, INVISIBLE), // LEFT arrow - ENTRY (0x4D, KEY_DC4, INVISIBLE), // RIGHT arrow - ENTRY (0x50, KEY_DC2, INVISIBLE), // DOWN arrow + + ENTRY (0x40, '\a', INVISIBLE), // F6 + + // Numpad keys + ENTRY (0x37, '*', NONE), + ENTRY (0x47, '7', NONE), + ENTRY (0x48, '8', NONE), + ENTRY (0x49, '9', NONE), + ENTRY (0x4A, '-', NONE), + ENTRY (0x4B, '4', NONE), + ENTRY (0x4C, '5', NONE), + ENTRY (0x4D, '6', NONE), + ENTRY (0x4E, '+', NONE), + ENTRY (0x4F, '1', NONE), + ENTRY (0x50, '2', NONE), + ENTRY (0x51, '3', NONE), + ENTRY (0x52, '0', NONE), + ENTRY (0x53, '.', NONE), + + ENTRY (0xE0, 0, INVISIBLE), }; const uint LeftShiftScanCodes[2 * 256] = { ENTRY (0x00, 0, INVISIBLE|INVALID), - ENTRY (0x01, KEY_ESC, INVISIBLE), + ENTRY (0x01, K_ESCAPE, INVISIBLE), ENTRY (0x02, '1', NONE), ENTRY (0x03, '2', NONE), @@ -120,7 +133,7 @@ const uint LeftShiftScanCodes[2 * 256] = ENTRY (0x0B, '0', NONE), ENTRY (0x0C, 'o', NONE), ENTRY (0x0D, '+', NONE), - ENTRY (0x0E, KEY_BS, NONE), // Backspace + ENTRY (0x0E, '\b', NONE), ENTRY (0x0F, '\t', NONE), ENTRY (0x10, 'A', CAPSLOCK), @@ -167,8 +180,54 @@ const uint LeftShiftScanCodes[2 * 256] = ENTRY (0x35, '!', NONE), ENTRY (0x39, ' ', NONE), + + // Numpad keys + ENTRY (0x47, K_HOME, INVISIBLE), + ENTRY (0x48, K_ARRW_UP, INVISIBLE), + ENTRY (0x49, K_PAGE_UP, INVISIBLE), + ENTRY (0x4B, K_ARRW_LEFT, INVISIBLE), + ENTRY (0x4D, K_ARRW_RIGHT, INVISIBLE), + ENTRY (0x4F, K_END, INVISIBLE), + ENTRY (0x50, K_ARRW_DOWN, INVISIBLE), + ENTRY (0x51, K_PAGE_DOWN, INVISIBLE), + ENTRY (0x52, K_INSERT, INVISIBLE), + ENTRY (0x53, K_DEL, INVISIBLE), + + ENTRY (0xE0, 0, INVISIBLE), }; -const uint LeftAltScanCodes[2 * 256]; -const uint LeftControlScanCodes[2 * 256]; +const uint AltGrScanCodes[2 * 256] = { + ENTRY (0x03, '~', NONE), + ENTRY (0x04, '#', NONE), + ENTRY (0x05, '{', NONE), + ENTRY (0x06, '[', NONE), + ENTRY (0x07, '|', NONE), + ENTRY (0x08, '`', NONE), + ENTRY (0x09, '\\', NONE), + ENTRY (0x0A, '^', NONE), + ENTRY (0x0B, '@', NONE), + ENTRY (0x0C, ']', NONE), + ENTRY (0x0D, '}', NONE), +}; + +const uint LeftAltScanCodes[2 * 256] = { 0 }; + +const uint LeftControlScanCodes[2 * 256] = { + ENTRY (0x2E, K_ESCAPE, INVISIBLE), // Ctrl+C +}; + +const uint E0ScanCodes[2 * 256] = { + ENTRY (0x1C, '\n', NONE), // Numpad Enter + ENTRY (0x35, '/', NONE), // Numpad Slash + ENTRY (0x47, K_HOME, INVISIBLE), // Home key + ENTRY (0x48, K_ARRW_UP, INVISIBLE), // Cursor UP + ENTRY (0x49, K_PAGE_UP, INVISIBLE), // Page UP + ENTRY (0x4B, K_ARRW_LEFT, INVISIBLE), // Cursor LEFT + ENTRY (0x4D, K_ARRW_RIGHT, INVISIBLE), // Cursor RIGHT + ENTRY (0x4F, K_END, INVISIBLE), // End key + ENTRY (0x50, K_ARRW_DOWN, INVISIBLE), // Cursor DOWN + ENTRY (0x51, K_PAGE_DOWN, INVISIBLE), // Page DOWN + ENTRY (0x52, K_INSERT, INVISIBLE), // Insert mode + ENTRY (0x53, K_DEL, INVISIBLE), // Delete key +}; diff --git a/kaleid/kernel/io/vga.c b/kaleid/kernel/io/vga.c index 80d6842..ff3c9fe 100644 --- a/kaleid/kernel/io/vga.c +++ b/kaleid/kernel/io/vga.c @@ -46,6 +46,8 @@ static uint bscroll = 0; static int bfg = VGA_COLOR_LIGHT_GREY; static int bbg = VGA_COLOR_BLACK; +static int cursorOffset = 0; + // // VGA Buffer Flusher // @@ -86,11 +88,12 @@ error_t bvgaflusher(Buffer_t *buf) } } } + // Update the cursor size_t curX = ((size_t)ptr - (size_t)bufStart - cols) % buf->lineLen; size_t curY = ((size_t)ptr - (size_t)bufStart) / buf->lineLen; - IoUpdateCursor(curX, curY); + IoUpdateCursor(max(min(curX + cursorOffset, buf->lineLen), 0), curY); // Empty the rest of the buffer @@ -108,6 +111,14 @@ error_t bvgaflusher(Buffer_t *buf) return EOK; } +int IoGetCursorOffset(void) { + return cursorOffset; +} + +void IoSetCursorOffset(int ins) { + cursorOffset = ins; +} + uint IoGetScroll(void) { return bscroll; diff --git a/kaleid/kernel/ps/sched.c b/kaleid/kernel/ps/sched.c index b6d3957..e157e0a 100644 --- a/kaleid/kernel/ps/sched.c +++ b/kaleid/kernel/ps/sched.c @@ -27,25 +27,21 @@ #include #include -// XXX not ready - -#if 0 - // // For test purpose only // int procslen = 10; Process_t procs[] = { - { 0, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 1, 2, 2, 16, 16, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 2, 3, 3, 31, 31, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 3, 2, 2, 1, 1, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 4, 3, 3, 5, 5, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 5, 0, 0, 30, 30, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 6, 1, 1, 19, 19, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 7, 1, 1, 0, 0, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 8, 3, 3, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, - { 9, 2, 2, 21, 21, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, + { {0}, 0, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 1, 2, 2, 16, 16, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 2, 3, 3, 31, 31, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 3, 2, 2, 1, 1, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 4, 3, 3, 5, 5, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 5, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 6, 1, 1, 19, 19, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 7, 1, 1, 0, 0, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 8, 3, 3, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, + { {0}, 9, 2, 2, 21, 21, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE }, }; //------------------------------------------// @@ -65,8 +61,8 @@ Process_t procs[] = { // static void SetCurProc(Process_t *proc) { - PsCurProc = proc; - if (PsCurProc) PsCurProc->procState = STATE_RUNNING; + KeCurProc = proc; + if (KeCurProc) KeCurProc->procState = STATE_RUNNING; } // @@ -80,7 +76,7 @@ void PsLockSched(void) { static inline void PsUnlockSched(void) { - //KeEnableIRQs(); + KeEnableIRQs(); } // @@ -104,7 +100,7 @@ static ListHead_t *GetPrioClassHead(int prioClass) case SERV_PRIO_PROC: return ServPrioProcs; case REGL_PRIO_PROC: return ReglPrioProcs; case IDLE_PRIO_PROC: return IdlePrioProcs; - default: KalAssert(FALSE && "Unknown priority class"); + default: assert(!"Unknown priority class"); } return NULL; @@ -116,7 +112,7 @@ static ListHead_t *GetPrioClassHead(int prioClass) // static Process_t *CompareProcs(Process_t *proc1, Process_t *proc2) { - KalAssert(proc1 && proc2); + assert(proc1 && proc2); if (proc1->prioClass < proc2->prioClass) return proc1; if (proc1->prioClass > proc2->prioClass) return proc2; @@ -132,26 +128,21 @@ static Process_t *CompareProcs(Process_t *proc1, Process_t *proc2) // static void SchedThisProcUnlocked(Process_t *proc) { - KalAssert(proc && proc->procState == STATE_RUNNABLE && !proc->schedNode); + assert(proc && proc->procState == STATE_RUNNABLE); bool found = 0; ListNode_t *iterNode = NULL; - ListNode_t *procNode = ExCreateNode(proc); ListHead_t *head = GetPrioClassHead(proc->prioClass); - - KalAssert(head); - KalAssert(procNode); - - proc->schedNode = procNode; + assert(head); // Find a process with lesser priority for (iterNode = head->first; iterNode; iterNode = iterNode->next) { if (proc->prioLevel > ExGetNodeData(iterNode, Process_t *)->prioLevel) { // Detect double insertions - KalAssert(proc->pid != ExGetNodeData(iterNode, Process_t *)->pid); + assert(proc->pid != ExGetNodeData(iterNode, Process_t *)->pid); // Add process to schedule - ExAddNodeBefore(head, iterNode, procNode); + ExAddNodeBefore(head, iterNode, &proc->schedNode); found = true; break; } @@ -159,7 +150,7 @@ static void SchedThisProcUnlocked(Process_t *proc) // Didn't find any process with lesser priority if (found == false) { - ExAppendNode(head, procNode); + ExAppendNode(head, &proc->schedNode); } } @@ -201,36 +192,29 @@ static Process_t *SelectSchedNext(void) // void PsBlockCurProc(void) { - KalAssert(PsCurProc && PsCurProc->procState == STATE_RUNNING); + assert(KeCurProc && KeCurProc->procState == STATE_RUNNING); - ListNode_t *procNode = PsCurProc->schedNode; + KeCurProc->procState = STATE_BLOCKED; + ExRemoveNode(KeCurProc->schedNode.head, &KeCurProc->schedNode); - KalAssert(procNode && "Blocking non-scheduled process"); - - PsCurProc->procState = STATE_BLOCKED; - ExRemoveNode(procNode->head, procNode); - - PsCurProc->schedNode = NULL; SetCurProc(SelectSchedNext()); } static void ReSchedCurProc(void) { - KalAssert(PsCurProc && PsCurProc->procState == STATE_RUNNING); - KalAssert(PsCurProc->schedNode); + assert(KeCurProc && KeCurProc->procState == STATE_RUNNING); // Restore default attributes, cancelling boosts - PsCurProc->prioClass = PsCurProc->defPrioClass; - PsCurProc->prioLevel = PsCurProc->defPrioLevel; - PsCurProc->timeSlice = PsCurProc->defTimeSlice; - PsCurProc->procState = STATE_RUNNABLE; + KeCurProc->prioClass = KeCurProc->defPrioClass; + KeCurProc->prioLevel = KeCurProc->defPrioLevel; + KeCurProc->timeSlice = KeCurProc->defTimeSlice; + KeCurProc->procState = STATE_RUNNABLE; // Remove from list - ExRemoveNode(PsCurProc->schedNode->head, PsCurProc->schedNode); - PsCurProc->schedNode = NULL; + ExRemoveNode(KeCurProc->schedNode.head, &KeCurProc->schedNode); // Schedule again, with default attributes now - SchedThisProcUnlocked(PsCurProc); + SchedThisProcUnlocked(KeCurProc); } // @@ -241,30 +225,30 @@ void PsSchedOnTick(void) { PsLockSched(); - Process_t *procNext, *winner, *previous = PsCurProc; + Process_t *procNext, *winner, *previous = KeCurProc; // We're either idle or running something - KalAssert(PsCurProc == NULL || PsCurProc->procState == STATE_RUNNING); + assert(KeCurProc == NULL || KeCurProc->procState == STATE_RUNNING); - // Have the current process spent its timeslice? + // Has the current process spent its timeslice? // (To be handled in CPU decisions function) - if (PsCurProc != NULL) { - if (PsCurProc->timeSlice <= 1) { + if (KeCurProc != NULL) { + if (KeCurProc->timeSlice <= 1) { // Re-schedule ReSchedCurProc(); // See next 'if' statement - PsCurProc = NULL; + KeCurProc = NULL; } // Otherwise, make it lose a tick else { - PsCurProc->timeSlice--; + KeCurProc->timeSlice--; } } // Are we idle, or scheduling next process? - if (PsCurProc == NULL) { + if (KeCurProc == NULL) { SetCurProc(SelectSchedNext()); goto leave; } @@ -274,7 +258,7 @@ void PsSchedOnTick(void) // Is there a higher priority process that is runnable? procNext = SelectSchedNext(); - winner = CompareProcs(PsCurProc, procNext); + winner = CompareProcs(KeCurProc, procNext); // Yes, procNext should preempt current process if (winner == procNext) { @@ -290,7 +274,7 @@ void PsSchedOnTick(void) leave: PsUnlockSched(); - if (PsCurProc != NULL && PsCurProc != previous) { + if (KeCurProc != NULL && KeCurProc != previous) { // dispatch & context switch } } @@ -309,7 +293,7 @@ void PsInitSched(void) ReglPrioProcs = ExCreateListHead(); IdlePrioProcs = ExCreateListHead(); - KalAssert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs); + assert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs); for (pid = 0; pid < procslen; pid++) { if (procs[pid].procState == STATE_RUNNABLE) { @@ -325,7 +309,7 @@ void PsInitSched(void) // void PsFiniSched(void) { - KalAssert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs); + assert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs); PsLockSched(); @@ -356,12 +340,12 @@ void PsFiniSched(void) // void PrintList(ListHead_t *head) { - KalAssert(head); + assert(head); Process_t *proc; ListNode_t *node = head->first; - KernLog("len: %lu\n", head->length); + KernLog("len %lu\n", head->length); while (node) { proc = ExGetNodeData(node, Process_t *); @@ -394,7 +378,7 @@ void pstest(void) while (tick < 100) { //if (tick%25==0)ClearTerm(StdOut); - if (tick > 0 && tick != 50 && tick % 10 == 0 && PsCurProc) { + if (tick > 0 && tick != 50 && tick % 10 == 0 && KeCurProc) { KernLog("Blocking current process\n"); PsBlockCurProc(); } @@ -406,12 +390,12 @@ void pstest(void) KernLog("Tick %d - Running: ", tick); - if (PsCurProc == NULL) { + if (KeCurProc == NULL) { KernLog("IDLE\n"); } else { - PrintProc(PsCurProc); + PrintProc(KeCurProc); } PsSchedOnTick(); @@ -423,5 +407,3 @@ void pstest(void) } } -#endif - diff --git a/kaleid/kernel/sh/shell.c b/kaleid/kernel/sh/shell.c index a22685f..6ad2fd8 100644 --- a/kaleid/kernel/sh/shell.c +++ b/kaleid/kernel/sh/shell.c @@ -29,6 +29,7 @@ #include #include #include +#include int shargc = 0; char **shargv = 0; @@ -65,13 +66,27 @@ void ExecuteCommand(char *cmdbuf, Command_t *cmdtable) } } +#define CMDBUFSIZE (BStdOut->lineLen - 9) // strlen("%Cshell> %C" = 9 + void ShStartShell(void) { uchar ch; error_t rc; - + char *ptr; // temp + + // Current line - beginning & current pos char *cmdbuf = malloc(CMDBUFSIZE); char *bufptr = cmdbuf; + char *bufend = cmdbuf; + + // History... + // We use a basic N-entries command history +#define N 10 // must be >1 + char *history = malloc(CMDBUFSIZE * N); + int historyIndex = 0; + int historyScroll = 0; + + bool insertMode = 0; argvbuf = malloc(ARG_MAX * 2); memzero(argvbuf, ARG_MAX * 2); @@ -98,57 +113,179 @@ void ShStartShell(void) switch (ch) { - case KEY_BS: - *bufptr = 0; - if (bufptr > cmdbuf) { - bufptr--; - } - break; + // Backspace character + case K_BACKSPACE: + if (bufptr == cmdbuf) + break; - case KEY_BEL: - if (rand() % 16 == 0) { - IoDoStarWars(); - } - else IoDoBeep(); - break; + memmove(bufptr-1, bufptr, bufend-bufptr+1); + bufptr--; + bufend--; + goto print_current_line; - case KEY_DC1: - IoScrollUp(); - break; + // DEL character + case K_DEL: + if (bufptr == bufend) + break; - case KEY_DC2: - IoScrollDown(); - break; + memmove(bufptr, bufptr+1, bufend-bufptr+1); + IoSetCursorOffset(IoGetCursorOffset()+1); + bufend--; + goto print_current_line; - case KEY_ESC: - PoShutdown(); + case K_BELL: IoDoBeep(); break; + case K_ESCAPE: PoShutdown(); break; + case K_PAGE_UP: IoScrollUp(); break; + case K_PAGE_DOWN: IoScrollDown(); break; + + case K_INSERT: + insertMode = 1 - insertMode; + break; + + // Move within buffer + case K_ARRW_LEFT: + if (!(bufptr > cmdbuf)) + break; + + bufptr--; + + IoSetCursorOffset(IoGetCursorOffset()-1); + BFlushBuf(BStdOut); + break; + + case K_ARRW_RIGHT: + if (bufptr == bufend) + break; + + bufptr++; + IoSetCursorOffset(IoGetCursorOffset()+1); + BFlushBuf(BStdOut); + break; + + case K_HOME: + if (bufptr == cmdbuf) + break; + + IoSetCursorOffset(IoGetCursorOffset()-(int)(bufptr-cmdbuf)); + bufptr = cmdbuf; + BFlushBuf(BStdOut); break; - default: - IoSetScroll(1); - IoScrollDown(); + case K_END: + if (bufptr == bufend) + break; - *bufptr++ = (char)ch; + IoSetCursorOffset(IoGetCursorOffset()+(int)(bufend-bufptr)); + bufptr = bufend; + BFlushBuf(BStdOut); + break; + + // Handle history scroll up/down + case K_ARRW_UP: + case K_ARRW_DOWN: + if (historyIndex == 0) + break; // No history yet + + if (ch == K_ARRW_UP) { + memmove(cmdbuf, &history[historyScroll*CMDBUFSIZE], CMDBUFSIZE); + if (historyScroll > 0) + historyScroll--; + } + + else if (historyScroll < historyIndex-1) { + historyScroll++; + memmove(cmdbuf, &history[historyScroll*CMDBUFSIZE], CMDBUFSIZE); + } + + else + break; + + for (bufend = cmdbuf; *bufend && bufend < cmdbuf+CMDBUFSIZE; bufend++); + bufptr = bufend; + + IoSetCursorOffset(0); + goto print_current_line; + + // Regular character + default: + if (bufptr >= bufend) { + *bufptr++ = (char)ch; + + bufend = bufptr; + *bufptr = 0; + + // Advance cursor + if (IoGetCursorOffset() < 0) + IoSetCursorOffset(IoGetCursorOffset() + 1); + } + + else { + if (!insertMode) { + *++bufend = 0; + for (ptr = bufend-1; ptr != bufptr; ptr--) + *ptr = *(ptr - 1); + } + + else { // insertMode + // Advance cursor + if (IoGetCursorOffset() < 0) + IoSetCursorOffset(IoGetCursorOffset() + 1); + } + + *bufptr++ = (char)ch; + } + + print_current_line: + + BLockBuf(BStdOut); + + BStdOut->wp -= BStdOut->lastLF; + BStdOut->size -= BStdOut->lastLF; + BStdOut->lastLF = 0; + bprintf(BStdOut, "%Cshell> %C%s", VGA_COLOR_WHITE, shcol, cmdbuf); + + BUnlockBuf(BStdOut); + + IoSetScroll(1); + IoScrollDown(); // This calls the flusher // End of buffer? - if (bufptr != cmdbuf+CMDBUFSIZE-1) { + if (bufend != cmdbuf+CMDBUFSIZE-1) { break; // No } - KernLog("\n"); - // Else, fallthrough to case '\n' + // Else, *FALLTHROUGH* to case '\n' case '\n': - + BPutOnBuf(BStdOut, '\n'); + while (IoGetScroll() > 0) { IoScrollDown(); } - *bufptr = 0; - bufptr = cmdbuf; - ExecuteCommand(cmdbuf, shcmdtable); + IoSetCursorOffset(0); + + bufptr = cmdbuf; // Reset bufptr + bufend = cmdbuf; + + if (cmdbuf[0] && !isspace(cmdbuf[0])) { + // Forget old commands + if (historyIndex >= N) { + assert(historyIndex == N); + memmove(history, history+CMDBUFSIZE, CMDBUFSIZE * (N-1)); + historyIndex = historyScroll = N-1; + + } + // Update history + memmove(&history[historyIndex*CMDBUFSIZE], cmdbuf, CMDBUFSIZE); + historyScroll = historyIndex; + historyIndex++; + + // Execute & reset + ExecuteCommand(cmdbuf, shcmdtable); + memzero(cmdbuf, CMDBUFSIZE); + } - memzero(cmdbuf, CMDBUFSIZE); KernLog("%Cshell> %C", VGA_COLOR_WHITE, shcol); BFlushBuf(BStdIn); BFlushBuf(BStdOut); @@ -157,5 +294,4 @@ void ShStartShell(void) KePauseCPU(); } - KernLog("[EOI]\n"); } diff --git a/kaleid/kernel/sh/testcmds.c b/kaleid/kernel/sh/testcmds.c index 2e2309b..1f7c376 100644 --- a/kaleid/kernel/sh/testcmds.c +++ b/kaleid/kernel/sh/testcmds.c @@ -303,6 +303,14 @@ error_t CmdPF(int argc, char **argv, char *cmdline) return EOK; } +extern void pstest(void); + +error_t CmdPS(int argc, char **argv, char *cmdline) +{ + pstest(); + return EOK; +} + error_t CmdShell(int argc, char **argv, char *cmdline) { ShStartShell(); @@ -358,6 +366,7 @@ static Command_t testcmdtable[] = "with z flags"}, { "pfree", CmdPageFree, "Free a page block of id x" }, { "pf", CmdPF, "Provoke a PF. Usage: pfault
"}, + { "ps", CmdPS, "Scheduler algorithm test" }, { "shell", CmdShell, "Start a new shell (nested)", }, { "stkov", CmdStackOverflow, "Provoke a stack overflow" }, { "stkun", CmdStackUnderflow, "Provoke a stack underflow" }, diff --git a/kaleid/libbuf/bgetc.c b/kaleid/libbuf/bgetc.c index 2bd60da..f0f6d0f 100644 --- a/kaleid/libbuf/bgetc.c +++ b/kaleid/libbuf/bgetc.c @@ -43,9 +43,6 @@ error_t BGetFromBuf(Buffer_t *buf, uchar *ch) ExReleaseLock(&buf->lock); return rc; } - -// XXX for now, at most 4096 characters can be inputed in BStdIn - error_t bgetc(Buffer_t *buf, uchar *ch) { error_t rc = EOK; @@ -72,7 +69,7 @@ error_t bgetc(Buffer_t *buf, uchar *ch) // (so that BStdIn works; don't make anything else) while (buf->rp >= buf->wp) { #ifdef _KALEID_KERNEL - KeSleep(1); + KeSleep(1); // XXX synchronization with keyboard driver #endif } diff --git a/kaleid/libbuf/bputc.c b/kaleid/libbuf/bputc.c index d2d4ee1..fe14e35 100644 --- a/kaleid/libbuf/bputc.c +++ b/kaleid/libbuf/bputc.c @@ -25,6 +25,8 @@ #include #include +#include + // // Writes a character on a buffer // @@ -78,10 +80,6 @@ error_t bputc(Buffer_t *buf, uchar ch) if (buf->flusher) buf->flusher(buf); } - else if (ch == '\a') { - IoDoBeep(); - } - // Deal with carriage returns else if (ch == '\r') { buf->wp -= buf->lastLF; @@ -89,7 +87,7 @@ error_t bputc(Buffer_t *buf, uchar ch) assert(buf->wp >= buf->buf); } - // Deal with tabs... we need a tabSize field + // Deal with tabs... should be dealt with elsewhere tho // We assume tabs are 4 characters long for now else if (ch == '\t') { rc = bputc(buf, ' '); @@ -98,25 +96,6 @@ error_t bputc(Buffer_t *buf, uchar ch) rc = bputc(buf, ' '); } } - - // Backspace - else if (ch == 8) { - if (buf->wp > buf->buf && buf->lastLF > 0) { - buf->wp--; - buf->lastLF--; - rc = bputc(buf, ' '); - if (!rc) { - buf->wp--; - buf->lastLF--; - } - } - } - - // DEL character, XXX lastLF - else if (ch == 127) { - rc = bputc(buf, ' '); - if (!rc) buf->wp--; - } // Just a regular character else {