VGA: Remove recursion from biosfn_write_teletype().
authorKevin O'Connor <kevin@koconnor.net>
Tue, 26 May 2009 04:20:40 +0000 (00:20 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 26 May 2009 04:20:40 +0000 (00:20 -0400)
vgasrc/vga.c

index 53e8dd831453000ef4b466064047fa85a054f7bc..6f954f373e0480e0542307f2b4066279c836f2cb 100644 (file)
@@ -7,7 +7,6 @@
 
 
 // TODO:
-//  * remove recursion from biosfn_write_teletype()
 //  * review correctness of converted asm by comparing with RBIL
 //  * refactor redundant code into sub-functions
 //  * See if there is a method to the in/out stuff that can be encapsulated.
@@ -176,21 +175,43 @@ biosfn_set_active_page(u8 page)
     set_cursor_pos(cp);
 }
 
+static struct cursorpos
+check_scroll(struct cursorpos cp)
+{
+    // Get the dimensions
+    u16 nbrows = GET_BDA(video_rows) + 1;
+    u16 nbcols = GET_BDA(video_cols);
+
+    // Do we need to wrap ?
+    if (cp.x == nbcols) {
+        cp.x = 0;
+        cp.y++;
+    }
+    // Do we need to scroll ?
+    if (cp.y == nbrows) {
+        // Get the mode
+        struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
+        if (!vmode_g)
+            return cp;
+
+        if (GET_GLOBAL(vmode_g->memmodel) & TEXT)
+            biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, cp.page,
+                          SCROLL_UP);
+        else
+            biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, cp.page,
+                          SCROLL_UP);
+        cp.y--;
+    }
+
+    return cp;
+}
+
 static void
 biosfn_write_teletype(u8 page, struct carattr ca)
 {
-    // Get the mode
-    struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
-    if (!vmode_g)
-        return;
-
     // Get the cursor pos for the page
     struct cursorpos cp = get_cursor_pos(page);
 
-    // Get the dimensions
-    u16 nbrows = GET_BDA(video_rows) + 1;
-    u16 nbcols = GET_BDA(video_cols);
-
     switch (ca.car) {
     case 7:
         //FIXME should beep
@@ -212,9 +233,10 @@ biosfn_write_teletype(u8 page, struct carattr ca)
     case '\t':
         do {
             struct carattr dummyca = {' ', ca.attr, ca.use_attr};
-            biosfn_write_teletype(page, dummyca);
-            cp = get_cursor_pos(page);
-        } while (cp.x % 8 == 0);
+            vgafb_write_char(cp, dummyca);
+            cp.x++;
+            cp = check_scroll(cp);
+        } while (cp.x % 8);
         break;
 
     default:
@@ -222,21 +244,8 @@ biosfn_write_teletype(u8 page, struct carattr ca)
         cp.x++;
     }
 
-    // Do we need to wrap ?
-    if (cp.x == nbcols) {
-        cp.x = 0;
-        cp.y++;
-    }
-    // Do we need to scroll ?
-    if (cp.y == nbrows) {
-        if (GET_GLOBAL(vmode_g->memmodel) & TEXT)
-            biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
-                          SCROLL_UP);
-        else
-            biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, page,
-                          SCROLL_UP);
-        cp.y--;
-    }
+    cp = check_scroll(cp);
+
     // Set the cursor for the page
     set_cursor_pos(cp);
 }