X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdevices%2Fvga.c;h=8255747244e641d599d686fadecb167a9fc6b4f7;hb=53a7f5d0952a4595f252247f5ee3d017468eb57e;hp=fdddd91de7b94e062869d416472b373f0a939e8b;hpb=7180597203a54c08582b1bb092dc465ec1d26d7c;p=pintos-anon diff --git a/src/devices/vga.c b/src/devices/vga.c index fdddd91..8255747 100644 --- a/src/devices/vga.c +++ b/src/devices/vga.c @@ -1,9 +1,11 @@ -#include "vga.h" +#include "devices/vga.h" +#include #include #include -#include "io.h" -#include "lib.h" -#include "mmu.h" +#include +#include "threads/io.h" +#include "threads/interrupt.h" +#include "threads/vaddr.h" /* VGA text screen support. See [FREEVGA] for more information. */ @@ -27,20 +29,33 @@ static void clear_row (size_t y); static void cls (void); static void newline (void); static void move_cursor (void); +static void find_cursor (size_t *x, size_t *y); -/* Initializes the VGA text display and clears the screen. */ -void -vga_init (void) +/* Initializes the VGA text display. */ +static void +init (void) { - fb = ptov (0xb8000); - cls (); + /* Already initialized? */ + static bool inited; + if (!inited) + { + fb = ptov (0xb8000); + find_cursor (&cx, &cy); + inited = true; + } } /* Writes C to the VGA text display, interpreting control - characters in the conventional ways. */ + characters in the conventional ways. */ void vga_putc (int c) { + /* Disable interrupts to lock out interrupt handlers + that might write to the console. */ + enum intr_level old_level = intr_disable (); + + init (); + switch (c) { case '\n': @@ -76,6 +91,8 @@ vga_putc (int c) /* Update cursor position. */ move_cursor (); + + intr_set_level (old_level); } /* Clears the screen and moves the cursor to the upper left. */ @@ -130,3 +147,19 @@ move_cursor (void) outw (0x3d4, 0x0f | (cp << 8)); } +/* Reads the current hardware cursor position into (*X,*Y). */ +static void +find_cursor (size_t *x, size_t *y) +{ + /* See [FREEVGA] under "Manipulating the Text-mode Cursor". */ + uint16_t cp; + + outb (0x3d4, 0x0e); + cp = inb (0x3d5) << 8; + + outb (0x3d4, 0x0f); + cp |= inb (0x3d5); + + *x = cp % COL_CNT; + *y = cp / COL_CNT; +}