vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / console / vga_text / vga_text.c
blob2dfe8c7da7f17bd6322ded3ac3a550a5f6898137
1 /*
2 * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
6 * Distributed under the terms of the NewOS License.
7 */
10 #include <KernelExport.h>
11 #include <Drivers.h>
12 #include <ISA.h>
14 #include <console.h>
16 #include <string.h>
19 #define SCREEN_START 0xb8000
20 #define SCREEN_END 0xc0000
21 #define LINES 25
22 #define COLUMNS 80
24 #define TEXT_INDEX 0x3d4
25 #define TEXT_DATA 0x3d5
27 #define TEXT_CURSOR_LO 0x0f
28 #define TEXT_CURSOR_HI 0x0e
30 static uint16 *sOrigin;
31 static isa_module_info *sISA;
34 static int
35 text_init(void)
37 addr_t i;
39 if (get_module(B_ISA_MODULE_NAME, (module_info **)&sISA) < 0) {
40 dprintf("text module_init: no isa bus found..\n");
41 return -1;
44 map_physical_memory("video_mem", SCREEN_START, SCREEN_END - SCREEN_START,
45 B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void *)&sOrigin);
46 dprintf("console/text: mapped vid mem to virtual address %p\n", sOrigin);
48 /* pre-touch all of the memory so that we dont fault while deep inside the kernel and displaying something */
49 for (i = (addr_t)sOrigin; i < (addr_t)sOrigin + (SCREEN_END - SCREEN_START);
50 i += B_PAGE_SIZE) {
51 uint16 val = *(volatile uint16 *)i;
52 *(volatile uint16 *)i = val;
54 return 0;
58 static int
59 text_uninit(void)
61 put_module(B_ISA_MODULE_NAME);
63 // ToDo: unmap video memory (someday)
64 return 0;
68 static status_t
69 get_size(int32 *width, int32 *height)
71 *width = COLUMNS;
72 *height = LINES;
73 return 0;
77 static void
78 move_cursor(int32 x, int32 y)
80 short int pos;
82 if (x < 0 || y < 0)
83 pos = LINES * COLUMNS + 1;
84 else
85 pos = y * COLUMNS + x;
87 sISA->write_io_8(TEXT_INDEX, TEXT_CURSOR_LO);
88 sISA->write_io_8(TEXT_DATA, (char)pos);
89 sISA->write_io_8(TEXT_INDEX, TEXT_CURSOR_HI);
90 sISA->write_io_8(TEXT_DATA, (char)(pos >> 8));
94 static void
95 put_glyph(int32 x, int32 y, uint8 glyph, uint8 attr)
97 uint16 pair = ((uint16)attr << 8) | (uint16)glyph;
98 uint16 *p = sOrigin + (y * COLUMNS) + x;
99 *p = pair;
103 static void
104 fill_glyph(int32 x, int32 y, int32 width, int32 height, uint8 glyph, uint8 attr)
106 uint16 pair = ((uint16)attr << 8) | (uint16)glyph;
107 int32 y_limit = y + height;
109 while (y < y_limit) {
110 uint16 *p = sOrigin + (y * COLUMNS) + x;
111 uint16 *p_limit = p + width;
112 while (p < p_limit) *p++ = pair;
113 y++;
118 static void
119 blit(int32 srcx, int32 srcy, int32 width, int32 height, int32 destx, int32 desty)
121 if ((srcx == 0) && (width == COLUMNS)) {
122 // whole lines
123 memmove(sOrigin + (desty * COLUMNS), sOrigin + (srcy * COLUMNS), height * COLUMNS * 2);
124 } else {
125 // FIXME
130 static void
131 clear(uint8 attr)
133 uint16 *base = (uint16 *)sOrigin;
134 uint32 i;
136 for (i = 0; i < COLUMNS * LINES; i++)
137 base[i] = (attr << 8) | 0x20;
141 static status_t
142 text_std_ops(int32 op, ...)
144 switch (op) {
145 case B_MODULE_INIT:
146 return text_init();
147 case B_MODULE_UNINIT:
148 return text_uninit();
150 default:
151 return B_ERROR;
156 static console_module_info sVGATextConsole = {
158 "console/vga_text/v1",
160 text_std_ops
162 get_size,
163 move_cursor,
164 put_glyph,
165 fill_glyph,
166 blit,
167 clear,
170 module_info *modules[] = {
171 (module_info *)&sVGATextConsole,
172 NULL