Solution 2

These are in diff format. Lines starting with a + are added to the code, and lines starting with - are removed. The @@ lines give cues about the line numbers, and context lines (neither + nor -) help you place the changes too.

Clear screen

-------------------- a2/src/geekos/screen.c --------------------
@@ -34,6 +34,11 @@
 void Clear_Screen(void)
 {
   // TODO
+  int i;
+  for(i = 0; i <= NUMROWS * NUMCOLS; i++) {
+    VIDMEM[i*2] = ' ';
+    VIDMEM[i*2+1] = DEFAULT_ATTRIBUTE;
+  }
 }

Write one char

-------------------- a2/src/geekos/screen.c --------------------
@@ -49,8 +49,14 @@
 static void Write_One_Char(int c)
 {
   // TODO
-  VIDMEM[0] = (uchar_t) c;
-  VIDMEM[1] = s_cons.currentAttr;
+  int offset = s_cons.row*NUMCOLS*2 + s_cons.col*2;
+  VIDMEM[offset] = (uchar_t) c;
+  VIDMEM[offset+1] = s_cons.currentAttr;
+  s_cons.col++;
+  if(s_cons.col >= NUMCOLS) {
+    s_cons.row++;
+    s_cons.col = 0;
+  }
 }

New line

-------------------- a2/src/geekos/screen.c --------------------
@@ -49,6 +49,11 @@
 static void Write_One_Char(int c)
 {
   // TODO
+  if(c == '\n' || c == '\r') {
+    s_cons.row++;
+    s_cons.col = 0;
+    return;
+  }
   int offset = s_cons.row*160 + s_cons.col*2;
   VIDMEM[offset] = (uchar_t) c;
   VIDMEM[offset+1] = s_cons.currentAttr;

Shift and release

------------------- a2/src/geekos/keyboard.c -------------------
@@ -198,11 +198,18 @@ static void Keyboard_Interrupt_Handler
     if (scanCode >= SCAN_TABLE_SIZE) { goto done; }

     // Look up the keycode in the conversion table
-    keycode = s_scanTableNoShift[scanCode];
+    if(s_shiftState & SHIFT_MASK) {
+        keycode = s_scanTableWithShift[scanCode];
+    }
+    else {
+        keycode = s_scanTableNoShift[scanCode];
+    }
+
+    if(!release) {
+        // Add the keycode to the queue.
+        Enqueue_Keycode(keycode);
+    }

-    // Add the keycode to the queue.
-    Enqueue_Keycode(keycode);
- 
     // Before returning from the interrupt handler, we have to
     // communicate with the Programmable Interrupt Controller (PIC) to

Don’t enqueue shifts

------------------- a2/src/geekos/keyboard.c -------------------
@@ -205,7 +205,14 @@ static void Keyboard_Interrupt_Handler
         keycode = s_scanTableNoShift[scanCode];
     }

-    if(!release) {
+    if(keycode == KEY_LSHIFT) {
+        Set_Or_Clear_Shift_State(LEFT_SHIFT, release);
+    }
+    else if(keycode == KEY_RSHIFT) {
+        Set_Or_Clear_Shift_State(RIGHT_SHIFT, release);
+    }
+
+    if(!release && keycode != KEY_LSHIFT && keycode != KEY_RSHIFT) {
         // Add the keycode to the queue.
         Enqueue_Keycode(keycode);

Scroll

This is much cleaner than the one I started in class.

-------------------- a2/src/geekos/screen.c --------------------
@@ -41,6 +41,27 @@
   }
 }

+void Scroll(void)
+{
+    int i;
+    // Move everything up
+    for(i = NUMCOLS*2; // beginning of second row
+        i < NUMROWS*NUMCOLS*2;
+        i++)
+    {
+        VIDMEM[i-NUMCOLS*2] = VIDMEM[i];
+    }
+    // Clear bottom row
+    for(i = (NUMROWS-1)*NUMCOLS*2;
+        i < NUMROWS*NUMCOLS*2;
+        i += 2)
+    {
+        VIDMEM[i] = ' ';
+        VIDMEM[i+1] = s_cons.currentAttr;
+    }
+    s_cons.row = NUMROWS-1;
+}
+
 /*
  * Write the graphic representation of given character to the screen
  * at current position, with current attribute, scrolling if
@@ -51,6 +72,7 @@ static void Write_One_Char(int c)
   // TODO
   if(c == '\n' || c == '\r') {
     s_cons.row++;
+    if(s_cons.row >= NUMROWS) Scroll();
     s_cons.col = 0;
     return;
   }
@@ -60,6 +82,7 @@ static void Write_One_Char(int c)
   s_cons.col++;
   if(s_cons.col >= NUMCOLS) {
     s_cons.row++;
+    if(s_cons.row+1 >= NUMROWS) Scroll();
     s_cons.col = 0;
   }
 }
comments powered by Disqus

 

©2012 Christopher League · some rights reserved · CC by-sa