#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int n_pages, size_page, n_frames, size_physical_memory, size_logical_memory;
int m, n,i,j;
int p = 0, d = 0;

int find_p(int),find_d(int);


int main()
{
    // Scanning size of Physical memory
    printf("Enter size of physical memory (power of 2)=  ");
    scanf("%d", &size_physical_memory);

    // Scanning the size of page
    // Frame size == Page size
    printf("Enter size of page/frame (power of 2)=  ");
    scanf("%d", &size_page);

    // Scanning number of pages in logical memory
    //printf("Enter no. of pages = ");
  //  scanf("%d", &n_pages);

   // size_logical_memory = size_page * n_pages;
   printf("Enter size of logical memory (power of 2)= ");
   scanf("%d",&size_logical_memory);
    n_pages=size_logical_memory/size_page;

    // Calculating the number of frames in the Physical memory
    n_frames = size_physical_memory / size_page;

    printf("\n\t\t\tLogical-Memory\t\tPhysical-Memory\n");
    printf("No. of Pages/frames\t\t%d\t\t\t%d\n", n_pages, n_frames);
    printf("Page/Frame size\t\t\t%d\t\t\t%d\n", size_page, size_page);
    printf("Size of Memory\t\t\t%d\t\t\t%d\n\n", size_logical_memory, size_physical_memory);

    // Declaring the Pages,Frames and Pagetable
    char pages[n_pages][size_page];
    int pagetable[n_pages];
    char frames[n_frames][size_page];

    n = sqrt(size_page);
    m = sqrt(size_page * n_pages);

    getchar();

    // Scanning Pages data
    printf("Enter details of the data availalbe in Logical Address Space\n");
    for (i = 0; i < n_pages; i++)
    {
        printf(" Enter the page%d data : ", (i));
        for (j = 0; j < size_page; j++)
        {
			pages[i][j] = getchar();
            getchar();
        }
    }

//Data Available in Logical Address
	printf("\nData Available in Logical Address is:\n");
	for (i = 0; i < n_pages; i++)
    {
        printf("\n Page%d: ", (i));
        for (j = 0; j < size_page; j++)
        {
			printf("%c\t",pages[i][j]);
        }
    }


    // Scanning Pagetable data
    printf("\nEnter the details of page table : \n");
for (i = 0; i < n_pages; i++) {
    printf(" Page%d stored in Frame: ", i);
    scanf("%d", &pagetable[i]);
}

	
        // Initializing all the default frames values to '0'
    for (i = 0; i < n_frames; i++){
        for (j = 0; j < size_page; j++)
        {
            frames[i][j] = '-';
        }
    }



    // Placing the data from pages to frams using page table
    for (i = 0; i < n_pages; i++)
    {
        p = i;
        int f = pagetable[p];
        for (j = 0; j < size_page; j++)
        {
            d = j;
            // Initializing Frames using (f,d)
            frames[f][d] = pages[i][j];
        }
    }

    // Displaying the Frames data
    printf("\nAccording to the given Page Table information \nFrames in the Physical Memory are loaded with following data:\n");
    for (i = 0; i < n_frames; i++)
    {
        printf(" \tFrame%d: ",i);
		for (j = 0; j < size_page; j++)
            printf("%c ", frames[i][j]);
        printf("\n");
    }
    printf("\n");

    // Finding the Physical address through Logical address
    printf("Enter any one address of Logical Memory : ");
    int n;
    scanf("%d", &n);
    p = find_p(n);
    d = find_d(n);
    int f = pagetable[p];
    printf(" Calculated Page Number is: %d\n",p);
    printf(" Calculated Displacement is: %d",d);
    printf("\nThe Physical address of %d (given Logical Address) is %d\n", n, (f * size_page) + d);
    printf("Data item \"%c\" of Logical Address %d is found at Physical Address %d i.e., at Frame Number %d with Displacement %d = \"%c\"\n", pages[n/4][n%4], n, (f * size_page) + d, f, d, frames[f][d]);


    
}

int find_p(int n)
{
    int res = n / size_page;
    return res;
}

int find_d(int n)
{
    int res = n % size_page;
    return res;
}