diff --git a/VGAColor.cs b/VGAColor.cs index 488488b..ea7b45a 100644 --- a/VGAColor.cs +++ b/VGAColor.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cosmos.System.Graphics +namespace Cosmos.System.Graphics { public enum VGAColor { diff --git a/VGADriverII.cs b/VGADriverII.cs index ec60fef..c42a76d 100644 --- a/VGADriverII.cs +++ b/VGADriverII.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Cosmos.Core; +using Cosmos.Core; using Cosmos.System.Graphics; namespace Cosmos.HAL @@ -14,6 +11,8 @@ public enum VGAMode Text90x60, Pixel320x200, Pixel320x200DB, + Pixel640x480, + Pixel640x480DB, } // vga mode register dumps @@ -102,6 +101,27 @@ public static class VGAModeRegisters 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00 }; + + // pixel 640x480x16 + public static byte[] Mode640x480x16_Pixel = new byte[] + { + /* MISC */ + 0xE3, + /* SEQ */ + 0x03, 0x01, 0x08, 0x00, 0x06, + /* CRTC */ + 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3, + 0xFF, + /* GC */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F, + 0xFF, + /* AC */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x01, 0x00, 0x0F, 0x00, 0x00 + }; } // vga controller class @@ -137,7 +157,7 @@ public static unsafe class VGADriverII // buffer public static byte* Buffer; - private static MemoryBlock BackBuffer = new MemoryBlock(0x60000, 0x10000); + private static MemoryBlock BackBuffer; // color palette - 8 bit public static uint[] Palette256 = new uint[256] @@ -164,60 +184,65 @@ public static unsafe class VGADriverII public static uint[] Palette16 = new uint[16] { 0x000000, 0x00001F, 0x001F00, 0x001F1F, 0x1F0000, 0x1F001F, 0x2F1F00, 0x2F2F2F, 0x1F1F1F, 0x00103F, 0x003F00, 0x003F3F, 0x3F0000, 0x3F003F, 0x3F3F00, 0x3F3F3F, }; - // initialization - public static void Initialize(VGAMode mode) - { - SetMode(mode); - } - #region Graphics Handling // clear screen public static void Clear(byte color) { - uint i = 0; // text mode - if (IsTextMode) { for (i = 0; i < (Width * Height) * 2; i += 2) { Buffer[i] = 0x20; Buffer[i + 1] = color; } } + if (IsTextMode) + for (uint i = 0; i < Width * Height * 2; i += 2) + { + Buffer[i] = 0x20; + Buffer[i + 1] = (byte)(color << 4); + } // graphics mode - else if (!IsTextMode && !IsDoubleBuffered) { for (i = 0; i < Width * Height; i++) { Buffer[i] = color; } } - // double buffered graphics mode - else if (!IsTextMode && IsDoubleBuffered) { BackBuffer.Fill(color); } + else + { + // double buffered + if (IsDoubleBuffered) + BackBuffer.Fill(color); + else + for (uint i = 0; i < Width * Height; i++) + Buffer[i] = color; + } } // draw pixel public static void DrawPixel(ushort x, ushort y, byte color) { - if (x >= Width || y >= Height) { return; } - if (IsTextMode) { return; } + if (x >= Width || y >= Height || IsTextMode) + return; + uint offset = (uint)(x + (y * Width)); // double buffered - if (IsDoubleBuffered) { BackBuffer.Bytes[offset] = color; } + if (IsDoubleBuffered) + BackBuffer.Bytes[offset] = color; // direct - else { Buffer[offset] = color; } + else + Buffer[offset] = color; } // swap back buffer public static void Display() { - // check mode - if (ModeID != VGAMode.Pixel320x200DB) { return; } + // check if double buffered + if (!IsDoubleBuffered) + return; byte* src = (byte*)BackBuffer.Base; for (uint i = 0; i < Width * Height; i++) - { if (*(Buffer + i) != *(src + i)) - { *(Buffer + i) = *(src + i); - } - } } // set text-mode cursor position public static void SetCursorPos(ushort x, ushort y) { - if (!IsTextMode) { return; } + if (!IsTextMode) + return; uint offset = (uint)(x + (y * Width)); PORT_CRTC_WRITE.Byte = 14; PORT_CRTC_DATA.Byte = (byte)((offset & 0xFF00) >> 8); @@ -251,6 +276,9 @@ private static void SetModeProperties(ushort w, ushort h, byte depth, bool text, Width = w; Height = h; Depth = depth; IsTextMode = text; IsDoubleBuffered = db; + + if (db) + BackBuffer = new MemoryBlock(0x60000, (uint) (Width * Height * Depth)); } // set current video mode @@ -307,12 +335,28 @@ public static void SetMode(VGAMode mode) SetColorPalette(Palette256); break; } + // 640x480 graphics mode + case VGAMode.Pixel640x480: + { + SetModeProperties(640, 480, 4, false, false); + fixed (byte* ptr = VGAModeRegisters.Mode640x480x16_Pixel) { WriteRegisters(ptr); } + ClearColorPalette(); + SetColorPalette(Palette16); + break; + } + // 640x480 double buffered graphics mode + case VGAMode.Pixel640x480DB: + { + SetModeProperties(640, 480, 4, false, true); + fixed (byte* ptr = VGAModeRegisters.Mode640x480x16_Pixel) { WriteRegisters(ptr); } + ClearColorPalette(); + SetColorPalette(Palette16); + break; + } // default to 80x25 text mode - default: { break; } + default: + break; } - - // clear the screen - Clear(0); } // get frame buffer segment @@ -334,10 +378,14 @@ public static void SetMode(VGAMode mode) private static void WriteRegisters(byte* regs) { // misc - PORT_MISC_WRITE.Byte = *(regs++); + PORT_MISC_WRITE.Byte = *regs++; // sequencer - for (byte i = 0; i < 5; i++) { PORT_SEQ_WRITE.Byte = i; PORT_SEQ_DATA.Byte = *(regs++); } + for (byte i = 0; i < 5; i++) + { + PORT_SEQ_WRITE.Byte = i; + PORT_SEQ_DATA.Byte = *regs++; + } // crtc PORT_CRTC_WRITE.Byte = 0x03; @@ -348,10 +396,18 @@ private static void WriteRegisters(byte* regs) // registers regs[0x03] = (byte)(regs[0x03] | 0x80); regs[0x11] = (byte)(regs[0x11] & ~0x80); - for (byte i = 0; i < 25; i++) { PORT_CRTC_WRITE.Byte = i; PORT_CRTC_DATA.Byte = *(regs++); } + for (byte i = 0; i < 25; i++) + { + PORT_CRTC_WRITE.Byte = i; + PORT_CRTC_DATA.Byte = *regs++; + } // graphics controller - for (byte i = 0; i < 9; i++) { PORT_GC_WRITE.Byte = i; PORT_GC_DATA.Byte = *(regs++); } + for (byte i = 0; i < 9; i++) + { + PORT_GC_WRITE.Byte = i; + PORT_GC_DATA.Byte = *regs++; + } // attribute controller byte val = 0; @@ -359,13 +415,12 @@ private static void WriteRegisters(byte* regs) { val = PORT_INSTAT_READ.Byte; PORT_AC_WRITE.Byte = i; - PORT_AC_WRITE.Byte = *(regs++); + PORT_AC_WRITE.Byte = *regs++; } val = PORT_INSTAT_READ.Byte; PORT_AC_WRITE.Byte = 0x20; - // set buffer address Buffer = GetFrameBufferSegment(); } diff --git a/VGAFont.cs b/VGAFont.cs index 53b10ab..e73a64c 100644 --- a/VGAFont.cs +++ b/VGAFont.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cosmos.System.Graphics +namespace Cosmos.System.Graphics { public enum VGAFont { - Font3x5, + Font3x5, Font8x8, Font8x16, } diff --git a/VGAGraphics.cs b/VGAGraphics.cs index 42180ac..ee3159e 100644 --- a/VGAGraphics.cs +++ b/VGAGraphics.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Cosmos.HAL; +using System; using vga = Cosmos.HAL.VGADriverII; namespace Cosmos.System.Graphics { - // this class is used to store vga-related graphical functions + // this class is used as a wrapper to the vga driver public static class VGAGraphics { private static int fontHeight = 16; @@ -13,6 +12,9 @@ public static class VGAGraphics // clear the screen public static void Clear(VGAColor color) { vga.Clear((byte)color); } + // initialize the driver + public static void Initialize(VGAMode mode) { vga.SetMode(mode); } + // swap back buffer if able public static void Display() { vga.Display(); } @@ -23,21 +25,22 @@ public static class VGAGraphics public static void DrawFilledRect(int x, int y, int w, int h, VGAColor color) { for (int i = 0; i < h; i++) - { - for (int j = 0; j < w; j++) { DrawPixel(x + j, y + i, color); } - } + for (int j = 0; j < w; j++) + DrawPixel(x + j, y + i, color); } // draw horizontal line public static void DrawLineX(int x, int y, int w, VGAColor color) { - for (int i = 0; i < w; i++) { DrawPixel(x + i, y, color); } + for (int i = 0; i < w; i++) + DrawPixel(x + i, y, color); } // draw vertical line public static void DrawLineY(int x, int y, int h, VGAColor color) { - for (int i = 0; i < h; i++) { DrawPixel(x, y + i, color); } + for (int i = 0; i < h; i++) + DrawPixel(x, y + i, color); } // draw point-to-point line @@ -57,10 +60,22 @@ public static void DrawLine(int x0, int y0, int x1, int y1, VGAColor color) DrawPixel(xx, yy, color); // increment - if ((x0 == x1) && (y0 == y1)) break; + if ((x0 == x1) && (y0 == y1)) + break; + var e2 = 2 * err; - if (e2 > -dy) { err -= dy; xx += (int)sx; } - if (e2 < dx) { err += dx; yy += (int)sy; } + + if (e2 > -dy) + { + err -= dy; + xx += sx; + } + + if (e2 < dx) + { + err += dx; + yy += sy; + } } } @@ -68,14 +83,13 @@ public static void DrawLine(int x0, int y0, int x1, int y1, VGAColor color) public static void DrawChar(int x, int y, char c, VGAColor fg, VGAFont font) { // determine font size - fontHeight = 8; - if (font == VGAFont.Font8x8) { fontHeight = 8; } - else if (font == VGAFont.Font8x16) { fontHeight = 16; } + if (font == VGAFont.Font8x8) + fontHeight = 8; + int p = fontHeight * (byte)c; // vertical for (int cy = 0; cy < fontHeight; cy++) - { // horizontal for (byte cx = 0; cx < 8; cx++) { @@ -84,31 +98,29 @@ public static void DrawChar(int x, int y, char c, VGAColor fg, VGAFont font) { // convert to position and draw if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x8_Data[p + cy], cx + 1)) - { DrawPixel(x + (8 - cx), y + cy, fg); } + DrawPixel(x + (8 - cx), y + cy, fg); } // 8x16 else if (font == VGAFont.Font8x16) { // convert to position and draw if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x16_Data[p + cy], cx + 1)) - { DrawPixel(x + (8 - cx), y + cy, fg); } + DrawPixel(x + (8 - cx), y + cy, fg); } } - } } // draw character with background color public static void DrawChar(int x, int y, char c, VGAColor fg, VGAColor bg, VGAFont font) { // determine font size - fontHeight = 8; - if (font == VGAFont.Font8x8) { fontHeight = 8; } - else if (font == VGAFont.Font8x16) { fontHeight = 16; } + if (font == VGAFont.Font8x8) + fontHeight = 8; + int p = fontHeight * (byte)c; // vertical for (int cy = 0; cy < fontHeight; cy++) - { // horizontal for (byte cx = 0; cx < 8; cx++) { @@ -117,34 +129,44 @@ public static void DrawChar(int x, int y, char c, VGAColor fg, VGAColor bg, VGAF { // convert to position and draw if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x8_Data[p + cy], cx + 1)) - { DrawPixel(x + (8 - cx), y + cy, fg); } else { DrawPixel(x + (8 - cx), y + cy, bg); } + DrawPixel(x + (8 - cx), y + cy, fg); + else + DrawPixel(x + (8 - cx), y + cy, bg); } // 8x16 else if (font == VGAFont.Font8x16) { // convert to position and draw if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x16_Data[p + cy], cx + 1)) - { DrawPixel(x + (8 - cx), y + cy, fg); } else { DrawPixel(x + (8 - cx), y + cy, bg); } + DrawPixel(x + (8 - cx), y + cy, fg); + else + DrawPixel(x + (8 - cx), y + cy, bg); } } - } } // draw string with transparent background public static void DrawString(int x, int y, string text, VGAColor fg, VGAFont font) { // determine font size - fontHeight = 8; - if (font == VGAFont.Font8x8) { fontHeight = 8; } - else if (font == VGAFont.Font8x16) { fontHeight = 16; } + if (font == VGAFont.Font8x8) + fontHeight = 8; int xx = x, yy = y; for (int i = 0; i < text.Length; i++) { // new line - if (text[i] == '\n') { xx = x; yy += fontHeight; } + if (text[i] == '\n') + { + xx = x; + yy += fontHeight; + } // character - else { DrawChar(xx, yy, text[i], fg, font); xx += 8; } + else + { + DrawChar(xx, yy, text[i], fg, font); + xx += 8; + } } } @@ -152,17 +174,24 @@ public static void DrawString(int x, int y, string text, VGAColor fg, VGAFont fo public static void DrawString(int x, int y, string text, VGAColor fg, VGAColor bg, VGAFont font) { // determine font size - fontHeight = 8; - if (font == VGAFont.Font8x8) { fontHeight = 8; } - else if (font == VGAFont.Font8x16) { fontHeight = 16; } + if (font == VGAFont.Font8x8) + fontHeight = 8; int xx = x, yy = y; for (int i = 0; i < text.Length; i++) { // new line - if (text[i] == '\n') { xx = x; yy += fontHeight; } + if (text[i] == '\n') + { + xx = x; + yy += fontHeight; + } // character - else { DrawChar(xx, yy, text[i], fg, bg, font); xx += 8; } + else + { + DrawChar(xx, yy, text[i], fg, bg, font); + xx += 8; + } } } @@ -170,25 +199,17 @@ public static void DrawString(int x, int y, string text, VGAColor fg, VGAColor b public static void DrawImage(int x, int y, VGAImage image) { for (int yy = 0; yy < image.Height; yy++) - { for (int xx = 0; xx < image.Width; xx++) - { DrawPixel(x + xx, y + yy, (VGAColor)image.Data[xx + (yy * image.Width)]); - } - } } // draw custom image format with transparency key public static void DrawImage(int x, int y, VGAColor transKey, VGAImage image) { for (int yy = 0; yy < image.Height; yy++) - { for (int xx = 0; xx < image.Width; xx++) - { if (image.Data[xx + (yy * image.Width)] != (byte)transKey) - { DrawPixel(x + xx, y + yy, (VGAColor)image.Data[xx + (yy * image.Width)]); } - } - } + DrawPixel(x + xx, y + yy, (VGAColor)image.Data[xx + (yy * image.Width)]); } } } diff --git a/VGAImage.cs b/VGAImage.cs index e73d293..76e76e6 100644 --- a/VGAImage.cs +++ b/VGAImage.cs @@ -1,7 +1,4 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Text; +using System.IO; namespace Cosmos.System.Graphics { diff --git a/Terminal.cs b/VGATerminal.cs similarity index 90% rename from Terminal.cs rename to VGATerminal.cs index 3145157..29ada73 100644 --- a/Terminal.cs +++ b/VGATerminal.cs @@ -1,12 +1,9 @@ using System; -using System.Collections.Generic; -using System.Text; -using Cosmos.HAL; using Cosmos.System.Graphics; namespace Cosmos.HAL { - public static class Terminal + public static class VGATerminal { // cursor public static int CursorX { get; private set; } @@ -116,8 +113,10 @@ public static void NewLine() // scroll by one line private static unsafe void Scroll() { - VGADriverII.MemoryCopy(VGADriverII.Buffer + (VGADriverII.Width * 2), VGADriverII.Buffer, (VGADriverII.Width * (VGADriverII.Height - 1)) * 2); - for (int i = 0; i < VGADriverII.Width; i++) { PutCharacter(i, VGADriverII.Height - 1, ' ', TextColor, BackColor); } + //VGADriverII.MemoryCopy(VGADriverII.Buffer + (VGADriverII.Width * 2), VGADriverII.Buffer, VGADriverII.Width * (VGADriverII.Height - 1) * 2); + + for (int i = 0; i < VGADriverII.Width; i++) + PutCharacter(i, VGADriverII.Height - 1, ' ', TextColor, BackColor); } // set cursor position