]> Zhao Yanbai Git Server - kernel.git/commitdiff
rewrite vga
authorAceVest <zhaoyanbai@126.com>
Thu, 5 Jun 2014 15:19:18 +0000 (23:19 +0800)
committerAceVest <zhaoyanbai@126.com>
Thu, 5 Jun 2014 15:19:18 +0000 (23:19 +0800)
drivers/vga.c
fs/write.c
kernel/printk.c
mm/slub.c
setup/setup.c

index fcc50e9085c94a52585077c0cd207f0eb825c9ba..8046161880992656cde602435afa51da2e512734 100644 (file)
 
 #include <io.h>
 
-#define VGA_CRTC_ADDR    0x3D4
-#define VGA_CRTC_DATA    0x3D5
-#define VGA_CRTC_START_ADDR_H    0xC
-#define VGA_CRTC_START_ADDR_L    0xD
-#define VGA_CRTC_CURSOR_H    0xE
-#define VGA_CRTC_CURSOR_L    0xF
+typedef struct {
+    u8_t    c;
+    u8_t    f;
+} __attribute__((packed)) vga_char_t;
 
+#define VIDEO_ADDR              0xC00B8000
 
-#define LINES_PER_SCREEN    24    //25
-#define CHARS_PER_LINE        80
-#define BYTES_PER_LINE        (CHARS_PER_LINE<<1)
-#define MAX_LINES        (LINES_PER_SCREEN<<1)
-#define VIDEO_ADDR        0xC00B8000
+#define VGA_CRTC_ADDR           0x3D4
+#define VGA_CRTC_DATA           0x3D5
+#define VGA_CRTC_START_ADDR_H   0xC
+#define VGA_CRTC_START_ADDR_L   0xD
+#define VGA_CRTC_CURSOR_H       0xE
+#define VGA_CRTC_CURSOR_L       0xF
 
-static unsigned int xpos, ypos;
+#define LINES_PER_SCREEN        25
+#define CHARS_PER_LINE          80
+#define BYTES_PER_LINE          (sizeof(vga_char_t)*CHARS_PER_LINE)
 
-void    setCursorPos(unsigned int x, unsigned int y);
-void     printString(const char *buf, unsigned char color);
-void    printChar(const unsigned char c, const unsigned char color);
-void    ScrollUp();
+#define TAB_ALIGN               4
+#define TAB_MASK                (TAB_ALIGN-1)
 
-void    setCursorPos(unsigned int x, unsigned int y)
+static unsigned int g_offset = 0;
+
+static void set_offset(unsigned int x, unsigned int y)
+{
+    g_offset = (y * CHARS_PER_LINE) + x;
+}
+
+static unsigned int xpos()
+{
+    return (g_offset % CHARS_PER_LINE);
+}
+
+static unsigned int ypos()
+{
+    return (g_offset / CHARS_PER_LINE);
+}
+
+vga_char_t vga_char(unsigned char c, unsigned char f)
+{
+    vga_char_t x;
+    x.c = c;
+    x.f = f;
+
+    return x;
+}
+
+void vga_set_cursor_pos()
+{
+    outb(VGA_CRTC_CURSOR_H,     VGA_CRTC_ADDR);
+    outb((g_offset>>8) & 0xFF,  VGA_CRTC_DATA);
+    outb(VGA_CRTC_CURSOR_L,     VGA_CRTC_ADDR);
+    outb(g_offset & 0xFF,       VGA_CRTC_DATA);
+}
+
+void vga_clear(unsigned int b, unsigned int e)
+{
+    vga_char_t *base = (vga_char_t *) VIDEO_ADDR;
+
+    base += b;
+
+    memset((void *)base, 0, (e-b)*sizeof(vga_char_t));
+}
+
+void vga_scroll_up()
 {
-    unsigned short    offset = x +  y * CHARS_PER_LINE;
-    outb(VGA_CRTC_CURSOR_H,    VGA_CRTC_ADDR);
-    outb((offset>>8) & 0xFF,VGA_CRTC_DATA);
-    outb(VGA_CRTC_CURSOR_L,    VGA_CRTC_ADDR);
-    outb(offset & 0xFF,    VGA_CRTC_DATA);
+    int delta = ypos() + 1 - LINES_PER_SCREEN;
+
+    if(delta <= 0)
+        return;
+
+    vga_char_t *base = (vga_char_t *) VIDEO_ADDR;
+    vga_char_t *head = base + delta*CHARS_PER_LINE;
+    vga_char_t *empt = base + (LINES_PER_SCREEN-delta)*CHARS_PER_LINE;
+
+    memcpy((void *)base, (void *)head, (empt-base)*sizeof(vga_char_t));
+    //memset((void *)empt, 0, delta*BYTES_PER_LINE);
+
+    vga_clear((LINES_PER_SCREEN-delta)*CHARS_PER_LINE, LINES_PER_SCREEN*CHARS_PER_LINE);
+
+    set_offset(xpos(), ypos() - delta);
 }
 
-void    printChar(const unsigned char c, const unsigned char color)
+
+
+void vga_putc(const unsigned char c, const unsigned char color)
 {
-    unsigned short * const pv = (unsigned short * const) VIDEO_ADDR;
+    vga_char_t * const pv = (vga_char_t * const) VIDEO_ADDR;
 
+    bool need_clear = true;
+    unsigned int old_offset = g_offset;
+    
     switch(c)
     {
     case '\r':
-        xpos = 0;
+        set_offset(0, ypos());
         break;
     case '\n':
-        xpos = 0; ypos++;
+        set_offset(0, ypos() + 1);
         break;
     case '\t':
-        xpos &= (~0x07);
-        xpos += 8;
-        if(xpos >= CHARS_PER_LINE)
-        {
-            xpos = 0;
-            ypos ++;
-        }
-        break;
-    case '\b':
-        if(xpos > 0)
-            xpos--;
-        else if(ypos > 0)
-        {
-            xpos = CHARS_PER_LINE - 1;
-            ypos --;
-        }
-        *(pv + xpos + ypos*CHARS_PER_LINE) = ' ' | (color << 8);
+        set_offset((xpos() + 1 + TAB_MASK) & ~TAB_MASK, ypos());
         break;
     default:
-        *(pv + xpos + ypos*CHARS_PER_LINE) = c | (color << 8);
-        xpos ++;
-        if(xpos == CHARS_PER_LINE)
-        {
-            xpos = 0;
-            ypos ++;
-        }
+        need_clear = false;
+        pv[g_offset] = vga_char(c, color);
+        set_offset(xpos()+1, ypos());
         break;
     }
 
-    ScrollUp();
-
-    setCursorPos(xpos, ypos);
-}
-
-void    ScrollUp()
-{
-    static unsigned int last_ypos;
-    unsigned short topline;
-    if((ypos >= LINES_PER_SCREEN) && (ypos > last_ypos))
+    if(need_clear)
     {
-        topline = ypos - LINES_PER_SCREEN;
-
-        if(topline == MAX_LINES)
-        {
-
-            memcpy(    VIDEO_ADDR,
-                VIDEO_ADDR+MAX_LINES*BYTES_PER_LINE,
-                LINES_PER_SCREEN*BYTES_PER_LINE);
-
-            unsigned char *p;
-            const unsigned char *pend;
-            p=(unsigned char *)
-            VIDEO_ADDR+LINES_PER_SCREEN*BYTES_PER_LINE;
-            while(p <=(unsigned char *) VIDEO_ADDR 
-            + (LINES_PER_SCREEN+MAX_LINES)*BYTES_PER_LINE)
-            {
-                *p++ = ' ';
-                *p++ = 0x0F;
-            }
-            ypos -= topline;
-            topline = 0;
-        }
-        outb(VGA_CRTC_START_ADDR_H,VGA_CRTC_ADDR);
-        outb(((topline*CHARS_PER_LINE)>>8)&0xFF,VGA_CRTC_DATA);
-        outb(VGA_CRTC_START_ADDR_L,VGA_CRTC_ADDR);
-        outb((topline*CHARS_PER_LINE)&0xFF,VGA_CRTC_DATA);
+        vga_clear(old_offset, g_offset);
     }
-    last_ypos = ypos;
+
+    vga_scroll_up();
+
+    vga_set_cursor_pos();
 }
 
-void     printString(const char *buf, unsigned char color)
+void vga_puts(const char *buf, unsigned char color)
 {
     char *p = (char *) buf;
 
     while(*p)
     {
-        printChar(*p, color);
+        vga_putc(*p, color);
         p++;
     }
 }
index 9dbe44b8b455af77340a859a119c0e49ba540384..cebc502208618c0686ce59d4ecc88a6a0ff14c84 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 
-extern void     printString(const char *buf, unsigned char color);
+extern void     vga_puts(const char *buf, unsigned char color);
 int sysc_write(int fd, const char *buf, unsigned long size)
 {
     if(size < 0) return -1;
@@ -23,7 +23,7 @@ int sysc_write(int fd, const char *buf, unsigned long size)
     switch(fd)
     {
     case 0:
-        printString(buf, 0xF);
+        vga_puts(buf, 0xF);
         break;
     default:
         return -1;
index d89372023b8479365ab64c9fae6ec3a7a1a99769..a32b5f4258dfb9e665524e2c40a2b9b1b437cec6 100644 (file)
  */
 
 char pkbuf[1024];
-extern void     printString(const char *buf, unsigned char color);
+extern void     vga_puts(const char *buf, unsigned char color);
 int printk(const char *fmtstr, ...)
 {
     char *args = (char*)(((char*)&fmtstr)+4);
     vsprintf(pkbuf, fmtstr, args);
-    printString(pkbuf,0x2);
+    vga_puts(pkbuf,0x2);
     return 0;
 }
index ddd0c0604a1e54200e1b63163fc8a610c0799b6c..39df055311b698d9eb48fd64a5acd796782650c1 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -320,7 +320,7 @@ void init_slub_system()
         kmem_cache_init(cache, "kmalloc_old", 1UL<<i, KMALLOC_MIN_ALIGN);
 
         list_add(&(cache->list), &slub_caches);
-        printk("kmem objsize %d  size %d \n", cache->objsize, cache->size);
+        printk("kmem objsize %d\tsize %d \n", cache->objsize, cache->size);
     }
 
 #if 0
index a8a27e10851679bec702ac67a1d8887039c5d93c..146cd0885a9cad30c669a198f85d27442ff15940 100644 (file)
@@ -62,7 +62,7 @@ void setup_kernel()
     printk("kernel: %08x - %08x\n", &kernel_begin, &kernel_end);
 
     init_mm();
-
+    //while(1);
     setup_gdt();
     setup_idt();
     setup_gate();