mirror of
https://github.com/0Nera/BMOSP.git
synced 2024-11-25 18:09:38 +03:00
136 lines
3.4 KiB
C
136 lines
3.4 KiB
C
/**
|
|
* log.c
|
|
* Функции отладки
|
|
*
|
|
* Функционал отладки
|
|
*
|
|
*/
|
|
|
|
#include <arch.h>
|
|
#include <fb.h>
|
|
#include <lock.h>
|
|
#include <log.h>
|
|
#include <mem.h>
|
|
#include <stdint.h>
|
|
#include <tool.h>
|
|
|
|
static char start_buffer[1024];
|
|
static char *log_buffer;
|
|
static uint64_t fb_pos_x = 4;
|
|
static uint64_t fb_pos_y = 0;
|
|
static uint64_t buf_pos = 0;
|
|
static uint64_t buf_max = 1024;
|
|
static lock_t log_lock = LOCK_INIT;
|
|
|
|
#define FONT_WIDTH 6 + 1
|
|
#define FONT_HEIGHT 8 + 1
|
|
|
|
void redraw_screen( );
|
|
|
|
// Получение кода символа в таблице
|
|
static inline uint32_t analyze(char glyth) {
|
|
return ((uint8_t)glyth - 32) * 8;
|
|
}
|
|
|
|
// Вывод символа по координатам
|
|
static void print_char(uint64_t x, uint64_t y, char glyth) {
|
|
for (uint64_t i = 0; i < FONT_6X8_SLIM_CHAR_HEIGHT; i++) {
|
|
fb_print_bits(x, y + i, font_6x8_slim[analyze(glyth) + i]);
|
|
}
|
|
}
|
|
|
|
void log_dump_buffer( ) {
|
|
for (uint64_t i = 0; i < buf_pos; i++) { com_write_byte(log_buffer[i]); }
|
|
}
|
|
|
|
static void log_fb_putchar(char c) {
|
|
if (c == '\0' || fb_init_status < 1) { return; }
|
|
if (c == '\t') {
|
|
fb_pos_x += FONT_6X8_SLIM_CHAR_WIDTH * 4;
|
|
} else if (c == '\n') {
|
|
fb_pos_x = 4;
|
|
fb_pos_y += FONT_6X8_SLIM_CHAR_HEIGHT + 1;
|
|
} else {
|
|
if (fb_pos_x >= SCREEN_WIDTH) {
|
|
fb_pos_x = 4;
|
|
fb_pos_y += FONT_6X8_SLIM_CHAR_HEIGHT + 1;
|
|
}
|
|
|
|
if (fb_pos_y + FONT_6X8_SLIM_CHAR_HEIGHT >= SCREEN_HEIGHT) {
|
|
// Дошли до нижнего края экрана
|
|
while (log_buffer[0] != '\n') {
|
|
for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; }
|
|
buf_pos--;
|
|
}
|
|
for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; }
|
|
buf_pos--;
|
|
redraw_screen( );
|
|
return;
|
|
}
|
|
|
|
print_char(fb_pos_x, fb_pos_y, c);
|
|
fb_pos_x += FONT_6X8_SLIM_CHAR_WIDTH;
|
|
}
|
|
}
|
|
|
|
void redraw_screen( ) {
|
|
// Перерисовка экрана
|
|
for (uint64_t i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { SCREEN_BUFFER[i] = DARK_GREEN; }
|
|
|
|
fb_pos_x = 4;
|
|
fb_pos_y = 0;
|
|
|
|
for (uint64_t i = 0; i < buf_pos; i++) { log_fb_putchar(log_buffer[i]); }
|
|
}
|
|
|
|
void log_putchar(char c) {
|
|
log_buffer[buf_pos] = c;
|
|
com_write_byte(c);
|
|
|
|
log_buffer[buf_pos] = c;
|
|
|
|
if (buf_pos + 1 == buf_max) {
|
|
// Смещение буфера на 1 символ влево
|
|
for (uint64_t i = 0; i < buf_max - 1; i++) { log_buffer[i] = log_buffer[i + 1]; }
|
|
|
|
if (fb_init_status < 1) { return; }
|
|
redraw_screen( );
|
|
} else {
|
|
buf_pos++;
|
|
|
|
if (fb_init_status < 1) { return; }
|
|
log_fb_putchar(c);
|
|
}
|
|
}
|
|
|
|
// Вывод текстового сообщения
|
|
void log_printf(char *str, ...) {
|
|
LOCK(log_lock);
|
|
va_list args;
|
|
va_start(args, str);
|
|
tool_format(&log_putchar, str, args);
|
|
lock_release(log_lock);
|
|
va_end(args);
|
|
}
|
|
|
|
void log_init_mem( ) {
|
|
LOCK(log_lock);
|
|
if (fb_init_status < 1) {
|
|
LOG("Нет доступных фреймбуфферов для вывода\n");
|
|
return;
|
|
}
|
|
|
|
LOG("Полная инициализация отладчика занимает %u килобайт озу\n",
|
|
(((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT)) / 1024);
|
|
|
|
log_buffer = mem_alloc(((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT));
|
|
tool_memcpy(log_buffer, start_buffer, buf_max);
|
|
buf_max = ((SCREEN_WIDTH - 4) / FONT_WIDTH) * (SCREEN_HEIGHT / FONT_HEIGHT);
|
|
LOG("Размер буффера: %u символов\n", buf_max);
|
|
redraw_screen( );
|
|
lock_release(log_lock);
|
|
}
|
|
|
|
void log_init( ) {
|
|
log_buffer = (char *)&start_buffer;
|
|
} |