kern
view src/vid.c @ 46:b793b8fcba7d
apparently free_phys_page was never tested. the check for double-freeing a page
was inverted.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 28 Jul 2011 05:33:59 +0300 |
parents | eaec918de072 |
children |
line source
1 #include <string.h>
2 #include "vid.h"
3 #include "intr.h"
4 #include "asmops.h"
6 /* height of our virtual console text buffer */
7 #define VIRT_HEIGHT 200
9 /* CRTC ports */
10 #define CRTC_ADDR 0x3d4
11 #define CRTC_DATA 0x3d5
13 /* CRTC registers */
14 #define CRTC_START_HIGH 0xc
15 #define CRTC_START_LOW 0xd
16 #define CRTC_CURSOR_HIGH 0xe
17 #define CRTC_CURSOR_LOW 0xf
19 /* construct a character with its attributes */
20 #define VMEM_CHAR(c, fg, bg) \
21 ((uint16_t)(c) | (((uint16_t)(fg) & 0xf) << 8) | (((uint16_t)(bg) & 0xf) << 12))
23 static void set_start_line(int line);
25 static uint16_t *vmem = (uint16_t*)0xb8000;
26 static int start_line;
29 void clear_scr(void)
30 {
31 int istate = get_intr_state();
32 disable_intr();
34 memset16(vmem, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH * HEIGHT);
35 start_line = 0;
36 set_start_line(0);
37 set_cursor(0, 0);
39 set_intr_state(istate);
40 }
42 void set_char(char c, int x, int y, int fg, int bg)
43 {
44 vmem[(y + start_line) * WIDTH + x] = VMEM_CHAR(c, fg, bg);
45 }
47 void set_cursor(int x, int y)
48 {
49 int loc;
50 int istate = get_intr_state();
51 disable_intr();
53 if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
54 loc = 0xffff;
55 } else {
56 loc = (y + start_line) * WIDTH + x;
57 }
59 outb(CRTC_CURSOR_LOW, CRTC_ADDR);
60 outb(loc, CRTC_DATA);
61 outb(CRTC_CURSOR_HIGH, CRTC_ADDR);
62 outb(loc >> 8, CRTC_DATA);
64 set_intr_state(istate);
65 }
67 void scroll_scr(void)
68 {
69 int new_line, istate = get_intr_state();
70 disable_intr();
72 if(++start_line > VIRT_HEIGHT - HEIGHT) {
73 /* The bottom of the visible range reached the end of our text buffer.
74 * Copy the rest of the lines to the top and reset start_line.
75 */
76 memcpy(vmem, vmem + start_line * WIDTH, (HEIGHT - 1) * WIDTH * 2);
77 start_line = 0;
78 }
80 /* clear the next line that will be revealed by scrolling */
81 new_line = start_line + HEIGHT - 1;
82 memset16(vmem + new_line * WIDTH, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH);
83 set_start_line(start_line);
85 set_intr_state(istate);
86 }
88 static void set_start_line(int line)
89 {
90 int start_addr = line * WIDTH;
92 outb(CRTC_START_LOW, CRTC_ADDR);
93 outb(start_addr & 0xff, CRTC_DATA);
94 outb(CRTC_START_HIGH, CRTC_ADDR);
95 outb((start_addr >> 8) & 0xff, CRTC_DATA);
96 }