#include <console.h>
#include <sched.h>
#include <string.h>
+#include <tty.h>
#include <wait.h>
void vga_putc(unsigned int nr, unsigned char c, const unsigned char color);
}
int cnsl_kbd_write(char ch) {
- if (ch == 0) return 0;
-
+ if (ch == 0) {
+ return 0;
+ }
+ extern tty_t default_tty;
if (ch == '\b') {
- if (!empty(&cnsl.wr_q)) vga_putc(0, '\b', 0xF);
+ if (!empty(&cnsl.wr_q)) {
+ tty_color_putc(&default_tty, '\b', TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK);
+ }
+ // tty_color_putc(default_tty, '\b', TTY_WHITE, TTY_BLACK);
erase(&cnsl.wr_q);
erase(&cnsl.sc_q);
} else {
put(&cnsl.wr_q, ch);
put(&cnsl.sc_q, ch);
- vga_putc(0, ch, 0xF);
+ tty_color_putc(&default_tty, ch, TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK);
}
if (ch == '\n') {
static unsigned long kbd_cnt = 0;
printl(MPL_KEYBOARD, "keyboard irq: %d scan code %02x", kbd_cnt++, scan_code);
- if (scan_code == 0x01) // Esc
+ if (scan_code == 0x01) { // Esc
reboot();
+ }
printd("[%02x]", scan_code);
- if (scan_code == 0x3B) // F1
- vga_switch(0);
- if (scan_code == 0x3C) // F2
- vga_switch(1);
- if (scan_code == 0x3D) // F3
- vga_switch(2);
- if (scan_code == 0x3E) // F4
- vga_switch(3);
+ // if (scan_code == 0x3B) // F1
+ // vga_switch(0);
+ // if (scan_code == 0x3C) // F2
+ // vga_switch(1);
+ // if (scan_code == 0x3D) // F3
+ // vga_switch(2);
+ // if (scan_code == 0x3E) // F4
+ // vga_switch(3);
if (scan_code == 0x3F) // F5
debug_wait_queue_put(0);
+++ /dev/null
-/*
- *--------------------------------------------------------------------------
- * File Name: vga.c
- *
- * Author: Zhao Yanbai [zhaoyanbai@126.com]
- * Sat Jul 18 23:01:18 2009
- *
- * Description: none
- *
- *--------------------------------------------------------------------------
- */
-
-#include <io.h>
-#include <irq.h>
-#include <string.h>
-
-typedef struct {
- u8_t c;
- u8_t f;
-} __attribute__((packed)) vga_char_t;
-
-#define VIDEO_ADDR 0xC00B8000
-
-#define VGA_CRTC_ADDR 0x3D4
-#define VGA_CRTC_DATA 0x3D5
-#define VGA_CRTC_START_ADDR_H 0xC
-#define VGA_CRTC_START_ADDR_L 0xD
-#define VGA_CRTC_CURSOR_H 0xE
-#define VGA_CRTC_CURSOR_L 0xF
-
-#define LINES_PER_SCREEN 25
-#define CHARS_PER_LINE 80
-#define BYTES_PER_LINE (sizeof(vga_char_t) * CHARS_PER_LINE)
-#define MAX_LINES_PER_SCREEN 32
-
-#define TAB_ALIGN 4
-#define TAB_MASK (TAB_ALIGN - 1)
-
-typedef struct {
- unsigned int id;
- vga_char_t *base;
- unsigned int offset;
-} vga_screen_t;
-
-#define VGA_SCREEN_CNT 3
-#define VGA_MAX_SCREEN_CNT ((VGA_SCREEN_CNT) + 1)
-unsigned int vga_screen_cnt() { return VGA_SCREEN_CNT; }
-vga_screen_t vga_screen[VGA_MAX_SCREEN_CNT] = {
- {0, (vga_char_t *)VIDEO_ADDR, 0},
-};
-
-static vga_screen_t *vga_current_screen = vga_screen + 0;
-
-static void set_offset(vga_screen_t *s, unsigned int x, unsigned int y) { s->offset = (y * CHARS_PER_LINE) + x; }
-
-static unsigned int xpos(vga_screen_t *s) { return (s->offset % CHARS_PER_LINE); }
-
-static unsigned int ypos(vga_screen_t *s) { return (s->offset / CHARS_PER_LINE); }
-
-vga_char_t vga_char(unsigned char c, unsigned char f) {
- vga_char_t x;
- x.c = c;
- x.f = f;
-
- return x;
-}
-
-void vga_set_cursor_pos(vga_screen_t *s) {
- unsigned int base = s->id * MAX_LINES_PER_SCREEN * CHARS_PER_LINE;
- unsigned int offset = base + s->offset;
- base = s->id * MAX_LINES_PER_SCREEN * CHARS_PER_LINE;
- offset = base + s->offset;
-
- unsigned long flags;
- irq_save(flags);
- outb(VGA_CRTC_CURSOR_H, VGA_CRTC_ADDR);
- outb((offset >> 8) & 0xFF, VGA_CRTC_DATA);
- outb(VGA_CRTC_CURSOR_L, VGA_CRTC_ADDR);
- outb(offset & 0xFF, VGA_CRTC_DATA);
- irq_restore(flags);
-}
-
-void vga_clear(vga_screen_t *s, unsigned int b, unsigned int e) {
- if (e <= b) return;
-
- vga_char_t *base = s->base;
-
- base += b;
-
- memset((void *)base, 0, (e - b) * sizeof(vga_char_t));
-}
-
-void vga_scroll_up(vga_screen_t *s) {
- int delta = ypos(s) + 1 - LINES_PER_SCREEN;
-
- if (delta <= 0) return;
-
- vga_char_t *base = s->base;
- vga_char_t *head = base + delta * CHARS_PER_LINE;
- vga_char_t *empt = base + (LINES_PER_SCREEN - delta) * CHARS_PER_LINE;
-
- memcpy((void *)base, (void *)head, (empt - base) * sizeof(vga_char_t));
- // memset((void *)empt, 0, delta*BYTES_PER_LINE);
-
- vga_clear(s, (LINES_PER_SCREEN - delta) * CHARS_PER_LINE, LINES_PER_SCREEN * CHARS_PER_LINE);
-
- set_offset(s, xpos(s), ypos(s) - delta);
-}
-
-void vga_putc(unsigned int nr, unsigned char c, const unsigned char color) {
- vga_screen_t *s = vga_screen + nr;
-
- vga_char_t *pv = s->base;
-
- bool need_clear = true;
- bool need_forward = true;
- unsigned int old_offset = s->offset;
-
- switch (c) {
- case '\r':
- set_offset(s, 0, ypos(s));
- break;
- case '\n':
- set_offset(s, 0, ypos(s) + 1);
- break;
- case '\t':
- set_offset(s, (xpos(s) + 1 + TAB_MASK) & ~TAB_MASK, ypos(s));
- break;
- case '\b':
- set_offset(s, xpos(s) - 1, ypos(s));
- c = ' ';
- need_forward = false;
- // NO BREAK
- default:
- need_clear = false;
- pv[s->offset] = vga_char(c, color);
- set_offset(s, xpos(s) + (need_forward ? 1 : 0), ypos(s));
- break;
- }
-
- if (need_clear) {
- vga_clear(s, old_offset, s->offset);
- }
-
- vga_scroll_up(s);
-
- if (vga_current_screen == s) vga_set_cursor_pos(s);
-}
-
-void vga_puts(unsigned int nr, const char *buf, unsigned char color) {
- assert(buf != 0);
- if (nr >= VGA_MAX_SCREEN_CNT) return;
-
- char *p = (char *)buf;
-
- while (*p) {
- vga_putc(nr, *p, color);
- p++;
- }
-}
-
-void __vga_switch(unsigned int offset) {
- outb(VGA_CRTC_START_ADDR_H, VGA_CRTC_ADDR);
- outb((offset >> 8) & 0xFF, VGA_CRTC_DATA);
- outb(VGA_CRTC_START_ADDR_L, VGA_CRTC_ADDR);
- outb((offset)&0xFF, VGA_CRTC_DATA);
-}
-
-void vga_switch(unsigned int nr) {
- if (nr >= VGA_MAX_SCREEN_CNT) return;
-
- vga_screen_t *s = vga_screen + nr;
-
- vga_current_screen = s;
-
- unsigned int offset = 0 + (s->base - (vga_char_t *)VIDEO_ADDR);
-
- __vga_switch(offset);
-}
-
-#define VIDEO_DBG_LINE ((VGA_MAX_SCREEN_CNT) * (MAX_LINES_PER_SCREEN))
-
-void vga_dbg_toggle() {
- static bool dbg = true;
- unsigned int offset = 0;
- if (dbg) {
- offset += VIDEO_DBG_LINE * CHARS_PER_LINE;
- }
-
- dbg = !dbg;
-
- __vga_switch(offset);
-}
-
-unsigned char vga_dbg_color = 0x1F;
-
-void vga_dbg_clear() {
- int i;
- int line;
- for (line = 0; line < MAX_LINES_PER_SCREEN; ++line) {
- vga_char_t *const pv = (vga_char_t *const)(VIDEO_ADDR + (VIDEO_DBG_LINE + line) * BYTES_PER_LINE);
- for (i = 0; i < CHARS_PER_LINE; ++i) pv[i] = vga_char(0, vga_dbg_color);
- }
-}
-
-void vga_dbg_puts(unsigned int line, unsigned int offset, const char *buf) {
- assert(line < LINES_PER_SCREEN);
- assert(offset < CHARS_PER_LINE);
-
- int i;
- char *p = (char *)buf;
- vga_char_t *const pv =
- (vga_char_t *const)(VIDEO_ADDR + (VIDEO_DBG_LINE + line) * BYTES_PER_LINE + offset * sizeof(vga_char_t));
-
- for (i = 0; *p; ++i, ++p) {
- pv[i] = vga_char(*p, vga_dbg_color);
- }
-}
-
-void vga_init() {
- unsigned int i;
- for (i = 1; i < VGA_MAX_SCREEN_CNT; ++i) {
- memset(vga_screen + i, 0, sizeof(vga_screen_t));
- vga_screen[i].id = i;
- vga_screen[i].base = (vga_char_t *)(VIDEO_ADDR + i * MAX_LINES_PER_SCREEN * BYTES_PER_LINE);
- memset(vga_screen[i].base, 0, MAX_LINES_PER_SCREEN * BYTES_PER_LINE);
- }
-
- vga_dbg_clear();
-}
switch (fd) {
case 0:
- vga_puts(0, buf, 0xF);
+ assert(0);
+ // vga_puts(0, buf, 0xF);
break;
default:
return -1;
int printd(const char *fmtstr, ...);
int printlo(unsigned int line, unsigned int offset, const char *fmtstr, ...);
-#define printl(line, fmt, args...) printlo(line, 1, fmt, ##args)
-#define printll(line, fmt, args...) printlo(line, 0, fmt, ##args)
-#define printlr(line, fmt, args...) printlo(line, 40, fmt, ##args)
+#define printl(line, fmt, args...) printlo(1, line, fmt, ##args)
+#define printll(line, fmt, args...) printlo(0, line, fmt, ##args)
+#define printlr(line, fmt, args...) printlo(40, line, fmt, ##args)
// monitor print line
enum {
#pragma once
+#define TTY_FG_HIGHLIGHT 0b1000
+#define TTY_BG_BLINK 0b1000
+
+#define TTY_BLACK 0b0000
+#define TTY_WHITE 0b0111
+#define TTY_RED 0b0100
+#define TTY_GREEN 0b0010
+#define TTY_BLUE 0b0001
+
typedef struct tty {
char name[32];
void tty_write(tty_t *tty, const char *buf, size_t size);
void tty_write_at(tty_t *tty, int xpos, int ypos, const char *buf, size_t size);
+void tty_color_putc(tty_t *tty, char c, unsigned int fg_color, unsigned bg_color);
void tty_set_cursor(tty_t *tty);
void tty_switch(tty_t *tty);
#include <system.h>
#include <tty.h>
-extern void vga_puts(unsigned int nr, const char *buf, unsigned char color);
-extern void vga_dbg_puts(unsigned int line, unsigned int offset, const char *buf);
-extern int vsprintf(char *buf, const char *fmt, char *args);
-
-unsigned int printk_screen_nr = 0;
-
-extern unsigned int vga_screen_cnt();
-void switch_printk_screen() {
- printk_screen_nr++;
- printk_screen_nr %= vga_screen_cnt();
-}
+int vsprintf(char *buf, const char *fmt, char *args);
char pkbuf[1024];
extern tty_t default_tty;
int printk(const char *fmtstr, ...) {
char *args = (char *)(((char *)&fmtstr) + 4);
int size = vsprintf(pkbuf, fmtstr, args);
- // vga_puts(printk_screen_nr, pkbuf, 0x2);
tty_write(&default_tty, pkbuf, (size_t)size);
- // tty_write(&default_tty, "aaa\n", (size_t)4);
return 0;
}
+extern tty_t debug_tty;
int printd(const char *fmtstr, ...) {
char *pdbuf = (char *)kmalloc(1024, 0);
char *args = (char *)(((char *)&fmtstr) + 4);
- vsprintf(pdbuf, fmtstr, args);
- vga_puts(3, pdbuf, 0x4);
+ int size = vsprintf(pdbuf, fmtstr, args);
+ tty_write(&debug_tty, pdbuf, (size_t)size);
kfree(pdbuf);
return 0;
}
char plobuf[1024];
extern tty_t monitor_tty;
-int printlo(unsigned int line, unsigned int offset, const char *fmtstr, ...) {
+int printlo(unsigned int xpos, unsigned int ypos, const char *fmtstr, ...) {
char *args = (char *)(((char *)&fmtstr) + 4);
int size = vsprintf(plobuf, fmtstr, args);
- // vga_dbg_puts(line, offset, plobuf);
- tty_write_at(&monitor_tty, offset, line, plobuf, (size_t)size);
- // tty_write_at(&monitor_tty, 1, 2, "abc\n", (size_t)4);
+ tty_write_at(&monitor_tty, xpos, ypos, plobuf, (size_t)size);
return 0;
}
#include <printk.h>
#include <system.h>
-extern void vga_init();
extern void init_mm();
extern void setup_gdt();
extern void setup_idt();
extern void reboot();
extern void cnsl_init();
-extern void vga_init();
extern void init_ttys();
#define HZ 10
"\n";
void setup_kernel() {
- vga_init();
init_ttys();
init_mm();
setup_tasks();
setup_irqs();
-
+ printk("fuck\tfu\tsad\tasdfa\t\taa\n");
return;
// switch_printk_screen();
setup_fs();
- // vga_puts(0, version, 0x2F);
printk(version);
// switch_printk_screen();
#include <string.h>
#include <tty.h>
-#define BLACK 0b000
-#define WHITE 0b111
-#define RED 0b100
-#define GREEN 0b010
-#define BLUE 0b001
-
// 从0xB8000处开始有32KB显存可利用
// 而一屏所需要的显存为 80*25*2 = 4000 约为4K
// 所以大致可以分出8个tty
tty_t default_tty;
tty_t monitor_tty;
+tty_t debug_tty;
void tty_clear(tty_t *tty) {
char *dst = (char *)tty->base_addr;
for (int src = 0; src < (MAX_Y * BYTES_PER_LINE); src += 2) {
- *dst++ = ' ';
+ *dst++ = 0;
*dst++ = (tty->bg_color << 4) | tty->fg_color;
}
}
strlcpy(tty->name, name, sizeof(tty->name));
- tty->fg_color = 0x8 | GREEN; // 高亮
- tty->bg_color = 0x0 | BLACK; // 不闪
+ tty->fg_color = 0x8 | TTY_GREEN; // 高亮
+ tty->bg_color = 0x0 | TTY_BLACK; // 不闪
tty->base_addr = base;
}
init_tty(&default_tty, "tty.default", VADDR + 0 * TTY_VRAM_SIZE);
init_tty(&monitor_tty, "tty.monitor", VADDR + 1 * TTY_VRAM_SIZE);
- monitor_tty.fg_color = WHITE;
- monitor_tty.bg_color = BLUE;
+ monitor_tty.fg_color = TTY_WHITE;
+ monitor_tty.bg_color = TTY_BLUE;
tty_clear(&monitor_tty);
current_tty = &default_tty;
+
+ init_tty(&debug_tty, "tty.debug", VADDR + 7 * TTY_VRAM_SIZE);
+ debug_tty.fg_color = TTY_BLACK;
+ debug_tty.bg_color = TTY_RED;
+ tty_clear(&debug_tty);
}
void tty_do_scroll_up(tty_t *tty) {
// 清空最后一行
dst = (char *)(tty->base_addr + ((MAX_Y - 1) * BYTES_PER_LINE));
for (int i = 0; i < BYTES_PER_LINE; i += 2) {
- *dst++ = ' ';
+ *dst++ = 0;
*dst++ = (tty->bg_color << 4) | tty->fg_color;
}
tty->ypos = MAX_Y - 1;
}
-void tty_putc(tty_t *tty, char c) {
+void tty_color_putc(tty_t *tty, char c, unsigned int fg_color, unsigned bg_color) {
bool display = false;
+ bool move_to_next_pos = true;
switch (c) {
case '\r':
tty->xpos = 0;
case '\t':
tty->xpos += TAB_SPACE;
tty->xpos &= ~(TAB_SPACE - 1);
- tty->ypos += tty->xpos / CHARS_PER_LINE;
- tty->xpos %= CHARS_PER_LINE;
+ break;
+ case '\b':
+ if (tty->xpos == 0) {
+ if (tty->ypos > 0) {
+ tty->xpos = CHARS_PER_LINE - 1;
+ tty->ypos -= 1;
+ } else {
+ tty->ypos = 0;
+ }
+ } else if (tty->xpos > 0) {
+ tty->xpos -= 1;
+ } else {
+ tty->xpos = 0;
+ }
+ c = 0;
+ display = true;
+ move_to_next_pos = false;
break;
default:
- tty->ypos += tty->xpos / CHARS_PER_LINE;
- tty->xpos %= CHARS_PER_LINE;
display = true;
break;
}
+ tty->ypos += tty->xpos / CHARS_PER_LINE;
+ tty->xpos %= CHARS_PER_LINE;
+
tty_do_scroll_up(tty);
// 显示
unsigned int pos = tty->ypos * BYTES_PER_LINE + tty->xpos * 2;
char *va = (char *)(tty->base_addr + pos);
va[0] = c;
- va[1] = (tty->bg_color << 4) | tty->fg_color;
+ va[1] = (bg_color << 4) | fg_color;
- tty->xpos++;
+ if (move_to_next_pos) {
+ tty->xpos++;
+ }
}
tty_set_cursor(tty);
}
+void tty_putc(tty_t *tty, char c) { tty_color_putc(tty, c, tty->fg_color, tty->bg_color); }
+
void tty_write(tty_t *tty, const char *buf, size_t size) {
assert(0 != tty);
if (0 == buf) {
if (tty != current_tty) {
return;
}
- unsigned int offset = tty->ypos * MAX_Y + tty->xpos;
- offset += VADDR;
+ unsigned int offset = tty->ypos * MAX_X + tty->xpos;
unsigned long flags;
irq_save(flags);
unsigned int offset = (tty->base_addr - VADDR) / 2;
+ unsigned long flags;
+ irq_save(flags);
outb(VGA_CRTC_START_ADDR_H, VGA_CRTC_ADDR);
outb((offset >> 8) & 0xFF, VGA_CRTC_DATA);
outb(VGA_CRTC_START_ADDR_L, VGA_CRTC_ADDR);
outb((offset)&0xFF, VGA_CRTC_DATA);
+ irq_restore(flags);
current_tty = tty;
}