kern

annotate src/vid.c @ 41:928b0ebfff4d

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