xref: /haiku/src/add-ons/kernel/console/vga_text/vga_text.c (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 /*
2  * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
6  * Distributed under the terms of the NewOS License.
7  */
8 
9 
10 #include <KernelExport.h>
11 #include <Drivers.h>
12 #include <ISA.h>
13 
14 #include <vm_address_space.h>
15 #include <console.h>
16 
17 #include <string.h>
18 
19 
20 #define SCREEN_START 0xb8000
21 #define SCREEN_END   0xc0000
22 #define LINES 25
23 #define COLUMNS 80
24 
25 #define TEXT_INDEX 0x3d4
26 #define TEXT_DATA  0x3d5
27 
28 #define TEXT_CURSOR_LO 0x0f
29 #define TEXT_CURSOR_HI 0x0e
30 
31 static uint16 *gOrigin;
32 static isa_module_info *isa;
33 
34 
35 static int
36 text_init(void)
37 {
38 	addr_t i;
39 
40 	if (get_module(B_ISA_MODULE_NAME, (module_info **)&isa) < 0) {
41 		dprintf("text module_init: no isa bus found..\n");
42 		return -1;
43 	}
44 
45 	/* we always succeede, so init our stuff */
46 	dprintf("console/text: mapping vid mem\n");
47 	vm_map_physical_memory(vm_kernel_address_space_id(), "vid_mem", (void *)&gOrigin,
48 		B_ANY_KERNEL_ADDRESS, SCREEN_END - SCREEN_START,
49 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, SCREEN_START);
50 	dprintf("console/text: mapped vid mem to virtual address %p\n", gOrigin);
51 
52 	/* pre-touch all of the memory so that we dont fault while deep inside the kernel and displaying something */
53 	for(i = (addr_t)gOrigin; i < (addr_t)gOrigin + (SCREEN_END - SCREEN_START); i += B_PAGE_SIZE) {
54 		uint16 val = *(volatile uint16 *)i;
55 		*(volatile uint16 *)i = val;
56 	}
57 	return 0;
58 }
59 
60 
61 static int
62 text_uninit(void)
63 {
64 	put_module(B_ISA_MODULE_NAME);
65 
66 	// ToDo: unmap video memory (someday)
67 	return 0;
68 }
69 
70 
71 static status_t
72 get_size(int32 *width, int32 *height)
73 {
74 	*width = COLUMNS;
75 	*height = LINES;
76 	return 0;
77 }
78 
79 
80 static void
81 move_cursor(int32 x, int32 y)
82 {
83 	short int pos;
84 
85 	if (x < 0 || y < 0)
86 		pos = LINES * COLUMNS + 1;
87 	else
88 		pos = y * COLUMNS + x;
89 
90 	isa->write_io_8(TEXT_INDEX, TEXT_CURSOR_LO);
91 	isa->write_io_8(TEXT_DATA, (char)pos);
92 	isa->write_io_8(TEXT_INDEX, TEXT_CURSOR_HI);
93 	isa->write_io_8(TEXT_DATA, (char)(pos >> 8));
94 }
95 
96 
97 static void
98 put_glyph(int32 x, int32 y, uint8 glyph, uint8 attr)
99 {
100 	uint16 pair = ((uint16)attr << 8) | (uint16)glyph;
101 	uint16 *p = gOrigin+(y*COLUMNS)+x;
102 	*p = pair;
103 }
104 
105 
106 static void
107 fill_glyph(int32 x, int32 y, int32 width, int32 height, uint8 glyph, uint8 attr)
108 {
109 	uint16 pair = ((uint16)attr << 8) | (uint16)glyph;
110 	int32 y_limit = y + height;
111 
112 	while (y < y_limit) {
113 		uint16 *p = gOrigin + (y * COLUMNS) + x;
114 		uint16 *p_limit = p + width;
115 		while (p < p_limit) *p++ = pair;
116 		y++;
117 	}
118 }
119 
120 
121 static void
122 blit(int32 srcx, int32 srcy, int32 width, int32 height, int32 destx, int32 desty)
123 {
124 	if ((srcx == 0) && (width == COLUMNS)) {
125 		// whole lines
126 		memmove(gOrigin + (desty * COLUMNS), gOrigin + (srcy * COLUMNS), height * COLUMNS * 2);
127 	} else {
128 		// FIXME
129 	}
130 }
131 
132 
133 static void
134 clear(uint8 attr)
135 {
136 	uint16 *base = (uint16 *)gOrigin;
137 	uint32 i;
138 
139 	for (i = 0; i < COLUMNS * LINES; i++)
140 		base[i] = (attr << 8) | 0x20;
141 }
142 
143 
144 static status_t
145 text_std_ops(int32 op, ...)
146 {
147 	switch (op) {
148 		case B_MODULE_INIT:
149 			return text_init();
150 		case B_MODULE_UNINIT:
151 			return text_uninit();
152 
153 		default:
154 			return B_ERROR;
155 	}
156 }
157 
158 
159 static console_module_info sVGATextConsole = {
160 	{
161 		"console/vga_text/v1",
162 		0,
163 		text_std_ops
164 	},
165 	get_size,
166 	move_cursor,
167 	put_glyph,
168 	fill_glyph,
169 	blit,
170 	clear,
171 };
172 
173 module_info *modules[] = {
174 	(module_info *)&sVGATextConsole,
175 	NULL
176 };
177