kern

changeset 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 a9176938bce1
files Makefile src/asmops.h src/klibc/ctype.c src/klibc/ctype.h src/klibc/stdio.c src/klibc/string.c src/klibc/string.h src/main.c src/term.c src/term.h src/vid.c src/vid.h
diffstat 12 files changed, 301 insertions(+), 33 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Thu Dec 02 08:45:41 2010 +0200
     1.2 +++ b/Makefile	Sat Dec 04 08:04:43 2010 +0200
     1.3 @@ -3,7 +3,7 @@
     1.4  asmsrc = $(wildcard src/*.S) $(wildcard src/klibc/*.S)
     1.5  
     1.6  # each source file will generate one object file
     1.7 -obj = $(csrc:.c=.o) $(asmsrc:.S=.o)
     1.8 +obj = $(asmsrc:.S=.o) $(csrc:.c=.o)
     1.9  
    1.10  CC = gcc
    1.11  
     2.1 --- a/src/asmops.h	Thu Dec 02 08:45:41 2010 +0200
     2.2 +++ b/src/asmops.h	Sat Dec 04 08:04:43 2010 +0200
     2.3 @@ -3,29 +3,29 @@
     2.4  
     2.5  #define inb(dest, port) asm volatile( \
     2.6  	"inb %1, %0\n\t" \
     2.7 -	: "=a" (unsigned char)(dest) \
     2.8 -	: "dN" (unsigned short)(port))
     2.9 +	: "=a" ((unsigned char)(dest)) \
    2.10 +	: "dN" ((unsigned short)(port)))
    2.11  
    2.12  #define ins(dest, port) asm volatile( \
    2.13  	"ins %1, %0\n\t" \
    2.14 -	: "=a" (unsigned short)(dest) \
    2.15 -	: "dN" (unsigned short)(port))
    2.16 +	: "=a" ((unsigned short)(dest)) \
    2.17 +	: "dN" ((unsigned short)(port)))
    2.18  
    2.19  #define inl(dest, port) asm volatile( \
    2.20  	"inl %1, %0\n\t" \
    2.21 -	: "=a" (unsigned long)(dest) \
    2.22 -	: "dN" (unsigned short)(port))
    2.23 +	: "=a" ((unsigned long)(dest)) \
    2.24 +	: "dN" ((unsigned short)(port)))
    2.25  
    2.26  #define outb(src, port) asm volatile( \
    2.27  	"outb %0, %1\n\t" \
    2.28 -	:: "a" (unsigned char)(src), "dN" (unsigned short)(port))
    2.29 +	:: "a" ((unsigned char)(src)), "dN" ((unsigned short)(port)))
    2.30  
    2.31  #define outs(src, port) asm volatile( \
    2.32  	"outs %0, %1\n\t" \
    2.33 -	:: "a" (unsigned short)(src), "dN" (unsigned short)(port))
    2.34 +	:: "a" ((unsigned short)(src)), "dN" ((unsigned short)(port)))
    2.35  
    2.36  #define outl(src, port) asm volatile( \
    2.37  	"outl %0, %1\n\t" \
    2.38 -	:: "a" (unsigned long)(src), "dN" (unsigned short)(port))
    2.39 +	:: "a" ((unsigned long)(src)), "dN" ((unsigned short)(port)))
    2.40  
    2.41  #endif	/* ASMOPS_H_ */
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/klibc/ctype.c	Sat Dec 04 08:04:43 2010 +0200
     3.3 @@ -0,0 +1,56 @@
     3.4 +#include "ctype.h"
     3.5 +
     3.6 +int isalnum(int c)
     3.7 +{
     3.8 +	return isalpha(c) || isdigit(c);
     3.9 +}
    3.10 +
    3.11 +int isalpha(int c)
    3.12 +{
    3.13 +	return isupper(c) || islower(c);
    3.14 +}
    3.15 +
    3.16 +int isblank(int c)
    3.17 +{
    3.18 +	return c == ' ' || c == '\t';
    3.19 +}
    3.20 +
    3.21 +int isdigit(int c)
    3.22 +{
    3.23 +	return c >= '0' && c <= '9';
    3.24 +}
    3.25 +
    3.26 +int isupper(int c)
    3.27 +{
    3.28 +	return c >= 'A' && c <= 'Z';
    3.29 +}
    3.30 +
    3.31 +int islower(int c)
    3.32 +{
    3.33 +	return c >= 'a' && c <= 'z';
    3.34 +}
    3.35 +
    3.36 +int isgraph(int c)
    3.37 +{
    3.38 +	return c > ' ' && c <= '~';
    3.39 +}
    3.40 +
    3.41 +int isprint(int c)
    3.42 +{
    3.43 +	return isgraph(c) || c == ' ';
    3.44 +}
    3.45 +
    3.46 +int isspace(int c)
    3.47 +{
    3.48 +	return isblank(c) || c == '\f' || c == '\n' || c == '\r' || c == '\v';
    3.49 +}
    3.50 +
    3.51 +int toupper(int c)
    3.52 +{
    3.53 +	return islower(c) ? (c + ('A' - 'a')) : c;
    3.54 +}
    3.55 +
    3.56 +int tolower(int c)
    3.57 +{
    3.58 +	return isupper(c) ? (c + ('A' - 'a')) : c;
    3.59 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/klibc/ctype.h	Sat Dec 04 08:04:43 2010 +0200
     4.3 @@ -0,0 +1,17 @@
     4.4 +#ifndef CTYPE_H_
     4.5 +#define CTYPE_H_
     4.6 +
     4.7 +int isalnum(int c);
     4.8 +int isalpha(int c);
     4.9 +#define isascii(c)	((c) < 128)
    4.10 +int isblank(int c);
    4.11 +int isdigit(int c);
    4.12 +int isupper(int c);
    4.13 +int islower(int c);
    4.14 +int isprint(int c);
    4.15 +int isspace(int c);
    4.16 +
    4.17 +int toupper(int c);
    4.18 +int tolower(int c);
    4.19 +
    4.20 +#endif	/* CTYPE_H_ */
     5.1 --- a/src/klibc/stdio.c	Thu Dec 02 08:45:41 2010 +0200
     5.2 +++ b/src/klibc/stdio.c	Sat Dec 04 08:04:43 2010 +0200
     5.3 @@ -7,5 +7,6 @@
     5.4  	while(*s) {
     5.5  		putchar(*s++);
     5.6  	}
     5.7 +	putchar('\n');
     5.8  	return 0;
     5.9  }
     6.1 --- a/src/klibc/string.c	Thu Dec 02 08:45:41 2010 +0200
     6.2 +++ b/src/klibc/string.c	Sat Dec 04 08:04:43 2010 +0200
     6.3 @@ -8,6 +8,14 @@
     6.4  	}
     6.5  }
     6.6  
     6.7 +void memset16(void *s, int c, size_t n)
     6.8 +{
     6.9 +	short *ptr = s;
    6.10 +	while(n--) {
    6.11 +		*ptr++ = c;
    6.12 +	}
    6.13 +}
    6.14 +
    6.15  void *memcpy(void *dest, const void *src, size_t n)
    6.16  {
    6.17  	char *dptr = dest;
     7.1 --- a/src/klibc/string.h	Thu Dec 02 08:45:41 2010 +0200
     7.2 +++ b/src/klibc/string.h	Sat Dec 04 08:04:43 2010 +0200
     7.3 @@ -4,6 +4,8 @@
     7.4  #include <stdlib.h>
     7.5  
     7.6  void memset(void *s, int c, size_t n);
     7.7 +void memset16(void *s, int c, size_t n);
     7.8 +
     7.9  void *memcpy(void *dest, const void *src, size_t n);
    7.10  void *memmove(void *dest, const void *src, size_t n);
    7.11  
     8.1 --- a/src/main.c	Thu Dec 02 08:45:41 2010 +0200
     8.2 +++ b/src/main.c	Sat Dec 04 08:04:43 2010 +0200
     8.3 @@ -1,10 +1,55 @@
     8.4  #include <stdio.h>
     8.5  #include "vid.h"
     8.6  #include "term.h"
     8.7 +#include <asmops.h>
     8.8 +
     8.9 +/* special keys */
    8.10 +enum {
    8.11 +	LALT, RALT,
    8.12 +	LCTRL, RCTRL,
    8.13 +	LSHIFT, RSHIFT,
    8.14 +	F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
    8.15 +	CAPSLK, NUMLK, SCRLK, SYSRQ,
    8.16 +	ESC		= 27,
    8.17 +	INSERT, DEL, HOME, END, PGUP, PGDN, LEFT, RIGHT, UP, DOWN,
    8.18 +	NUM_DOT, NUM_ENTER, NUM_PLUS, NUM_MINUS, NUM_MUL, NUM_DIV,
    8.19 +	NUM_0, NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9,
    8.20 +	BACKSP	= 127
    8.21 +};
    8.22 +
    8.23 +/* table with rough translations from set 1 scancodes to ASCII-ish */
    8.24 +static int keycodes[] = {
    8.25 +	0, ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',		/* 0 - e */
    8.26 +	'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',			/* f - 1c */
    8.27 +	LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',				/* 1d - 29 */
    8.28 +	LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', RSHIFT,			/* 2a - 36 */
    8.29 +	NUM_MUL, LALT, ' ', CAPSLK, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,			/* 37 - 44 */
    8.30 +	NUMLK, SCRLK, NUM_7, NUM_8, NUM_9, NUM_MINUS, NUM_4, NUM_5, NUM_6, NUM_PLUS,	/* 45 - 4e */
    8.31 +	NUM_1, NUM_2, NUM_3, NUM_0, NUM_DOT, SYSRQ, 0, 0, F11, F12,						/* 4d - 58 */
    8.32 +	0, 0, 0, 0, 0, 0, 0,															/* 59 - 5f */
    8.33 +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,									/* 60 - 6f */
    8.34 +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0									/* 70 - 7f */
    8.35 +};
    8.36 +
    8.37  
    8.38  void kmain(void)
    8.39  {
    8.40 -	clear_scr(0);
    8.41 -	set_text_color(LTRED);
    8.42 +	clear_scr();
    8.43 +	puts("kernel starting up");
    8.44 +
    8.45 +	set_text_color(YELLOW);
    8.46 +	puts("<initialization code goes here>");
    8.47 +	set_text_color(LTGRAY);
    8.48  	puts("hello world!");
    8.49 +
    8.50 +	for(;;) {
    8.51 +		char c, keypress;
    8.52 +		do {
    8.53 +			inb(keypress, 0x64);
    8.54 +		} while(!(keypress & 1));
    8.55 +		inb(c, 0x60);
    8.56 +		if(!(c & 0x80)) {
    8.57 +			putchar(keycodes[c]);
    8.58 +		}
    8.59 +	}
    8.60  }
     9.1 --- a/src/term.c	Thu Dec 02 08:45:41 2010 +0200
     9.2 +++ b/src/term.c	Sat Dec 04 08:04:43 2010 +0200
     9.3 @@ -1,23 +1,35 @@
     9.4  #include "term.h"
     9.5  #include "vid.h"
     9.6  
     9.7 -static int bg, fg = 15;
     9.8 +static int bg, fg = LTGRAY;
     9.9  static int cursor_x, cursor_y;
    9.10  
    9.11 -void set_text_color(int c)
    9.12 +/* sets the active text color and returns previous value */
    9.13 +int set_text_color(int c)
    9.14  {
    9.15 +	int prev = fg;
    9.16 +
    9.17  	if(c >= 0 && c < 16) {
    9.18  		fg = c;
    9.19  	}
    9.20 +	return prev;
    9.21  }
    9.22  
    9.23 -void set_back_color(int c)
    9.24 +/* sets the active background color and returns the current value */
    9.25 +int set_back_color(int c)
    9.26  {
    9.27 +	int prev = bg;
    9.28 +
    9.29  	if(c >= 0 && c < 16) {
    9.30  		bg = c;
    9.31  	}
    9.32 +	return prev;
    9.33  }
    9.34  
    9.35 +/* output a single character, handles formatting, cursor advancement
    9.36 + * and scrolling the screen when we reach the bottom.
    9.37 + * TODO make visible cursor actually move.
    9.38 + */
    9.39  int putchar(int c)
    9.40  {
    9.41  	switch(c) {
    9.42 @@ -38,10 +50,12 @@
    9.43  		break;
    9.44  
    9.45  	default:
    9.46 -		set_char(c, cursor_x, cursor_y, fg, bg);
    9.47 -		if(++cursor_x >= WIDTH) {
    9.48 -			cursor_x = 0;
    9.49 -			cursor_y++;
    9.50 +		if(isprint(c)) {
    9.51 +			set_char(c, cursor_x, cursor_y, fg, bg);
    9.52 +			if(++cursor_x >= WIDTH) {
    9.53 +				cursor_x = 0;
    9.54 +				cursor_y++;
    9.55 +			}
    9.56  		}
    9.57  	}
    9.58  
    9.59 @@ -49,5 +63,7 @@
    9.60  		scroll_scr();
    9.61  		cursor_y--;
    9.62  	}
    9.63 +
    9.64 +	set_cursor(cursor_x, cursor_y);
    9.65  	return c;
    9.66  }
    10.1 --- a/src/term.h	Thu Dec 02 08:45:41 2010 +0200
    10.2 +++ b/src/term.h	Sat Dec 04 08:04:43 2010 +0200
    10.3 @@ -1,8 +1,8 @@
    10.4  #ifndef TERM_H_
    10.5  #define TERM_H_
    10.6  
    10.7 -void set_text_color(int c);
    10.8 -void set_back_color(int c);
    10.9 +int set_text_color(int c);
   10.10 +int set_back_color(int c);
   10.11  
   10.12  int putchar(int c);
   10.13  
    11.1 --- a/src/vid.c	Thu Dec 02 08:45:41 2010 +0200
    11.2 +++ b/src/vid.c	Sat Dec 04 08:04:43 2010 +0200
    11.3 @@ -1,24 +1,145 @@
    11.4 +#if 0
    11.5 +
    11.6  #include <string.h>
    11.7  #include "vid.h"
    11.8 +#include "asmops.h"
    11.9 +
   11.10 +/* height of our virtual console text buffer */
   11.11 +#define VIRT_HEIGHT	1024
   11.12 +
   11.13 +/* CRTC ports */
   11.14 +#define CRTC_ADDR	0x3d4
   11.15 +#define CRTC_DATA	0x3d5
   11.16 +
   11.17 +/* CRTC registers */
   11.18 +#define CRTC_START_HIGH		0xc
   11.19 +#define CRTC_START_LOW		0xd
   11.20 +#define CRTC_CURSOR_HIGH	0xe
   11.21 +#define CRTC_CURSOR_LOW		0xf
   11.22 +
   11.23 +/* construct a character with its attributes */
   11.24 +#define VMEM_CHAR(c, fg, bg) \
   11.25 +	((uint16_t)(c) | (((uint16_t)(fg) & 0xf) << 8) | (((uint16_t)(bg) & 0xf) << 12))
   11.26 +
   11.27 +static void set_start_line(int line);
   11.28  
   11.29  static uint16_t *vmem = (uint16_t*)0xb8000;
   11.30 +static int start_line;
   11.31  
   11.32 -void clear_scr(int color)
   11.33 +
   11.34 +void clear_scr(void)
   11.35  {
   11.36 -	memset(vmem, 0, WIDTH * HEIGHT * 2);
   11.37 +	memset16(vmem, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH * HEIGHT);
   11.38 +	start_line = 0;
   11.39 +	set_start_line(0);
   11.40 +	set_cursor(0, 0);
   11.41  }
   11.42  
   11.43  void set_char(char c, int x, int y, int fg, int bg)
   11.44  {
   11.45 -	uint16_t attr = (fg & 0xf) | ((bg & 7) << 4);
   11.46 -	vmem[y * WIDTH + x] = (uint16_t)c | (attr << 8);
   11.47 +	vmem[(y + start_line) * WIDTH + x] = VMEM_CHAR(c, fg, bg);
   11.48 +}
   11.49 +
   11.50 +void set_cursor(int x, int y)
   11.51 +{
   11.52 +	int loc;
   11.53 +
   11.54 +	if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
   11.55 +		loc = 0xffff;
   11.56 +	} else {
   11.57 +		loc = (y + start_line) * WIDTH + x;
   11.58 +	}
   11.59 +
   11.60 +	outb(CRTC_CURSOR_LOW, CRTC_ADDR);
   11.61 +	outb(loc, CRTC_DATA);
   11.62 +	outb(CRTC_CURSOR_HIGH, CRTC_ADDR);
   11.63 +	outb(loc >> 8, CRTC_DATA);
   11.64  }
   11.65  
   11.66  void scroll_scr(void)
   11.67  {
   11.68 -	/* copy the second up to last text line, one line back, then
   11.69 -	 * clear the last line.
   11.70 -	 */
   11.71 -	memmove(vmem, vmem + WIDTH, WIDTH * (HEIGHT - 1) * 2);
   11.72 -	memset(vmem + WIDTH * (HEIGHT -1), 0, WIDTH * 2);
   11.73 +	if(++start_line > VIRT_HEIGHT - HEIGHT) {
   11.74 +		/* The bottom of the visible range reached the end of our text buffer.
   11.75 +		 * Copy the rest of the lines to the top and reset start_line.
   11.76 +		 */
   11.77 +		memcpy(vmem, vmem + start_line * WIDTH, (HEIGHT - 1) * WIDTH);
   11.78 +		start_line = 0;
   11.79 +	}
   11.80 +
   11.81 +	/* clear the next line that will be revealed by scrolling */
   11.82 +	int new_line = start_line + HEIGHT - 1;
   11.83 +	memset16(vmem + new_line * WIDTH, VMEM_CHAR(' ', LTGRAY, BLACK), WIDTH);
   11.84 +
   11.85 +	set_start_line(start_line);
   11.86  }
   11.87 +
   11.88 +static void set_start_line(int line)
   11.89 +{
   11.90 +	int start_addr = line * WIDTH;
   11.91 +
   11.92 +	outb(CRTC_START_LOW, CRTC_ADDR);
   11.93 +	outb(start_addr & 0xff, CRTC_DATA);
   11.94 +	outb(CRTC_START_HIGH, CRTC_ADDR);
   11.95 +	outb((start_addr >> 8) & 0xff, CRTC_DATA);
   11.96 +}
   11.97 +#endif	/* 0 */
   11.98 +
   11.99 +#include <string.h>
  11.100 +#include "vid.h"
  11.101 +#include "asmops.h"
  11.102 +
  11.103 +#define WIDTH 80
  11.104 +#define HEIGHT 25
  11.105 +
  11.106 +/* CRTC ports */
  11.107 +#define CRTC_ADDR   0x3d4
  11.108 +#define CRTC_DATA   0x3d5
  11.109 +
  11.110 +/* CRTC registers */
  11.111 +#define CRTC_CURSOR_HIGH 0xe
  11.112 +#define CRTC_CURSOR_LOW  0xf
  11.113 +
  11.114 +/* construct a character with its attributes */
  11.115 +#define VMEM_CHAR(c, fg, bg) \
  11.116 +    ((uint16_t)(c) | (((uint16_t)(fg) & 0xf) << 8) | \
  11.117 +     (((uint16_t)(bg) & 0xf) << 12))
  11.118 +
  11.119 +#define CLEAR_CHAR	VMEM_CHAR(' ', LTGRAY, BLACK)
  11.120 +
  11.121 +/* pointer to the text mode video memory */
  11.122 +static uint16_t *vmem = (uint16_t*)0xb8000;
  11.123 +
  11.124 +void clear_scr(void)
  11.125 +{
  11.126 +    memset16(vmem, CLEAR_CHAR, WIDTH * HEIGHT);
  11.127 +}
  11.128 +
  11.129 +void set_char(char c, int x, int y, int fg, int bg)
  11.130 +{
  11.131 +    vmem[y * WIDTH + x] = VMEM_CHAR(c, fg, bg);
  11.132 +}
  11.133 +
  11.134 +void set_cursor(int x, int y)
  11.135 +{
  11.136 +	int loc;
  11.137 +    if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
  11.138 +        loc = 0xffff;
  11.139 +    } else {
  11.140 +        loc = y * WIDTH + x;
  11.141 +    }
  11.142 +
  11.143 +    /* tell the vga where we want the cursor by writing
  11.144 +     * to the "cursor address" register of the CRTC */
  11.145 +    outb(CRTC_CURSOR_LOW, CRTC_ADDR);
  11.146 +    outb(loc, CRTC_DATA);
  11.147 +    outb(CRTC_CURSOR_HIGH, CRTC_ADDR);
  11.148 +    outb(loc >> 8, CRTC_DATA);
  11.149 +}
  11.150 +
  11.151 +void scroll_scr(void)
  11.152 +{
  11.153 +    /* simple scrolling by manually copying memory */
  11.154 +    memmove(vmem, vmem + WIDTH, WIDTH * (HEIGHT - 1) * 2);
  11.155 +    memset16(vmem + WIDTH * (HEIGHT - 1), CLEAR_CHAR, WIDTH);
  11.156 +}
  11.157 +
    12.1 --- a/src/vid.h	Thu Dec 02 08:45:41 2010 +0200
    12.2 +++ b/src/vid.h	Sat Dec 04 08:04:43 2010 +0200
    12.3 @@ -1,9 +1,10 @@
    12.4  #ifndef VID_H_
    12.5  #define VID_H_
    12.6  
    12.7 -#define WIDTH	80
    12.8 -#define HEIGHT	25
    12.9 +#define WIDTH			80
   12.10 +#define HEIGHT			25
   12.11  
   12.12 +/* the standard CGA color palette */
   12.13  enum {
   12.14  	BLACK,
   12.15  	BLUE,
   12.16 @@ -23,8 +24,9 @@
   12.17  	WHITE
   12.18  };
   12.19  
   12.20 -void clear_scr(int color);
   12.21 +void clear_scr(void);
   12.22  void set_char(char c, int x, int y, int fg, int bg);
   12.23 +void set_cursor(int x, int y);
   12.24  void scroll_scr(void);
   12.25  
   12.26  #endif	/* VID_H_ */