<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -108,12 +108,18 @@ void Tasks::saveRegisterToTask(Task *dest, void *regs) {
 	// internal consistency.
 	ASSERT(((((struct modeswitch_registers *)regs)-&gt;callback.cs - 0x08) / 0x11) == dest-&gt;cpl);
 
-	if (!dest-&gt;cpl &gt; 0) {
+	if (dest-&gt;cpl == 0) {
 		// update the tip of stack pointer so we can restore later
+		// Akari-&gt;console-&gt;putString(&quot;ks saved as 0x&quot;);
+		// Akari-&gt;console-&gt;putInt((u32)regs, 16);
+		// Akari-&gt;console-&gt;putString(&quot;\n&quot;);
 		dest-&gt;ks = (u32)regs;
 	} else {
 		// update utks pointer
 		dest-&gt;utks = (u32)regs;
+		// Akari-&gt;console-&gt;putString(&quot;utks saved as 0x&quot;);
+		// Akari-&gt;console-&gt;putInt((u32)regs, 16);
+		// Akari-&gt;console-&gt;putString(&quot;\n&quot;);
 	}
 }
 
@@ -152,7 +158,7 @@ void *Tasks::assignInternalTask(Task *task) {
 		task-&gt;userCall = 0;
 	}
 
-	return (void *)((!task-&gt;cpl &gt; 0) ? task-&gt;ks : task-&gt;utks);
+	return (void *)((task-&gt;cpl == 0) ? task-&gt;ks : task-&gt;utks);
 }
 
 Tasks::Task *Tasks::Task::BootstrapInitialTask(u8 cpl, Memory::PageDirectory *pageDirBase) {
@@ -177,17 +183,37 @@ Tasks::Task *Tasks::Task::BootstrapInitialTask(u8 cpl, Memory::PageDirectory *pa
 
 Tasks::Task *Tasks::Task::CreateTask(u32 entry, u8 cpl, bool interruptFlag, u8 iopl, Memory::PageDirectory *pageDirBase) {
 	Task *nt = new Task(cpl);
-	nt-&gt;ks = (u32)Akari-&gt;memory-&gt;allocAligned(USER_TASK_STACK_SIZE) + USER_TASK_STACK_SIZE;
+
+	nt-&gt;pageDir = pageDirBase-&gt;clone();
 
 	struct modeswitch_registers *regs = 0;
 
 	if (cpl &gt; 0) {
+		// Allocate the user's stack to top out at USER_TASK_BASE (i.e. it goes below that).
+		// We need to do the frame allocs ourselves so they're visible and writable by the user.
+		// We also save nt-&gt;ks as the top of the first frame (physically).
+		for (u32 i = 0, page = USER_TASK_BASE - 0x1000; i &lt; USER_TASK_STACK_SIZE; i += 0x1000, page -= 0x1000) {
+			Memory::Page *ksp = nt-&gt;pageDir-&gt;getPage(page, true);
+			ksp-&gt;allocAnyFrame(false, true);
+			/**
+			 * This appears to be completely unneeded.
+			if (i == 0) {
+				nt-&gt;ks = ksp-&gt;pageAddress * 0x1000 + 0x1000;
+			}
+			*/
+		}
+
+		Akari-&gt;console-&gt;putString(&quot;alloced nt-&gt;ks at 0x&quot;);
+		Akari-&gt;console-&gt;putInt(nt-&gt;ks, 16);
+		Akari-&gt;console-&gt;putString(&quot;\n&quot;);
+
 		nt-&gt;utks = (u32)Akari-&gt;memory-&gt;allocAligned(USER_TASK_KERNEL_STACK_SIZE) + USER_TASK_KERNEL_STACK_SIZE - sizeof(struct modeswitch_registers);
 		regs = (struct modeswitch_registers *)(nt-&gt;utks);
 
-		regs-&gt;useresp = nt-&gt;ks;
+		regs-&gt;useresp = USER_TASK_BASE;
 		regs-&gt;ss = 0x10 + (cpl * 0x11);		// same as ds: ss is set by TSS, ds is manually set by irq_timer_multitask after
 	} else {
+		nt-&gt;ks = (u32)Akari-&gt;memory-&gt;allocAligned(USER_TASK_STACK_SIZE) + USER_TASK_STACK_SIZE;
 		nt-&gt;ks -= sizeof(struct callback_registers);
 		regs = (struct modeswitch_registers *)(nt-&gt;ks);
 	}
@@ -202,8 +228,6 @@ Tasks::Task *Tasks::Task::CreateTask(u32 entry, u8 cpl, bool interruptFlag, u8 i
 	regs-&gt;callback.eip = entry;
 	regs-&gt;callback.cs = 0x08 + (cpl * 0x11);			// note the low 2 bits are the CPL
 	regs-&gt;callback.eflags = (interruptFlag ? 0x200 : 0x0) | (iopl &lt;&lt; 12);
-
-	nt-&gt;pageDir = pageDirBase-&gt;clone();
 	
 #define _PROCESS_HEAP_START	0x0500000
 #define _PROCESS_HEAP_SIZE	0x500000		// 5MiB</diff>
      <filename>Tasks.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -64,7 +64,7 @@ void KeyboardProcess() {
 	// 128-bit=16 bytes bitfield
 	u8 held_scancodes[16];     
 
-	bool echo_mode = true;
+	bool echo_mode = false;
 	bool capslock_down = false, numlock_down = false, scrolllock_down = false;
 	bool pressed_ctrl = false, pressed_alt = false, pressed_shift = false;
 </diff>
      <filename>TmpKb.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,12 +1,11 @@
 #include &lt;UserGates.hpp&gt;
 
-static u32 stdin;
-static char *getline() {
+static char *getline(u32 in) {
 	u32 cs = 8, n = 0;
 	char *kbbuf = (char *)syscall_malloc(cs);
 
 	while (true) {
-		u32 incoming = syscall_readNode(&quot;system.io.keyboard&quot;, &quot;input&quot;, stdin, kbbuf + n, 1);
+		u32 incoming = syscall_readNode(&quot;system.io.keyboard&quot;, &quot;input&quot;, in, kbbuf + n, 1);
 		syscall_putc(kbbuf[n]);
 		if (kbbuf[n] == '\n') break;
 
@@ -27,7 +26,7 @@ static char *getline() {
 
 
 void ShellProcess() {
-	stdin = (u32)-1;
+	u32 stdin = (u32)-1;
 	while (stdin == (u32)-1) {
 		stdin = syscall_obtainNodeListener(&quot;system.io.keyboard&quot;, &quot;input&quot;);
 	}
@@ -37,7 +36,7 @@ void ShellProcess() {
 	syscall_puts(&quot;.\n&quot;);
 
 	while (true) {
-		char *l = getline();
+		char *l = getline(stdin);
 		syscall_puts(&quot;got line (0x&quot;);
 		syscall_putl((u32)l, 16);
 		syscall_puts(&quot;): &quot;);</diff>
      <filename>TmpShell.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -79,7 +79,7 @@ static void AkariEntryCont() {
 
 	// Shell
 	Tasks::Task *shell = Tasks::Task::CreateTask((u32)&amp;ShellProcess, 3, true, 0, Akari-&gt;memory-&gt;_kernelDirectory);
-	// kbdriver-&gt;next = shell;
+	kbdriver-&gt;next = shell;
 	
 	// Now we need our own directory! BootstrapTask should've been nice enough to make us one anyway.
 	Akari-&gt;memory-&gt;switchPageDirectory(base-&gt;pageDir);</diff>
      <filename>entry.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -13,7 +13,9 @@
 // user task kernel stack is used for state when it's
 // pre-empted, and for system calls, etc.
 #define USER_TASK_KERNEL_STACK_SIZE	0x2000
-#define USER_TASK_STACK_SIZE	0x4000
+#define USER_TASK_STACK_SIZE		0x4000
+
+#define USER_TASK_BASE				0x50000000
 
 class Tasks : public Subsystem {
 public:</diff>
      <filename>inc/Tasks.hpp</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>11719f787287dfdbc5d92e809197e637dfc676e1</id>
    </parent>
  </parents>
  <author>
    <name>Arlen Cuss</name>
    <email>celtic@sairyx.org</email>
  </author>
  <url>http://github.com/celtic/akari/commit/52bbd2396e3dd09c295bcb39878e1a6c27b04c22</url>
  <id>52bbd2396e3dd09c295bcb39878e1a6c27b04c22</id>
  <committed-date>2009-10-10T20:28:37-07:00</committed-date>
  <authored-date>2009-10-10T20:28:37-07:00</authored-date>
  <message>We have a defined user stack now, which is important. Starting to resolve some confusing/ambiguous lines (like &quot;!a &gt; 0&quot;), and realising that the ks/utks distinction may be completely gone/pointless now.</message>
  <tree>bf67d0fd57eff0353501f4653434a6f2aa90aee5</tree>
  <committer>
    <name>Arlen Cuss</name>
    <email>celtic@sairyx.org</email>
  </committer>
</commit>
