namespace XFESystem.NativeKernel;
public static unsafe class Serial
{
const ushort Port = 0x3f8;
const uint PollLimit = 100000;
public static bool Present;
public static ulong DroppedBytes;
public static void Initialize()
{
Present = false;
byte old = Native.In8(Port + 7);
Native.Out8(Port + 7, 0x5a);
bool detected = Native.In8(Port + 7) == 0x5a;
Native.Out8(Port + 7, old);
if (!detected) return;
Native.Out8(Port + 1, 0);
Native.Out8(Port + 3, 0x80);
Native.Out8(Port, 1);
Native.Out8(Port + 1, 0);
Native.Out8(Port + 3, 3);
Native.Out8(Port + 2, 0xc7);
Native.Out8(Port + 4, 0x0b);
Present = true;
}
public static void Byte(byte value)
{
if (!Present) return;
for (uint i = 0; i < PollLimit; i++)
{
if ((Native.In8(Port + 5) & 0x20) != 0) { Native.Out8(Port, value); return; }
Native.Pause();
}
DroppedBytes++;
// A disappeared or stalled UART must never block the kernel.
Present = false;
}
public static void Write(string value)
{
fixed (char* text = value)
for (int i = 0; i < value.Length; i++)
{
char ch = text[i];
if (ch == '\n') Byte(13);
Byte(ch < 128 ? (byte)ch : (byte)'?');
}
}
public static void Line(string value) { Write(value); Byte(13); Byte(10); }
public static void Number(ulong value)
{
byte* digits = stackalloc byte[20];
uint count = 0;
do { digits[count++] = (byte)('0' + value % 10); value /= 10; } while (value != 0);
while (count != 0) Byte(digits[--count]);
}
public static void Hex(ulong value)
{
Write("0x");
for (int shift = 60; shift >= 0; shift -= 4)
{
byte digit = (byte)((value >> shift) & 15);
Byte((byte)(digit < 10 ? '0' + digit : 'a' + digit - 10));
}
}
}
namespace XFESystem.NativeKernel;
public static unsafe class Serial
{
const ushort Port = 0x3f8;
const uint PollLimit = 100000;
public static bool Present;
public static ulong DroppedBytes;
public static void Initialize()
{
Present = false;
byte old = Native.In8(Port + 7);
Native.Out8(Port + 7, 0x5a);
bool detected = Native.In8(Port + 7) == 0x5a;
Native.Out8(Port + 7, old);
if (!detected) return;
Native.Out8(Port + 1, 0);
Native.Out8(Port + 3, 0x80);
Native.Out8(Port, 1);
Native.Out8(Port + 1, 0);
Native.Out8(Port + 3, 3);
Native.Out8(Port + 2, 0xc7);
Native.Out8(Port + 4, 0x0b);
Present = true;
}
public static void Byte(byte value)
{
if (!Present) return;
for (uint i = 0; i < PollLimit; i++)
{
if ((Native.In8(Port + 5) & 0x20) != 0) { Native.Out8(Port, value); return; }
Native.Pause();
}
DroppedBytes++;
// A disappeared or stalled UART must never block the kernel.
Present = false;
}
public static void Write(string value)
{
fixed (char* text = value)
for (int i = 0; i < value.Length; i++)
{
char ch = text[i];
if (ch == '\n') Byte(13);
Byte(ch < 128 ? (byte)ch : (byte)'?');
}
}
public static void Line(string value) { Write(value); Byte(13); Byte(10); }
public static void Number(ulong value)
{
byte* digits = stackalloc byte[20];
uint count = 0;
do { digits[count++] = (byte)('0' + value % 10); value /= 10; } while (value != 0);
while (count != 0) Byte(digits[--count]);
}
public static void Hex(ulong value)
{
Write("0x");
for (int shift = 60; shift >= 0; shift -= 4)
{
byte digit = (byte)((value >> shift) & 15);
Byte((byte)(digit < 10 ? '0' + digit : 'a' + digit - 10));
}
}
}