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_ */