Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#15| Dragon God
Demon's Souls |#14| Flamelurker
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Стивенс Ал. Весь текст 495.21 Kb

Техника программирования на турбо-С

Предыдущая страница Следующая страница
1 ... 35 36 37 38 39 40 41  42 43

char notefile[64];

/*--------------------------------*/
int  resident(char *,void interrupt(*)());
void resinit(void);
void terminate(void);
void restart(void);
void wait(void);
void resident_psp(void);
void interrupted_psp(void);
void exec(void);
void cursor(int,int);
void curr_cursor(int *,int *);

main(argc,argv)
char *argv[];
{
  void interrupt ifunc();
  int ivec;

  if((ivec = resident(signature, ifunc)) != 0) {
    if(argc > 1) {
       rg.x.ax = 0;
       if(strcmp(argv[1],"quit") == 0)
          rg.x.ax = 1;
       else if(strcmp(argv[1],"restart") == 0)
          rg.x.ax = 2;
       else if(strcmp(argv[1],"wait") == 0)
          rg.x.ax = 3;
       if(rg.x.ax)  {
          int86(ivec, &rg, &rg);
          return;
      }
   }
   printf("\n Popup is already resident");
 }
 else   {

   /*load_help("tcprogs.hlp");
   getcwd(notefile, 64);
   if(*(notefile+strlen(notefile)-1) != '\\')
     strcat(notefile,"\\");
   strcat(notefile,"note.pad"); */

   printf("\nResident popup is loaded");
   resinit();
 }
}

/*--------------------------------*/
void interrupt ifunc(bp,di,si,ds,es,dx,cx,bx,ax)
{
   if(ax == 1)       /* quit */
     terminate();
   else if(ax == 2)  /* restart */
     restart();
   else if(ax == 3)  /* wait */
     wait();
}

/*--------------------------------*/
/*void closefiles()
{
 extern FILE *helpfp;

  resident_psp();
  if(helpfp)
    fclose(helpfp);
  interrupted_psp();
} */

/*--------------------------------*/
void popup()
{
  int x,y;

  curr_cursor(&x, &y);
  exec();
  cursor(x,y);
}

/*--------------------------------*/
void cursor(int x, int y)
{
  rg.x.ax=0x0200;
  rg.x.bx=0;
  rg.x.dx=((y<<8) &0xff00) + x;
  int86(16,&rg,&rg);
}
/*--------------------------------*/
void curr_cursor(int *x, int *y)
{
  rg.x.ax=0x0300;
  rg.x.bx=0;
  int86(16,&rg,&rg);
  *x=rg.h.dl;
  *y=rg.h.dh;
}

     Листинг 12.4.
     -------------

/*---- resident.c ----*/

#include 
#include 

static union REGS rg;
static struct SREGS seg;
static unsigned mcbseg;
static unsigned dosseg;
static unsigned dosbusy;
static unsigned enddos;
char far *intdta;
static unsigned intsp;
static unsigned intss;
static char far *mydta;
static unsigned myss;
static unsigned stack;
static unsigned ctrl_break;
static unsigned mypsp;
static unsigned intpsp;
static unsigned pids[2];
static int pidctr = 0;
static int pp;
static void interrupt (*oldtimer)();
static void interrupt (*old28)();
static void interrupt (*oldkb)();
static void interrupt (*olddisk)();
static void interrupt (*oldcrit)();
static void interrupt (*ZeroDivVector)();
void interrupt newtimer();
void interrupt new28();
void interrupt newkb();
void interrupt newdisk();
void interrupt newcrit();
extern unsigned sizeprogram;
extern unsigned scancode;
extern unsigned keymask;
static int resoff = 0;
static int running = 0;
static int popflg = 0;
static int diskflag = 0;
static int kbval;
static int cflag;

void dores(),pidaddr();
/*------------------------------------------------*/
void resinit()
{
  segread(&seg);
  myss=seg.ss;

  rg.h.ah=0x34;
  intdos(&rg, &rg);
  dosseg = _ES;
  dosbusy=rg.x.bx;

  mydta=getdta();

  pidaddr();

  oldtimer=getvect(0x1c);
  old28=getvect(0x28);
  oldkb=getvect(9);
  olddisk=getvect(0x13);

  setvect(0x1c,newtimer);
  setvect(0x9,newkb);
  setvect(0x28,new28);
  setvect(0x13,newdisk);

  stack=(sizeprogram - (seg.ds - seg.cs)) * 16 - 300;

  setvect(0,ZeroDivVector);

  rg.x.ax=0x3100;
  rg.x.dx=sizeprogram;
  intdos(&rg, &rg);
}

/*------------------------------------------------*/
void interrupt newdisk(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flgs)
{
  diskflag++;
  (*olddisk)();
  ax=_AX;
  cx=_CX;
  dx=_DX;
  newcrit();
  flgs=cflag;
  --diskflag;
}

/*------------------------------------------------*/
void interrupt newcrit(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flgs)
{
  ax=0;
  cflag=flgs;
}

/*------------------------------------------------*/
void interrupt newkb()
{
  if(inportb(0x60) == scancode) {
    kbval=peekb(0,0x417);
    if(!resoff && ((kbval & keymask) & keymask) == 0) { /* !!!!!!! & *
/
      kbval=inportb(0x61);
      outportb(0x61,kbval|0x80);
      outportb(0x61,kbval);
      outportb(0x20,0x20);
      if(!running)
        popflg=1;
      return;
   }
 }
 (*oldkb)();
 }

/*------------------------------------------------*/
void interrupt newtimer()
{
  (*oldtimer)();
  if(popflg && peekb(dosseg, dosbusy) == 0)
    if(diskflag == 0) {
      outportb(0x20,0x20);
      popflg=0;
      dores();
    }
}

/*------------------------------------------------*/
void interrupt new28()
{
  (*old28)();
  if(popflg && peekb(dosseg, dosbusy) != 0) {
      popflg=0;
      dores();
    }
}

/*------------------------------------------------*/
resident_psp()
{
  intpsp=peek(dosseg,*pids);
  for(pp=0; pp < pidctr; pp++)
    poke(dosseg,pids[pp],mypsp);
}

/*------------------------------------------------*/
interrupted_psp()
{
  for(pp=0; pp < pidctr; pp++)
    poke(dosseg,pids[pp],intpsp);
}
/*------------------------------------------------*/
void dores()
{
  running=1;
  disable();
  intsp=_SP;
  intss=_SS;
  _SP=stack;
  _SS=myss;
  enable();
  oldcrit = getvect(0x24);
  setvect(0x24,newcrit);
  rg.x.ax=0x3300;
  intdos(&rg, &rg);
  ctrl_break=rg.h.dl;
  rg.x.ax=0x3301;
  rg.h.dl=0;
  intdos(&rg, &rg);
  intdta=getdta();
  setdta(mydta);
  resident_psp();
  popup();
  interrupted_psp();
  setdta(intdta);
  setvect(0x24,oldcrit);
  rg.x.ax=0x3301;
  rg.h.dl=ctrl_break;
  intdos(&rg, &rg);

  disable();
  _SP=intsp;
  _SS=intss;
  enable();
  running=0;
}

/*------------------------------------------------*/
static int avec=0;
unsigned resident(signature, ifunc)
char *signature;
void interrupt (*ifunc)();
{
   char *sg;
   unsigned df;
   int vec;

   segread(&seg);
   df=seg.ds - seg.cs;
   for(vec=0x60; vec < 0x68; vec++) {
      if(getvect(vec) == NULL)  {
        if(!avec)
          avec=vec;
        continue;
      }
      for(sg=signature; *sg; sg++)
        if(*sg!=peekb(peek(0,2+vec*4)+df,(unsigned)sg))
           break;
        if(!*sg)
           return vec;
   }
   if(avec)
      setvect(avec, ifunc);
   return 0;
}

/*------------------------------------------------*/
static void pidaddr()
{
   unsigned adr=0;

   rg.h.ah=0x51;
   intdos(&rg, &rg);
   mypsp=rg.x.bx;

   rg.h.ah=0x52;
   intdos(&rg, &rg);
   enddos=_ES;
   enddos = peek(enddos, rg.x.bx-2);
   while(pidctr < 2 &&
       (unsigned)((dosseg<<4) + adr) < (enddos<<4)) {
    if(peek(dosseg, adr) == mypsp)  {
       rg.h.ah=0x50;
       rg.x.bx=mypsp+1;
       intdos(&rg, &rg);
       if(peek(dosseg, adr) == mypsp +1)
         pids[pidctr++]=adr;
       rg.h.ah=0x50;
       rg.x.bx=mypsp;
       intdos(&rg, &rg);
    }
    adr++;
  }
}

/*------------------------------------------------*/
static resterm()
{
 /* closefiles();*/

  setvect(0x1c,oldtimer);
  setvect(9,oldkb);
  setvect(0x28,old28);
  setvect(0x13,olddisk);
  setvect(avec, (void interrupt (*)()) 0);

  rg.h.ah=0x52;
  intdos(&rg, &rg);
  mcbseg=_ES;
  mcbseg=peek(mcbseg, rg.x.bx-2);

  segread(&seg);
  while(peek(mcbseg, 0) == 0x4d)  {
       if(peek(mcbseg, 1) == mypsp) {
         rg.h.ah=0x49;
         seg.es=mcbseg+1;
         intdosx(&rg, &rg, &seg);
       }
       mcbseg+=peek(mcbseg,3)+1;
  }
}

/*------------------------------------------------*/
terminate()
{
  if(getvect(0x13) == (void interrupt (*)()) newdisk)
    if(getvect(9) == newkb)
       if(getvect(0x28) == new28)
          if(getvect(0x1c) == newtimer) {
             resterm();
             return;
          }
  resoff=1;
}


/*------------------------------------------------*/
restart()
{
  resoff=0;
}
/*------------------------------------------------*/
wait()
{
  resoff=1;
}

          TSR-ПРОГРАММА - ПРИЛОЖЕНИЕ.
-----------------------------------------------------------------

     В popup.c   функция   popup   вызывается,   когда  программа
TSR-драйвера обнаруживает,  что нажата клавиша "горячего ключа" и
выполнение утилиты  безопасно  для  ДОС._  .Функция popup сохраняет
текущее положение курсора,  вызывает exec,  затем восстанавливает
курсор и завершает выполнение._ .Функция exec - это вход в утилиту,
в данном случае программа-пример из  главы  10._  .Дополнительно  к
тому,  что  вы узнали о exec ранее,  обратите внимание еще вот на
что.  Она работает точно так же как и нерезидентная menu.exe,  но
сейчас ее  имя  popup.exe,  и  она  является  TSR-программой.  На
листинге 12.5 дан файл проекта для построения popup.exe  в  Турбо
_Си..

     Листинг 12.5:popup.prj.

popup (twindow.h)
exec (twindow.h,keys.h)
tetstmove (twindow.h,keys.h)
promote (twindow.h,keys.h)
ccolor (twindow.h,keys.h)
fasttest (twindow.h)
notepad (twindow.h)
ordent (twindow.h)
maxims (twindow.h,keys.h)
poems (twindow.h,keys.h)
editor (twindow.h,keys.h)
entry (twindow.h,keys.h)
thelp (twindow.h,keys.h)
tmenu (twindow.h,keys.h)
twindow (twindow.h,keys.h)
resident
ibmpc.obj

     Чтобы запустить резидентную утилиту, построенную Турбо Си по
этому проекту, введите следующую команду:

C>popup

     Эта команда загрузит TSR-программу и оставит  ее  в  памяти.
При этом она выдаст сообщение:

Resident popup is loaded.

     При попытке повторного запуска будет выдано сообщение:

Popup is already resident.

     Когда программа   резидентна,  вы  можете  выполнять  ее  из
командной строки  для  того,  чтобы   приостановить,   продолжить
выполнение или снять ее. Это делается следующими командами:

C>popup wait
C>popup restart
C>popup quit


          ПРОВЕРКА TSR-ПРОГРАММ.
-----------------------------------------------------------------

     Если вы написали TSR-программу и  хотите  проверить  ее  как
резидентную программу,  ваши опыты могут разочаровать вас. Прежде
всего у вас  не  будет  возможности  использовать  Турбо  Си  для
интерактивного тестирования.   TSR-программа  устанавливается  из
командной строки и вызывается по нажатию клавиши.  Далее,  до тех
пор,  пока не заработает функция terminate,  вам придется удалять
ее путем перезагрузки.  То же придется делать при загрузке других
резидентных программ   после   нее.   Так   как   ваша  программа
присоединяется к прерываниям,  то ее выполнение может подвешивать
вашу  систему.  Так  что  TSR-программу  нелегко  отлаживать  как
резидентную.

     Лучшее решение   -   это   отлаживать   TSR-программу    как
нерезидентную. Все интерфейсы с ДОС,  необходимые для установки и
действия TSR-программы,  находятся в popup.c и resident.c. Почему
бы  не  пропустить  эти  операции до тех пор,  пока вы надежно не
протестируете вашу программу?  Как вы видите  из  примера,  часть
программы,   выполняющая   основные   функции,   была  создана  и
протестирована отдельно без TSR-операций. По сути дела, эта часть
используется  как  пример некоторых возможностей,  не связанных с
обсуждением TSR-программ.  Вы можете тестировать  свою  программу
таким же способом.

     Простейший путь  тестировать вашу утилиту - это связать ее с
корневой  программой,  обеспечивающей  функцию   main   и   любой
начальный код,  который  вы  потом включите в popup.c.  Программа
menu.c из главы 10 является хорошим примером.

     Другой способ - связать утилиту с popup.c и  resident.c, как
будто бы вы строите резидентную программу, но с одним изменением.
Вместо вызова функции resinit из функции main в  popup.c вставьте
вызовы  popup  и closefile из popup.c.Программа будет иметь те же
вид,  структуру и размер,  что и ее резидентная версия,  но будет
функционировать как нерезидентная программа.
Предыдущая страница Следующая страница
1 ... 35 36 37 38 39 40 41  42 43
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама