

















                            


                           
                                          
                                  
                                     
                               
                               
                               
                               
                               
                                     
                                  
                                          
                           



                      




















                             , 1989 .


- - -                                                        - - - 


                                - 005 -


               
     -----------------------------------------------------------------

                         ,
       ,    -  !

             .      
            .   ,  
           ,      
      ,   ,      
            .    ,  
         ,  ,  .
             .     
       ,              
       ,         
     ,                 
     .   ,    
                    
            
      .

              ,    
          .  
                 ,     
       .       
       ,              .    
       :

     #        
     #    (popup  pulldown) 
     #    
     #       
     #   
     #  ,   
     #  
     #     

                        ,  
         .      ,   
                  
        .     
            .

                    ANSI,
        ,    .    
            ,  
      .        
     Microsoft .

                          
     ,     .   ,  
     ,     ,        
          ,    
         ,      ,
      .    - 24.95$.     
                    .   
       MasterCard  Visa.
- - -                                                        - - - 

                                - 006 -


                           1.
                          --------
                  .
     -----------------------------------------------------------------

                  
      -      . 
      ,        ,
               .       
     ,    ,           
        .

                    
       .           
     ,            
                     
     /  .      
         ,          BIOS
           IBM.  BIOS-  
        ,       
        .

                              
      ,        , 
         ,     
         .



                    ?
     -----------------------------------------------------------------

                    
               .     
             ,   
     .    ,      
      .       
       .

               ,  
          .    ,  
        .     
             :  (1)     ,
         ,   ,  (2)
                     
              .         
              .         
              , 
        .    
          .   
           -  ,
             -         ,
         .

                     .
                
     .          
     ,   ,        . 
- - -                                                        - - - 

                                - 007 -

               
     .          
            
     . ,     ,
             ,      .  
       "",      
        ,             ,  
       .

                           
       ,        ,   
             , 
             ,
        .

                     ,
     ,            .
                    
      .



                .
     -----------------------------------------------------------------

          - ,          
           ,    
     .     -     ,
     /        (CGA)      
        (EGA).  CGA    EGA      
        ,    40-    80-      
      .               1-1.
       ,        ,   
         80-  ,    
            .   ,
           2,  3   7.    
       -     - 0,0.


      1-1.
     ------------

                                       
     ---------------------------------------------------------------
      0       ,/              40*25            CGA,EGA
      1        16         40*25            CGA,EGA
      2        /              80*25            CGA,EGA
      3        16         80*25            CGA,EGA
      4        4         320*200          CGA,EGA
      5        4     320*200          CGA,EGA
      6        /            640*200          CGA,EGA
      7        /              80*25            
      8        16       160*200          PCjr
      9        16       320*200          PCjr
     10        4  16 .   640*200          PCjr,EGA
     13        16       320*200          EGA
     14        16       640*200          EGA
     15        4         640*350          EGA
     --------------------------------------------------------------
- - -                                                        - - - 

                                - 008 -



          ,      ,         
               .  
       0000000H.  CGA,  EGA  ,
         B80000000H.  (   ,   
              -    
          .)   CGA  EGA  
      ,     2  3.

           ,    ,     
     .      ,   
        .               
      ,      1-2.    EGA
      CGA,      3,   
        7.       ,
         .       
                    
      ,    70H.

                .
      ,    ,    7, 
       (  )   70      .
     ,  1   .



      1-2
     -----------
      

                        
     ----------------------------------------------------------------
           0             1                
           1             2                
           2             4                
           3             8                
           4            16                
           5            32                
           6            64                
           7           128                
     ----------------------------------------------------------------

                 4   ,
              80-  .  
          .  -,        
     , (     ).  -  
                   
           .    
              
      .        
        0,      
      0.              .
     ,       ,  .

                   .   
       ,     
     .   -    BIOS,   ,   
      ,  ,   AT    PS/2  
- - -                                                        - - - 

                                - 009 -

     ,    .    -    
       ,       ,    
        .      
       .    BIOS,    
      .



                   BIOS
     -----------------------------------------------------------------

          - ,            
                ,      
     ,     ,    
     ,          .  
         ,    
            BIOS , 
          .

            ,   BIOS        .
     ,    (    )        
     ,    BIOS,     IBM,    
         .        ,  
                IBM   PC      100%
              ,        
     . ,       
         ,    100%
        IBM PC.   ,  
     BIOS    ,    
     .



                int86()
     -----------------------------------------------------------------

           BIOS     .  BIOS 
          .      
          .   16 (10),
          . (    
       BIOS,         ":
      ",  , 1987).     BIOS,
         16         ,      
           AH.      
     ,          AL.  ,   
          . 
          BIOS     
     int86(). (      
     ,      MicroSoft  C            int86().
          ,    
       .

          int86()   :

      int int86(num,inregs,outregs)
      int num; /*   */
      union REGS *inregs; /*    */
      union REGS *outregs; /*    */
- - -                                                        - - - 

                                - 010 -


          int86()      .    REGS
        DOS.H.     ,  
        , ,     MisroSoft
     C    .

     struct WORDREGS {
      unsigned int ax, bx, cx, dx, si, di, cflag, flags;
     };
     struct BYTEREGS {
     unsigned char al, ah, bl, bh, cl, ch, dl, dh;
     };
     union REGS {
     struct WORDREGS x;
     struct BYTEREGS h;
     };

             ,  REGS -    .
       WORDREGS   
       16- .  BYTREGS        8-
      .  ,     16, 
     5,     .

     union REGS in,out;

     in.h.ah=5;
     int86(16,&in,&out);



                 .
     -----------------------------------------------------------------

             ,      
          .   
          ,    
     16,    8,            
          .         
         ,        
     .        ,
           .            
     goto_xy()   .     16,
       2        DL     DH.
             (      0   
     ).

     /*    x,y */
     void goto_xy(x,y)
     int x,y;
     {
      union REGS r;

      r.h.ah=2; /*    */
      r.h.dl=y; /*         */
      r.h.dh=x; /*          */
      r.h.bh=0; /*             */
      int86(0x10,&r,&r);
     }
- - -                                                        - - - 

                                - 011 -


           16,    8         
          AL     AH.   save_video(),
      ,    ,   
     ,     .

     /*    */
     void save_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      union REGS r;
      register int i,j;

      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
          goto_xy(j,i);
          r.h.ah=8; /*      */
          r.h.bh=0; /*             */
          *buf_ptr++ = int86(0x10,&r,&r);
          putchar(' '); /*   */
        }
     }

   save_video   
          .   
buf_ptr        ,  
.      ,  
 ,   .

       ,   
      ,          
.    , ,    ,
  ,          .   
    ,     .



                
     -----------------------------------------------------------------

                      ,
           
        .   ,    ,  
      16,  9,  ,     AL,
       BL,     ,      
         CX  (      1).   restore_video(),
       ,        ,    
       buf_ptr,    ,      
      X  Y.

     /*    */
     void restore_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      union REGS r;
      register int i,j;

- - -                                                        - - - 

                                - 012 -

      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
          goto_xy(j,i);
          r.h.ah=9; /*      */
          r.h.bh=0; /*             */
          r.x.cx=1; /*    */
          r.h.al=*buf_ptr++; /*           */
          r.h.bl=*buf_ptr++; /*          */
          *buf_ptr++ = int86(0x10,&r,&r);
        }
     }



                 
     -----------------------------------------------------------------

          ,     ,     
      .  -,    
     .         ,  
            -    
           .  
     ,              
                   
     ,     .  ,   ,
         ""      ,    
       .         -    ,
        ""     ,  
      .

           popup()        ,
             .      
           ,        X  Y.
     ,          
         ,      - .     
         /.    ,      
       popup()    :

     /*       */
     int popup(menu,keys,count,x,y,border)
     char *menu[];  /*   */
     char *keys;    /*   */
     int count;     /*   */
     int x,y;       /*     */
     int border;    /*  0    */

           popup()   :

     #     
     #  ,  
     #  
     #   
     #     

                         save_video()   
     restore_video(),            .  
         .


- - -                                                        - - - 

                                - 013 -


                .
     -----------------------------------------------------------------

           ,     ,    ,  
     popup           .  
              ,
       .            
       .      display_menu()
        .

     /*      */
     void display_menu(menu,x,y,count)
     char *menu[];
     int x,y,count;
     {
      register int i;

     for(i=0;i<count;i++,x++) {
       goto_xy(x,y);
       printf(menu[i]);
       }
     }

             ,          
       ,      ,     
        .

                     
     ,      -   
       :

     char *< > [] = {
     " ",
     " ",
      .
      .

      .
     "N-   " };

                        
         .     
         .  ,     
      fruit (),    ""  "".

     char *fruit[] = {
      "",
      "",
      "",
      "",
      "",
      ""
     };


- - -                                                        - - - 

                                - 014 -




                
     -----------------------------------------------------------------
            ,      
              
          .    ,
             ,
       IBM.   ,    .

     void draw_border(startx,starty,endx,endy)
     int   startx,starty,endx,endy;
     {
        register int i;
        for(i=startx+1;i<endx;i++) {
          goto_xy(i,starty);
          putchar(179);
          goto_xy(i,endy);
          putchar(179);
        }
        for(i=starty+1;i<endy;i++) {
          goto_xy(startx,i);
          putchar(196);
          goto_xy(endx,i);
          putchar(196);
        }

        goto_xy(startx,starty); putchar(218);
        goto_xy(startx,endy  ); putchar(191);
        goto_xy(endx  ,starty); putchar(192);
        goto_xy(endx  ,endy  ); putchar(217);
     }



                 
     -----------------------------------------------------------------

           ,       
      .  -       
                
     , (      .)
          .  
         ,    .   get_resp(),
      ,   .

     /*    */
     get_resp(x,y,count,menu,keys)
     int x,y,count;
     char *menu[];
     char *keys;
     {
      union inkey {
        char ch[2];
        int i;
      } c;
     int arrow_choice=0,key_choice;

- - -                                                        - - - 

                                - 015 -

     y++;
     /*    */
     goto_xy(x,y);
     write_video(x,y,menu[0],REV_VID);

     for(;;) {
      while(!bioskey(1)); /*   */
      c.i=bioskey(0);

     /*      */
     goto_hy(arrow_choice,y);
     write_video(x+arrow_choice,y,
             menu[arrow_choice],norm_vid);
     if(c.ch[0]) { /*   */
      key_choice= is_in(keys,tlower(c.ch[0]));
     if(key_choice) return key_choice-1;
     switch(c.ch[0]) {
       case '\r' : return arrow_choice;
       case ' '  : arrow_choice++;
                   break;
      case ESC   : return -1; /*  */
        }
     }
     else { /*   */
      switch(c.ch[1]) {
       case 72 : arrow_choice--; /*   */
                 break;
       case 80 : arrow_choice++; /*   */
                 break;

          }
       }
     if(arrow_choice==count) arrow_choice=0;
     if(arrow_choice<0) arrow_choice=count-1;
         /*    */
      goto_xy(x+arrow_choice,y);
      write_video(x+arrow_choice,y,menu[arrow_choice],REV_VID);
      }
     }


          K get_resp()    ,    
      .   REV_VID  ,  
     70,  NORM_VID  7.  ESCAPE   
        .   ESC 27.      
     ,    .      
     bioskey()  ,     ,   
        .  bioskey()   
     .     ,   
       .

     /*    bioskey   */
     bioskey(c)
     int c;
     {
      switch(c) {
       case 0: return get_key();
       case 1: return kbhit();
       }
     }
- - -                                                        - - - 

                                - 016 -


     /*  16     */
     get_key()
     {
      union REGS r;

      r.h.ah=0;
      return int86(0x16, &r,&r);

          ,       bioskey() 
     getchar()   ,       
         16      ,    
     .     ,     
       8  ,     8   0.  ,   
      ,  ,  ,    0, 
           .     
          72  80 .  ,
        getchar(),          ,    
           .

                   
      ,   - .  
     ,             ,  
           .      ,     
              
     .

           write_video()    get_resp()  
            ,Y   .
     Write_video(),   ,     
          ,    ,    ,
        .

     /*      */
     void write_video(x,y,p,attrib)
     int x,y;
     char *p;
     int attrib;
     {
      union REGS r;
      register int i,j;

      for(i=y; *p; i++) {
       goto_xy(x,i);
          r.h.ah=9; /*      */
          r.h.bh=0; /*             */
          r.x.cx=1; /*    */
          r.h.al=*p++; /*           */
          r.h.bl=attrib; /*          */
          int86(0x10,&r,&r);
       }

           is_in()      ""     
     .         ,   is_in
      0.

     is_in(s,c)
     char *s,c;
     {
      register int i;
- - -                                                        - - - 

                                - 017 -


      for(i=0; *s; i++)
         if(*s++ == c) return i+1;
      return 0;
     }



                popup()
     -----------------------------------------------------------------

          ,     ,   popup  
     ,    .

     /*      
         -2,      
         -1,     ESC
              
        ,   0 */
     int popup(menu,keys,count,x,y,border)
     char *menu[];  /*   */
     char *keys;    /*   */
     int count;     /*   */
     int x,y;       /*     */
     int border;    /*  0    */
     {
      register int i,len;
      int endx endy choice;
      unsigned int *p;

      if((x>24)||(x<0)||(y>79)||(y<0)) {
       printf("    ");
       return -2;
      }
     /*   */
     len=0;
     for(i=0;i<count;i++)
      if(strlen(menu[i]) > len) len=strlen(menu[i]);
     endy=len+2+y;
     endx=count+1+x;
     if((endx+1>24) || (endy+1>79)) {
       printf("    ");
       return -2;
      }
     /*      */
     p=(unsigned int *)malloc((endx-x+1)*(endy-y+1));
      if(!p) exit(1); /*       */

     /*    */
     void save_video(startx,endx,starty,endy,p);

     if(border) draw_border(x,y,endx,endy);

     /*      */
     void display_menu(menu,x,y,count);

     /*    */
     choice=get_resp(x,y,count,menu,keys)

- - -                                                        - - - 

                                - 018 -

     /*    */
     void restore_video(startx,endx,starty,endy,p);
     free(p);
     return choice;
     }

               ,  popup()     
          .      -2,  
             .  -  ,   get_resp()
      -1,        ESC,      
         popup    ""
     .     ,     
         0  count-1    
      0.     ,  popup()    
            
      .       ,        
      ,      .



                
     -----------------------------------------------------------------

           ,      ,       
     ,     .  
        cls(),      .  
           ,     ,  
           (  ).

     /*         */
     #include "stdio.h"
     #include "dos.h"
     #include "stdlib.h"

     #define BORDER 1
     #define ESC 27
     #define REV_VID 0x70
     #define NORM_VID  7

     void save_video(),restore_video();
     void goto_xy(),cls(),write_video();
     void display_menu(),draw_border();

     char *fruit[] = {
      "",
      "",
      "",
      "",
      "",
      ""
     };

     char *color[]={
      "",
      "",
      "",
      ""
     };

- - -                                                        - - - 

                                - 019 -

     char *apple_type[] = {
      " ",
      "",
      " ",
      ""
     };

     main()
     {
      int i;

     cls();
     goto_xy(0,0);
     for(i=0;i<25;i++)
      printf("   \n");
     popup(fruit,"",6,1,3,BORDER);
     popup(color,"",4,5,10,BORDER);
     popup(apple_type,"",4,10,18,BORDER);
     }

     /*      
         -2,      
         -1,     ESC
              
        ,   0 */
     int popup(menu,keys,count,x,y,border)
     char *menu[];  /*   */
     char *keys;    /*   */
     int count;     /*   */
     int x,y;       /*     */
     int border;    /*  0    */
     {
      register int i,len;
      int endx endy choice;
      unsigned char *p;

      if((x>24)||(x<0)||(y>79)||(y<0)) {
       printf("    ");
       return -2;
      }
     /*   */
     len=0;
     for(i=0;i<count;i++)
      if(strlen(menu[i]) > len) len=strlen(menu[i]);
     endy=len+2+y;
     endx=count+1+x;
     if((endx+1>24) || (endy+1>79)) {
       printf("    ");
       return -2;
      }
     /*      */
     p=(unsigned int *)malloc((endx-x+1)*(endy-y+1));
      if(!p) exit(1); /*       */

     /*    */
     void save_video(x,endx+1,y,endy+1,p);

     if(border) draw_border(x,y,endx,endy);

- - -                                                        - - - 

                                - 020 -

     /*      */
     void display_menu(menu,x,y,count);

     /*    */
     choice=get_resp(x,y,count,menu,keys)

     /*    */
     void restore_video(x,endx+1,y,endy+1,p);
     free(p);
     return choice;
     }

     /*      */
     void display_menu(menu,x,y,count)
     char *menu[];
     int x,y,count;
     {
      register int i;

     for(i=0;i<count;i++,x++) {
       goto_xy(x,y);
       printf(menu[i]);
       }
     }

     void draw_border(startx,starty,endx,endy)
     int   startx,starty,endx,endy;
     {
      register int i;

      for(i=startx+1;i<endx;i++) {
     goto_xy(i,starty);
     putchar(179);
     goto_xy(i,endy);
     putchar(179);
     }

      for(i=starty+1;i<endy;i++) {
     goto_xy(startx,i);
     putchar(196);
     goto_xy(endx,i);
     putchar(196);
     }
     goto_xy(startx,starty); putchar(218);
     goto_xy(startx,endy  ); putchar(191);
     goto_xy(endx  ,starty); putchar(192);
     goto_xy(endx  ,endy  ); putchar(217);
     }
     /*    */
     get_resp(x,y,count,menu,keys)
     int x,y,count;
     char *menu[];
     char *keys;
     {
      union inkey {
        char ch[2];
        int i;
      } c;
     int arrow_choice=0,key_choice;
- - -                                                        - - - 

                                - 021 -


     y++;
     /*    */
     goto_xy(x,y);
     write_video(x,y,menu[0],REV_VID);

     for(;;) {
      while(!bioskey(1)); /*   */
      c.i=bioskey(0);

     /*      */
     goto_xy(arrow_choice,y);
     write_video(x+arrow_choice,y,
             menu[arrow_choice],norm_vid);
     if(c.ch[0]) { /*   */
      key_choice= is_in(keys,tlower(c.ch[0]));
     if(key_choice) return key_choice-1;
     switch(c.ch[0]) {
       case '\r' : return arrow_choice;
       case ' '  : arrow_choice++;
                   break;
      case ESC   : return -1; /*  */
        }
     }
     else { /*   */
      switch(c.ch[1]) {
       case 72 : arrow_choice--; /*   */
                 break;
       case 80 : arrow_choice++; /*   */
                 break;

          }
       }
     if(arrow_choice==count) arrow_choice=0;
     if(arrow_choice<0) arrow_choice=count-1;
         /*    */
      goto_xy(x+arrow_choice,y);
      write_video(x+arrow_choice,y,menu[arrow_choice],REV_VID);
      }
     }

     /*      */
     void write_video(x,y,p,attrib)
     int x,y;
     char *p;
     int attrib;
     {
      union REGS r;
      register int i,j;

      for(i=y; *p; i++) {
       goto_xy(x,i);
          r.h.ah=9; /*      */
          r.h.bh=0; /*             */
          r.x.cx=1; /*    */
          r.h.al=*p++; /*           */
          r.h.bl=attrib; /*          */
          int86(0x10,&r,&r);
       }
     }
- - -                                                        - - - 

                                - 022 -


     /*    */
     void save_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      union REGS r;
      register int i,j;

      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
          goto_xy(j,i);
          r.h.ah=8; /*      */
          r.h.bh=0; /*             */
          *buf_ptr++ = int86(0x10,&r,&r);
          putchar(' '); /*   */
        }
     }

     /*    */
     void restore_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      union REGS r;
      register int i,j;

      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
          goto_xy(j,i);
          r.h.ah=9; /*      */
          r.h.bh=0; /*             */
          r.x.cx=1; /*    */
          r.h.al=*buf_ptr++; /*           */
          r.h.bl=*buf_ptr++; /*          */
          int86(0x10,&r,&r);
        }
     }

     /*   */
     void cls()
     {
      union REGS r;

      r.h.ah=6; /*    */
      r.h.al=0; /*    */
      r.h.ch=0; /*   */
      r.h.cl=0; /*   */
      r.h.dh$; /*   */
      r.h.dly; /*   */
      r.h.bh=7; /*    */
      int86(0x10,&r,&r);
     }

                     .  
                .  (
         ,    ,
     ,  .)      ,
       ,        
      .       -
- - -                                                        - - - 

                                - 023 -

            ,    
       .      ,     
       BIOS  ,      
      ,    BIOS,    IBM,
         100% .



                   
     -----------------------------------------------------------------

              ,      ""  
         BIOS        
     .               
     .            
          !

                  
     .                
     ,               .
             
         .    -    far,
              .      
      ,   .   - 
       ,            
     .   ,            
      far.    ,         
      ,      
     .

                  
     -----------------------------------------------------------------

                       
     B0000000H, a   - 8000000.  ,  
            ,    ,
        .    ,      
      .  BIOS 16,  15  
      .    ,  ,  
      ,    2,  3  7.  CGA  EGA 
       2  3,        7.    
        .   ,   
      7,    ,   
       EGA  CGA.    ,     EGA  CGA
         ,          .
         popup()     
                     
      .      
     .

     vmode = video_mode();
      if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
        printf("   80   ");
        exit(1);
     }
      /*      */
     if(vmode==7) vid_mem=(char far *)0xB0000000;
     else   vid_mem=(char far *)0xB8000000;

- - -                                                        - - - 

                                - 024 -

           video_mode()         ,  
      vid_mem,    char far.



                save_video()  restore_video()
     -----------------------------------------------------------------

          Ka       vid_mem    
     ,            
         .  ,    
         ,    ,    
     .  - ,    ,   -
     ,       160  .    ,
             
     :

       = _ + X*160 + Y*2

           save_video()    restore_video()    
            .

     void save_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      register int i,j;
      char far *v, far *t;

      v=vid_mem;
      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
           t = v + (j*160) + i*2;  /*   */
           *buf_ptr++ = *t++;      /*   */
           *buf_ptr++ = *t;        /*   */
           *(t-1) = ' ';           /*   */
         }
     }

     /*    */
     void restore_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      register int i,j;
      char far *v, far *t;

      v=vid_mem;
      t=v;
      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
          v = t;
          v += (j*160) + i*2;   /*   */
          *v++ = *buf_ptr++;    /*   */
          *v = *buf_ptr++;      /*   */
         }
     }

- - -                                                        - - - 

                                - 025 -

            ,       
                 .  
     ,             
      .

                  ,    
       ( ).  write_char() 
                     
     .

     /*      */
     void write_char(x,y,ch,attrib)
     int x,y;
     char ch;
     int attrib;
     {
      register int i;
      char far *v;

      v=vid_mem;
      v += (x*160) +y*2;
      *v++ = ch; /*   */
      *v = attrib; /*   */
     }

                    
                   .     
                  ,
      BIOS.    ,  . ,
          .

     /*      
               */
     #include "stdio.h"
     #include "dos.h"
     #include "stdlib.h"

     #define BORDER 1
     #define ESC 27
     #define REV_VID 0x70
     #define NORM_VID  7

     void save_video(),restore_video();
     void goto_xy(),cls(),write_video();
     void display_menu(),draw_border();
     char far *vid_mem;

     char *fruit[] = {
      "",
      "",
      "",
      "",
      "",
      ""
     };

- - -                                                        - - - 

                                - 026 -

     char *color[]={
      "",
      "",
      "",
      ""
     };

     char *apple_type[] = {
      " ",
      "",
      " ",
      ""
     };

     main()
     {
      int i;

     cls();
     goto_xy(0,0);
     for(i=0;i<25;i++)
      printf("   \n");
     popup(fruit,"",6,1,3,BORDER);
     popup(color,"",4,5,10,BORDER);
     popup(apple_type,"",4,10,18,BORDER);
     }

     /*      
         -2,      
         -1,     ESC
              
        ,   0 */
     int popup(menu,keys,count,x,y,border)
     char *menu[];  /*   */
     char *keys;    /*   */
     int count;     /*   */
     int x,y;       /*     */
     int border;    /*  0    */
     {
      register int i,len;
      int endx endy choice;
      unsigned char *p;

      if((x>24)||(x<0)||(y>79)||(y<0)) {
       printf("    ");
       return -2;
      }
     /*   */
     len=0;
     for(i=0;i<count;i++)
      if(strlen(menu[i]) > len) len=strlen(menu[i]);
     endy=len+2+y;
     endx=count+1+x;
     if((endx+1>24) || (endy+1>79)) {
       printf("    ");
       return -2;
      }
- - -                                                        - - - 

                                - 027 -

     vmode = video_mode();
      if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
        printf("   80   ");
        exit(1);
     }

      /*      */
     if(vmode==7) vid_mem=(char far *)0xB0000000;
     else   vid_mem=(char far *)0xB8000000;
     /*      */
     p=(unsigned int *)malloc((endx-x+1)*(endy-y+1));
      if(!p) exit(1); /*       */

     /*    */
     void save_video(x,endx+1,y,endy+1,p);

     if(border) draw_border(x,y,endx,endy);

     /*      */
     void display_menu(menu,x,y,count);

     /*    */
     choice=get_resp(x,y,count,menu,keys)

     /*    */
     void restore_video(x,endx+1,y,endy+1,p);
     free(p);
     return choice;
     }

     /*      */
     void display_menu(menu,x,y,count)
     char *menu[];
     int x,y,count;
     {
      register int i;

     for(i=0;i<count;i++,x++) {
       write_string(x,y,menu[i],NORM_VID);
       }
     }

     void draw_border(startx,starty,endx,endy)
     int   startx,starty,endx,endy;
     {
      register int i;
      char far *v,far *t;

      v=vid_mem;
      t=v;
      for(i=startx+1;i<endx;i++) {
      v += (i*160) + starty*2;
      *v++ = 179;
      *v = NORM_VID;
      v=t;
      v += (i*160) + endy*2;
      *v++ = 179;
      *v = NORM_VID;
      v=t;
     }
- - -                                                        - - - 

                                - 028 -


      for(i=starty+1;i<endy;i++) {
      v += (startx*160) + i*2;
      *v++ = 196;
      *v = NORM_VID;
      v=t;
      v += (endx*160) + i*2;
      *v++ = 196;
      *v = NORM_VID;
      v=t;
     }

     write_char(startx,starty,218,NORM_VID);
     write_char(startx,endy  ,191,NORM_VID);
     write_char(endx  ,starty,192,NORM_VID);
     write_char(endx  ,endy  ,217,NORM_VID);
     goto_xy(startx,endy  ); putchar(191);
     goto_xy(endx  ,starty); putchar(192);
     goto_xy(endx  ,endy  ); putchar(217);
     }

     /*    */
     get_resp(x,y,count,menu,keys)
     int x,y,count;
     char *menu[];
     char *keys;
     {
      union inkey {
        char ch[2];
        int i;
      } c;
     int arrow_choice=0,key_choice;

     y++;
     /*    */
     goto_xy(x,y);
     write_string(x,y,menu[0],REV_VID);

     for(;;) {
      while(!bioskey(1)); /*   */
      c.i=bioskey(0);

     /*      */
     goto_xy(arrow_choice,y);
     write_string(x+arrow_choice,y,
             menu[arrow_choice],norm_vid);
     if(c.ch[0]) { /*   */
      key_choice= is_in(keys,tolower(c.ch[0]));
     if(key_choice) return key_choice-1;
     switch(c.ch[0]) {
       case '\r' : return arrow_choice;
       case ' '  : arrow_choice++;
                   break;
      case ESC   : return -1; /*  */
        }
     }
     else { /*   */
      switch(c.ch[1]) {
       case 72 : arrow_choice--; /*   */
                 break;
- - -                                                        - - - 

                                - 029 -

       case 80 : arrow_choice++; /*   */
                 break;

          }
       }
     if(arrow_choice==count) arrow_choice=0;
     if(arrow_choice<0) arrow_choice=count-1;
         /*    */
      goto_xy(x+arrow_choice,y);
      write_string(x+arrow_choice,y,menu[arrow_choice],REV_VID);
      }
     }

     /*      */
     void write_string(x,y,p,attrib)
     int x,y;
     char *p;
     int attrib;
     {
      register int i,j;
      char far *v;

      v=vid_mem;
      v += (x*160) + y*2;
      for(i=y; *p; i++) {
        *v++ =*p++; /*   */
        *v++ =attrib; /*   */
       }
     }

     /*      */
     void write_char(x,y,ch,attrib)
     int x,y;
     char ch;
     int attrib;
     {
      register int i;
      char far *v;

      v=vid_mem;
      v += (x*160) +y*2;
      *v++ = ch; /*   */
      *v = attrib; /*   */
     }

     /*     
             */
     void save_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      register int i,j;
      char far *v, far *t;

- - -                                                        - - - 

                                - 030 -

      v=vid_mem;
      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
           t = v + (j*160) + i*2;  /*   */
           *buf_ptr++ = *t++;      /*   */
           *buf_ptr++ = *t;        /*   */
           *(t-1) = ' ';           /*   */
         }
     }

     /*     
             */
     void restore_video(startx,endx,starty,endy,buf_ptr)
     int   startx,endx,starty,endy;
     unsigned int *buf_ptr;
     {
      register int i,j;
      char far *v, far *t;

      v=vid_mem;
      t=v;
      for(i=starty;i<endy;i++)
        for(j=startx;j<endx;j++) {
          v = t;
          v += (j*160) + i*2;   /*   */
          *v++ = *buf_ptr++;    /*   */
          *v = *buf_ptr++;      /*   */
         }
     }

     /*   */
     void cls()
     {
      union REGS r;

      r.h.ah=6; /*    */
      r.h.al=0; /*    */
      r.h.ch=0; /*   */
      r.h.cl=0; /*   */
      r.h.dh$; /*   */
      r.h.dly; /*   */
      r.h.bh=7; /*    */
      int86(0x10,&r,&r);
     }

     /*    x,y */
     void goto_xy(x,y)
     int x,y;
     {
      union REGS r;

      r.h.ah=2; /*    */
      r.h.dl=y; /*         */
      r.h.dh=x; /*          */
      r.h.bh=0; /*             */
      int86(0x10,&r,&r);
     }
- - -                                                        - - - 

                                - 031 -


     /*      */
     video_mode()
     {
      union REGS r;

      r.h.ah = 15;   /*   */
      return int86(0x10,&r,&r) & 255;
     }

     is_in(s,c)
     char *s,c;
     {
      register int i;

      for(i=0; *s; i++)
         if(*s++ == c) return i+1;
      return 0;
     }



                 
     -----------------------------------------------------------------

                    
       ,        
       .         
                   
         .        
     popup(),         ,      ,   
      ,   pulldown(),    
         (  ),  
              .       
                 .
             ,    
         .



                
     -----------------------------------------------------------------

                         ,
         .   ,  
                 
     ,    ,   ,   
     ,  .        
                      
        ,  .

                 -    
     ,    ,    .  
       ,   :

- - -                                                        - - - 

                                - 032 -

      struct menu_frame {
        int startx,endx,starty,endy;
        unsigned char *p; /*     */
        char **menu;      /*     */
        int border;       /*  / */
        int count;        /*   */
        int astive;       /*     */
      } frame[MAX_FRAME];

      AX_FRAME - ,     
       .      
         ,        -
      .      ,   
                   
     .



                 
     -----------------------------------------------------------------

                       
     .  make_menu(),  ,   .

      /*    .
         1     
            0 */
     make_menu(num,menu,keys,count,x,y,border)
     int num;   /*   */
     char *menu;   /*   */
     char *keys;   /*   */
     int count;    /*   */
     int x,y;      /*    */
     int border;   /*  */
     {
      register int i,len;
      int endx,endy,choice,vmode;
      unsigned char *p;

      if(num>MAX_FRAME) {
       printf("  ");
       return 0;
     }
      if((x>24)||(x<0)||(y>79)||(y<0)) {
       printf("    ");
       return 0;
      }

     /*   */
     len=0;
     for(i=0;i<count;i++)
      if(strlen(menu[i]) > len) len=strlen(menu[i]);
     endy=len+2+y;
     endx=count+1+x;
     if((endx+1>24) || (endy+1>79)) {
       printf("    ");
       return 0;
      }

- - -                                                        - - - 

                                - 033 -

     /*      */
     p=(unsigned int *)malloc((endx-x+1)*(endy-y+1));
      if(!p) exit(1); /*       */

     /*   */
     frame[num].startx=x;
     frame[num].endx=endx;
     frame[num].starty=y;
     frame[num].endy=endy;
     frame[num].p = p;
     frame[num].menu = (char **) menu;
     frame[num].border = border;
     frame[num].keys = keys;
     frame[num].count = count;
     frame[num].active =0;
     return 1;
     }

              make_menu          ,  
       popup()    ,      
            .        
      .



                pulldown()
     -----------------------------------------------------------------

           pulldown()  :

     /*     
         -1,     ESC
            ,   0 */

     int pulldown(num)
     int num; /*   */
     {
      int vmode,choice;

      vmode=video_mode();
      if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
        printf("   80   ");
        exit(1);
     }

      /*      */
     if(vmode==7) vid_mem=(char far *)0xB0000000;
     else   vid_mem=(char far *)0xB8000000;

     /*    */
     if(!frame[num].active) { /*   */
         save_video(num);
         frame[num].active= 1; /*    */
     }

     if( frame[num].border) draw_worder(num);

     display_menu(num);  /*   */
     return get_resp(num);  /*   */
     }
- - -                                                        - - - 

                                - 034 -


            pulldown()        
     ,       .      
      ,    restore_video()      
     .  ,       
     ,            
             ,     
         .             
           ,       
     .

           ,    ,   ,
                0.   
          ,     
        .  (    
          ,      
      ,   .)



                
     -----------------------------------------------------------------

                         ,    
     restore_video     ,        
     .      restore_video()     
       ,     .

     /*    */
     void restore_video(num)
     int   num;
     {
      register int i,j;
      char far *v, far *t;
      char *buf_ptr;

      buf_ptr=frame[num].p;
      v=vid_mem;
      t=v;
      for(i=frame[num].starty;i<frame[num].endy;i++)
        for(j=frame[num].startx;j<frame[num].endx;j++) {
          v = t;
          v += (j*160) + i*2;   /*   */
          *v++ = *buf_ptr++;    /*   */
          *v = *buf_ptr++;      /*   */
         }
      frame[num].active= 0;
     }


- - -                                                        - - - 

                                - 035 -


                ,   pulldown
     -----------------------------------------------------------------

                    
      -              
     .

     /*      
          - */
     #include "stdio.h"
     #include "dos.h"
     #include "stdlib.h"

     #define BORDER 1
     #define ESC 27
     #define REV_VID 0x70
     #define NORM_VID  7

     void save_video(),restore_video();
     void goto_xy(),cls(),write_video();
     void display_menu(),draw_border();
     char far *vid_mem;

      struct menu_frame {
        int startx,endx,starty,endy;
        unsigned char *p; /*     */
        char **menu;      /*     */
        int border;       /*  / */
        int count;        /*   */
        int astive;       /*     */
      } frame[MAX_FRAME];

     char *fruit[] = {
      "",
      "",
      "",
      "",
      ""
      ""
     };

     char *color[]={
      "",
      "",
      "",
      ""
     };

     char *apple_type[] = {
      " ",      ?
      "",
      " ",
      "A"
     };

- - -                                                        - - - 

                                - 036 -

     char *grape_type[]= {
       "",
       "",
       "",
       " "
     };

     main()
     {
      int i;

      cls();
      goto_xy(0,0);

     /* -    */
     make_menu(0,fruit,"",6,5,20,BORDER);
     make_menu(1,color,"",4,9,28,BORDER);
     make_menu(2,apple_type,"",4,12,32,BORDER);
     make_menu(3,grape_type,"",4,9,10,BORDER);

     printf(" :");

     pd_driver(); /*    */

     }

     void pd_driver()
     {
      int choice1,choice2,selection;

      /*      */
     while((choice1=pulldown(0)) != -1) {
       switch ( choice1 ) {
         case 0 :  /*  */
           while((choice2=pulldown(1)) != -1) {
             if(choice2 ==0) selection=pulldown(2);/*  */
             restore_video(2);
           }
           restore_video(1);
           break;
         case 1 :
         case 2 : goto_xy(1,0);
           printf(" ");
           break;
         case 3 : /*  */
           selection=pulldown(3);
           restore_video(3);
           break;
         case 4 :
         case 5 : goto_xy(1,0);
           printf(" ");
           break;
       }
      }
         restore_video(0);
     }

     /*      */

- - -                                                        - - - 

                                - 037 -

     int pulldown(num)
     int num; /*   */
     {
      int vmode,choice;

      vmode=video_mode();
      if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
        printf("   80   ");
        exit(1);
     }

      /*      */
     if(vmode==7) vid_mem=(char far *)0xB0000000;
     else   vid_mem=(char far *)0xB8000000;

     /*    */
     if(!frame[num].active) { /*   */
         save_video(num);
         frame[num].active= 1; /*    */
     }

     if( frame[num].border) draw_worder(num);

     display_menu(num);  /*   */
     return get_resp(num);  /*   */
     }

      /*    .
         1     
            0 */
     make_menu(num,menu,keys,count,x,y,border)
     int num;   /*   */
     char *menu;   /*   */
     char *keys;   /*   */
     int count;    /*   */
     int x,y;      /*    */
     int border;   /*  */
     {
      register int i,len;
      int endx,endy,choice,vmode;
      unsigned char *p;

      if(num>MAX_FRAME) {
       printf("  ");
       return 0;
     }
      if((x>24)||(x<0)||(y>79)||(y<0)) {
       printf("    ");
       return 0;
      }
     /*   */
     len=0;
     for(i=0;i<count;i++)
      if(strlen(menu[i]) > len) len=strlen(menu[i]);
     endy=len+2+y;
     endx=count+1+x;
     if((endx+1>24) || (endy+1>79)) {
       printf("    ");
       return 0;
      }
- - -                                                        - - - 

                                - 038 -


     /*      */
     p=(unsigned int *)malloc((endx-x+1)*(endy-y+1));
      if(!p) exit(1); /*       */

     /*   */
     frame[num].startx=x;
     frame[num].endx=endx;
     frame[num].starty=y;
     frame[num].endy=endy;
     frame[num].p = p;
     frame[num].menu = (char **) menu;
     frame[num].border = border;
     frame[num].keys = keys;
     frame[num].count = count;
     frame[num].active =0;
     return 1;
     }

     /*      */
     void display_menu(num)
      int num;
     {
      char **m;
      register int i, x;

      x = frame[num].startx+1;
      m = frame[num].menu;

     for(i=0;i<frame[num].count;i++,x++) {
       write_string(x,frame[num].starty+1,m[i],NORM_VID);
       }
     }

     void draw_border(num)
     int  num ;
     {
      register int i;
      char far *v,far *t;

      v=vid_mem;
      t=v;
      for(i=frame[num].startx+1;i<frame[num].endx;i++) {
      v += (i*160) + frame[num].starty*2;
      *v++ = 179;
      *v = NORM_VID;
      v=t;
      v += (i*160) + frame[num].endy*2;
      *v++ = 179;
      *v = NORM_VID;
      v=t;
     }

      for(i=frame[num].starty+1;i<frame[num].endy;i++) {
      v += (frame[num].startx*160) + i*2;
      *v++ = 196;
      *v = NORM_VID;
      v=t;
      v += (frame[num].endx*160) + i*2;
      *v++ = 196;
- - -                                                        - - - 

                                - 039 -

      *v = NORM_VID;
      v=t;
     }

     write_char(frame[num].startx,frame[num].starty,218,NORM_VID);
     write_char(frame[num].startx,frame[num].endy  ,191,NORM_VID);
     write_char(frame[num].endx  ,frame[num].starty,192,NORM_VID);
     write_char(frame[num].endx  ,frame[num].endy  ,217,NORM_VID);
     goto_xy(frame[num].startx,frame[num].endy  ); putchar(191);
     goto_xy(frame[num].endx  ,frame[num].starty); putchar(192);
     goto_xy(frame[num].endx  ,frame[num].endy  ); putchar(217);
     }

     /*    */
     get_resp(num)
     int num;
     {
      union inkey {
        char ch[2];
        int i;
      } c;
     int arrow_choice=0,key_choice;
     int x,y;

     x=frame[num].startx+1;
     y=frame[num].starty+1;

     /*    */
     goto_xy(x,y);
     write_string(x,y,frame[num].menu[0],REV_VID);

     for(;;) {
      while(!bioskey(1)); /*   */
      c.i=bioskey(0);

     /*      */
     goto_xy(arrow_choice,y);
     write_string(x+arrow_choice,y,
             frame[num].menu[arrow_choice],norm_vid);
     if(c.ch[0]) { /*   */
      key_choice= is_in(frame[num].keys,tolower(c.ch[0]));
     if(key_choice) return key_choice-1;
     switch(c.ch[0]) {
       case '\r' : return arrow_choice;
       case ' '  : arrow_choice++;
                   break;
      case ESC   : return -1; /*  */
        }
     }
     else { /*   */
      switch(c.ch[1]) {
       case 72 : arrow_choice--; /*   */
                 break;
       case 80 : arrow_choice++; /*   */
                 break;

          }
       }
     if(arrow_choice==frame[num].count) arrow_choice=0;
     if(arrow_choice<0) arrow_choice=frame[num].count-1;
- - -                                                        - - - 

                                - 040 -

         /*    */
      goto_xy(x+arrow_choice,y);
      write_string(x+arrow_choice,y,
                   frame[num].menu[arrow_choice],REV_VID);
      }
     }

     /*      */
     void write_string(x,y,p,attrib)
     int x,y;
     char *p;
     int attrib;
     {
      register int i,j;
      char far *v;

      v=vid_mem;
      v += (x*160) + y*2;
      for(i=y; *p; i++) {
        *v++ =*p++; /*   */
        *v++ =attrib; /*   */
       }
     }

     /*      */
     void write_char(x,y,ch,attrib)
     int x,y;
     char ch;
     int attrib;
     {
      register int i;
      char far *v;

      v=vid_mem;
      v += (x*160) +y*2;
      *v++ = ch; /*   */
      *v = attrib; /*   */
     }

     /*     
             */
     void save_video(num)
      int num;
     {
      register int i,j;
      char far *v, far *t;
      char *buf_ptr;

      buf_ptr=frame[num].p;
      v=vid_mem;
      for(i=frame[num].starty;i<frame[num].endy;i++)
        for(j=frame[num].startx;j<frame[num].endx;j++) {
           t = (v + (j*160) + i*2);  /*   */
           *buf_ptr++ = *t++;      /*   */
           *buf_ptr++ = *t;        /*   */
           *(t-1) = ' ';           /*   */
         }
     }

- - -                                                        - - - 

                                - 041 -

     /*    */
     void restore_video(num)
     int   num;
     {
      register int i,j;
      char far *v, far *t;
      char *buf_ptr;

      buf_ptr=frame[num].p;
      v=vid_mem;
      t=v;
      for(i=frame[num].starty;i<frame[num].endy;i++)
        for(j=frame[num].startx;j<frame[num].endx;j++) {
          v = t;
          v += (j*160) + i*2;   /*   */
          *v++ = *buf_ptr++;    /*   */
          *v = *buf_ptr++;      /*   */
         }
      frame[num].active= 0;
     }

     /*   */
     void cls()
     {
      union REGS r;

      r.h.ah=6; /*    */
      r.h.al=0; /*    */
      r.h.ch=0; /*   */
      r.h.cl=0; /*   */
      r.h.dh$;/*   */
      r.h.dly;/*   */
      r.h.bh=7; /*    */
      int86(0x10,&r,&r);
     }

     /*    x,y */
     void goto_xy(x,y)
     int x,y;
     {
      union REGS r;

      r.h.ah=2; /*    */
      r.h.dl=y; /*         */
      r.h.dh=x; /*          */
      r.h.bh=0; /*             */
      int86(0x10,&r,&r);
     }

     /*      */
     video_mode()
     {
      union REGS r;

      r.h.ah = 15;   /*   */
      return int86(0x10,&r,&r) & 255;
     }

- - -                                                        - - - 

                                - 042 -

     is_in(s,c)
     char *s,c;
     {
      register int i;

      for(i=0; *s; i++)
         if(*s++ == c) return i+1;
      return 0;
     }

            ,     "",    
               ;    ""
     ,          .    
              
     .       .

     +-------------------------------------------------------+
     |  :                                       |
     |               +---------+                             |
     |               |   |                             |
     |               | |                             |
     |               |    |                             |
     |               ||                             |
     |               |+-------+                         |
     |               |||                         |
     |               +-----| |                         |
     |                     |+-----------------+           |
     |                     || |           |
     |                     +---|*********|           |
     |                         |       |           |
     |                         |        |           |
     |                         +-----------------+           |
     |                                                       |
     +-------------------------------------------------------+

                   pd_driver(),  
                 main().      
          ,  
      .        
        pd_driver()    .   ,
             
     .            
            .  ,    
                          
      .

      1.  ,  make_menu().
      2.  ,  pulldown().
      3.  ,   restore_video(),   
          .



                
     -----------------------------------------------------------------

           ,        ,    
       .  ,         
        :

- - -                                                        - - - 

                                - 043 -

     #   
     #   (    )
     #      


                                2
                               -------

                            
     -----------------------------------------------------------------

                          
      ,          
     .      ,   ,  
     ,        .         
                
     ,       
        .

                    
      ,        
      .

                     
       ,     1. - , 
        ,    , 
     ,      ROM-BIOS  ,  -
         .

                      
      ,                
     .



                            .
     -----------------------------------------------------------------

                          ,
        .    
                
      .

            ,   ,  
     ,      .
     (       ).  
           .

                 ,         ,
         ,      
        . ,   ,
                      
          .

           ,    ,    
       -       
          .    
               ""      
     ,      ,    
     ,                   .
- - -                                                        - - - 

                                - 044 -

     ,     ,  /
         (,  printf()    lets()  )  ,    
            ,  
      /   .

                .   
           .    
         .      - 
      .     ,  ,    
     ,          ,   
      ,       .
     (  ,    ,  . 
         .       
               
     ).

           ,             
     , ,     ,
           ,       "
     ",           
           .
                      
         ,            
              .    
     ,      -     
          (), 
       .



                .
     -----------------------------------------------------------------

                ,   
     ,      ,    
           .      
         ,     ,   
             .  
           . 
      ,    .

                  struct window_frame
                    int startx, endx, starty, endy; /* */
                    int curx, cury; /*    */
                    unsigned chsr *p; /* */
                    char *header; /* */
                    int border; /*/ */
                    int active; /*   */
                  } frame [MAX_FRAME];

           startx,  starty,  endx  endy    
              .   
           curx    cury.  
        - ,    
             .
      p    ,   
         ,      .     
       ,    .   
        header.   border  
                 .
- - -                                                        - - - 

                                - 045 -

      active   "1",      
     ,   "0" -   .

                       
      .  -,     , ,
           ,       
              -     
     /.         ,   
     .


                           .
     -----------------------------------------------------------------

                         make_window(),
         .


         /*    .
           1,       
           0    */
         _window(num, header,startx,starty,endx,endy,border)
         int num; /*   */
         char *header; /*   */
         int startx,starty; /*  X,Y    */
         int endx,endy; /*  X,Y    */
         int border; /*  ,  0 */
         {
           unsigned char *p;

           if(num>MAX_FRAME) {
             printf("Too many windows\n");
             return 0;
           }

          if((startx>24) || (startx<0) || (starty>78) || (starty<0)) {
             printf("range error");
             return 0;
           }

           if((endx>24) || (endy>79)) {
             printf("window won't fit");
             return 0;
           }

       /*     */
       p=(unsigned char *) malloc(2*(endx-startx+1)*(endy-starty+1));
       if(!p) exit(1); /*     
        */

           /*   */
           frame[num].startx = startx; frame[num].endx = endx;
           frame[num].starty = starty; frame[num].endy = endy;
           frame[num].p = p;
           frame[num].haeder = header;
           frame[num].border = border;
           frame[num].active = 0;
           frame[num].curx = 0; frame[num].cury = 0;
           return 1;
         }
- - -                                                        - - - 

                                - 046 -


                     ,    
         ,      ,  
        .      
       make_window()          0  
     " [Es  ]",         0,0    
         24,78   .

      make_window (0, " [Ese  ]", 0,0,24,78, BORDER);

          ,  ,    curx 
     cury  0.   ,      
     ,         .  
          .



                         .
     -----------------------------------------------------------------

               window (). 
     num          ,    
     .


         /*      */
         void window(num)
         int num; /*   */
         {
           int vmode, choice;
           int x, y;

           vmode = video_mode();
           if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
             printf("video must be in 80 column text mode");
             exit(1);
           }
           /*     */
           if(vmode==7) vid_mem = (char far *) 0xB0000000;
           else vid_mem = (char far *) 0xB0000000;

           /*    */
           if(!frame[num].active) { /*    */
           save_video(num); /*     */
           frame[num].active = 1; /*    */
           }

           if(!frame[num].border) draw border(num);
           display_header(num); /*     */

           x = frame[num].startx + frame[num].curx + 1;
           y = frame[num].starty + frame[num].cury + 1;
           goto_xy(x,y);
         }


             ,      
     menu(),        .      vid-mem
         char far.

- - -                                                        - - - 

                                - 047 -

           display_header(),   ,  
            .   
          ,    .


         /*      
          */
         void display_header(num)
         int num;
         {
           register int y,len;

           y = frame[num].starty;
           /*      
           ,  ,     */
           len = strlen(frame[num].header);
           len = (frame[num].endy - y - len) / 2;
           if(len<0) return; /*     */
           y = y +len;

           write_string(frame[num].startx, y,
                        frame[num].header,NORM_VID);
         }


             ,           
     ,     NOR_VID (  7) 
     REV_VID (  70).

                   
     deactivate(),     .


         /*        */
         deactivate(num)
         int num;
         {
           /*       */
           frame[num].curx = 0;
           frame[num].cury = 0;
           restore_video(num);
         }


            ,       0,0.
     ,         ,  
                   
     ,                  ,
        .


- - -                                                        - - - 

                                - 048 -


                 /.
     -----------------------------------------------------------------

                          
            -  
     /.   ,      ,
         ,        /  
         .  ,      
     ,           ,
        .        
                
     -,      .   , 
       ,         
        ,        ,
                
            .  ,   
            
     ,   DOS.  ,   
         "    "            
     ,   ;      DOS  
       .

                           
     /     window.    ,    
             ,
        .



                      .
     -----------------------------------------------------------------

          , -   ,   ,
        ,      
     goto_xy().        .   
       /         
     ,       
         .    window_xy(),    ,
         .  (     

       0,0     ).


         /*      .
             0        -
               */

         window_xy(num, x, y,)
         int num, x, y;
         {
           if(x<0 || x+frame[num].startx>=frame[num].endx-1)
             return 0;
           if(x<0 || y+frame[num].starty>=frame[num].endy-1)
             return 0;
           frame[num].curx = x;
           frame[num].cury = y;
           goto_xy(frame[num].startx+x+1, frame[num].starty+y+1);
           return 1;
           }
- - -                                                        - - - 

                                - 049 -



               window_xy()  
       ,        X,Y         
     ,       .   
      X,Y   ,     
     .    ,           
        2,2,           
                    
       ,      .

             window_xy()     
                   
       .    ,      window_xy()   
          .



                   window_getche()
     -----------------------------------------------------------------

                         
     getche(),             
        ,        
       .      
       window_getche().       ,
          .


        /*             .   
             16- -. */
         window_getche(num)
         int num;
         {
           union inkey {
             char ch[2];
             int i;
           } c;

           if(!frame[num].active) return 0; /*    */

           window_xy(num, frame[num].curx, frame[num].cury);

           c.i = bioskey(0); /*     */

           if(c.ch[0]) {
            switch(c.ch[0]) {
             case '\r':  /*   ENTER */
              break;
             case BKSP; /*  */
              break;
             default:
           if(frame[num].cury+frame[num].starty < frame[num].endy-1) {
             write_char(frame[num].startx = frame[num].curx=1,
               frame[num].starty+frame[num].cury+1,c.ch[0],NORM_VID);
                 frame[num].cury++;
               }
             }
             if(frame[num].curx < 0) frame[num].curx = 0;
             if(frame[num].curx+frame[num].startx > frame[num].endx-2)
- - -                                                        - - - 

                                - 050 -

               frame[num].curx--;
             window_xy(num, frame[num].curx, frame[num].cury);
           }
           return c.i;
         }

                  getche(),    window_getche()
       16- -.    ,    
                
     ,             
     .      ,    
              window_getche()    
      .

               .     
       (..        ),       0.
         0    ,   
     ,           .
                ,  
        .     ,   
         RETURN    BACKSPASE,    
         Y,      ,  
         .    
       ,  Y .  
         window_xy()   ,   
         .

           window_getche          
       .    ,        ,
             .    
       ,    ,        
      .    ,      
     ,      .          
      ,           
      .

              1,   bios_key() c
       .        ,    
          bios_key(),   
      1.



                window_gets()
     -----------------------------------------------------------------

             ,      ,   
            window_gets().         
     ,    gets(),     
       .            
     ,  .


         /*     */
         void window_gets(nums, s)
         int num;
         char *s;
         {

           char ch, *temp;
- - -                                                        - - - 

                                - 051 -


           temp = s;
           for(;;) {
             ch = window_getche(num);
             switch(ch) {
               case '\r': /*   ENTER */
               *s='\0';
               return;
             case BKSP:   /*  */
               if(s>temp) {
                 s--;
                 frame[num].cury--;
                 if(frame[num].cury<0) frame[num].cury = 0;
                 window_xy(num, frame[num].curx, frame[num].cury);
                 write_char(frame[num].startx+ frame[num].curx+1' 
                   frame[num].starty+frame[num].cury+1, ' ',NORM_VID);
               }
               break;
             default: *s = ch;
               s++;
             }
           }
         }


             SPASE,     
       ,         
      .



                window_putchar()
     -----------------------------------------------------------------

                ,   
                   .  
           .  
         window_putchar().


         /*         .
           0,    ,  1 -  
          */
         window_putchar(num, ch)
         int num;
         char ch;
         {
           register int x, y;
           char far *v;

           /* ,    */
           if(!frame[num].active) return 0;

           x = frame[num].curx = frame[num].startx + 1;
           y = frame[num].cury = frame[num].starty + 1;

           v = vid_mem;
           v += (x*160) + y*2;  /*   */
           if(y>=frame[num].endy) {
             return 1;
- - -                                                        - - - 

                                - 052 -

           }
           if(x>=frame[num].endx) {
             return 1;
           }

           if(ch=='\n') {  /*      */
             x++;
             y = frame[num].startx+1;
             v = vid_mem;
             v += (x*160) = y*2;  /*   */
             frame[num].curx++;   /*  x */
             frame[num].cury = 0; /*  y */
           }
           else {
             frame[num].cury++;
             *v++ = ch;           /*   */
             *v++ =NORM_VID;      /*    */
           }
           window_xy(num, frame[num].curx, frame[num].cury);
           return 1;
         }

                 ,
          .      ,
                  ,
                  
     .                
     ,     .

           ,          
                  
     ,   .



                window_puts
     -----------------------------------------------------------------

           window_puts      ,
         window_putchar().


      /*  ,       .
                                                         /* 60 */
          0,      1    */

         window_puts(num, str)
         int num;
         char *str;
         {

           /* ,    */
           if(!frame[num].active) return 0;

           for( ; *str; str++)
             window_putchar(num, *str);
           return 1;
         }


- - -                                                        - - - 

                                - 053 -

                  .
     -----------------------------------------------------------------

                     
      :

                       
         ---------            ------------
        window cls()           
        window cleol()             
                                
        window_upline()            
        window_downline()          
        window_bksp()              

               .      
       ,            
     .


         /*   */
         void window_cls(num)
         int num;
         {

           register int i,j;
           char far *v, far *t;

           v = vid_mem;
           t = v;
           for(i=frame[num].starty+1; i<frame[num].endy; i++)
             for(j=frame[num].startx+1; j<frame[num].endx; j++) {
               v = t;
               v += (j*160) + i*2;
               *v++ = ' ';     /*   */
               *v =  NORM_VID; /*   */
             }
             frame[num].curx = 0;
             frame[num].cury = 0;
           }

           /*     */
           void window_cleol(num)
           int num;
           {
             register int i, x, y;

             x = frame[num].curx;
             y = frame[num].cury;
             window_xy(num, frame[num].curx, frame[num].cury);

             for(i=frame[num].cury; i<frame[num].endy-1; i++)
               window_putchar(num,' ');
             window_xy(num, x, y);
           }

     /*      .  
             0 -    */
           window_upline(num)
           int num;
- - -                                                        - - - 

                                - 054 -

           {
             if(frame[num].curx>0) {
               frame[num].curx--;
               window_xy(num, frame[num].curx, frame[num].cury);
               return 1;
             }
             return 0;
           }

           window_downline(num)
           int num;
           {
             if(frame[num].curx<frame[num].endx-frame[num].startx-1) {
               frame[num].curx++;
               window_xy(num, frame[num].curx, frame[num].cury);
               return 1;
             }
             return 1;
           }

           /*    */
           window_bksp(num)
           int num;
           {
             if(frame[num].cury>0) {
             frame[num].cury--;
             window_xy(num, frame[num].curx, frame[num].cury);
             window_putchar(num, ' ');
             frame[num].cury--;
             window_xy(num, frame[num].curx, frame[num].cury);
           }
         }



                     
              
     -----------------------------------------------------------------

             make_window()        
                 ,    
                  
     .                  
       ,    .   
                        
     .       size()  move() 
              .  
                     
     ,    HOME, END, PGDN  PGUP.

         /*     */
         void size(num)
         int num;
         {
           char ch;
           int x, y, startx, starty;

           /* ,   */
           if(!frame[num].active) window(num);
           startx = x = frame[num].startx;
- - -                                                        - - - 

                                - 055 -

           starty = y = frame[num].starty;
           window_xy(num, 0, 0);

           do {
             ch = get_special();
             switch(ch) {
               case 75:     /*  */
                 starty--;
                 break;
               case 77:     /*  */
                 starty++;
                 break;
               case 72:     /*  */
                 startx--;
                 break;
               case 80:     /*  */
                 startx++;
                 break;
               case 71:     /*   */
                 startx--;starty--;
                 break;
               case 73:     /*   */
                 startx--;starty++;
                 break;
               case 79:     /*   */
                 startx++;starty--;
                 break;
               case 81:     /*   */
                 startx++;starty++;
                 break;
               case 60:
                    /* F2:       */
                 startx = x;
                 starty = y;
                 ch = 59;
             }

             /*      */
             if(startx<0) startx++;
             if(startx>=frame[num].endx) startx--;
             if(starty<0) starty++;
             if(starty>=frame[num].endy) starty--;
             deactivate(num);  /*     */
             frame[num].startx = startx;
             frame[num].starty = starty;
             window(num);      /*      */
           } while(ch!Y);  /* F1     */
           deactivate(num);
         }


         /*    */
         void move(num)
         int num;
         {
           char ch;
           int x, y, ex, ey, startx, starty, endx, endy;

           /* ,   */
           if(!frame[num].active) window(num);
- - -                                                        - - - 

                                - 056 -

           startx = x = frame[num].startx;
           starty = y = frame[num].starty;
           endx = ex = frame[num].endx;
           endy = ey = frame[num].endy;
           window_xy(num, 0, 0);

           do {
             ch = get_special();
             switch(ch) {
               case 75:     /*  */
                 starty--;
                 endy--;
                 break;
               case 77:     /*  */
                 starty++;
                 endy++;
                 break;
               case 72:     /*  */
                 startx--;
                 endx--;
                 break;
               case 80:     /*  */
                 startx++;
                 endx++;
                 break;
               case 71:     /*   */
                 startx--;starty--;
                 endx--;endy--;
                 break;
               case 73:     /*   */
                 startx--;starty++;
                 endx--;endy++;
                 break;
               case 79:     /*   */
                 startx++;starty--;
                 endx++;endy--;
                 break;
               case 81:     /*   */
                 startx++;starty++;
                 endx++;endy++;
                 break;
       case 60:     /* F2:       */
                 startx = x;
                 starty = y;
                 endx = ex;
                 endy = ey;
                 ch = 59;
             }

             /*      */
             if(startx<0) {
               startx++;
               endx++;
             }
             if(endx>%) {
               startx--;
               endx--;
             }
             if(starty<0) {
               starty++;
- - -                                                        - - - 

                                - 057 -

               endy++;
             }
             if(endy>y) {
               starty--;
               endx--;
             }
             /*      */
             deactivate(num);
             frame[num].startx = startx;
             frame[num].starty = starty;
             frame[num].endx = endx;
             frame[num].endy = endy;
             /*      */
             window(num);
             } while(ch!Y);  /* F1    */
           deactivate(num);
         }

              size(),      move()
               F1.
                 
          ,      .
             F2,
             . 
         ,    ,    
            .



            ,   
     -----------------------------------------------------------------

               ,     -
          . 
                ,
             .  
     ,         prinf(),
       ,   ,  ,     
        .         
      ,       , 
               -    sprintf()    
            ,
                window_puts
     ().         ,   
         .        window_gets()  
     ,               
     - sscanf(),    
       .

                         
     ,   ,       .
          main()    ,
         .   
       ,  .

- - -                                                        - - - 

                                - 058 -



                       
                    .
     -----------------------------------------------------------------

         /* -  */
         void dectohex()
         {
           char in[80], out[80]
           int n;

           window(1);
           do {
             window_xy(1, 0, 0)  /*     */
             window_cleol(1);    /*   */

             window_puts(1, "dec: "); /*  */
             window_gets(1, in);      /*   */
            window_putchar(1,  '\n'); /*     */
             window_cleol(1);          /*   */
          sscanf(in,"%d", &n); /*     */
             sprintf(out, "%s%X", "hex: ",n);  /*  
                                    */
            window_puts(1, out); /*    */
           } while(*in);
           deactivate(1);
         }

               ,        
            ,  
      ,               
       .                 
     .





                  .
     -----------------------------------------------------------------
                       
                 .  
        .   , 
             ,   
      (..  ).    . 
             .
               ,    
         .  ,   , 
       (10+5)/5,      10, 
     5,   +.   ,  15,  
           .     5   
     /.      3.     100 .
            . 
     calc(),     push()  pop()    
      .            
      ,        , 
         .

- - -                                                        - - - 

                                - 059 -

         #define MAX 100
         int *p;  /*   */
         int *tos;  /*    */
         int *bos;  /*    */

     /* ,      
         */
         void calc()
         {
           chra in[80], out[80];
           int answer, stack[MAX];
           int a,b;

           p = stack;
           tos = p;
           bos = p+MAX-1;

           window(2);
           do {
              window_xy(2, 0,0);
              window_cleol(2);
              window_puts(2, ": "); /*   */
              window_gets(2, in);
              window_puts(2, "\n ");
              window_cleol(2);
              switch(*in) {
                case '+':
                  a = pop();
                  b = pop();
                  answer = a+b;
                  push(a+b);
                  break;
                case '-':
                  a = pop();
                  b = pop();
                  answer = b-a;
                  push(b-a);
                  break;
                case '*':
                  a = pop();
                  b = pop();
                  answer = b*a;
                  push(b*a;
                  break;
                case '/':
                  a = pop();
                  b=pop();
                  if(a==0) {
                      window_putch("divide by 0\n");
                      break;
                    }
                    answer = b/a;
                    break;
                  default:
                    push(atoi(in));
                    continue;
                  }
                  sprintf(out, "%d", answer);
                  window_puts(2, out);
                } while(*in);
- - -                                                        - - - 

                                - 060 -

                deactivate(2);
              }

            /*    .   1    
               0,    */
              push(i)
              int i;
              {
                if(p>bos) return 0;
                *p=i;
                p++;
                return 1;
              }

              /*     .   0, 
                   */

              pop()
              {
                p--;
                if(p<tos) {
                  p++;
                  return 0;
                }
                return *p;
             }



                 
     -----------------------------------------------------------------

                
        " ".   
              .
     ,    ,   , 
               ,     .  
                   "
     ".


         #include "ctype.h"

         /*    */
         #define MAX_NOTE 10
         #define BKSP 8
         char notes[MAX NOTE][80];

         void notepad()
         {
           static firs=1;
           register int i, j;
           union inkey {
             char ch[2];
             int i;
           } c;
           char ch;

           /*   ,    */
           if(frist) {
- - -                                                        - - - 

                                - 061 -

             for(i=0; i<MAX_note; i++)
               *note[i] = '\0';
             frist = !frist;
           }
           window(3);
           /*      */
           for(i=0; i<MAX_note; i++)  {
             if(*notes[i]) window_puts(3, notes[i]);
             window_putcar(3, '\n');
           }
           i=0;
           window_xy(3, 0, 0);
           for(;;) {
             c.i = window_getche(3);  /*  ,  
                                                          */
             if(tolower(c.ch[1])=Y {  /*  F1 -  */
               deactivate(3);
               break;
             }
             /*   ,      */
             if(isprint(c.ch[0]) || c.ch[0]==BKSP) {
               window_cleol(3);
               notes[i][0] = c.ch[0];
               j = 1;
               window_putchar(3, notes[i][0]);
               do {
                 ch = window_getche(3);
                 if(ch==BKSP) {
                   if(j>0) {
                     j--;
                     window_bksp(3);
                   }
                 }
                 else {
                   notes[i][j] = ch;
                   j++;
                 }
                 } while(notes[i][j-1]!='\r');
                 notes[i][j-1] = '\0';
                 i++;
                 window_putchar(3, '\n');
               }
               else {             /*    */
                 switch(c.ch[1]) {
                   case 72:       /*   */
                     if(i>0) {
                       i--;
                       window_upline(3);
                     }
                     break;
                   case 80:       /*   */
                     if(i<MAX_NOTE-1) {
                       i++;
                       window_dowline(3);
                     }
                     break;
                   }
                 }
               }
             }
- - -                                                        - - - 

                                - 062 -

           notepad()          .  
       UP ARROW  DOWN ARROW        
       .    ,    
       ,      .        
     " "   F1.



                  
     -----------------------------------------------------------------

              ,    
                        
     ,     1,    
     ,      .        
                    
                
            .      
          .


         /*      
         .   .  
               ,
           .   :
           4- , -
             .    */
         #include "stdio.h"
         #include "dos.h"
         #include "stdlib.h"

         #define BORDER 1
         #define ESC 27
         #define MAC_FRAME 10
         #define REV_VID 0x70
         #define NORM_VID 7
         #define BKSP 8

         void save_video(), restore_video(), pd_driver();
         void goto_xy(, cls(), write_string(), write_char();
         void display_header(), draw_border();
         void window_gets(), size(), move(), window_cls();
         void window_cleol(), window();
         void dectohex(), notepad(), calc();

         char far *vid_mem;

         struct window_frame {
           int startx, endx, starty, endy;
           int curx, cury;
           unsigned char *p;
           char *header;
           iht border;
           int active;
         } frame[MAX_FRAME];


         main()
         {
           union inkey {
- - -                                                        - - - 

                                - 063 -

           char ch[2];
           int i;
         } c;
         int i;
         char ch;

         cls();
         goto_xy(0,0);

         /*  ,    */
      make_window(0, " Editor [Esc to exit] ", 0, 0, 24, 78, BORDER);
      make_window(1, " Decimal to Hex ", 7, 40, 10, 70, BORDER);
      make_window(2, " Calculator ", 8, 20, 12, 60, BORDER);
      make_window(3, " Notepad [F1 to exit] ", 5, 20, 17, 60, BORDER);

         /*  window()     */
         window(0);
         do {
           c.i = window_getche(0);
           ch = c.i;      /*     */
           if(ch=='\r')   /*     
                                              */
               window_putchar(0, '\n');

           switch(c.ch[1]) {   /* .    
                                    */
             case 59: /* F1    window() */
               window(1);
               for(i=0; i<10; i++)
                 if(window_xy(1, i, i)) window_putchar(1,'X');
                 getch();
                 deactivate(1);
                 break;
                 case 60: /* F2    
                                                     */
                 size(1);
                 move(1);
                 break;
               case 61:  /* F3   */
                 calc();
                 break;
               case 62:    /* F4  -
                                */
                 dectohex();
                 break;
               case 63:  /*  F5    */
                 notepad();
                 break;
                 case 72:  /*  */
                 window_upline(0);
                 break;
               case 80:    /*  */
                 window_downline(0);
                 break;

               }
             } while (ch!=ESC);
             deactivate(0);  /*   */
           }

- - -                                                        - - - 

                                - 064 -


         /***********************************************************/
         /*                                           */
         /***********************************************************/

         /*      */
         void window(num)
         int num;  /*   */
         {
           int vmode, choice;
           int x, y;

           vmode = video_mode();
           if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
             printf("video must be in 80 column text mode");
             exit(1);
           }
           /*     */
           if(vmode==7) vid_mem = (char far *) 0xb0000000;
           else vid_mem = (char far *) 0xb0000000;

           if(!frame[num].active) {  /*   */
             save_video(num);/*     */
             frame[num].active = 1;  /*    */
           }

           if(frame[num].border) draw_border(num);
           dispay_header(num);     /*     */

           x = frame[num].startx + frame[num].curx + 1;
           y = frame[num].starty + frame[num].cury + 1;
           goto_xy(x, y);

         }


         /*    .  1,  
              0    */

         make_window(num, header, startx, starty, endx, endy, border)
         int num;         /*   */
         char *header;    /*   */
         int startx, starty; /*  x,y    */
         int endx, endy;     /*  x,y    */
         int border;           /*  ,  0 */
         {
           unsigned char *p;

           if(num>MAX_FRAME) {
             printf("Too many windows\n");
             return 0;
           }

         if((startx>24) || (startx<0) || (starty>78) || (starty<0)) {
             printf("range error");
             return 0:
           }

           if((endx>24) || (endy>79)) {
             printf("window won't fit");
- - -                                                        - - - 

                                - 065 -

             return 0;
           }

           /*     */
      p = (unsigned char *) malloc(2*(endx-startx+1)*(endy-starty=1));
     if(!p) exit(1);/*     */

           /*   */
           frame[num].startx = startx; frame[num].endx = endx;
           frame[num].starty = starty; frame[num].endy = endy;
           frame[num].p = p;
           frame[num].header = header;
           frame[num].border = border;
           frame[num].active = 0;
           frame[num].curx = 0; frame[num].cury = 0;
           return 1;
         }

         /*        */
         deactivate(num)
         int num;
         {

           /*       */
           frame[num].curx = 0;
           frame[num].cury = 0;
           restore_video(num);
         }

         /*     */
         void size(num)
         int num;
         {
           char ch;
           int x, y, startx, starty;

           /* ,   */
           if(!frame[num].active) window(num);

           startx = x = frame[num].startx;
           starty = y = frame[num].starty;
           window_xy(num, 0, 0);

           do {
             ch = get_special();
             switch(ch) {
               case 75:    /*  */
                 starty--;
                 break;
               case 77:    /*  */
                 starty++;
                 break;
               case 72:    /*  */
                 startx--;
                 break;
               case 80:    /*  */
                 startx++;
                 break;
               case 71:    /*   */
                 startx--; starty--;
- - -                                                        - - - 

                                - 066 -

                 break;
               case 73:    /*   */
                 startx--; starty++;
                 break;
               case 79:    /*   */
                 startx++; starty--;
                 break;
               case 81:    /*   */
                 startx++; starty++;
                 break;
               case 60:    /* F2:     
                                                          */
                 startx = x;
                 starty = y;
                 ch = 59;
             }

             if(startx<0) startx++;
             if(startx>=frame[num].endx) startx--;
             if(starty<0) starty++;
             if(starty>=frame[num].endy) starty--;
             deactivate(num);
             frame[num].startx = startx;
             frame[num].starty = starty;
             window(num);
           } while(ch!Y);
           deactivate(num);
         }


         /*    */
         void move(num)
         int num;
         {
           char ch;
           int x, y, ex, ey, startx, starty, endx, endy;

           /* ,   */
           if(!frame[num].active) window(num);

           startx = x = frame[num].startx;
           starty = y = frame[num].starty;
           endx = ex = frame[num].endx;
           endy = ey = frame[num].endy;
           window_xy(num, 0, 0);

           do {
             ch = get_special();
             switch(ch) {
               case 75:   /*  */
               starty--;
               endy--;
               break;
               case 77:   /*  */
               starty++;
               endy++;
               break;
               case 72:   /*  */
               startx--;
               endx--;
- - -                                                        - - - 

                                - 067 -

               break;
               case 80:   /*  */
               startx++;
               endx++;
               break;
               case 71:   /*   */
               startx--; starty--;
               endx--; endy--;
               break;
               case 73:   /*   */
               startx--; starty++;
               endx--; endy++;
               break;
               case 79:   /*   */
               startx++; starty--;
               endx++; endy--;
               break;
               case 81:   /*   */
               startx++; starty++;
               endx++; endy++;
               break;
               case 60:    /* F2:     
                                                          */
                 startx = x;
                 starty = y;
                 endx = ex;
                 endy =ey;
                 ch = 59;
         }

         /* .     */
         if(startx<0) {
           startx++;
           endx++;
         }
         if(endx>%) {
           startx--;
           endx--;
           }
           if(starty<0) {
             starty++;
             endy++;
           }
           if(endy>y) {
             starty--;
             endy--;
           }
           deactivate(num);
           frame[num].startx = startx;
           frame[num].starty = starty;
           frame[num].endx = endx;
           frame[num].endy = endy;
           window(num);
         } while(ch!Y);
         deactivate(num);
       }


- - -                                                        - - - 

                                - 068 -

         /*   ,     */
         void display_header(num)
         int num;
         {
           register int y, len;

           y = frame[num].starty;

           /*      
           ,  ,     */
           len = strlen(frame[num].header);
           len = (frame[num].endy - y - len) / 2;
           if(len<0) return;  /*     */
           y = y + len;

           write_string(frame[num].startx, y,
                      frame[num].header, NORM_VID);
         }

         void draw_border(num)
         int num;
         {
           register int i;
           char far *v, far *t;

           v = vid_mem;
           t = v;
           for(i=frame[num].startx+1; i<frame[num].endx; i++) {
           v += (i*160) + frame[num].starty*2;
           *v++ = 179;
           *v = NORM_VID;
           v = t;
           v += (i*160) + frame[num].endy*2;
           *v++ = 179;
           *v = NORM_VID;
           v = t;
         }
         for(i=frame[num].starty+1; i<frame[num].endy; i++) {
            v += (frame[num].startx*160) + i*2;
            *v++ = 196;
            *v = NORM_VID;
            v = t;
            v+ =(frame[num].endx*160) + i*2;
            *v++ = 196;
            *v = NORM_VID;
            v = t;
         }
      write_char(frame[num].startx, frame[num].starty, 218, NORM_VID);
      write_char(frame[num].startx, frame[num].endy, 191, NORM_VID);
      write_char(frame[num].endx, frame[num].starty, 192, NORM_VID);
         write_char(frame[num].endx, frame[num].endy, 217, NORM_VID);

         }


- - -                                                        - - - 

                                - 069 -

     /***************************************************************/
     /*     /                              */
     /***************************************************************/

     /*         .
         0,      1   . */
         window_puts(num, str)
         int num;
         char *str;
         {

           /* ,    */
           if(!frame[num].activite) return 0;

           for( ; *str; str++)
             window_putchar(num, *str);
           return 1;
         }

      /*         .
          0,      1    */
         window_putchar(num, ch)
         int num;
         char ch;
         {
           register int x, y;
           char far *v;

           /* ,    */
           if(!frame[num].active) return 0;

           x = frame[num].curx + frame[num].startx + 1;
           y = frame[num].cury + frame[num].starty + 1;

           v = vid_mem;
           v += (x*160) + y*2;  /*   */
           if(y>=frame[num].endy) {
             return 1;
           }
           if(x>=frame[num].endx) {
             return 1;
           }
           if(ch=='\n') {   /*      */
             x++;
             y = frame[num].startx+1;
             v = vid_mem;
             v += (x*160) + y*2;  /*   */
             frame[num].curx++;   /*  x */
             frame[num].cury = 0; /*  y */
           }
           else {
             frame[num].cury++;
             *v++ = ch;  /*   */
             *v++ = NORM_VID; /*   */
           }
           window_xy(num, frame[num].curx, frame[num].cury);
           return 1;
         }

- - -                                                        - - - 

                                - 070 -


         /*      .
             0    ,    
             */
         window_xy(num, x, y)
         int num, x, y;
         {
           if(x<0 || x+frame[num].startx>=frame[num].endx-1)
             return 0;
           if(y<0 || y+frame[num].starty>=frame[num].endy-1)
             return 0;
           frame[num].curx = x;
           frame[num].cury = y;
           goto_xy(frame[num].startx+x+1, frame[num].starty+y+1);
           return 1;
         }

         /*     */
         void window_gets(num, s)
         int num;
         char *s;
         {
           char ch, *temp;

           temp = s;
           for(,,) {
             ch = window_getche(num);
             switch(ch) {
               case '\r':  /*   ENTER */
                 *s='\0';
                 return;
               case BKSP:  /*  */
                 if(s>temp) {
                   s--;
                   frame[num].cury--;
                   if(frame[num].cury<0) frame[num].cury = 0;
                     window_xy(num, frame[num].curx, frame[num].cury);
                      write_char(frame[num].startx+ frame[num].curx+1;
                  frame[num].starty+frame[num].cury+1, ' ', NORM_VID);
                 }
                 break;
               default: *s = ch;
                 s++;
             }
           }
         }



         /*      .
              16-  - */
         window_getche(num)
         int num;
         {
            union inkey {
              char ch[2];
              int i;
             } c;

             if(!frame[num].active) return 0;  /*    */
- - -                                                        - - - 

                                - 071 -


             window_xy(num, frame[num].curx, frame[num].cury);

             c.i = bioskey(0);   /*     */

             if(c.ch[0]) {
               switch(c.ch[0]) {
                 case '\r':    /*   ENTER */
                   break;
                 case BKSP:   /* */
                   break;
                 default:
           if(frame[num].cury+frame[num].starty < frame[num].endy-1) {
           write_char(frame[num].startx+ frame[num].curx+1,
           frame[num].starty+frame[num].cury+1, c.ch[0], NORM_VID);
                     frame[num].cury++;
                   }
               }
            if(frame[num].curx < 0) frame[num].curx = 0;
            if(frame[num].curx+frame[num].startx > frame[num].endx-2)
                 frame[num].curx--;
               window_xy(num, frame[num].curx, frame[num].cury);
             }
             return c.i;
           }

           /*   */
           void window_cls(num)
           int num;
           {
             register int i,j;
             char far *v, far *t;

             v = vid_mem;
             t = v;
             for(i=frame[num].starty+1; i<frame[num].endy; i++)
               for(j=frame[num].startx+1; j<frame[num].endy; j++) {
                 v = t;
                 v += (j*160) + i*2;
                 *v++ = ' ';    /*   */
                 *v = NORM_VID; /*   */
             }
             frame[num].curx = 0;
             frame[num].cury = 0;
           }

           /*     */
           void window_cleol(num)
           int (num);
           {
           register int i, x, y;

           x = frame[num].curx;
           y = frame[num].cury;
           window_xy(num, frame[num].curx, frame[num].cury);

           for(i=frame[num].cury; i<frame[num].endy-1; i++)
             window_putchar(num,' ');
           window_xy(num, x, y);
         }
- - -                                                        - - - 

                                - 072 -



         /*      .
                 , 0 -  
            . */
         window_upline(num)
         int num;
         {
           if(frame[num].curx>0) {
             frame[num].curx--;
             window_xy(num, frame[num].curx, frame[num].cury);
             return 1;
           }
           return 0;
         }


         /*      .
                 , 0 -  
            . */

         window_dowline(num)
         int num,
         {
           if(frame[num].curx<frame[num].endx-frame[num].startx-1) {
             frame[num].curx++;
             window_xy(num, frame[num].curx, frame[num].cury);
             return 1;
           }
           return 1;

           /*   
           window_bksp(num)
           int (num);
           {
           if(frame[num].cury>0) {
             frame[num].cury--;
             window_xy(num, frame[num].curx, frame[num].cury);
             window_putchar(num, ' ');
             frame[num].cury--;
             window_xy(num, frame[num].curx, frame[num].cury);
           }
         }


     /***************************************************************/
     /*                                        */
     /***************************************************************/

         /*        */
         void write_strihg(x, y, attrib)
         int x, y;
         char *p;
         int attrib;
         {
           register int i;
           char far *v;

           v = vid_mem;
           v += (x*160) + y*2; /*   */
- - -                                                        - - - 

                                - 073 -

           for(i=y; i++) {
             *v++ = *p++;  /*   */
             *v++ = attrib; /*   */
           }
         }

         /*      */
         void write_char(x, y, ch, attrib)
         int x, y;
         char ch;
         int attrib;
         {
           register int i;
           char far *v;

           v = vid_mem;
           v += (x*160) + y*2;
           *v++ = ch;   /*   */
           *v = attrib; /*   */
         }

         /*     */
         void save_video(num)
         int num;
         {
           register int i, j;
           char *buf_ptr;
           char far *v, far *t;

           buf_ptr = frame[num].p;
           v = vid_mem;
           for(i=frame[num].starty; i<frame[num].endy+1; i++)
             for(j=frame[num].startx; j<frame[num].endx+1; j++) {
               t = (v + (j*160) + i*2);
               *buf_ptr++ = *t++;
               *buf_ptr++ = *t;
               *(t-1) = ' ';  /*   */
             }
         }


         /*     */
         void restore_video(num)
         int num;
         {
           register int i,j;
           char far *v, far *t;
           char *buf_ptr;

           buf_ptr = frame[num].p;
           v = vid_mem;
           t = v;
           for(i=frame[num].starty; i<frame[num].endy+1; i++)
             for(j=frame[num].startx; i<frame[num].endx+1; j++) {
               v = t;
               v += (j*160) + i*2;
               *v++ = buf_ptr++;   /*   */
               *v = *buf_ptr++;    /*   */
           }
           frame[num].active = 0;
- - -                                                        - - - 

                                - 074 -

         }

         /*   */
         void cls()
         {
           union REGS r;
           r.h.ah=6;   /*    */
           r.h.al=0;   /*    */
           r.h.ch=0;   /*   */
           r.h.cl=0;   /*   */
           r.h.dh$;  /*   */
           r.h.dly;  /*   */
           r.h.bh=7;   /*   -  */
           int86(0x10, &r, &r);
         }

         /*       x, y */
         void goto_xy(x,y)
         int x,y;
         {
           union REGS r;

           r.h.ah=2; /*    */
           r.h.dl=y; /*   */
           r.h.dh=x; /*   */
           r.h.bh=0; /*   */
           int86(0x10, &r, &r);
         }

     /*        */
         get_special()
         {
           union inkey {
             char ch[2];
             int i;
           } c;

           /* while(!bioskey(1)) ; /*    */
           c.i = bioskey(0);       /*     */

           return c.ch[1];
         }

         /*     */
         video_mode()
         {
           union REGS r;

           r.h.ah = 15;  /*    */
           return int86(0x10, &r, &r) & 255;
         }

         is_in(s, c)
         char *s, c;
         {
           register int i;

           for(i=0; *s; i++) if(*s++==c) return i+1;
           return 0;
         }
- - -                                                        - - - 

                                - 075 -



         #include "ctype.h"
     /***************************************************************/
     /*                          */
     /***************************************************************/

         #define MAX 100

         int *p;  /*   */
         int *tos; /*    */
         int *bos; /*    */


     /* ,      4- */
         void calc()
         {
           char in[80], out[80];
           int answer, stack[MAX];
           int a,b;

           p = stack;
           tos = p;
           bos = P+MAX-1;

           window(2);
           do {
             window_xy(2, 0, 0);
             window_cleol(2);
             window_puts(2, ": "); /*   */
             window_gets(2, in);
             window_puts(2, "\n");
             window_cleol(2);
             switch(*in) {
               case '+':
                 a = pop();
                 b = pop();
                 answer = a+b;
                 push(a+b);
                 break;
               case '-':
                 a = pop();
                 b = pop();
                 answer = b-a;
                 push(b-a);
                 break;
               case '*':
                 a = pop();
                 b = pop();
                 answer = b*a;
                 push(b*a);
                 break;
                 case '/':
                   a = pop();
                   b=pop();
                   if(a==0) {
                       window_puts("divide by 0\n");
                       break;
                   }
                   ansver = b/a;
- - -                                                        - - - 

                                - 076 -

                   push(b/a);
                   break;
                 default:
                   push(atoi(in));
                   continue;
               }
               sprintf(out, "%d", answer);
               window_puts(2, out);
             } wile(*in);
             deactivate(2);
           }


           /*    .
               1     0    */
           push(i)
           int i;
           {
             if(p>bos) return 0;

             *p=i;
             p++;
             return 1;
           }


           /*     .
               0    */
           pop()
           {
             p--;
             if(p<tos) {
               p++;
               return 0;
             }
             return *p;
           }


           /* -  */
           void dectohex()
           {
             char in[80], out[80];
             int n;

             window(1);
             do {
     window_xy(1, 0, 0);  /*     */
     window_cleol(1);     /*   */
     window_puts(1, "dec: ");  /*  */
     window_gets(1, in);       /*   */
     window_putchar(1, '\n');  /*     */
     window_cleol(1);          /*   */
     sscanf(in,"%d", &n);      /*    */
     sprintf(out, "%s%X", "hex: ",n); /*  
                                      */
            window_puts(1, out); /*    */
             } wile(*in);
             deactivate(1);
           }
- - -                                                        - - - 

                                - 077 -



           /*    */
           #define MAX_NOTE 10
           #define BKSP 8
           char notes[MAX_NOTE][80];

           void notepad()
           {
             static first=1;
             register int i; j;
             union inkey {
               char ch[2];
               int i;
             } c;
             char ch;

          /*   ,    */
             if(frist) {
               for(i=0; i<MAX_NOTE; i++)
                 *notes[i] = '\0';
               first = !first;
           }

           window(3);
           /*      */
           for(i=0; i<MAX_NOTE; i++) {
             if(*notes[i]) window_puts(3, notes[i]);
             window_putchar(3, '\n');
           }

           i=0;
           window_xy(3, 0, 0);

           for(;;) {
             c.i = bioskey(o);  /*    */
             if(tolower(c.ch[1])=Y) {  /* F1 -   */
               deactivate(3);
               break;
             }

             /*    */
             if(isprint(c.ch[0]) || c.ch[0]==BKSP) {
               window_cleol(3);
               notes[i][0] = c.ch[0];
               j = 1;
               window_putchar(3, notes[i][0]);
               do {
                 ch = window_getche(3);
                 if(ch==BKSP) {
                   if(j>0) {
                     j--;
                     window_bksp(3);
                       }
                     }
                     else {
                       notes[1][j] = ch;
                       j++;
                     }
                   } while(notes[i][j-1]!='\r');
- - -                                                        - - - 

                                - 078 -

                   notes[i][j-1] = '\0';
                   i++;
                   window_putchar(3, '\n');
                 }
                 else {    /*    */
                   switch(c.ch[1]) {
                     case 72:     /*   */
                       if(i>0) {
                         i--;
                         window_upline(3);
                       }break
                     case 80:     /*   */
                       if(i<MAX_NOTE-1) {
                         i++;
                         window_dowline(3);
                       }
                       break;
                   }
                 }
               }
             }


                      
     :

             F1 -    window_xy()
             F2 -      
             F3 -  
             F4 -        -
                  
             F5 -  " ".

           2-1, 2-2   2-3        
      .  . 2-4    
                    -
     .



                  
     -----------------------------------------------------------------

                  
                 ,  
         .        
        .    
         .

- - -                                                        - - - 

                                - 079 -

      Editor [Esc to exit] 
                                                                  
       To whom it may concern:                                    
                                                                  
       This is to inform you D. W. Porkbellies will no lohger     
       be providing its customers with the following products:    
                                                                  
                                                                  
                        Calculator    
                                                                
                        :                                       
                                                                
                                                                
                                                                
                                                                
                          
     

                          . 2-1  .

      Editor [Esc to exit] 
                                                                 
       To whom it may concern:                                   
                                                                 
       This is to inform you D. W. Porkbellies will no lohger    
       be providing its customers with the following products:   
                                                                 
                                                                 
                                   Decimal to Hex   
                                                               
                                   dec: 12                     
               . meat and oats fak hex: C                      
                                                               
               . lime cola drink p  
                                                                 
               . syrup coated sizzle links                       
                                                                 
                                                                 
     

         . 2-2  - .

      Editor [Esc to exit] 
                                                                
      To whom it may concern:                                   
                                                                
      This is to inform you D. W. Porkbellies will no lohger    
      be providi Notepad [F1 to exit]       
                                                              
                 call Sherry                                  
                 go to the store                              
                                                              
                                                              
                                                              
                                                              
                      
                                                                
     

              . 2-3      .
- - -                                                        - - - 

                                - 080 -





      Editor [Esc to exit] 
                                                               
      To whom it may concern:                                  
                                                               
      This is to inform you D. W. Porkbellies will no lohger   
      be providing its customers with the following products:  
                                                               
                   . meat and oats fake burgers                
                                                               
                   . lime cola drink pops                      
                                                               
                                                               
           Decimal to Hex  le links             
                                                             
                                                             
                                                             
                                
     



               . 2-4      
               - .

                   -  
             .        
          ,     .
             ,    
           .          
       .        
     ,              .  
            ,    
        .

                        ,   
       ,        
     .      ,       
     ,         .  
             ,   
      ,      .

          ,  ,     ,  
               
     .          
      .
- - -                                                        - - - 

                                - 081 -


                              3
                             -------

              ,        
                          
                     .
     -----------------------------------------------------------------
                    , 
                     
               
      ,         
           .      
     SR-.           
              , ..
      TSR-   .        
             -       
     ,          
     .

             SR-,  ,      
             ,
               
       IBM PC,     DOS.  
     ,        ,      
             Turbo  C,      
         .

          .      TSR-
         .  
              
     1.0                  
     .          
       .   ,     
      ,      .    ,    
                ,  
                        
      .     
     .  ,       60   100
              ,          
     .  ( ,           
     ).



                 TSR-?
     -----------------------------------------------------------------

          SR-          49 DOS, 
                 DOS.    
          ,  DOS   
     .  ,     
       .      
     TSR-   Sidekick  orland.

           TSR-       ,
           .  
             ,  
             .    TSR-,  
         ,           
- - -                                                        - - - 

                                - 082 -

          ,    
      TSR-    .



                   8086.
     -----------------------------------------------------------------

             8086      256  
        .     
        (ISR),     
         .     
        ,            
          ,  
                   
     .

                 0000:0000   
       1024  .         
         ,      32
      (4 ). ,      
         4  .    ISR-    
         ,          
       0     0000:0000,  
       1 -   0000:0004,  2 -  
      0000:0008  ..

              ,       
     .           
     ,       ,   ,
          .      
         IRET.



                      DOS  BIOS:
                    T   DOS.
     -----------------------------------------------------------------

                  ,  DOS 
        .   ,    
         DOS,     
      . ( ,  ,  DOS   
         ).  , 
            DOS, 
             .   
                    ,   
               DOS.    ,  
              
           1  2.

          BIOS        . ,
      16,      ,    
               -  .
            
     .      . 
     ,       ,    
           .       
             
     16  .
- - -                                                        - - - 

                                - 083 -


                  
         DOS    BIOS,      
      DOS  BIOS,     .
       ,     -  
     DOS   BIOS.  ,        malloc()
         DOS          
     .   ,  ,        
     ,            .  
     ,    TSR-           
               TSR-  
          .

           ,         TSR-   
     ""   ,            DOS   
     .     ,          
           
      DOS.      DOS ,    
         .    ,   
           .



                   .
     -----------------------------------------------------------------

            ANSI      ,     
              ,     
     interrupt                
     TSR-. (    
                       
     ,         ). ,
     ,      test()       
     .               , 
      . ,      
          ,   ,   
      .

     void interrupt test(bp, di, si, ds, es, dx, cx, bx,
                         ax, ip, cs, flags)
     unsigned bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags;
     {
         .
         .
         .
     }

            interrupt        
                   
        .           
       IRET          
     RET.

                        
     interrupt               ,   
                    
      TSR-.

                  interrupt,
              
- - -                                                        - - - 

                                - 084 -

     ,                   ,
         ,         
         .         
       IRET.         
             ,    
         .



                 TSR-
     -----------------------------------------------------------------

           TSR-       .  
             TSR-  
      DOS       
     .          ,   
         .      
           TSR-   
      .

          ,       ,       
     .               ,  
     ,   .   
              
      .  ,     TSR-
                   
     ,           "   "   
     "".           
               ,        
       .



                  .
     -----------------------------------------------------------------

           , ,    ""
      DOS,    5.    
         PT  SCR.       
      ,         
          TSR-.  ,  
       PT SCR    TSR-.

                 .
              
     2      .



                
     -----------------------------------------------------------------

                  
                 
     main().

     void interrupt tsr_ap(); /*     */
     main()
     {
       struct address {
- - -                                                        - - - 

                                - 085 -

         char far *p;
       } ;
       /*     */
       struct address far *addr = (struct address far *) 20;
       addr->p = (char far *) tsr_ap;
       set_vid_mem();
       tsr(2000);
     }

          TSR-        
       5  ,     
     TSR-.       
      .         
         DOS.     
     DOS   ,      
           S,      
      int86().   ,      ,
          ,      
        .   ,   ,
            .
       tsr_ap()             
     TSR-.          
     ,   5. (,   5
         20(45)  ,    
       4  .    TSR-  
        .      
                   ,   
         .

             ,     
           ,        
     .           ,  
             DOS.      
         vid_mem   
      set_vid_mem,  .

     set_vid_mem()
     {
       int vmode;
       vmode = video_mode();
       if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
         printf("video must be in 80 column text mode");
         exit (1);
       }
       /*     */
       if(vmode==7) vid_mem = (char far *) 0xB0000000;
       else vid_mem = (char far *) 0xB8000000;
     }

          ,         main()  ocy  
        tsr(),  .

     /*  ,    */
     tsr(size)
     unsigned size;
     {
       union REGS r;
       r.h.ah = 49; /*     */
       r.h.al = 0;  /*   */
       r.x.dx = size;
- - -                                                        - - - 

                                - 086 -

       int86(0x21, &r, &r);
     }

            size,    DX,  
     ,   DOS,     
     SR-.                16-
     .        ,    
           .        
              (  
      .EXE)  16,       2, 
             .         
       ,     
                     
              .  (    
       ,          ,
           ,           
     .                  
        ).      ,    
      AL,  .

                     in()  
       ,             
        .  ,    
              PT
     SCR.



                 TSR-
     -----------------------------------------------------------------

                  TSR-  
       interrupt.          
            window_main().

     /*      TSR- */
     void interrupt tsr_ap()
     {
       if(!busy) {
         busy = !busy;
         window_main();
         busy = !busy;
       }
     }

             busy    
     0.    TSR-    ,
     ,          
     .   busy        ,
           .   (      
       ,         
        ).

                   
         ,               
     TSR-.  -,      
     ,          ,
          .     
     ,     ,   
       ,    ,     
- - -                                                        - - - 

                                - 087 -

        ,      
     TSR-.         go_to_xy()  
                .   ,
       -  sscanf()  sprintf()    
      (  ,     ),      
           DOS.     
     i()  itoa().     
      .

     /* TSR-,     */
     #include "dos.h"
     #include "stdlib.h"

     #define BORDER 1
     #define ESC 27
     #define MAX_FRAME 1
     #define REV_VID 0x70
     #define NORM_VID 7
     #define BKSP 8
     void interrupt tsr_ap();
     void save_video(), restore_video();
     void write_string(), write_char();
     void display_header(), draw_border();
     void window_gets();
     void window_cleol(), window();
     void calc();
     char far *vid_mem;
     struct window_frame {
       int startx, endx, starty, endy;
       int curx, cury; /*      */
       unsigned char *p; /*   */
       char *header;    /*      */
       int border; /* /  */
       int active; /* /  */
     } frame[MAX_FRAME];
     char wp[4000]; /*       */

     /* busy   1,   ,  -  0 */
     char busy = 0;

     main()
     {
       struct address {
         char far *p;
       } ;
       /*     */
       struct address far *addr = (struct address far *) 20;
       addr->p = (char far *) tsr_ap;
       set_vid_mem();
       tsr(2000);
     }

     set_vid_mem()
     {
       int vmode;
       vmode = video_mode();
       if((vmode!=2) && (vmode!=3) && (vmode!=7)) {
         printf("video must be in &0 column text mode");
         exit(1);
         }
- - -                                                        - - - 

                                - 088 -

         /*     */
         if(vmode==7) vid_mem = (char far *) 0xB0000000;
         else vid_mem = (char far *) 0xB8000000;
     }

     /*      TSR- */
     void interrupt tsr_ap()
     {

         if(!busy) {
           busy = !busy;
           window_main();
           busy = !busy;
         }
      }

      /* ,    */
      tsr(size)
      unsigned size;
      {
        union REGS r;
        r.h.ah = 49;   /* ,    */
        r.h.al = 0;    /*   */
        r.x.ax = size;
        int86(0x21, &r, &r);
      }

        window_main()
      {
         /*  ,    */
         make_window(0, " Calculator ", 8, 20, 12, 60, BORDER);
         /*      window() */
         calc();
      }

     /*************************************************************/
     /*                                    */
     /*************************************************************/

      /*      */
      void window(num)
      int num; /*   */
      {

        int vmode, choice;
        int x, y;

        /*    */
        if(!frame[num].active)  { /*    */
          save_video(num);        /*    */
          frame[num].active = 1;  /*    */
        }

        if(frame[num].border) draw_border(num);
        display_header(num); /*   */
      }

      /*   
             ,  1;
           0.
- - -                                                        - - - 

                                - 089 -

      */
      make_window(num, header, startx, starty, endx, endy, border)
      int num; /*   */
      char *header;  /*   */

       int startx, starty; /*  X,Y    */
       int endx, endy; /*  X,Y    */
       int border;  /*    0 */
       {
         register int i;
         int choice, vmode;
         unsigned char *p;

         if(num>MAX_FRAME)   {
           window_puts(0, "Too many windows\n");
           return 0;
      }

      if((startx>24) || (starty>78) || (starty<0))  {
        window_puts(0, "range error");
        return  0;
      }

      if((endx>24) || (endy>79))  {
        window_puts(0, "window won't fit");
        return 0;
      }

      /*    */
      frame[num].startx = startx; frame[num].endx = endx;
      frame[num].starty = starty; frame[num].endy = endy;
      frame[num].p = wp;
      frame[num].header = header;
      frame[num].border = border;
      frame[num].active = 0;
      frame[num].curx = 0; frame[num].cury = 0;
      return 1;
      }

      /*        */
      deactivate(num)
      int num;
      {
        /*       */
        frame[num].curx = 0;
        frame[num].cury = 0;
        restore_video(num);
      }

      /*       */
      void display_header(num)
      int num;
      {
        register int i, y, len;

        y = frame[num].starty;

        /*      
             -     
        */
- - -                                                        - - - 

                                - 090 -

         len = strlen(frame[num].header);

         len = (frame[num].endy - y - len) / 2;
         if(len<0) return; /* don't display it */
         y = y +len;

         write_string(frame[num].startx, y,
        frame[num].header, NORM_VID);
      }

      void draw_border(num)
      int num;
      {
        register int i;
        char far *v, far *t;

        v = vid_mem;
        t = v;
        for(i=frame[num].startx+1; i<frame[num].endx; i++) {
           v += (i*160) + frame[num].starty*2;
           *v++ = 179;
           *v = NORM_VID;
           v = t;
           v += (i*160) + frame[num].endy*2;
           *v++ = 179;
           *v = NORM_VID;
           v = t;
      }
      for(i=frame[num].starty+1; i<frame[num].endy; i++) {
         v += (frame[num].startx*160) + i*2;
         *v++ = 196;
         *v = NORM_VID;
         v = t;
         v += (frame[num].endx*160) + i*2;
         *v++ = 190;
         *v = NORM_VID;
         v = t;
      }
      write_char(frame[num].startx, frame[num].starty, 218, NORM_VID);
      write_char(frame[num].startx, frame[num].endy, 191, NORM_VID);
      write_char(frame[num].endx, frame[num].starty, 192, NORM_VID);
      write_char(frame[num].endx, frame[num].endy, 217, NORM_VID);
      }

      /**************************************************************/
      /*    /                              */
      /**************************************************************/

      /*       
          .
          0    ;
          1   .
      */
      window_puts(num, str)
      int num;
      char *str;
      {
          /* ,    */
         if(!frame[num].active) return 0;

- - -                                                        - - - 

                                - 091 -

     for( ; *str; str++)
       window_putchar(num, *str);
     return 1;
          }

          /*      
              .
              0    ,
              1   .
          */
          window_putchar(num, ch)
          int num;
          char ch;
          {
            register int x, y;
            char far *v;

            /* ,    */
            if(!frame[num].active) return 0;

            x = frame[num].curx + frame[num].startx + 1;
            y = frame[num].cury + frame[num].starty + 1;

            v = vid_mem;
            v += (x*160) + y*2; /*   */
            if(y>=frame[num].endy) {
      return 1;
           }
           if(x>=frame[num].endx) {
      return 1;
          }
          if(ch=='\n') { /*      */
          x++;
          y = frame[num].startx+1;
          v = vid_mem;
          v += (x+160) + y*2; /*   */
          frame[num].curx++;  /*  X */
          frame[num].cury = 0; /*  Y */
        }
        else {
          frame[num].cury++;
          *v++ = ch;  /*   */
          *v++ = NORM_VID; /*    */
        }
        window_xy(num, frame[num].curx, frame[num].cury);
        return 1;
       }

       /*      .
           0    ;
              .
       */
       window_xy(num, x, y)
       int num, x, y;
       {

           if(x<0 || x+frame[num].startx>=frame[num].endx-1)
     return 0;
           if(y<0 || y+frame[num].starty>=frame[num].endy-1)
     return 0;
- - -                                                        - - - 

                                - 092 -

           frame[num].curx = x;
           frame[num].cury = y;
           return 1;
        }
        /*    . */
        void window_gets(num, s)
        int num;
        char *s;
        {
          char ch, *temp;

          temp = s;
          for(;;) {
            ch = window_getche(num);
            switch(ch) {
      case '\r':  /*   ENTER */
        *s='\0';
        return;
      case BKSP: /*  */
        if(s>temp) {
          s--;
          frame[num].cury--;
          if(frame[num].cury<0) frame[num].cury = 0;
            window_xy(num, frame[num].curx, frame[num].cury);
      write_char(frame[num].startx+ frame[num].curx+1,
          frame[num].starty+frame[num].cury+1, ' ', NORM_VID);
        }
        break;
      default:  *s = ch;
       s++;
            }
          }
        }

        /*      .
             16- -.
        /*
        window_getche(num)
        int num;
        {
          union inkey {
            char ch[2];
            int i;
          } c;

          if(!frame[num].active) return 0; /* window not active */
          window_xy(num, frame[num].curx, frame[num].cury);
          c.i = bioskey(0);    /*    */

       if(c.ch[0]) {
        switch(c.ch[0]) {
           case '\r': /*   ENTER */
     break;
           case BKSP: /*  */
             break;
           default:
     if(frame[num].cury+frame[num].starty < frame[num].endy-1) {
     write char(frame[num].startx+ frame[num].curx+1,
       frame[num].curx--;
     window_xy(num, frame[num].curx, frame[num].cury);
           }
- - -                                                        - - - 

                                - 093 -

           return c.i;
        }
        /*     */
        void window_cleol(num)
        int num;
        {
          register int i, x, y;
          x = frame[num].curx;
          y = frame[num].cury;
          window_xy(num, frame[num].curx, frame[num].cury);

          for(i=frame[num].cury; i<frame[num].endy-1; i++)
            window_putchar(num,' ');

          window_xy(num, x, y);
       }

       /*      .
               ;
             - 0.
       */
       window_upline(num)
       int num;
       {
         if(frame[num].curx>0) {
           frame[num].curx--;
           window_xy(num, frame[num].curx, frame[num].cury);
           return 1;
        }
        return 0;
      }

      /*      .
              ;
            - 0.
      */
      window_downline(num)

     int num;
     {
       if(frame[num].curx<frame[num].endx-frame[num].startx-1} {
         frame[num].curx++;
         window_xy(num, frame[num].curx, frame[num].cury);
         return 1;
       }
       return 1;
     }

     /*      */
     window_bksp(num)
     int num;
     {
       if(frame[num].cury>0) {
         frame[num].cury--;
         window_xy(num, frame[num].curx, frame[num].cury);
         window_putchar(num, ' ');
         frame[num].cury--;
         window_xy(num, frame{num}.curx, frame[num].cury);
       }
     }
- - -                                                        - - - 

                                - 094 -


     /********************************************************/
     /*                                 */
     /********************************************************/

     /*      */
     void write_string(x, y, p, attrib)
     int x, y;
     char *p;
     int attrib;
     {
       register int i;
       char far *v;
       v = vid_mem;
       v += (x*160) + y*2; /*   */
       for(i+y; *p; i++)  {
         *v++ = *p++;  /*   */
         *v++ = attrib;    /*   */
       }
     }

     /*      */
     void write_char(x, y, ch, attrib)
     int x, y;
     char ch;
     int attrib;
     {
       register int i;
       char far *v;

       v = vid_mem;
       v += (x*160) +y*2;
       *v++ = ch;  /*   */
       *v = attrib;    /*   */
     }

     /*     */
     void save_video(num)
     int num;
     {
       register int i,j;
       char far *v, far *t;
       char *but_ptr;

       but_ptr = frame[num].p;
       v = vid_mem;
       t=v;
       for(i=frame[num].starty; i<frame[num].endy+1; i++)
         for(j=frame[num].startx; j<frame[num].endx+1; j++) {
           t = (v + (j*160) + i*2);
           *buf_ptr++ = *t++;
           *buf_ptr++ = *t;
           *(t-1) = ' ';  /*   */
         }
     }

     /*     */
     void save_video(num)
     int num;
     {
- - -                                                        - - - 

                                - 095 -

       register int i,j;
       char far *v, far *t;
       char *but_ptr;

       but_ptr = frame[num].p;
       v = vid_mem;
       t=v;
       for(i=frame[num].starty; i<frame[num].endy+1; i++)
         for(j=frame[num].startx; j<frame[num].endx+1; j++) {
           v = t;
           v += (j*160) + i*2;
           *v++ = *but_ptr++;   /*   */
           *v = *but_ptr++;   /*   */
     }
     frame[num].active = 0; /*   */
          }

          /*     */
          video_mode()
          {
     union REGS r;

     r.h.ah ;  /*    */
     return int86(0x10, &r, &r) & 255;
     }

     /**********************************************************
              
     **********************************************************/

           #define MAX 100

           int *p;   /*   */
           int *tos; /*     */
           int *bos; /*    */

         char in[80], out[80];
         int stack[MAX];

         /* ,    
            */

         void calc()
         {
           int answer;
           int a, b;
           p = stack;
           tos = p;
           bos = p + MAX - 1;
           window(0);
           do {
             window_xy(0, 0, 0);
             window_cleol(0);
             window_puts(0, " : "); /*   */
             window_gets(0, in);
             window_puts(0, " \n ");
             window_cleol(0);
             switch(*in) {
               case '+ ':
                 a = pop();
- - -                                                        - - - 

                                - 096 -

                 b = pop();
                 answer = a + b;
                 push(a+b);
                 break;
       case '-':
                 a = pop();
                 b = pop();
                 answer = b-a;
                 push(b-a);
                 break;
               case '- ':
               a = pop();
               b = pop();
               answer = b*a;
               push(b*a);
               break;
             case '/ ':
               a = pop();
               b = pop();
               if(a==0) {
                   window_puts(0, "divide by 0\n");
                   break;
               }
               answer = b/a;
               push(b/a);
               break;
               default:
                 push(atoi(in));
                 continue;
            }
            itoa(answer, out, 10);
            window_puts(0, out);
        }   while(*in);
        deactivate(0);
     }

     /*    .
         1   ;
         0,   
     */
     push(i)
     int i;
     {
       if(p>bos) return 0;
       *p = i;
       p++;
       return 1;
     }

     /*    
         0,   .
     */
     pop()
     {
       p--;
       if(p<tos) {
         p++;
         return 0;
       }
       return *p;
- - -                                                        - - - 

                                - 097 -

     }

                 .  , 
       ,        .  
         PT SCR.



               .
     -----------------------------------------------------------------

                 ,    
         .  -,    
                TSR-.
     -,            .
     -,     " ",       
     .            TSR-   
        9      .    9
           .

               9      TSR-
          .  -,  
              ,  
       9,        ,    
      DOS .     
     60.  ,         TSR-  
         9      .     
     TSR-       
       .   ,     
       "  ",         
       TSR-.  ,  
       ,      
          TSR- .   ,
           ,  
       ,       TSR- 
         .

                       
     .    -,               
      .  -,    
            
     TSR-,                 
         " ".   
         TSR-          
           "",   " " (
      2),      .

          ,    ,     
     -   BIOS  .



                  ,   .
     -----------------------------------------------------------------

            ,      DOS      15
     ,   ,      
     .         9.
      ISR        
          .      DOS
- - -                                                        - - - 

                                - 098 -

       BIOS     ,    
     ,         .      
                 
     ,   ,      BIOS    DOS.  
     ,           
      TSR- ,    " ",
           .


                 0000:041 (1054
         ).       
       16- -,     15 
      30 .    32 , .. 
     -    RETURN       .
          ,      
            . 
           ,         .
              ,   
             DOS    BIOS.  
             0000:041C (1052   ..).
               
         ,       
      +30.  (       
        8086).      
         ,   .





                       .
     -----------------------------------------------------------------
              TSR-,        
     ,        .
          main(),   .
     main()
     {
       struct address {
         char far *p;
       } temp;
       /*    9 */
       struct address far *addr = (struct address far *) 36;
       /*    60 */
       struct address far *int9 = (struct address far *) 240;

       /*      
             60.    60 
          61   ,  TSR- 
           .
       */
       if(int9->p == (int9+1)->p) {
         int9->p = addr->p;
         addr->p = (char far *) tsr_ap;
       printf("tsr installed - F2 for note pad, F3 for calculator ");
       } else {
         printf ("tsr application already initialized\n ");
         exit(1);
     }  }
       set_vid_mem();
       tsr(2000);
- - -                                                        - - - 

                                - 099 -

     }

           ,       ,
                   
     .        ,        
             TSR-    
          60- ,     
             .    
         ,        
     ,    60   61.  (  61
         DOS).  DOS   
               
     .   ,      TSR-  
       ,      .



                   TSR-.
     -----------------------------------------------------------------

                   TSR- 
      ,       .
               60,   
                
     .             
     .         geninterrupt(),  
              ,      
     .       60      
         ,       
     ,   ,     " ". 
          ""   F2 
     F3    60  61 .  "
     "        ,    
        .     busy
           ,        
              ,   
                         
     -  .          
     ,              .
      tsr_ap()  .

     /*      TSR- */
     void interrupt tsr_ap()
     {
       char far *t = (char far *) 1050; /*    */
       geninterrupt(60);
       if(*t != *(t+2)) { /*    */
         t += *t - 30 + 5; /*     */
         if(*t == 60 || *t == 61) {
           bioskey(0); /*   F2/F5 */
           if(!busy) {
             busy = !busy;
           }
         }
       }
     }

            ,         window_main()
          " ",  ,  
          .
- - -                                                        - - - 

                                - 100 -


     /*   */
     window_main(which)
     int which;
     {
       union inkey {
         char ch[2];
         int i;
       } c;
       int i;
       char ch;

       /* -,    */
       make_window(0," Notepad [F1 to exit] ", 5, 20, 17, 60, BORDER);
       make_window(1, " Colculator ", 8, 20, 12, 60, BORDER);

       /*  window()     */
       switch(which) {
         case 60:
           notepad();
           break;
         case 61:
           calc();
           break;
       }
     }

                           
     .    ,     ,   F2 
         "  ",        F3   -
     "".

     /* ,     
          9  .
     */
     #include "dos.h "
     #include "stdlib.h "
     #include "ctype.h "

     #define BORDER 1
     #define ESC 27
     #define MAX_FRAME 2
     #define REV_VID 0x70
     #define NORM_VID 7
     #define BKSP 8

     void interrupt tsr_ap();
     void save_video(), restore_video();
     void write_string(), write_char();
     void display_header(), draw_border();
     void window_gets();
     void window_cleol(), window();
     void notepad(), calc();

     char far *vid_mem;
     char wp[4000]; /*    
                         */
     struct window_trame {
       int startx, endx, starty, endy;
       int curx, cury; /*      */
- - -                                                        - - - 

                                - 101 -

       unsigned char *p; /*    */
       char *header; /*   */
       int border; /* /  */
       int active; /* /    */
     } frame [MAX_FRAME];
     char in[80], out[80];

     /* busy   1,  ,  -  0 */
     char busy = 0;
     main()
     {
     struct adaress {
       char far *p;
       }temp;

     /*     9 */
     struct address far *addr = (struct address far *) 36;
     /*     60 */
     struct address far *int9 = (struct address far *) 240;

     /*       
           60.    60  61
          ,  TSR-   .
     */
     if (int9->p == (int9+1)->p) {
     int9->p = addr->p;
     addr->p = (char far *) tsr_ap;
     printf ("tsr installed - F2 for note pad, F3 for calculator");
     } else {
     printf ("tsr application already initialized\n");
     exit (1);
     }
     set_vid_mem();
     tsr (800);
     }
     set_vid_mem()
     {
       int vmode;
       vmode = video_mode();
       if(( vmode != 2) && ( vmode != 3) && ( vmode != 7))  {
         printf("video must be in 80 column text mode");
         exit(1);
       }
       /*     */
       if(vmode==7) vid_mem = (char far *) 0xB0000000;
       else vid_mem = (char far *) 0xB8000000;
     }

     /*      TSR- */
     void interrupt tsr_ap()
     {
       char far *t = (char far *) 1050; /*    */
       geninterrupt(60);/*   */
       if(*t != *(t+2)) { /*    */
       t += *t-30+5; /*     */
       if(*t == 60 || *t == 61)  {
       bioskey(0); /*   F2/F3 */
       if(!busy) {
         busy = !busy;
         window_main(*t);
- - -                                                        - - - 

                                - 102 -

         busy = !busy;
        }
       }
      }
     }

     /*     */
     tsr(size)
     unsigned size;
     {
       union REGS r;
       r.h.ah = 49;  /*     */
       r.h.al = 0;  /*   */
       r.x.dx = size;  /*  /16 */
       int86(0x21, &r, &r);
     }

     /*   */
     window_main(which)
     int which;
     {
       union inkey  {
         char ch[2];
         int i;
       } c;
       int i;
       char ch;

       /* -,    */
      make_window(0, " Notepad [F1 to exit] ", 5, 20, 17, 60, BORDER);
      make_window(1, " Calculator ", 8, 20, 12, 60, BORDER);

       /*  window()     */
       switch(which)  {
         case 60:
           notepad();
           break;

           case 61:
             calc();
             break;
        }
     }

     /***************************************************************/
     /*                                      */
     /***************************************************************/

     /*    */
     void window(num)
     int num; /*   */
     {
       /*    */
       if(!frame[num].active)  {  /*    */
         save_video(num);         /*    */
         frame[num].active = 1;  /*    */
         }
         if(frame[num].border) draw_border(num);
         display_header(num); /*   */
     }
- - -                                                        - - - 

                                - 103 -


     /*    .
            ,  1,
            0.
     */

     make_window(num, header, startx, starty, endx, endy, border)
     int num;     /*   */
     char *header;   /*   */
     int startx, starty;  /*  X,Y    */
     int endx, endy;  /*  X,Y    */
     int border;     /*    0 */
     {
       register int i;
       int choice, vmode;
       unsigned char *p;

       if(num>MAX_FRAME)  {
         window_puts(0, "Too many windows\n");
         return 0;
       }
       if((startx>24) || (startx<0) || (starty>78) || (starty<0)) {
         window_puts(0, "range error");
         return 0;
       }
       if((endx>24) || (endy>79)) {
         window_puts(0, "window won't fit");
         return 0;
       }


     /*     */
     p= (unsigned char *) malloc(2*(endx-startx+1)*(endy-starty+1));
       if(!p) exit(1); /*    
                            */

       /*   */
       frame[num].startx = startx; frame[num].endx = endx;
       frame[num].starty = starty; frame[num].endy = endy;
       frame[num].p = wp;
       frame[num].header = header;
       frame[num].border = border;
       frame[num].active = 0;
       frame[num].curx = 0;  frame[num].cury = 0;
       return 1;
     }

     /*        */
     deactivate(num)
     int num;
     {
        /*       */
        frame[num].curx = 0;
        frame[num].cury = 0;
        restore_video(num);
     }
     /*       */
     void display_header(num)
     int num;
     {
- - -                                                        - - - 

                                - 104 -

       register int i, y, len;
       y = frame[num].starty;

     /*    
         ,  , 
          .
     */
     len = strlen(frame[num].header);
     len = (frame[num].endy - y - len) / 2;
     if(len<0) return; /*    */
     y = y +len;
     write_string(frame[num].startx, y,
                  frame[num].header, NORM_VID);
     {
     void draw_border(num)
     int num;
     {
       register int i;
       char far *v, far *t;
       v = vid_mem;
       t = v;
       for(i=frame[num].startx+1; i<frame[num].endx; i++) {
          v += (i*160) + frame[num].starty*2;
          *v++ = 179;

        *v = NORM_VID;
         v = t;
         v += (i*160) + frame[num].endy*2;
         *v++ = 179;
         *v = NORM_VID;
         v = t;
     }
     for(i=frame[num].starty+1; i<frame[num].endy; i++) {
        v += (frame[num].startx*160) + i*2;
        *v++ = 196;
        *v = NORM_VID;
        v = t;
        v += (frame[num].endx*160) + i*2;
        *v++ = 196;
        *v = NORM_VID;
        v = t;
     }
     write_char(frame[num].startx, frame[num].starty, 218, NORM_VID);
     write_char(frame[num].startx, frame[num].endy, 191, NORM_VID);
     write_char(frame[num].endx, frame[num].starty, 192, NORM_VID);
     write_char(frame[num].endx, frame[num].endy, 217, NORM_VID);
     }

     /*************************************************************/
     /*   /                              */
     /*************************************************************/

     /*      
          .
         0,    ,
         1 -   .
     */
     window_puts(num, str)
     int num;
     char *str;
- - -                                                        - - - 

                                - 105 -

     {
        /* ,    */
       if(!frame[num].active) return 0;
       for( ; *str; str++)
         window_putchar(num, *str);
       return 1;
     }

     /*      
          
         0,    ,
         1 -   .
     */
     window_putchar(num, ch)
     int num;
     char ch;
     {
       register int x, y;
       char far *v;

        /* ,    */
       if(!frame[num].active) return 0;

       x = frame[num].curx + frame[num].startx + 1;
       y = frame[num].cury + frame[num].starty + 1;

       v = vid_mem;
       v += (x*160) + y*2; /*   */
       if(y>=frame[num].endy) {
         return 1;
       }
       if(x>=frame[num].endx) {
         return 1;
       }

       if(ch=='\n') { /*      */
         x++;
         y = frame[num].startx+1;
         v = vid_mem;
         v += (x*160) + y*2; /*   */
         frame[num].curx++; /*  X */
         frame[num].cury = 0; /*  Y */
       }
       else {
         frame[num].cury++;
         *v++ = ch; /*   */
         *v++ = NORM_VID; /*    */
       }
       window_xy(num, frame[num].curx, frame[num].cury);
       return 1;
     }

     /*      .
         0    ;
             .
     */
     window_xy(num, x, y)
     int num, x, y;
     {
       if(x<0 || x+frame[num].startx>=frame[num].endx-1)
- - -                                                        - - - 

                                - 106 -

         return 0;
       if(y<0 || y+frame[num].starty>=frame[num].endy-1)
         return 0;
       frame[num].curx = x;
       frame[num].cury = y;
       return 1;
     }

     /*     */
     void window_gets(num, s)
     int num;
     char *s;
     {
       char ch, *temp;
       char out[10];

          temp = s;
          for(;;) {
            ch = window_getche(num);
            switch(ch) {
              case '\r': /*   ENTER */
                *s='\0';
                return;
              case BKSP: /*    */
                if(s>temp) {
                s--;
                frame[num].cury--;
                if(frame[num].cury<0) frame[num].cury = 0;
                  window_xy(num, frame[num].curx, frame[num].cury);
                    write_char(frame[num].startx+ frame[num].curx+1,
                  frame[num].starty+frame[num].cury+1,' ',NORM_VID);
                }
                break;
              default: *s = ch;
                s++;
          }
        }
     }

     /*    .
          16- -
     */
     window_getche(num)
     int num;
     {
       union inkey {
         char ch[2];
         int i;
       } c;
       if(!frame[num].active) return 0; /*    */
       window_xy(num, frame[num].curx, frame[num].cury);
       c.i = bioskey(0);  /*    */
       if(c.ch[0]) {
         switch(c.ch[0]) {
           case'\r': /*   ENTER */
             break;
           case BKSP: /*    */
             break;
           default:
          if(frame[num].cury+frame[num].starty < frame[num].endy-1) {
- - -                                                        - - - 

                                - 107 -

          write_char(frame[num].startx+ frame[num].curx+1,
            frame[num].starty+frame[num].cury+1, c.ch[0], NORM_VID);
            frame[num].cury++;
             }
        }
        if(frame[num].curx < 0) frame[num].curx = 0;
        if(frame[num].curx+frame[num].startx > frame[num].endx-2)
        frame[num].curx--;

           window_xy(num, frame[num].curx, frame[num].cury);
         }
         return c.i;
     }

     /*     */
     void window_cleol(num)
     int num;
     {
       register int i, x, y;
       x = frame[num].curx;
       y = frame[num].cury;
       window_xy(num, frame[num].curx, frame[num].cury);
       for(i=frame[num].cury; i<frame[num].endy-1; i++)
         window_putchar(num,' ');
       window_xy(num, x, y);
     }

     /*      .
             
         0   .
     */
     window_upline(num)
     int num;
     {
       if(frame[num].curx>0) {
         frame[num].curx--;
         window_xy(num, frame[num].curx, frame[num].cury);
         return 1;
       }
       return 0;
     }

     /*      .
             
         0   .
     */
     window_downline(num)
     int num;
     {
     if(frame[num].curx<frame[num].endx-frame[num].startx-1) }
       frame[num].curx++;
       window_xy(num, frame[num].curx, frame[num].cury);
       return 1;
      }
      return 1;
     }

     /*     */
     window_bksp(num)
     int num;
- - -                                                        - - - 

                                - 108 -

     {
     if(frame[num].cury>0) {
       frame[num].cury--;
       window_xy(num, frame[num].curx, frame[num].cury);
       window_putchar(num, ' ');

          frame[num].cury--;
          window_xy(num, frame[num].curx, frame[num].cury);
        }
     }

     /***************************************************************/
     /*                                        */
     /***************************************************************/

     /*      */
     void write_string(x, y, p, attrib)
     int x, y;
     char *p;
     int attrib;
     {
       register int i;
       char far *v;

       v=vid_mem;
       v += (x*160) + y*2; /*   */
       for(i=y; *p; i++) {
         *v++ = *p++;  /*   */
         *v++ = attrib;  /*   */
       }
     }

     /*      */
     void write_char(x, y, ch, attrib)
     int x, y;
     char ch;
     int attrib;
     {
       register int i;
       char far *v;
       v = vid_mem;
       v += (x*160) + y*2;
       *v++ = ch;  /*   */
       *v = attrib;  /*   */
     }

     /*    */
     void save_video(num)
     int num;
     {
       register int i, j;
       char *buf_ptr;
       char far *v, far *t;
       buf_ptr = frame[num].p;
       v = vid_mem;
       for(i=frame[num].starty; i<frame[num].endy+1; i++)
         for(j=frame[num].startx; j<frame[num].endx+1; j++) {
           t = (v + (j*160) + i*2);
           *buf_ptr++ = *t++;

- - -                                                        - - - 

                                - 109 -

           *buf_ptr++ = *t;
           *(t-1) = ' '; /*   */
         }
     }

     /*    */
     void restore_video(num)
     int num;
     {
       register int i,j;
       char far *v, far *t;
       char *buf_ptr;
       buf_ptr = frame[num].p;
       v = vid_mem;
       t = v;
       for(i=frame[num].starty; i<frame[num].endy+1; i++)
         for(j=frame[num].startx; j<frame[num].endx+1; j++) {
           v = t;
           v += (j*160) + i*2;
           *v++ = *buf_ptr++; /*   */
           *v = *buf_ptr++;  /*   */
       }
       frame[num].active = 0;/*   */
     }

     /*     */
     video_mode()
     {
       union REGS r;
       r.h.ah = 15;  /*    */
       return int86(0x10, &r, &r) & 255;
     }

     /****************************************************/
     /*                            */
     /****************************************************/

     #define MAX 100

     int *p; /*   */
     int *tos; /*    */
     int *bos; /*    */
     int stack[MAX];

     /* ,    
       
     */
     void calc()
     {
       int answer;
       int a,b;
       p = stack;
       tos = p;
       bos = p+MAX-1;

            window(1);
            do {
              window_xy(1, 0, 0);
              window_cleol(1);
              window_puts(1, ": "); /*   */
- - -                                                        - - - 

                                - 110 -

              window_gets(1, in);
              window_puts(1, "\n ");
              window_cleol(1);
              switch(*in) {
                case '+':
                  a = pop();
                  b = pop();
                  answer = a+b;
                  push(a+b);
                  break;
                  case '-':
                    a = pop();
                    b = pop();
                    answer = b-a;
                    push(b-a);
                    break;
                  case '* ':
                    a = pop();
                    b = pop();
                    answer = b*a;
                    push(b*a);
                    break;
                  case '/ ':
                    a = pop();
                    b = pop();
                    if(a==0) {
                        window_puts(0, "divide by 0\n");
                        break;
                    }
                    answer = b/a;
                    push(b/a);
                    break;
                  default:
                    push(atoi(in));
                    continue;
               }
               itoa(answer, out, 10);
               window_puts(1, out);
           }   while(*in);
           deactivate(1);
     }
     /*    .
         1   
         0   
     */
     push(i)
     int i;
     {
       if(p>bos) return 0;
       *p = i;
       p++;

        return 1;
     }
     /*     .
         0   .
     */
     pop()
     {
       p--;
- - -                                                        - - - 

                                - 111 -

       if(p<tos) {
         p++;
         return 0;
       }
       return *p;
     }

     /**********************************************************/
     /*                               */
     #define MAX_NOTE 10
     #define BKSP 8
     char notes[MAX_NOTE] [80];
     void notepad()
     {
       static first = 1;
       register int i, j;
       union inkey {
         char ch[2];
         int i;
       } c;
       char ch;

       /*       */
       if(first) {
         for(i=0; i<MAX_NOTE; i++)
           *notes[i] = '\0 ';
         first = !first;
         }
         window(0);

       /*    */
         for(i=0; i<MAX_NOTE; i++) {
           if(*notes[i]) window_puts(0, notes[i]);
           window_putchar(0, '\n ');
           }
           i = 0;
           window_xy(0, 0, 0);

           for(;;) {
             c.i = bioskey(0);  /*    */
             if(tolower(c.ch[1])=Y) { /* F1   */
               deactivate(0);
               break;
             }

             /*    */
             if(isprint(c.ch[0]) || c.ch[0]==BKSP) {
               window_cleol(0);
               notes[i][0] = c.ch[0];
               j = 1;
               window_putchar(0, notes[i][0]);
               do {
                 ch = window_getche(0);
                 if(ch == BKSP) {
                   if( j>0 ) {
                   j--;
                   window_bksp(0);
                 }
               }
               else {
- - -                                                        - - - 

                                - 112 -

                 notes[i][j] = ch;
                 j++;
               }
             } while(notes[i][j-1]! = '\r ');
             notes[i][j-1] = '\0 ';
             i++;
             window_putchar(0, '\n ');
           }

           else { /*    */
             switch(c.ch[1]) {
               case 72: /*   */
                 if(i>0) {
                   i--;
                   window_upline(0);
                 }
                break;
              case 80: /*   */
                if(i<MAX_NOTE-1) {
                  i++;
                  window_downline(0);
                }
                break;
             }
          }
       }
     }



                      28- 
     -----------------------------------------------------------------

                 DOS,            
     ,           TSR-   
             ,       
      .   ,      
     TSR-           ,    
       .     
       ,      -
     .               
      ,   DOS   28,   
         "",  ..    .    
       ,          DOS,
             ,       
             .    28
           DOS        
     .          
      TSR-.       
     ,          
     .

           ,                
         28,      
        TSR-.   
     28,           TSR-         
           .  
                "
     "        (     
     is-hotkey).   ,      TSR-
- - -                                                        - - - 

                                - 113 -

       ,      
     28,    ,   is-hotkey  .
      ,     ,  
         is-hotkey.         
              28,  
     ,           28 
       28- .

               TSR-,   
           28  (      
     ),             
      DOS     .



                    TSR-
     -----------------------------------------------------------------

          TSR-              .
     ,      TSR-,     
     ,                
            TSR-,      
     ,                 
             9  
           .   ,         
     TSR-        ,   
     ,                   
     TSR-.



                                   4
                                  -------

                                  
     -----------------------------------------------------------------

                       ,
        (  )  ,  ,
     ,  ,      
      CGA  EGA.      , 
           .  
           
        ":   The  Complete  Reference"  Herb  Schild  (Osborn  /
     McGrow-Hall, 1987).

                  ,  
         :

          -       ;
          -     ;
          -     ;
          -     .

                        "-",
         ,   
      .

                    
     ,              
- - -                                                        - - - 

                                - 114 -

     .  ,         
        ,           
                  .
             ,    
         "  "  -      ""
     ,        .  
       ,                
          (CAD/CAM
     system).

                ,     
     ,      IBM PC  XT,  IBM PC AT 
               ,    
      CGA    EGA.    ,     
     ,     , -, 
                
       .




                           
     -----------------------------------------------------------------

             -     
                   .  
         IBM PC   ,     
        .

             4-1     ,   
          IBM PC.    ,   
      ,   4 ,  
            320   200.
       EGA       
      , 4      
             ,   
        EGA,   CGA.  
      EGA       (
             EGA  "Advance  Grafics  in C"
     Nelson   Jobson   Osborn/McGrow-Hall,   1987).      
     ,          
     0,0.

          BIOS- 16,    0,    
        mode(),      .  
              ,    
           ,       
     .      4-1.

- - -                                                        - - - 

                                - 115 -


      4-1     IBM PC

     -----------------------------------------------------------------
                                 
                                         
     -----------------------------------------------------------------

        0    -, /      4025    CGA, EGA
        1    -, 16 .   4025    CGA, EGA
        2    -, /      8025    CGA, EGA
        3    -, 16 .   8025    CGA, EGA
        4    , 4        320200    CGA, EGA
        5    , 4    320200    CGA, EGA
        6    , /           640200    CGA, EGA
        7    -, /      8025   
        8    , 16      160200     PCjr
        9    , 16      320200     PCjr
       10    , 4 -PCjr  640200    PCjr, EGA
                         16 -EGA
       13    , 16      320200      EGA
       14    , 16      640200      EGA
       15    , 4        640350      EGA
     -----------------------------------------------------------------

               mode().

          /*   */
          void mode(mode_code)
          int mode_code;
               {
               union REGS r;
               r.h.al = mode_code;
               r.h.ah = 0;
               int86(0x10,&r,&r);
               }


           4-      (  ). 
             ,        
     .    IBM PC    0    ,   
        ,     1      ,  -
     ()    .     
        ,    .  BIOS- 16,
      11,  .

            pallet(),    ,    
     ,       :

          /*   */
          void palette(pnum)
          int pnum;
               {
               union REGS r;

               r.h.bh=1;    /*  4   */
               r.h.bl=pnum; /*   */
               r.h.ah;   /*     */
               int86(0x10,&r,&r);
               }
- - -                                                        - - - 

                                - 116 -




                               
     -----------------------------------------------------------------

                 
       -       .  
           "  "    
                
     .              
         ,     
                ,  
           .      IBM   PC   
                 
              .      ,
       ROM-BIOS,   ,  
       (      ).
              
            (ROM).  
         .


       CGA/EGA   
     ----------------------------------------------

           CGA          
     8000000h.   EGA         
     ,            CGA  (  
                
              "IBM   Technical  Reference").    4
               4
        (     2 ). ,
             320    200    16
     .              4 
     ,  4    4 . 
                  
     ,  :

     ---------------------------------------------------
            0        1
     ---------------------------------------------------
                                         
         1                          
         2                         
         3                         
     ---------------------------------------------------

            CGA   ,   
          B8000000h,    -  
     2000h  (8152  -    )  ,  ..   
     B8002000h.  ,       80
       (40    ,  40 -  ).  
               ,      
        .   ,    
      0  6  7 ,    ,       
      3 - 0  1 .

                   ,
                 
- - -                                                        - - - 

                                - 117 -

     .      -     
     ,    1,  ,   .
           ""  
      ,           
        ""       .      
     ,       "-"   
     .              ""
         0,       "-"
            .  
           
     X  40,       Y,   
     4.   , ,      
           ,        
         2.     0,   
       (    ),      - 
      (  ).     
                  4.  
        ,   
           .       
              .  
           mempoint()  ,
     ,  ,      ,   
          .


     /*    CGA/EGA */
          void mempoint(x,y,color_code)
          int x,y,color_code;
            {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* "-"      */
            char far *ptr=(char far *) 0xB8000000; /*   
                                                                CGA */
            bit_mask.i=0xFF3F; /* 11111111 00111111    */
            if (x<0 || x>199 || y<0 || y>319) return;
            xor=color_code & 128; /* ,  
                                      "-" */

            color_code=color_code & 127; /*    */

            /*        
                   */

             bit_position=y%4; /*   
                                    */
             color_code<<=2*(3-bit_position); /*   
                                           */
             bit_mask.i>>=2*bit_position; /*    
                                            */

             /*       */
              index=x*40+(y%4);
              if (x%2) index+52; /*  , 
                                         */
              /*   */
- - -                                                        - - - 

                                - 118 -

               if (!xor) {  /*    */
                  t=*(ptr+index) & bit_mask.c[0];
                  *(ptr+index)=t|color_code;
               }
               else {
                  t=*(ptr+index) | (char)0;
                  *(ptr+index)=t & color_code;
               }
            }



          ,       far; 
     ,             (small)
     .      ,    
       XOR,     ROM-BIOS,    
      mempoint().



                             
     -----------------------------------------------------------------

               
                 
           .    , 
             
       ,       ,
           .  ,    
       ,        0,0 
        80,120?

                     
            X  Y. 
         ,       
       0,0    5,10.    X  5,    Y - 10.
       1/2.          
      ,      
     X  Y   .       ,  
         X     
      Y.       
             .    
           ,      
          ,      ,
                 
       .   ,     
        ,      
         (  -  Intel  8087).   
          .

                            
         .       
           X  Y,  
                  
       .    ,       
       X    Y       
         .         ,
                   
                    
     ,       .  
- - -                                                        - - - 

                                - 119 -

            
           .    
                       
     ,  ,  ,   
          .   
             xerr  yerr,
                    
       X    Y  .      
       ,        
        ,            
     .       ,   
        .   line(),   ,
       .        ,    
          . ,   
          mempoint(),         
         .


      /*      
           */
       void line(startx,starty,endx,endy,color)
       int startx,starty,endx,endy,color;
       {
         register int t,distnce;
         int xerr=0,yerr=0,delta_x,delta_y;
         int incx,incy;

       /*       */
         delta_x=endx-startx;
         delta_y=endy-starty;

       /*   ,
              ,  
             */
          if (delta_x>0) incx=1;
          else  if (delta_x==0) incx=0;
          else  incx= -1;
          if (delta_y>0) incy=1;
          else  if (delta_y==0) incy=0;
          else  incy= -1;

        /*     */
          delta_xs(delta_x);
          delta_ys(delta_y);
          if (delta_x>delta_y) distancelta_x;
          else distancelta_y;

        /*   */
          for (t=0; t<=distance+1; t++) {
             mempoint(startx,starty,color);
             xerr+lta_x;
             yerr+lta_y;
             if (xerr>distance) {
                xerr-=distance;
                startx+=incx;
             }
             if (yerr>distance) {
                yerr-=distance;
                starty+=incy;
             }
- - -                                                        - - - 

                                - 120 -

          }
       }




                    
     -----------------------------------------------------------------

                 ,    
                .
     ,   ,    
           .


         /*     */
        void box(startx,starty,endx,endy,color_code)
        int startx,starty,endx,endy,color_code;
        {
           line(startx,starty,endx,starty,color_code);
           line(startx,starty,startx,endy,color_code);
           line(startx,endy,endx,endy,color_code);
           line(endx,starty,endx,endy,color_code);
        }


           ,          ,    
                .
         fill_box(),         ,     
     ,        
     ,    .          line(),
        .


        /*      */
        void fill_box(startx,starty,endx,endy,color_code)
        int startx,starty,endx,endy,color_code;
        {
           register int i,begin,end;

           begin=startx<endx ? startx:endx;
           end=startx>endx ? startx:endx;

           for (igin;i<=end;++i)
              line(i,starty,i,endy,color_code);
         }


- - -                                                        - - - 

                                - 121 -


                           
     -----------------------------------------------------------------

                    
      ,      
     ,       .
                    
     ,         ,      
        .   ,  
         X   Y      
       .        delta.
       plot_circle()          .
      asp_ratio  ,  ..   
         circle(),          plot_circle().  
                     
              circle()    
         .        
              .    
     circle()     ,      .  
       .


         double asp_ratio;

        /*     
            */
         void circle(x_center,y_center,radius,color_code)
         int x_center,y_center,radius,color_code;
         {
            register x,y,delta;
            asp_ratio=1.0; /*      
                               */
             y=radius;
             delta=3-2*radius;
             for (x=0;x<y; ) {
                 plot_circle(x,y,x_center,y_center,color_code);
                 if (delta<0)
                    delta+=4*x+6;
                 else {
                    delta+=4*(x-y)+10;
                    y--;
                 }
                 x++;
              }
              x=y;
              if (y) plot_circle(x,y,x_center,y_center,color_code);
           }

         /*   ,   */
           void plot_circle(x,y,x_center,y_center,color_code)
           int x,y,x_center,y_center,color_code;
           {
              int startx,starty,endx,endy,x1,y1;
              starty=y*asp_ratio;
              endy=(y+1)*asp_ratio;
              startx=x*asp_ratio;
              endx=(x+1)*asp_ratio;

              for (x1=startx;x1<endx;++x1) {
- - -                                                        - - - 

                                - 122 -

                 mempoint(x1+x_center,y+y_center,color_code);
                 mempoint(x1+x_center,y_center-y,color_code);
                 mempoint(x_center-x1,y+y_center,color_code);
                 mempoint(x_center-x1,y_center-y,color_code);
              }

              for (y1=starty;y1<endy;++y1) {
                 mempoint(y1+x_center,x+y_center,color_code);
                 mempoint(y1+x_center,y_center-x,color_code);
                 mempoint(x_center-y1,x+y_center,color_code);
                 mempoint(x_center-y1,y_center-x,color_code);
              }
           }


                
     circle()             . 
              fill_circle(),    
      .


         /*     
            circle()    */

            void fill_circle(x,y,r,c)
            int x,y,r,c;
            {
               while (r) {
                  circle(x,y,r,c);
                  r--;
               }
             }



                         
     -----------------------------------------------------------------

                      
           .

        /* ,   
            */
         #include "dos.h"
         #include "stdio.h"

         void mode(),line(),box(),fill_box();
         void mempoint(),palette(),xhairs();
         void circle(),plot_circle(),fill_circle();

         double asp_ratio;

         main()
         {
         mode(4);
         palette(0);
         line(0,0,100,100,1);
         box(50,50,80,90,2);
         fill_box(100,0,120,40,3);
         circle(100,160,30,2);
- - -                                                        - - - 

                                - 123 -

         fill_circle(150,250,20,1);
         getchar();
         mode(2);
        }
             /*   */

         void palette(pnum)
         int pnum;
         {
            union REGS r;

            r.h.bh=1; /*  4   */
            r.h.bl=pnum; /*   */
            r.h.ah; /*     */
            int86(0x10,&r,&r);
         }

          /*   */
            void mode(mode_code)
            int mode_code;
            {
                union REGS r;
                r.h.al = mode_code;
                r.h.ah = 0;
                int86(0x10,&r,&r);
             }

         /*     */
        void box(startx,starty,endx,endy,color_code)
        int startx,starty,endx,endy,color_code;
        {
           line(startx,starty,endx,starty,color_code);
           line(startx,starty,startx,endy,color_code);
           line(startx,endy,endx,endy,color_code);
           line(endx,starty,endx,endy,color_code);
        }

      /*      
           */
       void line(startx,starty,endx,endy,color)
       int startx,starty,endx,endy,color;
       {
         register int t,distance;
         int xerr=0,yerr=0,delta_x,delta_y;
         int incx,incy;

       /*              */
         delta_x=endx-startx;
         delta_y=endy-starty;

       /*   ,
              ,   
                             */
          if (delta_x>0) incx=1;
          else  if (delta_x==0) incx=0;
          else  incx= -1;

          if (delta_y>0) incy=1;
          else  if (delta_y==0) incy=0;
          else  incy= -1;
- - -                                                        - - - 

                                - 124 -


        /*     */
          delta_xs(delta_x);
          delta_ys(delta_y);
          if (delta_x>delta_y) distancelta_x;
          else distancelta_y;

        /*   */
          for (t=0; t<=distance+1; t++) {
             mempoint(startx,starty,color);
             xerr+lta_x;
             yerr+lta_y;
             if (xerr>distance) {
                xerr-=distance;
                startx+=incx;
             }
             if (yerr>distance) {
                yerr-=distance;
                starty+=incy;
             }
          }
       }

        /*      */

        void fill_box(startx,starty,endx,endy,color_code)
        int startx,starty,endx,endy,color_code;
        {
           register int i,begin,end;

           begin=startx<endx ? startx:endx;
           end=startx>endx ? startx:endx;

           for (igin;i<=end;++i)
              line(i,starty,i,endy,color_code);
         }


        /*     
            */
         void circle(x_center,y_center,radius,color_code)
         int x_center,y_center,radius,color_code;
         {
            register x,y,delta;
            asp_ratio=1.0; /*      
                               */
             y=radius;
             delta=3-2*radius;
             for (x=0;x<y; ) {
                 plot_circle(x,y,x_center,y_center,color_code);
                 if (delta<0)
                    delta+=4*x+6;
                 else {
                    delta+=4*(x-y)+10;
                    y--;
                 }
                 x++;
              }
              x=y;
              if (y) plot_circle(x,y,x_center,y_center,color_code);
- - -                                                        - - - 

                                - 125 -

           }

         /*   ,   */
           void plot_circle(x,y,x_center,y_center,color_code)
           int x,y,x_center,y_center,color_code;
           {
              int startx,starty,endx,endy,x1,y1;
              starty=y*asp_ratio;
              endy=(y+1)*asp_ratio;
              startx=x*asp_ratio;
              endx=(x+1)*asp_ratio;

              for (x1=startx;x1<endx;++x1) {
                 mempoint(x1+x_center,y+y_center,color_code);
                 mempoint(x1+x_center,y_center-y,color_code);
                 mempoint(x_center-x1,y+y_center,color_code);
                 mempoint(x_center-x1,y_center-y,color_code);
              }

              for (y1=starty;y1<endy;++y1) {
                 mempoint(y1+x_center,x+y_center,color_code);
                 mempoint(y1+x_center,y_center-x,color_code);
                 mempoint(x_center-y1,x+y_center,color_code);
                 mempoint(x_center-y1,y_center-x,color_code);
              }
           }


       /*     
            circle()    */
            void fill_circle(x,y,r,c)
            int x,y,r,c;
            {
               while (r) {
                  circle(x,y,r,c);
                  r--;
               }
         }

        /*    CGA/EGA */
         void mempoint(x,y,color_code)
         int x,y,color_code;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
                           */
            char far *ptr=(char far *) 0xB8000000; /*   
                                                      CGA */
            bit_mask.i=0xFF3F;                 /* 11111111 00111111 
                                                    */
            if (x<0 || x>199 || y<0 || y>319) return;
            xor=color_code & 128;      /* ,  
                                           " " */
            color_code=color_code & 127;     /*    */

- - -                                                        - - - 

                                - 126 -

            /*        
                   */

             bit_position=y%4; /*      */
             color_code<<=2*(3-bit_position); /*   
                                           */
             bit_mask.i>>=2*bit_position; /*    
                                            */

             /*       */

              index=x*40+(y%4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */
               if (!xor) {  /*    */
                  t=*(ptr+index) & bit_mask.c[0];
                  *(ptr+index)=t|color_code;
               }
               else {
                  t=*(ptr+index) | (char)0;
                  *(ptr+index)=t & color_code;
               }
            }



                   
     -----------------------------------------------------------------

                     
         ,  ..        
      ,       
     .               
         ,    ,       
            .   ,
           ,         save_pic()  
     load_pic(),        .  
         14      ,    
     ,     ,    ,      
     ,  .


        /*     */
        void save_pic()
        {
          char fname[80];
          FILE *fp;
          register int i,j;
          char far *ptr=(char far *) 0xB8000000; /*  
                                                    CGA  */
          char far *temp;
          unsigned char buf[14][80]; /*    */

          temp=ptr;
        /*       */
          for (i=0;i<14;++i)
             for (j=0;j<80;++j) {
                buf[i][j]=*temp; /*   */
- - -                                                        - - - 

                                - 127 -

                buf[i][j+1]=*(temp+8152); /*   */
                *temp=0; *(temp+8152)=0; /*    */
                temp++;
             }
           goto_xy(0,0);
           printf(" :");
           gets(fname);
           if (!(fp=fopen(fname,"wb"))) {
               printf("    \n");
               return;
           }

           temp=ptr;
       /*    */
          for (i=0;i<14;++i)
             for (j=0;j<80;++j) {
                *temp= buf[i][j]; /*   */
                *(temp+8125)=buf[i][j+1]; /*   */
                *temp=0; *(temp+8152)=0; /*    */
                temp++;
             }
        /*      */
           for (i=0;i<8152;i++) {
              putc(*ptr,fp); /*   */
              putc(*(ptr+8125),fp); /*   */
              ptr++;
           }

           fclose(fp);
        }

       /*   */
         void load_pic()
         {
            char fname[80];
            FILE *fp;
            register int i,j;

            char far *ptr=(char far *) 0xB8000000; /*  
                                                      CGA  */
            char far *temp;
            unsigned char buf[14][80]; /*    */

            temp=ptr;
        /*       */
            for (i=0;i<14;++i)
               for (j=0;j<80;j+=2) {
                  buf[i][j]=*temp;
                  buf[i][j+1]=*(temp+8152);
                  *temp=0; *(temp+8152)=0; /*    */
                  temp++;
               }
            goto_xy(0,0);
            printf(" :");
            gets(fname);
            if (!(fp=fopen(fname,"rb"))) {
               goto_xy(0,0);
               printf("    \n");
               temp=ptr;
       /*    */
- - -                                                        - - - 

                                - 128 -

               for (i=0;i<14;++i)
                  for (j=0;j<80;j+=2) {
                     *temp= buf[i][j];
                     *(temp+8125)=buf[i][j+1];
                     temp++;
                  }
               return;
             }
      /*     */
           for (i=0;i<8152;i++) {
              *ptr=getc(fp); /*   */
              *(ptr+8125)=getc(fp); /*   */
              ptr++;
           }

           fclose(fp);
        }

                 ,    
     ,      temp     
               .
                      
             .     
               , 
         ,   - .



                           
     -----------------------------------------------------------------

                     
     .          copy(),  
       .

          /*       */
          void copy(startx,starty,endx,endy,x,y)
          int startx,starty;      /*    */
          int endx,endy;          /*    
                                      */
          int x,y;      /*    ,
                               */
          {
             int i,j;
             unsigned char c;

             for (;startx<endx;startx++,x++)
                for (i=starty,j=y;i<endy;i++,j++) {
                   c=read_point(startx,i); /*   */
                   mempoint(x,j,c); /*      */
                 }
            }


             ,       
                      
       ,    ,   
      ,   .

- - -                                                        - - - 

                                - 129 -

               ,        
       copy()         move(). 
     move()           
     .    .



       /*       */
          void move(startx,starty,endx,endy,x,y)
          int startx,starty; /*    */
          int endx,endy; /*    
                             */
          int x,y; /*    ,
                         */
          {
             int i,j;
             unsigned char c;

             for (;startx<endx;startx++,x++)
                for (i=starty;j=y;i<endy;i++,j++) {
                   c=read_point(startx,i); /*   */
                   mempoint(startx,i,0); /*  
                                             */
                   mempoint(x,j,c); /*      */
                 }
            }



                         
     -----------------------------------------------------------------

                 ( )
              
     .        ,
                 theta,  
     :

              new_x = old_x * cos(theta) - old_y * sin(theta)
              new_y = old_x * sin(theta) - old_y * cos(theta)

                    
          ,    
       .        4
     ,             4-2.    
          ,    X    Y  
        .           
             X  Y
           .    
           ,   
                 ,    
      .    rotate_point(),    ,
             X    Y    
     .

- - -                                                        - - - 

                                - 130 -


        /*      
           x_org  y_org   theta */
          void rotate_point(theta,x,y,x_org,y_org)
          double theta,*x,*y;
          int x_org,y_org;
          {
             double tx,ty;

        /*  X  Y    */
             tx=*x-x_org;
             ty=*y-y_org;

        /*  */
              *x=tx*cos(theta)-ty*sin(theta);
              *y=tx*sin(theta)-ty*cos(theta);

         /*    */
              *x+=x_org;
              *y+=y_org;
           }


          ,   rotate_point()    X  Y 
               ,
       theta.     .


     
                                                                   
                         Y                
                                         II       ^       I        
                                          +,-          +,+        
                                                                  
                                                  0.0             
                                          X     
                                                                  
                                          -,-          -,+        
                                                                  
                                        III       +       IV       
                                                                   
                                                                   
                                                         0.0       
                                   Y    
                                                                  
                                                       +,+        
                                                                  
                                                  +                
                                                  X                
     

     . 4-2.     .


- - -                                                        - - - 

                                - 131 -


      
     ----------------

            rotate_point(),    
       X   Y   ,     .
     ,          ()
     .     .   
                      .
              
         .     
            .   ,
                
     ,     ,     
       4  (        ).  ,
     ,  

          double object [10][4];

      ,   10 .

           ,       ,      
      4-3.

     
                                                                    
                >                               
                                                        
                                                                    
                      0           1            2           3       
                                                                   
                                                                   
         V                                                          
                                                                    
         0          start_X1     start_Y1     end_X1     end_Y1     
                                                                    
         1          start_X2     start_Y2     end_X2     end_Y2     
                                                                    
         2          start_X3     start_Y3     end_X3      end_Y3    
                                                                    
         3          start_X4     start_Y4     end_X4      end_Y4    
         .             .                                            
         .             .                                            
         .             .                                            
         n          start_Xn     start_Yn     end_Xn      end_Yn    
     

     . 4-3.   .

- - -                                                        - - - 

                                - 132 -


             -             
              ,  
     .  ,       
     :

                         0.00.10
                                             
                                             
                                             
                                             
                        10.010.10

        ,        ,   
      :

          object[0][0] = 0; object[0][1] = 0;
          object[0][0] = 0; object[0][3] = 10;

          object[1][0] = 0; object[1][1] = 10;
          object[1][0] = 10; object[1][3] = 10;

          object[2][0] = 10; object[2][1] = 10;
          object[2][0] = 10; object[2][3] = 0;

          object[3][0] = 10; object[3][1] = 0;
          object[3][0] = 0; object[3][3] = 0;

           ,      ,     ,
       rotate_object(),   ,   
       (  <R>)        (
     <L>).


          /*    */

          void rotate_object(ob, theta, x, y, sides)
          double ob[][4]; /*   */
          double theta;   /*     */
          int x, y;
          int sides;
            {
            register int i, j;
            double tempx, tempy;
            char ch;

            for(;;)
              {
              ch = getch(); /*     */
              switch(tolower(ch))
                {
                case 'l': /*     */
                  theta = theta < 0 ? -theta : theta;
                  break;
                case 'r': /*      */
                  theta = theta > 0 ? -theta : theta;
                  break;
                default: return;
                }
              for(j=0; j<=sides; j++) /*     */
- - -                                                        - - - 

                                - 133 -

                {
                line((int) ob[j][0], (int) ob[j][1],
                     (int) ob[j][2], (int) ob[j][3], 0);
                rotate_point(theta, &ob[j][0],
                             &ob[j][1], x, y);
                rotate_point(theta, &ob[j][2], &ob[j][3], x, y);
                line((int) ob[j][0], (int) ob[j][1],
                     (int) ob[j][2], (int) ob[j][3], 2);
                }
              }
            }

                 rotate_object(),
        ,   X 
     Y,  ,     theta  .
        theta  0.01  . ,
                ,  
       .           
     ,          .  
                rotate_object()    
        sides.

             display_object()   
       ,              
     .      ,    
     ob.

          /*     */
          void display_object(ob, sides)
          double ob[][4];
          int sides;
          {
            register int i;

            for(i=0; i<sides; i++)
              line((int)ob[i][0], (int)ob[i][1],
                   (int)ob[i][2], (int)ob[i][3], 2);
            }

                      
            
     .    4-4        
                .
     ,     ,  
          .

     _________________________________________________________________

        . .   4-4     
                    .
     _________________________________________________________________

     . 4-4.  .


          /*           
              CGA/EGA  4  
          */
- - -                                                        - - - 

                                - 134 -


          #include "dos.h"
          #include "stdio.h"
          #include "math.h"

          void mode(), line(), mempoint(), palette();
          void rotate_point(), rotate_object(), display_object();

          /*  house    */
          double house[][4]             {
       /*  startx,   starty,        endx,         endy  */
           120,         120,         120,          200,   /*  */
           120,         200,          80,          200,
           80,          120,          80,          200,
           80,          120,         120,          120,
           60,          160,          80,          120,   /* a*/
           60,          160,          80,          200,
           120,         155,         100,          155,   /* */
           100,         155,         100,          165,
           100,         165,         120,          165,
           90,          130,         100,          130,   /*  */
           90,          130,          90,          140,
           100,         130,         100,          140,
           90,          140,         100,          140,
           90,          180,         100,          180,
           90,          180,          90,          190,
           100,         180,         100,          190
           };
          main()
            {
            union k
              {
              char c[2];
              int i;
              }  key;

            mode(4);    /*    = 4 */
            palette(0); /*  = 0 */

            /*  ,  */
            line (30, 70, 30, 260, 2);
            line (160, 70, 160, 260, 2);
            line (30, 70, 160, 70, 2);
            line (30, 260, 160, 260, 2);

            display_object(house, 17);
            getchar();
            rotate_object(house, 0.025, 90, 160, 17);
            mode(3);
            }

          /*   */
          void palette(pnum)
          int pnum;
            {
            union REGS r;
- - -                                                        - - - 

                                - 135 -


            r.h.bh = 1; /*  4   */
            r.h.bl = pnum;
            r.h.ah = 11;
            int86(0x10, &r, &r);
            }

          /*   */
          void mode(mode_code)
          int mode_code;
            {
            union REGS r;

            r.h.al = mode_code;
            r.h.ah = 0;
            int86(0x10, &r, &r);
            }

          /*      */
          void line(start_x, start_y, endx, endy, color)
          int start_x, start_y, endx, endy, color;
            {
            register int t, distance;
            int x=0, y=0, delta_x, delta_y;
            int incx, incy;

            /*    x   y */
            delta_x = endx-start_x;
            delta_y = endy-start_y;

            /*     */
            if(delta_x>0)
              incx=1;
            else
              if(delta_x==0)
                incx=0;
              else
                incx= -1;
            if(delta_y>0)
              incy=1;
            else
              if(delta_y==0)
                incy=0;
              else
                incy= -1;
            delta_xs(delta_x);
            delta_ys(delta_y);
            if(delta_x>delta_y)
              distancelta_x;
            else
              distancelta_y;

            /*   */
            for(t=0; t<=distance; t++)
              {
              mempoint(start_x, start_y, color);
              x+lta_x;
              y+lta_y;
              if(x>distance)
                {
- - -                                                        - - - 

                                - 136 -

                x-=distance;
                start_x+=incx;
                }
              if(y>distance)
                {
                y-=distance;
                start_y+=incy;
                }
              }
            }

        /*    CGA/EGA */

         void mempoint(x,y,color_code)
         int x,y,color_code;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* "-"    
                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=0xFF3F; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return;
            xor=color_code & 128; /* ,  
                                      "-" */
            color_code=color_code & 127; /*    */

            /*        
                   */

             bit_position=y%4; /*   
                                    */
             color_code<<=2*(3-bit_position); /*   
                                           */
             bit_mask.i>>=2*bit_position; /*    
                                            */

             /*       */

              index=x*40+(y%4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */

               if (!xor) {  /*    */
                  t=*(ptr+index) & bit_mask.c[0];
                  *(ptr+index)=t|color_code;
               }
               else {
                  t=*(ptr+index) | (char)0;
                  *(ptr+index)=t & color_code;
               }
            }
- - -                                                        - - - 

                                - 137 -



        /*      
            x_org  y_org,   theta */

          void rotate_point(theta,x,y,x_org,y_org)
          double theta,*x,*y;
          int x_org,y_org;
          {
             double tx,ty;

        /*  X  Y    */
             tx=*x-x_org;
             ty=*y-y_org;

        /*  */
              *x=tx*cos(theta)-ty*sin(theta);
              *y=tx*sin(theta)-ty*cos(theta);

         /*    */
              *x+=x_org;
              *y+=y_org;
           }


          /*    */

          void rotate_object(ob, theta, x, y, sides)
          double ob[][4]; /*   */
          double theta;   /*     */
          int x, y;
          int sides;
            {
            register int i, j;
            double tempx, tempy;
            char ch;

            for(;;)
              {
              ch = getch(); /*     */
              switch(tolower(ch))
                {
                case 'l': /*     */
                  theta = theta < 0 ? -theta : theta;
                  break;
                case 'r': /*      */
                  theta = theta > 0 ? -theta : theta;
                  break;
                default: return;
                }
              for(j=0; j<=sides; j++) /*     */
                {
                line((int) ob[j][0], (int) ob[j][1],
                     (int) ob[j][2], (int) ob[j][3], 0);
                rotate_point(theta, &ob[j][0],
                             &ob[j][1], x, y);
                rotate_point(theta, &ob[j][2], &ob[j][3], x, y);
                line((int) ob[j][0], (int) ob[j][1],
                     (int) ob[j][2], (int) ob[j][3], 2);
                }
- - -                                                        - - - 

                                - 138 -

              }
            }


          /*     */

          void display_object(ob, sides)
          double ob[][4];
          int sides;
            {
            register int i;

            for(i=0; i<sides; i++)
              line((int) ob[i][0], (int) ob[i][1],
                   (int) ob[i][2], (int) ob[i][3], 2);
            }



                
     -----------------------------------------------------------------

           ,  , ,   
     ,   .  
         "",         
           .  ,  ""
            ,    
     "-"            
      .

           ""           
          X  Y (   
             ).  
                    
     ""  "",       
     ,        
     .   xhairs()      ,
         X  Y.

          ,           
     ""  128    7   1.    
     mempoint()      " "  
                 .  
            .  -,
        , ..   , 
        .   -,       
       ,  ,   .
             
     (,       
     "  "      ).
           .

        /*    */
         void xhairs(x,y)
         int x,y;
         {
            line(x-4,y,x+3,y,1|128);
            line(x,y+4,x,y-3,1|128);

          }
- - -                                                        - - - 

                                - 139 -



            ,      , 
     :

          -  ;
          -  ;
          -  ;
          -  ;
          -  ;
          -  ;
          -  ;
          -    ;
          -   ;
          -   ;
          -     ;
          -     .


               :

          main()
            {
            union k{
              char c[2];
              int i;
               } key ;

            int x, y; /*    */
            int cc=2;   /*   */
            int on_flag=1; /*    */
            int pal_num=1; /*   */
            /*    ,
              ,  */
            int startx=0, starty=0, endx=0, endy=0;
            int first_point=1;
            int inc=1; /*   */
            int sides=0; /*     */
            int i;

            mode(4); /*   CGA/EGA */
            palette(0); /*  0 */

            xhairs(x, y); /*   */

             do
              {
              key.i = bioskey(0);
              xhairs(x, y); /*   */
              if(!key.c[0]) switch(key.c[1])
                {
                case 75: /*  */
                  if(on_flag) line(x, y, x, y-inc, cc);
                  y -= inc;
                  break;
                case 77: /*  */
                  if(on_flag) line(x, y, x, y+inc, cc);
                  y += inc;
                  break;
                case 72: /*  */
- - -                                                        - - - 

                                - 140 -

                    if(on_flag) line(x, y, x-inc, y, cc);
                  x -= inc;
                  break;
                case 80: /*  */
                    if(on_flag) line(x, y, x+inc, y, cc);
                  x += inc;
                  break;
                case 71: /*    */
                  if(on_flag) line(x, y, x-inc, y-inc, cc);
                  x -= inc;
                  y -= inc;
                  break;
                case 73: /*    */
                  if(on_flag) line(x, y, x-inc, y+inc, cc);
                  x -= inc;
                  y += inc;
                  break;
                case 79: /*    */
                  if(on_flag) line(x, y, x+inc, y-inc, cc);
                  x += inc;
                  y -= inc;
                  break;
                case 81: /*    */
                  if(on_flag) line(x, y, x+inc, y+inc, cc);
                  x += inc;
                  y += inc;
                  break;
                case 59: /* F1 -  */             inc=1;
                  break;
                case 60: /* F2 -    */
                  inc=5;
                  break;
                }
              else switch(tolower(key.c[0]))
                {
                case 'o': /*   */
                  on_flag = !on_flag;
                  break;
                case '1': cc=1; /*  1 */
                  break;
                case '2': cc=2; /*  2 */
                  break;
                 case '3': cc=3; /*  3 */
                  break;
                case '0': cc=0; /*  0 */
                  break;
                case 'b': box(startx, starty, endx, endy, cc);
                    break;
                case 'f':
                  fill_box(startx, starty, endx, endy, cc); break;
                case 'l':
                  line(startx, starty, endx, endy, cc);     break;
                case 'c':
                  circle(startx, starty, endy-starty, cc);  break;
                case 'h':
                  fill_circle(startx, starty, endy-starty, cc); break;
                case 's':
                  save_pic();                               break;
                case 'r':
                  load_pic();                               break;
- - -                                                        - - - 

                                - 141 -

                case 'm': /*   */
                  move(startx, starty, endx, endy, x, y);   break;
                case 'x': /*   */
                  copy(startx, starty, endx, endy, x, y);   break;
                case 'd': /*  (c)  */

      /* !!      object
             "".   
             . (. . .)
      */

                  sides = define_objekt(object, x, y);      break;
                case 'a': /* ()  */
                  rotate_objekt(object, 0.05, x, y, sides); break;
                case '\r': /*     , 
                              */
                  if(first_point)
                    { startx = x, starty = y; }
                  else
                    { endx = x, endy = y; }
                  first_point = !first_point;break;
                case 'p':
                  pal_num = pal_num==1 ? 2:1;
                  palette(pal_num);
                }
              xhairs(x, y);
              }
            while (key.c[0]!='q');
            getchar();
            mode(2);
            }

                .  
             4  .  
       0,        
        .       
        2 (     0).    
                    ,   
                 .  
              ,     
             .  
          , 
           5   
        F2.     
         F1.      
               0   3.    0  0
     ,  1   ,  2 -  ,  3  -
     .          0.
      <    > (<HOME>),  < >
     (<PGUP>),  <  >  (<PGDN>)   <> (<END>) 
                    45
     .

                  
      bioskey().        
          1.     
     ,       
     ,   ,     
      ,              
     ,    .
- - -                                                        - - - 

                                - 142 -


             ,       
         .   
     -      .    
        ,     -  
      ,     .

                  
     <>  ,        
     .   ,             
        ,      
       <>  .        ,  
      ,      <>  .     
       <>     startx,  starty,
     endx  endy,          
       .    ,        
     ,     <>  ,    <F>  -
      ,       <L>    ,  
        <>      ,      <>   -   
     .

                       
            ,  
           (     <>  ).    
           ,     
       .        
       <>,       -  <>.  ,  
          ,    ,
      .

                   ,
        <D>.  ,    <>,  
                  
         .    
                      
     define_object().            
      <>.        
        <L>  (    )    <R>  (  
     ).             
     ,  <L>  <>.

                <Q>. 
                    
     "".        4-5.

     _________________________________________________________________

      4-5  . 163     
     . (. . .)
     _________________________________________________________________

     . 4-5.     .

- - -                                                        - - - 

                                - 143 -


                .


     /*         CGA/EGA,         ,
        .        -
                .  
                    
        . */

          #define NUM_SIDES 20 /*   ;
                                     */
          #include "dos.h"
          #include "stdio.h"
          #include "math.h"

          void mode(), line(), box(), fill_box();
          void mempoint(), palette(), xhairs();
          void circle(), plot_circle(), fill_circle();
          void rotate_point(), rotate_object(), goto_xy();
          void display_object(), copy(), move();
          void save_pic(), load_pic();
          unsigned char read_point();

          /*      
               .
          */
          double object[NUM_SIDES][4];
          double asp_ratio; /*    
                                */

          main()
            {
            union k{
              char c[2];
              int i;
               } key ;

            int x, y; /*    */
            int cc=2;   /*   */
            int on_flag=1; /*    */
            int pal_num=1; /*   */

            int startx=0, starty=0, endx=0, endy=0;
            int first_point=1;
            int inc=1; /*   */
            int sides=0; /*  o   */
            int i;

            mode(4); /*   CGA/EGA */
            palette(0); /*  0 */

            xhairs(x, y); /*   */
             do
              {
              key.i = bioskey(0);
              xhairs(x, y);
              if(!key.c[0]) switch(key.c[1])
                {
                case 75: /*  */
- - -                                                        - - - 

                                - 144 -

                  if(on_flag) line(x, y, x, y-inc, cc);
                  y -= inc;
                  break;
                case 77: /*  */
                  if(on_flag) line(x, y, x, y+inc, cc);
                  y += inc;
                  break;
                case 72: /*  */
                    if(on_flag) line(x, y, x-inc, y, cc);
                  x -= inc;
                  break;
                case 80: /*  */
                    if(on_flag) line(x, y, x+inc, y, cc);
                  x += inc;
                  break;
                case 71: /*    */
                  if(on_flag) line(x, y, x-inc, y-inc, cc);
                  x -= inc;
                  y -= inc;
                  break;
                case 73: /*    */
                  if(on_flag) line(x, y, x-inc, y+inc, cc);
                  x -= inc;
                  y += inc;
                  break;
                case 79: /*    */
                  if(on_flag) line(x, y, x+inc, y-inc, cc);
                  x += inc;
                  y -= inc;
                  break;
                case 81: /*    */
                  if(on_flag) line(x, y, x+inc, y+inc, cc);
                  x += inc;
                  y += inc;
                  break;
                case 59: /* F1 -  */
                  inc=1;
                  break;
                case 60: /* F2 -    */
                  inc=5;
                  break;
                }
              else switch(tolower(key.c[0]))
                {
                case 'o': /*   */
                  on_flag = !on_flag;
                  break;
                case '1': cc=1; /*  1 */
                  break;
                case '2': cc=2; /*  2 */
                  break;
                 case '3': cc=3; /*  3 */
                  break;
                case '0': cc=0; /*  0 */
                  break;
                case 'b':
                  box(startx, starty, endx, endy, cc);      break;
                case 'f':
                  fill_box(startx, starty, endx, endy, cc); break;
                case 'l':
- - -                                                        - - - 

                                - 145 -

                  line(startx, starty, endx, endy, cc);     break;
                case 'c':
                  circle(startx, starty, endy-starty, cc);  break;
                case 'h':
                  fill_circle(startx, starty, endy-starty, cc); break;
                case 's':
                  save_pic();                               break;
                case 'r':
                  load_pic();                               break;
                case 'm': /*   */
                  move(startx, starty, endx, endy, x, y);   break;
                case 'x': /*   */
                  copy(startx, starty, endx, endy, x, y);   break;
                case 'd': /*    */
                  sides = define_objekt(object, x, y);      break;
                case 'a': /*   */
                  rotate_objekt(object, 0.05, x, y, sides); break;
                case '\r': /*     , 
                                */
                  if(first_point)
                    { startx = x, starty = y; }
                  else
                    { endx = x, endy = y; }
                  first_point = !first_point;               break;
                case 'p':
                  pal_num = pal_num==1 ? 2:1;
                  palette(pal_num);
                }
              xhairs(x, y);
              }
            while (key.c[0]!='q');
            getchar();
            mode(2);
            }

          /*   */
          void palette(pnum)
          int pnum;
            {
            union REGS r;
            r.h.bh = 1; /*  4   */
            r.h.bl = pnum;
            r.h.ah = 11; /*   */
            int86(0x10, &r, &r);
            }

          /*  - */
          void mode (mode_code)
          int mode_code;
            {
            union REGS r;

            r.h.al = mode_code;
            r.h.ah = 0;
            int86(0x10,&r, &r);
            }

          /*   */
          void box(sx, sy, ex, ey, c)
          int sx, sy, ex, ey, c;
- - -                                                        - - - 

                                - 146 -

            {
            line(sx, sy, ex, sy, c);
            line(sx, sy, sx, ey, c);
            line(sx, ey, ex, ey, c);
            line(ex, sy, ex, ey, c);
            }

      /*      
           */
       void line(startx,starty,endx,endy,color)
       int startx,starty,endx,endy,color;
       {
         register int t,distance;
         int xerr=0,yerr=0,delta_x,delta_y;
         int incx,incy;

       /*              */
         delta_x=endx-startx;
         delta_y=endy-starty;

       /*   ,
              ,  
                             */
          if (delta_x>0) incx=1;
          else  if (delta_x==0) incx=0;
          else  incx= -1;

          if (delta_y>0) incy=1;
          else  if (delta_y==0) incy=0;
          else  incy= -1;

        /*     */
          delta_xs(delta_x);
          delta_ys(delta_y);
          if (delta_x>delta_y) distancelta_x;
          else distancelta_y;

        /*   */
          for (t=0; t<=distance+1; t++) {
             mempoint(startx,starty,color);
             xerr+lta_x;
             yerr+lta_y;
             if (xerr>distance) {
                xerr-=distance;
                startx+=incx;
             }
             if (yerr>distance) {
                yerr-=distance;
                starty+=incy;
             }
          }
       }


        /*      */

        void fill_box(startx,starty,endx,endy,color_code)
        int startx,starty,endx,endy,color_code;
        {
           register int i,begin,end;
- - -                                                        - - - 

                                - 147 -


           begin=startx<endx ? startx:endx;
           end=startx>endx ? startx:endx;

           for (igin;i<=end;++i)
              line(i,starty,i,endy,color_code);
         }


        /*               
            */

         void circle(x_center,y_center,radius,color_code)
         int x_center,y_center,radius,color_code;
         {
            register x,y,delta;
            asp_ratio=1.0; /*     
                               */
             y=radius;
             delta=3-2*radius;
             for (x=0;x<y; ) {
                 plot_circle(x,y,x_center,y_center,color_code);
                 if (delta<0)
                    delta+=4*x+6;
                 else {
                    delta+=4*(x-y)+10;
                    y--;
                 }
                 x++;
              }
              x=y;
              if (y) plot_circle(x,y,x_center,y_center,color_code);
           }

         /* plot_circle  ,   */
           void plot_circle(x, y, x_center, y_center, color_code)
           int x_center,y_center,radius,color_code;
           {
              int x, y, startx, starty, endx, endy, x1, y1;
              starty=y*asp_ratio;
              endy=(y+1)*asp_ratio;
              startx=x*asp_ratio;
              endx=(x+1)*asp_ratio;

              for (x1=startx;x1<endx;++x1) {
                 mempoint(x1+x_center,y+y_center,color_code);
                 mempoint(x1+x_center,y_center-y,color_code);
                 mempoint(x_center-x1,y+y_center,color_code);
                 mempoint(x_center-x1,y_center-y,color_code);
              }

              for (y1=starty;y1<endy;++y1) {
                 mempoint(y1+x_center,x+y_center,color_code);
                 mempoint(y1+x_center,y_center-x,color_code);
                 mempoint(x_center-y1,x+y_center,color_code);
                 mempoint(x_center-y1,y_center-x,color_code);
              }
           }
       }

- - -                                                        - - - 

                                - 148 -

       /*     
            circle()    */

            void fill_circle(x,y,r,c)
            int x,y,r,c;
            {
               while (r) {
                  circle(x,y,r,c);
                  r--;
               }
            }
        /*    CGA/EGA */

         void mempoint(x,y,color_code)
         int x,y,color_code;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=0xFF3F; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return;
            xor=color_code & 128; /* ,  
                                      " " */
            color_code=color_code & 127; /*    */

            /*        
                   */

             bit_position=y%4; /*   
                                    */
             color_code<<=2*(3-bit_position); /*   
                                           */
             bit_mask.i>>=2*bit_position; /*    
                                            */

             /*       */

              index=x*40+(y%4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */

               if (!xor) {  /*    */
                  t=*(ptr+index) & bit_mask.c[0];
                  *(ptr+index)=t|color_code;
               }
               else {
                  t=*(ptr+index) | (char)0;
                  *(ptr+index)=t & color_code;
               }
            }
- - -                                                        - - - 

                                - 149 -


        /*    */
         void xhairs(x,y)
         int x,y;
         {
            line(x-4,y,x+3,y,1|128);
            line(x,y+4,x,y-3,1|128);

          }

        /*      CGA/EGA */
         unsigned char read_point(x,y)
         int x,y;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=3; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return 0;

            /*        
                   */
             bit_position=y%4; /*   
                                    */
             bit_mask.i<<=2*(3-bit_position);

             /*       */
              index=x*40+(y>>4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */
               t=*(ptr+index) & bit_mask.c[0];
               t>>=2*(3-bit_position);
               return t;
            }

       /*      */

        void save_pic()
        {
          char fname[80];
          FILE *fp;
          register int i,j;
          char far *ptr=(char far *) 0xB8000000; /*  
                                                    CGA  */
          char far *temp;
          unsigned char buf[14][80]; /*    */

          temp=ptr;
        /*       */
          for (i=0;i<14;++i)
- - -                                                        - - - 

                                - 150 -

             for (j=0;j<80;++j) {
                buf[i][j]=*temp; /*   */
                buf[i][j+1]=*(temp+8152); /*   */
                *temp=0; *(temp+8152)=0; /*    */
                temp++;
             }
           goto_xy(0,0);
           printf(" :");
           gets(fname);
           if (!(fp=fopen(fname,"wb"))) {
               printf("    \n");
               return;
           }

           temp=ptr;
       /*    */
          for (i=0;i<14;++i)
             for (j=0;j<80;++j) {
                *temp= buf[i][j]; /*   */
                *(temp+8125)=buf[i][j+1]; /*   */
                *temp=0; *(temp+8152)=0; /*    */
                temp++;
             }
        /*      */
           for (i=0;i<8152;i++) {
              putc(*ptr,fp); /*   */
              putc(*(ptr+8125),fp); /*   */
              ptr++;
           }

           fclose(fp);
        }


       /*   */

         void load_pic()
         {
            char fname[80];
            FILE *fp;
            register int i,j;

            char far *ptr=(char far *) 0xB8000000; /*  
                                                      CGA  */
            char far *temp;
            unsigned char buf[14][80]; /*    */

            temp=ptr;
        /*       */
            for (i=0;i<14;++i)
               for (j=0;j<80;j+=2) {
                  buf[i][j]=*temp;
                  buf[i][j+1]=*(temp+8152);
                  *temp=0; *(temp+8152)=0; /*    */
                  temp++;
               }
            goto_xy(0,0);
            printf(" :");
            gets(fname);
            if (!(fp=fopen(fname,"rb"))) {
- - -                                                        - - - 

                                - 151 -

               goto_xy(0,0);
               printf("    \n");
               temp=ptr;
       /*    */
               for (i=0;i<14;++i)
                  for (j=0;j<80;j+=2) {
                     *temp= buf[i][j];
                     *(temp+8125)=buf[i][j+1];
                     temp++;
                  }
               return;
             }
      /*     */
           for (i=0;i<8152;i++) {
              *ptr=getc(fp); /*   */
              *(ptr+8125)=getc(fp); /*   */
              ptr++;
           }

           fclose(fp);
        }

       /*       */
           void goto_xy(x,y)
           int x,y;
           {
              r.h.ah=2; /*   */
              r.h.dl=y; /*   */
              r.h.dh=x; /*   */
              r.h.bh=0; /*  */
              int86(0x10,&r,&r);
            }


       /*       */

          void copy(startx,starty,endx,endy,x,y)
          int startx,starty; /*    */
          int endx,endy; /*    
                             */
          int x,y; /*    ,
                         */
          {
             int i,j;
             unsigned char c;

             for (;startx<endx;startx++,x++)
                for (i=starty,j=y;i<endy;i++,j++) {
                   c=read_point(startx,i); /*   */
                   mempoint(x,j,c); /*      */
                 }
            }


       /*       */

          void move(startx,starty,endx,endy,x,y)
          int startx,starty; /*    */
          int endx,endy; /*    
                             */
- - -                                                        - - - 

                                - 152 -

          int x,y; /*    ,
                         */
          {
             int i,j;
             unsigned char c;

             for (;startx<endx;startx++,x++)
                for (i=starty,j=y;i<endy;i++,j++) {
                   c=read_point(startx,i); /*   */
                   mempoint(startx,i,0); /*  
                                             */
                   mempoint(x,j,c); /*      */
                 }
            }


        /*      
           x_org  y_org   theta */

          void rotate_point(theta,x,y,x_org,y_org)
          double theta,*x,*y;
          int x_org,y_org;
          {
             double tx,ty;

        /*  X  Y    */
             tx=*x-x_org;
             ty=*y-y_org;

        /*  */
              *x=tx*cos(theta)-ty*sin(theta);
              *y=tx*sin(theta)-ty*cos(theta);

         /*    */
              *x+=x_org;
              *y+=y_org;
           }


          /*    */

          void rotate_object(ob, theta, x, y, sides)
          double ob[][4]; /*   */
          double theta;   /*     */
          int x, y;
          int sides;
            {
            register int i, j;
            double tempx, tempy;
            char ch;

            for(;;)
              {
              ch = getch(); /*     */
              switch(tolower(ch))
                {
                case 'l': /*     */
                  theta = theta < 0 ? -theta : theta;
                  break;
                case 'r': /*      */
- - -                                                        - - - 

                                - 153 -

                  theta = theta > 0 ? -theta : theta;
                  break;
                default: return;
                }
              for(j=0; j<=sides; j++) /*     */
                {
                line((int) ob[j][0], (int) ob[j][1],
                     (int) ob[j][2], (int) ob[j][3], 0);
                rotate_point(theta, &ob[j][0], &ob[j][1], x, y);
                rotate_point(theta, &ob[j][2], &ob[j][3], x, y);
                line((int) ob[j][0], (int) ob[j][1],
                     (int) ob[j][2], (int) ob[j][3], 2);
                }
              }
            }


          /*     */
          void display_object(ob, sides)
          double ob[][4];
          int sides;
            {
            register int i;

            for(i=0; i<sides; i++)
              line((int)ob[i][0], (int)ob[i][1],
                   (int)ob[i][2], (int)ob[i][3], 2);
            }

       /*      */
            define_object(ob,x,y)
            double ob[][4];
            int x,y;
            {

            union k{
              char c[2];
              int i;
               } key ;
            register int i,j;

            char far *ptr=(char far *) 0xB8000000; /*  
                                                      CGA  */
            char far *temp;
            unsigned char buf[14][80]; /*    */
            int sides=0;

            temp=ptr;
        /*       */
            for (i=0;i<14;++i)
               for (j=0;j<80;j+=2) {
                  buf[i][j]=*temp;
                  buf[i][j+1]=*(temp+8152);
                  *temp=0; *(temp+8152)=0; /*    */
                  temp++;
               }

              i=0;
              xhairs(x,y);
              do {
- - -                                                        - - - 

                                - 154 -

                 goto_xy(0,0);



             printf("  %d,",sides+1);
                 if (i==0) printf("    ");
                 else printf("    ");

                 key.i=bioskey(0);
                 xhairs(x,y);
                 if (key.c[0]) {
                    ob[sides][++i]=(double) x;
                    ob[sides][++i]=(double) y;
                    if (i==4) {
                       i=0;
                       sides++;
                    }
                  }
                 /*    */
                 if (rey.c[0]) switch (key.c[1]) {
                    case 75: /*  */
                       y-=1;
                       break;
                      case 77: /*  */
                       y += 1
                       break;
                     case 72: /*  */
                            x -= 1;
                       break;
                     case 80: /*  */
                            x += 1;
                       break;
                     case 71: /*    */
                          x -= 1;
                       y -= 1;
                       break;
                     case 73: /*    */
                          x -= 1;
                       y += 1;
                       break;
                     case 79: /*    */
                       x += 1;
                       y -= 1;
                       break;
                     case 81: /*    */
                          x += 1;
                       y += 1;
                       break;
                    }
                    if (key.c[1]!Y) xhairs(x,y);

                 }  while (key.c[1]!Y); /*   F1 */

                 /*    */
                 for (i=0;i<14;++i)
                    for (j=0;j<80;j+=2) {
                       *temp= buf[i][j];
                       *(temp+8125)=buf[i][j+1];
                       temp++;
                    }
- - -                                                        - - - 

                                - 155 -

                 return sides;
              }


                 ,    
         ,     . 
                    
     ,               
     .



                                 5.
                                --------

                               
     -----------------------------------------------------------------
               ,    .  
               .    
        ,    . ,  
            .
      ,         ,  
         .      ,  
       ,      
         ""    .
                    
      ,            
       .     ""   
        .          
       .   ,    
     ,           .
       ,       
     ,    IBM PC  ,   ,
            CGA,  EGA  VGA.   
     ,     ,    4.
     ,        4,    
      .



                                  
     -----------------------------------------------------------------

           ,           ,
           ,           
         ,        :
       (          )   
     .     -        ,  
                
     .  ,        
     ,      .    
              ,  
        ().  ,    
          ,  ,  
     .    ,            ,
                .
     ,  ,    4        
      

- - -                                                        - - - 

                                - 156 -

                             int sprite [4][4];

                  
     ,    -     (
                     4).
                
     :

                       start_x, start_y, end_x, end_y

          ,     ,     
     0,0  0,10     :

               sprite[0][0] = 0;   /* start_x */
               sprite[0][1] = 0;   /* start_y */
               sprite[0][2] = 0;   /* end_x */
               sprite[0][3] = 10;  /* end_y */



                                  
     -----------------------------------------------------------------

                         
        (   )  ,    
         .        
     ,             ,      
                   
           .       
      .  ,    ,
              ,     4.
           .



                            
     -----------------------------------------------------------------

                
     .   -    
     .           :  
               ,       
       .        
     .             
           ,     
      4.

             ,   
                  
       "-"           
     .      
       ,       ,    
            .

          ,              ,
          display_object()
       4.

          /*     */

- - -                                                        - - - 

                                - 157 -


          void display_object(ob, sides,cc)
          double ob[][4];
          int sides,cc;
          {
            register int i;

            for(i=0; i<sides; i++)
              line((int)ob[i][0], (int)ob[i][1],
                   (int)ob[i][2], (int)ob[i][3], cc | 128);
         }

             ,   display_object()  
       ,       4  line().
     ,         "" 
       128        .    
     ,    mempoint(),    line() 
        ,    
     "-"  .      
            .

                     
      .      
     (     6x6  )  ,
          .       
          bioskey(),           1  
       ,   .


        #include "dos.h"
        #include "stdio.h"

        void mode(), line();
        void mempoint(), palette();
        void display_object(),update_object();
        unsigned char read_point();

        int sprite[2][4] = {
           3,0,3,5,
           0,3,5,3
        };

        main()
        {
             union k {
                char c[2];
                int i;
             } key;

           int deltax=0,deltay=0;

           mode(4); /*m  4   CGA/EGA */
           palette(0); /*  0 */

           display_object(sprite,2,1);
           do {
                  key.i = bioskey(0);
                  deltax=0;deltay=0;
                  if(!key.c[0]) switch(key.c[1]) {
                     case 75: /*  */
- - -                                                        - - - 

                                - 158 -

                        deltay= -1;
                         break;
                     case 77: /*  */
                        deltay= 1;
                         break;
                     case 72: /*  */
                        deltax= -1;
                        break;
                     case 80: /*  */
                        deltax= 1;
                        break;
                     case 71: /*    */
                        deltay= -1;
                        deltax= -1;
                        break;
                     case 73: /*    */
                        deltay= 1;
                        deltax= -1;
                        break;
                     case 79: /*    */
                        deltay= -1;
                        deltax= 1;
                        break;
                     case 81: /*    */
                        deltay= 1;
                        deltax= 1;
                        break;
                    }
                   /*     */
                   display_object(sprite,2,1);
                   if (is_legal(sprite,deltax,deltay,2))
                   update_object(sprite,deltax,deltay,2);
                   /*      */
                   displey_object(sprite2,1);
               }   while (key.c[0]!='q');
               getchar();
               mode(2);
           }

          /*   */
          void palette(pnum)
          int pnum;
            {
            union REGS r;

            r.h.bh = 1; /*  4-   */
            r.h.bl = pnum;
            r.h.ah = 11;
            int86(0x10, &r, &r);
            }

          /*   */
          void mode(mode_code)
          int mode_code;
            {
            union REGS r;

            r.h.al = mode_code;
            r.h.ah = 0;
            int86(0x10, &r, &r);
- - -                                                        - - - 

                                - 159 -

            }

      /*      
           */
       void line(startx,starty,endx,endy,color)
       int startx,starty,endx,endy,color;
       {
         register int t,distance;
         int x=0,y=0,delta_x,delta_y;
         int incx,incy;

       /*              */
         delta_x=endx-startx;
         delta_y=endy-starty;

       /*   ,
              ,   
                             */
          if (delta_x>0) incx=1;
          else  if (delta_x==0) incx=0;
          else  incx= -1;

          if (delta_y>0) incy=1;
          else  if (delta_y==0) incy=0;
          else  incy= -1;

        /*     */
          delta_xs(delta_x);
          delta_ys(delta_y);
          if (delta_x>delta_y) distancelta_x;
          else distancelta_y;

        /*   */
          for (t=0; t<=distance+1; t++) {
             mempoint(startx,starty,color);
             x+lta_x;
             y+lta_y;
             if (x>distance) {
                x-=distance;
                startx+=incx;
             }
             if (y>distance) {
                y-=distance;
                starty+=incy;
             }
          }
       }


        /*    CGA/EGA */
         void mempoint(x,y,color_code)
         int x,y,color_code;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
- - -                                                        - - - 

                                - 160 -

                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=0xFF3F; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return;
            xor=color_code & 128; /* ,  
                                      " " */
            color_code=color_code & 127; /*    */

            /*        
                   */

             bit_position=y%4; /*   
                                    */
             color_code<<=2*(3-bit_position); /*   
                                           */
             bit_mask.i>>=2*bit_position; /*    
                                            */

             /*       */

              index=x*40+(y%4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */

               if (!xor) {  /*    */
                  t=*(ptr+index) & bit_mask.c[0];
                  *(ptr+index)=t|color_code;
               }
               else {
                  t=*(ptr+index) | (char)0;
                  *(ptr+index)=t & color_code;
               }
            }

        /*      CGA/EGA */
         unsigned char read_point(x,y)
         int x,y;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=3; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return 0;

            /*        
                   */
             bit_position=y%4; /*   
                                    */
- - -                                                        - - - 

                                - 161 -

             bit_mask.i<<=2*(3-bit_position);

             /*       */
              index=x*40+(y>>4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */
               t=*(ptr+index) & bit_mask.c[0];
               t>>=2*(3-bit_position);
               return t;
            }

          /*     */

          void display_object(ob, sides,cc)
          double ob[][4];
          int sides,cc;
          {
            register int i;

            for(i=0; i<sides; i++)
              line((int)ob[i][0], (int)ob[i][1],
                   (int)ob[i][2], (int)ob[i][3], cc|128);
         }

          /*  ( )   ,
           x  y
          */
          void update_object(ob, x, y, sides)
          int ob[][4];        /*  */
          int x, y;           /*   */
          register int sides; /*    */
            {
            sides--;
            for(; sides>=0; sides--)
              {
              ob[sides][0] += x;
              ob[sides][1] += y;
              ob[sides][2] += x;
              ob[sides][3] += y;
              }
            }

          /*    .
           1,   , 0- 
           
          */
          void is_legal(ob, x, y, sides)
          int ob[][4];          /*  */
          int x, y;             /*   */
          int sides;            /*    */
            {
            if(x==0 && y==0)
              return 1;      /*    */

            sides--;
            for(; sides>=0; sides--)
              {
              /*      */
- - -                                                        - - - 

                                - 162 -

              if(ob[sides][0]+x>199 || ob[sides][1]+y>319)
                return 0;
              if(ob[sides][2]+x<0 || ob[sides][3]+y<0)
                return 0;
              }
            return 1;
            }

            ,        .  
        (          <HOME>,
     <PGUP>, <END>  <PGDN>)   .  
                     
     .    -          
      ,   - .  
     is_legal()     
       .        
       ,     .   
        ,     4.

                  ,    
     "" ( )  ,     
        .      
       .     ,  
        .     
           ,     
        .



                
     -----------------------------------------------------------------

                   
           "".            
             ,      
     .  ,  ,     ,
           ,          .    
     ""    (    ).
              
      ,       , 
                
     .          
         .

                     main(),    
      ,          .    
         ("+"),       45 .
        ,       ,
                     .
      swap      .


- - -                                                        - - - 

                                - 163 -

        int sprite2[2][4] = {
           0,0,5,5,
           0,5,5,0
        };

        main()
        {
             union k {
                char c[2];
                int i;
             } key;

           int deltax=0,deltay=0; /*   */
           int swap=0; /*   */

           mode(4); /*  4   CGA/EGA */
           palette(0); /*  0 */

           display_object(sprite,2,1);
           do {
                  key.i = bioskey(0);
                  deltax=0;deltay=0;
                  if(!key.c[0]) switch(key.c[1]) {
                     case 75: /*  */
                        deltay= -1;
                         break;
                     case 77: /*  */
                        deltay= 1;
                         break;
                     case 72: /*  */
                        deltax= -1;
                        break;
                     case 80: /*  */
                        deltax= 1;
                        break;
                     case 71: /*    */
                        deltay= -1;
                        deltax= -1;
                        break;
                     case 73: /*    */
                        deltay= 1;
                        deltax= -1;
                        break;
                     case 79: /*    */
                        deltay= -1;
                        deltax= 1;
                        break;
                     case 81: /*    */
                        deltay= 1;
                        deltax= 1;
                        break;
                    }
                   /*     */
                   if(!swap) displey_object(sprite,2,1);
                   else displey_object(sprite2,2,1);

                   if (is_legal(sprite,deltax,deltay,2)) {
                      update_object(sprite,deltax,deltay,2);
                      update_object(sprite2,deltax,deltay,2);
                   }
- - -                                                        - - - 

                                - 164 -

                   swap= !swap; /*    */
                   /*      */
                   if (!swap) displey_object(sprite,2,1);
                   else displey_object(sprite2,2,1);
               }   while (key.c[0]!='q');
               getchar();
               mode(2);
           }



                         
     -----------------------------------------------------------------

             ,     
       ,      .           
     ,             (,
           ),     ,
       ,      
      .          
           . 
                
           .     
           (  
     ),       
          .



           .
          -----------------

              ,  
         .         
             
      .           
     .           
       ,        .  
              
         .      
                  
      .        
               -
           .  
      ,        
          - .


           .
          ----------------

                  .
     ,         
     ,      ,   
     -   .      
     ,   ,    
          .      
        ,                   
     . ,      ,
      ,          ,  
- - -                                                        - - - 

                                - 165 -

             .

                    .
     ,   "-"    :  
     .                (
     ),        .
      ,       , 
                  ()
       .         ,
             .    ,  
              ,  
               
        .



                         
     -----------------------------------------------------------------

                   ,  
                   .    
        ,          
              .  ,    ,  
       ,     .
             ,   
        ,  .



                             
     -----------------------------------------------------------------

                   ,  
       ,    .


           
          -------------

                         
              ,        .
     ,  ,   
            "".    
        "".     ,
     ,          ,      .
         ,    
        .

          C        :  
                  ,   
        .     
     .   ,        999
     .              
      <Q>.

                       
       .         
       .          
      ("-"),     4. ,
           .
- - -                                                        - - - 

                                - 166 -



              .
          ---------------------------------------

           ""           
         .  ,    
       ,   - ,   
        -   .             ,  
                
      ,  ..    
      .     ,    ,  
            
     .               
     is_legal(),  ,    .

          /*    .
           1,   , 0 - 
           
          */
          void is_legal(ob, x, y, sides)
          int ob[][4];          /*  */
          int x, y;             /*   */
          int sides;          /*    */
            {
            if(x==0 && y==0)
              return 1;    /*    */
            sides--;
            for(; sides>=0; sides--)
              {
              /*      */
              if(ob[sides][0]+x>199 || ob[sides][1]+y>319)
                return 0;
              if(ob[sides][2]+x<0 || ob[sides][3]+y<0)
                return 0;
              /*   */
              if(read_point(ob[sides][0]+x, ob[sides][1]+y)==2)
                return 0;
              if(read_point(ob[sides][2]+x, ob[sides][3]+y)==2)
                return 0;
              }
            return 1;
            }

               :   - 1,   - 2,
      - 3,  () - 0.


           .
          -----------------

          ,     ,    
     .

     _________________________________________________________________

         . 187     
      . (. . ..)
     _________________________________________________________________

- - -                                                        - - - 

                                - 167 -

                .    
      ""  .      
           .

                       
     ,    -   .   
      .

          int human[4][4] = /*    */
               {
               1,     6,     6,     6,
               4,     2,     3,     9,
               9,     1,     6,     6,
               9,     11,    6,     6
               };

          int human2[4][4]                {
               1,     6,     6,     6,
               4,     2,     3,     9,
               9,     3,     6,     6,
               9,     9,     6,     6
               };

          int computer[4][4] = /*     */
               {
               180,     6,     185,     6,
               183,     2,     182,     9,
               188,     1,     185,     6,
               188,     11,    185,     6
               };
          int computer2[4][4]                {
               180,     6,     185,     6,
               183,     2,     182,     9,
               188,     3,     185,     6,
               188,     9,     185,     6
               };



                 
     -----------------------------------------------------------------

                       
     ,   ,            
       - ,   .    
     -     .    
             ,   
          ,    
       ,       
     ,         
     .


- - -                                                        - - - 

                                - 168 -

          int directx,directy; /*   */

          main()
          {
             union k {
                char c[2];
                int i;
             } key;

           int deltax=0,deltay=0;
           int swaph=0,swapc=0;
           int it=COMPUTER;
           long htime,ctime,starttime,curtime; /*   */
           int count;
           mode(4); /*  4   CGA/EGA */
           palette(0); /*  0 */

           load_pic(); /*    */

           time(&starttime); /*   */
           htime=ctime=0;

           display_object(human,4,1);
           display_object(computer,4,3);
           count=0;

           /*    */
           do {
               /*     */
              time(&curtime);
              if (it==COMPUTER) htime+=curtime-starttime;
              else ctime+=curtime-starttime;
              time(&starttime);
              show_score(it,htime,ctime);

              if (bioskey(1)) { /*    */
                  directx=directy=IDLE; /* 
                                 */
                  key.i = bioskey(0);
                  deltax=0;deltay=0;
                  if(!key.c[0]) switch(key.c[1]) {
                     case 75: /*  */
                        deltay= -1;
                        directy=LEFT;
                        break;
                     case 77: /*  */
                        deltay=1;
                        directy=RIGHT;
                        break;
                     case 72: /*  */
                        deltax= -1;
                        directx=UP;
                         deltax= -1;
                        directx=UP;
                        break;
                     case 80: /*  */
                        deltax=1;
                        directx=DOWN;
                        break;
                     case 71: /*    */
- - -                                                        - - - 

                                - 169 -

                        deltay= -1;
                        directy=LEFT;
                        deltax= -1;
                        directx=UP;
                        break;
                     case 73: /*    */
                        deltay=1;
                        directy=RIGHT;
                        deltax= -1;
                        directx=UP;
                        break;
                     case 79: /*    */
                        deltay= -1;
                        directy=LEFT;
                        deltax=1;
                        directx=DOWN;
                        break;
                     case 81: /*    */
                        deltay=1;
                        directy=RIGHT;
                        deltax=1;
                        directx=DOWN;
                        break;
                   }
                 }
                 /*      */
                 if (!swaph) display_object(human,4,1);
                 else display_object(human2,4,1);
                 if (is_legal(human,deltax,deltay,4)) {
                    update_object(human,deltax,deltay,4);
                    update_object(human2,deltax,deltay,4);
                 }
                 /* :    */
                 if (!count && tag(human,computer)) {
                    it= !it; /*   */
                    count=6;
                 }
                 swaph= !swaph; /*     */

                 /*  ""    */
                 if (!swaph) displey_object(human,4,1);
                 else displey_object(human2,4,1);

                 if (!swapc) display_object(computer,4,3);
                 else display_object(computer2,4,3);

                 /*     */
                 if (it==COMPUTER)
                 it_comp_move(computer,computer2,human,4);
                 else
               not_it_comp_move(computer,computer2,directx,directy,4);
                 if (!count && tag(human,computer)) {
                    it= !it;
                    count=6;
               /*  ;     2
                  ,    
               */
                     if (is_legal(computer, 2, 0, 4))
                     {
                        update_object(computer, 2, 0, 4);
- - -                                                        - - - 

                                - 170 -

                       update_object(computer2, 2, 0, 4);
                    }
                   else
                   {
                     update_object(computer, -2, 0, 4);
                     update_object(computer2, -2, 0, 4);
                   }
                }
                swapc = !swapc; /*    */
            /*      */
                if(!swapc) display_object(computer, 4, 3);
                else       display_object(computer2, 4, 3);
                if(count) count--;
             }
             while (key.c[0] !='q' && htime<999 && ctime<999);
             mode(2);
             if(ctime>htime)
                printf(" !");
             else
                printf(" !");
           }


                   
     4-  ,    0    
         .        
       .

           htime    ,   ctime  -
     .    swapc  swaph   
      .    deltax    deltay    
                 .
         directx    directy    
     ,  .    
          . -
       it        ,       
        .       
     ,        #define:  COMPUTER 
     HUMAN.

                    .       
         .      ,   
       -  .           ,  
              
     .        ,       
          .  ,    
     ,         ,     
     ,          
     ,       .   
         .

                   ,  
        ,      .
           ,        
                 
             .   
         ,      
       .

- - -                                                        - - - 

                                - 171 -

            ,    .


              .
          ------------------------------------------------

                  ,  
            
     it_comp_move().      
     .     - ,  
         -.     
         ,      
      .

             it_comp_move().


          /*    , 
                 */
          void it_comp_move(ob1, ob2, human, sides)
          int ob1[][4], ob2[][4], human[][4], sides;
               {
               register int x, y, d; /* d = direction */
               static skip = 0;
               skip++;
               if(skip==3)
                 {
                 skip=0;
                 return;
                 /*     */
                 }
               x = 0;
               y = 0;

        /*    */
          if(human[0][0]<ob1[0][0])
                 x = -1;
               else
                 if(human[0][0]>ob1[0][0])
                   x = 1;
               if(human[0][1]<ob1[0][1])
                 y = -1;
               else
                 if(human[0][1]>ob1[0][1])
                   y = 1;

               if(is_legal(ob1, x, y, sides))
                 {
                 update_object(ob1, x, y, sides);
                 update_object(ob2, x, y, sides);
                 }
               else
                 {
                 if(x && is_legal(ob1, x, 0, sides))
                   {
                   update_object(ob1, x, 0, sides);
                   update_object(ob2, x, 0, sides);
                   }
                 else
                   if(is_legal(ob1, 0, y, sides))
- - -                                                        - - - 

                                - 172 -

                   {
                   update_object(ob1, 0, y, sides);
                   update_object(ob2, 0, y, sides);
                   }
                 }
               }

          ,         3  
     ,     .      
          .

          ,      ,
           ,      
     .     ,   
                
     .


          /*    , 
                  */
          void it_comp_move(ob1, ob2, human, sides)
          int ob1[][4], ob2[][4], human[][4], sides;
               {
               register int x, y, d; /* d = direction */
               static skip = 0;
               skip++;
               if(skip==3)
                 {
                 skip=0;
                 return;
                 /*     */
                 }
               x = 0;
               y = 0;

        /*    */
          if(human[0][0]<ob1[0][0])
                 x = -1;
               else
                 if(human[0][0]>ob1[0][0])
                   x = 1;
               if(human[0][1]<ob1[0][1])
                 y = -1;
               else
                 if(human[0][1]>ob1[0][1])
                   y = 1;

               if(is_legal(ob1, x, y, sides))
                 {
                 update_object(ob1, x, y, sides);
                 update_object(ob2, x, y, sides);
                 }
               else
                 {
                 if(x && is_legal(ob1, x, 0, sides))
                   {
                   update_object(ob1, x, 0, sides);
                   update_object(ob2, x, 0, sides);
                   }
                 else
- - -                                                        - - - 

                                - 173 -

                   if(is_legal(ob1, 0, y, sides))
                   {
                   update_object(ob1, 0, y, sides);
                   update_object(ob2, 0, y, sides);
                   }
                 }
               }

          /*    , 
                   */
          void not_it_comp_move(ob1, ob2, dx, dy, sides)
          int ob1[][4], ob2[][4];
          int dx, dy; /*   
                       "" */
          int sides;
               {
               register int x, y, d;
               static skip = 1;

               skip++;
               if (skip==3)
                 {
                 skip = 0;
                 return;
                 /*      3  */
                 }
               x = 0;
               y = 0;
               /*     */
               x = -dx;
               y = -dy;

               if (is_legal(ob1, x, y, sides))
                 {
                 updte_object(ob1, x, y, sides);
                 updte_object(ob2, x, y, sides);
                 }
               else
                 {
                 if (x && is_legal(ob1, x, 0, sides))
                   {
                   update_object(ob1, x, 0, sides);
                   update_object(ob2, x, 0, sides);
                   }
                 else if (is_legal(ob1, 0, y, sides)) {
                     update_object(ob1, 0, y, sides);
                     update_object(ob2, 0, y, sides);
                     }
                   }
                 }


                  ,    3-
     .


- - -                                                        - - - 

                                - 174 -

             .
          ------------------------------------

                   
       ,            
           . 
             ,     
               .   
     -     .  
      tag()    1,   , 
     0 -   .

          /*       */
          tag(ob1, ob2)
          int ob1[][4], ob2[][4];
               {
               register int i;
               /*    ,  
                         */
               for (i= -1; i<2; i++)
                 if (ob1[0][0]==ob2[0][0]+i && ob1[0][1]==ob2[0][2]+i)
                   return 1;
               return 0;
               }

                tag()   
        .


              TAG.
          --------------------------------

                  TAG, 
       "".        , 
        .


       /*    ""

              "", 
            "".

           ""- ,"" -
          . ,     ,
           .

               
          ,  "" 
                 */

        #define COMPUTER 0
        #define HUMAN 1

        #define IDLE 0
        #define DOWN 1
        #define UP -1
        #define LEFT -1
        #define RIGHT 1

        #include "dos.h"
- - -                                                        - - - 

                                - 175 -

        #include "stdio.h"
        #include "math.h"
        #include "time.h"

        void mode(), line();
        void mempoint(), palette(), xhairs();
        void goto_xy(),show_score();
        void display_object(),update_object();
        void it_comp_move(),not_it_comp_move();
        void save_pic(), load_pic();
        unsigned char read_point();

        int human[4][4] = { /*   */
           1,6,6,6,
           4,2,3,9,
           9,1,6,6,
           9,11,6,6
         };

         int human2[4][4] = {

           1,6,6,6,
           4,2,3,9,
           9,3,6,6,
           9,9,6,6
          };

          int computer[4][4] = { /*   */
            180,6,185,6,
            183,2,182,9,
            188,1,185,6,
            188,11,185,6
          };

          int computer2[4][4] = {
            180,6,185,6,
            183,2,182,9,
            188,3,185,6,
            188,9,185,6
          };

          int directx,directy; /*   */

          main()
          {
             union k {
                char c[2];
                int i;
             } key;

           int deltax=0,deltay=0;
           int swaph=0,swapc=0;
           int it=COMPUTER;
           long htime,ctime,starttime,curtime;
           int count;
           mode(4); /*  4   CGA/EGA */
           palette(0); /*  0 */

           load_pic(); /*    */

- - -                                                        - - - 

                                - 176 -

           time(&starttime); /*   */
           htime=ctime=0;

           display_object(human,4,1);
           display_object(computer,4,3);
           count=0;

           /*    */
           do {
               /*     */
              time(&curtime);
              if (it==COMPUTER) htime+=curtime-starttime;
              else ctime+=curtime-starttime;
              time(&starttime);
              show_score(it,htime,ctime);

              if (bioskey(1)) { /*    */
                  directx=directy=IDLE; /* 
                                 */
                  key.i = bioskey(0);
                  deltax=0;deltay=0;
                  if(!key.c[0]) switch(key.c[1]) {
                     case 75: /*  */
                        deltay= -1;
                        directy=LEFT;
                        break;
                     case 77: /*  */
                        deltay=1;
                        directy=RIGHT;
                        break;
                     case 72: /*  */
                        deltax= -1;
                        directx=UP;
                         deltax= -1;
                        directx=UP;
                        break;
                     case 80: /*  */
                        deltax=1;
                        directx=DOWN;
                        break;
                     case 71: /*    */
                        deltay= -1;
                        directy=LEFT;
                        deltax= -1;
                        directx=UP;
                        break;
                     case 73: /*    */
                        deltay=1;
                        directy=RIGHT;
                        deltax=-1;
                        directx=UP;
                        break;
                     case 79: /*    */
                        deltay= -1;
                        directy=LEFT;
                        deltax=1;
                        directx=DOWN;
                        break;
                     case 81: /*    */
                        deltay=1;
- - -                                                        - - - 

                                - 177 -

                        directy=RIGHT;
                        deltax=1;
                        directx=DOWN;
                        break;
                    }
                 }
                 /*      */
                 if (!swaph) disply_object(human,4,1);
                 else displey_object(human2,4,1);
                 if (is_legal(human,deltax,deltay,4)) {
                    update_object(human,deltax,deltay,4);
                    update_object(human2,deltax,deltay,4);
                 }
                 /* :    */
                 if (!count && tag(human,computer)) {
                    it=!it; /*   */
                    count=6;
                 }
                 swaph= !swaph; /*  ,   */
                 /*  ""    */
                 if (!swaph) disply_object(human,4,1);
                 else disply_object(human2,4,1);

                 if (!swapc) disply_object(computer,4,3);
                 else disply_object(computer2,4,3);

                 /*     */
                 if (it==COMPUTER)
                 it_comp_move(computer,computer2,human,4);
                 else
               not_it_comp_move(computer,computer2,directx,directy,4);
                 if (!count && tag(human,computer)) {
                    it= !it;
                    count=6;
               /*  ;     2
                  ,     */
                     if(is_legal(computer, 2, 0, 4))
                     {
                        update_object(computer, 2, 0, 4);
                       update_object(computer2, 2, 0, 4);
                    }
                   else
                   {
                     update_object(computer, -2, 0, 4);
                     update_object(computer2, -2, 0, 4);
                   }
                }
                swapc = !swapc; /*    */
            /*      */
                if(!swapc) display_object(computer, 4, 3);
                else       display_object(computer2, 4, 3);
                if(count) count--;
             }
             while (key.c[0] !='q' && htime<999 && ctime<999);
             getchar();
             mode(2);
             if(ctime>htime)
                printf(" !");
             else
                printf(" !");
- - -                                                        - - - 

                                - 178 -

           }

          /*      */
          void shou_score(it, htime, ctime)
          int it;
          long htime, ctime;
            {
            goto_xy(24, 6);
            if(it==COMPUTER)
              printf(":%ld", htime);
            else
              printf(":%ld", htime);
            goto_xy(24, 26);
            if(it==HUMAN)
              printf(":%ld", ctime);
            else
              printf(":%ld", ctime);
            }

          /*   */
          void palette(pnum)
          int pnum;
            {
            union REGS r;

            r.h.bh = 1; /*  4-   */
            r.h.bl = pnum;
            r.h.ah = 11;
            int86(0x10, &r, &r);
            }

          /*   */
          void mode(mode_code)
          int mode_code;
            {
            union REGS r;

            r.h.al = mode_code;
            r.h.ah = 0;
            int86(0x10, &r, &r);
            }

      /*      
           */
       void line(startx,starty,endx,endy,color)
       int startx,starty,endx,endy,color;
       {
         register int t,distance;
         int x=0,y=0,delta_x,delta_y;
         int incx,incy;

       /*              */
         delta_x=endx-startx;
         delta_y=endy-starty;

       /*     ,         
          ,       */
          if (delta_x>0) incx=1;
          else if (delta_x==0) incx=0; else incx=-1;

- - -                                                        - - - 

                                - 179 -

          if (delta_y>0) incy=1;
          else  if (delta_y==0) incy=0;
          else  incy=-1;

        /*     */
          delta_xs(delta_x);
          delta_ys(delta_y);
          if (delta_x>delta_y) distancelta_x;
          else distancelta_y;

        /*   */
          for (t=0; t<=distance+1; t++) {
             mempoint(startx,starty,color);
             x+lta_x;
             y+lta_y;
             if (x>distance) {
                x-=distance;
                startx+=incx;
             }
             if (y>distance) {
                y-=distance;
                starty+=incy;
             }
          }
       }


        /*    CGA/EGA */

         void mempoint(x,y,color_code)
         int x,y,color_code;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=0xFF3F; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return;
            xor=color_code & 128; /* ,  
                                      " " */
            color_code=color_code & 127; /*    */

            /*        
                   */

             bit_position=y%4; /*   
                                    */
             color_code<<=2*(3-bit_position); /*   
                                           */
             bit_mask.i>>=2*bit_position; /*    
                                            */

             /*       */
- - -                                                        - - - 

                                - 180 -


              index=x*40+(y%4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */

               if (!xor) {  /*    */
                  t=*(ptr+index) & bit_mask.c[0];
                  *(ptr+index)=t|color_code;
               }
               else {
                  t=*(ptr+index) | (char)0;
                  *(ptr+index)=t & color_code;
               }
            }

        /*      CGA/EGA */
         unsigned char read_point(x,y)
         int x,y;
         {
            union mask {
               char c[2];
               int i;
            } bit_mask;
            int i,index,bit_position;
            unsigned char t;
            char xor; /* " "    
                           */
            char far *ptr=(char far *) 0xB8000000; /*  
                                                   CGA */
            bit_mask.i=3; /* 11111111 00111111 
                                    */
            if (x<0 || x>199 || y<0 || y>319) return 0;

            /*        
                   */
             bit_position=y%4; /*   
                                    */
             bit_mask.i<<=2*(3-bit_position);

             /*       */
              index=x*40+(y>>4);
              if (x%2) index+52; /*  , 
                                         */

              /*   */
               t=*(ptr+index) & bit_mask.c[0];
               t>>=2*(3-bit_position);
               return t;
            }

       /*   */

           void load_pic()
           {
              char fname[80];
              FILE *fp;
              register int i,j;

- - -                                                        - - - 

                                - 181 -

              char far *ptr=(char far *) 0xB8000000; /*  
                                                        CGA  */
              char far *temp;
              unsigned char buf[14][80]; /*    */

              temp=ptr;
         /*       */
              for (i=0;i<14;++i)
                 for (j=0;j<80;j+=2) {
                    buf[i][j]=*temp;
                    buf[i][j+1]=*(temp+8152);
                    *temp=0; *(temp+8152)=0;/*  */
                    temp++;
                 }
              goto_xy(0,0);
              printf(" :");
              gets(fname);
              if (!(fp=fopen(fname,"rb"))) {
                 goto_xy(0,0);
                 printf("    \n");
                 temp=ptr;
         /*    */
                 for (i=0;i<14;++i)
                    for (j=0;j<80;j+=2) {
                       *temp= buf[i][j];
                       *(temp+8125)=buf[i][j+1];
                       temp++;
                    }
                 return;
               }
        /*     */
              for (i=0;i<8152;i++) {
                *ptr=getc(fp); /*   */
                *(ptr+8125)=getc(fp); /*   */
                ptr++;
              }

              fclose(fp);
           }

       /*      */
           void goto_xy(x,y)
           int x,y;
           {
              r.h.ah=2; /*   */
              r.h.dl=y; /*   */
              r.h.dh=x; /*   */
              r.h.bh=0; /* - */
              int86(0x10,&r,&r);
            }

          /*     */

          void display_object(ob, sides,cc)
          double ob[][4];
          int sides,cc;
          {
            register int i;

- - -                                                        - - - 

                                - 182 -

            for(i=0; i<sides; i++)
              line((int)ob[i][0], (int)ob[i][1],
                   (int)ob[i][2], (int)ob[i][3], cc|128);
         }

          /*  ( )   ,
           x  y
          */
          void update_object(ob, x, y, sides)
          int ob[][4];        /*  */
          int x, y;           /*   */
          register int sides; /*    */
            {
            sides--;
            for(; sides>=0; sides--)
              {
              ob[sides][0] += x;
              ob[sides][1] += y;
              ob[sides][2] += x;
              ob[sides][3] += y;
              }
            }

          /*     . 
          1,   , 0 -    */
          is_legal(ob, x, y, sides)
          int ob[][4];        /*  */
          int x, y;           /*   */
          int sides;          /*    */
            {
            if(x==0 && y==0)
              return 1;       /*    */
            sides--;
            for(; sides>=0; sides--)
              {
              /*      */
              if(ob[sides][0]+x>199 || ob[sides][1]+y>319)
                return 0;
              if(ob[sides][2]+x<0 || ob[sides][3]+y<0)
                return 0;
              if(read_point(ob[sides][0]+x, ob[sides][1]+y)==2)
                return 0;
              if(read_point(ob[sides][2]+x, ob[sides][3]+y)==2)
                return 0;
              }
            return 1;
            }

          /*    ,    
          */
            void it_comp_move(ob1,  ob2,  human, sides)
            int ob1[][4],ob2[][4], human[][4], sides;
               {
               register int x, y, d; /* d = direction */
               static skip = 0;
               skip++;
               if(skip==3)
                 {
                 skip=0;
                 return;
- - -                                                        - - - 

                                - 183 -

                 /*     */
                 }
               x = 0;
               y = 0;

        /*    */
          if(human[0][0]<ob1[0][0])
                 x = -1;
               else
                 if(human[0][0]>ob1[0][0])
                   x = 1;
               if(human[0][1]<ob1[0][1])
                 y = -1;
               else
                 if(human[0][1]>ob1[0][1])
                   y = 1;

               if(is_legal(ob1, x, y, sides))
                 {
                 update_object(ob1, x, y, sides);
                 update_object(ob2, x, y, sides);
                 }
               else
                 {
                 if(x && is_legal(ob1, x, 0, sides))
                   {
                   update_object(ob1, x, 0, sides);
                   update_object(ob2, x, 0, sides);
                   }
                 else
                   if(is_legal(ob1, 0, y, sides))
                   {
                   update_object(ob1, 0, y, sides);
                   update_object(ob2, 0, y, sides);
                   }
                 }
               }

          /*    , 
                   */
          void not_it_comp_move(ob1, ob2, dx, dy, sides)
          int ob1[][4], ob2[][4];
          int dx, dy; /*   
                       "" */
          int sides;
               {
               register int x, y, d;
               static skip = 1;

               skip++;
               if (skip==3)
                 {
                 skip = 0;
                 return;
                 /*      3  */
                 }
               x = 0;
               y = 0;
               /*     */
               x = -dx;
- - -                                                        - - - 

                                - 184 -

               y = -dy;

               if (is_legal(ob1, x, y, sides))
                 {
                 updte_object(ob1, x, y, sides);
                 updte_object(ob2, x, y, sides);
                 }
               else
                 {
                 if (x && is_legal(ob1, x, 0, sides))
                   {
                   updte_object(ob1, x, 0, sides);
                   updte_object(ob2,x, 0, sides);

                   }
                 else if (is_legal(ob1, 0, y, sides)) {
                     updte_object(ob1, 0, y, sides);
                     updte_object(ob2, 0, y, sides);
                     }
                   }
                 }

          /*       */
          tag(ob1, ob2)
          int ob1[][4], ob2[][4];
               {
               register int i;
               /*    ,  
                         */
               for (i=-1; i<2; i++)
                 if (ob1[0][0]==ob2[0][0]+i && ob1[0][1]==ob2[0][2]+i)
                   return 1;
               return 0;
               }


                   
       ,    ,            4.
            .   
          .        
     ,       .  
      5-1  5-2          
     ,        .

           ,       AT  PS/2
      50,  60  80,      .  
            PC.   
      ,      .

     _________________________________________________________________

      . 5-1  . 205     
      . (. . ..)
     _________________________________________________________________

     . 5-1.     ""


- - -                                                        - - - 

                                - 185 -

     _________________________________________________________________

      . 5-2  . 205     
     . (. . ..)
     _________________________________________________________________

     . 5-2.     ""




                   
                                 
     -----------------------------------------------------------------

          ,          ,
     ,  ,         TAG.   
       ,  ,     
                -  
     (""  ).           
          -  
       - . ,    
         -  ,    
                 ,      
              .

          ,        ,  
                  ""
          .     ,   
     ,     ,    ,    
        .        !
          ,         
       .
                    , 
          .

          , ,    :        
            "".   
      ,    ""  "",    
       .      
      .
- - -                                                        - - - 
