#include<iostream.h>
#include<string.h>
#include<dos.h>
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
#include<malloc.h>

void Draw_Board();
void ForeGround();

void Read_Process(int ch);
void Write_Memory(int ch, int c);
void Read_cache(int ch);
int mem;
char string[5], value_string[5];
int a[10][10];
void action();
void Draw_Table();
void Input_Data();

void main()
{
    clrscr();
    int gd = DETECT, gm, ch;
    int i, r, j;
    int rw;

    initgraph(&gd, &gm, "..//bgi");

    ForeGround();
    Input_Data();
    cleardevice();
    Draw_Table();
    Draw_Board();

    getch();
}

void Input_Data()
{
    int i, j;
    cleardevice();

    cout << "Enter The Value Into the Main Memmroy";
    cin >> mem;

    for (i = 1; i <= 7; i++) {
        cout << endl
             << "\nTime:- " << i;
        for (j = 1; j <= 3; j++) {

            cout << endl
                 << "Enter Read[1] and Write[2] And 0 for None ";
            cin >> a[i][j];
        }
    }
}

void ForeGround()
{
    int i;
    setcolor(3);
    for (i = 0; i < 3; i++) {
        rectangle(0 + i, 0 + i, 640 - i, 480 - i);
    }

    for (i = 0; i < 200; i++) {
        setcolor(0);
        rectangle(215 - i, 215 - i, 425 + i, 265 + i);
    }
    setcolor(11);
    settextstyle(4, 0, 7);
    int l, m;

    outtextxy(60, 140, "Cache Coherence's");
    outtextxy(170, 190, "Problem");
    setcolor(14);
    settextstyle(5, 0, 4);
    //settextstyle(4,0,7);
    outtextxy(140, 290, "Developed by:- Darshan L.M ");
    outtextxy(110, 330, "Email:-darshan .malathesh@gmail.com ");
    settextstyle(2, 0, 6);
    outtextxy(110, 380, "I'st Sem Mtech");
    outtextxy(110, 410, "S.I.T College Tumkur");

    int y;
    while (!kbhit()) {

        i = random(700);
        y = random(700);
        delay(5);

        putpixel(y, i, i);
    }

    cleardevice();
    for (i = 0; i < 215; i++) {
        setcolor(i);
        rectangle(0 + i, 0 + i, 640 - i, 480 - i);
    }

    getch();

    for (i = 0; i < 200; i++) {
        setcolor(0);
        rectangle(215 - i, 215 - i, 425 + i, 265 + i);
    }
    getch();
    cleardevice();

    setcolor(3);
    for (i = 0; i < 3; i++) {
        rectangle(0 + i, 0 + i, 640 - i, 480 - i);
    }
}

void Draw_Board()
{
    int width, i;
    setcolor(3);
    for (i = 0; i < 3; i++) {
        rectangle(0 + i, 0 + i, 640 - i, 480 - i);
    }

    setcolor(11);
    /* DRAWS THE LINE FROM CACHE TO BUS*/

    line(90, 150, 90, 90);
    line(185, 150, 185, 90);
    line(300, 150, 300, 90);

    setcolor(2);
    rectangle(150, 20, 220, 60);
    settextstyle(5, 0, 2);
    setcolor(14);
    outtextxy(235, 15, "Main Memory");
    setcolor(2);

    line(185, 60, 185, 90);

    //       line(50,90,330,90);
    setfillstyle(SOLID_FILL, 6);
    bar3d(50, 90, 330, 90, 1, 1);

    setcolor(14);

    rectangle(50, 150, 130, 200);

    circle(100, 250, 15);

    settextstyle(4, 0, 4);
    setcolor(4);
    outtextxy(90, 270, "P1");
    setcolor(14);

    rectangle(150, 150, 230, 200);

    line(200, 235, 200, 200);
    circle(200, 250, 15);
    setcolor(4);

    outtextxy(190, 270, "P2");
    setcolor(14);
    line(100, 235, 100, 200); /*DRAWS THE LINE FROM PROCESS TO CACHE */

    rectangle(250, 150, 330, 200);

    line(300, 235, 300, 200);
    circle(300, 250, 15);
    setcolor(4);
    outtextxy(290, 270, "P3");
    settextstyle(5, 0, 2);
    setcolor(14);
    outtextxy(340, 150, "Cache's");
    setcolor(14);

    settextstyle(5, 0, 4);
    outtextxy(50, 420, "Status: -");

    itoa(mem, value_string, 10);
    strcpy(string, " ");
    strncat(string, value_string, 5);
    settextstyle(4, 0, 2);
    setcolor(14);
    outtextxy(160, 30, string);

    getch();
    action();
}

void action()
{
    // getch();

    /*THE BELOW CODES ACCESS THE MAIN MEMMROY WHICH IMPLEMENTED USING PUTPIXEL FACILITY */
    int write = 0, i;

    for (i = 1; i <= 7; i++) {
        for (int j = 1; j <= 3; j++) {
            if (a[i][j] == 1) {
                if (write != 0) {
                    Read_cache(j);
                    settextstyle(5, 0, 4);
                    outtextxy(250, 420, "Cache Coherence Problem");
                }
                else {
                    Read_Process(j);
                }
            }
            else if (a[i][j] == 2) {
                getch();
                write = 1;
                Write_Memory(j, i);
            }
        }
    }

    /* THE BELOW BLOCK CODE DEALS WITH SNOOPY COHERENCE */

    /*

      for(i=1;i<=7;i++)
	{
	for(int j=1;j<=3;j++)
		{
		 if(a[i][j]==1)
			{
			 if(write!=0)
				{
				Read_cache(j);
				settextstyle(5,0,4);
				outtextxy(250,420,"Cache Coherence Problem");

				}
			 else
				{
				Read_Process(j);
				}

			 }
		 else if(a[i][j]==2)
			{
			getch();
			write=1;
			Write_Memory(j,i);


			}
		 }
	}








  */

} /* END OF FUNCTION*/

void Read_Process(int ch)
{
    int i = 150;
    if (ch == 1) /* THIS BLOCK OF CODE IS HELPFUL IN ACESS THE MAIN MEMMORY BY	THE PROCESS 1*/
    {
        while (i != 90) {
            putpixel(90, i, 6);
            putpixel(89, i, 6);
            i--;
            delay(5);
        }
        while (i != 185) {
            putpixel(i, 90, 6);
            putpixel(i, 89, 6);
            i++;
            delay(5);
        }
        i = 90;

        while (i != 60) {
            putpixel(185, i, 6);
            putpixel(184, i, 6);
            i--;
            delay(5);
        }

        outtextxy(60, 160, string);
    } //END OF IF

    if (ch == 2) { /* THIS BLOCK OF CODE IS HELPFUL IN ACESS THE MAIN MEMMORY BY	THE PROCESS 2	*/
        int i = 150;
        while (i != 90) {
            putpixel(185, i, 9);
            putpixel(184, i, 9);
            i--;
            delay(5);
        }
        i = 90;
        while (i != 60) {
            putpixel(185, i, 9);
            putpixel(184, i, 9);
            i--;
            delay(5);
        }

        outtextxy(155, 160, string);
    }

    if (ch == 3) /* THIS BLOCK OF CODE IS HELPFUL    IN ACESS THE MAIN MEMMORY BY THE PROCESS 3				*/
    {
        int i = 150;
        while (i != 90) {
            putpixel(300, i, 3);
            putpixel(299, i, 3);
            i--;
            delay(5);
        }
        i = 300;

        while (i != 185) {
            putpixel(i, 90, 3);
            putpixel(i, 89, 3);
            i--;
            delay(5);
        }
        i = 90;
        while (i != 60) {
            putpixel(185, i, 3);
            putpixel(184, i, 3);
            i--;
            delay(5);
        }

        outtextxy(265, 160, string);
    }

} /* END OF THE FUNCTION*/

void Read_cache(int ch)
{
    int i = 235;
    if (ch == 1) {
        while (i != 200) {
            putpixel(100, i, 15);
            putpixel(99, i, 15);
            i--;
            delay(15);
        }
    }

    if (ch == 2) { /* THIS BLOCK OF CODE IS HELPFUL IN ACESS THE MAIN MEMMORY BY	THE PROCESS 2	*/
        int i = 235;
        while (i != 200) {
            putpixel(200, i, 15);
            putpixel(199, i, 15);
            i--;
            delay(15);
        }
    }
    if (ch == 3) /* THIS BLOCK OF CODE IS HELPFUL    IN ACESS THE MAIN MEMMORY BY THE PROCESS 3				*/
    {
        int i = 235;
        while (i != 200) {
            putpixel(300, i, 15);
            putpixel(299, i, 15);
            i--;
            delay(15);
        }
    }
}

void Write_Memory(int ch, int c)
{
    int i = 150;
    int poly[8];
    if (ch == 1) {
        poly[0] = 50;
        poly[1] = 150;
        poly[2] = 130;
        poly[3] = 150;
        poly[4] = 130;
        poly[5] = 200;
        poly[6] = 50;
        poly[7] = 200;

        while (i != 90) {
            putpixel(90, i, 5 + c);
            putpixel(89, i, 5 + c);
            i--;
            delay(10);
        }
        while (i != 185) {
            putpixel(i, 90, 5 + c);
            putpixel(i, 89, 5 + c);
            i++;
            delay(10);
        }
        i = 90;

        while (i != 60) {
            putpixel(185, i, 5 + c);
            putpixel(184, i, 5 + c);
            i--;
            delay(10);
        }

        setfillstyle(1, 0 + c);
        fillpoly(4, poly);

        mem = mem + 200;

        itoa(mem, value_string, 10);
        strcpy(string, " ");
        strncat(string, value_string, 5);
        settextstyle(4, 0, 2);
        setcolor(14);
        outtextxy(60, 160, string);

        poly[0] = 150;
        poly[1] = 20;
        poly[2] = 220;
        poly[3] = 20;
        poly[4] = 220;
        poly[5] = 60;
        poly[6] = 150;
        poly[7] = 60;
        setfillstyle(1, 0 + c);
        fillpoly(4, poly);

        outtextxy(160, 30, string);
    }

    if (ch == 2) {
        poly[0] = 150;
        poly[1] = 150;
        poly[2] = 230;
        poly[3] = 150;
        poly[4] = 230;
        poly[5] = 200;
        poly[6] = 150;
        poly[7] = 200;

        int i = 150;
        while (i != 90) {
            putpixel(185, i, 9 + c);
            putpixel(184, i, 9 + c);
            i--;
            delay(15);
        }
        i = 90;
        while (i != 60) {
            putpixel(185, i, 9 + c);
            putpixel(184, i, 9 + c);
            i--;
            delay(15);
        }

        setfillstyle(1, 0 + c);
        fillpoly(4, poly);

        mem = mem + 50;

        itoa(mem, value_string, 10);
        strcpy(string, " ");
        strncat(string, value_string, 5);
        settextstyle(4, 0, 2);
        setcolor(14);
        outtextxy(155, 160, string); /* CACHE BLOCK OF P2*/

        poly[0] = 150;
        poly[1] = 20;
        poly[2] = 220;
        poly[3] = 20;
        poly[4] = 220;
        poly[5] = 60;
        poly[6] = 150;
        poly[7] = 60;
        setfillstyle(1, 0 + c);
        fillpoly(4, poly);

        outtextxy(160, 30, string); /*MAIN MEMEORY BLOCK*/
    }
    if (ch == 3) {

        int i = 150;

        poly[0] = 250;
        poly[1] = 150;
        poly[2] = 330;
        poly[3] = 150;
        poly[4] = 330;
        poly[5] = 200;
        poly[6] = 250;
        poly[7] = 200;

        while (i != 90) {
            putpixel(300, i, 8 + c);
            putpixel(299, i, 8 + c);
            i--;
            delay(15);
        }
        i = 300;

        while (i != 185) {
            putpixel(i, 90, 8 + c);
            putpixel(i, 89, 8 + c);
            i--;
            delay(15);
        }
        i = 90;
        while (i != 60) {
            putpixel(185, i, 8 + c);
            putpixel(184, i, 8 + c);
            i--;
            delay(15);
        }

        setfillstyle(1, 0 + c);
        fillpoly(4, poly);

        mem = mem + 50;

        itoa(mem, value_string, 10);
        strcpy(string, " ");
        strncat(string, value_string, 5);
        settextstyle(4, 0, 2);
        setcolor(14);
        outtextxy(265, 160, string); /*CACHE BLOCK P3*/

        poly[0] = 150;
        poly[1] = 20;
        poly[2] = 220;
        poly[3] = 20;
        poly[4] = 220;
        poly[5] = 60;
        poly[6] = 150;
        poly[7] = 60;
        setfillstyle(1, 0 + c);
        fillpoly(4, poly);

        outtextxy(160, 30, string); /*MAIN MEMEORY BLOCK*/
    }
}

void Draw_Table()
{
    char tstring[5], table_string[5];
    setcolor(9);
    line(450, 50, 649, 50); /* DRAWS THE HORIZONTAL LINE*/
    line(480, 35, 480, 300); /*DRAWS THE VERTICAL LINE*/
    settextstyle(5, 0, 1);
    setcolor(14);
    outtextxy(490, 25, "P1");
    outtextxy(540, 25, "P2");
    outtextxy(590, 25, "P3");
    int j = 10;
    for (int i = 10; i <= 70; i = i + 10) {

        itoa(i / 10, table_string, 10);
        strcpy(tstring, " ");
        strncat(tstring, table_string, 5);
        settextstyle(4, 0, 2);
        setcolor(14);
        settextstyle(3, 0, 1);
        outtextxy(460, 50 + j, tstring);
        j = j + 30;
    }
    setcolor(12);
    for (i = 1; i <= 7; i++) {
        for (j = 1; j <= 3; j++) {
            if (a[i][j] == 1) {
                outtextxy(440 + j * 50, 30 + i * 30, "R");
            }
            else if (a[i][j] == 2) {
                outtextxy(440 + j * 50, 30 + i * 30, "W");
            }
            else {
                outtextxy(440 + j * 50, 30 + i * 30, "-");
            }
        }

    } /*  END OF OUTER FOR LOOP*/
}