/base/Kernel/Singularity.Hal.LegacyPC/HalScreenDirect.cs
C# | 342 lines | 271 code | 48 blank | 23 comment | 39 complexity | 314356007e431cbcd5aa2482ad01f48e MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Microsoft Research Singularity
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // File: HalScreenDirect.cs
- //
- // Note:
- // The Indispensable PC Hardware Book (Third Edition), pp1055-1066.
-
- using System;
- using System.Runtime.CompilerServices;
-
- using Microsoft.Singularity.Channels;
- using Microsoft.Singularity.Io;
- using Microsoft.Singularity.Configuration;
-
- [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
- [assembly: System.Reflection.AssemblyKeyFileAttribute(@"..\public.snk")]
- [assembly: System.Reflection.AssemblyDelaySignAttribute(true)]
-
- namespace Microsoft.Singularity.Hal
- {
- // declare resources for the kernel manifest
- [DriverCategory]
- public sealed class HalScreenResources : DriverCategoryDeclaration
- {
- [IoFixedPortRange(Base = 0x03d4, Length = 0x01, Shared = true)]
- public IoPortRange indexPort;
-
- [IoFixedPortRange(Base = 0x03d5, Length = 0x01, Shared = true)]
- public IoPortRange dataPort;
-
- [IoFixedMemoryRange(Base = 0xb8000, Length = 8000, Shared = true)]
- public IoMemoryRange screenMemory;
-
- // TODO: how can we represent endpoints here?
- //[ServiceEndpoint(typeof(ConsoleDeviceContract.Exp),
- // CustomName = "HalScreen")]
- //TRef<ServiceProviderContract.Exp:Start> conoutsp;
- }
-
- [CLSCompliant(false)]
- public class HalScreenDirect : HalScreen
- {
- public const int Columns = 80;
- public const int Rows = 50;
- public const int ScreenSize = Columns * Rows;
-
- public const ushort CGA_INDEX_PORT = 0x3d4;
- public const ushort CGA_DATA_PORT = 0x3d5;
- public const byte SmallCursorStart = 6;
- public const byte LargeCursorStart = 0;
-
- private enum Coloring
- {
- Dim = 0x1700,
- Yellow = 0x1e00,
- Green = 0x1a00,
- Red = 0x1c00,
- Normal = 0x1f00
- }
-
- private ushort color = (ushort)Coloring.Normal;
- private int cursor = 0;
- private bool cursorVisible = false;
- private byte cursorStartLine = SmallCursorStart;
-
- private const byte CGA_CURSOR_START = 0xa;
- private const byte CGA_CURSOR_MSB = 0xe;
- private const byte CGA_CURSOR_LSB = 0xf;
-
- private IoPort indexRegister = null;
- private IoPort dataRegister = null;
- private IoMemory screenBuffer = null;
-
- public HalScreenDirect(IoConfig config)
- {
- indexRegister =
- ((IoPortRange) config.FixedRanges[0]).PortAtOffset(
- 0, 1, Access.Write);
- dataRegister =
- ((IoPortRange) config.FixedRanges[1]).PortAtOffset(
- 0, 1, Access.Write);
- screenBuffer =
- ((IoMemoryRange) config.FixedRanges[2]).MemoryAtOffset(
- 0, ScreenSize * 2, Access.ReadWrite);
- Clear();
- WriteLine("Singularity HAL Console Driver.");
- UpdateCursor(true);
- }
-
- public HalScreenDirect()
- {
- // For compatibility with .csi compiled file
- DebugStub.Break();
- }
-
- [NoHeapAllocation]
- public void Dim()
- {
- color = (ushort)Coloring.Dim;
- }
-
- [NoHeapAllocation]
- public void Yellow()
- {
- color = (ushort)Coloring.Yellow;
- }
-
- [NoHeapAllocation]
- public void Green()
- {
- color = (ushort)Coloring.Green;
- }
-
- [NoHeapAllocation]
- public void Red()
- {
- color = (ushort)Coloring.Red;
- }
-
- [NoHeapAllocation]
- public void Normal()
- {
- color = (ushort)Coloring.Normal;
- }
-
- [NoHeapAllocation]
- public override void CursorFlash()
- {
- ushort was;
-
- screenBuffer.Read16NoThrow(0, out was);
- was &= (ushort)0xff00;
- screenBuffer.Write16NoThrow(0, was);
- }
-
- [NoHeapAllocation]
- public override void CursorHide()
- {
- UpdateCursor(false);
- }
-
- [NoHeapAllocation]
- public override void CursorShow()
- {
- UpdateCursor(true);
- }
-
- [NoHeapAllocation]
- public override void Clear()
- {
- if (screenBuffer == null) {
- DebugStub.Break();
- return;
- }
- ushort zip = (ushort)(color | ' ');
- IoResult result = screenBuffer.Write16NoThrow(0, zip, ScreenSize);
- DebugStub.Assert(IoResult.Success == result);
-
- cursor = 0;
- UpdateCursor(cursorVisible);
- }
-
- [NoHeapAllocation]
- public override void GetDisplayDimensions(out int columns, out int rows)
- {
- columns = Columns;
- rows = Rows;
- }
-
- [NoHeapAllocation]
- public override void GetCursorPosition(out int column, out int row)
- {
- column = cursor % Columns;
- row = cursor / Columns;
- }
-
- [NoHeapAllocation]
- public override void SetCursorSizeLarge()
- {
- cursorStartLine = LargeCursorStart;
- ForcedCursorUpdate();
- }
-
- [NoHeapAllocation]
- public override void SetCursorSizeSmall()
- {
- cursorStartLine = SmallCursorStart;
- ForcedCursorUpdate();
- }
-
- [NoHeapAllocation]
- private void ForcedCursorUpdate()
- {
- bool saved = cursorVisible;
- cursorVisible = !cursorVisible;
- UpdateCursor(saved);
- }
-
- [NoHeapAllocation]
- private void UpdateCursor(bool newVisibleState)
- {
- IoResult result;
-
- if (newVisibleState != cursorVisible) {
- byte cgaStart = 32; // Cursor off
- if (newVisibleState) {
- cgaStart = (byte)(64 + cursorStartLine); // Cursor on
- }
-
- result = indexRegister.Write8NoThrow(CGA_CURSOR_START);
- DebugStub.Assert(IoResult.Success == result);
-
- result = dataRegister.Write8NoThrow(cgaStart);
- DebugStub.Assert(IoResult.Success == result);
-
- cursorVisible = newVisibleState;
- }
-
- if (newVisibleState) {
- // Write cursor location
- result = indexRegister.Write8NoThrow(CGA_CURSOR_MSB);
- DebugStub.Assert(IoResult.Success == result);
- result = dataRegister.Write8NoThrow((byte)(cursor >> 8));
- DebugStub.Assert(IoResult.Success == result);
- result = indexRegister.Write8NoThrow(CGA_CURSOR_LSB);
- DebugStub.Assert(IoResult.Success == result);
- result = dataRegister.Write8NoThrow((byte)(cursor & 0xff));
- DebugStub.Assert(IoResult.Success == result);
- }
- }
-
- [NoHeapAllocation]
- public override bool SetCursorPosition(int column, int row)
- {
- if (column < 0 || column >= Columns ||
- row < 0 || row >= Rows) {
- return false;
- }
- cursor = column + row * Columns;
- UpdateCursor(cursorVisible);
- return true;
- }
-
- [NoHeapAllocation]
- public override void ClearCursorToEndOfLine()
- {
- // Writing to the screen is slow. We might
- // want to track how many characters are written per line
- // to speed this up.
- int column = cursor % Columns;
- int row = cursor / Columns;
- while (column != Columns) {
- PutCharAt(' ', column++, row);
- }
- }
-
- [NoHeapAllocation]
- public override bool PutCharAt(char c, int column, int row)
- {
- if (column < 0 || column >= Columns ||
- row < 0 || row >= Rows) {
- return false;
- }
- int offset = (column + row * Columns) * 2;
- IoResult result = screenBuffer.Write16NoThrow(offset,
- (ushort)(color | c));
- DebugStub.Assert(IoResult.Success == result);
- return true;
- }
-
- [NoHeapAllocation]
- public override void PutChar(char c)
- {
- PutChar((byte)c);
- }
-
- [NoHeapAllocation]
- public void PutChar(byte c)
- {
- if (screenBuffer == null) {
- return;
- }
-
- if (c == (byte)'\b') {
- cursor--;
- }
- else if (c == (byte)'\r') {
- int left = Columns - (cursor % Columns);
-
- cursor -= cursor % Columns;
- }
- else if (c == (byte)'\n') {
- cursor += Columns - (cursor % Columns);
- }
- else {
- IoResult result =
- screenBuffer.Write16NoThrow(cursor++ * 2,
- (ushort)(color | (c & 0x7f)));
- DebugStub.Assert(IoResult.Success == result);
- }
-
- if (cursor >= ScreenSize) {
- IoResult result;
- // Scroll up 1-line
- result = screenBuffer.Copy8NoThrow(Columns * 2, 0,
- (ScreenSize - Columns) * 2);
- DebugStub.Assert(IoResult.Success == result);
- // Blank bottom line
- result =
- screenBuffer.Write16NoThrow((ScreenSize - Columns) * 2,
- (ushort)(color | ' '),
- Columns);
- DebugStub.Assert(IoResult.Success == result);
- // Reel in cursor
- cursor -= Columns;
- }
-
- UpdateCursor(cursorVisible);
- }
-
- [NoHeapAllocation]
- public override void Write(byte[] buffer, int offset, int count)
- {
- for (int i = 0; i < count; i++) {
- PutChar(buffer[offset + i]);
- }
- }
-
- private void WriteLine(String value)
- {
- for (int i = 0; i < value.Length; i++) {
- PutChar((byte)value[i]);
- }
- PutChar((byte)'\r');
- PutChar((byte)'\n');
- }
- }
- } // namespace Microsoft.Singularity.Hal