kern

view src/vid.c @ 80:4db99a52863e

fixed the "endianess" of the text messages in the ATA identify info block. this is the first time I've seen wrong byteorder in ascii text, the ATA committee should be commended.
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 06 Dec 2011 13:35:39 +0200
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 }