<commit_before>using System;
using System.Collections.Generic;
using System.Text;
using Cosmos.Core.Memory.Old;
using Cosmos.HAL.BlockDevice.Registers;

namespace Cosmos.HAL.BlockDevice.Ports
{
    public class Satapi : StoragePort
    {
        public Debug.Kernel.Debugger mSATAPIDebugger = new Debug.Kernel.Debugger("HAL", "SATAPI");

        public PortRegisters mPortReg;

        public override PortType mPortType => PortType.SATAPI;
        public override string mPortName => "SATAPI";
        public override uint mPortNumber => mPortReg.mPortNumber;

        public Satapi(PortRegisters aSATAPIPort)
        {

            // Check if it is really a SATAPI Port!
            if (aSATAPIPort.mPortType != PortType.SATAPI || (aSATAPIPort.CMD & (1U << 24)) == 0)
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.Write("\n[Error]");
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($" 0:{aSATAPIPort.mPortNumber} is not a SATAPI port!");
                return;
            }
            mSATAPIDebugger.Send("SATAPI Constructor");

            mPortReg = aSATAPIPort;

            mBlockSize = 2048;
        }

        public void SendSATAPICommand(ATACommands aCommand, uint aStart, uint aCount)
        {
            mPortReg.IS = unchecked((uint)-1);

            int xSlot = FindCMDSlot(mPortReg);
            if (xSlot == -1) return;

            HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot);
            xCMDHeader.CFL = 5;
            xCMDHeader.ATAPI = 1;
            xCMDHeader.PRDTL = 0;
            xCMDHeader.Write = 0;
            xCMDHeader.ClearBusy = 1;

            xCMDHeader.CTBA = Heap.MemAlloc(256) + (uint)(256 * xSlot);

            HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, (uint)xSlot);

            FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS)
            {
                FISType = (byte)FISType.FIS_Type_RegisterH2D,
                IsCommand = 1,
                Command = (byte)ATACommands.Packet,
                Device = 0
            };

            byte[] xATAPICMD = new byte[12];
            xATAPICMD[0] = (byte)aCommand;
            xATAPICMD[2] = (byte)((aStart >> 0x18) & 0xFF);
            xATAPICMD[3] = (byte)((aStart >> 0x10) & 0xFF);
            xATAPICMD[4] = (byte)((aStart >> 0x08) & 0xFF);
            xATAPICMD[5] = (byte)((aStart >> 0x00) & 0xFF);
            xATAPICMD[9] = (byte)(aCount);
            for (uint i = 0; i < xATAPICMD.Length; i++)
            new Core.MemoryBlock(xCMDTable.ACMD, 12).Bytes[i] = xATAPICMD[i];
            
            int xSpin = 0;
            do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSpin < 1000000);

            if (xSpin == 1000000)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("\n[Error]: ");
                Console.Write("Port timed out!");
                Console.ResetColor();
                return;
            };

            mPortReg.CI = 1U;

            while(true)
            {
                if((mPortReg.CI & (1 << xSlot)) == 0)
                {
                    break;
                }
                if ((mPortReg.IS & (1 << 30)) != 0)
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.Write("\n[Fatal]: ");
                    Console.Write("Fatal error occurred while sending command!");
                    Console.ResetColor();
                    return;
                }
            }

            if ((mPortReg.IS & (1 << 30)) != 0)
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.Write("\n[Fatal]: ");
                Console.Write("Fatal error occurred while sending command!");
                Console.ResetColor();
                return;
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write("\n[Success]: ");
            Console.Write("Command has been sent successfully!");
            Console.ResetColor();

            return;
        }

        public int FindCMDSlot(PortRegisters aPort)
        {
            // If not set in SACT and CI, the slot is free
            var xSlots = (aPort.SACT | aPort.CI);

            for (int i = 1; i < 32; i++)
            {
                if ((xSlots & 1) == 0)
                    return i;
                xSlots >>= 1;
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("\n[Error]: ");
            Console.Write("Cannot find a free command slot!");
            Console.ResetColor();
            return -1;
        }

        public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData)
        {
            SendSATAPICommand(ATACommands.Read, (uint)aBlockNo, (uint)aBlockCount);
        }

        public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData)
        {

        }
    }<commit_msg>[AHCI] First working AHCI Controller<commit_after>using System;
using System.Collections.Generic;
using System.Text;
using Cosmos.Core.Memory.Old;
using Cosmos.HAL.BlockDevice.Registers;
using Cosmos.Core;

namespace Cosmos.HAL.BlockDevice.Ports
{
    public class SATAPI : StoragePort
    {
        public Debug.Kernel.Debugger mSATAPIDebugger = new Debug.Kernel.Debugger("HAL", "SATAPI");

        public PortRegisters mPortReg;

        public override PortType mPortType => PortType.SATAPI;
        public override string mPortName => "SATAPI";
        public override uint mPortNumber => mPortReg.mPortNumber;

        public SATAPI(PortRegisters aSATAPIPort)
        {

            // Check if it is really a SATAPI Port!
            if (aSATAPIPort.mPortType != PortType.SATAPI || (aSATAPIPort.CMD & (1U << 24)) == 0)
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.Write("\n[Error]");
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($" 0:{aSATAPIPort.mPortNumber} is not a SATAPI port!");
                return;
            }
            mSATAPIDebugger.Send("SATAPI Constructor");

            mPortReg = aSATAPIPort;

            mBlockSize = 2048;
        }

        public void SendSATAPICommand(ATACommands aCommand, uint aStart, uint aCount)
        {
            mPortReg.IS = unchecked((uint)-1);

            int xSlot = FindCMDSlot(mPortReg);
            if (xSlot == -1) return;

            HBACommandHeader xCMDHeader = new HBACommandHeader(mPortReg.CLB, (uint)xSlot);
            xCMDHeader.CFL = 5;
            xCMDHeader.ATAPI = 1;
            xCMDHeader.PRDTL = (ushort)(((aCount - 1) >> 4) + 1);
            xCMDHeader.Write = 0;

            xCMDHeader.CTBA = Heap.MemAlloc(128 + ((uint)xCMDHeader.PRDTL) * 16);

            HBACommandTable xCMDTable = new HBACommandTable(xCMDHeader.CTBA, xCMDHeader.PRDTL);

            uint DataBaseAddress = 0x0046C000;
            for (int i = 0; i < xCMDHeader.PRDTL - 1; i++)
            {
                xCMDTable.PRDTEntry[i].DBA = DataBaseAddress;
                xCMDTable.PRDTEntry[i].DBC = 8 * 1024 - 1;   // 8K bytes (this value should always be set to 1 less than the actual value)
                xCMDTable.PRDTEntry[i].InterruptOnCompletion = 1;
                DataBaseAddress += 8 * 1024;    // 4K words
                aCount -= 16;    // 16 sectors
            }

            // Last entry
            xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBA = DataBaseAddress;
            xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].DBC = aCount * 512 - 1;   // 8K bytes (this value should always be set to 1 less than the actual value)
            xCMDTable.PRDTEntry[xCMDHeader.PRDTL - 1].InterruptOnCompletion = 1;

            FISRegisterH2D xCMDFIS = new FISRegisterH2D(xCMDTable.CFIS)
            {
                FISType = (byte)FISType.FIS_Type_RegisterH2D,
                IsCommand = 1,
                Command = (byte)ATACommands.Packet,
                Device = 1 << 4
            };

            byte[] xATAPICMD = new byte[12];
            xATAPICMD[0] = (byte)aCommand;
            xATAPICMD[2] = (byte)((aStart >> 0x18) & 0xFF);
            xATAPICMD[3] = (byte)((aStart >> 0x10) & 0xFF);
            xATAPICMD[4] = (byte)((aStart >> 0x08) & 0xFF);
            xATAPICMD[5] = (byte)((aStart >> 0x00) & 0xFF);
            xATAPICMD[9] = (byte)(aCount);
            for (uint i = 0; i < xATAPICMD.Length; i++)
            new Core.MemoryBlock(xCMDTable.ACMD, 12).Bytes[i] = xATAPICMD[i];
            
            int xSpin = 0;
            do xSpin++; while ((mPortReg.TFD & 0x88) != 0 && xSpin < 1000000);

            if (xSpin == 1000000)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("\n[Error]: ");
                Console.Write("Port timed out!");
                Console.ResetColor();
                return;
            };

            mPortReg.CI = 1U;

            while(true)
            {
                if((mPortReg.CI & (1 << xSlot)) == 0)
                {
                    break;
                }
                if ((mPortReg.IS & (1 << 30)) != 0)
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.Write("\n[Fatal]: ");
                    Console.Write("Fatal error occurred while sending command!");
                    Console.ResetColor();
                    return;
                }
            }

            if ((mPortReg.IS & (1 << 30)) != 0)
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.Write("\n[Fatal]: ");
                Console.Write("Fatal error occurred while sending command!");
                Console.ResetColor();
                return;
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write("\n[Success]: ");
            Console.Write("Command has been sent successfully!");
            Console.ResetColor();

            return;
        }

        public int FindCMDSlot(PortRegisters aPort)
        {
            // If not set in SACT and CI, the slot is free
            var xSlots = (aPort.SACT | aPort.CI);

            for (int i = 1; i < 32; i++)
            {
                if ((xSlots & 1) == 0)
                    return i;
                xSlots >>= 1;
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("\n[Error]: ");
            Console.Write("Cannot find a free command slot!");
            Console.ResetColor();
            return -1;
        }

        public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData)
        {
            SendSATAPICommand(ATACommands.Read, (uint)aBlockNo, (uint)aBlockCount);
            byte[] xByte = new byte[512];
            new MemoryBlock(0x0046C000, 512).Read8(xByte);
            for (int i = 0; i < 512; i++)
            {
                Console.Write(xByte[i]);
            }
        }

        public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData)
        {

        }
    }
{'fraction_non_alphanumeric': 0.11155555555555556, 'fraction_numerical': 0.02142222222222222, 'mean_word_length': 1.5605370960400546, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6605472', 'n_tokens_mistral': 3549, 'n_tokens_neox': 3278, 'n_words': 702}