kern

diff src/vid.c @ 2:86781ef20689

added hardware scrolling, memset16 and temporary keyboard input for testing
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 04 Dec 2010 08:04:43 +0200
parents ebe5e0e44a9d
children 0489a34ab348
line diff
     1.1 --- a/src/vid.c	Thu Dec 02 08:45:41 2010 +0200
     1.2 +++ b/src/vid.c	Sat Dec 04 08:04:43 2010 +0200
     1.3 @@ -1,24 +1,145 @@
     1.4 +#if 0
     1.5 +
     1.6  #include <string.h>
     1.7  #include "vid.h"
     1.8 +#include "asmops.h"
     1.9 +
    1.10 +/* height of our virtual console text buffer */
    1.11 +#define VIRT_HEIGHT	1024
    1.12 +
    1.13 +/* CRTC ports */
    1.14 +#define CRTC_ADDR	0x3d4
    1.15 +#define CRTC_DATA	0x3d5
    1.16 +
    1.17 +/* CRTC registers */
    1.18 +#define CRTC_START_HIGH		0xc
    1.19 +#define CRTC_START_LOW		0xd
    1.20 +#define CRTC_CURSOR_HIGH	0xe
    1.21 +#define CRTC_CURSOR_LOW		0xf
    1.22 +
    1.23 +/* construct a character with its attributes */
    1.24 +#define VMEM_CHAR(c, fg, bg) \
    1.25 +	((uint16_t)(c) | (((uint16_t)(fg) & 0xf) << 8) | (((uint16_t)(bg) & 0xf) << 12))
    1.26 +
    1.27 +static void set_start_line(int line);
    1.28  
    1.29  static uint16_t *vmem = (uint16_t*)0xb8000;
    1.30 +static int start_line;
    1.31  
    1.32 -void clear_scr(int color)
    1.33 +
    1.34 +void clear_scr(void)
    1.35  {
    1.36 -	memset(vmem, 0, WIDTH * HEIGHT * 2);
    1.37 +	memset16(vmem, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH * HEIGHT);
    1.38 +	start_line = 0;
    1.39 +	set_start_line(0);
    1.40 +	set_cursor(0, 0);
    1.41  }
    1.42  
    1.43  void set_char(char c, int x, int y, int fg, int bg)
    1.44  {
    1.45 -	uint16_t attr = (fg & 0xf) | ((bg & 7) << 4);
    1.46 -	vmem[y * WIDTH + x] = (uint16_t)c | (attr << 8);
    1.47 +	vmem[(y + start_line) * WIDTH + x] = VMEM_CHAR(c, fg, bg);
    1.48 +}
    1.49 +
    1.50 +void set_cursor(int x, int y)
    1.51 +{
    1.52 +	int loc;
    1.53 +
    1.54 +	if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
    1.55 +		loc = 0xffff;
    1.56 +	} else {
    1.57 +		loc = (y + start_line) * WIDTH + x;
    1.58 +	}
    1.59 +
    1.60 +	outb(CRTC_CURSOR_LOW, CRTC_ADDR);
    1.61 +	outb(loc, CRTC_DATA);
    1.62 +	outb(CRTC_CURSOR_HIGH, CRTC_ADDR);
    1.63 +	outb(loc >> 8, CRTC_DATA);
    1.64  }
    1.65  
    1.66  void scroll_scr(void)
    1.67  {
    1.68 -	/* copy the second up to last text line, one line back, then
    1.69 -	 * clear the last line.
    1.70 -	 */
    1.71 -	memmove(vmem, vmem + WIDTH, WIDTH * (HEIGHT - 1) * 2);
    1.72 -	memset(vmem + WIDTH * (HEIGHT -1), 0, WIDTH * 2);
    1.73 +	if(++start_line > VIRT_HEIGHT - HEIGHT) {
    1.74 +		/* The bottom of the visible range reached the end of our text buffer.
    1.75 +		 * Copy the rest of the lines to the top and reset start_line.
    1.76 +		 */
    1.77 +		memcpy(vmem, vmem + start_line * WIDTH, (HEIGHT - 1) * WIDTH);
    1.78 +		start_line = 0;
    1.79 +	}
    1.80 +
    1.81 +	/* clear the next line that will be revealed by scrolling */
    1.82 +	int new_line = start_line + HEIGHT - 1;
    1.83 +	memset16(vmem + new_line * WIDTH, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH);
    1.84 +
    1.85 +	set_start_line(start_line);
    1.86  }
    1.87 +
    1.88 +static void set_start_line(int line)
    1.89 +{
    1.90 +	int start_addr = line * WIDTH;
    1.91 +
    1.92 +	outb(CRTC_START_LOW, CRTC_ADDR);
    1.93 +	outb(start_addr & 0xff, CRTC_DATA);
    1.94 +	outb(CRTC_START_HIGH, CRTC_ADDR);
    1.95 +	outb((start_addr >> 8) & 0xff, CRTC_DATA);
    1.96 +}
    1.97 +#endif	/* 0 */
    1.98 +
    1.99 +#include <string.h>
   1.100 +#include "vid.h"
   1.101 +#include "asmops.h"
   1.102 +
   1.103 +#define WIDTH 80
   1.104 +#define HEIGHT 25
   1.105 +
   1.106 +/* CRTC ports */
   1.107 +#define CRTC_ADDR   0x3d4
   1.108 +#define CRTC_DATA   0x3d5
   1.109 +
   1.110 +/* CRTC registers */
   1.111 +#define CRTC_CURSOR_HIGH 0xe
   1.112 +#define CRTC_CURSOR_LOW  0xf
   1.113 +
   1.114 +/* construct a character with its attributes */
   1.115 +#define VMEM_CHAR(c, fg, bg) \
   1.116 +    ((uint16_t)(c) | (((uint16_t)(fg) & 0xf) << 8) | \
   1.117 +     (((uint16_t)(bg) & 0xf) << 12))
   1.118 +
   1.119 +#define CLEAR_CHAR	VMEM_CHAR(' ', LTGRAY, BLACK)
   1.120 +
   1.121 +/* pointer to the text mode video memory */
   1.122 +static uint16_t *vmem = (uint16_t*)0xb8000;
   1.123 +
   1.124 +void clear_scr(void)
   1.125 +{
   1.126 +    memset16(vmem, CLEAR_CHAR, WIDTH * HEIGHT);
   1.127 +}
   1.128 +
   1.129 +void set_char(char c, int x, int y, int fg, int bg)
   1.130 +{
   1.131 +    vmem[y * WIDTH + x] = VMEM_CHAR(c, fg, bg);
   1.132 +}
   1.133 +
   1.134 +void set_cursor(int x, int y)
   1.135 +{
   1.136 +	int loc;
   1.137 +    if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
   1.138 +        loc = 0xffff;
   1.139 +    } else {
   1.140 +        loc = y * WIDTH + x;
   1.141 +    }
   1.142 +
   1.143 +    /* tell the vga where we want the cursor by writing
   1.144 +     * to the "cursor address" register of the CRTC */
   1.145 +    outb(CRTC_CURSOR_LOW, CRTC_ADDR);
   1.146 +    outb(loc, CRTC_DATA);
   1.147 +    outb(CRTC_CURSOR_HIGH, CRTC_ADDR);
   1.148 +    outb(loc >> 8, CRTC_DATA);
   1.149 +}
   1.150 +
   1.151 +void scroll_scr(void)
   1.152 +{
   1.153 +    /* simple scrolling by manually copying memory */
   1.154 +    memmove(vmem, vmem + WIDTH, WIDTH * (HEIGHT - 1) * 2);
   1.155 +    memset16(vmem + WIDTH * (HEIGHT - 1), CLEAR_CHAR, WIDTH);
   1.156 +}
   1.157 +