Скачиваний:
35
Добавлен:
15.09.2014
Размер:
6.89 Кб
Скачать
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <stdarg.h>
#include <STRING.H>

#pragma inline

#define REALMODE 0
#define VIRTUALMODE 1
#define PROTECTEDMODE 2

#define RAMTOHDD '1'
#define HDDTORAM '2'
#define EXIT '0'

#define CHECKMODE '1'
#define SWITCHMODE '2'
#define SHOWCR0 '3'

union REGS inRegs;
union REGS outRegs;
struct SREGS segRegs;
unsigned hostDataSeg;
unsigned hostDataSize;
unsigned DPMIFlags;

unsigned int regStorage[12];

char *fileName = "tempFile.txt";

void (far *realModeEP)();
void (far *protectedModeEP)();

int initDPMI(void);
int getCurMode();
int checkMode();
void switchMode();
void switchToReal();
void switchToProtected();
void saveRegs();
void exitToDOS(unsigned);

int main()
{
	int mode;
	char action;
	int _CR0;

	clrscr();

	if(initDPMI() == -1)//для работы в защищ режим
	{
		printf("Error dpmi init\n");
		getch();
		return -1;
	}
	saveRegs();

	//
	do
	{
		clrscr();
		mode = getCurMode();
		printf("\n");
		if(mode == PROTECTEDMODE)
			printf("Mode is: protected\n");
		if(mode == VIRTUALMODE)
			printf("Mode is: virtual\n");
		if(mode == REALMODE)
			printf("Mode is: real\n");

		printf("\n");
		printf("\n");
		printf("[1] Check mode      \n");
		printf("[2] Switch mode     \n");
		printf("[3] Show cr0        \n");
		printf("[0] Exit            \n");
		printf("\n");
		action = getch();
		switch(action)
		{
			case CHECKMODE:
					checkMode();
					break;
			case SWITCHMODE:
					switchMode();
					break;
			case SHOWCR0:
					asm{
						cli
						mov eax,cr0
						mov _CR0,eax
						sti
					}
					printf("CR0: %d",(_CR0 & 1));
					getch();
					break;
			case EXIT:
				break;
			default:
				break;
		}
	}while(action != '0');
	exitToDOS(0);
	return 0;
}

void exitToDOS(unsigned err)
{
	asm{
		mov ax, err
		mov ah, 04ch
		int 21h
	}
}

int initDPMI(void)
{
	inRegs.x.ax = 0x1687;
	int86x(0x2F, &inRegs, &outRegs, &segRegs); 
	if(outRegs.x.ax != 0)
	{
		printf("Error DPMI");
		return -1;
	}
	DPMIFlags = outRegs.x.bx;    //бит 0 = 1, если поддерживаются 32-битные программы, 0 — если нет
	hostDataSize = outRegs.x.si; //SI = размер временной области данных, требуемой для переключения в 16-байтных параграфах

	// Определяем адрес точки входа в защищённый режим
	FP_SEG(protectedModeEP) = segRegs.es;     // ES:DI = адрес процедуры переключения в защищенный режим
	FP_OFF(protectedModeEP) = outRegs.x.di;   //

	if(hostDataSize)
	{
		if(_dos_allocmem(hostDataSize, &hostDataSeg) != 0) //память для сервера DPMI
		{
			printf("Error allocmem");
			return -1;
		}
	}
	return 0;
}

int getCurMode()
{
	int curMode = PROTECTEDMODE;
	long flags;
	long isVirtualMode;

	asm{
		mov ax,0x1686  //
		int 2fh   ///в ах текущий режим курмод
		mov curMode,ax
	}

	if(curMode == 0)
		curMode = PROTECTEDMODE;
	else
	{
		asm{
			pushfd //в стек регистор ефлагс
			pop ebx //извлекаем
			mov flags, ebx //помещ его в переменн
		}
		isVirtualMode = flags & 131072; //10000000000000000   един это наш показатель  -1 и 17 нулей
		if(isVirtualMode == 131072)
			curMode = VIRTUALMODE;
		else
			curMode = REALMODE;
	}
	return curMode;
}

void switchMode()
{
	if(getCurMode() == REALMODE)
		switchToProtected();
	else if(getCurMode() == VIRTUALMODE)
		switchToProtected();
	else if(getCurMode() == PROTECTEDMODE)
		switchToReal();
}

void switchToReal()
{
	unsigned int selector;
	unsigned int off;

//SI:DI        Адрес программы для переключения из защищённого режима 
//в реальный в формате <селектор:смещение>
	asm{
		mov ax,0306h  
		int 31h
		mov selector, si
		mov off, di
	}

	(void far*)realModeEP = MK_FP(selector, off);

	asm{
		mov ax,word ptr regStorage[0]
		mov cx,word ptr regStorage[2]
		mov dx,word ptr regStorage[4]
		mov bx,word ptr regStorage[6]
		mov si,word ptr regStorage[8]
		mov di,word ptr regStorage[10]
	}

	(*realModeEP)();
}

void switchToProtected()
{
	asm{
		mov ax, hostDataSeg
		mov es, ax
		mov ax, DPMIFlags
	}

	(*protectedModeEP)();
}

void saveRegs()
{
	asm{
		push ax
		mov ax, ds
		mov word ptr regStorage[0], ax
		mov ax, es
		mov word ptr regStorage[2], ax
		mov ax, ss
		mov word ptr regStorage[4], ax
		mov ax, sp
		mov word ptr regStorage[6], ax
		mov ax, cs
		mov word ptr regStorage[8], ax
		push dx
		lea dx, start
		mov word ptr regStorage[10], dx
		pop dx
		pop ax
	}
}

int checkMode()
{
	char action;
	int mode;
	int nItemsWrite;
	int nItemsRead;
	char stringToWrite[200];
	char stringToRead[200];
	FILE * file;

	stringToWrite[0] = stringToRead[0] = '\0';

	int i;
	int _CR0;
	long flags;
	int CR0[32];
	int EFLAGS[32];
	mode = getCurMode();
	do
	{
		clrscr();
		asm{
			mov eax,cr0
			mov _CR0,eax
			pushfd
			pop ebx
			mov flags, ebx
		}
		printf("CR0:\n");
		for(i = 31; i >= 0; i--)
		{
			//printf("%d", (_CR0 & 1));
			CR0[i] = (_CR0 & 1);
			_CR0 = _CR0 >> 1;
		}
		for(i = 0; i < 32; i++)
			printf("%d", CR0[i]);
		printf("\nEFLAGS:\n");
		for(i = 31; i >= 0; i--)
		{
			//printf("%d", (flags & 1));
			EFLAGS[i] = (flags & 1);
			flags = flags >> 1;
		}
		for(i = 0; i < 32; i++)
			printf("%d", EFLAGS[i]);
		printf("\n");
		if(mode == PROTECTEDMODE)
			printf("It's Protected mode\n");
		if(mode == REALMODE)
			printf("It's Real mode\n");
		if(mode == VIRTUALMODE)
			printf("It's Virtual mode\n");
		printf("\n");
		printf("\n");
		printf("Write from...             \n");
		printf("\n");
		printf("\n");
		printf(" 1 - RAM to HDD           \n");
		printf(" 2 - HDD to RAM           \n");
		printf(" 0 - Or Exit to menu      \n");
		printf("\n");

		fflush(stdin);
		action = getch();
		switch (action)
		{
			case RAMTOHDD:
				if((file = fopen(fileName, "w")) == NULL)
				{
					printf("Error open file\n");
					return -1;
				}
				printf("Enter a string:\n");
				fflush(stdin);
				scanf("%s", stringToWrite);
				printf("Write from RAM to HDD... \n");
				nItemsWrite = fwrite(stringToWrite, sizeof(char), strlen(stringToWrite), file);
				fclose(file);
				printf("%d items had written succesfully\n", nItemsWrite);
				getch();
				break;
			case HDDTORAM:
				if((file = fopen(fileName, "r")) == NULL)
				{
					printf("Error open file\n");
					return -1;
				}
				printf("Read from HDD to RAM... \n");
				nItemsRead = fread(stringToRead, sizeof(char), 200, file);
				stringToRead[nItemsRead] = '\0';
				if(nItemsRead > 0)
					printf("%d items had read successfully: (%s)\n", nItemsRead, stringToRead);
				else
					printf("We have read empty string\n");
				getch();
				break;
			case EXIT:
				break;
			default:
				break;
		}

	}while(action != EXIT);
	return 0;
}