基础vt1000框架

This commit is contained in:
XIAOYI12 2024-09-02 16:02:08 +08:00
parent ab6763337a
commit 288db801e1
5 changed files with 404 additions and 12 deletions

View File

@ -6,15 +6,47 @@
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{
uint32_t *frame_buffer; // 图形缓冲区映射
uint32_t width;
uint32_t height;
bool is_default_frame; // 是否为根缓冲区
void (*print)(struct tty *res,const char *string);
void (*putchar)(struct tty *res,int c);
void (*MoveCursor)(struct tty *res,int x, int y);
void (*clear)(struct tty *res);
void (*gotoxy)(struct tty *res, int x, int y);
void (*screen_ne)(struct tty *res);
bool is_using; // 是否可以接受输入
struct FIFO8 *fifo; // 键盘输出缓冲区
key_lis keyboard_press; // 键盘按下
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;
#include "task.h"

View File

@ -73,7 +73,6 @@ int check_task(int *pid){
}
int check_task_usershell(int *pid){
while (1) asm("hlt");
struct task_struct *shell = found_task_pid(*pid);
while (1){
if(shell->state == TASK_DEATH){

View File

@ -403,6 +403,7 @@ void init_sched() {
current->mem_size = 0;
current->next = current;
current->isUser = 0;
init_default_tty(current);
extern header_t *head;
extern header_t *tail;

View File

@ -1,27 +1,366 @@
#include "../include/tty.h"
#include "../include/task.h"
#include "../include/graphics.h"
#include "../include/printf.h"
extern uint32_t *screen;
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){
task->tty->fifo = kmalloc(sizeof(struct FIFO8));
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->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);
}
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);
kfree(task->tty);
}

View File

@ -2,6 +2,7 @@
#include "../include/common.h"
#include "../include/graphics.h"
#include "../include/serial.h"
#include "../include/tty.h"
static int skip_atoi(const char **s) {
int i = 0;
@ -305,18 +306,38 @@ void printf(const char *formet, ...) {
}
void screen_clear(){
struct task_struct *task = get_current();
if(task != NULL){
task->tty->clear(task->tty);
return;
}
if(vbe_status){
vbe_clear();
} else vga_clear();
}
void putchar(char c){
struct task_struct *task = get_current();
if(task != NULL){
task->tty->putchar(task->tty,c);
return;
}
if(vbe_status){
vbe_putchar(c);
} else vga_putchar(c);
}
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){
vbe_writestring(message);
} else vga_writestring(message);