
                            




                           
                                          
                                  
                                     
                               
                               
                               
                               
                               
                                     
                                  
                                          
                           



                      



- - -                                                          - - - 
                                
                                - 186 -

                                   6
                                  -------

             :   
                                C
     -----------------------------------------------------------------

             p      pp,
      p  p.    p
     p  p,    p,        
     p       p      p
     . p    ,       "p
     ", p     pp    
     p  p      p  
     p ""  ,   p
             p.    ,    p          
     p  p  p,    
              
     p, p  p, p p .

               -   p 
     p  p  ,   ,  p    p
     ,        ,   
     p p   p.

           p    p             p
                
     p  p      p.  -p,     pp
     p   ,  p        p
     p     (    )    
     p.  pp  p       p
     p p  p  p. -p,
       p   p   
     (),          pp  (  p
           )    p       ,
         p  p         
        pp.

          pp, p   ,   p
     IBM PC, XT, AT  PS/2 (      )
       p DOS.           
     p  p p ,  OS/2.




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

          p ,     p         
     p  p          p
       p p p . (  ,
       p    p      p
       p  -  "   p").   
     p  p    p  p    
      p.        p
      p, p  p  p 
             p.  p      
- - -                                                          - - - 
                                
                                - 187 -

     p  ,    p p  p
     p  p ( 1       p)  
       .    p
        p    ,p    
         p p .

              ,  p  p  
     p,      :

          1.  p 
          2.    (  p  - 7 )
          3.   
          4.     

           p        p  p
     p p.

          p p   p      p  
     .      p "p"   
     ,  p ,  p p  "p"  ,
     p    p .  p  p 
      p  , p     
     ,      .    p  
       .    p   
     ,   p        p  "p"  ,
        .  p ()    p
       p    p    .   
     p     ,     
        ,    p   
      ,         p    p
     p.

           ,   p  p ,
       p pp p    .
     p  p  p    (p
     pp p    2 p  pp    
       pp ),     (p
     pp  p    2 p pp  
       pp ).

          p p     p   ( 
     ).   p p p  300
     .    p  p      p  
     (     p p
       1200  2400 ).   p IBM PC p
     p p   9600 .  p   p
       p p   38400 !


                               RS-232
     -----------------------------------------------------------------

          p  ,      p  RS-232    
                      p    p
       p    ,        
     p p      p   RS-232
     (    -    -2)        .
       p     , 
     p  p     p  
       p   pp.
- - -                                                          - - - 
                                
                                - 188 -


          p     p  
     p,     p  ppp  
     p,      p   RS-232.     
     p p p 25 .  ( p IBM PC  AT
       9-    p).    ,  
          p    p
        p  ,  p    p  RS-232.
     p   p     ,      
     p       p   
     p ;  p  p  p ,   
        p,   p RS-232   
                   p
     p  RS-232         p
     p   RS-232  .        p
     RS-232 :

                          pp       p p
        ------                  ------------      ---------------
     p           RTS                 4
                    CTS                 5
     p                DSR                 6
     p  p           DTR                20
     p                  TxD                 2
     p                     RxD                 3
                                GRD                 7


                   ,
          p  p   pp  
     p  p   .          ,    p
        p p,      
      p     .    
         p p p     
     p,   p (1)   p p,
           p   (2)  p    
     p   .

           p (..  ,   p p
     p    ,   p      p   
     )    p        ,        
     pp      p   
     p  p.     ,    p
       ,      p p ,   pp
     ,  p       .    
        p  p  p  .    p
           pepe  p      
     .       p-p    
     p    p-,    p   p
           (..  pp  ),          
     ppp  p (framing error).


- - -                                                          - - - 
                                
                                - 189 -


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

          p p     p
         ,       p    p    
     "--" (CTS),  p  p-p. 
       p    p,       
     "--"         p     
        p.      p,   p   
     p  p    pp  p ,
       p -,   :

     do {
       while(not CTS) wait;
       send(byte);
     } while(bytes to send);

                 p p
       p      p  RS-232, 
              p,  p 
      p p .     
       .



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

          p p p       p
            p      
     p     .  ,    p
         p,  p 
     (  ,    ),        
     ,      p    GRD,  TxD  RxD.
                              p
     p-p   ppp,     
           p          p    
       ,  ,  ppp p.
       p     p 
               p ,   p p
       p .   p RS-232  p-
           p,  p  ,   
       p         p   RS-232.
        p      ,    
     p pp (overrun error).



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

                           p
         p ppp  (),  
                p     "p"     
     p-  p,   p-p   
     p  .   "p"     
      6,  8  20 p 25-p p.     
       pp   p  p pp
        p.   p,   p 
- - -                                                          - - - 
                                
                                - 190 -

        p,      p  .    p
     p   ,   p   p
     p p    p ,    p, 
     p    p  pp  ,
       ppp  "p pp" (oberrun
     error).      ppp , 
     p   p  p ,  pp
      p   p.

           p  ,  p 6, 8  20 
      p- ,   p-p    p
     .  p,    ,     p  p
       .



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

            p p  PC,   
             p
       DOS  p  -BIOS        DOS    BIOS,  
     p  p  p  p.    
       p  p DOS   p  ,
        DOS         p   p       
       p          
     p        p.     
         pp DOS.  p 
     ,    p   pp   p
     p   p    pp,      
      p  p   p   
       ,      p  p p p
                 
     pp -BIOS.

              p    p  p
     p   -BIOS.  p 
     p          pp 14H.  p
     p  .



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

          p     p    
            ,    
     p  ,  ,  p ,  p
     p. ( , p  p  
     pp: p  - 1200 , pp  ,
          p ).  pp 14, 
     0,            p.
       p pp BIOS pp   
     p  p  .  p  L   p
     pp ,  p p        
      p:
- - -                                                          - - - 
                                
                                - 191 -


                              p : 7 6 5 4 3 2 1 0
                                             
                                                    
       p p ()         
       p            
        p     
          


          p  p    p        
       6-1.  p    p     
      6-2.


           6-1
     -----------------------------------------------------------------
          p p p   7, 6  5
             p.

                 p                 
                                 
                   9600                              1  1  1
                   4800                              1  1  0
                   2400                              1  0  1
                   1200                              1  0  0
                    600                              0  1  1
                    300                              0  1  0
                    150                              0  0  1
                    110                              0  0  0
     -----------------------------------------------------------------

           p    p      
                p.  
        p  1,        p
     ;    p     p .  
              p
         pp    .   p ,
     p      
          ,     .
           p      pp    
     p     "1  0",      p  
         .          pp  p
      "1 1",     .


           6-2
     -----------------------------------------------------------------
          p    4  3
             p

                p              
                            
               p               0 0    1 0
               pp          0 1
               pp            1 1
     -----------------------------------------------------------------
- - -                                                          - - - 
                                
                                - 192 -


          pp,     p p 
      p 9600  , pp  ,  p  
             ,            
           p   .     
     p    p 251.

                                    1  1  1  1 1  0  1 1
                                          
          p p ()             
           p          
           p     
             

          p PC pp    
     p  (             ).   
        p   p    pp  DX.  p
      p  p 0,  p - 1  . . ,
     p  ,     int_port(),   
       p p .

     /*   */
     void port_init(port, code)
     int port;
     unsigned char code;

     {
       union REGS r;

       r.x.dx = port; /*  p */
       r.h.ah = 0;    /*   p */
       r.h.al = code; /*   - .  */
       int86(0x14, &r, &r);
     }


                  int86(),   p
      p,      MicroSoft C.  
       p,   int86()  p,   
           (    p
      ),    p  .   pp
            p.
     (                  bioscom(),   
     p p).




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

          pp BIOS 14H,   1      p
             p    p      p,
     p  p  pp  DX.  p   
       p    pp AL.   p p
     p  pp AH.  sport() , p ,
     p    p  p.
- - -                                                          - - - 
                                
                                - 193 -


     /* p    p */
     void sport(port, c)
     int port;                 /* p / */
     char c;                   /* p  */
     {
       union REGS r;
       r.x.dx = port;          /*  p */
       r.h.al = c;             /* p  */
       r.h.ah = 1;             /* p   */
       int86(0x14, &r, &r);
       if(r.h.ah & 128) {      /* p 7-  */
         printf("p  p  ");
         printf(" p");
         exit(1);
       }
     }

            7 pp         
     pp  BIOS,   ppp  p .  
     p p      p; 
        . p  ,   sport()
     p  p    pp    p,      
     p    p pp,   , p
      ,  pp p    p.



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

          pp BIOS  14H,    3    p
      p.   p  p    p,
     p  p  pp  DX.    p 
     ,  p pp,  pp      AL  
     p  ,  p      6-3
       p   pp BIOS.

           6-3
     -----------------------------------------------------------------
             p
     -----------------------------------------------------------------
             (  )
          ,                           

                                                0
           p                                   1
           p                               2
           p                                    3
           p  pp                   4
          p  p                 5
          p  p                           6
             p p                  7


- - -                                                          - - - 
                                
                                - 194 -


            ( AL )
          ,                           

            --                       0
            p--                       1
          p  p              2
                                    3
          --                                   4
          p--                                    5
          p                                         6
          p                       7
     -----------------------------------------------------------------

              ,   p p ,
     p p    ,      
         p    -   p,
        ,       p  
        6-3  p  .  ,        -
     "  "    p  .   p
     p  p        ,  
      p,   p       
     p      .   rport()  ,

        p.   pp   ,  
     p        "
     ". , p   p .


                                 
     -----------------------------------------------------------------
          pp BIOS  14H,    3      
        p.  p  p
     pp  p  p  pp  DX.  
       ,  p pp  BIOS,  p
           pp  AL.    p    
        pp AL  7  pp  A  p  
     p    p -  (
      p).
           rport(), p ,   
      p  p.

     /*    p */
     rport(port)
     int port; /* p / */
     {
       union REGS r;
       /*  p  */
       while(!(check_stat(PORT)&256))
       if(kbhit()) { /*   pp  p */
         getch();
         exit(1);
       }
     r.x.dx = port; /*  p */
     r.h.ah = 2;    /* p   */
     int86(0x14, &r, &r);
     if(r.h.ah & 128)
       printf("  p p  ");
     return r.h.al;
     }
- - -                                                          - - - 
                                
                                - 195 -


          pp         p     p
           p,    p       

      p,   p  ,    
     p  pp.      p 
           ,   p
       p.  p  p  rport()
     p  p p, pp 
     ,  p    .      p 
     kbhit() pp  pp   p.  
        ,    rport() pp  p.
     (  pp  p    - 
       p    ).     kbhit()
        pp p  rport()
       ,        p  ,   
     p,  pp  p.     
     ,  p  pp 14,   2,   p
         p,    p 
     7  pp    p p  p (
       p).      ,       p
        pp.



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

            p           
     pp   p,  p   p
      p      p  ,      
       p  .  Hpp  3.5    
      PS/2   5.5     p
      p IBM - PC, XT, AT. p  p
     p    p         p
       p  p    p  
           p  /  pp.  
          pp,    
       p p    p,  
     p.
               p  
     pp p .  pp p pp
        ;    p  p:  
     p               p,
     p            p      p   
     p ,   ,    p
     p  .     pp 
      p .      ,  pp
      p  ,  p p  
     p   .

            p    p p
       ,          p
     p    p 
     p    .       ,    
     p   pp p  pp
     p      pp  ,    
         .       (p   
     p)           ,
         p  .
- - -                                                          - - - 
                                
                                - 196 -


          pp p            ,
        pp   p  ,    p
       p  p.      p  
     p      p   p,   
      .



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

           p    p         
     ,   ,     
     p  pp,  p       pp
     p    p  p         ,
        pp p .  pp
     p          p            p:
     p-    p   p  
       p    p-p  p  
     (,  p  p  p  ).  p
        p      p-    
                 p       
     p   p-p.

           p p   p,    
         p.     p     p  -
     p p  p .


     send()
     {
        while (    p ){
           send(  );
           wait();
        }
     }
     receive()
     {
        do {
           receive_byte();
           send( p  );
        } while(      );
     }


          p       p         
     p  pp    p-p      ,
           p      p    p
     p,  p  .

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


- - -                                                          - - - 
                                
                                - 197 -


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

             p  p p  
     ,          
         p,         
     p   p    .  p  
       ,          p p
     .   ,   p   , 
     pp?

            ,  p pp  ()  p
          ,       p
     ,     .    p   p ,
     p    pp,  pp  p  
       p     .      
     p,   p p   : EOF (
     End-Of-File)     e        
     .  p  p      
     p p-p  p  .



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

          p     pp      ,
       p    p   p.  
             p  ,  p  
     p  p p,   , p  p
     -p  p  ,   , p
       .   send_file(),  p ,   p 
     p  p  .


     /* p p  */
     void send_file(fname)
     char *fname;
     {
       FILE *fp;
       char ch;
       union {
         char c[2];
         unsigned int count;
       } cnt;

       if(!(fp=fopen(fname,"rb"))) {
         printf("     p\n");
         exit(1);
       }

       send_file_name(fname);  /* p   */

       wait(PORT);  /*  p  */

       /*  pp   */
       cnt.count = filesize(fp);
       /* pp  */
       sport(PORT, cnt.c[0]);
- - -                                                          - - - 
                                
                                - 198 -

       wait(PORT);
       sport(PORT, cnt.c[1]);

       do {
         ch = getc(fp);
         if(ferror(fp)) {
           printf("    \n");
           break;
         }

         /*   p-p */
         if(!feof(fp)) {
           wait(PORT);
           sport(PORT, ch);
         }
       } while(!feof(fp));
       wait(PORT);/*  p   
     */
       fclose(fp);
     }


           send_file_name(), p , 
        p  p .


     /* p   */
     void send_file_name(f)
     char *f;
     {
       printf("  p... \n");
       do {
         sport(PORT, '?');
       } while(!kbhit() && !(check_stat(PORT)&256));
       if(kbhit()) {
         getch();
         exit(1);
       }
       wait(PORT); /*   p  */
       printf("p %s\n\n",f);

       /*  p   */
       while(*f) {
         sport(PORT, *f++);
         wait(PORT); /*   p   */
       }
       sport(PORT,'\0'); /*   p */
     }


            send_file_name()  p    p  
        .    -p,            
     p-p  p  pp p ('?') 
           p  . ( 
     p     .       
      p    p  .   , 
        ,    p   .
     ,      p  p    p p
      pp  p.

- - -                                                          - - - 
                                
                                - 199 -

           wait(), p ,  p 
     p-p,  p   pp   p
     .


     /*   */
     void wait(port)
     int port;
     {
       if(rport(port)!='.') {
         printf("   \n");
         exit(1);
       }
     }

           p, p p    pp
       p.        pp p 
     .

           filesize() p  pp      .  
       ,      p    p
        ,    p      
              pp   ,    
      . p cnt,    pp
     union,   p   ,   
     ,        p      p  p
      p   .



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

          p       p   p   p
     p . -p,  p  pp p
        ( '?').     pp  
         ( p).    
          pp  .   
            .     
          p-  p
     .    p    p  pp  p
     .  rec_file() p .


                            /*   */
     void rec_file()
     {
       FILE *fp;
       char ch;
       char fname[14];
       union {
         char c[2];
         unsigned int count;
       } cnt;

       get_file_name(fname); /*    */

       printf("   %s\n",fname);
       remove(fname);
       if(!(fp=fopen(fname, "wb"))) {
- - -                                                          - - - 
                                
                                - 200 -

         printf("  p   \n");
         exit(1);
       }

       /*    */
       sport(PORT, '.'); /* p */
       cnt.c[0] = rport(PORT);
       sport(PORT, '.'); /* p */
       cnt.c[1] = rport(PORT);
       sport(PORT, '.'); /* p */

       for(; cnt.count; cnt.count--) {
         ch = rport(PORT);
         putc(ch, fp);
         if(ferror(fp)) {
           printf("     ");
           exit(1);
         }
         sport(PORT, '.'); /* p */
       }
       fclose(fp);
     }

           get_file_name() p .

     /*    */
     void get_file_name(f)
     char *f;
     {
       printf(" ...\n");
       while(rport(PORT)!='?') ;
       sport(PORT, '.'); /* p */
       while((*f=rport(PORT))) {
         if(*f!='?') {
           f++;
           sport(PORT, '.'); /* p */
         }
        }
      }




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

          , p  p pp  p
       p,           p,
     p     pp.  pp p 
      p   0 - p   p;
     ,      pp PORT   
     pp,    p p.

     /*   pp p , 
          pp p .
          p p  pp:
               p p - 9600 ,
               p /  p,
                 ,
                p -.
- - -                                                          - - - 
                                
                                - 201 -

     */
     #define PORT 0
     #include "dos.h"
     #include "stdio.h"

     unsigned int filesize();
     void sport(), send_file(), rec_file(), send_file_name();
     void get_file_name(), port_init(), wait();

     main(argc,argv)
     int argc;
     char *argv[];
     {
       if(argc<2) {
      printf("  p TRANS S < >  TRANS R\n");
         exit(1);
       }

       printf(" p pp .  p\n");
       printf("p   .\n\n");

       port_init(PORT, 231); /*   p
                             */

       if(tolower(*argv[1]) == 's') send_file(argv[2]);
       else rec_file();
     }
     /* p p  */
     void send_file(fname)
     char *fname;
     {
       FILE *fp;
       char ch;
       union {
         char c[2];
         unsigned int count;
       } cnt;

       if(!(fp=fopen(fname,"rb"))) {
         printf("     p\n");
         exit(1);
       }

       send_file_name(fname);  /* p   */

       wait(PORT);  /*  p  */

       /*  pp   */
       cnt.count = filesize(fp);
       /* pp  */
       sport(PORT, cnt.c[0]);
       wait(PORT);
       sport(PORT, cnt.c[1]);

       do {
         ch = getc(fp);
         if(ferror(fp)) {
           printf("    \n ");
           break;
         }
- - -                                                          - - - 
                                
                                - 202 -


         /*   p-p */
         if(!feof(fp)) {
           wait(PORT);
           sport(PORT, ch);
         }
       } while(!feof(fp));
       wait(PORT);/*  p   
     */
       fclose(fp);
     }

     /* p  */
     void rec_file()
     {
       FILE *fp;
       char ch;
       char fname[14];
       union {
         char c[2];
         unsigned int count;
       } cnt;

       get_file_name(fname); /*    */

       printf("  %s\n",fname);
       remove(fname);
       if(!(fp=fopen(fname, "wb"))) {
         printf("  p   \n");

         exit(1);
       }

       /*    */
       sport(PORT, '.'); /* p */
       cnt.c[0] = rport(PORT);
       sport(PORT, '.'); /* p */
       cnt.c[1] = rport(PORT);
       sport(PORT, '.'); /* p */

       for(; cnt.count; cnt.count--) {
         ch = rport(PORT);
         putc(ch, fp);
         if(ferror(fp)) {
           printf("    ");
           exit(1);
         }
         sport(PORT, '.'); /* p */
       }
       fclose(fp);
     }

     /* p      */
     unsigned int filesize(fp)
     FILE *fp;
     {
       unsigned long int i;

       i = 0;
       do {
- - -                                                          - - - 
                                
                                - 203 -

         getc(fp);
         i++;
       } while(!feof(fp));
       rewind(fp);
       return (i-1); /*    EOF */
     }

     /* p   */
     void send_file_name(f)
     char *f;
     {
       printf("  p... \n");
       do {
         sport(PORT, '?');
       } while(!kbhit() && !(check_stat(PORT)&256));
       if(kbhit()) {
         getch();
         exit(1);
       }
       wait(PORT); /*   p  */
       printf("p %s\n\n",f);

       /*  p   */
       while(*f) {
         sport(PORT, *f++);
         wait(PORT); /*   p   */
       }
       sport(PORT, '\0'); /*   p */
     }

     /*    */
     void get_file_name(f)
     char *f;
     {
       printf("  ...\n");
       while(rport(PORT)!='?');
       sport(PORT, '.');     /* p */
       while((*f=rport(PORT))) {
         if(*f!='?') {
           f++;
           sport(PORT, '.'); /* p */
         }
        }
      }

     /*   */
     void wait(port)
     int port;
     {
       if(rport(port)!='.') {
         printf("   \n");
         exit(1);
       }
     }

     /* p    p */
     void sport(port, c)
     int port; /* p / */
     char c;   /* p  */
     {
- - -                                                          - - - 
                                
                                - 204 -

       union REGS r;

       r.x.dx = port; /*  p */
       r.h.al = c; /*   p */
       r.h.ah = 1; /*  p  */
       int86(0x14, &r, &r);
       if(r.h.ah & 128) {
       printf(" p p    p ");
         exit(1);
       }
     }

     /*     p */
     rport(port)
     int port; /* p / */
     {
       union REGS r;

       /*   */
       while(!(check_stat(PORT)&256))
         if(kbhit()) { /* p p  pp 
                          p */
           getch();
           exit(1);
         }

       r.x.dx = port; /*  p */
       r.h.ah = 2; /*     */
       int86(0x14, &r, &r);
       if(r.h.ah & 128)
        printf(" p     p ");
       return r.h.al;
     }

     /* p   p */
     cheek_stat(port)
     int port; /* p / */
     {
       union REGS r;

       r.x.dx = port; /*  p  */
       r.h.ah = 3;    /*   */
       int86(0x14, &r, &r);
       return r.x.ax;
     }

     /*  p
     */
     void port_init(port, code)
     int port;
     unsigned char code;
     {
       union REGS r;

       r.x.dx = port; /*  p */
       r.h.ah = 0;    /*   p*/
       r.h.al = code; /*   - .  */
       int86(0x14, &r, &r);
     }

- - -                                                          - - - 
                                
                                - 205 -



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

          pp p p        
     pp       p.        pp
     p     TRANS  .      p
     ,    p :

                            TRANS S <_>,

            <_>  -   , p p p 
     p p p  p.

               :

                            TRANS R

          p       p            
              ,      p  
      p  p p   p  -
     .



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

          pp p       ,
     p         .   ,     p
      pp     p  p  p
     ,    p      
     .         ,   ,      
     p  pp,     .

                p  p p
        p ""    
     ,  p      p
           p.      
     p    p.  ,    ,   

     p cp  p        
     p p . p p   
       pp  .

            p pp ,   
       p ,   ,    pp
     p p p .    ,  
       p     pp p 
             p,       
       .        p p  
     ,    pp  ,     p  
         p                  
     p p .

          , ,                p
           p p . 
       pp        p   p   p
      p p   p  p.
- - -                                                          - - - 
                                
                                - 206 -




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

              ()      
     p  p    p.
        p  ,    pp  
      p p.    
      p  . p    
      p  ,  p  p  p
      p  pp   p  p. 
                 .
     ,     p   p  p
     p ,  p   p 
     .  -p,   p (    p  
     pp)         p.  -p,
     p   pp     ,
       p p p  
     .  -p,    p,      ,
            pp 
     p p      ,      
      p  p.
          p,             
     p  .         p
     p-p   p     p
     p .  p p    
      (file  server).  p,     
     ,         p      
                (nodes),  p
     (terminals)  p  (workstations).

                pp p
     6-1.      pp  pp    p
     .            pp   
     p.         "pp" 
          pp   p 
        p         .
     pp,  p   pp,  p
                .  
     p,      p  pp
     ,       p  p p
      p   .        
     pp       p    p  pp  
     pp  .



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

                  p    p
             p  
          p    .    
     p   p        p  ,
         "r"    "s"    p.   "s" 
     p  p ;   "r"  p  
       ( p )    .

- - -                                                          - - - 
                                
                                - 207 -

     _________________________________________________________________

          ""

                                        
                        
                                  
                                  

                                                
                                                

                                         
                         
                                   
                                   

     _________________________________________________________________

             ""
                                
                                
                              
                              

                                  
                                  
                                           
                
                             
                                     
                                  
                                  

                                
                                
                              
                              
     _________________________________________________________________

          . 6.1.    p .

          p pp            p  pp,
      p       p  ,
                ,         
      p     p
        p  p .  
       p    p    
     pp p   p  .

             p      p .
       pp,        p,   
     p   p   p 
        p (   ).

     main()
     {

       printf("  ./n");
       printf("    ./n/n");
- - -                                                          - - - 
                                
                                - 208 -


       port_init(PORT); /*   p */

       do {
         /* p  p   */
         if(check_stat(PORT)&256) {
           switch(rport(PORT)) {
             case 's': send_file(PORT);
               break;
             case 'r': rec_file(PORT);
               break;
           }
         }

     /*************************************
     p   p 
     p   p
      p ...

         if(check_stat(PORT1)&256) {
           switch(rport(PORT1)) {
             case 's': send_file(PORT1);
               break;
             case 'r': rec_file(PORT1);
               break;
           }
         }
     .
     .
     .
         if(check_stat(PORTn)&256) {
           switch(rport(PORTn)) {
             case 's': send_file(PORTn);
               break;
             case 'r': rec_file(PORTn);
               break;
           }
         }
     ******************************************/
       } while(!kbhit());
     }

           ,    p    p
      ( ),  ,    p, 
      p  p   N    .  ,  
       p   p,    pp
       p.                
       p p p  p/
     .

               ,    send_file()    rec_file()
     p    p p,  p p  
     p.        p   
        p  p.   
            p  p  
            p  p 
       .    send_file()   rec_file()
      p    p .


- - -                                                          - - - 
                                
                                - 209 -


     /* p p  p  p
     */
     void send_file(port)
     int port;
     {
       FILE *fp;
       char ch, fname[14];
       union {
         char c[2];
         unsigned int count;
       } cnt;

       sport(port, '.'); /* p */

       get_file_name(fname, PORT);
       if(!(fp=fopen(fname,"rb"))) {
         printf("     p\n");
         exit(1);
       }

       if(rport(port)!='.') {
          printf(" p p   \n");
          exit(1);
       }

       printf("p  %s\n", fname);
       /* p pp  */
       cnt.count = filesize(fp);
       /* p pp  */
       sport(port, cnt.c[0]);
       wait(port);

       sport(port, cnt.c[1]);
       do {
         ch = getc(fp);
         if(ferror(fp)) {
            printf("   \n");
            break;
         }

         /*  */
         if(!feof(fp)) {
           wait(port);
           sport(port, ch);
         }
       } while(!feof(fp));
       wait(port); /*  p   p*/
       fclose(fp);
     }

     /*  p  p*/
     void rec_file(port)
     int port;
     {
       FILE *fp;
       char ch, fname[14];
       union {
         char c[2];
         unsigned int count;
- - -                                                          - - - 
                                
                                - 210 -

       } cnt;

       sport(port, '.'); /* p */

       get_file_name(fname, PORT);

       printf("  %s\n", fname);
       remove(fname);
       if(!(fp=fopen(fname,"wb"))) {
         printf("     p\n");
         exit(1);
       }

       /*  */
       sport(port, '.');
       cnt.c[0] = rport(port);
       sport(port, '.');
       cnt.c[1] = rport(port);
       sport(port, '.');

       for(; cnt.count; cnt.count--) {
         ch = rport(port);
         putc(ch, fp);
         if(ferror(fp)) {
           printf(" p  \n");
           exit(1);
         }
         sport(port, '.');
       }
       fclose(fp);
     }


           pp,  p  , p
     .   pp  p   0.  ,  
          ,       
     pp  pp ( .   p  
       )  p p  .


     /* p   . pp p:
               p p - 9600 ,
               p        . ,
                 ,
                p -.
     */

     #define PORT 0

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

     unsigned int filesize();
     void sport(), send_file(), rec_file(), send_file_name();
     void get_file_name(), port_init(), wait();

     main()
     {

- - -                                                          - - - 
                                
                                - 211 -

       printf("  .\n");
       printf("    ./n/n");


       port_init(PORT); /*   p */

       do {
        /* p  p */
        if(check_stat(PORT)&256) {
          switch(rport(PORT)) {
             case 's': send_file(PORT);
               break;
             case 'r': rec_file(PORT);
               break;
           }
         }
     /*****************************************
     p   p 
     p  . p, 
     p ...

        if(check_stat(PORT1)&256) {
          switch(rport(PORT1)) {
             case 's': send_file(PORT1);
               break;
             case 'r': rec_file(PORT1);
               break;
           }
         }
     .
     .
     .
        if(check_stat(PORTn)&256) {
          switch(rport(PORTn)) {
             case 's': send_file(PORTn);
               break;
             case 'r': rec_file(PORTn);
               break;
           }
         }
     ******************************************/
       } while(!kbhit());
     }

     /* p p  p  p
     */
     void send_file(port)
     int port;
     {
       FILE *fp;
       char ch, fname[14];
       union {
         char c[2];
         unsigned int count;
       } cnt;

       sport(port, '.'); /* p */

       get_file_name(fname, PORT);
       if(!(fp=fopen(fname,"rb"))) {
- - -                                                          - - - 
                                
                                - 212 -

         printf("     p\n");
         exit(1);
       }

       if(rport(port)!='.') {
          printf(" p p   \n");
          exit(1);
       }

       printf("p  %s\n", fname);
       /* p pp  */
       cnt.count = filesize(fp);
       /* p pp  */
       sport(port, cnt.c[0]);
       wait(port);

       sport(port, cnt.c[1]);
       do {
         ch = getc(fp);
         if(ferror(fp)) {
            printf("   \n");
            break;
         }

         /*  */
         if(!feof(fp)) {
           wait(port);
           sport(port, ch);
         }
       } while(!feof(fp));
       wait(port); /*  p   p*/
       fclose(fp);
     }

     /*p p  p 
     p.*/
     void rec_file(port)
     int port;
     {
       FILE *fp;
       char ch, fname[14];
       union {
         char c[2];
         unsigned int count;
       } cnt;

       sport(port, '.'); /* p */

       get_file_name(fname, PORT);

       printf("  %s\n", fname);
       remove(fname);
       if(!(fp=fopen(fname,"wb"))) {
         printf("     p\n");
         exit(1);
       }

       /*  */
       sport(port, '.');
       cnt.c[0] = rport(port);
- - -                                                          - - - 
                                
                                - 213 -

       sport(port, '.');
       cnt.c[1] = rport(port);
       sport(port, '.');

       for(; cnt.count; cnt.count--) {
         ch = rport(port);
         putc(ch, fp);
         if(ferror(fp)) {
           printf(" p  \n");
           exit(1);
         }
         sport(port, '.');
       }
       fclose(fp);
     }

     /* p      */
     unsigned int filesize(fp)
     FILE *fp;
     {
       unsigned long int i;

       i = 0;
       do {
         getc(fp);
         i++;
       } while(!feof(fp));
       rewind(fp);
       return (i-1); /*    EOF */
     }

     /* p   */
     void send_file_name(f, port)
     char *f;
     int port;
     {
       do {
         sport(port, '?');
       } while(!kbhit() && !(check_stat(port)&256));
       if(kbhit()) {
         getch();
         exit(1);
       }
       wait(port);

       while(*f) {
         sport(port, *f++);

         wait(port); /*   p   */
       }
       sport(port, 0); /*   p */
     }

     /*    */
     void get_file_name(f, port)
     char *f;
     int port;
     {

       while(rport(port)!='?') printf(".");
- - -                                                          - - - 
                                
                                - 214 -

       sport(port, '.');
       while((*f=rport(port))) {
         if(*f!='?') {
           f++;
           sport(port, '.');
         }
        }
        sport(port, '.');
      }

     /*   */
     void wait(port)
     int port;
     {
       if(rport(port)!='.') {
         printf("   \n");
         exit(1);
       }
     }

     /* p    p */
     void sport(port, c)
     int port;                 /* p / */
     char c;                   /* p  */
     {
       union REGS r;

       r.x.dx = port;          /*  p */
       r.h.al = c;             /* p  */
       r.h.ah = 1;             /* p   */
       int86(0x14, &r, &r);
       if(r.h.ah & 128) {      /* p 7-  */
       printf("p  p   p ");
       printf("%d",r.h.ah);
         exit(1);
       }
     }

     /*    p */
     rport(port)
     int port; /* p / */
     {
       union REGS r;
       /*  p  */
     while(!(check_stat(port)&256))
       if(kbhit()) { /*   pp  p */
         getch();
         exit(1);
       }

     r.x.dx = port; /*  p */
     r.h.ah = 2;    /*    */
     int86(0x14, &r, &r);
     if(r.h.ah & 128)
       printf("  p p  ");
     return r.h.al;
     }

     /* pp   p */
     check_stat(port)
- - -                                                          - - - 
                                
                                - 215 -

     int port; /* p / */
     {
       union REGS r;

       r.x.dx = port; /*  p  */
       r.h.ah = 3;    /*   */
       int86(0x14, &r, &r);
       return r.x.ax;
     }

     /*  p  pp:
     p p 9600 ,  -,
     p    ., 8  .
     */
     void port_init(port)
     int port;
     {
       union REGS r;

       r.x.dx = port; /*  p */
       r.h.ah = 0;    /*   p*/
       r.h.al = 231; /*   - .  */
       int86(0x14, &r, &r);
     }



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

           ,    p  p p 
              p,  p
         pp.   pp   
     GET   p ,  p    .
           p       pp    
     pp p  DOS.   p  pp
     GET  :

                              GET <_>

           <_> -  p .

          p p    GET     
     p p p ,    
     .

          -p  rec_file() p   p
     -.

          -p,  p  p  pp,  
     p pp   p,    
      .

            pp GET p .


     /* p    . */

     #define PORT 0

- - -                                                          - - - 
                                
                                - 216 -

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

     void sport(), send_file(), rec_file(), send_file_name();
     void get_file_name(), port_init(), wait();

     main(argc,argv)
     int argc;
     char *argv[];
     {
       if(argc!=2) {
         printf("  p: GET < >\n");
         exit(1);
       }

       port_init(PORT); /*   p */

         rec_file(argv[1]);
       }
       /* */
     void rec_file(fname)
     char *fname;
     {
       FILE *fp;
       char ch;
       union {
         char c[2];
         unsigned int count;
       } cnt;

       printf("p  %s\n", fname);
       remove(fname);
       if(!(fp=fopen(fname,"wb"))) {
         printf("     p\n");
         exit(1);
       }

       sport(PORT, 's');     /*p  pp
                               "  p "*/
       wait(PORT);         /*    */

       /*    */
       send_file_name(fname);

       sport(PORT, '.'); /* p */
       cnt.c[0] = rport(PORT);
       sport(PORT, '.'); /* p */
       cnt.c[1] = rport(PORT);
       sport(PORT, '.'); /* p */

       for(; cnt.count; cnt.count--) {
         ch = rport(PORT);
         putc(ch, fp);
         if(ferror(fp)) {
           printf("    ");
           exit(1);
         }
         sport(PORT, '.'); /* p */
       }
       fclose(fp);
- - -                                                          - - - 
                                
                                - 217 -

     }

     /* p   */
     void send_file_name(f)
     char *f;
     {
       do {
         sport(PORT, '?');
       } while(!kbhit() && !(check_stat(PORT)&256));
       if(kbhit()) {
         getch();
         exit(1);
       }
       wait(PORT);

       while(*f) {
         sport(PORT, *f++);
         wait(PORT);
       }
       sport(PORT, '\0'); /*   p */
       wait(PORT);
     }
     /*  (p)*/
     void wait(port)
     int port;
     {
       if(rport(port)!='.') {
         printf("   \n");
         exit(1);
       }
     }

     /* p    p */
     void sport(port, c)
     int port;                 /* p / */
     char c;                   /* p  */
     {
       union REGS r;

       r.x.dx = port;          /*  p */
       r.h.al = c;             /* p  */
       r.h.ah = 1;             /* p   */
       int86(0x14, &r, &r);
       if(r.h.ah & 128) {      /* p 7-  */
       printf("p  p   p ");
       printf("%d",r.h.ah);
         exit(1);
       }
     }

     /*    p */
     rport(port)
     int port; /* p / */
     {
       union REGS r;

       /*  p  */
     while(!(check_stat(port)&256))
       if(kbhit()) {
         getch();
- - -                                                          - - - 
                                
                                - 218 -

         exit(1);
       }

     r.x.dx = port; /*  p */
     r.h.ah = 2;    /*    */
     int86(0x14, &r, &r);
     if(r.h.ah & 128)
       printf("  p p  ");
     return r.h.al;
     }

     /* pp   p */
     check_stat(port)
     int port; /* p / */
     {
       union REGS r;

       r.x.dx = port; /*  p  */
       r.h.ah = 3;    /*   */
       int86(0x14, &r, &r);
       return r.x.ax;
     }

     /*  p  pp:
     p p 9600 ,  -,
     p    ., 8  .
     */
     void port_init(port)
     int port;
     {
       union REGS r;

       r.x.dx = port; /*  p */
       r.h.ah = 0;    /*   p*/
       r.h.al = 231; /*   - .  */
       int86(0x14, &r, &r);
     }



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

                    p  
           p,   p 
     p p -         p.  
     p        pp  pp  PUT.
     pp PUT           p    
       p          .
       pp     pp
     GET  (    ,        p
     p).   p  pp:

                              PUT <_>

          p   pp   PUT   p   
     p      pp,   p     p
     pp .

            pp PUT p .
- - -                                                          - - - 
                                
                                - 219 -



     #define PORT 0

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

     unsigned int filesize();
     void sport(), send_file(), send_file_name();
     void wait(), port_init(), wait();

     main(argc,argv)
     int argc;
     char *argv[];
     {
       if(argc!=2) {
         printf("  p GET < >\n");
         exit(1);
       }

       port_init(PORT); /*   p */

       send_file(argv[1]);
       }

     /* p p  */
     void send_file(fname)
     char *fname;
     {
       FILE *fp;
       char ch;
       union {
         char c[2];
         unsigned int count;
       } cnt;

       if(!(fp=fopen(fname,"rb"))) {
         printf("     p\n");
         exit(1);
       }
       printf("p  %s\n", fname);

     /* p  .*/
       sport(PORT, 'r'); /* pp   p 
                              */
       wait(PORT);/*   .*/

       send_file_name(fname);  /* p   */

       if(rport(PORT)!='.') {
         printf(" p p   \n");
         exit(1);
       }

      /*  pp   */
       cnt.count = filesize(fp);

       /* p pp */
       sport(PORT, cnt.c[0]);
       wait(PORT);
- - -                                                          - - - 
                                
                                - 220 -

       sport(PORT, cnt.c[1]);

       do {
         ch = getc(fp);
         if(ferror(fp)) {
           printf("    \n");
           break;
         }

         /*   p-p */
         if(!feof(fp)) {
           wait(PORT);
           sport(PORT, ch);
         }
       } while(!feof(fp));
       wait(PORT);/*   p  p*/
       fclose(fp);
     }

     /* p      */
     unsigned int filesize(fp)
     FILE *fp;
     {
       unsigned long int i;

       i = 0;
       do {
         getc(fp);
         i++;
       } while(!feof(fp));
       rewind(fp);
       return (i-1); /*    EOF */
     }

     /* p   */
     void send_file_name(f)
     char *f;
     {
       do {
          sport(PORT, '?');
       } while(!kbhit() && !(check_stat(PORT)&256));
       if(kbhit()) {
         getch();
         exit(1);
       }
       wait(PORT);

       while(*f) {
         sport(PORT, *f++);
         wait(PORT);
       }
       sport(PORT, '\0'); /*   p */
       wait(PORT);
     }

     /*   */
     void wait(port)
     int port;
     {
       if(rport(port)!='.') {
- - -                                                          - - - 
                                
                                - 221 -

         printf("   \n");
         exit(1);
       }
     }

     /* p    p */
     void sport(port, c)
     int port; /* p / */
     char c;   /* p  */
     {
       union REGS r;

       r.x.dx = port; /*  p */
       r.h.al = c; /*   p */
       r.h.ah = 1; /*  p  */
       int86(0x14, &r, &r);
       if(r.h.ah & 128) {
       printf(" p   p %d",r.h.ah);
         exit(1);
       }
     }

     /*     p */
     rport(port)
     int port; /* p / */
     {
       union REGS r;

       /*   */
       while(!(check_stat(PORT)&256))
         if(kbhit()) {
           getch();
           exit(1);
         }

       r.x.dx = port; /*  p */
       r.h.ah = 2; /*     */
       int86(0x14, &r, &r);
       if(r.h.ah & 128)
         printf("     p ");
       return r.h.al;
     }

     /* p   p */
     cheek_stat(port)
     int port; /* p / */
     {
       union REGS r;

       r.x.dx = port; /*  p  */
       r.h.ah = 3;    /*   */
       int86(0x14, &r, &r);
       return r.x.ax;
     }

     /*  p pp:
               p p - 9600 ,
               p        . ,
                 ,
                p -.
- - -                                                          - - - 
                                
                                - 222 -

     */
     void port_init(port)
     int port;
     {
       union REGS r;

       r.x.dx = port; /*  p */
       r.h.ah = 0;    /*   p*/
       r.h.al = 231; /*   - .  */
       int86(0x14, &r, &r);
     }



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

            p      
        p p.  p 
     -                 pp
        GET.EXE  PUT.EXE.  p  
     ,    GET,  p  p  
           PUT.



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

              p   p        
     p        
      p   pp    
     p  p.           
      'd' (directory)   p    p  .  
     p  p       
     p         pp.   ,      
     p  ,      'd'  p
             p  
                   p  p
       .    p
        p ,     dir 
      p.

           p  pp p 
     p         RUN, 
      p           ,
     p    p   .

          p ,      p    
       p    p  ,       
     p p p .

                       
       pp p      (p
     )  p     .

- - -                                                          - - - 
                                
                                - 223 -



                                   7
                                  -------

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

            -      ?
                 ,
           .  ,
               
       .        
      ,      
     .  ,       ,
          .     
             
         .

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

                 
      BASIC,     "SMALL  BASIC".  BASIC  
       C,    BASIC  ,   C 
       .       ,
         C    ,      BASIC - 
              ,       
         .    ,      
      BASIC,      ,   
               .
     ,    ,     
     ,     ,     
       ,   C.          BASIC,  
     ,    SMALL BASIC   
     .

                : 
      .



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

                       
       ,   
     ,    (10-X)/23,    ,   
            .      C:  The Complete
     Reference   (Osborne/McGraw-uill,   1987)      
- - -                                                          - - - 
                                
                                - 224 -

          .    
      ,      ,    
       ,  (,    ) 
         SMALL BASIC  
         .  (       
             ,       
                  
     : The Compelete Reference.

                  
     ,         ,   
             
       .    ,     
     ,            
       .

           ,                 
      ,          
     .        
     .



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

                      
      ,          
     .      ,          
          :

           - 
           -   + - / * ^ % = () <> ; ,
           - 
           - 

           '^'   ,     '=' 
       ,       
     .            
      .

             :

      7-8 (100-5)*14/6
      a+b-c
      10^5
      a=7-b

           '=', '>', '<', ',', ';'  ,  
              IF,
     PRINT   .  (,    
     C                    
     ).

                 BASIC,        
     .               
        :
- - -                                                          - - - 
                                
                                - 225 -


               ()
                     ^
                     *  /  %
                     +  -
               =

               .

            SMALL BASIC ,   
       .      
            (      A      Z).   
        BASIC        
          ,  (,   
     27),           
          SMALL BASIC  
      .   ,     
         ,  ,   "a"  "A" 
             .  ,    
       ,        
                 .   
               ,
       ,            
           .

          ,           
       .        
           .



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

           ,             ,
           ,        
       ,  ,  
     . , 

                                 *-(W+10)

         "",  "*",  "", "-", "(", "W", "+", "10" 
     ")".             
     .             
      .  ,    
     ,      :  (1)   
      ,  (2)      ,  (3)
       ,       ,
     (4)   .

                :      .
         -     ,     
        -   . ,
     "PRINT"  -        PRINT  BASIC.  
             ,         
        ,     
     -,           
                      
     .        
     ,          ,     
- - -                                                          - - - 
                                
                                - 226 -

               
     .      .  ,   PRINT 
         1,   INPUT -  2    ..
                   ,  
     ,   ,    ,  
     ,   .     
      ,            
                     
     .  ,          .
     ,       ,   
                      
     .

             ,     .  ,
         ,      
      ,    .   
                 ,      
         .

          ,        ,
      get_token( ).        ,    
        SMALL   BASIC,            ,
              (\0).  
     get_token()      ,      
     ,           
         .   get_token(),
      ,     prog.     prog
         ,      
     get_token         
     .

          ,     ,   
      :  DELIMITER,  VARIABLE,  NUMBER,  COMMAND,  STRING 
     QUOTE   (,   ,   ,  ,    
     ).  VARIABLE   .    DELIMITER
        .   NUMBER -  .  
     COMMAND -      SMALL  BASIC.    STRING  
         get_token()     .  
     QUOTE         ,   
     .      token_type   .
                   
      tok.

                    get_token().      
            
            .


          #define DELIMITER  1
          #define VARIABLE   2
          #define NUMBER     3
          #define COMMAND    4
          #define STRING     5
          #define QUOTE      6
          #define FINISHED   10
          #define EOL        9
- - -                                                          - - - 
                                
                                - 227 -


          extern char token[80];
          extern int tok, token_type;
          extern char *prog;  /*    */
          /*   */
          get_token()
          {
            register char *temp;

            token_type=0; tok=0;
            temp=token;

            if(*prog=='\0')  { /*   */
              *token=0;
              tok=FINISHED;
              return(token_typeLIMITER);
             }

             while(iswhite(*prog)) ++prog;  /*   */

             if(*prog=='\r') { /* crtl */
               ++prog; ++prog;
               tok= EOL; *token='\r';
               token[1]='\n';token[2]=0;
               return (token_type = DELIMITER);
             }

             if(strchr("+-*^/%=;(),><", *prog)) { /*  */
               *temp=*prog;
               prog++; /*     */
               temp++;
               *temp=0;
               return (token_typeLIMITER);
             }

             if(*prog=='"')  { /*    */
              prog++;
               while(*prog != '"' && *prog!='\r') *temp++=*prog++;
               if(*prog=='\r') serror(1);
               prog++;*temp=0;
               return(token_type=QUOTE);
             }

             if(isdigit(*prog)) { /*  */
               while(!isdelim(*prog)) *temp++=*prog++;
               *temp = '\0';
               return(token_type = NUMBER);
             }

             if(isalpha(*prog))  { /*    */
               while(!isdelim(*prog)) *temp++=*prog++;
               token_type=STRING;
             }

             *temp = '\0';
      /* ,       */
             if(token_type==STRING) {
               tok=look_up(token); /*   
                                       */
               if(!tok) token_type = VARIABLE;
- - -                                                          - - - 
                                
                                - 228 -

               else token_type = COMMAND; /*   */
             }
             return token_type;
           }


             get_token().    
                      
         .  
            is_white(),   
      "" ("TRUE"),        
           .        ,  ,
         prog,     ,
     ,  ,    "  "  ,  
              ().        
         " " (\r), 
        "    "  ("EOL").  
           ,      
       token    ,
         token_type   DELIMITER. 
          .    
             .      
     ,   ,  ,       
     .    look_up()     
      ,      , 
             ,   
         ().        
           .   ,   ,       
           ,    ,    
           .     token
     .

                 get_token()     ,
          :

                            PRINT A+100-(B*C)/2

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

          PRINT           COMMAND
          A               VARIABLE
          +               DELIMITER
          100             NUMBER
          -               DELIMITER
          (               DELIMITER
          B               VARIABLE
          *               DELIMITER
          C               VARIABLE
          )               DELIMITER
          /               DELIMITER
          2               NUMBER
          null            DELIMITER
     --------------------------------

          ,       token   ,  
         .

                     
       .        
- - -                                                          - - - 
                                
                                - 229 -

       .  putback()   .

      /*        */
          void putback()
          {

            char *t;

            t = token;
            for(; *t; t++) prog--;
          }



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

                 . 
            
                    
      .   ,        
           .             
        "+" ,"-" ,"*" ,"/"    ,  
               
     :

                   = >  [+][-]
                        = >  [*][/]
                      = > ,   ()

          ,                   
      .         
          .      =>    
     "".

          ,        ,     
            .      
                   :   "   
        ".

            ,      
       ,            
         .

                . 

                                   10+5*B

       : "10"  "5*B". ,   ,  
       :  "10",  "5"    "B",      
     .

             

                                  14*(7-C)

         "14"   "(7-C)",  ,    ,
               .     
          .

- - -                                                          - - - 
                                
                                - 230 -

                    
         ,         
         .  
               
          .  
               
       .

                :

                                9/3-(100+56)

                  :

     1.    : "9/3".
     2.              , 
          "3".
     3.       :  "(100+56)".         
            .
     4.              , 
          156
     5.    ,      ,      
         : 3-156.    "-153".


                          
     ,    ,       . 
           ,     
      ,              .
         .

                     
     :  (1)           
                ;  (2)    
                
     ,                 
     .



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

               
                  . 
                   
     (       
         ,      
      ).      
      ,    .

                    
           .


          /*    
               ,  
               
          */
             #include "setjmp.h"
- - -                                                          - - - 
                                
                                - 231 -

             #include "math.h"
             #include "ctype.h"
             #include "stdlib.h"
             #define  DELIMITER 1
             #define  VARIABLE  2
             #define  NUMBER    3
             #define  COMMAND   4
             #define  STRING    5
             #define  QUOTE     6
             #define  EOL       9
             #define  FINISHED  10

             extern char *prog;  /*    */
             extern jmp_buf e_buf; /*    longjmp() */
             extern int variables[26]; /*  */
               extern struct commands {
               char command[20];
               char tok;
             } table[];

           extern char token[80]; /*    */
           extern char token_type; /*   */
           extern char tok; /*    */
             void get_exp(),level2(),level3(),level4(),level5();
             void level6(),primitive(),arith(),unary();
             void serror(), putback();

             /*    . */
             void get_exp(result)
             int *result;
             {
               get_token();
               if(!*token) {
                 serror(2);
                 return;
               }
               level2(result);
               putback(); /*   
                                  */
             }

             /*      */
             void level2(result)
             int *result;
             {
               register char op;
               int hold;

               level3(result);
               while((op=*token) == '+' || op == '-') {
                 get_token();
                 level3(&hold);
                 arith(op,result,&hold);
               }
             }

            /*       */
             void level3(result)
             int *result;
             {
- - -                                                          - - - 
                                
                                - 232 -

               register char op;
               int hold;

               level4(result);

               while((op = *token) == '+' || op == '/' || op == '%') {
                 get_token();
                 level4(&hold);
                 arith(op,result,&hold);
               }
             }

             /*    () */
             void level4(result)
             int *result;
             {
               int hold;

               level5(result);
               if(*token== '^') {
                 get_token();
                 level4(&hold);
                 arith('^', result, &hold);
               }
             }

             /*  +  - */
             void level5(result)
             int *result;
             {
               register char op;

               op = 0;
           if((token_type=LIMITER) && *token=='+' || *token=='-') {
                 op = *token;
                 get_token();
               }
               level6(result);
               if(op)
                 unary(op, result);
             }

             /*      */
             void level6(result)
             int *result;
             {
               if((*token == '(') && (token_type == DELIMITER)) {
                 get_token();
                 level2(result);
                 if(*token != ')')
                   serror(1);
                 get_token();
               }
               else
                 primitive(result);
             }

             /*       */
             void primitive(result)
             int *result;
- - -                                                          - - - 
                                
                                - 233 -

             {
               switch(token_type) {
               case VARIABLE:
                 *result = find_var(token);
                 get_token();
                 return;
               case NUMBER:
                 *result  = atoi(token);
                 get_token();
                 return;
               default:
                 serror(0);
               }
             }

             /*    */
             void arith(o, r, h)
             char o;
             int *r, *h;
             {register int t, ex;

             switch(o) {
               case '-':
                 *r = *r-*h;
                 break;
               case '+':
                 *r = *r+*h;
                 break;
               case '*':
                 *r = *r * *h;
                 break;
               case '/':
                 *r = (*r)/(*h);
                 break;
               case '%':
                 t = (*r)/(*h);
                 *r = *r-(t*(*h));
                 break;
               case '^':
                 ex =*r;
                 if(*h==0) {
                   *r = 1;
                   break;
                 }
                 for(t=*h-1; t>0; --t) *r = (*r) * ex;
                 break;
               }
             }

             /*   */
             void unary(o, r)
             char o;
             int *r;
             {
               if(o=='-') *r = -(*r);
             }

             /*    */
             int find_var(s)
             char *s;
- - -                                                          - - - 
                                
                                - 234 -

             {
               if(!isalpha(*s)){
                 serror(4); /*   */
                 return 0;
               }
               return variables[toupper(*token)-'^'];
             }

             /*     */
             void serror(error)
             int error;
             {
               static char *e[]= {
                 " ",
                 "  ",
                 "  t",
                 "  ",
                 " ",
                 "  ",
                 " ",
                 " ",
                 "  THEN",
                 "  TO",
                 "   FOR  ",
                 "NEXT   FOR",
                 "  GOSUB  ",
                 "RETURN   GOSUB"
               };
               printf("&4%s\n",e[error]);
               longjmp(e_buf, 1); /*     */
             }

             /*  . */
             get_token()
             {

               register char *temp;
               token_type=0; tok=0;
               temp=token;
               if(*prog=='\0') { /*   */
                 *token=0;
                 tok = FINISHED;
                 return(token_typeLIMITER);
               }
               while(iswhite(*prog)) ++prog; /*   */

               if(*prog=='\r') { /*    */
                 ++prog; ++prog;
                 tok = EOL; *token='\r';
                 token[1]='\n'; token[2]=0;
                 return (token_type = DELIMITER);
               }

               if(strchr("+-^/%=;(),><", *prog)){ /*  */
                 *temp=*prog;
                 prog++; /*     */
                 temp++;
                 *temp=0;
                 return (token_typeLIMITER);
               }
- - -                                                          - - - 
                                
                                - 235 -


               if(*prog=='"') { /*   */
                 prog++;
                 while(*prog != '"' && *prog!='\r') *temp++=*prog++;
                 if(*prog=='\r') serror(1);
                 prog++;*temp=0;
                 return(token_type=QUOTE);
               }

               if(isdigit(*prog)) { /*  */
                 while(!isdelim(*prog)) *temp++=*prog++;
                 *temp = '\0';
                 return(token_type = NUMBER);
               }

               if(isalpha(*prog)) { /*    */
                 while(!isdelim(*prog)) *temp++=*prog++;
                 token_type=STRING;
               }

               *temp = '\0';

        /* ,   -    */
               if (token_type==STRING) {
       tok=look_up(token); /*     */
                 if (!tok) token_type = VARIABLE;
                 else token_type = COMMAND; /*   */
               }
               return token_type;
             }

             /*      */
            void putback()
             {

               char *t;

               t = token;
               for(; *t; t++) prog--;
             }

             /*     
                    .
             */
             look_up(s)
             char *s;
             {
               register int i,j;
               char *p;

               /*     */
               p = s;
               while(*p){ *p = tolower(*p); p++; }

               /* ,    
                   */
               for(i=0; *table[i].command; i++)
                 if(!strcmp(table[i].command, s)) return table[i].tok;
               return 0; /*   */
             }
- - -                                                          - - - 
                                
                                - 236 -


             /*  "",  "c"  */
             isdelim(c)
             char c;
             {
             if(strchr(" ;,+-<>/*%^=()",c) || c==9 || c=='\r' || c==0)
                 return 1;
               return 0;
             }

             /*  1,  ""    */
             iswhite(c)
             char c;
             {
               if(c==' ' || c=='\t') return 1;
               else return 0;
             }


             :  "+", "-", "*",
     "/",  "%",     (^)   .
                  
     . , , ,     
       ,               
     primitive(),     .       ,
       ,     
      arith()  unary(),   get_token().

             prog       ,
      ,    get_exp()   ,
          .

                    serror(),   
             .   
       serror()      
       .        0,   
      " ",     ,  
            .    
      .  ,   serror()  
      longjmp().

           logjmp()    , 
       ,          setjmp().   
     setjmp()            .  
       logjmp()    , 
         setjmp().      -  ,  
          setjmp()    
      .    ,  .

           ljgjmp()     ,   
     -              
       .            
      setjmp()  logjmp(),        
                 
     .

- - -                                                          - - - 
                                
                                - 237 -



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

               ,     SMALL BASIC
             "A"    "Z".  
         variables,  
     26 .       , 
      ,    .

        int variables[26]= {   /* 26  , A-Z */
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0
        };
                 "A"   "Z", 
         variables     
                 
     ASCII   'A'.  find_var(),  
          ,  .

         /*      */
         int find_var(s)
         char *s;
         {
           if(!isalpha(*s)){
             serror(4); /*    */
             return 0;
           }
           return variables[toupper(*token)-'A'];
         }

                 ,  
           .



                         SMALL BASIC
     -----------------------------------------------------------------

                
         BASIC:

            PRINT
            INPUT
            IF
            THEN
            FOR
            NEXT
            TO
            GOTO
            GOSUB
            RETURN
            END

              (   EOL 
           FINISHED        )
      :

- - -                                                          - - - 
                                
                                - 238 -

          #define PRINT   1
          #define INPUT   2
          #define IF      3
          #define THEN    4
          #define FOR     5
          #define NEXT    6
          #define TO      7
          #define GOTO    8
          #define EOL     9
          #define FINISHED 10
          #define GOSUB    11
          #define RETURN   12
          #define END      13

                        
          table.

          struct commands { /*   
                                                  */
            char command[20];
            char tok;
          } table[] = { /*   ,  */
            "print",PRINT, /*    */
            "input",INPUT,
            "if",IF,
            "then",THEN,
            "goto",GOTO,
            "for",FOR,
            "next",NEXT,
            "to",TO,
            "gosub",GOSUB,
            "return",RETURN,
            "end",END,
            "",END  /* mark end of table */
          };

             ,        (
     )    .

           look_up()    
        '\0',    .

          /*      
               .
          */
          look_up(s)
          char *s;
          {
            register int i,j;
            char *p;
            /*      */
            p =s;
            while(*p){ *p = tolower(*p); p++; }

            /*      */
            for(i=0; *table[i].command; i++)
                if(!strcmp(table[i].command, s)) return table[i].tok;
            return 0; /*    */
          }

- - -                                                          - - - 
                                
                                - 239 -

            SMALL  BASIC      
     ,           BASIC,
        .

                        
     .  ,   , 
     load_program().


         /*   */
         load_program(p, fname)
         char *p;
         char *fname;
         {
           FILE *fp;
           int i=0;
           if(!(fp=fopen(fname, "rb"))) return 0;

           i = 0;
             do {
                *p = getc(fp);
                p++; i++;
             } while(!feof(fp) && i<PROG_SIZE);
             *(p-2) = '\0'; /*     */
             fclose(fp);
             return 1;
           }



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

                     
             .
                  SMALL  BASIC
       .

           do {
             token_type = get_token();
             /*      */
             if (token_type == VARIABLE) {
               putback(); /*      */
               assignment(); /*     */
             }
             else /*   */


               switch(tok) {
                 case PRINT:
                   print();
                   break;
                 case GOTO:
                   exec_if();
                   break;

                 case FOR:
                   exec_for();
                   break;
                 case NEXT:
- - -                                                          - - - 
                                
                                - 240 -

                   next();
                   break;
                 case INPUT:
                   input();
                   break;
                 case GOSUB:
                   gosub();
                   break;
                 case RETURN:
                   greturn();
                   break;
                 case END:
                   exit(0);
               }
           } while (tok != FINISHED);


                  .    
             .  
       ,  ,   ,  
                (SMALL   BASIC   
            LET).      ,
                    case   
           tok     
     . ,     .



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

               BASIC         
      :

                        < >=<>

           assignment()    .

           /*    */
           assignment()
           {
             int var, value;
             /*    */
             get_token();
               if(!isalpha(*token)) {
                 serror(4); /*    */
                 return;
               }

               /*      */
               var = toupper(*token)-'A';

               /*   */
               get_token();
               if(*token!='=') {}
                 serror(3);
                 return;
               }
- - -                                                          - - - 
                                
                                - 241 -


               /*     */
               get_exp(&value);

               /*  */
               variables[var] = value;
             }


           assignment()     .   -
     -,      . 
         ,     .  
        ( ).   
      get_exp(),    . 
        ,    
     get_token     .


                PRINT
     -----------------------------------------------------------------

           PRINT      BASIC     
     ,       PRINT  USING.  
      ,      ,
          ,      
      .         PRINT  SMALL
     BASIC:

                         PRINT < >

      < >      ,
                     
     .   print(),  ,  
        PRINT     BASIC.    ,    
         do-while,     
            .


        /*    PRINT */
        void print()
        {
          int answer;
          int len=0, spaces;
          char last_delim;
          do {
               get_token(); /*     */
               if (tok == EOL || tok == FINISHED) break;
               if (token_tipe == QUOTE) { /*   */
                   printf(token);
                     len += strlen(token);
                    get_token();
              }
               else { /*   */
                  putback();
                  get_exp(&answer);
                  get_token();
                  len+= printf("%d", answer);
               }
               last_delim = *token;
               if (*token == ';') {
- - -                                                          - - - 
                                
                                - 242 -

          /*       
              */
               spaces = 8-(len % 8);
               len += spaces; /*     */
               while (spaces) {
                 printf(" ");
                 spaces--;
               }
               }
               else if (*token == ','); /*    */;
               else if (tok != EOL && tok != FINESHED) serror(0);
               } while (*token == ';' || *token == ',');
               if (tok == EOL || tok == FINESHED) {
                  if (last_delim != ';' && last_delim != ',')
                                                        printf("\n");
                  else serror(0); /*   */
              }

           PRINT           
               .     
       ,              
      ().      
      ,        ,    
       .       
        ,        .

                       
     :

     PRINT X; Y; " "
     PRINT 10 / 4
     PRINT

           print()      putback()  
        .    ,  ,
          ,    ,   
     ,    print()      
          .        
     ,         
         ,           
         .



           INPUT.
     -----------------------------------------------------------------

              BASIC      INPUT      
            .    
         .          
        ('?')       
      :

                           INPUT < >

                        
     ,     :
 !
               INPUT "< >" < >

- - -                                                          - - - 
                                
                                - 243 -

           input (),   ,   
     BASIC INPUT.

         /*    INPUT */
         void input()
         {
           char str[80], var;
           int i;

           get_token(); /*    */
           if (token_type == QUOTE) {
             printf(token); /*  ,   */
             get_token();
             if (*token != ',') serror(1);
             get_token();
           }
           else printf("? "); /*     "? "*/
      var = toupper(*token)-'A'; /*     */
           scanf("%d",&i);   /*    */
           variables[var] = i;  /*   */
         }

                          
     .



                GOTO
     -----------------------------------------------------------------

                   ,
             .   BASIC
            GOTO. 
       BASIC ,     GOTO,
       .        
       SMALL BASIC.  ,  SMALL BASIC   
      .        ,  
             GOTO.      GOTO
      :

                          GOTO < >

              GOTO    ,
            ,    
       .          
     ,    ,   
         ,     ,  
        .    .

          struct label {
            char name[LAB_LEN]; /*   */
            char *p; /*       */
          };
          struct label label_table[NUM_LAB];

          ,        
          ,   scan_labels(). 
           .

- - -                                                          - - - 
                                
                                - 244 -

         /*    */
         void scan_labels()
         {
           register int loc;
           char *temp;

           label_init();  /*    */
           temp = prog;   /*      */
           /*       */
           get_token();
           if(token_type==NUMBER) {
             strcpy(label_table[0].name,token);
             label_table[0].p=prog;
           }

           find_eol();
           do {
             get_token();
             if(token_type==NUMBER) {
               loc=get_next_label(token);
               if(loc == -1 || loc == -2) {
                   (loc == -1) ? serror(5):serror(6);
               }
               strcpy(label_table[loc].name, token);
           label_table[loc].p = prog; /*   */
             }
             /*    ,    */
             if(tok!=EOL) find_eol();
           } while(tok != FINISHED);
           prog = temp; /*   */
         }

         /*    .
                 , 
                  */
         void label_init()
         {
           register int t;
           for(t=0;t<NUM_LAB;++t) lable_table[t].name[0]='\0';
         }
         /*     */
         void find_eol()
         {
           while (*prog!='\n'  && *prog!='\0') ++prog;
           if (*prog) prog++;
         }

         /*       
            .  -1    .
             -2           */
         get_next_label(s)
         char *s;
         {
           register int t;

           for (t=0;t<NUM_LAB;++t) {
             if (label_table[t].name[0] == 0) return t;
             if(!strcmp(label_table[t].name,s)) return -2; /*  */
           }
           return -1;
- - -                                                          - - - 
                                
                                - 245 -

         }


           scan_labels()     .  -
       .    BASIC (    
     )       .    -
           .        
       NUM_LAB.       
      .

              ,     GOTO
         exec_goto(),  .


         /*   GOTO */
         void exec_goto()
         {
           char *loc;

           get_token(); /*    */
           /*     */
           loc = find_label(token);
           if (loc == '\0')
             serror(7);   /*     */
           else prog=loc; /*     */
         }

         /*   .  ,  
             ;      
            ,                               */

         char *find_label(s)
         char *s;
         {
         register int t;

         for (t=0;t<NUM_LAB;++t)
          if (!strcmp(label_tabel[t].name,s)) return label_tabel[t].p;
         return '\0';
         }

            find_label(),  ,  
                .    
     ,  ,  null.    null,  
          prog,        
     ,        .  (    ,  
       prog        ).
        ,        ,  
      .



                IF
     -----------------------------------------------------------------

            SMALL  BASIC       IF   
                 BASIC.    SMALL  BASIC,
      ELSE      :  "",
     ""  "". (   ,    
        ).   :
- - -                                                          - - - 
                                
                                - 246 -


            IF <><><> THEN <>

          ,     THEN,        
     ,           .  
     exec_if(),   ,     
      IF.

         /*    IF  */
         void exec_if()
         {
           int x , y, cond;
           char op;
           get_exp(&x); /*    */
           get_token(); /*    */
           if (!strchr("=<>", *token)) {
           serror(0);      /*    */
           return;
         }
         op=*token;
         get_exp(&y);  /*    */
         /*   */
         cond=0;
         switch(op) {
             case '=':
           if(x==y) cond=1;
           break;
             case '<':
           if(x<y) cond=1;
           break;
             case '>':
           if(x>y) cond=1;
           break;
         }
         if(cond) {  /*  ,    IF  */
           get_token();
           if(tok!=THEN) {
              serror(8);
              return;
           }  /*      
                      */
         }
         else find_eol(); /*     */
       }

           exec_if()   :
         1.    .
         2.   .
         3.    .
         4.   .
         5.    ,     THEN;
               , find_eol     
             .


- - -                                                          - - - 
                                
                                - 247 -


                FOR
     -----------------------------------------------------------------

                    FOR,
             BASIC,        
       .            FOR
     :

      FOR<  >=<. >TO<. >
          .
          .
          .
         
          .
          .
          .
       NEXT

             FOR,    SMALL
     BASIC,          1  
       .  STEP  .

              BASIC,             C,  
       FOR.   ,    
     ,      -,  
                  
        .         ,    -
           (                   
     -),    ,  
       :   ,    
               ,   
                   .
      ,     NEXT,    
         ,     
            .  
             
     ,         
         NEXT.      ,  
               
      .            
       .     
       FOR       
     NEXT.

                  FOR       
      :

          struct for_stack {
               int var; /*   */
               int target; /*   */
               char *loc;
          } fstack[FOR_NEST]; /*    FOR/NEXT */
          int ftos; /*    FOR */

             FOR_NEST    
     .  (      25      ).
      ftos      .

- - -                                                          - - - 
                                
                                - 248 -

                    fpush() 
     fpop(),   .

                /*     */
          void fpush(i)
          struct for_stack i;
          {
               if (ftos > FOR_NEST)
                    serror(10);

               fstack[ftos]=i;
               ftos++;
          }

          struct for_stack fpop()
          {
               ftos--;
               if (ftos < 0) serror(11);
               return(fstack[ftos]);
          }


          ,   ,      
         ,  
      ,   FOR  NEXT.


          /*     FOR */
          void exec_for()
          {
               struct for_stack i;
               int value;

               get_token(); /*    */
               if (!isalfa(*token)) {
                    serror(4);
                    return;
               }

               i.var=toupper(token) - 'A'; /*   */

               get_token(); /*    */
               if (*token != '=') {
               serror(3);
               return;
               }

               get_exp(&value); /*    */

               variables[i.var] = value;

               get_token();
               if (tok != TO) serror(9); /*    TO */

               get_exp(&i.target); /*    */

     /*     ,  
         */
               if (value >= variables[i.var]) {
                    i.loc = prog;
- - -                                                          - - - 
                                
                                - 249 -

                    fpush(i);
               }
               else { /*     */
                    while(tok != NEXT) get_token();
               }
             }

      /*   NEXT */
          void next()
          {
              struct for_stack i;

              i = fpop(); /*     */

              variables[i.var]++; /*    */
              if (variables[i.var] > i.target) return; /*  */
              fpush(i); /*      */
              prog = i.loc; /*  */
          }


                 ,        
       .   ,     
               GOTO            
     .      GOTO        
             ,     -   
     .

                FOR   
         ,      ,      

        .     SMALL
     BASIC      ,   
           
     WHILE  DO-WHILE.         ,
                      
      ,  .



                GOSUB.
     -----------------------------------------------------------------

           BASIC          ,  
              
       GOSUB           RETURN.
       GOSUB-RETURN  :

     GOSUB < >
             .
             .
             .
             < >
             .
              
             .
             .
     RETURN

- - -                                                          - - - 
                                
                                - 250 -

                .  ,
           ,     FOR
     ,       RETURN   GOSUB.
       GOSUB  .

         char *gstack[SUB_NEST]; /*   */
         int gtos; /*      */

           gosub()     .

         /*    GOSUB  */
         void gosub()
         {
           char *loc;

           get_token();
           /*    */
           loc = find_label(token);
           if(loc=='\0')
             serror(7); /*    */
           else {
             gpush(prog); /*  ,    */
             prog = loc; /*     loc */
           }
         }

         /*     */
         void greturn()
         {
           prog = gpop();
         }

         /*      GOSUB () */
         void gpush(s)
         char *s;
         {
           gtos++;
           if(gtos == SUB_NEST) {
             serror(12);
             return;
           }
           gstack[gtos]=s;
         }

      /*      GOSUB () */
         char *gpop()
         {
           if(gtos==0) {
             serror(13);
             return;
           }
           return(gstack[gtos--]);
         }
           GOSUB    .   
     prog     GOSUB.    prog    
     ,            ,    
      .   RETURN,   GOSUB
              prog.  
                 
     GOSUB.  GOSUB  .
- - -                                                          - - - 
                                
                                - 251 -




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

             SMALL  BASIC,      
         ,       .      
             ,    
      .

        /*  BASIC- */
        #include "stdio.h"
        #include "setjmp.h"
        #include "math.h"
        #include "ctype.h"
        #include "stdlib.h"

        #define NUM_LAB 100
        #define LAB_LEN 10
        #define FOR_NEST 25
        #define SUB_NEST 25
        #define PROG_SIZE 10000

        #define DELIMITER 1
        #define VARIABLE  2
        #define NUMBER    3
        #define COMMAND   4
        #define STRING    5
        #define QUOTE     6

        #define PRINT 1
        #define INPUT 2
        #define IF    3
        #define THEN  4
        #define FOR   5
        #define NEXT  6
        #define TO    7
        #define GOTO  8
        #define EOL   9
        #define FINISHED 10
        #define GOSUB 11
        #define RETURN 12
        #define END   13

        char *prog; /*     */
        jmp_buf e_buf; /*    longjmp() */

        int variables[26]= {   /* 26   A - Z */
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0
        };

          struct commands { /*     */
            char command[20];
            char tok;
          } table[] = { /*     */
            "print",PRINT, /*     */
            "input",INPUT,
- - -                                                          - - - 
                                
                                - 252 -

            "if",IF,
            "then",THEN,
            "goto",GOTO,
            "for",FOR,
            "next",NEXT,
            "to",TO,
            "gosub",GOSUB,
            "return",RETURN,
            "end",END,
            "",END  /*    */
          };

          char token[80];
          char token_type, tok;

          struct label {
            char name[LAB_LEN];
            char *p; /*      */
          };
          struct label label_table[NUM_LAB];

          char *find_label(), *gpop();

          struct for_stack {
            int var; /*   */
            int target; /*   */
            char *loc;
          } fstack[FOR_NEST]; /*   FOR/NEXT */
          struct for_stack fpop();

          char *gstack[SUB_NEST]; /*   GOSUB */
          int ftos; /*    FOR */
          int gtos; /*    GOSUB */

          void print(), scan_labels(), find_eol(),exec_goto();
          void exec_if(), exec_for(), next(), fpush(), input();
          void gosub(), greturn(), gpush(), label_init();

          main(argc, argv)
          int argc;
          char *argv[];
          {
            char in[80];
            int answer;
            char *p_buf;
            char *t;

            if(argc!=2) {
              printf(" : run <filename>\n");
              exit(1);
            }

            /*     */
            if (!(p_buf=(char *) malloc(PROG_SIZE))) {
              printf("    ");
              exit(1);
            }

            /*     */
            if(!load_program(p_buf,argv[1])) exit(1);
- - -                                                          - - - 
                                
                                - 253 -

            if(setjmp(e_buf)) exit(1); /*  
                                            */
            prog = p_buf;
            scan_labels(); /*     */
            ftos = 0; /*    FOR */
            gtos = 0; /*    GOSUB */
           do {
             token_type = get_token();
             /*     */
             if(token_type==VARIABLE) {
               putback(); /*  .     */
               assignment(); /*     */
             }
             else /*   */
               switch(tok) {
                 case PRINT:
                   print();
                   break;
                 case GOTO:
                   exec_if();
                   break;
                 case FOR:
                   exec_for();
                   break;
                 case NEXT:
                   next();
                   break;
                 case INPUT:
                   input();
                   break;
                 case GOSUB:
                   gosub();
                   break;
                 case RETURN:
                   greturn();
                   break;
                 case END:
                   exit(0);
               }
           } while (tok != FINISHED);
         }

         /*  . */
         load_program(p, fname)
         char *p;
         char *fname;
         {
           FILE *fp;
           int i=0;
           if(!(fp=fopen(fname, "rb"))) return 0;

           i = 0;
             do {
                *p = getc(fp);
                p++; i++;
             } while(!feof(fp) && i<PROG_SIZE);
             *(p-2) = '\0'; /*    */
             fclose(fp);
             return 1;
           }
- - -                                                          - - - 
                                
                                - 254 -


           /*    */
           assigment()
           {
             int var, value;
             /*    */
             get_token();
               if(!isalpha(*token)) {
                 serror(4); /*    */
                 return;
               }

               /*    */
               var = toupper(*token)-'A';

               /*    */
               get_token();
               if(*token!='=') {
                 serror(3);
                 return;
               }

               /*  ,   */
               get_exp(&value);

               /*    */
               variables[var] = value;
             }

             /*    PRINT */
             void print()
             {
               int answer;
               int len=0, spaces;
               char last_delim;

               do {
                 get_token(); /*      */
                 if(tok==EOL || tok==FINISHED) break;
                 if(token_type==QUOTE) { /*   */
                   print(token);
                   len += strlen(token);
                   get_token();
                 }
                 else { /*   */
                   putback();
                   get_exp(&answer);
                   get_token();
                   len +=printf("%d", answer);
                 }
                 last_delim = *token;

                 if(*token==';') {
     /*        */
                   spaces= 8- (len % 8);
                   len += spaces; /*     */
                   while(spaces) {
                     print(" ");
                     spaces--;
                   }
- - -                                                          - - - 
                                
                                - 255 -

                 }
                 else if(*token==','); /*    */
                 else if(tok!=EOL && tok!=FINISHED)  serror(0);
               } while (*token == ';' || *token == ',');

              if(tok==EOL || tok==FINISHED) {
              if(last_delim != ';' && last_delim != ',') printf("\n");
              }
               else serror(0); /*  ','  ';'  */
             }
             /*    */
             void scan_labels()
             {
               int addr;
               char *temp;

             label_init();  /*    */
             temp = prog; /*     */
               /*        */
               get_token();
               if(token_type==NUMBER) {
                 strcpy(label_table[0].name,token);
                 label_table[0].p=prog;
               }

               find_eol();
               do {
                 get_token();
                 if(token_type==NUMBER) {
                   addr =get_next_label(token);
                   if(addr==-1 || addr==-2) {
                       (addr==-1) ?serror(5):serror(6);
                   }
                   strcpy(label_table[addr].name, token);
         label_table[addr].p = prog; /*    */
                 }
                 /*    ,    */
                 if(tok!=EOL) find_eol();
               } while(tok!=FINISHED);
               prog = temp; /*   */
             }

             /*     */
             void find_eol()
             {
               while(*prog!='\n'  && *prog!='\0') ++prog;
               if(*prog) prog++;
             }

             /*      
                 . -1,   .
                               -2,   . */

             get_next_label(s)
             char *s;
             {
               register int t;

               for(t=0;t<NUM_LAB;++t) {
                 if(label_table[t].name[0]==0) return t;
- - -                                                          - - - 
                                
                                - 256 -

              if(!strcmp(label_table[t].name,s)) return -2; /**/
               }

               return -1;
             }

         /*     .  0 ,
               ;    
                        */

             char *find_label(s)

             char *s;
             {
               register int t;

               for(t=0; t<NUM_LAB; ++t)
           if(!strcmp(label_table[t].name,s)) return label_table[t].p;
               return '\0'; /*   */
             }

             /*   GOTO */
             void exec_goto()
             {
               char *loc;

               get_token(); /*    */
               /*    */
               loc = find_label(token);
               if(loc=='\0')
                 serror(7);   /*     */
               else prog=loc; /*       */
             }

          /*    .  
                 */
             void label_init()
             {
             register int t;

             for(t=0; t<NUM_LAB; ++t) label_table[t].name[0]='\0';
           }

             /*   IF  */
             void exec_if()
             {
               int x , y, cond;
               char op;
               get_exp(&x); /*    */
               get_token(); /*   */
               if(!strchr("=<>", *token)) {
               serror(0);      /*   */
               return;
             }
             op=*token;
             get_exp(&y);  /*    */
             /*   */
             cond=0;
             switch(op) {
                 case '=':
- - -                                                          - - - 
                                
                                - 257 -

               if(x==y) cond=1;
               break;
                 case '<':
               if(x<y) cond=1;
               break;
                 case '>':
               if(x>y) cond=1;
               break;
             }
             if(cond) {  /*   IF ""  */
               get_token();
               if(tok!=THEN) {
                  serror(8);
                  return;
              } /* ,      */
             }
             else find_eol(); /*     */
           }

           /*   FOR */
           void exec_for()
           {
             struct for_stack i;
             int value;

             get_token(); /*    */
             if(!isalpha(*token)); {
               serror(4);
               return;
             }
             i.var=toupper(*token)-'A'; /*    */
             get_token(); /*    */
             if(*token!='=') {
               serror(3);
               return;
             }
             get_exp(&value); /*     */
             variables[i.var]=value;

             get_token();
             if(tok!=TO) serror(9); /*    TO */
             get_exp(&i.target); /*    */

             /*     , 
                    */
             if(value>=variables[i.var]) {
               i.loc = prog;
               fpush(i);
             }
             else /*    */
               while(tok!=NEXT) get_token();
           }

           /*   NEXT */
           void next()
           {
             struct for_stack i;
             i = fpop(); /*     */

            variables[i.var]++; /*   */
- - -                                                          - - - 
                                
                                - 258 -

             if(variables[i.var]>i.target) return; /*   */
             fpush(i); /* ,     */
             prog = i.loc; /*  */
           }

           /*     FOR */
           void fpush(i)
           struct for_stack i;
           {
             if(ftos>FOR_NEST)
             serror(10);
           fstack[ftos]=i;
           ftos++;
         }

         struct for_stack fpop()
         {
           ftos--;
           if(ftos<0) serror(11);
           return(fstack[ftos]);
         }

         /*   INPUT */
         void input()
         {
           char str[80], var;
           int i;

      get_token(); /*    */
           if(token_type==QUOTE) {
          printf(token); /*  ,      ',' */
             get_token();
             if(*token!=',') serror(1);
             get_token();
           }
           else printf("? "); /*     */
       var = toupper(*token)-'A'; /*    */
           scanf("%d",&i);   /*    */
           variables[var] = i;  /*   */
         }

         /*   GOSUB */
         void gosub()
         {
           char *loc;

           get_token();
           /*    */
           loc = find_label(token);
           if(loc=='\0')
             serror(7); /*    */
           else {
             gpush(prog); /*  ,   */
             prog = loc; /*      */
           }
         }

         /*   ,   GOSUB */
         void greturn()
         {
- - -                                                          - - - 
                                
                                - 259 -

           prog = gpop();
         }

         /*     GOSUB */
         void gpush(s)
         char *s;
         {
           gtos++;
           if(gtos==SUB_NEST) {
             serror(12);
             return;
           }
           gstack[gtos]=s;
         }

         /*   */
         char *gpop()
         {
           if(gtos==0) {
             serror(13);
             return;
           }
           return(gstack[gtos--]);
         }



                  SMALL BASIC
     -----------------------------------------------------------------

                     BASIC-.


         PRINT "    ."
         FOR X = 1 TO 100
         PRINT X, X/2; X, X*X
         NEXT
         GOSUB 300
         PRINT ""
         INPUT H
         IF H<11 THEN GOTO 200
         PRINT 12-4/2
         PRINT 100
         200 A = 100/2
         IF A>10 THEN PRINT " "
         PRINT A
         PRINT A+34
         INPUT H
         PRINT H
         INPUT " ",y
         PRINT H+Y
         END
         300 PRINT " "
             RETURN

         PRINT "    GOSUB"
         INPUT " : ", i
         GOSUB 100

         END
- - -                                                          - - - 
                                
                                - 260 -


         100 FOR T = 1 TO I
           X = X+I
           GOSUB 150
         NEXT
         RETURN

         150 PRINT X;
             RETURN


         print "     "
         input "   : ", l
         input "   : ", w
         input "   : ", d
         t = l * w * d
         print " : ", t


         PRINT "    "
         FOR X = 1 TO 100
          FOR Y = 1 TO 10
            PRINT X; Y; X*Y
          NEXT
         NEXT



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

                     
                  
       BASIC.     ,
           ,          
                          
     .   ,  ,   
     ,             
     .

                
               .      

              
             ;       
         ,      
                  .  
                
       .       
             255
        .

              :    ,      
     ,    .

- - -                                                          - - - 
                                
                                - 261 -



                                   8
                                  -------

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

                ,   ,  

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

          ,              ,     
     -.      IBM PC, XT, AT,
     PS/2      .      
             
     ().          
      ,       
      .



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

                     ,   
      ,     .
                  1,      PC
         .          
         ,         
       3,    ,   
             80*25  .      
          , ,  
         .


- - -                                                          - - - 
                                
                                - 262 -


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

                  
        ,        
      (.   1).          
     ,    ,   3,  
                 
       ,    ,     
      (  ),        
         .          
      8.1.

           0,  1  2     
     . ,    0 (   1),
          .      
           ,         .
     ,       .   
             ( 1),    
      .         ,  
        -,   () 
     .    4  6        .
            ( 0),    
       ,              
         .

               ,    
         ,        ,
                  
          .      IBM  PC
             :   
          PC        
     "" ,      
           ,       1   
         (  )
                ,
        .


      8-1.
     ------------
           3 
     _________________________________________________________________

                       

          0                 
          1                 
          2                 
          3                 
          4                 
          5                 
          6                 
          7                
     _________________________________________________________________

- - -                                                          - - - 
                                
                                - 263 -


                 ,  
           ,     
       BIOS,         .
                 
                       
     .            
                 (
     ),                   
              
       OS/2.  ,      ,  
      BIOS     ,      
         ,    ,   
             .
      ,     
          .


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

                    
      ,       ,  
        ,   ,    
     ,    BIOS     (ROM-BIOS).  ROM-BIOS
      10,   9       
     (!)      .    
          ,      
        .

                ,  -, 
          .       
        read_cursor_xy(),     .    
      ROM-BIOS- 10,  3,   
           X    Y.    
          .

          /*      */
     void read_cursor_xy(x,y)
     char *x,*y;
     {
          union REGS r;

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

                       ,
     ,       ,    
         ,   ,  
     ROM-BIOS-    .       
          goto_xy(),    
              
     .
- - -                                                          - - - 
                                
                                - 264 -


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

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

           color_puts(),      ,    
          .

          /*       */
     void color_puts(s,color)
     char *s;  /*  */
     char color; /*   */
     {
           union REGS r;
           char x,y;
           read_cursor_xy(&x,&y); /*    
                           */
           while (*s) {
           if (*s == '\n') {  /*     */
               printf("\n");
               s++;
               x = 0; y++;  /*     */
               continue;
      }
         r.h.ah = 9; /*       */
         r.h.al = *s++;    /*   */
         r.h.bl = color;   /*   */
         r.h.bh = 0;       /* 0 */
         r.x.cx = 1; /*     (  ) */
          int86(0x10,&r,&r);
          x++;
          goto_xy(x,y); /*   */
      }
     }

             ,        
       AL,        -    BL,  
      -   BH,       
     (  ),            - 
      CX.  ,     
            ('\n').      ,    ,
         ('\t'),  
     (")    .

            color_puts()   
           . 
       
- - -                                                          - - - 
                                
                                - 265 -


            #define BLUE             1
            #define GREEN        2
            #define RED             4
            #define INTENSE      8
            #define BLUE_BACK    16
            #define GREEN_BACK   32
            #define RED_BACK     64
            #define BLINK        128

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

          color_puts("  - ",GREEN | RED | INTENSE );


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

                   
        .          
        ,   .  
              
       :

          -   ""  .  
                
      .     - 
              
     .

          -       
       .

          -                
        (,    )     
     .

          -       (   ) 
       ,  ,      
                   
     .

- - -                                                          - - - 
                                
                                - 266 -




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

                   
             IBM PC.   ,  
             .         
            ( ).
              
            () .  
                0    8
      .  (      
      0  14  ,         
           ).     

       0.      
           0,       
             
       .  (       
     ,    ,    
              
             ).    ,    
           
       ,          
        .8-1.

                
     ROM-BIOS- 10,   1,   
     .         (      )  -
        C,   (  ) 
      CL.





     
                                                     
                                                                    
        7                                                      
                                                                  
        6                                                    
                                                                
        5                                                  
                                                              
        4                                                
                                                            
        3                                              
                                                          
        2                                            
                                                        
        1                                          
                                                      
        0                                             
                                 
     
        . 8-1.      
                    .
- - -                                                          - - - 
                                
                                - 267 -

           size_cursor(),    ,  
      .

          /*    */
     void size_cursor(start,end)
     char start,end; /*      */
     {
          union REGS r;

          r.h.ah = 1; /*    */
          r.h.ch = start;
          r.h.cl = end;
          int86(0x10,&r,&r);
     }

               size_cursor()    
             ,     
     .  ,       
          :

               size_cursor(0,2);

                     
      size_cursor(),   .

                  
             ,     
          .      ,    
          .



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

                    ROM-BIOS-
            . 
             ROM-BIOS     
     .   ,        
                 <>,    
                
           .    ,  
       6  7  ROM-BIOS 10,   
           .    6    
         (),   7 -  ().

                 ,    
       .     ,   
      ""  ( )    AL.
        ,    "", 
       CH,       -      CL.
            DH,    
       -   DL.        BH
       ,   ,  
             .  
     scroll_window()  .

- - -                                                          - - - 
                                
                                - 268 -

          /*       */

     void scroll_window(startx,starty,endx,endy,lines,direct)
     char startx,starty;/*    */
     char endx,endy;    /*    */
     char lines;        /*    */
     char direct;       /*    */
     {
          union REGS r;

          if ( direct == UP ) r.h.ah = 6; /*   */
          else r.h.ah = 7; /*   () */
          r.h.al = lines;
          r.h.ch = starty;
          r.h.cl = startx;
          r.h.dh = endy;
          r.h.dl = endx;
          r.h.bh = 0;     /*   */
          int86(0x10,&r,&r);
     }

                 UP        
     .            DOWN,  
             UP,           
                          
     .               
     .      scroll_window()      
      0    ,    
         .



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

                 ,
            .   
        ,       ,  
         .    
        .8-2.

- - -                                                          - - - 
                                
                                - 269 -


     
     
        a)      - 
          aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa    
          bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb    
          cccccccccccccccccccccccccccccccccccccccccccccccccccccc    
          dddddddddddddddddddddddddddddddddddddddddddddddddddddd    
          eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee    
          ffffffffffffffffffffffffffffffffffffffffffffffffffffff    
          gggggggggggggggggggggggggggggggggggggggggggggggggggggg    
          hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh    
          iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii    
          jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj    
          kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk    
          llllllllllllllllllllllllllllllllllllllllllllllllllllll    
          mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm    
          nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn    
          oooooooooooooooooooooooooooooooooooooooooooooooooooooo    
          pppppppppppppppppppppppppppppppppppppppppppppppppppppp    
          qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq    
          rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr    
          ssssssssssssssssssssssssssssssssssssssssssssssssssssss    
          tttttttttttttttttttttttttttttttttttttttttttttttttttttt    
          uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu    
          vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    
                                                                    
          )  - .                                            
          aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa    
          bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb    
          cccccccccccccccccccccccccccccccccccccccccccccccccccccc    
          dddddddddddddddddddddddddddddddddddddddddddddddddddddd    
          eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee    
          ffffffffffffffffffffffffffffffffffffffffffffffffffffff    
          gggggggggggggggggggggggggggggggggggggggggggggggggggggg    
          hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh    
          iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii    
          jjjjjjjjjj                     jjjjjjjjjjjjjjjjjjjjjjj    
          kkkkkkkkkk                     kkkkkkkkkkkkkkkkkkkkkkk    
          llllllllll                     lllllllllllllllllllllll    
          mmmmmmmmmmjjjjjjjjjjjjjjjjjjjjjmmmmmmmmmmmmmmmmmmmmmmm    
          nnnnnnnnnnkkkkkkkkkkkkkkkkkkkkknnnnnnnnnnnnnnnnnnnnnnn    
          oooooooooolllllllllllllllllllllooooooooooooooooooooooo    
          pppppppppppppppppppppppppppppppppppppppppppppppppppppp    
          qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq    
          rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr    
          ssssssssssssssssssssssssssssssssssssssssssssssssssssss    
          tttttttttttttttttttttttttttttttttttttttttttttttttttttt    
          uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu    
          vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    
                                                                    
     

      . 8-2   .

- - -                                                          - - - 
                                
                                - 270 -


          /*      ,
                   
          */

            #include "dos.h"

            #define BLUE         1
            #define GREEN        2
            #define RED          4
            #define INTENSE      8
            #define BLUE_BACK   16
            #define GREEN_BACK  32
            #define RED_BACK    64
            #define BLINK      128

               #define UP        0
            #define DOWN         1

            void mode(),color_puts(),palette(), read_cursor_xy();
            void goto_xy(),size_cursor(),scroll_window();

               main()
               {
                int i,j;

             mode(3); /*  ,  */

                size_cursor(0,3);
                goto_xy(0,0);
                color_puts("  - \n",BLUE |RED | INTENSE);
                for ( i=0;i<22;i++) {
                    for ( j=0;j<79;j++)
                    printf("%c",i+'a');
                    printf("\n");
               }
               getche();
               scroll_window(10,10,50,15,3,DOWN);
               getche();
     }
          /*     */

               void color_puts(s,color)
               char *s;      /*  */
               char color;   /*   */
               {
                    union REGS r;
                    char x,y;

                    read_cursor_xy(&x,&y); /*   
                                                 */
                    while (*s) {
                     if (*s == '\n') { /*   
                                           */
                     printf("\n");
                     s++;
                     x = 0; y++;  /*     */
                     continue;
                    }

- - -                                                          - - - 
                                
                                - 271 -

                    r.h.ah = 9;/*     */
                    r.h.al = *s++; /*   */
                    r.h.bl = color;  /*   */
                    r.h.bh = 0; /*      0 */
                    r.x.cx = 1; /*      */
                    int86(0x10,&r,&r);
                    x++;
                    goto_xy(x,y);      /*   */
                    }
               }
          /*     */
               void read_cursor_xy(x,y)
               char *x,*y;
               {
                union REGS r;

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

          /*   */
               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);
               }

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

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

- - -                                                          - - - 
                                
                                - 272 -

          /*   ()  */
               void size_cursor(start,end)
               char start,end; /*    
                          */
               {
                union REGS r;

                r.h.ah = 1; /*    */
                r.h.ch = start;
                r.h.cl = end;
                int86(0x10,&r,&r);
               }

          /*       */
         void scroll_window(startx,starty,endx,endy,lines,direct)
         char startx,starty; /*    */
         char endx,endy;     /*    */
         char lines;         /*   */
         char direct;        /*    */
          {
           union REGS r;

           if ( direct == UP ) r.h.ah = 6; /*   */
            else r.h.ah = 7; /*   */

          r.h.al = lines;
          r.h.ch = starty;
          r.h.cl = startx;
          r.h.dh = endy;
          r.h.dl = endx;
          r.h.bh = 0; /*   */
          int86(0x10,&r,&r);
          }



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

             DOS,    OS/2  ,     
      ,         
          .       ,
        ,          
     .

             ROM-BIOS- 10,   8
             ,    
          .      ,
          goto_xy(),     
                
      ,         
      .

           ,                ,
         .  ,   ,  
        ,     ,  screen,  
               
          scr.sav:

     C> screen scr.sav
- - -                                                          - - - 
                                
                                - 273 -


                :

               /*      
                    ,     
                  
               */

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

          void save_screen(),goto_xy();

          main(argc,argv)
          int argc;
          char *argv[];
          {
            if ( argc != 2 ) {
               printf("   : screen < >");
               exit(1);
            }
            save_screen(argv[1]);
          }

          /*       */
               void save_screen(fname)
               char *fname;
          {
           FILE *fp;
           union REGS r;
           register char x,y;

           if ( !( fp=fopen(fname,"w"))) {
               printf("      ");
               exit(1);
           }

           for (y=0;y<25;y++)
               for (x=0;x<80;x++) {
               goto_xy(x,y);
               r.h.ah = 8; /*   */
               r.h.bh = 0; /*  */
               int86(0x10,&r,&r);
               putc(r.h.al,fp); /*  ()  */
           }
          fclose(fp);
          }

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

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


                ASCII ,
                   
       .         ,
       ,     
         .      
     ,       ,   
         .



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

                         
      .      
        ""         
         .      ,
               ,
       .     
         .


            8253.
          -----------------------------

                 PC      
       8253,    
        .             
       ,  ,     ,  
             .      
            .  
     66      ,    
               .  
               
          ,    
     .  ,       
           ,           
        .    
        :

          count = 1,193,180/ 

      1,193,180     .

          -   8253      
      (          
     ):

       1.      67    182  (,     
            ).

       2.     66   ,  
           .

       3.     66   ,  
           .
- - -                                                          - - - 
                                
                                - 275 -


                 PC    
        ,   
      (  20      18.000  ).       
         ,        
      12000    .     
       100-5000 .

          ,    .           
      ,      .    8253  
     ,         .
               
       0   1    ,
                  97.  
          ( 1),   
      ,    8253.    
       0,      . 
               ,  
             . 
     ,              
         :

      1.       97.
      2.     3    3.
      3.     97.

           ,     ,    
       253.

           ,        
       ,       .  
      C -   inportb()  outportb().   Microsoft C  -
       inp()  outp().     :

               int inportb(int port);
               void outportb(int port, char value);
               int inp(unsigned port);
               int outp(unsigned port, int value);

                         
     ,       ,
                . 
     ,      ,   
      C.


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

                   ,   
       ,      
       .       ,    
       PC     12000 . 
      ,          ,  
          . ,  
     ,          ,     
         12000 .  (: 
                 .
     ,   ,            
     .  ,         
- - -                                                          - - - 
                                
                                - 276 -

             ,    
      ).

                    sound(),
           
     .   ,      
     ,                 
     .

               /*      */

          void sound(freq)
          int freq;
          {
            unsigned i;
            union {
               long divisor;
               unsigned char c[2];
            } count;

            unsigned char p;

            count.divisor = 1193280 / freq; /*  
                                               */
            outportb(67,182); /*    8253 
                                   */
            outportb(66,count.c[0]); /*    */
            outportb(66,count.c[1]); /*    */
            p = inportb(97); /*     */
            outportb(97,p|3); /*   0  1 */

            for (i=0;i<64000;++i); /*   */

            outportb(97,p); /*   
                                    */
          }



          ,            
      .   ,      
           ""    "".     
                
     .   ,          ,  
            .  
     sound()                
     "" .

                  
     .


               /*    */

          #include "dos.h"

          void sound();

          main()
          {
- - -                                                          - - - 
                                
                                - 277 -

               int freq;

               do {
                 printf("   ( 0 -  ): ");
                 scanf("%d",&freq);
                 if ( freq ) sound(freq);
               } while(freq);
          }



            ,      
         ,      .  
       0.


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

                 
           ,  ,    ,
           .   
              - 
       .

          ,           
            .  
           ,   
           .    siren(),   ,
            .


          #define DELAY 10000

          /*     */
          void siren()
          {
            unsigned i,freq;
            union {
               long divisor;
               unsigned char c[2];
            } count;

            unsigned char p;

            p = inportb(97); /*     */
            outportb(97,p|3); /*   0  1 */
               /*    */
            for (freq = 1000;freq<3000;freq+=RATE) {
               count.divisor = 1193280 / freq; /*  
                                                    */
               outportb(67,182); /*    8253 
                                         */
               outportb(66,count.c[0]); /*    */
               outportb(66,count.c[1]); /*    */

               for (i=0;i<DELAY;++i);
            }

- - -                                                          - - - 
                                
                                - 278 -

               /*    */
            for (;freq>1000;freq-=RATE) {
               count.divisor = 1193280 / freq; /*  
                                                    */
               outportb(67,182); /*    8253 
                                         */
               outportb(66,count.c[0]); /*    */
               outportb(66,count.c[1]); /*    */

               for (i=0;i<DELAY;++i);
            }
            outportb(97,p); /*    
                                            */
          }

                        DELAY   
                
     .   ,   siren()    
             .    
                 
       siren()  .

             ,       
     ,      siren()  ,
               .
       laser(),    ,    
     .


          #define DELAY 10000
          /*    */
          void laser()
          {
            unsigned i,freq;
            union {
               long divisor;
               unsigned char c[2];
            } count;

            unsigned char p;

            p = inportb(97); /*     */
            outportb(97,p|3); /*   0  1 */
               /*  */
               for (;freq>1000;freq-=RATE) {
               count.divisor = 1193280 / freq; /*  
                           */
               outportb(67,182); /*    8253 
                            */
               outportb(66,count.c[0]); /*    */
               outportb(66,count.c[1]); /*    */

               for (i = 0;i<DELAY;++i);
            }
            outportb(97,p); /*    
                                   */
          }



- - -                                                          - - - 
                                
                                - 279 -

                       
         .   
                
      .


           " ".
          ------------------------------

               
      rend()  sound(),     ""  .  ,
              ,    ,
      " "   - .
       ,       ,
            ,            ,
        " ".

               /*    */

          #define DELAY 64000

          #include "dos.h"

          void sound();

          main()
          {
               int freq;

               do {
                    do {
                         freq = rand();
                    } while (freq>5000); /*  
                                             */
                    sound(freq);
               } while (!kbhit());
          }

          /*      */
          void sound(freq)
          int freq;
          {
            unsigned i;
            union {
               long divisor;
               unsigned char c[2];
            } count;

            unsigned char p;
            count.divisor = 1193280 / freq; /*  
                                                 */
               outportb(67,182); /*    8253 
                                       */
               outportb(66,count.c[0]); /*    */
               outportb(66,count.c[1]); /*    */

               p = inportb(97); /*     */
               outportb(97,p|3); /*   0  1 */

- - -                                                          - - - 
                                
                                - 280 -

               for (i = 0;i<DELAY;++i); /*  64000  10+ 
                                           
                                        32000  6  PC/AT
                                        20000   PC  XT */

               outportb(97,p); /*   
                         */
          }

                5000  ,  
                       
              ,  
      .

                    ,
             
       ,      sound().    
        .



                                   9
                                  -------

                              ""
     -----------------------------------------------------------------

                         
       ""  (mouse).   ,  "" 
       ,     "roller ball",   
              ,   ""
               
       Apple    Apple  Lisa,        
       ""      ()
          .   Apple
     Lisa          Macintosh, 
         ""     
        .         IBM
     PS/2  "",   ,     .  
          IBM  PS/2 ,  
             "",     ""  
        .

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

                "",      
         ,       
     .   ,    ,     
     ,        ""  Microsoft,
        "",    PS
     /2.          ""  Microsoft 
- - -                                                          - - - 
                                
                                - 281 -

                 "",   
          "" (Microsoft Mouse
     Programmer's Reference Guide)      
     .          
     MOUSE.LIB,    ""  
      .        
           , 
        .    ,     
                
              
      Microsoft.      ,    
         MOUSE.SYS.

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




                       ""
     -----------------------------------------------------------------

           ,   "",   
       .  ""  Microsoft
       CONFIG.SYS     :

                             device = mouse.sys

                 ""    IBM    
       MOUSE.COM.         AUTOEXEC.BAT
         :

                                   mouse

           ,       ,  
         ""           
       33.  ,  "", 
     ,             
          .   ,
               "" 
     ,  ""    
        .

            ,          ,  
     ""           (
      ).         ""
        Microsoft             
     :     -  ,      
       -         .
           -  ""   
             ,      ""   
     .        -  ""  
        ,     "" 
      .

- - -                                                          - - - 
                                
                                - 282 -

            ,   ""      
      ,            ,    
     ""               ,
             -  ""  
     .    ""   
                "".
     ,         "",    
     ""  .         1/200 .   
            "" 
     .




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

               ""     Microsoft
                    
     (       ,      
                 ),
            .    
     ""         .
                  
           .    6,
     14,  15  16       .  
       4  5      
          ,      .  
                ,      
     ,       ""  
             ,        4
      .



                          ""
     -----------------------------------------------------------------

            MOUSE.LIB    
      ,      ,
            "".  ( 
                   DOS
         21      ).
                    ,   
             .   
     cmouses()       ,  cmousec()    
      ,   cmousem()            
     cmousel()        ()  .
     (,          
     ).  ,     ,  
      ,         
      .

             cmouses() :

          void cmouses(fnum, arg2, arg3, arg4);
               int *fnum, *arg2, *arg3, *arg4;
           ,  fnum      "",
       .    ,
           .   ,  
- - -                                                          - - - 
                                
                                - 283 -

         ,     .
       cmouses()      
     ,  ,       .    Microsoft
         "".    
              .    
          ""  Microsoft,  
          .


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

           0  ""     (
     "")     - ""    
     "  "  .          
     ""      arg2.     fnum
       0,   ""    
       ,  -1   .


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

           1      -   "".    
       .


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

           2     .      
      .


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

           3         arg2,  
         arg3,   
        arg4.

                  0  1  arg2.  
       0   (  1),        
       "",     1  ( 1),  
           .           
      ( 0),      .


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

           4       "".
      arg3    ,   arg4
     -     .      , 
                  ,
       .

- - -                                                          - - - 
                                
                                - 284 -


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

           11        
     "" ,   ""        
             11,      -    
           "".    
       -  0.  
        arg3,    -    arg4.  
     ,    ""       
       ,    ,
          0.     
      ( )   0,    ""    
     .

                   ""
           ,      ""      .
                 ""
     .

                
           ,    ""    ,  
         ,   "" 
     .



                    ""  
     -----------------------------------------------------------------

            cmouses()      
           ,        
      ,     
     "". ,   .


           ""   .
          --------------------------------------

          ,  , mouse_reset()  
      ""      .  ,    
                
       ,        
     "".

     /*  ""    */

     void mouse_reset()
     {
          int fnum, arg2, arg3, arg4;

          fnum = 0;  /*  ""     */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          if(fnum!=-1) {
          printf("     ");
          printf("''  ");
               exit(1);
          }
          if(arg2!=2) {
- - -                                                          - - - 
                                
                                - 285 -

       printf("    ''");
               exit(1);
          }
     }


              "".
          -----------------------------------------

                     cursor_on()    
     cursor_off(),    ,     
          .


     /*    ""  */
     void cursor_on()
     {
          int fnum;

          fnum = 1; /*   */
          cmouses( &fnum,  &fnum,  &fnum,  &fnum);
     }

     /*    ""  */
     void cursor_off()
     {
          int fnum;

          fnum = 2; /*   */
          cmouses( &fnum,  &fnum,  &fnum,  &fnum);
     }


             ""  ?
          -----------------------------------

                  
      rightb_pressed()  leftb_pressed(),   .
         "",     
      .


     /*   "",    ,
           ""                               */

     rightb_pressed()
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3;   /*      */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          return arg2 & 2;
     }



     /*   "",    ,
           ""                               */

     leftb_pressed()
- - -                                                          - - - 
                                
                                - 286 -

     {
          int fnum, arg2, arg3, arg4;

          fnum = 3;   /*      */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          return arg2 & 1;
     }


             ""?
          ----------------------------------

           11,       
     "" ( "" )          ,
                   "".   
     mouse_motion(),      ,      
         ""             
       ,        
     .        deltax   deltay  0,   
      ""  .

     /*      */
     void mouse_motion(deltax, deltay)
     char *deltax, *deltay;
     {
          int fnum, arg2, arg3, arg4;

          fnum = 11; /*    */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          if(arg3>0) *deltax = RIGHT;
          else if(arg3<0) *deltax = LEFT;
          else *deltax = NOT_MOVED;

          if(arg4>0) *deltay = DOWN;
          else if(arg4<0) *deltay = UP;
          else *deltay = NOT_MOVED;
     }


           RIGHT, LEFT, UP, DOWN  NOT_MOVED 
      :

     #define NOT_MOVED 0
     #define RIGHT     1
     #define LEFT      2
     #define UP        3
     #define DOWN      4


- - -                                                          - - - 
                                
                                - 287 -


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

           set_mouse_position()              mouse_position(),
       ,       
       "".


     /*    "" */
     void set_mouse_position(x, y)
     int x, y;
     {

          int fnum, arg2;

          fnum = 4; /*   */
          cmouses(&fnum, &arg2, &x, &y);
     }

     /*    "" */
     void mouse_position(x, y)
     int *x, *y;
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3; /*      */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          *x = arg3;
          *y = arg4;
     }




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

          ,    ,    
       ""  .     
             .

     /*    "" Microsoft/IBM */

     #include "dos.h"
     #define NOT_MOVED 0
     #define RIGHT     1
     #define LEFT      2
     #define UP        3
     #define DOWN      4
     void mouse_position(), mode(), goto_xy(), mouse_motion();
     void cursor_on(), cursor_off(), mouse_reset();

     main(argc, argv)
     int argc;
     char *argv[];
     {
          char deltax, deltay, x, y;

          if(argc!=2) {
- - -                                                          - - - 
                                
                                - 288 -

               printf("  : mouser <> ");
               exit(1);
          }

          mode(atoi(argv[1]));

          mouse_reset();  /*  ""  */
          cursor_on();    /* ""    */

          do {
               goto_xy(0, 0);
               if(leftb_presed()) printf(" ");
               if(rightb_pressed()) {
                    printf(" ");
                    mouse_position(&x, &y);
                    printf("%d %d - ", x, y);
               }

               /*   "" */
               mouse_motion(&deltax, &deltay);
               if(deltax || deltay) {
                    printf("");
                    switch(deltax) {
                         case NOT_MOVED: break;
                         case RIGHT: printf("");
                              break;
                         case LEFT: printf("");
                              break;
                    }
                    switch(deltay) {
                         case NOT_MOVED: break;
                         case UP: printf("");
                              break;
                         case DOWN: printf("");
                              break;
                    }
               }
          /*        */
          } while(!(leftb_pressed() && rightb_pressed()));
          mode(3);
     }

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

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

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

- - -                                                          - - - 
                                
                                - 289 -

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

     /**********************************************************/
     /* ,    ""            */
     /**********************************************************/

     /*    ""  */
     void cursor_on()
     {
          int fnum;

          fnum = 1; /*   */
          cmouses( &fnum,  &fnum,  &fnum,  &fnum);
     }


     /*    ""  */
     void cursor_off()
     {
          int fnum;

          fnum = 2; /*   */
          cmouses( &fnum,  &fnum,  &fnum,  &fnum);
     }


     /*   "",    ,
           ""                               */

     rightb_pressed()
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3;   /*        */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          return arg2 & 2;
     }


     /*   "",    ,
           ""                               */

     leftb_pressed()
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3;   /*        */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          return arg2 & 1;
     }


     /*      */
     void mouse_motion(deltax, deltay)
     char *deltax, *deltay;
- - -                                                          - - - 
                                
                                - 290 -

     {
          int fnum, arg2, arg3, arg4;

          fnum = 11; /*    */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          if(arg3>0) *deltax = RIGHT;
          else if(arg3<0) *deltax = LEFT;
          else *deltax = NOT_MOVED;

          if(arg4>0) *deltay = DOWN;
          else if(arg4<0) *deltay = UP;
          else *deltay = NOT_MOVED;
     }



     /*    "" */
     void set_mouse_position(x, y)
     int x, y;
     {
          int fnum, arg2;

          fnum = 4; /*   */
          cmouses(&fnum, &arg2, &x, &y);
     }

     /*    "" */
     void mouse_position(x, y)
     int *x, *y;
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3; /*      */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          *x = arg3;
          *y = arg4;
     }




     /*  ""      */

     void mouse_reset()
     {
          int fnum, arg2, arg3, arg4;

          fnum = 0;  /*  ""     */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          if(fnum!=-1) {
          printf("     ");
          printf("''  ");
               exit(1);

          }
          if(arg2!=2) {
          printf("    ");
          printf("''");
               exit(1);
          }
- - -                                                          - - - 
                                
                                - 291 -

     }

                   DOS
       ,            .
              "",
           "".      ,  
             ,  .
             .  
                   
          .





               ""   
     -----------------------------------------------------------------
          ,             ,      
     ,      ""  
     .   ""     
         ,   ,   ,      
     ,      
     .
                   ,    
                100
     ,            
                     
     (  "").
           ,  ""          
       ,       ,
       "".      -  wait_on()
           ()
       .      
        ,    
       ,           .   (
               ,  
            ).  
                
              ( 
       ,    )      
     ,   .    ,  
              wait_on(),    ,
             ,    
      .


     /*  1,      */

     void wait_on(button)
     int button;
     {
          if(button== LEFTB)
               while(leftb_pressed());
          else
               while(rightb_pressed());
     }

           LEFTB   RIGHTB,   ,  
        wait_on().

- - -                                                          - - - 
                                
                                - 292 -


     #define LEFTB     1
     #define RIGHTB    2

                mouse_menu().  
               
             "" 
      (, ,  ""  )  
         "".           4
      .     ,
                 (      
     ),      ( ),  
                .   
                     19
     .               
        ,   0,  -1, 
             .   

       ,         
     ( )   ,    
                 
       ,        
     len. (        
     8             16    .)    
     ,       
       "".           
      ""         , ,
       ,        .  
     mouse_menu()  .


     /*     ""  
                      */

     mouse_menu(count, item, x, y)
     int count;           /*    */
     char item[][20];      /*   */
     int x, y;           /*   */
     {
          int i, len[MENU_MAX][2], t;
          int mousex, mousey;

          goto_xy(x, y);
          t = 0;
          for(i=0; i<count; i++) {
               printf("%s   ", item[i]);
               len[i][0] = t;
               /*      16   */
               len[i][1] = t + strlen(item[i])*16;
               t = len[i][1] + 32; /*    
                                     */
          }

          /*      */
          do {
               if(rightb_pressed() || leftb_pressed()) break;
          } while(!kbhit());
          /*    */
          while(rightb_pressed() || leftb_pressed());

- - -                                                          - - - 
                                
                                - 293 -

          /*     "" */
          mouse_position(&mousex, &mousey);

          /* ,       */
               if(mousey>=0 && mousey<8)  /*   
                                   8   */
                    for(i=0; i<count; i++) {
                         if(mousex>len[i][0] && mousex<len[i][1])
                              return i;
                    }
               return i;
          }
           returtn -1; /*      */
       }



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

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

     main()
     {
          char done=0;

          mode(4); /*   4   
                     CGA/EGA  */
          palette(0); /*  0  */
          mouse_reset(); /*  "" */

          xhairs(x, y); /*    */
          set_mouse_position(y*2, x); /*   
                                          "" */
          do {
               /* ,   "" */
               mouse_motion(&deltax, &deltay);
               if(deltax || deltay) read_mouse();
               /*    */
               if(leftb_pressed() || rightb_pressed())
                    read_mouse();
               if(kbhit()) {
                    done = read_kb();
               /*  ""    
                      */
                    set_mouse_position(y*2, x);
               }
          } while (!done);
          mode(2);
     }


- - -                                                          - - - 
                                
                                - 294 -


             ,  main(),   
     done(),       .    
          ,      
     ,    ,        
       ,       "", 
                  ,   
         .      ,  
         (       "") 
       .            
       .  ,    ""
           .          
                
         .  "" 
          .

           read_kb(),          
     ,  .      
             
      .

     /*    ,    */

     read_kb()
     {
          union k{
               char c[2];
               int i;
          } key;

          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:  /*  */
                    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);
                    y -= inc; x -= inc;
                    break;
               case 73:  /*   */
                    if(on_flag) line(x, y, x-inc, y+inc, cc);
                    y += inc; x -= inc;
                    break;
- - -                                                          - - - 
                                
                                - 295 -

               case 79: /*   */
                    if(on_flag) line(x, y, x+inc, y-inc, cc);
                    y -= inc; x += inc;
                    break;
               case 81:  /*   */
                    if(on_flag) line(x, y, x+inc, y+inc, cc);
                    y += inc; x += inc;
                    break;
               case 59: inc = 1; /* F1 -   */
                    break;
               case 60: inc = 5; /* F2 -   */
                    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;
               case 'm': /*   */
                    move(startx, starty, endx, endy, x, y);
                    break;
               case 'x': /*   */
                    copy(startx, starty, endx, endy, x, y);
                    break;
               case 'd': /*     */
                    sides = define_object(object, x, y);
                    break;
               case 'a': /*   */
                    rotate_object(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;
- - -                                                          - - - 
                                
                                - 296 -

                    break;
               case 'p': pal_num = pal_num==1 ? 2:1;
                    palette(pal_num);
          }
          /*     */
          xhairs(x, y);
          if(tolowel(key.c[0])=='q') return 1;
          return 0;
     }

           read_mouse(),       "",
      .


     /*    ,    "" */

     read_mouse()
     {
          int oldx, oldy;
          int choice;

          oldx = x; oldy = y;
          xhairs(x, y); /*     */

          /*       */
          if(rightb_pressed() && leftb_pressed()) {
               choice = menu(); /*   
                                     */
               switch(choice) {
                case 0: box(startx, starty, endx, endy, cc);
                     break;
                case 1: circle(startx, starty, endy-starty, cc);
                     break;
                case 2: line(startx, starty, endx, endy, cc);
                     break;
                case 3: fill_box(startx, starty, endx, endy, cc);
                     break;
                case 4: fill_circle(startx, starty, endy-starty, cc);
                     break;
               }
          }

          /*       */

          else if(rightb_pressed()) {
               if(first_point) {
                    startx = x; starty = y;
               }
               else {
                    endx = x; endy = y;
               }
               first_point = !first_point;
               wait_on(RIGHTB); /*    */
          }

          if(deltax || deltay) {
               mouse_position(&y, &x);
               y = y / 2; /*   
                          */
               /*      */
- - -                                                          - - - 
                                
                                - 297 -

               if(leftb_pressed()) mouse_on_flag = 1;
               else mouse_on_flag = 0;
               if(mouse_on_flag) line(oldx, oldy, x, y, cc);
          }
          /*     */
          xhairs(x, y);
     }

           read_mouse()    . -,
          .   
      ,       menu()  
     ,           
     mouse_menu().             
      ,    .  
                ,    
      ,  - ,  ,  
     ,  ,  ,    ,   
       ""        
       .  (      ,
           ).

                  
     ,    ,    ,  
     <>           .
      ""             
      .   ""    
        .     
      .

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

            ,   ""   , 
        X  Y.

           menu(),       ,      
               mouse_menu(),  
     .

     /*    */
     menu()
     {
          register int i, j;
          char far *ptr = (char far *) 0xB8000000; /*  
                                                       CGA- */
          char far *temp;
          unsigned char buf[14][80]; /*   
                                         */
          int x, y, choice;
          char items[][20] = {
               "BOX",
               "CIRCLE",
               "LINE",
               "FILL BOX",
               "FILL CIRCLE"
          };
- - -                                                          - - - 
                                
                                - 298 -


          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);
          /* ,       
              */
          while(rightb_pressed() || leftb_pressed());

          cursor_on();

          choice = mouse_menu(5, items, 0, 0);

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

                 
          ,        -
     .     ""  ""   
      mouse_menu().      mouse_
     menu()        ,       
             ,         
         .



                       ""
     -----------------------------------------------------------------

                         
         ,            
     define_object(),        
       .           
         .             define_object(),
       ,      "" 
       () .


     /*        
          "" */
     define_object(ob, x, y)
     double ob[][4];
     int x, y;
- - -                                                          - - - 
                                
                                - 299 -

     {
          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;
          int deltax, deltay, oldx, oldy;

          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;
          key.i = 0;
          xhairs(x, y);
          do {
               goto_xy(0, 0);
               printf("  %d", sides+1);
               if(i==0) printf("   ");
               else printf("   ");

               do {
     /**************    . *******************/
               /* ,  ""  */

                    mouse_motion(&deltax, &deltay);
               /*      */
                    if(leftb_pressed()) {
                         /*    */
                         xhairs(x, y);
                         /*    */
                         ob[sides][i++] = (double) x;
                         ob[sides][i++] = (double) y;
                         if(i==4) {
                              i = 0;
                              sides++;
                         }
                         break;
                    }
               } while(!kbhit() && !deltax && ! deltay);
               if(leftb_pressed()) wait_on(LEFTB);

               if(deltax || deltay) {
               /*  "" ,   */
                    oldx = x; oldy = y;
                    mouse_position(&y, &x);
                    y = y / 2; /*   
                                   */
- - -                                                          - - - 
                                
                                - 300 -

                    /*    */
                    xhairs(oldx, oldy);
               }
     /**********     "" *****************/

               else if(kbhit()) {
                    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(!key.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] != 59) xhairs(x, y);
          } while(key.c[1] != 59); /*  F1   */

          temp = ptr;
          /*       */
          for(i=0; i<14; i++)
               for(j=0; j<80; j+=2) {

                    *temp = buf[i][j];
                    *(temp+8152) = buf[i][j+1];
                    temp++;
               }
- - -                                                          - - - 
                                
                                - 301 -

          return sides;
     }


                 ,        
       .   ""    
     ,        read_mouse().    ,   
               
              "",      
     define_object()          .  
            ""  
        .





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

                    
        ,  .

     /*        CGA/EGA
          ""  Microsoft/IBM,
             ()
     */
     #define NUM_SIDES 20 /*    .
                                   */
     #define NOT_MOVED 0
     #define RIGHT     1
     #define LEFT      2
     #define UP        3
     #define DOWN      4
     #define LEFTB     1
     #define RIGHTB    2

     #define MENU_MAX 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();
     void set_mouse_position(), mouse_position(), mouse_motion();
     void cursor_on(), cursor_off(), wait_on(), mouse_reset();

     unsigned char read_point();

     /*       
               */

     double object[NUM_SIDES][4];

     double asp_ratio; /*    */
- - -                                                          - - - 
                                
                                - 302 -


          int x, y; /*    */
          int cc=2; /*   */
          int on_flag=1, mouse_on_flag=0; /*   
                                               */
          int pal_num=1;                 /*   */

          /*  ,  , 
            */
          int startx=0, starty=0, endx=0, endy=0, first_point=1;
          int inc=1;       /*   */
          int sides=0;     /*     */
          int deltax, deltay;    /* ""   
                                       */


     main()
     {
          char done=0;

          mode(4); /*   4   
                          CGA/EGA  */
          palette(0);    /*  0  */
          mouse_reset(); /*  "" */

          xhairs(x, y);  /*    */
          set_mouse_position(y*2, x); /*   
                                         "" */
          do {
               /* ,   "" */
               mouse_motion(&deltax, &deltay);
               if(deltax || deltay) read_mouse();
               /*    */
               if(leftb_pressed() || rightb_pressed())
                    read_mouse();
               if(kbhit()) {
                    done = read_kb();
               /*  ""    
                      */
                    set_mouse_position(y*2, x);
               }
          } while (!done);
          mode(2);
     }


     /*    ,    "" */
     read_mouse()
     {
          int oldx, oldy;
          int choice;

          oldx = x; oldy = y;
          xhairs(x, y); /*     */

          /*       */
          if(rightb_pressed() && leftb_pressed()) {
               choice = menu(); /*   
                                     */
               switch(choice) {
- - -                                                          - - - 
                                
                                - 303 -

                 case 0: box(startx, starty, endx, endy, cc);
                      break;
                 case 1: circle(startx, starty, endy-starty, cc);
                      break;
                 case 2: line(startx, starty, endx, endy, cc);
                      break;
                 case 3: fill_box(startx, starty, endx, endy, cc);
                      break;
                 case 4: fill_circle(startx, starty, endy-starty, cc);
                      break;
               }
          }

          /*       */
          else if(rightb_pressed()) {
               if(first_point) {
                    startx = x; starty = y;
               }
               else {
                    endx = x; endy = y;
               }
               first_point = !first_point;
               wait_on(RIGHTB); /*    */
          }

          if(deltax || deltay) {
               mouse_position(&y, &x);
               y = y / 2; /*   
                          */
               /*      */
               if(leftb_pressed()) mouse_on_flag = 1;
               else mouse_on_flag = 0;
               if(mouse_on_flag) line(oldx, oldy, x, y, cc);
          }
          /*     */
          xhairs(x, y);
     }

     /*    ,    */
     read_kb()
     {
          union k{
               char c[2];
               int i;
          } key;

          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:  /*  */
                    if(on_flag) line(x, y, x-inc, y, cc);
                    x -= inc;
- - -                                                          - - - 
                                
                                - 304 -

                    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);
                    y -= inc; x -= inc;
                    break;
               case 73:  /*   */
                    if(on_flag) line(x, y, x-inc, y+inc, cc);
                    y += inc; x -= inc;
                    break;
               case 79: /*   */
                    if(on_flag) line(x, y, x+inc, y-inc, cc);
                    y -= inc; x += inc;
                    break;
               case 81:  /*   */
                    if(on_flag) line(x, y, x+inc, y+inc, cc);
                    y += inc; x += inc;
                    break;
               case 59: inc = 1; /* F1 -   */
                    break;
               case 60: inc = 5; /* F2 -   */
                    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;
               case 'm': /*   */
                    move(startx, starty, endx, endy, x, y);
                    break;
               case 'x': /*   */
                    copy(startx, starty, endx, endy, x, y);
                    break;
               case 'd': /*     */
                    sides = define_object(object, x, y);
- - -                                                          - - - 
                                
                                - 305 -

                    break;
               case 'a': /*   */
                    rotate_object(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);
          if(tolowel(key.c[0])=='q') return 1;
          return 0;
     }

     /*   */
     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(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)
- - -                                                          - - - 
                                
                                - 306 -

     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;

          /*   . 
            0   ,
              
          */
          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_x = abs(delta_x);
          delta_y = abs(delta_y);
          if(delta_x>delta_y) distance = delta_x;
          else distance = delta_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;
               }
          }
     }

     /*     */
     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)
- - -                                                          - - - 
                                
                                - 307 -

     int x_center, y_center, radius, color_code;
     {
          register int 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, endx, x1, starty, endy, 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_center-y, color_code);
               mempoint(x_center-x1, y+y_center, 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, y_center-x, color_code);
               mempoint(x_center-y1, x+y_center, color_code);
          }
     }


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

               circle(x, y, r, c);
               r--;
          }
     }


     /*     */
     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 */
     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; /* xor -    
                        */
          char far *ptr = (char far *) 0xB8000000; /* 
                                                      CGA  */
          bit_mask.i=0xFF3F;  /* 11111111 00111111  
                                 */

          /*    4  */
          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 >> 2);
           if(x % 2) index += 8152; /*  
                                        2- 
                                        */

           /*   */
           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;
           }
- - -                                                          - - - 
                                
                                - 309 -

     }


     /*      CGA/EGA
          4 */
     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; /* xor -    
                        */
          char far *ptr = (char far *) 0xB8000000; /* 
                                                      CGA  */
          bit_mask.i=0xFF3F;  /* 11111111 00111111    */

          /*    4  */
          if(x<0 || x>199 || y<0 || y>319) return;

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

           /*      */
           index = x*40 +(y >> 2);
           if(x % 2) index += 8152; /*  
                                        2- 
                                        */

          /*   */
           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++)
               for(j=0; j<80; j+=2) {
                    buf[i][j] = *temp; /*   */
                    buf[i][j+1] = *(temp+8152); /*   */
- - -                                                          - - - 
                                
                                - 310 -

                    *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+=2) {
                    *temp = buf[i][j];
                    *(temp+8152) = buf[i][j+1];
                    temp++;
               }

          /*     */
          for(i=0; i<8152; i++) {
               putc(*ptr, fp); /*   */
               putc(*(ptr+8152), 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);
- - -                                                          - - - 
                                
                                - 311 -

               printf("    \n");
               temp = ptr;
               /*      */
               for(i=0; i<14; i++)
                    for(j=0; j<80; j+=2) {
                         *temp = buf[i][j];
                         *(temp+8152) = buf[i][j+1];
                         temp++;
                    }
               return;
          }

          /*     */
          for(i=0; i<8152; i++) {
               *ptr = getc(fp); /*   */
               *(ptr+8152) = getc(fp); /*   */
               ptr++;
          }
          fclose(fp);
     }


     /*      */
     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);
     }



     /*      */
     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++, endx++)
               for(i=starty, j=y; i<=endy; i++, j++) {
                    c = read_point(startx, i); /*   */
                    mempoint(startx, i, 0); /*  
                                                */
                    mempoint(x, j, c); /*      */
               }
     }



     /*      */
- - -                                                          - - - 
                                
                                - 312 -

     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++, endx++)
               for(i=starty, j=y; i<=endy; i++, j++) {
                    c = read_point(startx, i); /*   */
                    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;

          /*        */
          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;
- - -                                                          - - - 
                                
                                - 313 -

                    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);
               }
          }
     }

     /*   */
     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;
          int deltax, deltay, oldx, oldy;

          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; /*  
                                                      */
- - -                                                          - - - 
                                
                                - 314 -

                    temp++;
               }

          i = 0;
          key.i = 0;
          xhairs(x, y);
          do {
               goto_xy(0, 0);
               printf("  %d", sides+1);
               if(i==0) printf("   ");
               else printf("   ");

               do {
     /****************     *******************/
               /*   ""  */
                 mouse_motion(&deltax, &deltay);
                 /*      */
                 if(leftb_pressed()) {
                   xhairs(x, y); /*    */
                   /*    */
                   ob[sides][i++] = (double) x;
                   ob[sides][i++] = (double) y;
                   if(i==4) {
                        i = 0;
                        sides++;
                   }
                   break;
                 }
               } while(!kbhit() && !deltax && ! deltay);
               if(leftb_pressed()) wait_on(LEFTB);

               if(deltax || deltay) {
                 /*  "" ,   */
                 oldx = x; oldy = y;
                 mouse_position(&y, &x);
                 y = y / 2; /*   
                                */
                 /*    */
                 xhairs(oldx, oldy);
               }
     /***********     "" *****************/

               else if(kbhit()) {
                    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(!key.c[0]) switch(key.c[1]) {
                         case 75: /*  */
- - -                                                          - - - 
                                
                                - 315 -

                              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] != 59) xhairs(x, y);
          } while(key.c[1] != 59); /*  F1   */

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

     /*    */
     menu()
     {
          register int i, j;
          char far *ptr = (char far *) 0xB8000000; /*  
                                                      CGA- */
          char far *temp;
          unsigned char buf[14][80]; /*   
                                         */
          int x, y, choice;
          char items[][20] = {
               "BOX",
               "CIRCLE",
               "LINE",
               "FILL BOX",
               "FILL CIRCLE"
          };

          temp = ptr;
          /*      */
          for(i=0; i<14; i++)
- - -                                                          - - - 
                                
                                - 316 -

               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);
          /* ,       
              */
          while(rightb_pressed() || leftb_pressed());

          cursor_on();

          choice = mouse_menu(5, items, 0, 0);

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


     /**********************************************************/
     /* ,    ""            */
     /**********************************************************/

     /*    ""  */
     void cursor_on()
     {
          int fnum;

          fnum = 1; /*   */
          cmouses( &fnum,  &fnum,  &fnum,  &fnum);
     }


     /*    ""  */
     void cursor_off()
     {
          int fnum;

          fnum = 2; /*   */
          cmouses( &fnum,  &fnum,  &fnum,  &fnum);
     }



     /*   "",    ,
           ""                              */

     rightb_pressed()
     {
- - -                                                          - - - 
                                
                                - 317 -

          int fnum, arg2, arg3, arg4;

          fnum = 3;   /*        */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          return arg2 & 2;
     }



     /*   "",    ,
           ""    */

     leftb_pressed()
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3;   /*        */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          return arg2 & 1;
     }


     /*    "" */
     void set_mouse_position(x, y)
     int x, y;
     {
          int fnum, arg2;

          fnum = 4; /*   */
          cmouses(&fnum, &arg2, &x, &y);
     }

     /*    "" */
     void mouse_position(x, y)
     int *x, *y;
     {
          int fnum, arg2, arg3, arg4;

          fnum = 3; /*      */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          *x = arg3;
          *y = arg4;
     }

     /*      */
     void mouse_motion(deltax, deltay)
     char *deltax, *deltay;
     {
          int fnum, arg2, arg3, arg4;

          fnum = 11; /*    */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          if(arg3>0) *deltax = RIGHT;
          else if(arg3<0) *deltax = LEFT;
          else *deltax = NOT_MOVED;

          if(arg4>0) *deltay = DOWN;
          else if(arg4<0) *deltay = UP;
          else *deltay = NOT_MOVED;
     }
- - -                                                          - - - 
                                
                                - 318 -


     /*     ""  
               */
     mouse_menu(count, item, x, y)
     int count;           /*    */
     char item[][20];      /*   */
     int x, y;           /*   */
     {
          int i, len[MENU_MAX][2], t;
          int mousex, mousey;

          goto_xy(x, y);
          t = 0;
          for(i=0; i<count; i++) {
               printf("%s   ", item[i]);
               len[i][0] = t;
               /*      16   */
               len[i][1] = t + strlen(item[i])*16;
               t = len[i][1] + 32; /*    
                                        */
          }

          /*      */
          do {
               if(rightb_pressed() || leftb_pressed()) break;
          } while(!kbhit());
          /*    */
          while(rightb_pressed() || leftb_pressed());

          /*     "" */
          mouse_position(&mousex, &mousey);

          /* ,       */
               if(mousey>=0 && mousey<8)  /*   
                                   8   */
                    for(i=0; i<count; i++) {
                         if(mousex>len[i][0] && mousex<len[i][1])
                              return i;
                    }
               return i;
          }


     /*  1,      */
     void wait_on(button)
     int button;
     {
          if(button== LEFTB)
               while(leftb_pressed());
          else
               while(rightb_pressed());
     }



     /*  ""      */
     void mouse_reset()
     {
          int fnum, arg2, arg3, arg4;
- - -                                                          - - - 
                                
                                - 319 -


          fnum = 0;  /*  ""     */
          cmouses( &fnum, &arg2, &arg3, &arg4);
          if(fnum!=-1) {
          printf("     ");
          printf("''  ");
               exit(1);
          }
          if(arg2!=2) {
        printf("    ''");
               exit(1);
          }
     }


           ,     , 
        ,       
      (   ),    
                .  ,
       9.1               
       .  .  9.2  ,     
         "" (  -   
     ).



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

          -,       
     mouse_menu()    ,          ,
          .    
                   
       ""     "" ,
        1.

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

- - -                                                          - - - 
                                
                                - 320 -



                                   10
                                  --------

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

                   ,  
                  
              -  .  
            
       .      ,    
       ,    .

                       ,
         .        
     ,             
       ,      ,    
        .

                       
       .   ,
             .  ,  
                 ,  
         .



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

                 
        ,               
        .    ,  
                320*200,      320   -
         200 - .  ,  
        ,   
         ,         
       0  199.      
     .

             ,       
       ,         
           .         ,
                 ,
              .       
     ,              
                 
       .    ,      4-   
         :

                  _ = 200 / ( - min)

           ,            
     :

       _ = _ * _


- - -                                                          - - - 
                                
                                - 321 -


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

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

                  bargraph(),         ,
       .


          /*   */
     void bargraph(data,num,offset,min,max,width)
     double *data;      /*   */
     int num;           /*     */
     int offset;        /*    */
     int min,max;       /* .  .   */
     int width;         /*   */
     {
          int y,t,incr;
          double norm_data,norm_ratio,spread;
          char s[80];
          static int color = 0;
          int tempwidth;

          /*     */
          color++;
          if ( color > 3 ) color = 1;

          /*    */
          spread = (double)max-min;
          norm_ratio = 180/spread;

          incr = 280/num;/*     */
          tempwidth = width;
          for (t=0;t<num;++t) {
               norm_data = data[t];

          /*    */
               norm_data = norm_data-(double)min;
               norm_data *= norm_ratio; /*  */
               y = (int)norm_data; /*   */
               do {
                    Line(179,((t*incr)+20+offset+width),179-y,
                      ((t*incr)+20+offset+width),color);
               width--;
               } while(width);
               width = tempwidth;
               }
          }

- - -                                                          - - - 
                                
                                - 322 -

                    .   
     bargraph()    :  , 
         ,      ( 
            ),      
                 (
         ).     color
                 bargraph().
       ,            
               
     .       
         (200    4- )  
      - 180,         
           .   ,  
                 
       .  ,  ,    
     ,    ,      
     ,            
         .        
         (   
       280  300)        
     ,       
        .      
            
         .

           bargraph() -  ,     
       ,       
     .          
      .


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

                ,
                     .
       grid(),    , 
        .

          /*     */
     void grid(min,max)
     int min,max;
     {
          register int t;

          goto_xy(22,0); printf("%d",min);
          goto_xy(0,0); printf("%d",max);
          line(180,10,180,300,1);
     }

           ,      grid()    ,    bargraph()
                
      .

- - -                                                          - - - 
                                
                                - 323 -


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

               ,  
     .  ,    ,      
            ,    
          .  ,    
            ,      goto_xy()  
     printf();   label(),  ,   
       ,     
          .        label()
     :          .     
      20  (    ),      
              
        .


               /*     */
     void label(str,num)
     char str[][20]; /*   */
     int num; /*   */
     {
          int i,j,inc;

          inc = 38/num;
          i = 2; /*    */
          for (j=0;j<num;j++) {
               goto_xy(23,i);
               printf(str[j]);
               i += inc;
          }
     }





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

                  
         .       
       ,      
      .   hashlines(),   , 
       .

               /*    */
     void hashlines()
     {
          int i,j;
          for (i;1<180;i+) {
               for (j;j<300;j+=5)
                    mempoint(i,j,3); /*     5 
                                         */
          }
     }

- - -                                                          - - - 
                                
                                - 324 -

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

                  
             ,    
     .    ,  ,   , 
                  .
      legend(),  ,   
            ,      
               .
      legend()   fill_box(),   ,
        .

               /*   */
     void legend(names,num)
     char names[][20];
     int num;            /*   */
     {
          int color = 1,i,j;

          goto_xy(24,0); /*      */
          j = 0;
          for (i=0;i<num;i++) {
               /*   */
               printf("%s   ",names[i]);
               /*    .  4
                       8 
                   ( )  */
               j += strlen(names[i]) * 8 + 4;
               fill_box(192,j,198,j+12,color);
               j += 28; /*      */
               color ++;
               if ( color>3 ) color = 1;
          }
     }

     _________________________________________________________________

               355    
            . (.  ..)
     _________________________________________________________________

     .10-1.     



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

                      
     .       .10-1. 
                
     .

- - -                                                          - - - 
                                
                                - 325 -

          /*     */
     #include "dos.h"

     void bargraph(),mode(),mempoint();
     void line(),goto_xy(),grid(),label();
     void hashlines(),legend(),read_cursor_xy();
     void palette(),color_puts(),fill_box();

     main()
     {
          double widget[] = {
               10.1,20,30,35.34,50
               };
          double global[] = {
               19,20,8.8,30,40
               };
          double tower[] = {
               25.25,19,17.4,33,29
               };
          int min,max;

          char n[][20] = {
               "widget",
               "global",
               "tower"
               };
          char lab[][20] = {
               "1983",
               "1984",
               "1985",
               "1986",
               "1987"
               };
          mode(4);       /*   320*200 */
          palette(0);
          grid(0,50);    /*     */
          hashlines();   /*    */
          label(lab,5);  /*   */
          legend(n,3);   /*   */

          /*      */
          bargraph(widget,5,0,0,50,4);
          bargraph(global,5,10,0,50,4);
          bargraph(tower,5,20,0,50,4);

          getch();
          mode(3);
     }

     /*      */
     void grid(min,max)
     int min,max;
     {
          register int t;

          goto_xy(22,0); printf("%d",min);
          goto_xy(0,0); printf("%d",max);
          line(180,10,180,300,1);
     }

- - -                                                          - - - 
                                
                                - 326 -

     /*     */
     void label(str,num)
     char str[][20]; /*   */
     int num; /*   */
     {
          int i,j,inc;

          inc = 38/num;
          i = 2; /*    */
          for (j=0;j<num;j++) {
               goto_xy(23,i);
               printf(str[j]);
               i += inc;
          }
     }

     /*      */
     void hashlines()
     {
          int i,j;

          for (i;1<180;i+) {
               for (j;j<300;j+=5)
                    mempoint(i,j,3); /*     5 
                                         */
          }
     }

     /*   */
     void legend(names,num)
     char names[][20];
     int num; /*   */
     {
          int color = 1,i,j;

          goto_xy(24,0); /*      */
          j = 0;
          for (i=0;i<num;i++) {
               /*   */
               printf("%s   ",names[i]);
               /*    .  4
                       8 
                   (   )  */
               j++ = strlen(names[i]*8+4);
               fill_box(192,j,198,j+12,color);
               j++ = 28; /*      */
               color ++;
               if ( color>3 ) color = 1;
          }
     }

     /*   */

     void bargraph(data,num,offset,min,max,width)
     double *data; /*   */
     int num; /*     */
     int offset; /*    */
     int min,max; /*      */
     int width; /*   */
     {
- - -                                                          - - - 
                                
                                - 327 -

          int y,t,incr;
          double norm_data,norm_ratio,spread;
          char s[80];
          static int color = 0;
          int tempwidth;

          /*     */
          color++;
          if ( color > 3 ) color = 1;

          /*    */
          spread = (double)max-min;
          norm_ratio = 180/spread;

          incr = 280/num; /*    */
          tempwidth = width;
          for (t=0;t<num;++t) {
               norm_data = data[t];

          /*    */
               norm_data = norm_data-(double)min;
               norm_data *= norm_ratio; /*  */
               y = (int)norm_data; /*   */
               do {
                    line(179,((t*incr)+20+offset+width),179-y,
                      ((t*incr)+20+offset+width),color);
               width--;
               } while(width);
               width = tempwidth;
               }
          }

     /*    ,   
           */
     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_x = abs(delta_x);
          delta_y = abs(delta_y);
          if ( delta_x > delta_y ) distance = delta_x;
          else distance = delta_y;
     /*   */
          for (t=0;t<=distance+1;t++) {
- - -                                                          - - - 
                                
                                - 328 -

               mempoint(startx,starty,color);
               x+= delta_x;
               y+= delta_y;
               if (x>distance) {
               x-=distance;
               startx+=incx;
               }
               if (y>distance) {
               y-=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);
     }
     /*    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; /* xor -    */
          char far *ptr = (char far *) 0xB8000000; /*  
                                                       CGA  */
          bit_mask.i = 0xFF3F; /* 11111111 00111111    */
          /*    4  */
          if (x<0 || x>199 || y<0 || y>319) return;

          xor = color_code & 128; /*    xor */
          color_code = color_code & 127; /*  7   */

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

     /*       */
          index = x*40 + (y>>2);
          if (x%2) index+52; /*  ,  
                                    */
     /*   */
          if (!xor) { /*   */
               t = *(ptr + index) & bit_mask.c[0];
               *(ptr + index) = t | color_code;
          }
          else { /*  xor */
- - -                                                          - - - 
                                
                                - 329 -

                t = *(ptr + index) | (char)0;
               *(ptr + index) = t | color_code;
          }
     }

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

          r.h.al = mode_code;
          r.h.ah = 0;
          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);
     }

     /*    */
     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);
     }


- - -                                                          - - - 
                                
                                - 330 -


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

                     
        .      
        ,     
     ,        ,    
                .    
            .
                   
           .


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

                   main(),   
           .


     #define MAX_SETS 3
     #define MAX_ENTRIES 50
     #define MAX_LABELS 20
     #define MAX_NAMES 20

     main()
     {
          double v[MAX_SETS][MAX_ENTRIES]; /*   */
          int num_entries;
          int num_sets;
          int min,max,i;
          int lines,offset;
          char save = 0; /*    */
          char names[MAX_NAMES][20];
          char lab[MAX_LABELS][20];

     /*   */
          enter(v,&num_entries,&num_sets);

     /*      */
          min_max(v,num_entries,num_sets,&min,&max);

     /*    */
          get_names(names,num_sets);

     /*     */
          get_labels(lab,num_entries);

     /*    */
          lines = get_line_size();

     /*     */
          offset = get_offset();

     /*     ? */
          printf("     ? (y/n) ");
          if (tolower(getche()) == 'y') save = 1;

- - -                                                          - - - 
                                
                                - 331 -

          mode(4); /*   320*200 */
          palette(0);

          grid(min,max); /*     */
          hashlines(); /*    */
          label(lab,num_entries); /*    */
          legend(names,num_sets); /*    */

          /*      */
          for (i=0;i<num_sets;i++)
               bargraph(v[i],num_entries,i*offset,min,max,lines);

          if (save) save_pic();
          getch();
          mode(3);
     }

              ,      main()      
     ,    .  v
         ,       
          50      .   (      
            .)  
                   
              .  
           ,   
     ,         .   
       .    
             save_pic().    
          main()  ,    
           .


           enter().
          ----------------

               enter()      
        ,     ,
               
         .          
                     
          .   
           .

          /*   */
     enter(v,entries,sets)
     double v[][MAX_ENTRIES]; /*    */
     int *entries; /*       */

     int *sets; /*    */
     {
          int i,j,count,num;
          char s[80];

     printf("    ( 1  %d)",MAX_SETS);
          scanf("%d%c",&count,&j);
          if (count>MAX_SETS) count = MAX_SETS; /*   
                                                    */
          *sets = count;
     printf("   ( 1  %d) ",MAX_ENTRIES);
          scanf("%d%c",&num,&j);
- - -                                                          - - - 
                                
                                - 332 -

          if (num>MAX_SETS) num = MAX_ENTRIES; /*   
                                                   */
          *entries = num;

          j = 0;

          /*    */
          while((j<count)) {
               printf("  %d\n",j+1);
               for (i=0;i<num;i++) {
                    printf("%d:",i+1);
                    gets(s);
                    sscanf(s,"%lf",&v[j][i]);
               }
               j++;
          }
          return count;
     }


           min_max().
          ------------------

                 bargraph()       
           ,        
             .  
      ,             
             ,   
               
           ,        
             .   
     min_max(),      ,         
        .

          /*      
                 */
     void min_max(v,entries,sets,min,max)
     double v[][MAX_ENTRIES]; /*   */
     int entries; /*     
                       */

     int sets; /*    */
     int *min,*max; /*    
                        */
     {
          int i,j;
          int tmin,tmax;

          *min = *max = 0;

          for (i=0;i<sets;i++) {
               tmax = getmax(v[i],entries);
               tmin = getmin(v[i],entries);
               if (tmax>*max) *max = tmax;
               if (tmin <*min) *min = tmin;
          }
     }
      /*     */
     getmax(data,num)
     double *data;
- - -                                                          - - - 
                                
                                - 333 -

     int num;
     {
          int t,max;

          max = (int)data[0];
          for (t=1;t<num;++t)
               if (data[t]>max) max = (int)data[t];
          return max;
     }

     /*     */
     getmin(data,num)
     double *data;
     int num;
     {
          int t,min;

          min = (int)data[0];
          for (t=1;t<num;++t)
               if (data[t]<min) min = (int)data[t];
          return min;
     }


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

                   
     .


          /*    */

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

     #define MAX_SETS 3
     #define MAX_ENTRIES 50
     #define MAX_LABELS 20
     #define MAX_NAMES 20

     void bargraph(),mode(),mempoint();
     void line(),goto_xy(),grid(),label();
     void hashlines(),legend(),read_cursor_xy();
     void palette(),color_puts(),fill_box();
     void get_labels(),get_names(),min_max();
     void save_pic();

     main()
     {
          double v[MAX_SETS][MAX_ENTRIES]; /*   */
          int num_entries;
          int num_sets;
          int min,max,i;
          int lines,offset;
          char save = 0; /*    */
          char names[MAX_NAMES][20];
          char lab[MAX_LABELS][20];
     /*   */
          enter(v,&num_entries,&num_sets);
- - -                                                          - - - 
                                
                                - 334 -


     /*      */
          min_max(v,num_entries,num_sets,&min,&max);

     /*    */
          get_names(names,num_sets);

     /*     */
          get_labels(lab,num_entries);

     /*    */
          lines = get_line_size();

     /*     */
          offset = get_offset();

     /*     ? */
          printf("     ? (y/n) ");
          if (tolower(getche()) == 'y') save = 1;

          mode(4); /*   320*200 */
          palette(0);

          grid(min,max); /*     */
          hashlines(); /*    */
          label(lab,num_entries); /*    */
          legend(names,num_sets); /*    */

          /*      */
          for (i=0;i<num_sets;i++)
               bargraph(v[i],num_entries,i*offset,min,max,lines);

          if (save) save_pic();
          getch();
          mode(3);
     }
          /*   */
     enter(v,entries,sets)
     double v[][MAX_ENTRIES]; /*    */
     int *entries;      /*      
                            */

     int *sets; /*    */
     {
          int i,j,count,num;
          char s[80];

     printf("    ( 1  %d)",MAX_SETS);
          scanf("%d%c",&count,&j);
          if (count>MAX_SETS) count = MAX_SETS; /*   
                                                    */
          *sets = count;
     printf("    ( 1  %d)",MAX_ENTRIES);
          scanf("%d%c",&num,&j);
          if (num>MAX_ENTRIES) num = MAX_ENTRIES; /*   
                                                   */
          *entries = num;

          j = 0;

- - -                                                          - - - 
                                
                                - 335 -

          /*   */
     while((j<count)) {
          printf("   %d\n",j+1);
          for (i = 0;i<num;i++) {
          printf("%d:",i+1);
          gets(s);
          sscanf(s,"%lf",&v[j][i]);
          }
          j++;
        }
        return count;
     }

     /*    */
     void get_names(n,num)
     char n[][20];         /*    */
     int num;              /*   */
     {
          int i;

          for (i=0;i<num;i++) {
               printf("  : ");
               gets(n[i]);
          }
     }

     /*     */
     void get_labels(l,num)
     char l[][20]; /*    */
     int num; /*   */
     {
          int i;

          for (i=0;i<num;i++) {
               printf("   : ");
               gets(l[i]);
          }
     }

     /*        */
     get_offset()
     {
          int i;

     printf("       ");
          scanf("%d%*c",&i);
          return i;
     }

     /*       */
     get_line_size()
     {
          int i;

     printf("      : ");
          scanf("%d",&i);
          return i;
     }
     /*      */
     void grid(min,max)
- - -                                                          - - - 
                                
                                - 336 -

     int min,max;
     {
          register int t;

          goto_xy(22,0); printf("%d",min);
          goto_xy(0,0); printf("%d",max);
          line(180,10,180,300,1);
     }

     /*     */
     void label(str,num)
     char str[][20]; /*   */
     int num; /*   */
     {
          int i,j,inc;

          inc = 38/num;
          i = 2; /*    */
          for (j=0;j<num;j++) {
               goto_xy(23,i);
               printf(str[j]);
               i += inc;
          }
     }

     /*      */
     void hashlines()
     {
          int i,j;

          for (i;1<180;i+) {
               for (j;j<300;j+=5)
                    mempoint(i,j,3); /*     5 
                                         */
          }
     }

     /*   */
     void legend(names,num)
     char names[][20];
     int num; /*   */
     {
          int color = 1,i,j;

          goto_xy(24,0); /*      */
          j = 0;
          for (i=0;i<num;i++) {
               /*   */
               printf("%s   ",names[i]);
               /*    .  4
                       8 
                   (   )  */
               j += strlen(names[i]) * 8 + 4;

               fill_box(192,j,198,j+12,color);
               j += 28; /*      */
               color ++;
               if ( color>3 ) color = 1;
          }
     }
- - -                                                          - - - 
                                
                                - 337 -


     void bargraph(data,num,offset,min,max,width)
     double *data;          /*   */
     int num;               /*     */
     int offset;            /*    */
     int min,max;  /*      */
     int width;             /*   */
     {
          int y,t,incr;
          double norm_data,norm_ratio,spread;
          char s[80];
          static int color = 0;
          int tempwidth;

          /*     */
          color++;
          if ( color > 3 ) color = 1;

          /*    */
          spread = (double)max-min;
          norm_ratio = 180/spread;

          incr = 280/num; /*    */
          tempwidth = width;
          for (t=0;t<num;++t) {
               norm_data = data[t];

          /*    */
               norm_data = norm_data-(double)min;
               norm_data *= norm_ratio; /*  */
               y = (int)norm_data; /*   */
               do {
                    Line(179,((t*incr)+20+offset+width),179-y,
                      ((t*incr)+20+offset+width),color);
               width--;
               } while(width);
               width = tempwidth;
               }
          }

          /*      
                 */
     void min_max(v,entries,sets,min,max)
     double v[][MAX_ENTRIES]; /*   */
     int entries; /*     
                       */

     int sets; /*    */
     int *min,*max; /*    
                        */
     {
          int i,j;
          int tmin,tmax;

          *min = *max = 0;

          for (i=0;i<sets;i++) {
               tmax = getmax(v[i],entries);
               tmin = getmin(v[i],entries);
               if (tmax>*max) *max = tmax;
- - -                                                          - - - 
                                
                                - 338 -

               if (tmin <*min) *min = tmin;
          }
     }
      /*     */
     getmax(data,num)
     double *data;
     int num;
     {
          int t,max;

          max = (int)data[0];
          for (t=1;t<num;++t)
               if (data[t]>max) max = (int)data[t];
          return max;
     }

     /*     */
     getmin(data,num)
     double *data;
     int num;
     {
          int t,min;

          min = (int)data[0];
          for (t=1;t<num;++t)
               if (data[t]<min) min = (int)data[t];
          return min;
     }

     /*    ,   
           */
     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_x = abs(delta_x);
          delta_y = abs(delta_y);
          if ( delta_x > delta_y ) distance = delta_x;
          else distance = delta_y;
     /*   */
          for (t=0;t<=distance+1;t++) {
               mempoint(startx,starty,color);
               x+= delta_x;
               y+= delta_y;
- - -                                                          - - - 
                                
                                - 339 -

               if (x>distance) {
               x-=distance;
               startx+=incx;
               }
               if (y>distance) {
               y-=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);
     }
     /*    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; /* xor -    */
          char far *ptr = (char far *) 0xB8000000; /*  
                                                      CGA  */
          bit_mask.i = 0xFF3F; /* 11111111 00111111    */
          /*    4  */
          if (x<0 || x>199 || y<0 || y>319) return;

          xor = color_code & 128; /*    xor */
          color_code = color_code & 127; /*  7   */

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

     /*       */
          index = x*40 + (y>>2);
          if (x%2) index+52; /*  ,  
                                    */
     /*   */
          if (!xor) { /*   */
               t = *(ptr + index) & bit_mask.c[0];
               *(ptr + index) = t | color_code;
          }
          else { /*  xor */
                t = *(ptr + index) | (char)0;
               *(ptr + index) = t ^ color_code;
          }
- - -                                                          - - - 
                                
                                - 340 -

     }

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

          r.h.al = mode_code;
          r.h.ah = 0;
          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);
     }

     /*    */
     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 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+=2) {
                    buf[i][j] = *temp; /*   */
                    buf[i][j+1] = *(temp+8152); /*  */
                    *temp = 0;
                    *(temp+8152) = 0; /*   
                                          */
                    temp++;
- - -                                                          - - - 
                                
                                - 341 -

               }
          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+=2) {
                    *temp = buf[i][j];
                    *(temp+8152) = buf[i][j+1];
                    temp++;
               }
          /*     */
          for (i=0;i<8152;i++) {
               putc(*ptr,fp); /*   */
               putc(*(ptr+8152),fp); /*   */
               ptr++;
          }
          fclose(fp);
     }



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

                 ,   
          .    
        SHOW,    . 
      ,   ,     
      . ,   , 
       backlog,   

                        show backlog

           show                  load_pic(),
             .  ( 
                  
          ,    
       .)

     /*      */

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

     void load_pic(),mode(),palette(),goto_xy();

     main(argc,argv)
     int argc;
     char *argv[];
     {
          if (argc != 2) {
               printf(" :  < >");
               exit(1);
          }
- - -                                                          - - - 
                                
                                - 342 -

          mode(4);
          palette(0);
          load_pic(argv[1]);
          getch();
          mode(3);
     }

     /*    */
     void load_pic(fname)
     char *fname;
     {
          FILE *fp;
          register int i,j;
          char far *ptr = (char far *) 0xB8000000; /* 
                CGA  */
          char far *temp;
          unsigned char buf[14][80]; /*   
                                         */
          if (!(fp=fopen(fname,"rb"))) {
               goto_xy(0,0);
               printf("    \n");
               return;
          }
          /*     */
          for (i=0;i<8152;i++) {
               *ptr = getc(fp); /*   */
               *(ptr+8152) = getc(fp); /*   */
               ptr++;
          }
          fclose(fp);
     }

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

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

     /*    */
     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);
     }

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


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




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

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