Rev 4339 | Rev 4342 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4339 | Rev 4341 | ||
|---|---|---|---|
| Line 182... | Line 182... | ||
| 182 | 182 | ||
| 183 | 183 | ||
| 184 | /** Hide logo and refresh screen |
184 | /** Hide logo and refresh screen |
| 185 | * |
185 | * |
| 186 | */ |
186 | */ |
| 187 | static void logo_hide(void) |
187 | static void logo_hide(bool silent) |
| 188 | { |
188 | { |
| 189 | ylogo = 0; |
189 | ylogo = 0; |
| 190 | ytrim = yres; |
190 | ytrim = yres; |
| 191 | rowtrim = rows; |
191 | rowtrim = rows; |
| - | 192 | if (!silent) |
|
| 192 | fb_redraw(); |
193 | fb_redraw(); |
| 193 | } |
194 | } |
| 194 | 195 | ||
| 195 | 196 | ||
| 196 | /** Draw character at given position |
197 | /** Draw character at given position |
| 197 | * |
198 | * |
| 198 | */ |
199 | */ |
| 199 | static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row) |
200 | static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
| 200 | { |
201 | { |
| 201 | unsigned int x = COL2X(col); |
202 | unsigned int x = COL2X(col); |
| 202 | unsigned int y = ROW2Y(row); |
203 | unsigned int y = ROW2Y(row); |
| 203 | unsigned int yd; |
204 | unsigned int yd; |
| 204 | 205 | ||
| 205 | if (y >= ytrim) |
206 | if (y >= ytrim) |
| 206 | logo_hide(); |
207 | logo_hide(silent); |
| 207 | 208 | ||
| 208 | backbuf[BB_POS(col, row)] = glyph; |
209 | backbuf[BB_POS(col, row)] = glyph; |
| 209 | 210 | ||
| - | 211 | if (!silent) { |
|
| 210 | for (yd = 0; yd < FONT_SCANLINES; yd++) |
212 | for (yd = 0; yd < FONT_SCANLINES; yd++) |
| 211 | memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
213 | memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
| 212 | &glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
214 | &glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
| - | 215 | } |
|
| 213 | } |
216 | } |
| 214 | 217 | ||
| 215 | 218 | ||
| 216 | /** Scroll screen down by one row |
219 | /** Scroll screen down by one row |
| 217 | * |
220 | * |
| 218 | * |
221 | * |
| 219 | */ |
222 | */ |
| 220 | static void screen_scroll(void) |
223 | static void screen_scroll(bool silent) |
| 221 | { |
224 | { |
| 222 | if (ylogo > 0) { |
225 | if (ylogo > 0) { |
| 223 | logo_hide(); |
226 | logo_hide(silent); |
| 224 | return; |
227 | return; |
| 225 | } |
228 | } |
| 226 | 229 | ||
| 227 | unsigned int row; |
230 | if (!silent) { |
| 228 | - | ||
| 229 | for (row = 0; row < rows; row++) { |
- | |
| 230 | unsigned int y = ROW2Y(row); |
- | |
| 231 | unsigned int yd; |
231 | unsigned int row; |
| 232 | 232 | ||
| 233 | for (yd = 0; yd < FONT_SCANLINES; yd++) { |
233 | for (row = 0; row < rows; row++) { |
| 234 | unsigned int x; |
234 | unsigned int y = ROW2Y(row); |
| 235 | unsigned int col; |
235 | unsigned int yd; |
| 236 | 236 | ||
| 237 | for (col = 0, x = 0; col < cols; col++, |
237 | for (yd = 0; yd < FONT_SCANLINES; yd++) { |
| 238 | x += FONT_WIDTH) { |
238 | unsigned int x; |
| 239 | uint8_t glyph; |
239 | unsigned int col; |
| 240 | 240 | ||
| 241 | if (row < rows - 1) { |
- | |
| 242 | if (backbuf[BB_POS(col, row)] == |
241 | for (col = 0, x = 0; col < cols; col++, |
| 243 | backbuf[BB_POS(col, row + 1)]) |
242 | x += FONT_WIDTH) { |
| 244 | continue; |
243 | uint8_t glyph; |
| 245 | 244 | ||
| - | 245 | if (row < rows - 1) { |
|
| - | 246 | if (backbuf[BB_POS(col, row)] == |
|
| - | 247 | backbuf[BB_POS(col, row + 1)]) |
|
| - | 248 | continue; |
|
| - | 249 | ||
| 246 | glyph = backbuf[BB_POS(col, row + 1)]; |
250 | glyph = backbuf[BB_POS(col, row + 1)]; |
| 247 | } else |
251 | } else |
| 248 | glyph = 0; |
252 | glyph = 0; |
| 249 | 253 | ||
| 250 | memcpy(&fb_addr[FB_POS(x, y + yd)], |
254 | memcpy(&fb_addr[FB_POS(x, y + yd)], |
| 251 | &glyphs[GLYPH_POS(glyph, yd)], |
255 | &glyphs[GLYPH_POS(glyph, yd)], |
| 252 | glyphscanline); |
256 | glyphscanline); |
| - | 257 | } |
|
| 253 | } |
258 | } |
| 254 | } |
259 | } |
| 255 | } |
260 | } |
| 256 | 261 | ||
| 257 | memmove(backbuf, backbuf + cols, cols * (rows - 1)); |
262 | memmove(backbuf, backbuf + cols, cols * (rows - 1)); |
| 258 | memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
263 | memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
| 259 | } |
264 | } |
| 260 | 265 | ||
| 261 | 266 | ||
| 262 | static void cursor_put(void) |
267 | static void cursor_put(bool silent) |
| 263 | { |
268 | { |
| 264 | glyph_draw(CURSOR, position % cols, position / cols); |
269 | glyph_draw(CURSOR, position % cols, position / cols, silent); |
| 265 | } |
270 | } |
| 266 | 271 | ||
| 267 | 272 | ||
| 268 | static void cursor_remove(void) |
273 | static void cursor_remove(bool silent) |
| 269 | { |
274 | { |
| 270 | glyph_draw(0, position % cols, position / cols); |
275 | glyph_draw(0, position % cols, position / cols, silent); |
| 271 | } |
276 | } |
| 272 | 277 | ||
| 273 | 278 | ||
| 274 | /** Print character to screen |
279 | /** Print character to screen |
| 275 | * |
280 | * |
| 276 | * Emulate basic terminal commands. |
281 | * Emulate basic terminal commands. |
| 277 | * |
282 | * |
| 278 | */ |
283 | */ |
| 279 | static void fb_putchar(chardev_t *dev, char ch) |
284 | static void fb_putchar(chardev_t *dev, char ch, bool silent) |
| 280 | { |
285 | { |
| 281 | spinlock_lock(&fb_lock); |
286 | spinlock_lock(&fb_lock); |
| 282 | 287 | ||
| 283 | switch (ch) { |
288 | switch (ch) { |
| 284 | case '\n': |
289 | case '\n': |
| 285 | cursor_remove(); |
290 | cursor_remove(silent); |
| 286 | position += cols; |
291 | position += cols; |
| 287 | position -= position % cols; |
292 | position -= position % cols; |
| 288 | break; |
293 | break; |
| 289 | case '\r': |
294 | case '\r': |
| 290 | cursor_remove(); |
295 | cursor_remove(silent); |
| 291 | position -= position % cols; |
296 | position -= position % cols; |
| 292 | break; |
297 | break; |
| 293 | case '\b': |
298 | case '\b': |
| 294 | cursor_remove(); |
299 | cursor_remove(silent); |
| 295 | if (position % cols) |
300 | if (position % cols) |
| 296 | position--; |
301 | position--; |
| 297 | break; |
302 | break; |
| 298 | case '\t': |
303 | case '\t': |
| 299 | cursor_remove(); |
304 | cursor_remove(silent); |
| 300 | do { |
305 | do { |
| 301 | glyph_draw((uint8_t) ' ', position % cols, |
306 | glyph_draw((uint8_t) ' ', position % cols, |
| 302 | position / cols); |
307 | position / cols, silent); |
| 303 | position++; |
308 | position++; |
| 304 | } while ((position % 8) && (position < cols * rows)); |
309 | } while ((position % 8) && (position < cols * rows)); |
| 305 | break; |
310 | break; |
| 306 | default: |
311 | default: |
| 307 | glyph_draw((uint8_t) ch, position % cols, position / cols); |
312 | glyph_draw((uint8_t) ch, position % cols, |
| - | 313 | position / cols, silent); |
|
| 308 | position++; |
314 | position++; |
| 309 | } |
315 | } |
| 310 | 316 | ||
| 311 | if (position >= cols * rows) { |
317 | if (position >= cols * rows) { |
| 312 | position -= cols; |
318 | position -= cols; |
| 313 | screen_scroll(); |
319 | screen_scroll(silent); |
| 314 | } |
320 | } |
| 315 | 321 | ||
| 316 | cursor_put(); |
322 | cursor_put(silent); |
| 317 | 323 | ||
| 318 | spinlock_unlock(&fb_lock); |
324 | spinlock_unlock(&fb_lock); |
| 319 | } |
325 | } |
| 320 | 326 | ||
| 321 | static chardev_t framebuffer; |
327 | static chardev_t framebuffer; |