у DOS адрес флага занятости
if (sx[0]!='y') WAITDISK=-1;
printf("Синхронизация BIOS(y/n):"); scanf("%s",sx);
if (sx[0]!='y') WAITBIOS=-1;
SP+=NSTACK-10; //Вычисляем значение указателя внутреннего стека.
DS=SS=_DS; //Запоминаем значения сегментных регистров.
SIZE=(DS-_CS+0x10)+((unsigned)(malloc(200)) >> 4);
//Вычисляем размер резидента
printf("Объем резидента %d KB\n\r",SIZE >> 6);
rg.x.ax=0x5100; //Получить у DOS адрес PSP программы
intdos(&rg,&rg);
PSP=rg.x.bx;
rg.x.ax=0x3400; //Спросить у DOS адрес флага занятости DOS,
intdos(&rg,&rg); //который лежит в сегменте DOS.
DOSSEG=_ES; //Попутно запомнить адрес этого сегмента
DOSBUSY=rg.x.bx; //и адрес этого флага
PDOSBUSY=(char far*)MK_FP(DOSSEG,DOSBUSY);
//Собрать far указатели на флаг занятости DOS,
PSPADR=(unsigned far*)MK_FP(DOSSEG,0);
// и свой собственный PSP
while(1) //В этом цикле находим в сегменте DOS адрес
{ // идентификатора процесса (проще говоря,
// где DOS хранит адрес PSP текущего процесса).
if (*PSPADR==PSP)
{
rg.x.ax=0x5000;
rg.x.bx=PSP+1;
intdos(&rg,&rg);
i=(*PSPADR==(PSP+1));
rg.x.ax=0x5000;
rg.x.bx=PSP;
intdos(&rg,&rg);
if(i) break;
}
PSPADR++;
}
DTA=getdta(); //Читаем и запоминаем адрес своего DTA
KBSAV=getvect(0x9); //Переустанавливаем вектор прерывания
setvect(0x9,(void interrupt (far*)(...))KB);
TIMSAV=getvect(0x1C);
setvect(0x1C,(void interrupt (far*)(...))TIMER);
DOSOKSAV=getvect(0x28);
setvect(0x28,(void interrupt (far*)(...))DOSOK );
DISKSAV=getvect(0x13);
setvect(0x13,(void interrupt (far*)(...))BIOSDISK);
b=(unsigned far*)MK_FP(_psp,0x2C);
_ES=*b; //Освободить в памяти ENVIROMENT.
_AH=0x49;
geninterrupt(0x21);
keep(0,SIZE); // Выйти и остаться резидентным.
fatal: printf("Не хватает памяти\n");
} // А если были ошибки, то резидентным не оставаться
Содержание Назад Вперед
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий