kern
view src/vid.c @ 7:611b2d66420b
segment descriptors
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 16 Feb 2011 07:26:03 +0200 |
parents | 86781ef20689 |
children | eaec918de072 |
line source
1 #include <string.h>
2 #include "vid.h"
3 #include "asmops.h"
5 /* height of our virtual console text buffer */
6 #define VIRT_HEIGHT 1024
8 /* CRTC ports */
9 #define CRTC_ADDR 0x3d4
10 #define CRTC_DATA 0x3d5
12 /* CRTC registers */
13 #define CRTC_START_HIGH 0xc
14 #define CRTC_START_LOW 0xd
15 #define CRTC_CURSOR_HIGH 0xe
16 #define CRTC_CURSOR_LOW 0xf
18 /* construct a character with its attributes */
19 #define VMEM_CHAR(c, fg, bg) \
20 ((uint16_t)(c) | (((uint16_t)(fg) & 0xf) << 8) | (((uint16_t)(bg) & 0xf) << 12))
22 static void set_start_line(int line);
24 static uint16_t *vmem = (uint16_t*)0xb8000;
25 static int start_line;
28 void clear_scr(void)
29 {
30 memset16(vmem, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH * HEIGHT);
31 start_line = 0;
32 set_start_line(0);
33 set_cursor(0, 0);
34 }
36 void set_char(char c, int x, int y, int fg, int bg)
37 {
38 vmem[(y + start_line) * WIDTH + x] = VMEM_CHAR(c, fg, bg);
39 }
41 void set_cursor(int x, int y)
42 {
43 int loc;
45 if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
46 loc = 0xffff;
47 } else {
48 loc = (y + start_line) * WIDTH + x;
49 }
51 outb(CRTC_CURSOR_LOW, CRTC_ADDR);
52 outb(loc, CRTC_DATA);
53 outb(CRTC_CURSOR_HIGH, CRTC_ADDR);
54 outb(loc >> 8, CRTC_DATA);
55 }
57 void scroll_scr(void)
58 {
59 if(++start_line > VIRT_HEIGHT - HEIGHT) {
60 /* The bottom of the visible range reached the end of our text buffer.
61 * Copy the rest of the lines to the top and reset start_line.
62 */
63 memcpy(vmem, vmem + start_line * WIDTH, (HEIGHT - 1) * WIDTH);
64 start_line = 0;
65 }
67 /* clear the next line that will be revealed by scrolling */
68 int new_line = start_line + HEIGHT - 1;
69 memset16(vmem + new_line * WIDTH, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH);
71 set_start_line(start_line);
72 }
74 static void set_start_line(int line)
75 {
76 int start_addr = line * WIDTH;
78 outb(CRTC_START_LOW, CRTC_ADDR);
79 outb(start_addr & 0xff, CRTC_DATA);
80 outb(CRTC_START_HIGH, CRTC_ADDR);
81 outb((start_addr >> 8) & 0xff, CRTC_DATA);
82 }