kern

annotate 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
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 }