ROADMAP: закрыт 1 пункт
This commit is contained in:
parent
8e6f9cb31a
commit
7136ac3155
3 changed files with 59 additions and 5 deletions
|
|
@ -12,7 +12,7 @@
|
|||
- [x] UART отладка
|
||||
- [x] Драйвер таймера
|
||||
- [x] Драйвер клавиатуры
|
||||
- [ ] Нормальный драйвер VGA (скролл итд)
|
||||
- [x] Нормальный драйвер VGA (скролл итд)
|
||||
- [ ] Нормальный драйвер клавиатуры (Caps Lock, Shift, Numpad итд)
|
||||
- [ ] Драйвер PC Speaker
|
||||
- [ ] Screen buffers (как tty в Linux)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include "vga.h"
|
||||
#include "../kernel/io.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define VGA_WIDTH 80
|
||||
#define VGA_HEIGHT 25
|
||||
|
|
@ -9,6 +11,34 @@ static int cursor_x = 0;
|
|||
static int cursor_y = 0;
|
||||
static char current_color = 0x07; // По умолчанию серый на черном
|
||||
|
||||
// Локальная функция для сдвига экрана вверх на одну строку
|
||||
static void vga_scroll(void) {
|
||||
// Копируем строки с 1-й по 24-ю на место строк с 0-й по 23-ю
|
||||
// Каждая строка занимает VGA_WIDTH * 2 байт (символ + атрибут)
|
||||
for (int i = 0; i < (VGA_HEIGHT - 1) * VGA_WIDTH * 2; i++) {
|
||||
video_mem[i] = video_mem[i + VGA_WIDTH * 2];
|
||||
}
|
||||
|
||||
// Очищаем самую нижнюю строку (заполняем пробелами с текущим цветом)
|
||||
int last_row_start = (VGA_HEIGHT - 1) * VGA_WIDTH * 2;
|
||||
for (int i = 0; i < VGA_WIDTH; i++) {
|
||||
video_mem[last_row_start + i * 2] = ' ';
|
||||
video_mem[last_row_start + i * 2 + 1] = current_color;
|
||||
}
|
||||
}
|
||||
|
||||
void vga_update_cursor(int x, int y) {
|
||||
// Вычисляем плоский индекс в видеопамяти
|
||||
uint16_t pos = y * VGA_WIDTH + x;
|
||||
|
||||
// Передаем контроллеру VGA младший байт позиции (регистр 15)
|
||||
outb(0x3D4, 0x0F);
|
||||
outb(0x3D5, (uint8_t)(pos & 0xFF));
|
||||
|
||||
// Передаем старший байт позиции (регистр 14)
|
||||
outb(0x3D4, 0x0E);
|
||||
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
|
||||
}
|
||||
void vga_init(void) {
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
|
|
@ -17,6 +47,7 @@ void vga_init(void) {
|
|||
video_mem[i * 2] = ' ';
|
||||
video_mem[i * 2 + 1] = current_color;
|
||||
}
|
||||
vga_update_cursor(0,0);
|
||||
}
|
||||
|
||||
void vga_set_color(char fg, char bg) {
|
||||
|
|
@ -24,11 +55,26 @@ void vga_set_color(char fg, char bg) {
|
|||
}
|
||||
|
||||
void vga_putchar(char c) {
|
||||
// Обработка бэкспейса (стирание символа)
|
||||
if (c == '\b') {
|
||||
if (cursor_x > 0) {
|
||||
cursor_x--;
|
||||
} else if (cursor_y > 0) {
|
||||
cursor_y--;
|
||||
cursor_x = VGA_WIDTH - 1;
|
||||
}
|
||||
int index = (cursor_y * VGA_WIDTH + cursor_x) * 2;
|
||||
video_mem[index] = ' ';
|
||||
video_mem[index + 1] = current_color;
|
||||
vga_update_cursor(cursor_x, cursor_y);
|
||||
return; // Выходим, чтобы не двигать курсор вперед
|
||||
}
|
||||
|
||||
// Обработка переноса строки
|
||||
if (c == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y++;
|
||||
} else {
|
||||
} else if (c >= ' ') { // Печатаем только видимые символы
|
||||
int index = (cursor_y * VGA_WIDTH + cursor_x) * 2;
|
||||
video_mem[index] = c;
|
||||
video_mem[index + 1] = current_color;
|
||||
|
|
@ -41,10 +87,12 @@ void vga_putchar(char c) {
|
|||
cursor_y++;
|
||||
}
|
||||
|
||||
// Если экран кончился — просто сбрасываем наверх (примитивный скролл)
|
||||
// Если экран кончился — скроллим вверх, пока курсор не встанет на последнюю строку
|
||||
if (cursor_y >= VGA_HEIGHT) {
|
||||
vga_init();
|
||||
vga_scroll();
|
||||
cursor_y = VGA_HEIGHT - 1;
|
||||
}
|
||||
vga_update_cursor(cursor_x, cursor_y);
|
||||
}
|
||||
|
||||
void vga_print(const char *str) {
|
||||
|
|
@ -54,6 +102,9 @@ void vga_print(const char *str) {
|
|||
}
|
||||
|
||||
void vga_println(const char *str) {
|
||||
vga_print(str);
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
vga_putchar(str[i]);
|
||||
}
|
||||
vga_putchar('\n');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,4 +25,7 @@ void vga_print(const char *str);
|
|||
// Вывод строки с автоматическим переносом на новую линию
|
||||
void vga_println(const char *str);
|
||||
|
||||
// Обновление курсора
|
||||
void vga_update_cursor(int x, int y);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue