#include "vgatxt.h" #include #include static uint16_t *video_memory = (uint16_t*)((size_t)K_HIGHHALF_ADDR + 0xB8000); #define VIDMEM_SIZE (80 * 25 * 2) vgatxt *text_display; vgatxt::vgatxt(node *parent) : display(parent) { dev_type = DT_VGATXT; } int vgatxt::text_w() { return 80; } int vgatxt::text_h() { return 25; } void vgatxt::text_setcsr(int l, int c, bool visible) { uint16_t cursor_location = l * 80 + c; if (!visible) cursor_location = 10000; outb(0x3D4, 14); //Sending high cursor byte outb(0x3D5, cursor_location >> 8); outb(0x3D4, 15); //Sending high cursor byte outb(0x3D5, cursor_location); } void vgatxt::text_put(int l, int c, int ch, uint8_t fgcolor, uint8_t bgcolor) { if (ch >= 0x80) ch = '?'; video_memory[l * 80 + c] = (char)ch | ((bgcolor << 4 | fgcolor) << 8); } void vgatxt::text_scroll(int n, uint8_t fgcolor, uint8_t bgcolor) { //TODO: optimize if (n > 0) { for (int i = 0; i < n; i++) { uint16_t blank = (((bgcolor << 4) | fgcolor) << 8) | 0x20; int j; for (j = 0; j < 80*24; j++) { video_memory[j] = video_memory[j+80]; } for (j = 80*24; j < 80*25; j++) { video_memory[j] = blank; } } } else if (n < 0) { // TODO } } // Operations as a FS node size_t vgatxt::get_size() { // size as a node of the filesystem return (text_w() << 16) + text_h(); } int vgatxt::read(size_t offset, size_t len, char *buffer) { if (offset > VIDMEM_SIZE) return 0; if (offset + len > VIDMEM_SIZE) len = VIDMEM_SIZE - offset; char *vm = (char*)video_memory; memcpy(buffer, vm + offset, len); return len; } int vgatxt::write(size_t offset, size_t len, char *buffer) { if (offset > VIDMEM_SIZE) return 0; if (offset + len > VIDMEM_SIZE) len = VIDMEM_SIZE - offset; char *vm = (char*)video_memory; memcpy(vm + offset, buffer, len); return len; } int vgatxt::dev_control(char *data) { uint16_t *d = (uint16_t*)data; text_setcsr(d[0], d[1], d[2] != 0); return 0; }