SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2004  David Decotigny
002 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007 
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012 
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.
017 */
018 #include <sos/klibc.h>
019 #include <hwcore/ioports.h>
020 
021 #include "x86_videomem.h"
022 
023 /* The text video memory starts at address 0xB8000. Odd bytes are the
024    ASCII value of the character, even bytes are attribute for the
025    preceding character. */
026 #define VIDEO   0xb8000
027 
028 
029 /* Console screen size */
030 #define LINES   25
031 #define COLUMNS 80
032 
033 /*
034  * VGA ports and commands.
035  * 
036  * @see Ralf Brown's interrupt (and port) list   
037  * http://www-2.cs.cmu.edu/~ralf/files.html      
038  */
039 
040 /* VGA ports */
041 #define VGA_COMMAND_PORT 0x3D4
042 #define VGA_DATA_PORT    0x3D5
043 
044 /* VGA commands */
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 /** The structure of a character element in the video memory. @see
051     http://webster.cs.ucr.edu/AoA DOS edition chapter 23 */
052 typedef struct {
053   unsigned char character;
054   unsigned char attribute;
055 } __attribute__ ((packed)) x86_video_mem[LINES*COLUMNS];
056 
057 
058 
059 /** The base pointer for the video memory */
060 static volatile x86_video_mem *video = (volatile x86_video_mem*)VIDEO;
061 
062 sos_ret_t sos_x86_videomem_setup(void)
063 {
064   /* CRT index port => ask for access to register 0xa ("cursor
065      start") */
066   outb(0x0a, VGA_COMMAND_PORT);
067 
068   /* (RBIL Tables 708 & 654) CRT Register 0xa => bit 5 = cursor OFF */
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   /* Clears the screen */
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, /* args */...)
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  * Console that supports scrolling, based on the low-level code
141  * above. This console only takes part of the screen, starting at row
142  * CONSOLE_ROW_START. The rows before that one are free for use by the
143  * kernel debugging messages.
144  */
145 
146 /* Current row in the high-level console. Must be signed, because of
147    computations inside sos_screen_putchar() */
148 static int row;
149 
150 /* Current column in the high-level console. Must be signed, because
151    of computations inside sos_screen_putchar() */
152 static int col;
153 
154 /* The limit between the low-level console, accessible to the kernel,
155    and the high-level console, accessible to the user applications
156    through the sos_screen_putchar() function. */
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       /* Go to first row */
176       col = 0;
177     }
178 
179   /* New line */
180   else if (c == '\n')
181     {
182       /* Go to next line */
183       col = 0;
184       row ++;
185     }
186 
187   /* Remove the last character */
188   else if (c == '\b')
189     {
190       /* Next character should be displayed instead of the current
191          one */
192       col --;
193 
194       /* Handle the case where we're at the beginning of a line */
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       /* Replace the current character with a space */
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   /* Need to scroll ? */
224   if (row == LINES)
225     {
226       int i;
227 
228       /* Copy each line in the previous line */
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       /* Reset the last line of the console */
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   /* Set the first scan line for the cursor, and the blinking
255      mode. First scan line is 11, so that we have a visible
256      cursor. */
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 }

source navigation ] diff markup ] identifier search ] general search ]