#include "VGATextOutput.class.h" #include #include //Virtual address in higher half #define RAM_ADDR 0xC00B8000 using namespace Sys; //For outb using namespace Disp; String VGATextOutput::getClass() { return "display.text"; } String VGATextOutput::getName() { return "Standard VGA text display"; } void VGATextOutput::getModes(Vector &to) { mode_t m; m.textCols = 40; m.textRows = 25; m.identifier = 1; m.graphWidth = 0; m.graphHeight = 0; m.graphDepth = 0; m.device = this; to.push(m); m.textCols = 80; m.identifier = 3; //3 = text 80x25 16color, just what we want to.push(m); } bool VGATextOutput::setMode(mode_t& mode) { if (mode.device == this && (mode.identifier == 3 or mode.identifier == 1)) { v86_regs_t r; r.ax = mode.identifier; m_cols = mode.textCols; V86::biosInt(0x10, r); clear(); return true; } return false; } void VGATextOutput::putChar(u16int line, u16int col, WChar c, u8int color) { u16int* where = (u16int*)RAM_ADDR; where[(m_cols * line) + col] = (color << 8) | c.toAscii(); } void VGATextOutput::moveCursor(u16int line, u16int col) { u16int csrLoc = (line * m_cols) + col; outb(0x3D4, 14); outb(0x3D5, csrLoc >> 8); outb(0x3D4, 15); outb(0x3D5, csrLoc & 0xFF); } void VGATextOutput::clear() { u16int* where = (u16int*)RAM_ADDR; for (int i = 0; i < 25 * 80; i++) where[i] = 0; } bool VGATextOutput::textScroll(u16int line, u16int col, u16int height, u16int width, u8int color) { u8int* where = (u8int*)RAM_ADDR; for (u32int i = 1; i < height; i++) { memcpy(where + ((line + i - 1) * (m_cols * 2)) + (col * 2), where + ((line + i) * (m_cols * 2)) + (col * 2), width * 2); } u16int* w = (u16int*)where; memsetw(w + ((line + height - 1) * m_cols) + col, 0x20 | (color << 8), width); return true; }