OpenCores
URL https://opencores.org/ocsvn/layer2/layer2/trunk

Subversion Repositories layer2

[/] [layer2/] [trunk/] [sw/] [lib/] [stdio.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 idiolatrie
/******************************************************************************
2
 * Standard Input/Output                                                      *
3
 ******************************************************************************
4
 * Copyright (C)2011  Mathias Hörtnagl <mathias.hoertnagl@gmail.com>          *
5
 *                                                                            *
6
 * This program is free software: you can redistribute it and/or modify       *
7
 * it under the terms of the GNU General Public License as published by       *
8
 * the Free Software Foundation, either version 3 of the License, or          *
9
 * (at your option) any later version.                                        *
10
 *                                                                            *
11
 * This program is distributed in the hope that it will be useful,            *
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
14
 * GNU General Public License for more details.                               *
15
 *                                                                            *
16
 * You should have received a copy of the GNU General Public License          *
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
18
 ******************************************************************************/
19
#include "stddef.h"
20
#include "stdio.h"
21
#include "stdlib.h"
22
 
23
/* Current character and background color. */
24
static color col = {WHITE, BLACK};
25
 
26
/* Current cursor position. */
27
static cursor cur = {0, 0};
28
 
29
/* Current received key. */
30
static key ckey;
31
 
32
/* Input buffer. Holds INBUF_SIZE keyboard input characters. This variable is
33
   located in the *.bss section and thus all zero. Important for the termination
34
   character '\0' at position INBUF_SIZE. */
35
static uchar inbuf[INBUF_SIZE+1];
36
 
37
/* Buffer for all number to string converting functions: itoa, itox, itob */
38
static uchar bufc[35];
39
 
40
/******************************************************************************
41
 * Private Functions                                                          *
42
 ******************************************************************************/
43
/* Save cur.y--; */
44
static void decy() {
45
   if(cur.y > 0) cur.y--;
46
}
47
 
48
/* Save cur.x--; */
49
static void decx() {
50
   if(cur.x > 0) {
51
      cur.x--;
52
   }
53
   else {
54
      decy();
55
      cur.x = VGA_H-1;
56
   }
57
 
58
   // if(--cur.x < 0) {
59
      // decy();
60
      // cur.x = VGA_H-1;
61
   // }
62
}
63
 
64
/* Save cur.y++; */
65
static void incy() {
66
   if(++cur.y >= VGA_V) scroll();
67
}
68
 
69
/* Save cur.x++; */
70
static void incx() {
71
   if(++cur.x >= VGA_H) {
72
      incy();
73
      cur.x = 0;
74
   }
75
}
76
 
77
/******************************************************************************
78
 * Output Functions                                                           *
79
 ******************************************************************************/
80
/* Set text and background colors. */
81
void setcolor(uchar fg, uchar bg) {
82
   col.fg = fg;
83
   col.bg = bg;
84
}
85
 
86
 /* Set cursor at position x,y. */
87
void gotoxy(uchar x, uchar y) {
88
   if(x < 100) cur.x = x;
89
   if(y < 37)  cur.y = y;
90
}
91
 
92
/* Clears the entire display and resets the cursor. */
93
void cls() {
94
   for(int i=0; i < VGA_H * VGA_V; VGA_MEMORY[i++] = 0); // Clear display.
95
   cur.x = 0;                                            // Reset cursor.
96
   cur.y = 0;
97
}
98
 
99
/* Scrolls down one line and clears the lowest line. The vertical cursor jumps
100
   one line up, if not already on line one. If the cursor is on the first line
101
   the horizontal cursor is reset to zero. */
102
void scroll() {
103
 
104
   // Shift up content one line.
105
   for(int i=VGA_H; i < VGA_H * VGA_V; VGA_MEMORY[i-VGA_H] = VGA_MEMORY[i++]);
106
   // Clean up last line.
107
   for(int i=VGA_H * (VGA_V-1); i < VGA_H * VGA_V; VGA_MEMORY[i++] = 0);
108
   // Reposition cursor.
109
   if(cur.y == 0) cur.x = 0;  // On top line carrage return.
110
   decy();
111
}
112
 
113
/* Outputs a single character onto the screen. */
114
void putc(const uchar chr) {
115
   VGA_MEMORY[ VGA_POS(cur.x, cur.y) ] = VGA_CHR(col.fg, col.bg, chr);
116
   incx();
117
}
118
 
119
/* Print a string without it's trailing '\0' onto the screen. */
120
void puts(const uchar *str) {
121
   for(char *s = str; *s; putc(*s++));
122
}
123
 
124
/* Formatted string printig. The following parameters are available:
125
      +----+--------------------------------------------------+
126
      | %s | print a string                                   |
127
      | %c | print a single character                         |
128
      | %x | print a hexadecimal representation of an integer |
129
      | %b | print a binary representation of an intger       |
130
      | %% | print a '%'                                      |
131
      +----+--------------------------------------------------+
132
      +----+----------------+
133
      | \n | line break     |
134
      | \r | carrage return |
135
      | \t | tab space      |
136
      | \b | back space     |
137
      | \\ | print a '\'    |
138
      +----+----------------+
139
 
140
   Despite the standard printf implementation, you can manipulate the background
141
   and text colors:
142
      +----+---------+----+---------+----+---------+----+---------+
143
      | $k | black   | $b | blue    | $g | green   | $c | cyan    |
144
      | $r | red     | $m | magenta | $y | yellow  | $w | white   |
145
      +----+---------+----+---------+----+---------+----+---------+
146
        $$ - print a '$'
147
 
148
   The background colors can be specified the same way with a '#' as a format
149
   indicator. Besides the format string, the function takes only one value
150
   argunment. */
151
void printf(const uchar *format, void *arg) {
152
 
153
   char *f = format;
154
 
155
   for(char c; c = *f; f++) {
156
      switch(c) {
157
 
158
         // Argument format flags.
159
         case '%':
160
            switch( (c = *++f) ) {
161
               case '%': putc(c);                           break;
162
               case 's': puts( (uchar *) arg );             break;
163
               case 'c': putc( (uchar) arg );               break;
164
               case 'd': /*puts( itoa((int *) arg, bufc) );*/ break;
165
               case 'x': puts( itox((int *) arg, bufc) );   break;
166
               case 'b': puts( itob((int *) arg, bufc) );   break;
167
            }
168
            break;
169
 
170
         // Foreground color state arguments.
171
         case '$':
172
            switch( (c = *++f) ) {
173
               case '$': putc(c);            break;
174
               case 'k': col.fg = BLACK;     break;
175
               case 'b': col.fg = BLUE;      break;
176
               case 'g': col.fg = GREEN;     break;
177
               case 'c': col.fg = CYAN;      break;
178
               case 'r': col.fg = RED;       break;
179
               case 'm': col.fg = MAGENTA;   break;
180
               case 'y': col.fg = YELLOW;    break;
181
               case 'w': col.fg = WHITE;     break;
182
            }
183
            break;
184
 
185
         // Background color state arguments.
186
         case '#':
187
            switch( (c = *++f) ) {
188
               case '#': putc(c);            break;
189
               case 'k': col.bg = BLACK;     break;
190
               case 'b': col.bg = BLUE;      break;
191
               case 'g': col.bg = GREEN;     break;
192
               case 'c': col.bg = CYAN;      break;
193
               case 'r': col.bg = RED;       break;
194
               case 'm': col.bg = MAGENTA;   break;
195
               case 'y': col.bg = YELLOW;    break;
196
               case 'w': col.bg = WHITE;     break;
197
            }
198
            break;
199
 
200
         // Text layout flags.
201
         case '\\':
202
            putc(c);
203
            break;
204
         case '\n':
205
            incy();
206
            cur.x = 0;
207
            break;
208
         case '\r':
209
            cur.x = 0;
210
            break;
211
         case '\t':
212
            cur.x += 4; // ohohhhh
213
            cur.x &= ~3;
214
            break;
215
         case '\b':
216
            decx();
217
            break;
218
 
219
         default:
220
            putc(c);
221
            break;
222
      }
223
   }
224
}
225
 
226
/******************************************************************************
227
 * Input Functions                                                            *
228
 ******************************************************************************/
229
/* Polls for a singe character. The keyboard controller only sends make codes
230
   and postpones the read ack until a key is pressed. */
231
key* getc() {
232
 
233
   // Blocks until keyboard input is ready.
234
   uint k = KEYB_MEMORY[0];
235
 
236
   ckey.flags = k >> 4;
237
   ckey.chr = k;
238
   return &ckey;
239
}
240
 
241
/* Returns a string of at most INBUF_SIZE characters (without '\0'). The user
242
   can confirm the input with the enter button. */
243
uchar* gets() {
244
 
245
   int i=0;
246
   uchar chr;
247
 
248
   while( ((chr = getc()->chr) != KEY_ENTER) && (i < INBUF_SIZE) ) {
249
 
250
      if(chr == KEY_BACKSP) {
251
         // Go back no further than the start of the input.
252
         if(i > 0) {
253
            decx();
254
            // Undo last character.
255
            VGA_MEMORY[ VGA_POS(cur.x, cur.y) ] = 0;
256
            // Clear buffer.
257
            inbuf[i--] = '\0';
258
         }
259
      }
260
      else {
261
         putc(chr);
262
         inbuf[i++] = chr;
263
      }
264
   }
265
 
266
   // We do not need to terrminate the string if we ran out of buffer size
267
   // (i == INBUF_SZE), since it is by default zero and will not be altered.
268
   inbuf[i] = '\0';
269
   return inbuf;
270
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.