kern

annotate src/vid.c @ 33:373a9f50b4e6

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