rudimentary console
[3sys] / sys1 / kern / src / con.c
1 #include <string.h>
2 #include "con.h"
3 #include "vga.h"
4
5 #define NCOLS                   80
6 #define NROWS                   25
7
8 /* must be pow2 */
9 #define TEXTBUF_SIZE    256
10
11 static char textbuf[TEXTBUF_SIZE][NCOLS];
12 static int tbuf_first, tbuf_last;
13
14 static int curx, cury, scroll;
15
16
17 static void newline(void);
18
19
20 void con_init(void)
21 {
22         con_reset();
23 }
24
25 void con_reset(void)
26 {
27         vga_reset();
28
29         curx = cury = scroll = 0;
30         tbuf_first = tbuf_last = 0;
31         memset(textbuf[0], 0, sizeof textbuf[0]);
32 }
33
34 void con_putchar(int c)
35 {
36         switch(c) {
37         case '\t':
38                 curx = (curx + 8) & 0xfffffff8;
39                 if(curx >= NCOLS) {
40                         newline();
41                 }
42                 break;
43
44         case '\r':
45                 curx = 0;
46                 break;
47
48         case '\n':
49                 newline();
50                 break;
51
52         case '\b':
53                 if(curx > 0) {
54                         textbuf[tbuf_last][--curx] = 0;
55                         vga_drawchar(curx, cury, 0);
56                 }
57                 break;
58
59         default:
60                 textbuf[tbuf_last][curx] = c;
61                 vga_drawchar(curx, cury, c);
62                 if(++curx >= NCOLS) {
63                         newline();
64                 }
65                 break;
66         }
67
68         if(cury >= NROWS) {
69                 cury--;
70                 vga_scroll(++scroll);
71                 vga_clearline(NROWS - 1);
72         }
73
74         vga_setcursor(curx, cury);
75 }
76
77 static void newline(void)
78 {
79         int num;
80
81         curx = 0;
82         cury++;
83
84         num = (tbuf_last + 1) & (TEXTBUF_SIZE - 1);
85
86         if(tbuf_last == tbuf_first) {
87                 tbuf_first = num;
88         }
89         tbuf_last = num;
90 }