linker.ld: use all .data* and .bss* sections
[marionette.git] / kernel / console.c
bloba89b922f50e14c9fcec77d3f5af7f90afc78e5d5
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 console tty1;
35 // get position of the hardware cursor
36 static void get_hw_cursor(struct console *self)
38 unsigned int tmp;
39 outb(0x3D4, 14);
40 tmp = inb(0x3D5) << 8;
41 outb(0x3D4, 15);
42 tmp |= inb(0x3D5);
43 self->y = tmp / self->width;
44 self->x = tmp % self->width;
47 // set position of the hardware cursor
48 static void set_hw_cursor(struct console *self, int x, int y)
50 unsigned int tmp;
51 tmp = y * self->width + x;
52 outb(0x3D4, 14);
53 outb(0x3D5, tmp >> 8);
54 outb(0x3D4, 15);
55 outb(0x3D5, tmp);
58 // scroll up n lines
59 static void scroll(struct console *self, int n)
61 unsigned short p;
62 // Move everything up
63 memmove(self->vram,
64 self->vram + n * self->width,
65 self->width * (self->height - n) * sizeof *self->vram);
66 // Clear the bottom
67 for (p = self->width * (self->height - n)
68 ; p < (self->height * self->width); p++){
69 *(self->vram + p) = (self->attrib << 8) | ' ';
71 self->y -= n;
74 // process a newline
75 static void newline(struct console *self)
77 self->x = 0;
78 self->y++;
79 if (self->y >= self->height){
80 scroll(self, self->y + 1 - self->height);
84 // process a backspace
85 static void backspace(struct console *self)
87 if (self->x == 0)
88 return;
89 self->x--;
90 self->vram[self->y * self->width + self->x] = (self->attrib << 8) | ' ';
93 // handle special characters
94 static void special_chars(struct console *self, char ch)
96 if (ch == '\n'){
97 newline(self);
98 } else if (ch == '\b'){
99 backspace(self);
100 } else {
101 console_printf(self, "\n*** TODO: Implement character %.8X\n", ch);
105 void console_init(struct console *self)
107 self->vram = (unsigned short *) 0x000B8000;
108 self->width = 80;
109 self->height = 25;
110 get_hw_cursor(self);
111 self->attrib = 0x07; // white on black
114 void console_clear(struct console *self)
116 int i;
117 for (i=0; i<(self->width * self->height); i++)
118 self->vram[i] = (self->attrib << 8) | ' ';
121 void console_colour_default(struct console *self)
123 self->attrib = 0x07;
126 void console_colour_fg(struct console *self, int fg)
128 self->attrib = (self->attrib & ~0xF) | fg;
131 void console_colour_fgbg(struct console *self, int fg, int bg)
133 self->attrib = (bg << 4) | fg;
136 void console_putchar(struct console *self, char ch)
138 if (ch < ' ' || ch == 0x7F){
139 special_chars(self, ch);
140 } else {
141 if (self->y >= self->height){
142 scroll(self, self->y + 1 - self->height);
144 self->vram[self->y * self->width + self->x] = (self->attrib << 8) | ch;
145 self->x++;
146 if (self->x == self->width){
147 newline(self);
152 void console_puts(struct console *self, const char *str)
154 while (*str){
155 console_putchar(self, *str);
156 str++;
158 set_hw_cursor(self, self->x, self->y);
161 void console_printf(struct console *self, const char *fmt, ...)
163 va_list ap;
164 va_start(ap, fmt);
165 console_vprintf(self, fmt, ap);
166 va_end(ap);
169 void console_vprintf(struct console *self, const char *fmt, va_list ap)
171 char buf[256]; // should be enough for anyone :)
172 vsnprintf(buf, 255, fmt, ap);
173 console_puts(self, buf);