This commit is contained in:
catfood 2022-12-23 23:22:37 +08:00
commit 4bd7c1e46d
9 changed files with 1546 additions and 1145 deletions

View File

@ -14,7 +14,6 @@
#ifndef _ORANGES_CONSOLE_H_
#define _ORANGES_CONSOLE_H_
/* CONSOLE */
typedef struct s_console
{
@ -26,20 +25,19 @@ typedef struct s_console
unsigned int current_line;
} CONSOLE;
#define SCR_UP 1 /* scroll upward */
#define SCR_DN -1 /* scroll downward */
#define SCR_WIDTH 80
#define SCR_HEIGHT 25
#define SCR_SIZE (SCR_HEIGHT * SCR_WIDTH)
#define SCR_BUFSIZE (8 * SCR_SIZE)
#define SCR_BUFSIZE (2 * SCR_SIZE)
#define SCR_MAXLINE (SCR_BUFSIZE / SCR_WIDTH)
#define DEFAULT_CHAR_COLOR (MAKE_COLOR(BLACK, WHITE | BRIGHT))
#define DEFAULT_CHAR_COLOR ((MAKE_COLOR(BLACK, WHITE | BRIGHT)) << 8)
#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 MAKE_CELL(clr, ch) (clr | ch)
#define BLANK MAKE_CELL(DEFAULT_CHAR_COLOR, ' ')
#endif /* _ORANGES_CONSOLE_H_ */

View File

@ -14,7 +14,6 @@
#ifndef _ORANGES_TTY_H_
#define _ORANGES_TTY_H_
#define TTY_IN_BYTES 256 /* tty input queue size */
#define TTY_OUT_BUF_LEN 2 /* tty output buffer size */
@ -49,7 +48,8 @@ typedef struct s_tty
struct s_console *console;
} TTY;
typedef struct MouseState{
typedef struct MouseState
{
u8 mouse_lb;
u8 mouse_mb;
u8 mouse_rb;
@ -58,14 +58,23 @@ typedef struct MouseState{
int mouse_y;
} MouseState;
typedef struct n_tty {
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 {
enum CSI_state
{
CSI_ESC,
CSI_BRACKET,
CSI_PARAM1,
CSI_PARAM2
};
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;
@ -73,6 +82,11 @@ typedef struct vga_buf {
int head_line; // for circular buffer use
int cur_row;
int cur_col; // cursor position, on screen
enum CSI_state CSI;
i16 param1; // the first param of CSI
i16 param2; // the second of CSI
u16 color;
} vga_buf;
typedef struct keyboard_buf {
@ -106,6 +120,9 @@ int ps2_tty_read(NTTY* tty, u8* buf, int nr);
#define NEXT(x, _max) (((x) + 1) % (_max))
#define LAST(x, _max) (((x) - 1) >= 0 ? ((x) - 1) % (_max) : (_max) - 1)
#define DEBUGNEW
#define FOREGROUND(color) ((u16)(color & 0xf) << 8)
#define BACKGROUND(color) ((u16)(color & 0xf) << 12)
extern int cur_ntty;
extern NTTY ntty_table[3];
#endif /* _ORANGES_TTY_H_ */

View File

@ -47,22 +47,24 @@ void init_screen(TTY* tty)
tty->console->is_full = 0;
tty->console->current_line = 0;
if(nr_tty==0){
if (nr_tty == 0)
{
tty->console->cursor = disp_pos / 2;
}
const char prompt[] = "[TTY #?]\n";
const char *p = prompt;
for (; *p; p++){
for (; *p; p++)
{
out_char(tty->console, *p == '?' ? nr_tty + '0' : *p);
}
set_cursor(tty->console->cursor);
}
static inline void write_char_c(int pos, char ch) {
u16* pch = (u16*)K_PHY2LIN(V_MEM_BASE + pos);\
static inline void write_char_c(int pos, char ch)
{
u16 *pch = (u16 *)K_PHY2LIN(V_MEM_BASE + pos);
*pch = (0x0f << 8) | ch;
}
@ -83,12 +85,14 @@ void out_char(CONSOLE* con, char ch)
int cursor_x = (con->cursor - con->orig) % SCR_WIDTH;
int cursor_y = (con->cursor - con->orig) / SCR_WIDTH;
switch(ch) {
switch (ch)
{
case '\n':
con->cursor = con->orig + SCR_WIDTH * (cursor_y + 1);
break;
case '\b':
if (con->cursor > con->orig) {
if (con->cursor > con->orig)
{
con->cursor--;
//*(pch - 2) = ' ';
//*(pch - 1) = DEFAULT_CHAR_COLOR;
@ -108,9 +112,8 @@ void out_char(CONSOLE* con, char ch)
break;
}
if (con->cursor - con->orig >= con->con_size) {
if (con->cursor - con->orig >= con->con_size)
{
cursor_x = (con->cursor - con->orig) % SCR_WIDTH;
cursor_y = (con->cursor - con->orig) / SCR_WIDTH;
int cp_orig = con->orig + (cursor_y + 1) * SCR_WIDTH - SCR_SIZE;
@ -125,7 +128,8 @@ void out_char(CONSOLE* con, char ch)
// assert(con->cursor - con->orig < con->con_size);
while (con->cursor >= con->crtc_start + SCR_SIZE ||
con->cursor < con->crtc_start) {
con->cursor < con->crtc_start)
{
scroll_screen(con, SCR_UP);
clear_screen(con->cursor, SCR_WIDTH);
@ -136,7 +140,6 @@ void out_char(CONSOLE* con, char ch)
enable_int();
}
/*****************************************************************************
* clear_screen
*****************************************************************************/
@ -149,13 +152,13 @@ void out_char(CONSOLE* con, char ch)
static void clear_screen(int pos, int len)
{
u8 *pch = (u8 *)K_PHY2LIN(V_MEM_BASE + pos * 2);
while (--len >= 0) {
while (--len >= 0)
{
*pch++ = ' ';
*pch++ = DEFAULT_CHAR_COLOR;
*pch++ = (u8)(DEFAULT_CHAR_COLOR >> 8);
}
}
/*****************************************************************************
* is_current_console
*****************************************************************************/
@ -171,7 +174,6 @@ int is_current_console(CONSOLE* con)
return (con == &console_table[current_console]);
}
/*****************************************************************************
* set_cursor
*****************************************************************************/
@ -191,7 +193,6 @@ static void set_cursor(unsigned int position)
enable_int();
}
/*****************************************************************************
* set_video_start_addr
*****************************************************************************/
@ -210,7 +211,6 @@ static void set_video_start_addr(u32 addr)
enable_int();
}
/*****************************************************************************
* select_console
*****************************************************************************/
@ -221,12 +221,12 @@ static void set_video_start_addr(u32 addr)
*****************************************************************************/
void select_console(int nr_console)
{
if ((nr_console < 0) || (nr_console >= NR_CONSOLES)) return;
if ((nr_console < 0) || (nr_console >= NR_CONSOLES))
return;
flush(&console_table[current_console = nr_console]);
}
/*****************************************************************************
* scroll_screen
*****************************************************************************/
@ -259,43 +259,52 @@ void scroll_screen(CONSOLE* con, int dir)
oldest = con->is_full ? (newest + SCR_WIDTH) % con->con_size : 0;
scr_top = con->crtc_start - con->orig;
if (dir == SCR_DN) {
if (!con->is_full && scr_top > 0) {
if (dir == SCR_DN)
{
if (!con->is_full && scr_top > 0)
{
con->crtc_start -= SCR_WIDTH;
}
else if (con->is_full && scr_top != oldest) {
if (con->cursor - con->orig >= con->con_size - SCR_SIZE) {
else if (con->is_full && scr_top != oldest)
{
if (con->cursor - con->orig >= con->con_size - SCR_SIZE)
{
if (con->crtc_start != con->orig)
con->crtc_start -= SCR_WIDTH;
}
else if (con->crtc_start == con->orig) {
else if (con->crtc_start == con->orig)
{
scr_top = con->con_size - SCR_SIZE;
con->crtc_start = con->orig + scr_top;
}
else {
else
{
con->crtc_start -= SCR_WIDTH;
}
}
}
else if (dir == SCR_UP) {
if (!con->is_full && newest >= scr_top + SCR_SIZE) {
else if (dir == SCR_UP)
{
if (!con->is_full && newest >= scr_top + SCR_SIZE)
{
con->crtc_start += SCR_WIDTH;
}
else if (con->is_full && scr_top + SCR_SIZE - SCR_WIDTH != newest) {
else if (con->is_full && scr_top + SCR_SIZE - SCR_WIDTH != newest)
{
if (scr_top + SCR_SIZE == con->con_size)
con->crtc_start = con->orig;
else
con->crtc_start += SCR_WIDTH;
}
}
else {
else
{
// assert(dir == SCR_DN || dir == SCR_UP);
}
flush(con);
}
/*****************************************************************************
* flush
*****************************************************************************/
@ -307,7 +316,8 @@ void scroll_screen(CONSOLE* con, int dir)
*****************************************************************************/
static void flush(CONSOLE *con)
{
if (is_current_console(con)) {
if (is_current_console(con))
{
set_cursor(con->cursor);
set_video_start_addr(con->crtc_start);
}

View File

@ -65,7 +65,6 @@ static int memcmp(const void *s1, const void *s2, int n);
//~xw
int get_fs_dev(int drive, int fs_type); // added by mingxuan 2020-10-27
// added by mingxuan 2020-10-27
int get_fs_dev(int drive, int fs_type)
{
@ -105,7 +104,8 @@ void init_fs()
kprintf("Superblock Address:0x%x \n", sb);
if(sb->magic != MAGIC_V1) { //deleted by mingxuan 2019-5-20
if (sb->magic != MAGIC_V1)
{ // deleted by mingxuan 2019-5-20
mkfs();
kprintf("Make file system Done.\n");
read_super_block(orange_dev); // modified by mingxuan 2020-10-27
@ -199,7 +199,6 @@ static void mkfs()
for (i = 0; i < (NR_CONSOLES + 3); i++) // modified by mingxuan 2019-5-22
fsbuf[0] |= 1 << i;
WR_SECT(orange_dev, 2, fsbuf); // modified by mingxuan 2020-10-27
/************************/
@ -228,13 +227,15 @@ static void mkfs()
int bit_left = INSTALL_NR_SECTORS;
int cur_sect = bit_offset / (SECTOR_SIZE * 8);
RD_SECT(orange_dev, 2 + sb.nr_imap_sects + cur_sect, fsbuf); // modified by mingxuan 2020-10-27
while (bit_left) {
while (bit_left)
{
int byte_off = bit_off_in_sect / 8;
/* this line is ineffecient in a loop, but I don't care */
fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8);
bit_left--;
bit_off_in_sect++;
if (bit_off_in_sect == (SECTOR_SIZE * 8)) {
if (bit_off_in_sect == (SECTOR_SIZE * 8))
{
WR_SECT(orange_dev, 2 + sb.nr_imap_sects + cur_sect, fsbuf); // modified by mingxuan 2020-10-27
cur_sect++;
RD_SECT(orange_dev, 2 + sb.nr_imap_sects + cur_sect, fsbuf); // modified by mingxuan 2020-10-27
@ -261,7 +262,8 @@ static void mkfs()
pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
/* inode of `/dev_tty0~2' */
for (i = 0; i < NR_CONSOLES; i++) {
for (i = 0; i < NR_CONSOLES; i++)
{
pi = (struct inode *)(fsbuf + (INODE_SIZE * (i + 1)));
pi->i_mode = I_CHAR_SPECIAL;
pi->i_size = 0;
@ -289,10 +291,12 @@ static void mkfs()
strcpy(pde->name, ".");
/* dir entries of `/dev_tty0~2' */
for (i = 0; i < NR_CONSOLES; i++) {
for (i = 0; i < NR_CONSOLES; i++)
{
pde++;
pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
switch(i) {
switch (i)
{
case 0:
strcpy(pde->name, "dev_tty0");
break;
@ -419,13 +423,15 @@ static int do_open(MESSAGE *fs_msg)
/* find a free slot in PROCESS::filp[] */
int i;
for (i = 0; i < NR_FILES; i++) { //modified by mingxuan 2019-5-20
if (p_proc_current->task.filp[i] == 0) {
for (i = 0; i < NR_FILES; i++)
{ // modified by mingxuan 2019-5-20
if (p_proc_current->task.filp[i] == 0)
{
fd = i;
break;
}
}
// printf("%d\n", fd);
assert(0 <= fd && fd < NR_FILES);
/* find a free slot in f_desc_table[] */
@ -438,15 +444,19 @@ static int do_open(MESSAGE *fs_msg)
int inode_nr = search_file(pathname);
struct inode *pin = 0;
if (flags & O_CREAT) {
if (inode_nr) {
if (flags & O_CREAT)
{
if (inode_nr)
{
return -1;
}
else {
else
{
pin = create_file(pathname, flags);
}
}
else {
else
{
char filename[MAX_PATH];
struct inode *dir_inode;
if (strip_path(filename, pathname, &dir_inode) != 0)
@ -454,7 +464,8 @@ static int do_open(MESSAGE *fs_msg)
pin = get_inode(dir_inode->i_dev, inode_nr); // modified by mingxuan 2019-5-20
}
if (pin) {
if (pin)
{
/* connects proc with file_descriptor */
p_proc_current->task.filp[fd] = &f_desc_table[i];
@ -468,24 +479,30 @@ static int do_open(MESSAGE *fs_msg)
int imode = pin->i_mode & I_TYPE_MASK;
if (imode == I_CHAR_SPECIAL) {
if (imode == I_CHAR_SPECIAL)
{
// MESSAGE driver_msg;
// int dev = pin->i_start_sect;
//?
}
else if (imode == I_DIRECTORY) {
if(pin->i_num != ROOT_INODE) {
else if (imode == I_DIRECTORY)
{
if (pin->i_num != ROOT_INODE)
{
panic("pin->i_num != ROOT_INODE");
}
}
else {
if(pin->i_mode != I_REGULAR) {
else
{
if (pin->i_mode != I_REGULAR)
{
panic("Panic: pin->i_mode != I_REGULAR");
}
}
}
else {
else
{
return -1;
}
@ -544,22 +561,24 @@ static struct inode * create_file(char * path, int flags)
*****************************************************************************/
static int memcmp(const void *s1, const void *s2, int n)
{
if ((s1 == 0) || (s2 == 0)) { /* for robustness */
if ((s1 == 0) || (s2 == 0))
{ /* for robustness */
return (s1 - s2);
}
const char *p1 = (const char *)s1;
const char *p2 = (const char *)s2;
int i;
for (i = 0; i < n; i++,p1++,p2++) {
if (*p1 != *p2) {
for (i = 0; i < n; i++, p1++, p2++)
{
if (*p1 != *p2)
{
return (*p1 - *p2);
}
}
return 0;
}
/*****************************************************************************
* search_file
*****************************************************************************/
@ -599,11 +618,13 @@ static int search_file(char * path)
int m = 0;
struct dir_entry *pde;
char fsbuf[SECTOR_SIZE]; // local array, to substitute global fsbuf. added by xw, 18/12/27
for (i = 0; i < nr_dir_blks; i++) {
for (i = 0; i < nr_dir_blks; i++)
{
// RD_SECT_SCHED(dir_inode->i_dev, dir_blk0_nr + i, fsbuf); //modified by xw, 18/12/27
RD_SECT(dir_inode->i_dev, dir_blk0_nr + i, fsbuf); // modified by mingxuan 2019-5-20
pde = (struct dir_entry *)fsbuf;
for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) {
for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++, pde++)
{
if (memcmp(filename, pde->name, MAX_FILENAME_LEN) == 0)
return pde->inode_nr;
if (++m > nr_dir_entries)
@ -657,7 +678,8 @@ static int strip_path(char * filename, const char * pathname, struct inode** ppi
if (*s == '/')
s++;
while (*s) { /* check each character */
while (*s)
{ /* check each character */
if (*s == '/')
return -1;
*t++ = *s++;
@ -711,7 +733,6 @@ void read_super_block(int dev) //modified by mingxuan 2020-10-30
super_block[i].fs_type = ORANGE_TYPE; // added by mingxuan 2020-10-30
}
/*****************************************************************************
* get_super_block
*****************************************************************************/
@ -725,15 +746,14 @@ void read_super_block(int dev) //modified by mingxuan 2020-10-30
struct super_block *get_super_block(int dev) // modified by mingxuan 2020-10-30
{
struct super_block *sb = super_block;
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++){
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++)
{
if (sb->sb_dev == dev)
return sb;
}
return 0;
}
/*****************************************************************************
* get_inode
*****************************************************************************/
@ -754,15 +774,19 @@ static struct inode * get_inode(int dev, int num)
struct inode *p;
struct inode *q = 0;
for (p = &inode_table[0]; p < &inode_table[NR_INODE]; p++) {
if (p->i_cnt) { /* not a free slot */
if ((p->i_dev == dev) && (p->i_num == num)) {
for (p = &inode_table[0]; p < &inode_table[NR_INODE]; p++)
{
if (p->i_cnt)
{ /* not a free slot */
if ((p->i_dev == dev) && (p->i_num == num))
{
/* this is the inode we want */
p->i_cnt++;
return p;
}
}
else { /* a free slot */
else
{ /* a free slot */
if (!q) /* q hasn't been assigned yet */
q = p; /* q <- the 1st free slot */
}
@ -781,8 +805,7 @@ static struct inode * get_inode(int dev, int num)
RD_SECT(dev, blk_nr, fsbuf); // added by xw, 18/12/27
struct inode *pinode =
(struct inode *)((u8 *)fsbuf +
((num - 1 ) % (SECTOR_SIZE / INODE_SIZE))
* INODE_SIZE);
((num - 1) % (SECTOR_SIZE / INODE_SIZE)) * INODE_SIZE);
q->i_mode = pinode->i_mode;
q->i_size = pinode->i_size;
q->i_start_sect = pinode->i_start_sect;
@ -798,15 +821,19 @@ static struct inode * get_inode_sched(int dev, int num)
struct inode *p;
struct inode *q = 0;
for (p = &inode_table[0]; p < &inode_table[NR_INODE]; p++) {
if (p->i_cnt) { /* not a free slot */
if ((p->i_dev == dev) && (p->i_num == num)) {
for (p = &inode_table[0]; p < &inode_table[NR_INODE]; p++)
{
if (p->i_cnt)
{ /* not a free slot */
if ((p->i_dev == dev) && (p->i_num == num))
{
/* this is the inode we want */
p->i_cnt++;
return p;
}
}
else { /* a free slot */
else
{ /* a free slot */
if (!q) /* q hasn't been assigned yet */
q = p; /* q <- the 1st free slot */
}
@ -825,8 +852,7 @@ static struct inode * get_inode_sched(int dev, int num)
RD_SECT_SCHED(dev, blk_nr, fsbuf); // added by xw, 18/12/27
struct inode *pinode =
(struct inode *)((u8 *)fsbuf +
((num - 1 ) % (SECTOR_SIZE / INODE_SIZE))
* INODE_SIZE);
((num - 1) % (SECTOR_SIZE / INODE_SIZE)) * INODE_SIZE);
q->i_mode = pinode->i_mode;
q->i_size = pinode->i_size;
q->i_start_sect = pinode->i_start_sect;
@ -867,8 +893,7 @@ static void sync_inode(struct inode * p)
char fsbuf[SECTOR_SIZE]; // local array, to substitute global fsbuf. added by xw, 18/12/27
RD_SECT(p->i_dev, blk_nr, fsbuf); // modified by mingxuan 2019-5-20
pinode = (struct inode *)((u8 *)fsbuf +
(((p->i_num - 1) % (SECTOR_SIZE / INODE_SIZE))
* INODE_SIZE));
(((p->i_num - 1) % (SECTOR_SIZE / INODE_SIZE)) * INODE_SIZE));
pinode->i_mode = p->i_mode;
pinode->i_size = p->i_size;
pinode->i_start_sect = p->i_start_sect;
@ -937,15 +962,18 @@ static void new_dir_entry(struct inode *dir_inode,int inode_nr,char *filename)
int i, j;
char fsbuf[SECTOR_SIZE]; // local array, to substitute global fsbuf. added by xw, 18/12/27
for (i = 0; i < nr_dir_blks; i++) {
for (i = 0; i < nr_dir_blks; i++)
{
RD_SECT(dir_inode->i_dev, dir_blk0_nr + i, fsbuf); // modified by mingxuan 2019-5-20
pde = (struct dir_entry *)fsbuf;
for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) {
for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++, pde++)
{
if (++m > nr_dir_entries)
break;
if (pde->inode_nr == 0) { /* it's a free slot */
if (pde->inode_nr == 0)
{ /* it's a free slot */
new_de = pde;
break;
}
@ -954,7 +982,8 @@ static void new_dir_entry(struct inode *dir_inode,int inode_nr,char *filename)
new_de) /* free slot is found */
break;
}
if (!new_de) { /* reached the end of the dir */
if (!new_de)
{ /* reached the end of the dir */
new_de = pde;
dir_inode->i_size += DIR_ENTRY_SIZE;
}
@ -968,7 +997,6 @@ static void new_dir_entry(struct inode *dir_inode,int inode_nr,char *filename)
sync_inode(dir_inode);
}
/*****************************************************************************
* alloc_imap_bit
*****************************************************************************/
@ -989,15 +1017,19 @@ static int alloc_imap_bit(int dev)
char fsbuf[SECTOR_SIZE]; // local array, to substitute global fsbuf. added by xw, 18/12/27
for (i = 0; i < sb->nr_imap_sects; i++) {
for (i = 0; i < sb->nr_imap_sects; i++)
{
RD_SECT(dev, imap_blk0_nr + i, fsbuf); // modified by mingxuan 2019-5-20
for (j = 0; j < SECTOR_SIZE; j++) {
for (j = 0; j < SECTOR_SIZE; j++)
{
if (fsbuf[j] == '\xFF') // modified by xw, 18/12/28
continue;
/* skip `1' bits */
for (k = 0; ((fsbuf[j] >> k) & 1) != 0; k++) {}
for (k = 0; ((fsbuf[j] >> k) & 1) != 0; k++)
{
}
/* i: sector index; j: byte index; k: bit index */
inode_nr = (i * SECTOR_SIZE + j) * 8 + k;
@ -1042,24 +1074,31 @@ static int alloc_smap_bit(int dev, int nr_sects_to_alloc)
int free_sect_nr = 0;
char fsbuf[SECTOR_SIZE]; // local array, to substitute global fsbuf. added by xw, 18/12/27
for (i = 0; i < sb->nr_smap_sects; i++) { /* smap_blk0_nr + i :
for (i = 0; i < sb->nr_smap_sects; i++)
{ /* smap_blk0_nr + i :
current sect nr. */
// RD_SECT_SCHED(dev, smap_blk0_nr + i, fsbuf); //modified by xw, 18/12/27
RD_SECT(dev, smap_blk0_nr + i, fsbuf); // modified by mingxuan 2019-5-20
/* byte offset in current sect */
for (j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++) {
for (j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++)
{
k = 0;
if (!free_sect_nr) {
if (!free_sect_nr)
{
/* loop until a free bit is found */
// if (fsbuf[j] == 0xFF) continue;
if (fsbuf[j] == '\xFF') continue; //modified by xw, 18/12/28
for (; ((fsbuf[j] >> k) & 1) != 0; k++) {}
if (fsbuf[j] == '\xFF')
continue; // modified by xw, 18/12/28
for (; ((fsbuf[j] >> k) & 1) != 0; k++)
{
}
free_sect_nr = (i * SECTOR_SIZE + j) * 8 +
k - 1 + sb->n_1st_sect;
}
for (; k < 8; k++) { /* repeat till enough bits are set */
for (; k < 8; k++)
{ /* repeat till enough bits are set */
// assert(((fsbuf[j] >> k) & 1) == 0);
fsbuf[j] |= (1 << k);
if (--nr_sects_to_alloc == 0)
@ -1180,7 +1219,6 @@ int real_write(int fd, const void *buf, int count) //注意:buf的类型被修
return fs_msg.CNT;
}
/*****************************************************************************
* do_rdwt
*****************************************************************************/
@ -1210,26 +1248,32 @@ static int do_rdwt(MESSAGE *fs_msg)
int imode = pin->i_mode & I_TYPE_MASK;
if (imode == I_CHAR_SPECIAL) {
if (imode == I_CHAR_SPECIAL)
{
int t = fs_msg->type == READ ? DEV_READ : DEV_WRITE;
fs_msg->type = t;
// added by mingxuan 2019-5-19
int dev = pin->i_start_sect;
int nr_tty = MINOR(dev);
if(MAJOR(dev) != DEV_CHAR_TTY) {
if (MAJOR(dev) != DEV_CHAR_TTY)
{
panic("Error: MAJOR(dev) should be DEV_CHAR_TTY(4)\n");
}
if(fs_msg->type == DEV_READ){
if (fs_msg->type == DEV_READ)
{
fs_msg->CNT = tty_read(&tty_table[nr_tty], buf, len);
}else if(fs_msg->type==DEV_WRITE){
}
else if (fs_msg->type == DEV_WRITE)
{
tty_write(&tty_table[nr_tty], buf, len);
}
return fs_msg->CNT;
}
else {
else
{
int pos_end;
if (fs_msg->type == READ)
pos_end = min(pos + len, pin->i_size);
@ -1250,7 +1294,8 @@ static int do_rdwt(MESSAGE *fs_msg)
char fsbuf[SECTOR_SIZE]; // local array, to substitute global fsbuf. added by xw, 18/12/27
for (i = rw_sect_min; i <= rw_sect_max; i += chunk) {
for (i = rw_sect_min; i <= rw_sect_max; i += chunk)
{
/* read/write this amount of bytes every time */
int bytes = min(bytes_left, chunk * SECTOR_SIZE - off);
rw_sector(DEV_READ, // modified by mingxuan 2019-5-21
@ -1260,12 +1305,14 @@ static int do_rdwt(MESSAGE *fs_msg)
proc2pid(p_proc_current), /// TASK_FS
fsbuf);
if (fs_msg->type == READ) {
if (fs_msg->type == READ)
{
memcpy((void *)va2la(src, buf + bytes_rw),
(void *)va2la(proc2pid(p_proc_current), fsbuf + off),
bytes);
}
else { /* WRITE */
else
{ /* WRITE */
memcpy((void *)va2la(proc2pid(p_proc_current), fsbuf + off),
(void *)va2la(src, buf + bytes_rw),
bytes);
@ -1283,7 +1330,8 @@ static int do_rdwt(MESSAGE *fs_msg)
bytes_left -= bytes;
}
if (p_proc_current->task.filp[fd]->fd_pos > pin->i_size) {
if (p_proc_current->task.filp[fd]->fd_pos > pin->i_size)
{
/* update inode::size */
pin->i_size = p_proc_current->task.filp[fd]->fd_pos;
sync_inode(pin);
@ -1347,13 +1395,15 @@ static int do_unlink(MESSAGE *fs_msg)
name_len);
pathname[name_len] = 0;
if (strcmp(pathname , "/") == 0) {
if (strcmp(pathname, "/") == 0)
{
kprintf("FS:do_unlink():: cannot unlink the root\n");
return -1;
}
int inode_nr = search_file(pathname);
if (inode_nr == INVALID_INODE) { /* file not found */
if (inode_nr == INVALID_INODE)
{ /* file not found */
kprintf("FS::do_unlink():: search_file() returns invalid inode: %s\n", pathname);
return -1;
}
@ -1365,12 +1415,14 @@ static int do_unlink(MESSAGE *fs_msg)
struct inode *pin = get_inode_sched(dir_inode->i_dev, inode_nr); // modified by xw, 18/8/28
if (pin->i_mode != I_REGULAR) { /* can only remove regular files */
if (pin->i_mode != I_REGULAR)
{ /* can only remove regular files */
kprintf("cannot remove file %s, because it is not a regular file.\n", pathname);
return -1;
}
if (pin->i_cnt > 1) { /* the file was opened */
if (pin->i_cnt > 1)
{ /* the file was opened */
kprintf("cannot remove file %s, because pin->i_cnt is %d\n", pathname, pin->i_cnt);
return -1;
}
@ -1418,7 +1470,8 @@ static int do_unlink(MESSAGE *fs_msg)
int i;
/* clear the first byte */
for (i = bit_idx % 8; (i < 8) && bits_left; i++,bits_left--) {
for (i = bit_idx % 8; (i < 8) && bits_left; i++, bits_left--)
{
// assert((fsbuf[byte_idx % SECTOR_SIZE] >> i & 1) == 1);
fsbuf[byte_idx % SECTOR_SIZE] &= ~(1 << i);
}
@ -1426,8 +1479,10 @@ static int do_unlink(MESSAGE *fs_msg)
/* clear bytes from the second byte to the second to last */
int k;
i = (byte_idx % SECTOR_SIZE) + 1; /* the second byte */
for (k = 0; k < byte_cnt; k++,i++,bits_left-=8) {
if (i == SECTOR_SIZE) {
for (k = 0; k < byte_cnt; k++, i++, bits_left -= 8)
{
if (i == SECTOR_SIZE)
{
i = 0;
WR_SECT_SCHED(pin->i_dev, s, fsbuf); // modified by xw, 18/12/27
RD_SECT_SCHED(pin->i_dev, ++s, fsbuf); // modified by xw, 18/12/27
@ -1437,7 +1492,8 @@ static int do_unlink(MESSAGE *fs_msg)
}
/* clear the last byte */
if (i == SECTOR_SIZE) {
if (i == SECTOR_SIZE)
{
i = 0;
WR_SECT_SCHED(pin->i_dev, s, fsbuf); // modified by xw, 18/12/27
RD_SECT_SCHED(pin->i_dev, ++s, fsbuf); // modified by xw, 18/12/27
@ -1473,16 +1529,19 @@ static int do_unlink(MESSAGE *fs_msg)
int flg = 0;
int dir_size = 0;
for (i = 0; i < nr_dir_blks; i++) {
for (i = 0; i < nr_dir_blks; i++)
{
RD_SECT_SCHED(dir_inode->i_dev, dir_blk0_nr + i, fsbuf); // modified by xw, 18/12/27
pde = (struct dir_entry *)fsbuf;
int j;
for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) {
for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++, pde++)
{
if (++m > nr_dir_entries)
break;
if (pde->inode_nr == inode_nr) {
if (pde->inode_nr == inode_nr)
{
/* pde->inode_nr = 0; */
memset(pde, 0, DIR_ENTRY_SIZE);
WR_SECT_SCHED(dir_inode->i_dev, dir_blk0_nr + i, fsbuf); // modified by xw, 18/12/27
@ -1499,7 +1558,8 @@ static int do_unlink(MESSAGE *fs_msg)
break;
}
// assert(flg);
if (m == nr_dir_entries) { /* the file is the last one in the dir */
if (m == nr_dir_entries)
{ /* the file is the last one in the dir */
dir_inode->i_size = dir_size;
sync_inode(dir_inode);
}
@ -1538,7 +1598,8 @@ static int do_lseek(MESSAGE *fs_msg)
// int f_size = p_proc_current->task.filp[fd]->fd_inode->i_size; //deleted by mingxuan 2019-5-17
int f_size = p_proc_current->task.filp[fd]->fd_node.fd_inode->i_size; // modified by mingxuan 2019-5-17
switch (whence) {
switch (whence)
{
case SEEK_SET:
pos = off;
break;
@ -1552,7 +1613,8 @@ static int do_lseek(MESSAGE *fs_msg)
return -1;
break;
}
if ((pos > f_size) || (pos < 0)) {
if ((pos > f_size) || (pos < 0))
{
return -1;
}
p_proc_current->task.filp[fd]->fd_pos = pos;

View File

@ -119,7 +119,9 @@ int kernel_main()
p_proc_current = proc_table;
kernel_initial = 0; // kernel initialization is done. added by xw, 18/5/31
restart_initial(); // modified by xw, 18/4/19
while(1){}
while (1)
{
}
}
/*************************************************************************
@ -185,7 +187,6 @@ static int initialize_processes()
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
// p_proc->task.cr3 在页表初始化中处理
/**************线性地址布局初始化**********************************/ // add by visual 2016.5.4
/**************task的代码数据大小及位置暂时是不会用到的所以没有初始化************************************/
p_proc->task.memmap.heap_lin_base = HeapLinBase;
@ -229,7 +230,6 @@ static int initialize_processes()
disp_color_str("kernel_main Error:lin_mapping_phy", 0x74);
return -1;
}
}
/***************copy registers data to kernel stack****************************/
@ -325,7 +325,6 @@ static int initialize_processes()
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
// p_proc->task.cr3 在页表初始化中处理
/**************线性地址布局初始化**********************************/ // edit by visual 2016.5.25
p_proc->task.memmap.text_lin_base = 0; // initial这些段的数据并不清楚在变身init的时候才在中赋新值
p_proc->task.memmap.text_lin_limit = 0; // initial这些段的数据并不清楚在变身init的时候才在exec中赋新值
@ -353,7 +352,6 @@ static int initialize_processes()
p_proc->task.info.text_hold = 1; // 是否拥有代码
p_proc->task.info.data_hold = 1; // 是否拥有数据
/***************初始化PID进程页表*****************************/
if (0 != init_page_pte(pid))
{
@ -385,7 +383,6 @@ static int initialize_processes()
disp_color_str("kernel_main Error:lin_mapping_phy", 0x74);
return -1;
}
}
/***************copy registers data to kernel stack****************************/

View File

@ -30,9 +30,11 @@ int cur_ntty = 0;
static keyboard_buf keyboardbuf[3];
static vga_buf vgabuf[3];
void init_tty_main() {
void init_tty_main()
{
NTTY *tty;
for (int i = 0; i < 3; ++ i) {
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));
@ -299,7 +301,8 @@ static void put_key(TTY *tty, u32 key)
void tty_write(TTY *tty, char *buf, int len)
{
#ifdef DEBUGNEW
while (--len >= 0) {
while (--len >= 0)
{
vga_tty_write(&ntty_table[cur_ntty], *buf++);
}
// vga_tty_flush(&ntty_table[cur_ntty]);

View File

@ -85,15 +85,16 @@ void init_fileop_table()
f_op_table[2].opendir = OpenDir;
f_op_table[2].createdir = CreateDir;
f_op_table[2].deletedir = DeleteDir;
}
// added by mingxuan 2020-10-30
void init_super_block_table(){
void init_super_block_table()
{
struct super_block *sb = super_block; // deleted by mingxuan 2020-10-30
// super_block[0] is tty0, super_block[1] is tty1, uper_block[2] is tty2
for(; sb < &super_block[3]; sb++) {
for (; sb < &super_block[3]; sb++)
{
sb->sb_dev = DEV_CHAR_TTY;
sb->fs_type = TTY_FS_TYPE;
}
@ -109,14 +110,16 @@ void init_super_block_table(){
sb++;
// another super_block are free
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++) {
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++)
{
sb->sb_dev = NO_DEV;
sb->fs_type = NO_FS_TYPE;
}
}
// added by mingxuan 2020-10-30
void init_sb_op_table(){
void init_sb_op_table()
{
// orange
sb_op_table[0].read_super_block = read_super_block;
sb_op_table[0].get_super_block = get_super_block;
@ -127,7 +130,8 @@ void init_sb_op_table(){
}
// static void init_dev_table(){
static void init_vfs_table(){ // modified by mingxuan 2020-10-30
static void init_vfs_table()
{ // modified by mingxuan 2020-10-30
// 我们假设每个tty就是一个文件系统
// tty0
@ -169,10 +173,10 @@ static void init_vfs_table(){ // modified by mingxuan 2020-10-30
vfs_table[4].op = &f_op_table[1];
vfs_table[4].sb = &super_block[3]; // added by mingxuan 2020-10-30
vfs_table[4].s_op = &sb_op_table[0]; // added by mingxuan 2020-10-30
}
static int get_index(char path[]){
static int get_index(char path[])
{
int pathlen = strlen(path);
// char dev_name[DEV_NAME_LEN];
@ -180,13 +184,16 @@ static int get_index(char path[]){
int len = (pathlen < DEV_NAME_LEN) ? pathlen : DEV_NAME_LEN;
int i, a = 0;
for(i=0;i<len;i++){
if( path[i] == '/'){
for (i = 0; i < len; i++)
{
if (path[i] == '/')
{
a = i;
a++;
break;
}
else {
else
{
// dev_name[i] = path[i];
fs_name[i] = path[i]; // modified by mingxuan 2020-10-18
}
@ -208,7 +215,6 @@ static int get_index(char path[]){
return -1;
}
/*======================================================================*
sys_*
*======================================================================*/
@ -238,36 +244,42 @@ int sys_lseek(void *uesp)
return do_vlseek(get_arg(uesp, 1), get_arg(uesp, 2), get_arg(uesp, 3));
}
int sys_unlink(void *uesp) {
int sys_unlink(void *uesp)
{
return do_vunlink((const char *)get_arg(uesp, 1));
}
int sys_create(void *uesp) {
int sys_create(void *uesp)
{
return do_vcreate((char *)get_arg(uesp, 1));
}
int sys_delete(void *uesp) {
int sys_delete(void *uesp)
{
return do_vdelete((char *)get_arg(uesp, 1));
}
int sys_opendir(void *uesp) {
int sys_opendir(void *uesp)
{
return do_vopendir((char *)get_arg(uesp, 1));
}
int sys_createdir(void *uesp) {
int sys_createdir(void *uesp)
{
return do_vcreatedir((char *)get_arg(uesp, 1));
}
int sys_deletedir(void *uesp) {
int sys_deletedir(void *uesp)
{
return do_vdeletedir((char *)get_arg(uesp, 1));
}
/*======================================================================*
do_v*
*======================================================================*/
int do_vopen(const char *path, int flags) {
int do_vopen(const char *path, int flags)
{
int pathlen = strlen(path);
char pathname[MAX_PATH];
@ -278,7 +290,8 @@ int do_vopen(const char *path, int flags) {
int index;
int fd = -1;
index = get_index(pathname);
if(index == -1){
if (index == -1)
{
kprintf("pathname error! path: %s\n", path);
return -1;
}
@ -287,25 +300,29 @@ int do_vopen(const char *path, int flags) {
if (fd != -1)
{
p_proc_current->task.filp[fd]->dev_index = index;
} else {
}
else
{
kprintf(" error!\n");
}
return fd;
}
int do_vclose(int fd) {
int do_vclose(int fd)
{
int index = p_proc_current->task.filp[fd]->dev_index;
return vfs_table[index].op->close(fd); // modified by mingxuan 2020-10-18
}
int do_vread(int fd, char *buf, int count) {
int do_vread(int fd, char *buf, int count)
{
int index = p_proc_current->task.filp[fd]->dev_index;
return vfs_table[index].op->read(fd, buf, count); // modified by mingxuan 2020-10-18
}
int do_vwrite(int fd, const char *buf, int count) {
int do_vwrite(int fd, const char *buf, int count)
{
// modified by mingxuan 2019-5-23
char s[512];
int index = p_proc_current->task.filp[fd]->dev_index;
@ -332,7 +349,8 @@ int do_vwrite(int fd, const char *buf, int count) {
return count;
}
int do_vunlink(const char *path) {
int do_vunlink(const char *path)
{
int pathlen = strlen(path);
char pathname[MAX_PATH];
@ -341,7 +359,8 @@ int do_vunlink(const char *path) {
int index;
index = get_index(pathname);
if(index==-1){
if (index == -1)
{
kprintf("pathname error!\n");
return -1;
}
@ -350,16 +369,17 @@ int do_vunlink(const char *path) {
return vfs_table[index].op->unlink(pathname); // modified by mingxuan 2020-10-18
}
int do_vlseek(int fd, int offset, int whence) {
int do_vlseek(int fd, int offset, int whence)
{
int index = p_proc_current->task.filp[fd]->dev_index;
// return device_table[index].op->lseek(fd, offset, whence);
return vfs_table[index].op->lseek(fd, offset, whence); // modified by mingxuan 2020-10-18
}
// int do_vcreate(char *pathname) {
int do_vcreate(char *filepath) { //modified by mingxuan 2019-5-17
int do_vcreate(char *filepath)
{ // modified by mingxuan 2019-5-17
// added by mingxuan 2019-5-17
int state;
const char *path = filepath;
@ -372,20 +392,25 @@ int do_vcreate(char *filepath) { //modified by mingxuan 2019-5-17
int index;
index = get_index(pathname);
if(index == -1){
if (index == -1)
{
kprintf("pathname error! path: %s\n", path);
return -1;
}
state = vfs_table[index].op->create(pathname); // modified by mingxuan 2020-10-18
if (state == 1) {
if (state == 1)
{
kprintf(" create file success!");
} else {
}
else
{
DisErrorInfo(state);
}
return state;
}
int do_vdelete(char *path) {
int do_vdelete(char *path)
{
int pathlen = strlen(path);
char pathname[MAX_PATH];
@ -395,14 +420,16 @@ int do_vdelete(char *path) {
int index;
index = get_index(pathname);
if(index==-1){
if (index == -1)
{
kprintf("pathname error!\n");
return -1;
}
// return device_table[index].op->delete(pathname);
return vfs_table[index].op->delete (pathname); // modified by mingxuan 2020-10-18
}
int do_vopendir(char *path) {
int do_vopendir(char *path)
{
int state;
int pathlen = strlen(path);
@ -419,15 +446,19 @@ int do_vopendir(char *path) {
pathname[j] = pathname[j + 3];
}
state = f_op_table[index].opendir(pathname);
if (state == 1) {
if (state == 1)
{
kprintf(" open dir success!");
} else {
}
else
{
DisErrorInfo(state);
}
return state;
}
int do_vcreatedir(char *path) {
int do_vcreatedir(char *path)
{
int state;
int pathlen = strlen(path);
@ -444,15 +475,19 @@ int do_vcreatedir(char *path) {
pathname[j] = pathname[j + 3];
}
state = f_op_table[index].createdir(pathname);
if (state == 1) {
if (state == 1)
{
kprintf(" create dir success!");
} else {
}
else
{
DisErrorInfo(state);
}
return state;
}
int do_vdeletedir(char *path) {
int do_vdeletedir(char *path)
{
int state;
int pathlen = strlen(path);
char pathname[MAX_PATH];
@ -468,9 +503,12 @@ int do_vdeletedir(char *path) {
pathname[j] = pathname[j + 3];
}
state = f_op_table[index].deletedir(pathname);
if (state == 1) {
if (state == 1)
{
kprintf(" delete dir success!");
} else {
}
else
{
DisErrorInfo(state);
}
return state;

View File

@ -63,51 +63,55 @@ static inline void vga_set_video_start_addr(u32 addr)
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) {
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) {
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) {
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) {
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) {
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
{
*dst++ = *_src++;
}
}
static inline void vga_flush_blankline(int line_no) {
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) {
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
{
*dst++ = (BLANK << 16) | BLANK;
}
}
@ -130,45 +134,238 @@ void vga_tty_init(NTTY* tty) {
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) {
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) NEXT(row, SCR_MAXLINE)
#define LASTLINE(row) LAST(row, SCR_MAXLINE)
#define NEXTLINE(row) (((row) + 1) % SCR_MAXLINE)
#define LASTLINE(row) (((row)-1) >= 0 ? ((row)-1) % SCR_MAXLINE : SCR_MAXLINE)
static void newline(vga_buf* vga) {
vga->cur_col = 0;
static void newline(vga_buf *vgabuf)
{
vgabuf->cur_col = 0;
// kprintf("bf %x\n", vgabuf->scr_cur_line);
vga->scr_cur_line = NEXTLINE(vga->scr_cur_line);
vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line);
// kprintf("af %x\n", vgabuf->scr_cur_line);
vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE);
if (vga->cur_row == SCR_HEIGHT) {
vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line);
if (vgabuf->cur_row == SCR_HEIGHT)
{
// auto scroll
vga->scr_top_line = NEXTLINE(vga->scr_top_line);
if(vga->scr_cur_line == vga->head_line) {
vga->head_line = NEXTLINE(vga->head_line);
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*) (vga->buf + sizeof(u16) * vga->head_line * SCR_WIDTH);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) {
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) {
static void nextcol(vga_buf *vgabuf)
{
vgabuf->cur_col++;
if (vgabuf->cur_col == SCR_WIDTH)
{
newline(vgabuf);
}
}
static void cursor_move(i16 move_row, i16 move_col, vga_buf *vgabuf)
{
vgabuf->scr_cur_line += move_row;
if (vgabuf->scr_cur_line < 0)
vgabuf->scr_cur_line = 0;
else if (vgabuf->scr_cur_line >= SCR_MAXLINE)
vgabuf->scr_cur_line = SCR_MAXLINE - 1;
vgabuf->cur_col += move_col;
if (vgabuf->cur_col < 0)
vgabuf->cur_col = 0;
else if (vgabuf->cur_col >= SCR_WIDTH)
vgabuf->cur_col = SCR_WIDTH - 1;
}
inline static void
param12vga_color(i16 *param)
{
u8 tmp = *param & 1;
*param &= 0b0110;
*param |= *param >> 2;
*param &= 0b0011;
*param |= tmp << 2;
}
static void set_color(vga_buf *vgabuf)
{
if (vgabuf->param1 == 0)
{
vgabuf->color = DEFAULT_CHAR_COLOR;
}
else if (vgabuf->param1 == 1)
{
vgabuf->color |= 0x8800;
}
else if (vgabuf->param1 == 2)
{
vgabuf->color &= 0x7700;
}
else if (30 <= vgabuf->param1 && vgabuf->param1 <= 37)
{
vgabuf->param1 -= 30;
param12vga_color(&(vgabuf->param1));
vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param1);
}
else if (40 <= vgabuf->param1 && vgabuf->param1 <= 47)
{
vgabuf->param1 -= 40;
param12vga_color(&(vgabuf->param1));
vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param1);
}
else if (90 <= vgabuf->param1 && vgabuf->param1 <= 97)
{
vgabuf->param1 -= 90;
param12vga_color(&(vgabuf->param1));
vgabuf->param1 |= 0x8;
vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param1);
}
else if (100 <= vgabuf->param1 && vgabuf->param1 <= 107)
{
vgabuf->param1 -= 100;
param12vga_color(&(vgabuf->param1));
vgabuf->param1 |= 0x8;
vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param1);
}
else
{
warn("unsupport CSI: color");
}
if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
{
vgabuf->color = DEFAULT_CHAR_COLOR;
}
else if (vgabuf->param2 == 1)
{
vgabuf->color |= 0x8800;
}
else if (vgabuf->param2 == 2)
{
vgabuf->color &= 0x7700;
}
else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37)
{
vgabuf->param2 -= 30;
param12vga_color(&(vgabuf->param2));
vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2);
}
else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47)
{
vgabuf->param2 -= 40;
param12vga_color(&(vgabuf->param2));
vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2);
}
else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97)
{
vgabuf->param2 -= 90;
param12vga_color(&(vgabuf->param2));
vgabuf->param2 |= 0x8;
vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2);
}
else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107)
{
vgabuf->param2 -= 100;
param12vga_color(&(vgabuf->param2));
vgabuf->param2 |= 0x8;
vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2);
}
else
{
warn("unsupport CSI: color");
}
}
static void CSI_handler(u8 terminator, vga_buf *vgabuf)
{
vgabuf->CSI = CSI_ESC;
switch (terminator)
{
case 'A':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(-vgabuf->param1, 0, vgabuf);
break;
case 'B':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(+vgabuf->param1, 0, vgabuf);
break;
case 'C':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(0, -vgabuf->param1, vgabuf); // nothing
break;
case 'D':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(0, +vgabuf->param1, vgabuf);
break;
case 'E':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(+vgabuf->param1, -vgabuf->cur_col, vgabuf);
break;
case 'F':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(-vgabuf->param1, -vgabuf->cur_col, vgabuf);
break;
case 'G': // added
cursor_move(0, vgabuf->param1 - vgabuf->cur_col, vgabuf);
break;
case 'H':
cursor_move(vgabuf->param1 - vgabuf->scr_cur_line, vgabuf->param1 - vgabuf->cur_col, vgabuf);
break;
case 'J':
break;
case 'K':
break;
case 'S':
break;
case 'T':
break;
case 'm':
set_color(vgabuf);
break;
}
}
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);
if (vga->CSI == CSI_ESC)
{
switch (ch)
{
case '\t':
if (INDEX(vga->scr_cur_line, vga->cur_col) == SCR_BUFSIZE - 1)
break;
while (vga->cur_col % 4 != 1)
{
nextcol(vga);
}
break;
case '\n':
newline(vga);
break;
@ -178,17 +375,72 @@ void vga_tty_write(NTTY* tty, char ch) {
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) {
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);
}
case '\x1b':
vga->CSI = CSI_BRACKET;
break;
default:
if (vga->color == 0)
{
buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(DEFAULT_CHAR_COLOR, ch);
}
else
{
buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(vga->color, ch);
}
// buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(DEFAULT_CHAR_COLOR, ch);
nextcol(vga);
break;
}
}
else if (vga->CSI == CSI_BRACKET)
{
switch (ch)
{
case '[':
vga->CSI = CSI_PARAM1;
vga->param1 = vga->param2 = 0;
break;
default:
vga->CSI = CSI_ESC;
break;
}
}
else
{
switch (ch)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (vga->CSI == CSI_PARAM1)
vga->param1 = vga->param1 * 10 + ch - '0';
else if (vga->CSI == CSI_PARAM2)
vga->param2 = vga->param2 * 10 + ch - '0';
else
; // do nothing
break;
case ';':
vga->CSI = CSI_PARAM2;
break;
default:
if (!(0x20 <= ch && ch <= 0x7e))
vga->CSI = CSI_ESC;
if (0x40 <= ch && ch <= 0x7e)
CSI_handler(ch, vga);
break;
}
}
vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE);
// kprintf("row: %d; ", vga->cur_row);
@ -212,49 +464,69 @@ void vga_tty_flush(NTTY* tty) {
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) {
if (vga->cur_row == SCR_WIDTH - 1)
{
vga_flush_screen(&buf[INDEX(vga->scr_top_line, 0)]);
}
else {
else
{
cur_line = vga->scr_top_line;
for (i = 0; i <= vga->cur_row; ++ i){
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) {
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) {
void vga_tty_scroll(NTTY *tty, int direction)
{
vga_buf *vga = tty->output_buf;
u16 *buf = vga->buf;
if (direction > 0) {
if (direction > 0)
{
// down
if (vga->scr_top_line == vga->scr_cur_line) return;
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;
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) {
if (vga->cur_row >= SCR_HEIGHT)
{
vga_disable_cursor();
}
else {
else
{
vga_enable_cursor(0, 15);
}
}
void vga_scroll_to_cur(NTTY* tty) {
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) {
void vga_ttroll_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

@ -16,11 +16,14 @@ int main(int arg, char *argv[])
char buf[1024];
int pid;
int times = 0;
for (int i = 0; i < 20; ++ i) {
for (int i = 0; i < 20; ++i)
{
printf("test %d\n", i);
}
for (int i = 0; i < 2; ++ i) {
printf("1111111111");
for (int i = 0; i < 2; ++i)
{
printf("\x1b[42;31m1111111111");
// printf("\x1b[m1111111111");
printf("2222222222");
printf("3333333333");
printf("4444444444");
@ -31,6 +34,7 @@ int main(int arg, char *argv[])
printf("9999999999\r\b\b\n");
}
while(1);
while (1)
;
return 0;
}