Don't use <string.h>.
[pintos-anon] / src / devices / vga.c
1 #include "vga.h"
2 #include <stdint.h>
3 #include <stddef.h>
4 #include "io.h"
5 #include "lib.h"
6 #include "mmu.h"
7
8 static size_t vga_cols, vga_rows;
9 static size_t vga_x, vga_y;
10 static uint16_t *vga_base;
11
12 void
13 vga_init (void)
14 {
15   vga_cols = 80;
16   vga_rows = 25;
17   vga_base = (uint16_t *) ptov (0xb8000);
18   vga_cls ();
19 }
20
21 void
22 vga_cls (void)
23 {
24   size_t i;
25   for (i = 0; i < vga_cols * vga_rows; i++)
26     vga_base[i] = 0x0700;
27   vga_x = vga_y = 0;
28 }
29
30 static void
31 vga_newline (void)
32 {
33   vga_x = 0;
34   vga_y++;
35   if (vga_y >= vga_rows)
36     {
37       vga_y = vga_rows - 1;
38       memmove (vga_base, vga_base + vga_cols,
39                vga_cols * (vga_rows - 1) * 2);
40       memset (vga_base + vga_cols * (vga_rows - 1),
41               0, vga_cols * 2);
42     }
43 }
44
45 static void
46 move_cursor (void) 
47 {
48   uint16_t cp = (vga_x + vga_cols * vga_y);
49   outw (0x3d4, 0x0e | (cp & 0xff00));
50   outw (0x3d4, 0x0f | (cp << 8));
51 }
52
53 void
54 vga_putc (int c)
55 {
56   switch (c) 
57     {
58     case '\n':
59       vga_newline ();
60       break;
61
62     case '\f':
63       vga_cls ();
64       break;
65
66     case '\b':
67       if (vga_x > 0)
68         vga_x--;
69       break;
70       
71     case '\r':
72       vga_x = 0;
73       break;
74
75     case '\t':
76       vga_x = (vga_x + 8) / 8 * 8;
77       if (vga_x >= vga_cols)
78         vga_newline ();
79       break;
80       
81     default:
82       vga_base[vga_x + vga_y * vga_cols] = 0x0700 | c;
83       vga_x++;
84       if (vga_x >= vga_cols)
85         vga_newline ();
86       break;
87     }
88
89   move_cursor ();
90 }