2 * Copyright (c) 2008 Joshua Phillips. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 static int tty_write(struct cdev
*cdev
, void *ptr
, size_t count
);
39 static const struct cdev_ops tty_ops
= {
43 struct cdev_tty _dev_tty1
= {
47 struct cdev
*const dev_tty1
= &_dev_tty1
.cdev
;
49 static int tty_write(struct cdev
*cdev
, void *ptr
, size_t count
)
53 for (i
=0; i
<count
; ++i
){
54 console_putchar(&tty1
, *c_ptr
++);
61 // get position of the hardware cursor
62 static void get_hw_cursor(struct console
*self
)
66 tmp
= inb(0x3D5) << 8;
69 self
->y
= tmp
/ self
->width
;
70 self
->x
= tmp
% self
->width
;
73 // set position of the hardware cursor
74 static void set_hw_cursor(struct console
*self
, int x
, int y
)
77 tmp
= y
* self
->width
+ x
;
79 outb(0x3D5, tmp
>> 8);
85 static void scroll(struct console
*self
, int n
)
90 self
->vram
+ n
* self
->width
,
91 self
->width
* (self
->height
- n
) * sizeof *self
->vram
);
93 for (p
= self
->width
* (self
->height
- n
)
94 ; p
< (self
->height
* self
->width
); p
++){
95 *(self
->vram
+ p
) = (self
->attrib
<< 8) | ' ';
101 static void newline(struct console
*self
)
105 if (self
->y
>= self
->height
){
106 scroll(self
, self
->y
+ 1 - self
->height
);
110 // process a backspace
111 static void backspace(struct console
*self
)
116 self
->vram
[self
->y
* self
->width
+ self
->x
] = (self
->attrib
<< 8) | ' ';
119 // handle special characters
120 static void special_chars(struct console
*self
, char ch
)
124 } else if (ch
== '\b'){
127 console_printf(self
, "\n*** TODO: Implement character %.8X\n", ch
);
131 void console_init(struct console
*self
)
133 self
->vram
= (unsigned short *) 0x000B8000;
137 self
->attrib
= 0x07; // white on black
140 void console_clear(struct console
*self
)
143 for (i
=0; i
<(self
->width
* self
->height
); i
++)
144 self
->vram
[i
] = (self
->attrib
<< 8) | ' ';
147 void console_colour_default(struct console
*self
)
152 void console_colour_fg(struct console
*self
, int fg
)
154 self
->attrib
= (self
->attrib
& ~0xF) | fg
;
157 void console_colour_fgbg(struct console
*self
, int fg
, int bg
)
159 self
->attrib
= (bg
<< 4) | fg
;
162 void console_putchar(struct console
*self
, char ch
)
164 if (ch
< ' ' || ch
== 0x7F){
165 special_chars(self
, ch
);
167 if (self
->y
>= self
->height
){
168 scroll(self
, self
->y
+ 1 - self
->height
);
170 self
->vram
[self
->y
* self
->width
+ self
->x
] = (self
->attrib
<< 8) | ch
;
172 if (self
->x
== self
->width
){
178 void console_puts(struct console
*self
, const char *str
)
181 console_putchar(self
, *str
);
184 set_hw_cursor(self
, self
->x
, self
->y
);
187 void console_printf(struct console
*self
, const char *fmt
, ...)
191 console_vprintf(self
, fmt
, ap
);
195 void console_vprintf(struct console
*self
, const char *fmt
, va_list ap
)
197 char buf
[256]; // should be enough for anyone :)
198 vsnprintf(buf
, 255, fmt
, ap
);
199 console_puts(self
, buf
);