Fixed uninitialised n_chunks in untested vpcreate
[marionette.git] / kernel / console.c
blob3bce7a5aa09b14e3dae3f2e96b40068ea426d433
1 /*
2 * Copyright (c) 2008 Joshua Phillips. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
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
13 * distribution.
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.
28 #include "console.h"
29 #include "portio.h"
30 #include "string.h"
31 #include "stdio.h"
33 struct cdev_tty {
34 struct cdev cdev;
37 static int tty_write(struct cdev *cdev, void *ptr, size_t count);
39 static const struct cdev_ops tty_ops = {
40 tty_write,
43 struct cdev_tty _dev_tty1 = {
44 { &tty_ops, },
47 struct cdev *const dev_tty1 = &_dev_tty1.cdev;
49 static int tty_write(struct cdev *cdev, void *ptr, size_t count)
51 char *c_ptr = ptr;
52 int i;
53 for (i=0; i<count; ++i){
54 console_putchar(&tty1, *c_ptr++);
56 return count;
59 struct console tty1;
61 // get position of the hardware cursor
62 static void get_hw_cursor(struct console *self)
64 unsigned int tmp;
65 outb(0x3D4, 14);
66 tmp = inb(0x3D5) << 8;
67 outb(0x3D4, 15);
68 tmp |= inb(0x3D5);
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)
76 unsigned int tmp;
77 tmp = y * self->width + x;
78 outb(0x3D4, 14);
79 outb(0x3D5, tmp >> 8);
80 outb(0x3D4, 15);
81 outb(0x3D5, tmp);
84 // scroll up n lines
85 static void scroll(struct console *self, int n)
87 unsigned short p;
88 // Move everything up
89 memmove(self->vram,
90 self->vram + n * self->width,
91 self->width * (self->height - n) * sizeof *self->vram);
92 // Clear the bottom
93 for (p = self->width * (self->height - n)
94 ; p < (self->height * self->width); p++){
95 *(self->vram + p) = (self->attrib << 8) | ' ';
97 self->y -= n;
100 // process a newline
101 static void newline(struct console *self)
103 self->x = 0;
104 self->y++;
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)
113 if (self->x == 0)
114 return;
115 self->x--;
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)
122 if (ch == '\n'){
123 newline(self);
124 } else if (ch == '\b'){
125 backspace(self);
126 } else {
127 console_printf(self, "\n*** TODO: Implement character %.8X\n", ch);
131 void console_init(struct console *self)
133 self->vram = (unsigned short *) 0x000B8000;
134 self->width = 80;
135 self->height = 25;
136 get_hw_cursor(self);
137 self->attrib = 0x07; // white on black
140 void console_clear(struct console *self)
142 int i;
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)
149 self->attrib = 0x07;
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);
166 } else {
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;
171 self->x++;
172 if (self->x == self->width){
173 newline(self);
178 void console_puts(struct console *self, const char *str)
180 while (*str){
181 console_putchar(self, *str);
182 str++;
184 set_hw_cursor(self, self->x, self->y);
187 void console_printf(struct console *self, const char *fmt, ...)
189 va_list ap;
190 va_start(ap, fmt);
191 console_vprintf(self, fmt, ap);
192 va_end(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);