Makefile: add .c files as prerequisites where needed
[glg-os.git] / terminal.c
blob647f38f62cc255ab177c248b3b48f65e1434eddf
1 /* terminal.c
3 * module for graphical output on the terminal
4 *********************************************/
6 #include <stddef.h>
7 #include <stdint.h>
8 #include "terminal.h"
9 #include "utils.h"
11 typedef struct {
12 size_t MAX_HEIGHT;
13 size_t MAX_WIDTH;
14 size_t row;
15 size_t column;
16 VGAColor color;
17 uint16_t *buffer;
18 } Terminal;
20 Terminal term;
22 static uint8_t mkcolor(uint8_t fg, uint8_t bg);
23 static uint16_t mkVGAentry(char c, uint8_t color);
24 static void putCharAt(char c, uint8_t color, size_t i, size_t j);
25 static void mvcursor();
26 static void newline();
27 static void scroll1();
29 /* clear the terminal */
30 void term_clear(void)
32 term.row = 0;
33 term.column = 0;
35 for(size_t i = 0; i < term.MAX_HEIGHT; i++) {
36 for(size_t j = 0; j < term.MAX_WIDTH; j++) {
37 const size_t k = i * term.MAX_WIDTH + j;
38 term.buffer[k] = mkVGAentry(' ', term.color);
44 /* initialize terminal to default values and draw all entries */
45 void term_init(size_t max_width, size_t max_height, uint8_t fg, uint8_t bg)
47 term.MAX_HEIGHT = max_height;
48 term.MAX_WIDTH = max_width;
49 term.row = 0;
50 term.column = 0;
51 term.color = mkcolor(fg,bg);
52 term.buffer = (uint16_t*) 0xB8000;
54 for(size_t i = 0; i < max_height; i++) {
55 for(size_t j = 0; j < max_width; j++) {
56 const size_t k = i * max_width + j;
57 term.buffer[k] = mkVGAentry(' ', term.color);
62 /* draw char using current term settings, and update cursor position */
63 void term_putChar(char c)
65 if(c == '\n') {
66 newline();
67 } else {
68 putCharAt(c,term.color,term.column, term.row);
69 mvcursor();
74 void term_putStr(const char *str)
76 size_t len = strlen(str);
77 for(size_t i = 0; i < len; i++)
78 term_putChar(str[i]);
81 void term_setcolor(uint8_t fg, uint8_t bg)
83 term.color = mkcolor(fg,bg);
86 /*** static functions ***/
88 /* return color suitable for drawing on terminal */
89 uint8_t mkcolor(uint8_t fg, uint8_t bg)
91 return fg | bg << 4;
94 /* create an entry for drawing */
95 uint16_t mkVGAentry(char c, uint8_t color)
97 uint16_t c16 = c;
98 uint16_t color16 = color;
99 return c16 | color16 << 8;
102 /* draw entry at specified position */
103 void putCharAt(char c, uint8_t color, size_t i, size_t j)
105 const size_t k = j * term.MAX_WIDTH + i;
106 term.buffer[k] = mkVGAentry(c,color);
109 void mvcursor()
111 if(++term.column == term.MAX_WIDTH)
112 newline();
115 void newline() {
116 term.column = 0;
117 if(term.row + 1 == term.MAX_HEIGHT)
118 scroll1();
119 else
120 ++term.row;
123 void scroll1()
125 for(size_t i = 0; i < term.MAX_HEIGHT - 1; i++) {
126 for(size_t j = 0; j < term.MAX_WIDTH; j++) {
127 const size_t k1 = i * term.MAX_WIDTH + j;
128 const size_t k2 = (i+1) * term.MAX_WIDTH + j;
129 term.buffer[k1] = term.buffer[k2];
133 for(size_t j = 0; j < term.MAX_WIDTH; j++) {
134 const size_t k = (term.MAX_HEIGHT - 1) * term.MAX_WIDTH + j;
135 term.buffer[k] = mkVGAentry(' ', term.color);