1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <libpayload.h>
31#include <video_console.h>
32
33struct video_console vga_video_console;
34
35#define VGA_COLOR_WHITE 7
36
37#define CRTC_INDEX 0x3d4
38#define CRTC_DATA 0x3d5
39
40#define VIDEO(_r, _c)\
41 ((u16 *) (phys_to_virt(0xB8000) + ((_r) * (vga_video_console.columns * 2)) + ((_c) * 2)))
42
43static u8 crtc_read(u8 index)
44{
45 outb(index, CRTC_INDEX);
46 return inb(CRTC_DATA);
47}
48
49static void crtc_write(u8 data, u8 index)
50{
51 outb(index, CRTC_INDEX);
52 outb(data, CRTC_DATA);
53}
54
55static void vga_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en)
56{
57 unsigned int addr;
58 addr = ((unsigned int) crtc_read(0x0E)) << 8;
59 addr += crtc_read(0x0F);
60
61 *x = addr % vga_video_console.columns;
62 *y = addr / vga_video_console.columns;
63
64 *en = !(crtc_read(0x0A) & (1 << 5));
65}
66
67static void vga_set_cursor(unsigned int x, unsigned int y)
68{
69 unsigned int addr;
70
71 addr = x + (vga_video_console.columns * y);
72 crtc_write(addr >> 8, 0x0E);
73 crtc_write(addr, 0x0F);
74}
75
76static void vga_enable_cursor(int state)
77{
78 unsigned char tmp = crtc_read(0x0a);
79
80 if (state == 0)
81 tmp |= (1 << 5);
82
83 else
84 tmp &= ~(1 << 5);
85
86 crtc_write(tmp, 0x0a);
87}
88
89static void vga_clear_line(u8 row, u8 ch, u8 attr)
90{
91 int col;
92 u16 *ptr = VIDEO(row, 0);
93
94 for(col = 0; col < vga_video_console.columns; col++)
95 ptr[col] = ((attr & 0xFF) << 8) | (ch & 0xFF);
96}
97
98static void vga_scroll_up(void)
99{
100 u16 *src = VIDEO(1,0);
101 u16 *dst = VIDEO(0,0);
102 int i;
103
104 for(i = 0; i < (vga_video_console.rows - 1) * vga_video_console.columns; i++)
105 *dst++ = *src++;
106
107 vga_clear_line(vga_video_console.rows - 1, ' ', VGA_COLOR_WHITE);
108}
109
110static void vga_fill(u8 ch, u8 attr)
111{
112 u8 row;
113 for(row = 0; row < vga_video_console.rows; row++)
114 vga_clear_line(row, ch, attr);
115}
116
117static void vga_clear(void)
118{
119 vga_fill(' ', VGA_COLOR_WHITE);
120}
121
122static void vga_putc(u8 row, u8 col, unsigned int c)
123{
124 u16 *ptr = VIDEO(row, col);
125 *ptr = (u16) (c & 0xFFFF);
126}
127
128static void vga_init_cursor(void)
129{
130 u8 val;
131
132#define CURSOR_MSL 0x09
133#define CURSOR_START 0x0A
134#define CURSOR_END 0x0B
135
136 val = crtc_read(CURSOR_MSL) & 0x1f;
137 crtc_write(0, CURSOR_START);
138 crtc_write(val - 2, CURSOR_END);
139}
140
141static int vga_init(void)
142{
143 vga_init_cursor();
144 return 0;
145}
146
147struct video_console vga_video_console = {
148 .init = vga_init,
149 .putc = vga_putc,
150 .clear = vga_clear,
151 .scroll_up = vga_scroll_up,
152
153 .get_cursor = vga_get_cursor,
154 .set_cursor = vga_set_cursor,
155 .enable_cursor = vga_enable_cursor,
156
157 .columns = 80,
158 .rows = 25
159};
160