implement a very basic new vgatty

This commit is contained in:
catfood 2022-12-21 19:55:08 +08:00
parent d0cdcdf420
commit 627a6e323b
12 changed files with 396 additions and 17 deletions

View File

@ -30,12 +30,16 @@ typedef struct s_console
#define SCR_UP 1 /* scroll upward */
#define SCR_DN -1 /* scroll downward */
#define SCR_SIZE (80 * 25)
#define SCR_WIDTH 80
#define SCR_HEIGHT 25
#define SCR_SIZE (SCR_HEIGHT * SCR_WIDTH)
#define SCR_BUFSIZE (8 * SCR_SIZE)
#define SCR_MAXLINE (SCR_BUFSIZE / SCR_WIDTH)
#define DEFAULT_CHAR_COLOR (MAKE_COLOR(BLACK, WHITE))
#define DEFAULT_CHAR_COLOR (MAKE_COLOR(BLACK, WHITE | BRIGHT))
#define GRAY_CHAR (MAKE_COLOR(BLACK, BLACK) | BRIGHT)
#define RED_CHAR (MAKE_COLOR(BLUE, RED) | BRIGHT)
#define MAKE_CELL(clr, ch) ((clr << 8) | ch)
#define BLANK MAKE_CELL(DEFAULT_CHAR_COLOR, ' ')
#endif /* _ORANGES_CONSOLE_H_ */

View File

@ -20,10 +20,13 @@
*/
//added by mingxuan 2019-5-19
#define BLACK 0x0 /* 0000 */
#define WHITE 0x7 /* 0111 */
#define RED 0x4 /* 0100 */
#define GREEN 0x2 /* 0010 */
#define BLUE 0x1 /* 0001 */
#define GREEN 0x2 /* 0010 */
#define CYAN 0x3
#define RED 0x4 /* 0100 */
#define MAGENTA 0x5
#define BROWN 0x6 /* yellow = bright brown, which is 0xe*/
#define WHITE 0x7 /* 0111 actually its light grey, white = bright light grey*/
#define FLASH 0x80 /* 1000 0000 */
#define BRIGHT 0x08 /* 0000 1000 */
#define MAKE_COLOR(x,y) ((x<<4) | y) /* MAKE_COLOR(Background,Foreground) */
@ -180,5 +183,5 @@
//added by mingxuan 2019-5-19
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
#define abs(a) ((a) < 0 ? -(a) : (a))
#endif /* _ORANGES_CONST_H_ */

View File

@ -49,6 +49,7 @@ void in_process(TTY* p_tty,u32 key);
void task_tty();
void tty_write(TTY* tty, char* buf, int len);
int tty_read(TTY* tty, char* buf, int len);
void init_tty_main();
/* printf.c */
//added by mingxuan 2019-5-19

View File

@ -49,6 +49,38 @@ typedef struct s_tty
struct s_console * console;
}TTY;
typedef struct MouseState{
u8 mouse_lb;
u8 mouse_mb;
u8 mouse_rb;
signed char mouse_scroll;
int mouse_x;
int mouse_y;
} MouseState;
typedef struct n_tty {
int driver_type; // 1-vga&kbd; 2-serial
MouseState mouse;
void* input_buf;
void* output_buf;
} NTTY;
typedef struct vga_buf {
void* buf; // 2d array, screen size, for text mode it's [maxline][80]
int max_line; // to support scroll, max line should be a lot more than screen
int scr_top_line; // the index in buf of top line on screen;
int scr_cur_line; // the index in buf of the cursor's line
int head_line; // for circular buffer use
int cur_row;
int cur_col; // cursor position, on screen
} vga_buf;
typedef struct keyboard_buf {
void* buf; // 1d array, buffer input virtual line, works as a ldisc
int max_buf;
int tail;
} keyboard_buf;
#include "console.h"
void select_console(int nr_console);
@ -60,4 +92,8 @@ int init_serial();
char read_serial();
void write_serial(char a);
void vga_tty_init(NTTY* tty);
void vga_tty_write(NTTY* tty, char ch);
void vga_tty_flush(NTTY* tty);
#endif /* _ORANGES_TTY_H_ */

View File

@ -31,6 +31,7 @@ KERN_SRCFILES :=kernel/kernel.asm \
kernel/testfunc.c \
kernel/protect.c \
kernel/serialport.c \
kernel/vga.c \
lib/klib.c \
lib/kliba.asm \

View File

@ -61,6 +61,11 @@ void init_screen(TTY* tty)
}
static inline void write_char_c(int pos, char ch) {
u16* pch = (u16*)K_PHY2LIN(V_MEM_BASE + pos);\
*pch = (0x0f << 8) | ch;
}
/*****************************************************************************
* out_char
*****************************************************************************/
@ -88,14 +93,16 @@ void out_char(CONSOLE* con, char ch)
//*(pch - 2) = ' ';
//*(pch - 1) = DEFAULT_CHAR_COLOR;
disp_pos = con->cursor*2;
write_char(' ');
// write_char(' ');
write_char_c(disp_pos, ' ');
}
break;
default:
//*pch++ = ch;
//*pch++ = DEFAULT_CHAR_COLOR;
disp_pos = con->cursor*2;
write_char(ch);
// write_char(ch);
write_char_c(disp_pos, ch);
con->cursor++;
break;

View File

@ -127,7 +127,7 @@ void initial()
do_vclose(stdout);
do_vclose(stderr);
exec("orange/shell_0.bin");
exec("orange/test.bin");
while(1);
}

View File

@ -34,19 +34,19 @@ int kernel_main()
init_serial();
int error;
disp_pos = 0;
for (int i = 0; i < 25; i++) {
for (int j = 0; j < 80; j++) {
disp_str(" ");
}
}
// disp_pos = 0;
// for (int i = 0; i < 25; i++) {
// for (int j = 0; j < 80; j++) {
// disp_str(" ");
// }
// }
disp_pos = 0;
kprintf("-----Kernel Initialization Begins-----\n");
kernel_initial = 1; //kernel is in initial state. added by xw, 18/5/31
init();//内存管理模块的初始化 add by liang
init_tty_main();
//initialize PCBs, added by xw, 18/5/26
error = initialize_processes();
if(error != 0)

View File

@ -9,6 +9,10 @@
#include "proto.h"
#include "keyboard.h"
#include "x86.h"
#include "memman.h"
#include "stdio.h"
#define DEBUGNEW
int current_console; //当前显示在屏幕上的console
void tty_write(TTY *tty, char *buf, int len);
@ -20,6 +24,27 @@ static void tty_dev_read(TTY *tty);
static void tty_dev_write(TTY *tty);
static void put_key(TTY *tty, u32 key);
#ifdef DEBUGNEW
static NTTY ntty_table[3];
static int cur_ntty = 0;
static keyboard_buf keyboardbuf[3];
static vga_buf vgabuf[3];
void init_tty_main() {
NTTY* tty;
for (int i = 0; i < 3; ++ i) {
tty = &ntty_table[i];
tty->driver_type = 1; // vga
// tty->input_buf = (void*)do_kmalloc(sizeof(keyboard_buf));
// tty->output_buf = (void*)do_kmalloc(sizeof(vga_buf));
tty->input_buf = &keyboardbuf[i];
tty->output_buf = &vgabuf[i];
vga_tty_init(tty);
}
}
#endif
void in_process(TTY *p_tty, u32 key)
{
int real_line = p_tty->console->orig / SCR_WIDTH;
@ -87,6 +112,17 @@ void in_process(TTY *p_tty, u32 key)
void task_tty()
{
#ifdef DEBUGNEW
// NTTY* p_tty;
// for (p_tty = ntty_table; p_tty < ntty_table + 3; ++ p_tty) {
// init_ntty(p_tty);
// }
while(1)
{
// vga_tty_flush(&ntty_table[cur_ntty]);
}
#else
TTY *p_tty;
for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++)
{
@ -118,6 +154,7 @@ void task_tty()
} while (p_tty->ibuf_cnt);
}
}
#endif
}
static void init_tty(TTY *p_tty)
@ -258,8 +295,15 @@ static void put_key(TTY *tty, u32 key)
*****************************************************************************/
void tty_write(TTY *tty, char *buf, int len)
{
#ifdef DEBUGNEW
while (--len >= 0) {
vga_tty_write(&ntty_table[cur_ntty], *buf++);
}
vga_tty_flush(&ntty_table[cur_ntty]);
#else
while (--len >= 0)
out_char(tty->console, *buf++);
#endif
}
/*****************************************************************************

246
kernel/vga.c Normal file
View File

@ -0,0 +1,246 @@
#include "type.h"
#include "stdio.h"
#include "const.h"
#include "protect.h"
#include "string.h"
#include "proc.h"
#include "tty.h"
#include "console.h"
#include "global.h"
#include "keyboard.h"
#include "proto.h"
#include "x86.h"
#include "memman.h"
#include "assert.h"
/*****************************************************************************
* Low level vga driver
*****************************************************************************/
/*****************************************************************************
* Display the cursor by setting CRTC (6845 compatible) registers.
*
* @param position Position of the cursor based on the beginning of the video
* memory. Note that it counts in WORDs, not in BYTEs.
*****************************************************************************/
static inline void vga_set_cursor(unsigned int position)
{
disable_int();
outb(CRTC_ADDR_REG, CURSOR_H);
outb(CRTC_DATA_REG, (position >> 8) & 0xFF);
outb(CRTC_ADDR_REG, CURSOR_L);
outb(CRTC_DATA_REG, position & 0xFF);
enable_int();
}
static inline void vga_disable_cursor()
{
outb(CRTC_ADDR_REG, 0x0A);
outb(CRTC_DATA_REG, 0x20);
}
static inline void vga_enable_cursor(u8 cursor_start, u8 cursor_end)
{
outb(0x3D4, 0x0A);
outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start);
outb(0x3D4, 0x0B);
outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end);
}
/*****************************************************************************
* Routine for hardware screen scrolling.
*
* @param addr Offset in the video memory.
*****************************************************************************/
static inline void vga_set_video_start_addr(u32 addr)
{
disable_int();
outb(CRTC_ADDR_REG, START_ADDR_H);
outb(CRTC_DATA_REG, (addr >> 8) & 0xFF);
outb(CRTC_ADDR_REG, START_ADDR_L);
outb(CRTC_DATA_REG, addr & 0xFF);
enable_int();
}
/*****************************************************************************
* Write data directly to Video Memory cell
*
* @param pos text mode position(pos*2 yourself)
* @param dat data to be written, with format [ BG | FG | ASCII ]
*****************************************************************************/
static inline void vga_put_raw(u32 pos, u16 dat) {
u16* pch = (u16*)K_PHY2LIN(V_MEM_BASE + pos);
*pch = dat;
}
/*****************************************************************************
* copy a whole screen of text mode data into video memory, assume that screen
* width is 80 or 40
*
* @param src memory block with the same size as text mode video memory()
*****************************************************************************/
static inline void vga_flush_screen(void* src) {
u32* _src = src;
u32* dst = (u32*)K_PHY2LIN(V_MEM_BASE);
for (int i = 0; i < SCR_SIZE * sizeof(u16) / sizeof(u32); ++ i) {
*dst ++ = *_src ++;
}
}
/*****************************************************************************
* copy a whole screen of text mode data into video memory, assume that screen
* width is 80 or 40
*
* @param src memory block with the same size as text mode video memory()
*****************************************************************************/
static inline void vga_flush_line(void* src, int line_no) {
u32* _src = src;
u32* dst = (u32*)K_PHY2LIN(V_MEM_BASE + line_no * SCR_WIDTH * 2);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++ i) {
*dst ++ = *_src ++;
}
}
static inline void vga_flush_blankline(int line_no) {
u32* dst = (u32*)K_PHY2LIN(V_MEM_BASE + line_no * SCR_WIDTH * 2);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++ i) {
*dst ++ = (BLANK << 16) | BLANK;
}
}
/*****************************************************************************
* tty - vga driver
*****************************************************************************/
static u16 pagebuf[3][SCR_BUFSIZE];
void vga_tty_init(NTTY* tty) {
assert(tty->driver_type == 1);
assert(tty->output_buf);
vga_buf* vga = tty->output_buf;
// vga->buf = (void*)do_kmalloc(sizeof(u16) * SCR_BUFSIZE);
vga->buf = (void*)pagebuf[0];
// kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line);
vga->cur_col = vga->cur_row = 0;
// buf->max_line = SCR_BUFSIZE / SCR_WIDTH;
vga->scr_top_line = vga->scr_cur_line = 0;
vga->head_line = 0;
u32* ptr_buf = (u32*) vga->buf;
for (int i = 0; i < SCR_BUFSIZE * sizeof(u16) / sizeof(u32); ++i) {
ptr_buf[i] = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space
}
kprintf("%p 0x%x %d\n", vga->buf, ((u32*)vga->buf)[20], vga->scr_cur_line);
}
#define INDEX(row, col) ((row) * SCR_WIDTH + (col))
#define NEXTLINE(row) (((row) + 1) % SCR_MAXLINE)
#define LASTLINE(row) (((row) - 1) >= 0 ? ((row) - 1) % SCR_MAXLINE : SCR_MAXLINE)
static void newline(vga_buf* vgabuf) {
vgabuf->cur_col = 0;
// kprintf("bf %x\n", vgabuf->scr_cur_line);
vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line);
// kprintf("af %x\n", vgabuf->scr_cur_line);
vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line);
if (vgabuf->cur_row == SCR_HEIGHT) {
// auto scroll
vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line);
if(vgabuf->scr_cur_line == vgabuf->head_line) {
vgabuf->head_line = NEXTLINE(vgabuf->head_line);
// remember to fill blank the old line
u32* ptr_buf = (u32*) (vgabuf->buf + sizeof(u16) * vgabuf->head_line * SCR_WIDTH);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) {
*ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space
}
}
}
}
void vga_tty_write(NTTY* tty, char ch) {
// assert(tty->driver_type == 1);
// assert(tty->output_buf);
vga_buf* vga = tty->output_buf;
u16* buf = vga->buf;
// kprintf("vga_tty_write %c to %d %d\n", ch, vga->scr_cur_line, vga->cur_col);
switch (ch)
{
case '\n':
newline(vga);
break;
case '\r':
vga->cur_col = 0;
break;
case '\b':
// this implementation is mimic to usual linux shell
// it moves cursor left but neither crosses line nor delete character
if (vga->cur_col > 0) {
vga->cur_col --;
}
break;
default:
buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(DEFAULT_CHAR_COLOR, ch);
vga->cur_col ++;
if (vga->cur_col == SCR_WIDTH) {
newline(vga);
}
break;
}
vga->cur_row = abs(vga->scr_cur_line - vga->scr_top_line);
// kprintf("row: %d; ", vga->cur_row);
}
void vga_tty_flush(NTTY* tty) {
vga_buf* vga = tty->output_buf;
u16* buf = vga->buf;
int i, cur_line;
vga_set_cursor(INDEX(vga->cur_row, vga->cur_col));
if (vga->cur_row == SCR_WIDTH - 1) {
vga_flush_screen(&buf[INDEX(vga->scr_top_line, 0)]);
}
else {
cur_line = vga->scr_top_line;
for (i = 0; i <= vga->cur_row; ++ i){
vga_flush_line(&buf[INDEX(cur_line, 0)], i);
cur_line = NEXTLINE(cur_line);
}
for (; i < SCR_WIDTH; ++ i) {
vga_flush_blankline(i);
}
}
// kprintf("flush: row=%d, top=%d, cur=%d\n", vga->cur_row, vga->scr_top_line, vga->scr_cur_line);
}
void vga_tty_scroll(NTTY* tty, int direction) {
vga_buf* vga = tty->output_buf;
u16* buf = vga->buf;
if (direction > 0) {
// down
if (vga->scr_top_line == vga->scr_cur_line) return;
vga->scr_top_line = NEXTLINE(vga->scr_top_line);
}
else {
if (vga->scr_top_line == vga->head_line) return;
vga->scr_top_line = LASTLINE(vga->scr_top_line);
}
vga->cur_row = abs(vga->scr_cur_line - vga->scr_top_line);
if (vga->cur_row >= SCR_HEIGHT) {
vga_disable_cursor();
}
else {
vga_enable_cursor(0, 15);
}
}
void vga_scroll_to_cur(NTTY* tty) {
vga_buf* vga = tty->output_buf;
u16* buf = vga->buf;
// vga->scr_top_line = vga->scr_cur_line
}
void vga_tty_select(NTTY* tty) {
//
}

View File

@ -8,6 +8,7 @@ USERLIB_OBJS := $(patsubst %.asm, $(OBJDIR)/%.o, $(USERLIB_OBJS))
# 这里给我整不会了文件名只能长度为16位否则会寄原因还挺难找
USER_SRCS := user/ptTest.c \
user/shell_0.c \
user/test.c \
USER_BINS := $(patsubst %.c, $(OBJDIR)/%.bin, $(USER_SRCS))
USER_BASENAMES := $(patsubst $(OBJDIR)/user/%, %, $(USER_BINS))

36
user/test.c Normal file
View File

@ -0,0 +1,36 @@
#include "type.h"
#include "const.h"
#include "protect.h"
#include "string.h"
#include "proc.h"
#include "global.h"
#include "proto.h"
#include "stdio.h"
int main(int arg, char *argv[])
{
int stdin = open("dev_tty0", O_RDWR);
int stdout = open("dev_tty0", O_RDWR);
int stderr = open("dev_tty0", O_RDWR);
char buf[1024];
int pid;
int times = 0;
for (int i = 0; i < 20; ++ i) {
printf("test %d\n", i);
}
for (int i = 0; i < 2; ++ i) {
printf("1111111111");
printf("2222222222");
printf("3333333333");
printf("4444444444");
printf("5555555555");
printf("6666666666");
printf("7777777777");
printf("8888888888");
printf("9999999999\r\b\b\n");
}
while(1);
return 0;
}