Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions VGAColor.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Cosmos.System.Graphics
namespace Cosmos.System.Graphics
{
public enum VGAColor
{
Expand Down
129 changes: 92 additions & 37 deletions VGADriverII.cs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -14,6 +11,8 @@ public enum VGAMode
Text90x60,
Pixel320x200,
Pixel320x200DB,
Pixel640x480,
Pixel640x480DB,
}

// vga mode register dumps
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -348,24 +396,31 @@ 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;
for (byte i = 0; i < 21; i++)
{
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();
}
Expand Down
8 changes: 2 additions & 6 deletions VGAFont.cs
Original file line number Diff line number Diff line change
@@ -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,
}
Expand Down
Loading