基础vt1000框架
This commit is contained in:
parent
ab6763337a
commit
288db801e1
@ -6,15 +6,47 @@
|
|||||||
|
|
||||||
typedef void (*key_lis) (uint8_t);
|
typedef void (*key_lis) (uint8_t);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MODE_A = 'A',
|
||||||
|
MODE_B = 'B',
|
||||||
|
MODE_C = 'C',
|
||||||
|
MODE_D = 'D',
|
||||||
|
MODE_E = 'E',
|
||||||
|
MODE_F = 'F',
|
||||||
|
MODE_G = 'G',
|
||||||
|
MODE_H = 'H',
|
||||||
|
MODE_f = 'f',
|
||||||
|
MODE_J = 'J',
|
||||||
|
MODE_K = 'K',
|
||||||
|
MODE_S = 'S',
|
||||||
|
MODE_T = 'T',
|
||||||
|
MODE_m = 'm'
|
||||||
|
} vt100_mode_t;
|
||||||
|
|
||||||
typedef struct tty{
|
typedef struct tty{
|
||||||
uint32_t *frame_buffer; // 图形缓冲区映射
|
void (*print)(struct tty *res,const char *string);
|
||||||
uint32_t width;
|
void (*putchar)(struct tty *res,int c);
|
||||||
uint32_t height;
|
void (*MoveCursor)(struct tty *res,int x, int y);
|
||||||
bool is_default_frame; // 是否为根缓冲区
|
void (*clear)(struct tty *res);
|
||||||
|
void (*gotoxy)(struct tty *res, int x, int y);
|
||||||
|
void (*screen_ne)(struct tty *res);
|
||||||
|
|
||||||
|
|
||||||
bool is_using; // 是否可以接受输入
|
bool is_using; // 是否可以接受输入
|
||||||
struct FIFO8 *fifo; // 键盘输出缓冲区
|
struct FIFO8 *fifo; // 键盘输出缓冲区
|
||||||
key_lis keyboard_press; // 键盘按下
|
key_lis keyboard_press; // 键盘按下
|
||||||
key_lis keyboard_release; // 键盘松开
|
key_lis keyboard_release; // 键盘松开
|
||||||
|
int xsize, ysize;
|
||||||
|
int x, y;
|
||||||
|
uint8_t color;
|
||||||
|
|
||||||
|
/* vt100 */
|
||||||
|
int vt100; // 是否检测到标志
|
||||||
|
char buffer[81]; // 缓冲区
|
||||||
|
int buf_p; // 缓冲区指针
|
||||||
|
int done; // 这个东西读取完毕没有?
|
||||||
|
vt100_mode_t mode; // 控制模式
|
||||||
|
int color_saved; // 保存的颜色
|
||||||
}tty_t;
|
}tty_t;
|
||||||
|
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
@ -73,7 +73,6 @@ int check_task(int *pid){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int check_task_usershell(int *pid){
|
int check_task_usershell(int *pid){
|
||||||
while (1) asm("hlt");
|
|
||||||
struct task_struct *shell = found_task_pid(*pid);
|
struct task_struct *shell = found_task_pid(*pid);
|
||||||
while (1){
|
while (1){
|
||||||
if(shell->state == TASK_DEATH){
|
if(shell->state == TASK_DEATH){
|
||||||
|
@ -403,6 +403,7 @@ void init_sched() {
|
|||||||
current->mem_size = 0;
|
current->mem_size = 0;
|
||||||
current->next = current;
|
current->next = current;
|
||||||
current->isUser = 0;
|
current->isUser = 0;
|
||||||
|
init_default_tty(current);
|
||||||
|
|
||||||
extern header_t *head;
|
extern header_t *head;
|
||||||
extern header_t *tail;
|
extern header_t *tail;
|
||||||
|
353
src/kernel/tty.c
353
src/kernel/tty.c
@ -1,27 +1,366 @@
|
|||||||
#include "../include/tty.h"
|
#include "../include/tty.h"
|
||||||
#include "../include/task.h"
|
#include "../include/task.h"
|
||||||
|
#include "../include/graphics.h"
|
||||||
|
#include "../include/printf.h"
|
||||||
|
|
||||||
extern uint32_t *screen;
|
extern uint32_t *screen;
|
||||||
extern uint32_t width, height;
|
extern uint32_t width, height;
|
||||||
|
|
||||||
|
static char eos[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'f', 'J', 'K', 'S', 'T', 'm'};
|
||||||
|
// vt100控制字符中可能的结束符号
|
||||||
|
|
||||||
|
static inline int t_is_eos(char ch) {
|
||||||
|
for (int i = 0; i < sizeof(eos); i++) {
|
||||||
|
if (ch == eos[i]) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long atol(char* s) {
|
||||||
|
bool neg = *s == '-';
|
||||||
|
if (neg || *s == '+') s++;
|
||||||
|
long n = 0;
|
||||||
|
for (; isdigit(*s); s++)
|
||||||
|
n = n * 10 + (*s - '0');
|
||||||
|
return neg ? -n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tty_gotoxy(struct tty *res, int x, int y) {
|
||||||
|
if (res->x == x && res->y == y) return;
|
||||||
|
if (x >= 0 && y >= 0) {
|
||||||
|
int x2 = x;
|
||||||
|
int y2 = y;
|
||||||
|
if (x <= res->xsize - 1 && y <= res->ysize - 1) {
|
||||||
|
res->MoveCursor(res, x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x <= res->xsize - 1) {
|
||||||
|
for (int i = 0; i < y - res->ysize + 1; i++) {
|
||||||
|
res->screen_ne(res);
|
||||||
|
}
|
||||||
|
res->MoveCursor(res, x, res->ysize - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x > res->xsize - 1) {
|
||||||
|
y2 += x / res->xsize - 1;
|
||||||
|
x2 = x % res->xsize;
|
||||||
|
if (y2 <= res->ysize - 1)
|
||||||
|
tty_gotoxy(res, x2, y2 + 1);
|
||||||
|
else
|
||||||
|
tty_gotoxy(res, x2, y2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (x < 0) {
|
||||||
|
x += res->xsize;
|
||||||
|
y--;
|
||||||
|
tty_gotoxy(res, x, y);
|
||||||
|
}
|
||||||
|
if (y < 0) { return; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_vt100(struct tty *res, char *string) {
|
||||||
|
switch (res->mode) {
|
||||||
|
case MODE_A: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, res->x, res->y - delta);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_B: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, res->x, res->y + delta);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_C: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, res->x + delta, res->y);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_D: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, res->x - delta, res->y);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_E: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, 0, res->y + delta);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_F: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, 0, res->y - delta);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_G: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (!delta) delta = 1;
|
||||||
|
res->gotoxy(res, delta - 1, res->y); // 可能是这样的
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_H: {
|
||||||
|
int k = 0;
|
||||||
|
char dig_string[2][81];
|
||||||
|
memset(dig_string, 0, sizeof(dig_string)); // 全部设置为0
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) {
|
||||||
|
if (string[i] == ';') { // 分号
|
||||||
|
k++;
|
||||||
|
j = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dig_string[k][j++] = string[i];
|
||||||
|
}
|
||||||
|
if (k > 1) return 0;
|
||||||
|
|
||||||
|
int delta[2] = {0};
|
||||||
|
for (int i = 0; i <= k; i++) {
|
||||||
|
delta[i] = atol(dig_string[i]);
|
||||||
|
}
|
||||||
|
if (k == 0 && delta[0] != 0) return 0;
|
||||||
|
switch (k) {
|
||||||
|
case 0: res->gotoxy(res, 0, 0); break;
|
||||||
|
case 1: res->gotoxy(res, delta[0], delta[1]); break;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_J: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
int old_x = res->x, old_y = res->y;
|
||||||
|
switch (delta) {
|
||||||
|
case 0: {
|
||||||
|
int flag = 0;
|
||||||
|
for (int i = old_y * res->xsize + old_x; i < res->xsize * res->ysize; i++) {
|
||||||
|
flag = 1;
|
||||||
|
res->putchar(res, ' ');
|
||||||
|
}
|
||||||
|
if (flag) res->gotoxy(res, old_x, old_y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
res->gotoxy(res, 0, 0);
|
||||||
|
for (int i = 0; i < old_y * res->xsize + old_x; i++) {
|
||||||
|
res->putchar(res, ' ');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: res->clear(res); break;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_K: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
int old_x = res->x, old_y = res->y;
|
||||||
|
switch (delta) {
|
||||||
|
case 0: {
|
||||||
|
int flag = 0;
|
||||||
|
for (int i = old_y * res->xsize + old_x; i < (old_y + 1) * res->ysize; i++) {
|
||||||
|
flag = 1;
|
||||||
|
res->putchar(res, ' ');
|
||||||
|
}
|
||||||
|
if (flag) res->gotoxy(res, old_x, old_y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
res->gotoxy(res, 0, res->y);
|
||||||
|
for (int i = old_y * res->xsize; i < old_y * res->xsize + old_x; i++) {
|
||||||
|
res->putchar(res, ' ');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
res->gotoxy(res, 0, res->y);
|
||||||
|
for (int i = old_y * res->xsize; i < (old_y + 1) * res->xsize; i++) {
|
||||||
|
res->putchar(res, ' ');
|
||||||
|
}
|
||||||
|
res->gotoxy(res, old_x, old_y);
|
||||||
|
break;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_S: return 0; // unsupported
|
||||||
|
case MODE_T: {
|
||||||
|
char dig_string[81] = {0};
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) return 0;
|
||||||
|
dig_string[j++] = string[i];
|
||||||
|
}
|
||||||
|
int delta = atol(dig_string);
|
||||||
|
if (delta) return 0;
|
||||||
|
res->screen_ne(res);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case MODE_m: {
|
||||||
|
// klogd("MODE_m");
|
||||||
|
int k = 0;
|
||||||
|
char dig_string[2][81];
|
||||||
|
memset(dig_string, 0, sizeof(dig_string)); // 全部设置为0
|
||||||
|
for (int i = 2, j = 0; string[i]; i++) {
|
||||||
|
if (t_is_eos(string[i])) break;
|
||||||
|
if (!isdigit(string[i])) {
|
||||||
|
if (string[i] == ';') { // 分号
|
||||||
|
k++;
|
||||||
|
j = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dig_string[k][j++] = string[i];
|
||||||
|
}
|
||||||
|
if (k > 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delta[2] = {0};
|
||||||
|
// klogd("start for %d", k);
|
||||||
|
for (int i = 0; i <= k; i++) {
|
||||||
|
delta[i] = atol(dig_string[i]);
|
||||||
|
}
|
||||||
|
if (delta[0] == 0 && k == 0) {
|
||||||
|
int sel_color = res->color_saved != -1 ? res->color_saved : res->color;
|
||||||
|
res->color = sel_color;
|
||||||
|
res->color_saved = -1;
|
||||||
|
return 1;
|
||||||
|
} else if (delta[0] == 1 && k == 0) { // unsupported
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// klogd("switch k");
|
||||||
|
static const uint8_t color_map[8] = {0, 4, 2, 6, 1, 5, 3, 7};
|
||||||
|
switch (k) {
|
||||||
|
case 0: {
|
||||||
|
if (delta[0] >= 30 && delta[0] <= 37) { // foreground color
|
||||||
|
if (res->color_saved == -1) res->color_saved = res->color;
|
||||||
|
res->color &= 0xf0;
|
||||||
|
res->color |= color_map[delta[0] - 30];
|
||||||
|
return 1;
|
||||||
|
} else if (delta[0] >= 40 && delta[0] <= 47) {
|
||||||
|
if (res->color_saved == -1) res->color_saved = res->color;
|
||||||
|
res->color &= 0x0f;
|
||||||
|
res->color |= color_map[delta[0] - 40] << 4;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
if (delta[0] != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (delta[1] >= 30 && delta[1] <= 37) { // foreground color
|
||||||
|
if (res->color_saved == -1) { res->color_saved = res->color; }
|
||||||
|
res->color &= 0xf0;
|
||||||
|
res->color |= color_map[delta[1] - 30] + 8;
|
||||||
|
return 1;
|
||||||
|
} else if (delta[1] >= 40 && delta[1] <= 47) {
|
||||||
|
if (res->color_saved == -1) res->color_saved = res->color;
|
||||||
|
res->color &= 0x0f;
|
||||||
|
res->color |= (color_map[delta[1] - 40] + 8) << 4;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tty_print(struct tty *res,const char *string){
|
||||||
|
vbe_writestring(string);
|
||||||
|
}
|
||||||
|
void tty_putchar(struct tty *res,int c){
|
||||||
|
vbe_putchar(c);
|
||||||
|
}
|
||||||
|
void tty_MoveCursor(struct tty *res,int x, int y){
|
||||||
|
|
||||||
|
}
|
||||||
|
void tty_clear(struct tty *res){
|
||||||
|
vbe_clear();
|
||||||
|
}
|
||||||
|
|
||||||
void init_default_tty(struct task_struct *task){
|
void init_default_tty(struct task_struct *task){
|
||||||
task->tty->fifo = kmalloc(sizeof(struct FIFO8));
|
task->tty->fifo = kmalloc(sizeof(struct FIFO8));
|
||||||
char* buffer = kmalloc(256);
|
char* buffer = kmalloc(256);
|
||||||
|
|
||||||
task->tty->frame_buffer = screen;
|
|
||||||
task->tty->width = width;
|
|
||||||
task->tty->height = height;
|
|
||||||
task->tty->is_default_frame = true;
|
|
||||||
task->tty->is_using = true;
|
task->tty->is_using = true;
|
||||||
|
task->tty->print = tty_print;
|
||||||
|
task->tty->clear = tty_clear;
|
||||||
|
task->tty->putchar = tty_putchar;
|
||||||
|
task->tty->gotoxy = tty_gotoxy;
|
||||||
|
|
||||||
fifo8_init(task->tty->fifo,256,buffer);
|
fifo8_init(task->tty->fifo,256,buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_tty(struct task_struct *task){
|
void free_tty(struct task_struct *task){
|
||||||
if(!task->tty->is_default_frame){
|
|
||||||
kfree(task->tty->frame_buffer);
|
|
||||||
}
|
|
||||||
kfree(task->tty->fifo->buf);
|
kfree(task->tty->fifo->buf);
|
||||||
kfree(task->tty->fifo);
|
kfree(task->tty->fifo);
|
||||||
kfree(task->tty);
|
kfree(task->tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
#include "../include/graphics.h"
|
#include "../include/graphics.h"
|
||||||
#include "../include/serial.h"
|
#include "../include/serial.h"
|
||||||
|
#include "../include/tty.h"
|
||||||
|
|
||||||
static int skip_atoi(const char **s) {
|
static int skip_atoi(const char **s) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -305,18 +306,38 @@ void printf(const char *formet, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void screen_clear(){
|
void screen_clear(){
|
||||||
|
struct task_struct *task = get_current();
|
||||||
|
if(task != NULL){
|
||||||
|
task->tty->clear(task->tty);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(vbe_status){
|
if(vbe_status){
|
||||||
vbe_clear();
|
vbe_clear();
|
||||||
} else vga_clear();
|
} else vga_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void putchar(char c){
|
void putchar(char c){
|
||||||
|
struct task_struct *task = get_current();
|
||||||
|
if(task != NULL){
|
||||||
|
task->tty->putchar(task->tty,c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(vbe_status){
|
if(vbe_status){
|
||||||
vbe_putchar(c);
|
vbe_putchar(c);
|
||||||
} else vga_putchar(c);
|
} else vga_putchar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(char *message) {
|
void print(char *message) {
|
||||||
|
struct task_struct *task = get_current();
|
||||||
|
if(task != NULL){
|
||||||
|
task->tty->print(task->tty,message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logk(message);
|
||||||
|
|
||||||
if(vbe_status){
|
if(vbe_status){
|
||||||
vbe_writestring(message);
|
vbe_writestring(message);
|
||||||
} else vga_writestring(message);
|
} else vga_writestring(message);
|
||||||
|
Loading…
Reference in New Issue
Block a user