/** * log.c * Функции отладки * * Функционал отладки * */ #include #include #include #include #include #include #include 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; }