From: AceVest Date: Thu, 5 Jun 2014 15:19:18 +0000 (+0800) Subject: rewrite vga X-Git-Tag: 0.3.0~53 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=0305cccf6ebb3cc1e07a23c6ab5e55d6653f5dc7;p=kernel.git rewrite vga --- diff --git a/drivers/vga.c b/drivers/vga.c index fcc50e9..8046161 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -12,126 +12,133 @@ #include -#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++; } } diff --git a/fs/write.c b/fs/write.c index 9dbe44b..cebc502 100644 --- a/fs/write.c +++ b/fs/write.c @@ -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; diff --git a/kernel/printk.c b/kernel/printk.c index d893720..a32b5f4 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -16,11 +16,11 @@ */ 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; } diff --git a/mm/slub.c b/mm/slub.c index ddd0c06..39df055 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -320,7 +320,7 @@ void init_slub_system() kmem_cache_init(cache, "kmalloc_old", 1UL<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 diff --git a/setup/setup.c b/setup/setup.c index a8a27e1..146cd08 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -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();