XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
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));
        }
    }
}