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

#pragma inline

// Modes
#define REALMODE 0
#define VIRTUALMODE 1
#define PROTECTMODE 2
// DPMI functions
#define GETPMEP 0x1687
#define GETCURMODE 0x1686
// Constants
#define MAXSTR 200
#define NUMREGS 12
#define TOBINARY
#define PEBIT 1
#define BIT17 131072
// CheckMode Menu alternatives
#define RAMTOHDD '1'
#define HDDTORAM '2'
#define EXIT '0'
// Main Menu alternatives
#define CHECKMODE '1'
#define SWITCHMODE '2'
#define SHOWCR0 '3'
// Exit statuses
#define ERROR -1
#define SUCCESS 0

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

unsigned int regStorage[NUMREGS];

char * fileName = "tempFile";

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

int initDPMI(void);
int getCurMode();
int checkMode();
void switchMode();
void switchModeToReal();
void switchModeToProtected();
void saveRegs();
void exitToDOS(unsigned);

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

	clrscr();

	if (initDPMI() == ERROR){
	  printf("Error dpmi init\n");
	  getch();
	  return ERROR;
	}

	saveRegs();

	asm start label word

	do{
	  clrscr();
	  mode = getCurMode();
	  printf("ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ\n");
	  if (mode == PROTECTMODE) {
		  printf("ЭCurrent mode: protected   Ю\n");
	  }

	  if (mode == VIRTUALMODE) {
		  printf("ЭCurrent mode: virtual     Ю\n");
	  }

	  if (mode == REALMODE){
		  printf("ЭCurrent mode: 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 & PEBIT));
			getch();
			break;
		 case EXIT:
			break;
		 default:
			break;
	  }
	} while (action != '0');

	exitToDOS(0);
	return SUCCESS;
}


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

}

int initDPMI(void){
	inRegs.x.ax = GETPMEP;
	int86x(0x2F, &inRegs, &outRegs, &segRegs);
	if(outRegs.x.ax != 0){
		printf("Error DPMI");
		return ERROR;
	}

	DPMIFlags = outRegs.x.bx;
	hostDataSize = outRegs.x.si;

	FP_SEG(protectedModeEP) = segRegs.es;
	FP_OFF(protectedModeEP) = outRegs.x.di;

	if(hostDataSize){
		if(_dos_allocmem(hostDataSize, &hostDataSeg) != 0){
			printf("Error allocmem");
			return ERROR;
		}
	}
                
	return SUCCESS;
}

int getCurMode(){
  int curMode = PROTECTMODE;

  long flags;
  long isVirtualMode;

  asm{
	  mov ax,GETCURMODE
	  int 2fh
	  mov curMode,ax
  }

  if (curMode == 0){
	 curMode = PROTECTMODE;
  } else {
	 asm{
		 pushfd
		 pop ebx
		 mov flags, ebx
	 }
	 isVirtualMode = flags & BIT17;
	 if (TOBINARY(isVirtualMode)){
		curMode = VIRTUALMODE;
	 } else{
		curMode = REALMODE;
	 }
  }

  return curMode;
}

void switchMode(){
  if (getCurMode() == REALMODE){
	  switchModeToProtected();
  } else if (getCurMode() == VIRTUALMODE){
	 switchModeToProtected();
  } else if (getCurMode() == PROTECTMODE){
	 switchModeToReal();
  }
}

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

  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 switchModeToProtected(){
  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[MAXSTR];
  char stringToRead[MAXSTR];
  FILE * file;

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

  mode = getCurMode();
  do{
	  clrscr();
	  printf("ЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬ\n");
	  if (mode == PROTECTMODE){
		  printf("ЭIt's Protected mode, MilordЮ\n");
	  }

	  if (mode == REALMODE){
		  printf("ЭIt's Real mode, Milord     Ю\n");
	  }

	  if (mode == VIRTUALMODE){
		  printf("ЭIt's Virtual mode, Milord  Ю\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 ERROR;
			}

			printf("Enter a string, Milord:\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 ERROR;
			}
			printf("Read from HDD to RAM... \n");
			nItemsRead = fread(stringToRead, sizeof(char), MAXSTR, file);
			stringToRead[nItemsRead] = '\0';
			if (nItemsRead > 0){
				printf("%d items had read successfully: (%s)\n", nItemsRead, stringToRead);
			} else{
			  printf("We have read empty string, Milord\n");
			}
			getch();
			break;
		case EXIT:
			break;
		default :
			break;
	 }

  } while (action != EXIT);

  return SUCCESS;
}