<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cosmos.Core;

namespace Cosmos.HAL {
	/// <summary>
	/// Programmable Interval Timer
	/// with 1,193181818... MHz
	/// </summary>
    public class PIT : Device {
        public class PITTimer : IDisposable {
            internal int NSRemaining;
            public int NanosecondsTimeout;
            public bool Recuring;
            internal int ID = -1;

            public int TimerID {
                get {
                    return ID;
                }
            }

            public delegate void dOnTrigger();
            public dOnTrigger HandleTrigger;

            public PITTimer(dOnTrigger HandleOnTrigger, int NanosecondsTimeout, bool Recuring) {
                this.HandleTrigger = HandleOnTrigger;
                this.NanosecondsTimeout = NanosecondsTimeout;
                this.NSRemaining = this.NanosecondsTimeout;
                this.Recuring = Recuring;
            }

            public PITTimer(dOnTrigger HandleOnTrigger, int NanosecondsTimeout, int NanosecondsLeft) {
                this.HandleTrigger = HandleOnTrigger;
                this.NanosecondsTimeout = NanosecondsTimeout;
                this.NSRemaining = NanosecondsLeft;
                this.Recuring = true;
            }

            ~PITTimer() {
                Dispose();
            }

            public void Dispose() {
                if (ID != -1) {
                    Global.PIT.UnregisterTimer(ID);
                }
            }
        }

        protected Core.IOGroup.PIT IO = Core.Global.BaseIOGroups.PIT;
        private List<PITTimer> ActiveHandlers = new List<PITTimer>();
        private ushort _T0Countdown = 65535;
        private ushort _T2Countdown = 65535;
        private int TimerCounter = 0;
        private bool WaitSignaled = false;
        public const uint PITFrequency = 1193180;
        public const uint PITDelayNS = 838;
        public bool T0RateGen = false;

	    public PIT()
	    {
            INTs.SetIrqHandler(0x00, HandleIRQ);
	        _T0Countdown = 65535;
        }

        public ushort T0Countdown {
            get {
                return _T0Countdown;
            }
            set {
                _T0Countdown = value;

                IO.Command.Byte = (byte)(T0RateGen ? 0x34 : 0x30);
                IO.Data0.Byte = (byte)(value & 0xFF);
                IO.Data0.Byte = (byte)(value >> 8);
            }
        }
        public uint T0Frequency {
            get {
                return (PITFrequency / ((uint)_T0Countdown));
            }
            set {
                if (value < 19 || value > 1193180) {
                    throw new ArgumentException("Frequency must be between 19 and 1193180!");
                }

                T0Countdown = (ushort)(PITFrequency / value);
            }
        }
        public uint T0DelyNS {
            get {
                return (PITDelayNS * _T0Countdown);
            }
            set {
                if (value > 54918330)
                    throw new ArgumentException("Delay must be no greater that 54918330");

                T0Countdown = (ushort)(value / PITDelayNS);
            }
        }

        public ushort T2Countdown {
            get {
                return _T2Countdown;
            }
            set {
                _T2Countdown = value;

                IO.Command.Byte = 0xB6;
                IO.Data0.Byte = (byte)(value & 0xFF);
                IO.Data0.Byte = (byte)(value >> 8);
            }
        }
        public uint T2Frequency {
            get {
                return (PITFrequency / ((uint)_T2Countdown));
            }
            set {
                if (value < 19 || value > 1193180) {
                    throw new ArgumentException("Frequency must be between 19 and 1193180!");
                }

                T2Countdown = (ushort)(PITFrequency / value);
            }
        }
        public uint T2DelyNS {
            get {
                return (PITDelayNS * _T2Countdown);
            }
            set {
                if (value > 54918330)
                    throw new ArgumentException("Delay must be no greater than 54918330");

                T2Countdown = (ushort)(value / PITDelayNS);
            }
        }

        //TODO: Why is sound in PIT? Is it a function of the PIT?
        //Channel 3 is for the pc speaker ^
        public void EnableSound() {
            //IO.Port61.Byte = (byte)(IO.Port61.Byte | 0x03);
        }
        public void DisableSound() {
            //IO.Port61.Byte = (byte)(IO.Port61.Byte | 0xFC);
        }
        public void PlaySound(int aFreq) {
            EnableSound();
            T2Frequency = (uint)aFreq;
        }
        public void MuteSound() {
            DisableSound();
        }

        private void SignalWait() {
            WaitSignaled = true;
        }

        public void Wait(uint TimeoutMS) {
            WaitSignaled = false;

            RegisterTimer(new PITTimer(SignalWait, (int)(TimeoutMS * 1000000), false));

            while (!WaitSignaled) {
                Core.Global.CPU.Halt();
            }
        }

        public void WaitNS(int TimeoutNS) {
            WaitSignaled = false;

            RegisterTimer(new PITTimer(SignalWait, TimeoutNS, false));

            while (!WaitSignaled) {
                Core.Global.CPU.Halt();
            }
        }

	    private void HandleIRQ(ref INTs.IRQContext aContext)
	    {

	        int T0Delay = (int) T0DelyNS;
	        PITTimer hndlr = null;
	        for (int i = ActiveHandlers.Count - 1; i >= 0; i--)
	        {
	            hndlr = ActiveHandlers[i];

	            hndlr.NSRemaining -= T0Delay;

	            if (hndlr.NSRemaining < 1)
	            {
	                if (hndlr.Recuring)
	                {
	                    hndlr.NSRemaining = hndlr.NanosecondsTimeout;
	                }
	                else
	                {
	                    hndlr.ID = -1;<commit_msg>Changes requested by charlesbetros<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cosmos.Core;

namespace Cosmos.HAL {
	/// <summary>
	/// Programmable Interval Timer
	/// with 1,193181818... MHz
	/// </summary>
    public class PIT : Device {
        public class PITTimer : IDisposable {
            internal int NSRemaining;
            public int NanosecondsTimeout;
            public bool Recuring;
            internal int ID = -1;

            public int TimerID {
                get {
                    return ID;
                }
            }

            public delegate void dOnTrigger();
            public dOnTrigger HandleTrigger;

            public PITTimer(dOnTrigger HandleOnTrigger, int NanosecondsTimeout, bool Recuring) {
                this.HandleTrigger = HandleOnTrigger;
                this.NanosecondsTimeout = NanosecondsTimeout;
                this.NSRemaining = this.NanosecondsTimeout;
                this.Recuring = Recuring;
            }

            public PITTimer(dOnTrigger HandleOnTrigger, int NanosecondsTimeout, int NanosecondsLeft) {
                this.HandleTrigger = HandleOnTrigger;
                this.NanosecondsTimeout = NanosecondsTimeout;
                this.NSRemaining = NanosecondsLeft;
                this.Recuring = true;
            }

            ~PITTimer() {
                Dispose();
            }

            public void Dispose() {
                if (ID != -1) {
                    Global.PIT.UnregisterTimer(ID);
                }
            }
        }

        protected Core.IOGroup.PIT IO = Core.Global.BaseIOGroups.PIT;
        private List<PITTimer> ActiveHandlers = new List<PITTimer>();
        private ushort _T0Countdown = 65535;
        private ushort _T2Countdown = 65535;
        private int TimerCounter = 0;
        private bool WaitSignaled = false;
        public const uint PITFrequency = 1193180;
        public const uint PITDelayNS = 838;
        public bool T0RateGen = false;

	    public PIT()
	    {
            INTs.SetIrqHandler(0x00, HandleIRQ);
	        T0Countdown = 65535;
        }

        public ushort T0Countdown {
            get {
                return _T0Countdown;
            }
            set {
                _T0Countdown = value;

                IO.Command.Byte = (byte)(T0RateGen ? 0x34 : 0x30);
                IO.Data0.Byte = (byte)(value & 0xFF);
                IO.Data0.Byte = (byte)(value >> 8);
            }
        }
        public uint T0Frequency {
            get {
                return (PITFrequency / ((uint)_T0Countdown));
            }
            set {
                if (value < 19 || value > 1193180) {
                    throw new ArgumentException("Frequency must be between 19 and 1193180!");
                }

                T0Countdown = (ushort)(PITFrequency / value);
            }
        }
        public uint T0DelyNS {
            get {
                return (PITDelayNS * _T0Countdown);
            }
            set {
                if (value > 54918330)
                    throw new ArgumentException("Delay must be no greater that 54918330");

                T0Countdown = (ushort)(value / PITDelayNS);
            }
        }

        public ushort T2Countdown {
            get {
                return _T2Countdown;
            }
            set {
                _T2Countdown = value;

                IO.Command.Byte = 0xB6;
                IO.Data0.Byte = (byte)(value & 0xFF);
                IO.Data0.Byte = (byte)(value >> 8);
            }
        }
        public uint T2Frequency {
            get {
                return (PITFrequency / ((uint)_T2Countdown));
            }
            set {
                if (value < 19 || value > 1193180) {
                    throw new ArgumentException("Frequency must be between 19 and 1193180!");
                }

                T2Countdown = (ushort)(PITFrequency / value);
            }
        }
        public uint T2DelyNS {
            get {
                return (PITDelayNS * _T2Countdown);
            }
            set {
                if (value > 54918330)
                    throw new ArgumentException("Delay must be no greater than 54918330");

                T2Countdown = (ushort)(value / PITDelayNS);
            }
        }

        //TODO: Why is sound in PIT? Is it a function of the PIT?
        //Channel 3 is for the pc speaker ^
        public void EnableSound() {
            //IO.Port61.Byte = (byte)(IO.Port61.Byte | 0x03);
        }
        public void DisableSound() {
            //IO.Port61.Byte = (byte)(IO.Port61.Byte | 0xFC);
        }
        public void PlaySound(int aFreq) {
            EnableSound();
            T2Frequency = (uint)aFreq;
        }
        public void MuteSound() {
            DisableSound();
        }

        private void SignalWait() {
            WaitSignaled = true;
        }

        public void Wait(uint TimeoutMS) {
            WaitSignaled = false;

            RegisterTimer(new PITTimer(SignalWait, (int)(TimeoutMS * 1000000), false));

            while (!WaitSignaled) {
                Core.Global.CPU.Halt();
            }
        }

        public void WaitNS(int TimeoutNS) {
            WaitSignaled = false;

            RegisterTimer(new PITTimer(SignalWait, TimeoutNS, false));

            while (!WaitSignaled) {
                Core.Global.CPU.Halt();
            }
        }

	    private void HandleIRQ(ref INTs.IRQContext aContext)
	    {

	        int T0Delay = (int) T0DelyNS;
	        PITTimer hndlr = null;

	        T0Countdown = 65535;

            for (int i = ActiveHandlers.Count - 1; i >= 0; i--)
	        {
	            hndlr = ActiveHandlers[i];

	            hndlr.NSRemaining -= T0Delay;

	            if (hndlr.NSRemaining < 1)
	            {
	                if (hndlr.Recuring)
	                {
	                    hndlr.NSRemaining = hndlr.NanosecondsTimeout;
	                }
	                else
	                {
	                    hndlr.ID = -1;
{'fraction_non_alphanumeric': 0.0857024450891007, 'fraction_numerical': 0.02967260671363448, 'mean_word_length': 1.2753158589477653, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 29, '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': '782384', 'n_tokens_mistral': 3680, 'n_tokens_neox': 3186, 'n_words': 762}