/// <summary>
        /// Converts the virtual address into a physical address, then returns the address.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns>Returns the physical address</returns>
        public string Read(int address)
        {
            var virtualAddress = new VirtualAddress(address);

            if (tlb != null)
            {
                var pa = DoesEntryExist(virtualAddress);
                if (pa != -1)
                {
                    return("h " + pa);
                }
            }

            var pageTable = GetPageTable(virtualAddress.segment);

            if (pageTable == -1 || pageTable == 0)
            {
                return(pageTable.ToString());
            }

            var page = GetPage(pageTable + virtualAddress.page);

            if (page == -1 || page == 0)
            {
                return(page.ToString());
            }

            if (tlb != null)
            {
                InsertEntry(virtualAddress);
            }

            return(tlb != null ? "m " + (page + virtualAddress.word) : (page + virtualAddress.word).ToString());
        }
        /// <summary>
        /// Converts the virtual address into a phsyical address. If the segment table's value is
        /// 0, then create a new page table. Consequently this will then have 0 for the page table,
        /// and a new page needs to be created.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns>Returns the physical address</returns>
        public string Write(int address)
        {
            var virtualAddress = new VirtualAddress(address);

            if (tlb != null)
            {
                var pa = DoesEntryExist(virtualAddress);
                if (pa != -1)
                {
                    return("h " + pa);
                }
            }

            var pageTable = GetPageTable(virtualAddress.segment);

            if (pageTable == -1)
            {
                return(pageTable.ToString());
            }

            // Create page table
            if (pageTable == 0)
            {
                var frame = GetFreePageTable();
                EmptyFrame(frame);
                pageTable = frame * FrameSize;
                SetSegmentToPageTable(virtualAddress.segment, pageTable);
            }

            var page = GetPage(pageTable + virtualAddress.page);

            if (page == -1)
            {
                return(page.ToString());
            }

            // Create page
            if (page == 0)
            {
                var frame = GetFreeFrame();
                EmptyFrame(frame);
                page = frame * FrameSize;
                SetPageToPageTable(pageTable + virtualAddress.page, page);
            }

            if (tlb != null)
            {
                InsertEntry(virtualAddress);
            }

            return(tlb != null ? "m " + (page + virtualAddress.word) : (page + virtualAddress.word).ToString());
        }
 /// <summary>
 /// Inserts the tlb entry if it does not exist. If the entry exists, return
 /// the frame number of the entry. Otherwise, return -1;
 /// </summary>
 /// <param name="page">The page.</param>
 /// <param name="frame">The frame.</param>
 /// <returns></returns>
 private void InsertEntry(VirtualAddress va)
 {
     // Entry was not found, so replace the least recently used entry
     foreach (var entry in tlb)
     {
         if (entry.priority == 0)
         {
             entry.priority = 3;
             entry.sp       = va.sp;
             entry.f        = physicalMemory[physicalMemory[va.segment] + va.page];
         }
         else
         {
             entry.priority -= 1;
         }
     }
 }
        private int DoesEntryExist(VirtualAddress va)
        {
            // search TLB for entry, then update it's priority and return PA
            for (var i = 0; i < tlb.Count; i++)
            {
                if (tlb[i].sp == va.sp)
                {
                    foreach (var entry in tlb)
                    {
                        if (entry.priority > tlb[i].priority)
                        {
                            entry.priority -= 1;
                        }
                    }

                    tlb[i].priority = 3;
                    return(tlb[i].f + va.word);
                }
            }

            return(-1);
        }