001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018 #include <sos/klibc.h>
019 #include <hwcore/ioports.h>
020
021 #include "x86_videomem.h"
022
023
024
025
026 #define VIDEO 0xb8000
027
028
029
030 #define LINES 25
031 #define COLUMNS 80
032
033
034
035
036
037
038
039
040
041 #define VGA_COMMAND_PORT 0x3D4
042 #define VGA_DATA_PORT 0x3D5
043
044
045 #define VGA_SET_CURSOR_START 0xA
046 #define VGA_SET_CURSOR_END 0xB
047 #define VGA_SET_CURSOR_HIGH 0xE
048 #define VGA_SET_CURSOR_LOW 0xF
049
050
051
052 typedef struct {
053 unsigned char character;
054 unsigned char attribute;
055 } __attribute__ ((packed)) x86_video_mem[LINES*COLUMNS];
056
057
058
059
060 static volatile x86_video_mem *video = (volatile x86_video_mem*)VIDEO;
061
062 sos_ret_t sos_x86_videomem_setup(void)
063 {
064
065
066 outb(0x0a, VGA_COMMAND_PORT);
067
068
069 outb(1 << 5, VGA_DATA_PORT);
070
071 return SOS_OK;
072 }
073
074
075 sos_ret_t sos_x86_videomem_cls(unsigned char attribute)
076 {
077
078 int i;
079 for(i = 0 ; i < LINES*COLUMNS ; i++)
080 {
081 (*video)[i].character = 0;
082 (*video)[i].attribute = attribute;
083 }
084
085 return SOS_OK;
086 }
087
088
089 sos_ret_t sos_x86_videomem_putstring(unsigned char row, unsigned char col,
090 unsigned char attribute,
091 const char *str)
092 {
093 unsigned video_offs = row*COLUMNS + col;
094
095 if (video_offs >= LINES*COLUMNS)
096 return -SOS_EINVAL;
097
098 for ( ; str && *str && (video_offs < LINES*COLUMNS) ; str++, video_offs++)
099 {
100 (*video)[video_offs].character = (unsigned char)*str;
101 (*video)[video_offs].attribute = attribute;
102 }
103
104 return SOS_OK;
105 }
106
107
108 sos_ret_t sos_x86_videomem_putchar(unsigned char row, unsigned char col,
109 unsigned char attribute,
110 unsigned char c)
111 {
112 unsigned video_offs = row*COLUMNS + col;
113
114 if (video_offs >= LINES*COLUMNS)
115 return -SOS_EINVAL;
116
117 (*video)[video_offs].character = c;
118 (*video)[video_offs].attribute = attribute;
119
120 return SOS_OK;
121 }
122
123
124 sos_ret_t sos_x86_videomem_printf(unsigned char row, unsigned char col,
125 unsigned char attribute,
126 const char *format, ...)
127 {
128 char buff[256];
129 va_list ap;
130
131 va_start(ap, format);
132 vsnprintf(buff, sizeof(buff), format, ap);
133 va_end(ap);
134
135 return sos_x86_videomem_putstring(row, col, attribute, buff);
136 }
137
138
139
140
141
142
143
144
145
146
147
148 static int row;
149
150
151
152 static int col;
153
154
155
156
157 #define CONSOLE_ROW_START 12
158
159 static void sos_screen_set_cursor (unsigned int row, unsigned int col)
160 {
161 unsigned int pos;
162
163 pos = (row * COLUMNS + col);
164
165 outb(VGA_SET_CURSOR_HIGH, VGA_COMMAND_PORT);
166 outb( (pos >> 8), VGA_DATA_PORT);
167 outb(VGA_SET_CURSOR_LOW, VGA_COMMAND_PORT);
168 outb( (pos & 0xFF), VGA_DATA_PORT);
169 }
170
171 sos_ret_t sos_screen_putchar (char c)
172 {
173 if (c == '\r')
174 {
175
176 col = 0;
177 }
178
179
180 else if (c == '\n')
181 {
182
183 col = 0;
184 row ++;
185 }
186
187
188 else if (c == '\b')
189 {
190
191
192 col --;
193
194
195 if (col < 0)
196 {
197 row --;
198 col = COLUMNS-1;
199
200 if (row < CONSOLE_ROW_START)
201 {
202 row = CONSOLE_ROW_START;
203 col = 0;
204 }
205 }
206
207
208 sos_x86_videomem_putchar
209 (row, col, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, ' ');
210 }
211 else if (c != 0)
212 {
213 sos_x86_videomem_putchar
214 (row, col, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, c);
215 col++;
216 if (col == COLUMNS)
217 {
218 col = 0;
219 row++;
220 }
221 }
222
223
224 if (row == LINES)
225 {
226 int i;
227
228
229 for (i = CONSOLE_ROW_START; i < LINES; i++)
230 memcpy ((char*) video + i * COLUMNS * 2,
231 (char*) video + ((i + 1) * COLUMNS * 2),
232 COLUMNS * 2);
233
234
235 for (i = 0; i < COLUMNS; i++)
236 sos_x86_videomem_putchar
237 (LINES-1, i, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, ' ');
238
239 row--;
240 }
241
242 sos_screen_set_cursor (row, col);
243
244 return SOS_OK;
245 }
246
247 sos_ret_t sos_screen_init (void)
248 {
249 int i, j;
250
251 row = CONSOLE_ROW_START;
252 col = 0;
253
254
255
256
257 outb(VGA_SET_CURSOR_START, VGA_COMMAND_PORT);
258 outb(((0x2 << 5) | 14), VGA_DATA_PORT);
259
260 for (i = CONSOLE_ROW_START; i < LINES; i++)
261 {
262 for (j = 0; j < COLUMNS; j++)
263 sos_x86_videomem_putchar
264 (i, j, SOS_X86_VIDEO_FG_BLUE | SOS_X86_VIDEO_BG_LTGRAY, ' ');
265 }
266
267 sos_screen_set_cursor (row, col);
268
269 return SOS_OK;
270 }