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

#pragma inline

#define REALMODE 0
#define VIRTUALMODE 1
#define PROTECTMODE 2
#define MAXSTR 200

union REGS inregs, outregs;
struct SREGS segregs;
unsigned hostdata_seg, hostdata_size, dpmi_flags;

unsigned int sRegs[12];
//int CR0;

char * fname = "output.txt";

void (far *realEPoint)();
void (far *protectEPoint)();//adres vhoda v zaschischenui rejim

int initialDPMI(void);
int test_mode();
void try_mode();
void switch_mode();
void to_real();
void to_protected();
void save_regs();
void dos_exit(unsigned);

void main()
{
	int mode;
	char c;

	clrscr();

	if (initialDPMI() == -1)
	{
	  printf("Error dpmi init\n");
	  getch();
	  return 0;
	}

	save_regs();

	asm begn label word

	do
	{
	  //clrscr();

	  int cc = 0;
	  asm {
	    cli
	    mov eax, cr0
	    mov cc, eax
	    sti
	  }
	  cc = cc & 1;
	  clrscr();
	  printf ("CR0 : %d  ",!!cc);

	  mode = test_mode();

	  if (mode == PROTECTMODE)
	  {
	    printf("Protected mode!\n\n");
	  }
	  if (mode == VIRTUALMODE)
	  {
	    printf("Virtual mode! \n\n");
	  }
	  if (mode == REALMODE)
	  {
	    printf("Real mode! \n\n");
	  }
	    printf("[1] Test mode\n");
	    printf("[2] Switch mode\n");
	    printf("[0] Exit\n");
	    c = getch();
	  switch (c)
	  {
	    case '1': try_mode();
		      break;
	    case '2': switch_mode();
		 //printf("4");
		 //getch();
		      break;
	    case '0': break;
	    default:  break;
	  }
	  //printf("5");
	  //getch();
	} while (c != '0');

	dos_exit(0);
}


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

int initialDPMI(void)
{
	inregs.x.ax = 0x1687;  //poluchenie adresa procedyru vhoda  v z.rejim
	int86x(0x2F, &inregs, &outregs, &segregs);
	if(outregs.x.ax != 0)
	{
		printf("Error DPMI");
		return (-1);
	}

	dpmi_flags = outregs.x.bx;  //esli 0,to dpmi mojet rabotat' s 32 programmami
	hostdata_size = outregs.x.si;// kol-vo paragrafov pamyati,trebyemoi dlya dpmi

	FP_SEG(protectEPoint) = segregs.es;   //segment vhoda v zasch.rejim
	FP_OFF(protectEPoint) = outregs.x.di; //smeschenie

	if(hostdata_size)
	{
		if(_dos_allocmem(hostdata_size, &hostdata_seg) != 0)
		{
			printf("Error allocmem");
			return (-1);
		}
	}

	return 0;
}

int test_mode()       //opredelenie tekyschego rejima rabotu
{
  int res = PROTECTMODE;

  int pe;
  long flags, vm;

  asm mov ax,1686h //proverka rejima rabotu
  asm int 2fh
  asm mov res,ax

  if (res == 0)
    res = PROTECTMODE;
  else
  {
    asm pushfd   //registr flagov EFLAGS--v stack
    asm pop ebx  //registr flagov v ebx
    asm mov flags, ebx //registr flagov v flags
    vm = flags & 131072;//sravnenie s 2 v 17 stepeni
    printf ("vm : %d  ", !!vm);
    if (!!vm)
    {
      res = VIRTUALMODE;
    }
    else
      res = REALMODE;
  }

  return res;
}

void switch_mode()   //pereklyuchenie rejimov
{
  if (test_mode() == REALMODE)
  {
    to_protected();
  }
  else
  if (test_mode() == VIRTUALMODE)
  {
    to_protected();
  }
  else
  if (test_mode() == PROTECTMODE)
  {
    to_real();
  }
  //printf("3");
  //getch();
}

void to_real()
{
  unsigned int sel, off;

  asm {
    mov ax,0306h   //vozvraschaet adres perehoda v real mode
    int 31h
    mov sel, si
    mov off, di
  }

  realEPoint = MK_FP(sel, off);

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

  (*realEPoint)();
}

void to_protected()
{
  asm {
    mov ax, hostdata_seg
    mov es, ax
    mov ax, dpmi_flags
  }

  (*protectEPoint)();
}

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

void try_mode()
{
  char c;
  int mode;
  int bts, res_bts;
  char string[MAXSTR];
  char res_string[MAXSTR];
  FILE * file;

  string[0] = res_string[0] = '\0';

  printf("-------------------\n");

  mode = test_mode();
  if (mode == PROTECTMODE)
    printf("Protected mode\n");
  if (mode == REALMODE)
    printf("Real mode\n");
  if (mode == VIRTUALMODE)
    printf("Virtual mode\n");

  do
  {
    clrscr();
    printf("[1] RAM -> HDD\n");
    printf("[2] HDD -> RAM\n");
    printf("[0] Exit to menu\n");

    c = getch();

    switch (c)
    {
      case '1':
      {
	if ((file = fopen(fname, "w")) == NULL)
	{
	  printf("Error open file\n");
	  return;
	}

	printf("Enter a string:\n");
	scanf("%s", string);
	printf("RAM -> HDD... \n");
	bts = fwrite(string, sizeof(char), strlen(string), file);
	fclose(file);
	printf("success %d bytes!\n", bts);
	getch();
	break;
      }
      case '2':
      {
	if ((file = fopen(fname, "r")) == NULL)
	{
	  printf("Error open file\n");
	  return;
	}
	printf("HDD -> RAM... \n");
	res_bts = fread(res_string, sizeof(char), MAXSTR, file);
	res_string[res_bts] = '\0';
	if (res_bts > 0)
	{
	  printf("success %d bytes! (%s)\n", res_bts, res_string);
	}
	else
	  printf("empty string\n");

	getch();
	break;
      }
      case '0': break;
      default : break;
    }

  } while (c != '0');

  return;
}