2019-07-03 18:12:57 +02:00
|
|
|
#include "tty.h"
|
|
|
|
#include "../libc/string.h"
|
|
|
|
#include "ports.h"
|
|
|
|
|
|
|
|
#define VGA_PTR ((uint8_t*) VIDEO_MEM_ADDR) // Pointer to frame buffer
|
|
|
|
// Also define a 2 byte pointer because cells are 16 bits wide
|
|
|
|
#define UVGA_PTR ((uint16_t *)VIDEO_MEM_ADDR)
|
|
|
|
|
2019-07-08 18:43:45 +02:00
|
|
|
static uint32_t fb_col = 1; // X
|
2019-07-03 18:12:57 +02:00
|
|
|
static uint32_t fb_row = 0; // Y
|
|
|
|
|
2019-07-03 21:04:05 +02:00
|
|
|
void write_cell(int16_t i, uint8_t c, uint8_t fg, uint8_t bg) {
|
2019-07-03 18:12:57 +02:00
|
|
|
uint8_t *fb = VGA_PTR;
|
|
|
|
fb[i*2] = c;
|
2019-07-04 12:49:53 +02:00
|
|
|
fb[i*2 + 1] = ((bg & 0x0F) << 4) | (fg & 0x0F);
|
2019-07-03 18:12:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void move_cursor(uint16_t pos) {
|
|
|
|
outb(VGA_CMD_PORT, VGA_HIGH_BYTE);
|
|
|
|
outb(VGA_DATA_PORT, ((pos >> 8) & 0x00FF));
|
|
|
|
outb(VGA_CMD_PORT, VGA_LOW_BYTE);
|
|
|
|
outb(VGA_DATA_PORT, pos & 0x00FF);
|
|
|
|
}
|
|
|
|
|
2020-08-24 01:12:39 +02:00
|
|
|
void cursor_adv() { // TODO: specify number of adv. with a parameter
|
2019-07-03 18:12:57 +02:00
|
|
|
if(fb_col < VGA_WIDTH - 1)
|
2019-07-04 01:58:34 +02:00
|
|
|
fb_col++;
|
2019-07-03 18:12:57 +02:00
|
|
|
else
|
|
|
|
newline();
|
|
|
|
|
|
|
|
move_cursor(fb_col + (fb_row * VGA_WIDTH));
|
|
|
|
}
|
|
|
|
|
|
|
|
void cursor_prev() {
|
|
|
|
if(fb_col == 0) {
|
|
|
|
if(fb_row == 0)
|
|
|
|
return; // If first row do not do anything
|
|
|
|
fb_col = VGA_WIDTH - 1;
|
|
|
|
fb_row--;
|
|
|
|
} else
|
|
|
|
fb_col--;
|
|
|
|
move_cursor(fb_col + (fb_row * VGA_WIDTH));
|
|
|
|
}
|
|
|
|
|
|
|
|
void backspace() {
|
|
|
|
uint16_t pos;
|
|
|
|
uint8_t c = ' ';
|
|
|
|
|
|
|
|
fb_col--;
|
|
|
|
pos = fb_col + (fb_row * VGA_WIDTH);
|
|
|
|
write_cell(pos, c, WHITE, BLACK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void kprint_c(uint8_t *buf, uint32_t len, uint8_t fg, uint8_t bg) {
|
|
|
|
uint16_t pos;
|
|
|
|
for(uint32_t i = 0; i < len; i++) {
|
|
|
|
uint8_t c = buf[i];
|
|
|
|
if(c == '\n' || c == '\r')
|
|
|
|
newline();
|
2020-08-24 01:12:39 +02:00
|
|
|
else if(c == '\t')
|
|
|
|
tab();
|
2019-07-03 21:04:05 +02:00
|
|
|
else {
|
2019-07-03 18:12:57 +02:00
|
|
|
pos = fb_col + (fb_row * VGA_WIDTH);
|
2019-07-03 21:04:05 +02:00
|
|
|
write_cell(pos, (uint8_t)c, fg, bg);
|
2019-07-03 18:12:57 +02:00
|
|
|
cursor_adv();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void kprint(uint8_t *buf) {
|
|
|
|
kprint_c(buf, strlen(buf), WHITE, BLACK);
|
|
|
|
}
|
|
|
|
|
2019-09-19 12:04:12 +02:00
|
|
|
void kprint_dec(uint32_t num) {
|
|
|
|
if(num == 0) {
|
2019-09-20 11:50:01 +02:00
|
|
|
uint8_t *buf = (uint8_t*)'0';
|
2019-09-19 12:04:12 +02:00
|
|
|
kprint_c(buf, strlen(buf), WHITE, BLACK);;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int32_t acc = num;
|
|
|
|
uint8_t c[32];
|
2019-09-20 11:50:01 +02:00
|
|
|
int32_t i = 0;
|
2019-09-19 12:04:12 +02:00
|
|
|
while(acc > 0) {
|
|
|
|
c[i] = '0' + acc%10;
|
|
|
|
acc /= 10;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
c[i] = 0;
|
|
|
|
uint8_t c2[32];
|
|
|
|
c2[i--] = 0;
|
|
|
|
uint32_t j = 0;
|
|
|
|
while(i >= 0)
|
|
|
|
c2[i--] = c[j++];
|
|
|
|
kprint(c2);
|
|
|
|
}
|
|
|
|
|
2019-07-03 18:12:57 +02:00
|
|
|
void init_prompt() {
|
2019-07-08 18:43:45 +02:00
|
|
|
uint8_t *prompt = (uint8_t*)"\nring0@iceOS-$ ";
|
|
|
|
kprint_c(prompt, strlen(prompt), LIGHT_RED, BLACK);
|
2019-07-03 18:12:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void clear_prompt() {
|
2019-07-08 18:43:45 +02:00
|
|
|
fb_col = 1;
|
2019-07-03 18:12:57 +02:00
|
|
|
fb_row = 0;
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < (VGA_WIDTH * VGA_HEIGHT); i++)
|
|
|
|
write_cell(i, ' ', WHITE, BLACK);
|
|
|
|
move_cursor(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear_row(uint8_t row) {
|
|
|
|
for(size_t i = 0; i < VGA_WIDTH; i++)
|
|
|
|
write_cell((row*VGA_WIDTH)+i, ' ', WHITE, BLACK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scroll() {
|
|
|
|
uint16_t *fb = UVGA_PTR;
|
|
|
|
memmove(fb, fb+VGA_WIDTH, VGA_WIDTH*2*(VGA_HEIGHT*2-1));
|
|
|
|
clear_row(VGA_HEIGHT - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void newline() {
|
|
|
|
if(fb_row < VGA_HEIGHT - 1) // If there's at least one cell add it
|
|
|
|
fb_row++;
|
|
|
|
else // Otherwise scroll framebuffer
|
|
|
|
scroll();
|
|
|
|
|
2019-07-08 18:43:45 +02:00
|
|
|
fb_col = 1;
|
2019-07-03 18:12:57 +02:00
|
|
|
move_cursor(fb_col + (fb_row * VGA_WIDTH));
|
2020-08-24 01:12:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void tab() {
|
|
|
|
for(uint8_t i = 0; i < 4; i++)
|
|
|
|
cursor_adv(); // Increment cursor 4 times
|
|
|
|
}
|