From b2814db927c0e5663c7e182faf62090b57e251cf Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 22 Jul 2012 15:51:38 +0200 Subject: [PATCH] Added support for getting a copy of the VGA Font. This will be useful for providing a text-mode like environment (console) after having switched to graphical mode where the system needs a font. --- sortix/vga.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++---- sortix/vga.h | 16 ++++++--- 2 files changed, 103 insertions(+), 11 deletions(-) diff --git a/sortix/vga.cpp b/sortix/vga.cpp index ad068ee3..0fc71a8d 100644 --- a/sortix/vga.cpp +++ b/sortix/vga.cpp @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. This file is part of Sortix. @@ -14,13 +14,13 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . - vga.h + vga.cpp A Video Graphics Array driver. -******************************************************************************/ +*******************************************************************************/ #include #include @@ -31,6 +31,8 @@ #include "process.h" #include "serialterminal.h" +#define TEST_VGAFONT 0 + using namespace Maxsi; namespace Sortix @@ -41,9 +43,93 @@ namespace Sortix const unsigned WIDTH = 80; const unsigned HEIGHT = 25; const size_t VGA_SIZE = sizeof(uint16_t) * WIDTH * HEIGHT; + size_t vgafontsize; + uint8_t* vgafont; + + static void WriteIndex(uint16_t port, uint8_t index, uint8_t value) + { + CPU::OutPortB(port, index); + CPU::OutPortB(port+1, value); + } + + static uint8_t ReadIndex(uint16_t port, uint8_t index) + { + CPU::OutPortB(port, index); + return CPU::InPortB(port+1); + } + + static uint8_t ReplaceIndex(uint16_t port, uint8_t index, uint8_t value) + { + uint8_t ret = ReadIndex(port, index); + WriteIndex(port, index, value); + return ret; + } + + static void FetchVGAFont(uint8_t* font) + { + // TODO: I just got these magic constants off the net. + // Select plane 2 for reading. + uint8_t old_03ce_04 = ReplaceIndex(0x03CE, 0x04, 0x02); + // Clear even/odd mode. + uint8_t old_03ce_05 = ReplaceIndex(0x03CE, 0x05, 0x04); + // Map VGA Memory to 0xA0000 (Select 0xA0000-0xAFFFF). + uint8_t old_03ce_06 = ReplaceIndex(0x03CE, 0x06, 0x04); + // Set bitplane 2. + uint8_t old_03c4_02 = ReplaceIndex(0x03C4, 0x02, 0x04); + // Clear even/odd mode (the other way, don't ask why). + uint8_t old_03c4_04 = ReplaceIndex(0x03C4, 0x04, 0x07); + // The font data is now at 0xA0000, so fetch it. Note that there is + // reserved room for a 8x32 resolution but we are using 8x16. + const uint8_t* data = (const uint8_t*) 0xA0000UL; + for ( size_t i = 0; i < VGA_FONT_NUMCHARS; i++ ) + { + const uint8_t* src = data + (32*8)/8 * i; + uint8_t* dest = font + VGA_FONT_CHARSIZE * i; + Memory::Copy(dest, src, VGA_FONT_CHARSIZE); + } + // Restore the VGA state. + WriteIndex(0x03C4, 0x02, old_03c4_02); + WriteIndex(0x03C4, 0x04, old_03c4_04); + WriteIndex(0x03CE, 0x05, old_03ce_05); + WriteIndex(0x03CE, 0x06, old_03ce_06); + WriteIndex(0x03CE, 0x04, old_03ce_04); + } + +#if TEST_VGAFONT + static void PrintFontChar(const uint8_t* font, unsigned char c) + { + const uint8_t* glyph = font + VGA_FONT_CHARSIZE * (size_t) c; + for ( size_t y = 0; y < VGA_FONT_HEIGHT; y++ ) + { + for ( size_t x = 0; x < VGA_FONT_WIDTH; x++ ) + { + size_t bitindex = y * VGA_FONT_WIDTH + x; + uint8_t bitmap = glyph[bitindex/8UL]; + uint8_t bitmod = bitindex % 8UL; + uint8_t bitmask = 1U << bitmod; + const char* toprint = (bitmap & bitmask) ? "X" : " "; + Log::Print(toprint); + } + Log::Print("\n"); + } + } +#endif + + const uint8_t* GetFont() + { + return vgafont; + } void Init() { + vgafontsize = VGA_FONT_NUMCHARS * VGA_FONT_CHARSIZE; + if ( !(vgafont = new uint8_t[vgafontsize]) ) + Panic("Unable to allocate vga font buffer"); + FetchVGAFont(vgafont); +#if TEST_VGAFONT + PrintFontChar(vgafont, 'A'); + PrintFontChar(vgafont, 'S'); +#endif } // Changes the position of the hardware cursor. diff --git a/sortix/vga.h b/sortix/vga.h index 18b6c830..efdcfee5 100644 --- a/sortix/vga.h +++ b/sortix/vga.h @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. This file is part of Sortix. @@ -14,13 +14,13 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . vga.h A Video Graphics Array driver. -******************************************************************************/ +*******************************************************************************/ #ifndef SORTIX_VGA_H #define SORTIX_VGA_H @@ -30,6 +30,11 @@ namespace Sortix { + const size_t VGA_FONT_WIDTH = 8UL; + const size_t VGA_FONT_HEIGHT = 16UL; + const size_t VGA_FONT_NUMCHARS = 256UL; + const size_t VGA_FONT_CHARSIZE = VGA_FONT_WIDTH * VGA_FONT_HEIGHT / 8UL; + namespace VGA { // TODO: Move these to a better place @@ -52,6 +57,7 @@ namespace Sortix void Init(); void SetCursor(nat x, nat y); + const uint8_t* GetFont(); } class DevVGA : public DevBuffer